refactor: replace exportName with name throughout codebase

- Update TpmjsToolDefinitionSchema to only use 'name' field
- Add 'sandbox' as valid category for sprites tools
- Update all package.json files to use 'name' instead of 'exportName'
- Update documentation and source files accordingly
- Add 11 new sprites tools for sandbox/code-execution
This commit is contained in:
Ajax Davis 2026-01-14 14:18:36 +10:00
parent b1dd3371cd
commit 2cd2b10cd0
91 changed files with 4019 additions and 195 deletions

View file

@ -22,11 +22,11 @@
],
"tools": [
{
"exportName": "textToEmoji",
"name": "textToEmoji",
"description": "Convert text into emoji representations - perfect for making messages more expressive!"
},
{
"exportName": "emojiMood",
"name": "emojiMood",
"description": "Detect the mood/sentiment and suggest appropriate emojis for the text"
}
]

View file

@ -23,7 +23,7 @@
],
"tools": [
{
"exportName": "helloWorldTool",
"name": "helloWorldTool",
"description": "Returns a simple 'Hello, World!' greeting with optional timestamp and customizable message",
"parameters": [
{
@ -39,7 +39,7 @@
}
},
{
"exportName": "helloNameTool",
"name": "helloNameTool",
"description": "Returns a personalized greeting with the provided name",
"parameters": [
{

View file

@ -22,11 +22,11 @@
],
"tools": [
{
"exportName": "markdownToPlainText",
"name": "markdownToPlainText",
"description": "Convert markdown to plain text by removing all formatting"
},
{
"exportName": "formatMarkdownTable",
"name": "formatMarkdownTable",
"description": "Format and align markdown table columns for better readability"
}
]

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "audiencePersonaTool",
"name": "audiencePersonaTool",
"description": "Creates detailed audience persona profiles from demographic and behavioral data. Generates personas with demographics, psychographics, goals, pain points, behaviors, and actionable marketing implications.",
"parameters": [
{

View file

@ -330,6 +330,37 @@ domain:
fields: [effect, standardError, assumptions, parallel]
description: "Difference-in-differences result"
# -------------------------------------------------------------------------
# Sandbox & execution entities
# -------------------------------------------------------------------------
sprite:
fields: [name, status, createdAt, runtime, filesystem]
description: "Isolated Linux sandbox environment"
sprite_list:
fields: [sprites, count]
description: "Collection of sprites with metadata"
exec_result:
fields: [exitCode, stdout, stderr, duration]
description: "Command execution result from a sprite"
exec_session:
fields: [id, status, startedAt, command]
description: "Active execution session in a sprite"
checkpoint:
fields: [id, name, createdAt, size]
description: "Point-in-time snapshot of sprite state"
checkpoint_list:
fields: [checkpoints, count]
description: "Collection of checkpoints for a sprite"
network_policy:
fields: [mode, allowedDomains, rules]
description: "DNS-based network filtering configuration"
# -------------------------------------------------------------------------
# Agent & workflow entities
# -------------------------------------------------------------------------
@ -521,10 +552,9 @@ domain:
severity: warning
# =============================================================================
# DOMAIN RULES - Enforce code quality across all blocks
# DOMAIN RULES - Enforce code quality across all blocks (documentation only)
# =============================================================================
blocks:
domain_rules:
domain_rules:
# -------------------------------------------------------------------------
# Core implementation rules (apply to ALL tools)
# -------------------------------------------------------------------------
@ -794,10 +824,10 @@ blocks:
- Handle missing/extra items
- Report confidence in scores
# ===========================================================================
# BLOCK DEFINITIONS - All 100 tools organized by category
# ===========================================================================
# ===========================================================================
# BLOCK DEFINITIONS - All 100 tools organized by category
# ===========================================================================
blocks:
# ---------------------------------------------------------------------------
# A) Web Research & Evidence (15 tools)
# ---------------------------------------------------------------------------
@ -4494,6 +4524,260 @@ blocks:
description: "Standards to activities mapping"
measures: [working_implementation, valid_output_structure, readme_documentation]
# ---------------------------------------------------------------------------
# K) Sandbox & Code Execution - Sprites API (11 tools)
# ---------------------------------------------------------------------------
sprites.createSprite:
description: "Creates a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API"
path: "sprites-create"
domain_rules:
- id: api_integration
description: |
Must call Sprites API POST /sprites endpoint:
- Use fetch with Authorization Bearer header
- Send name in request body
- Handle API errors with meaningful messages
- id: auth_handling
description: "Must use SPRITES_TOKEN environment variable for authentication"
inputs:
- name: name
type: string
description: "Unique name for the sprite (must be lowercase alphanumeric with hyphens)"
outputs:
- name: sprite
type: Sprite
description: "Created sprite with name, status, and metadata"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.listSprites:
description: "Lists all sprites in the account with their current status and metadata"
path: "sprites-list"
domain_rules:
- id: api_integration
description: "Must call Sprites API GET /sprites endpoint"
- id: auth_handling
description: "Must use SPRITES_TOKEN environment variable for authentication"
inputs: []
outputs:
- name: sprites
type: Sprite[]
description: "Array of sprites with name, status, and metadata"
- name: count
type: number
description: "Total number of sprites"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.getSprite:
description: "Retrieves details of a specific sprite by name including status and configuration"
path: "sprites-get"
domain_rules:
- id: api_integration
description: "Must call Sprites API GET /sprites/{name} endpoint"
- id: error_handling
description: "Must handle 404 for non-existent sprites gracefully"
inputs:
- name: name
type: string
description: "Name of the sprite to retrieve"
outputs:
- name: sprite
type: Sprite
description: "Sprite details including status and metadata"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.deleteSprite:
description: "Deletes a sprite and all its associated data including checkpoints"
path: "sprites-delete"
domain_rules:
- id: api_integration
description: "Must call Sprites API DELETE /sprites/{name} endpoint"
- id: confirmation
description: "Returns success status after deletion"
inputs:
- name: name
type: string
description: "Name of the sprite to delete"
outputs:
- name: deleted
type: boolean
description: "Whether the sprite was successfully deleted"
- name: name
type: string
description: "Name of the deleted sprite"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.execCommand:
description: "Executes a command inside a sprite and returns the output. Supports stdin input for interactive commands."
path: "sprites-exec"
domain_rules:
- id: api_integration
description: |
Must call Sprites API POST /sprites/{name}/exec endpoint:
- Send cmd and optional stdin in request body
- Handle command execution timeout
- Return stdout, stderr, and exit code
- id: timeout_handling
description: "Must implement configurable timeout (default 60s)"
inputs:
- name: name
type: string
description: "Name of the sprite to execute command in"
- name: cmd
type: string
description: "Command to execute (e.g., 'ls -la', 'python script.py')"
- name: stdin
type: string
optional: true
description: "Optional stdin input to pass to the command"
- name: timeoutMs
type: number
optional: true
description: "Execution timeout in milliseconds (default: 60000)"
outputs:
- name: exitCode
type: number
description: "Command exit code (0 for success)"
- name: stdout
type: string
description: "Standard output from the command"
- name: stderr
type: string
description: "Standard error output from the command"
- name: duration
type: number
description: "Execution duration in milliseconds"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.listSessions:
description: "Lists active execution sessions for a sprite"
path: "sprites-sessions"
domain_rules:
- id: api_integration
description: "Must call Sprites API GET /sprites/{name}/exec/sessions endpoint"
inputs:
- name: name
type: string
description: "Name of the sprite to list sessions for"
outputs:
- name: sessions
type: ExecSession[]
description: "Array of active execution sessions"
- name: count
type: number
description: "Total number of active sessions"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.createCheckpoint:
description: "Creates a point-in-time snapshot (checkpoint) of a sprite's filesystem state for later restoration"
path: "sprites-checkpoint-create"
domain_rules:
- id: api_integration
description: "Must call Sprites API POST /sprites/{name}/checkpoints endpoint"
- id: checkpoint_metadata
description: "Must return checkpoint ID and creation timestamp"
inputs:
- name: name
type: string
description: "Name of the sprite to checkpoint"
- name: checkpointName
type: string
optional: true
description: "Optional human-readable name for the checkpoint"
outputs:
- name: checkpoint
type: Checkpoint
description: "Created checkpoint with ID and metadata"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.listCheckpoints:
description: "Lists all checkpoints for a sprite ordered by creation time"
path: "sprites-checkpoint-list"
domain_rules:
- id: api_integration
description: "Must call Sprites API GET /sprites/{name}/checkpoints endpoint"
inputs:
- name: name
type: string
description: "Name of the sprite to list checkpoints for"
outputs:
- name: checkpoints
type: Checkpoint[]
description: "Array of checkpoints with IDs and metadata"
- name: count
type: number
description: "Total number of checkpoints"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.restoreCheckpoint:
description: "Restores a sprite to a previous checkpoint state, reverting all filesystem changes since that checkpoint"
path: "sprites-checkpoint-restore"
domain_rules:
- id: api_integration
description: "Must call Sprites API POST /sprites/{name}/checkpoints/{id}/restore endpoint"
- id: state_verification
description: "Must verify restoration completed successfully"
inputs:
- name: name
type: string
description: "Name of the sprite to restore"
- name: checkpointId
type: string
description: "ID of the checkpoint to restore to"
outputs:
- name: restored
type: boolean
description: "Whether the restoration was successful"
- name: checkpointId
type: string
description: "ID of the restored checkpoint"
- name: sprite
type: Sprite
description: "Sprite status after restoration"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.getPolicy:
description: "Retrieves the current network policy for a sprite including allowed domains and filtering rules"
path: "sprites-policy-get"
domain_rules:
- id: api_integration
description: "Must call Sprites API GET /sprites/{name}/policies endpoint"
inputs:
- name: name
type: string
description: "Name of the sprite to get policy for"
outputs:
- name: policy
type: NetworkPolicy
description: "Current network policy with allowed domains and rules"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
sprites.setPolicy:
description: "Updates the network policy for a sprite to control outbound network access with DNS-based filtering"
path: "sprites-policy-set"
domain_rules:
- id: api_integration
description: "Must call Sprites API POST /sprites/{name}/policies endpoint"
- id: policy_validation
description: "Must validate policy format before sending"
inputs:
- name: name
type: string
description: "Name of the sprite to update policy for"
- name: mode
type: "'allow' | 'deny'"
description: "Policy mode - 'allow' blocks all except listed, 'deny' allows all except listed"
- name: domains
type: string[]
description: "List of domains to allow or deny based on mode"
outputs:
- name: policy
type: NetworkPolicy
description: "Updated network policy"
- name: applied
type: boolean
description: "Whether the policy was successfully applied"
measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance, readme_documentation]
# =============================================================================
# VALIDATORS - Which validators to run against each block
# =============================================================================

View file

@ -48,7 +48,7 @@
],
"tools": [
{
"exportName": "churnRiskScoreTool",
"name": "churnRiskScoreTool",
"description": "Scores customer churn risk based on usage, engagement, and support signals. Provides risk score (0-100) with detailed contributing factors and recommendations.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "contentCalendarPlanTool",
"name": "contentCalendarPlanTool",
"description": "Generates a structured content calendar with posting schedule, themes, topics, and content types. Organizes content by date, channel, and theme while maintaining consistent posting frequency.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "createBlogPostTool",
"name": "createBlogPostTool",
"description": "Creates structured blog posts with customizable frontmatter, content sections, and SEO metadata. Supports multiple output formats including Markdown and MDX.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "emailSubjectScoreTool",
"name": "emailSubjectScoreTool",
"description": "Scores email subject lines for open rate potential based on length, clarity, urgency, curiosity, and personalization. Provides detailed feedback and improvement suggestions.",
"parameters": [
{

View file

@ -48,7 +48,7 @@
],
"tools": [
{
"exportName": "feedbackThemesTool",
"name": "feedbackThemesTool",
"description": "Extracts themes and sentiment from customer feedback text. Identifies recurring themes, scores sentiment per theme, and provides frequency counts.",
"parameters": [
{

View file

@ -48,7 +48,7 @@
],
"tools": [
{
"exportName": "npsAnalysisTool",
"name": "npsAnalysisTool",
"description": "Analyzes NPS survey responses to categorize by promoter/passive/detractor and extract themes from comments. Provides NPS score, distribution, and actionable insights.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "pricingPageCopyTool",
"name": "pricingPageCopyTool",
"description": "Generates comprehensive pricing page copy with tier names, headlines, benefit-oriented feature lists, CTAs, FAQs, and trust signals. Frames features as benefits and clearly differentiates tiers.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "reconciliationMatchTool",
"name": "reconciliationMatchTool",
"description": "Matches bank transactions to ledger entries for reconciliation. Uses amount, date proximity, and description similarity to identify matches with confidence scoring.",
"parameters": [
{

View file

@ -47,7 +47,7 @@
],
"tools": [
{
"exportName": "socialPostDraftTool",
"name": "socialPostDraftTool",
"description": "Drafts social media posts optimized for specific platforms (Twitter, LinkedIn, Instagram, Facebook) with appropriate hashtags, CTAs, and platform-specific best practices. Respects character limits and engagement patterns.",
"parameters": [
{

View file

@ -0,0 +1,77 @@
{
"name": "@tpmjs/tools-sprites-checkpoint-create",
"version": "0.1.1",
"description": "Create a point-in-time snapshot of a sprite's filesystem state for later restoration",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"checkpoint",
"snapshot",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-checkpoint-create"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesCheckpointCreateTool",
"description": "Create a point-in-time snapshot of a sprite's filesystem state for later restoration",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to checkpoint",
"required": true
},
{
"name": "checkpointName",
"type": "string",
"description": "Optional name for the checkpoint",
"required": false
}
],
"returns": {
"type": "Checkpoint",
"description": "Created checkpoint with ID and metadata"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,124 @@
/**
* Sprites Checkpoint Create Tool for TPMJS
* Creates a point-in-time snapshot of a sprite's filesystem state for later restoration.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface Checkpoint {
id: string;
name?: string;
createdAt: string;
size?: number;
}
type SpritesCheckpointCreateInput = {
name: string;
checkpointName?: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesCheckpointCreateTool = tool({
description:
"Create a point-in-time snapshot (checkpoint) of a sprite's filesystem state for later restoration. Useful for saving state before risky operations.",
inputSchema: jsonSchema<SpritesCheckpointCreateInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to checkpoint',
},
checkpointName: {
type: 'string',
description: 'Optional human-readable name for the checkpoint',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name, checkpointName }): Promise<Checkpoint> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 min for checkpoints
const body: Record<string, unknown> = {};
if (checkpointName) {
body.name = checkpointName;
}
response = await fetch(
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'TPMJS/1.0',
},
body: JSON.stringify(body),
signal: controller.signal,
}
);
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to create checkpoint for sprite "${name}" timed out`);
}
throw new Error(`Failed to create checkpoint for sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to create checkpoint for sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to create checkpoint for sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
return {
id: (data.id as string) || '',
name: (data.name as string) || checkpointName,
createdAt:
(data.createdAt as string) || (data.created_at as string) || new Date().toISOString(),
size: data.size as number | undefined,
};
},
});
export default spritesCheckpointCreateTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,71 @@
{
"name": "@tpmjs/tools-sprites-checkpoint-list",
"version": "0.1.1",
"description": "List all checkpoints for a sprite ordered by creation time",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"checkpoint",
"snapshot",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-checkpoint-list"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesCheckpointListTool",
"description": "List all checkpoints for a sprite ordered by creation time",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to list checkpoints for",
"required": true
}
],
"returns": {
"type": "{ checkpoints: Checkpoint[], count: number }",
"description": "Array of checkpoints with count"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,127 @@
/**
* Sprites Checkpoint List Tool for TPMJS
* Lists all checkpoints for a sprite ordered by creation time.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface Checkpoint {
id: string;
name?: string;
createdAt: string;
size?: number;
}
export interface SpritesCheckpointListResult {
checkpoints: Checkpoint[];
count: number;
}
type SpritesCheckpointListInput = {
name: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesCheckpointListTool = tool({
description:
'List all checkpoints for a sprite ordered by creation time. Use this to find checkpoint IDs for restoration.',
inputSchema: jsonSchema<SpritesCheckpointListInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to list checkpoints for',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<SpritesCheckpointListResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
}
);
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to list checkpoints for sprite "${name}" timed out`);
}
throw new Error(`Failed to list checkpoints for sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to list checkpoints for sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to list checkpoints for sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: unknown;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
const checkpointsArray = Array.isArray(data)
? data
: (data as Record<string, unknown>).checkpoints;
const checkpoints: Checkpoint[] = (Array.isArray(checkpointsArray) ? checkpointsArray : []).map(
(c: Record<string, unknown>) => ({
id: c.id as string,
name: c.name as string | undefined,
createdAt: (c.createdAt as string) || (c.created_at as string) || '',
size: c.size as number | undefined,
})
);
return {
checkpoints,
count: checkpoints.length,
};
},
});
export default spritesCheckpointListTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,77 @@
{
"name": "@tpmjs/tools-sprites-checkpoint-restore",
"version": "0.1.1",
"description": "Restore a sprite to a previous checkpoint state",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"checkpoint",
"restore",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-checkpoint-restore"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesCheckpointRestoreTool",
"description": "Restore a sprite to a previous checkpoint state, reverting all filesystem changes",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to restore",
"required": true
},
{
"name": "checkpointId",
"type": "string",
"description": "ID of the checkpoint to restore to",
"required": true
}
],
"returns": {
"type": "{ restored: boolean, checkpointId: string, sprite: Sprite }",
"description": "Restoration result with sprite status"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,135 @@
/**
* Sprites Checkpoint Restore Tool for TPMJS
* Restores a sprite to a previous checkpoint state, reverting all filesystem changes.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface Sprite {
name: string;
status: 'creating' | 'running' | 'stopped' | 'error';
createdAt: string;
runtime?: string;
metadata?: Record<string, unknown>;
}
export interface SpritesCheckpointRestoreResult {
restored: boolean;
checkpointId: string;
sprite: Sprite;
}
type SpritesCheckpointRestoreInput = {
name: string;
checkpointId: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesCheckpointRestoreTool = tool({
description:
'Restore a sprite to a previous checkpoint state, reverting all filesystem changes since that checkpoint. Use this to undo changes or recover from errors.',
inputSchema: jsonSchema<SpritesCheckpointRestoreInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to restore',
},
checkpointId: {
type: 'string',
description: 'ID of the checkpoint to restore to',
},
},
required: ['name', 'checkpointId'],
additionalProperties: false,
}),
async execute({ name, checkpointId }): Promise<SpritesCheckpointRestoreResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
if (!checkpointId || typeof checkpointId !== 'string') {
throw new Error('Checkpoint ID is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 min for restore
response = await fetch(
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/checkpoints/${encodeURIComponent(checkpointId)}/restore`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
}
);
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to restore checkpoint "${checkpointId}" timed out`);
}
throw new Error(`Failed to restore checkpoint "${checkpointId}": ${error.message}`);
}
throw new Error(`Failed to restore checkpoint "${checkpointId}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" or checkpoint "${checkpointId}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to restore checkpoint "${checkpointId}": HTTP ${response.status} - ${errorText}`
);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
// If no JSON response, assume success
data = {};
}
const spriteData = (data.sprite as Record<string, unknown>) || data;
return {
restored: true,
checkpointId,
sprite: {
name: (spriteData.name as string) || name,
status: (spriteData.status as Sprite['status']) || 'running',
createdAt: (spriteData.createdAt as string) || '',
runtime: spriteData.runtime as string | undefined,
metadata: spriteData.metadata as Record<string, unknown> | undefined,
},
};
},
});
export default spritesCheckpointRestoreTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,70 @@
{
"name": "@tpmjs/tools-sprites-create",
"version": "0.1.1",
"description": "Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-create"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesCreateTool",
"description": "Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Unique name for the sprite (must be lowercase alphanumeric with hyphens)",
"required": true
}
],
"returns": {
"type": "Sprite",
"description": "Created sprite with name, status, and metadata"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,141 @@
/**
* Sprites Create Tool for TPMJS
* Creates a new isolated Linux sandbox environment (sprite) with persistent filesystem
* using the Sprites API.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
/**
* Output interface for a sprite
*/
export interface Sprite {
name: string;
status: 'creating' | 'running' | 'stopped' | 'error';
createdAt: string;
runtime?: string;
metadata?: Record<string, unknown>;
}
type SpritesCreateInput = {
name: string;
};
/**
* Validates that a sprite name is valid
* Must be lowercase alphanumeric with hyphens, 3-63 characters
*/
function isValidSpriteName(name: string): boolean {
return /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/.test(name);
}
/**
* Gets the Sprites API token from environment
*/
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
/**
* Sprites Create Tool
* Creates a new sprite sandbox environment
*/
export const spritesCreateTool = tool({
description:
'Create a new isolated Linux sandbox environment (sprite) with persistent filesystem using the Sprites API. Sprites are lightweight VMs for running code securely.',
inputSchema: jsonSchema<SpritesCreateInput>({
type: 'object',
properties: {
name: {
type: 'string',
description:
'Unique name for the sprite (must be lowercase alphanumeric with hyphens, 3-63 characters)',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<Sprite> {
// Validate input
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
if (!isValidSpriteName(name)) {
throw new Error(
`Invalid sprite name: ${name}. Must be lowercase alphanumeric with hyphens, 3-63 characters.`
);
}
const token = getSpritesToken();
// Create the sprite via API
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60s timeout for creation
response = await fetch(`${SPRITES_API_BASE}/sprites`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'TPMJS/1.0',
},
body: JSON.stringify({ name }),
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to create sprite "${name}" timed out after 60 seconds`);
}
throw new Error(`Failed to create sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to create sprite "${name}": Unknown network error`);
}
if (!response.ok) {
const errorText = await response.text().catch(() => 'Unknown error');
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
if (response.status === 409) {
throw new Error(`Sprite "${name}" already exists. Choose a different name.`);
}
throw new Error(`Failed to create sprite "${name}": HTTP ${response.status} - ${errorText}`);
}
// Parse response
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error(`Failed to parse response from Sprites API`);
}
const sprite: Sprite = {
name: (data.name as string) || name,
status: (data.status as Sprite['status']) || 'creating',
createdAt: (data.createdAt as string) || new Date().toISOString(),
runtime: data.runtime as string | undefined,
metadata: data.metadata as Record<string, unknown> | undefined,
};
return sprite;
},
});
export default spritesCreateTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,70 @@
{
"name": "@tpmjs/tools-sprites-delete",
"version": "0.1.1",
"description": "Delete a sprite and all its associated data including checkpoints",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-delete"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesDeleteTool",
"description": "Delete a sprite and all its associated data including checkpoints",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to delete",
"required": true
}
],
"returns": {
"type": "{ deleted: boolean, name: string }",
"description": "Deletion result with success status"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,95 @@
/**
* Sprites Delete Tool for TPMJS
* Deletes a sprite and all its associated data including checkpoints.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface SpritesDeleteResult {
deleted: boolean;
name: string;
}
type SpritesDeleteInput = {
name: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesDeleteTool = tool({
description:
'Delete a sprite and all its associated data including checkpoints. This action is irreversible.',
inputSchema: jsonSchema<SpritesDeleteInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to delete',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<SpritesDeleteResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to delete sprite "${name}" timed out after 30 seconds`);
}
throw new Error(`Failed to delete sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to delete sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(`Failed to delete sprite "${name}": HTTP ${response.status} - ${errorText}`);
}
return {
deleted: true,
name,
};
},
});
export default spritesDeleteTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,88 @@
{
"name": "@tpmjs/tools-sprites-exec",
"version": "0.1.1",
"description": "Execute a command inside a sprite and return the output with exit code",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-exec"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesExecTool",
"description": "Execute a command inside a sprite and return the output with exit code",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to execute command in",
"required": true
},
{
"name": "cmd",
"type": "string",
"description": "Command to execute",
"required": true
},
{
"name": "stdin",
"type": "string",
"description": "Optional stdin input",
"required": false
},
{
"name": "timeoutMs",
"type": "number",
"description": "Execution timeout in milliseconds",
"required": false
}
],
"returns": {
"type": "ExecResult",
"description": "Command output with exitCode, stdout, stderr, and duration"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,138 @@
/**
* Sprites Exec Tool for TPMJS
* Executes a command inside a sprite and returns the output.
* Supports stdin input for interactive commands.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface ExecResult {
exitCode: number;
stdout: string;
stderr: string;
duration: number;
}
type SpritesExecInput = {
name: string;
cmd: string;
stdin?: string;
timeoutMs?: number;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesExecTool = tool({
description:
'Execute a command inside a sprite and return the output. Supports stdin input for interactive commands. Returns exit code, stdout, stderr, and execution duration.',
inputSchema: jsonSchema<SpritesExecInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to execute command in',
},
cmd: {
type: 'string',
description: "Command to execute (e.g., 'ls -la', 'python script.py')",
},
stdin: {
type: 'string',
description: 'Optional stdin input to pass to the command',
},
timeoutMs: {
type: 'number',
description: 'Execution timeout in milliseconds (default: 60000)',
},
},
required: ['name', 'cmd'],
additionalProperties: false,
}),
async execute({ name, cmd, stdin, timeoutMs }): Promise<ExecResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
if (!cmd || typeof cmd !== 'string') {
throw new Error('Command is required and must be a string');
}
const token = getSpritesToken();
const timeout = timeoutMs || 60000;
const startTime = Date.now();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const body: Record<string, unknown> = { cmd };
if (stdin) {
body.stdin = stdin;
}
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/exec`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'TPMJS/1.0',
},
body: JSON.stringify(body),
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Command execution in sprite "${name}" timed out after ${timeout}ms`);
}
throw new Error(`Failed to execute command in sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to execute command in sprite "${name}": Unknown network error`);
}
const duration = Date.now() - startTime;
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to execute command in sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
return {
exitCode: (data.exitCode as number) ?? (data.exit_code as number) ?? 0,
stdout: (data.stdout as string) || '',
stderr: (data.stderr as string) || '',
duration: (data.duration as number) || duration,
};
},
});
export default spritesExecTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,70 @@
{
"name": "@tpmjs/tools-sprites-get",
"version": "0.1.1",
"description": "Retrieve details of a specific sprite by name including status and configuration",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-get"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesGetTool",
"description": "Retrieve details of a specific sprite by name including status and configuration",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to retrieve",
"required": true
}
],
"returns": {
"type": "Sprite",
"description": "Sprite details including status and metadata"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,108 @@
/**
* Sprites Get Tool for TPMJS
* Retrieves details of a specific sprite by name including status and configuration.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface Sprite {
name: string;
status: 'creating' | 'running' | 'stopped' | 'error';
createdAt: string;
runtime?: string;
metadata?: Record<string, unknown>;
}
type SpritesGetInput = {
name: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesGetTool = tool({
description:
'Retrieve details of a specific sprite by name including status and configuration. Use this to check if a sprite exists and get its current state.',
inputSchema: jsonSchema<SpritesGetInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to retrieve',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<Sprite> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to get sprite "${name}" timed out after 30 seconds`);
}
throw new Error(`Failed to get sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to get sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(`Failed to get sprite "${name}": HTTP ${response.status} - ${errorText}`);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
return {
name: (data.name as string) || name,
status: (data.status as Sprite['status']) || 'running',
createdAt: (data.createdAt as string) || '',
runtime: data.runtime as string | undefined,
metadata: data.metadata as Record<string, unknown> | undefined,
};
},
});
export default spritesGetTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,63 @@
{
"name": "@tpmjs/tools-sprites-list",
"version": "0.1.1",
"description": "List all sprites in the account with their current status and metadata",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-list"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesListTool",
"description": "List all sprites in the account with their current status and metadata",
"parameters": [],
"returns": {
"type": "{ sprites: Sprite[], count: number }",
"description": "Array of sprites with count"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,118 @@
/**
* Sprites List Tool for TPMJS
* Lists all sprites in the account with their current status and metadata.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface Sprite {
name: string;
status: 'creating' | 'running' | 'stopped' | 'error';
createdAt: string;
runtime?: string;
metadata?: Record<string, unknown>;
}
export interface SpritesListResult {
sprites: Sprite[];
count: number;
}
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesListTool = tool({
description:
'List all sprites in the account with their current status and metadata. Returns an array of sprites with their names, statuses, and creation times.',
inputSchema: jsonSchema<Record<string, never>>({
type: 'object',
properties: {},
additionalProperties: false,
}),
async execute(): Promise<SpritesListResult> {
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(`${SPRITES_API_BASE}/sprites`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error('Request to list sprites timed out after 30 seconds');
}
throw new Error(`Failed to list sprites: ${error.message}`);
}
throw new Error('Failed to list sprites: Unknown network error');
}
if (!response.ok) {
const errorText = await response.text().catch(() => 'Unknown error');
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
throw new Error(`Failed to list sprites: HTTP ${response.status} - ${errorText}`);
}
let data: unknown;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
// Handle both array response and object with sprites property
const spritesArray = Array.isArray(data) ? data : (data as Record<string, unknown>).sprites;
if (!Array.isArray(spritesArray)) {
throw new Error('Invalid response from Sprites API: expected an array of sprites');
}
const sprites: Sprite[] = spritesArray.map((s: unknown) => {
const sprite = s as Record<string, unknown>;
const status = sprite.status as string | undefined;
// Validate status is a known value
if (status && !['creating', 'running', 'stopped', 'error'].includes(status)) {
throw new Error(`Invalid sprite status: ${status}`);
}
return {
name: sprite.name as string,
status: (status as Sprite['status']) || 'running',
createdAt: (sprite.createdAt as string) || '',
runtime: sprite.runtime as string | undefined,
metadata: sprite.metadata as Record<string, unknown> | undefined,
};
});
return {
sprites,
count: sprites.length,
};
},
});
export default spritesListTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,71 @@
{
"name": "@tpmjs/tools-sprites-policy-get",
"version": "0.1.1",
"description": "Retrieve the current network policy for a sprite including allowed domains",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"network",
"policy",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-policy-get"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesPolicyGetTool",
"description": "Retrieve the current network policy for a sprite including allowed domains",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to get policy for",
"required": true
}
],
"returns": {
"type": "NetworkPolicy",
"description": "Current network policy with allowed domains and rules"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,106 @@
/**
* Sprites Policy Get Tool for TPMJS
* Retrieves the current network policy for a sprite including allowed domains.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface NetworkPolicy {
mode: 'allow' | 'deny';
domains: string[];
rules?: Record<string, unknown>[];
}
type SpritesPolicyGetInput = {
name: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesPolicyGetTool = tool({
description:
'Retrieve the current network policy for a sprite including allowed domains and filtering rules. Use this to understand what network access a sprite has.',
inputSchema: jsonSchema<SpritesPolicyGetInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to get policy for',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<NetworkPolicy> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/policies`, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to get policy for sprite "${name}" timed out`);
}
throw new Error(`Failed to get policy for sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to get policy for sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to get policy for sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
return {
mode: (data.mode as NetworkPolicy['mode']) || 'deny',
domains: (data.domains as string[]) || (data.allowedDomains as string[]) || [],
rules: data.rules as Record<string, unknown>[] | undefined,
};
},
});
export default spritesPolicyGetTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,83 @@
{
"name": "@tpmjs/tools-sprites-policy-set",
"version": "0.1.1",
"description": "Update the network policy for a sprite to control outbound network access",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"network",
"policy",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-policy-set"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesPolicySetTool",
"description": "Update the network policy for a sprite to control outbound network access",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to update policy for",
"required": true
},
{
"name": "mode",
"type": "'allow' | 'deny'",
"description": "Policy mode",
"required": true
},
{
"name": "domains",
"type": "string[]",
"description": "List of domains to allow or deny",
"required": true
}
],
"returns": {
"type": "{ policy: NetworkPolicy, applied: boolean }",
"description": "Updated policy and application status"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,136 @@
/**
* Sprites Policy Set Tool for TPMJS
* Updates the network policy for a sprite to control outbound network access.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface NetworkPolicy {
mode: 'allow' | 'deny';
domains: string[];
rules?: Record<string, unknown>[];
}
export interface SpritesPolicySetResult {
policy: NetworkPolicy;
applied: boolean;
}
type SpritesPolicySetInput = {
name: string;
mode: 'allow' | 'deny';
domains: string[];
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesPolicySetTool = tool({
description:
"Update the network policy for a sprite to control outbound network access with DNS-based filtering. Use 'allow' mode to block all traffic except listed domains, or 'deny' mode to allow all traffic except listed domains.",
inputSchema: jsonSchema<SpritesPolicySetInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to update policy for',
},
mode: {
type: 'string',
enum: ['allow', 'deny'],
description:
"Policy mode - 'allow' blocks all except listed domains, 'deny' allows all except listed domains",
},
domains: {
type: 'array',
items: { type: 'string' },
description: 'List of domains to allow or deny based on mode',
},
},
required: ['name', 'mode', 'domains'],
additionalProperties: false,
}),
async execute({ name, mode, domains }): Promise<SpritesPolicySetResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
if (mode !== 'allow' && mode !== 'deny') {
throw new Error("Mode must be 'allow' or 'deny'");
}
if (!Array.isArray(domains)) {
throw new Error('Domains must be an array of strings');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/policies`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'User-Agent': 'TPMJS/1.0',
},
body: JSON.stringify({ mode, domains }),
signal: controller.signal,
});
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to set policy for sprite "${name}" timed out`);
}
throw new Error(`Failed to set policy for sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to set policy for sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to set policy for sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: Record<string, unknown>;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
// If no JSON response, assume policy was applied with our input
data = { mode, domains };
}
return {
policy: {
mode: (data.mode as NetworkPolicy['mode']) || mode,
domains: (data.domains as string[]) || domains,
rules: data.rules as Record<string, unknown>[] | undefined,
},
applied: true,
};
},
});
export default spritesPolicySetTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -0,0 +1,70 @@
{
"name": "@tpmjs/tools-sprites-sessions",
"version": "0.1.1",
"description": "List active execution sessions for a sprite",
"type": "module",
"keywords": [
"tpmjs",
"sprites",
"sandbox",
"code-execution",
"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"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/anthropics/tpmjs.git",
"directory": "packages/tools/official/sprites-sessions"
},
"homepage": "https://tpmjs.com",
"license": "MIT",
"tpmjs": {
"category": "sandbox",
"frameworks": [
"vercel-ai"
],
"tools": [
{
"name": "spritesSessionsTool",
"description": "List active execution sessions for a sprite",
"parameters": [
{
"name": "name",
"type": "string",
"description": "Name of the sprite to list sessions for",
"required": true
}
],
"returns": {
"type": "{ sessions: ExecSession[], count: number }",
"description": "Array of active execution sessions with count"
}
}
]
},
"dependencies": {
"ai": "6.0.23"
}
}

View file

@ -0,0 +1,125 @@
/**
* Sprites Sessions Tool for TPMJS
* Lists active execution sessions for a sprite.
*
* @requires SPRITES_TOKEN environment variable
*/
import { jsonSchema, tool } from 'ai';
const SPRITES_API_BASE = 'https://api.sprites.dev/v1';
export interface ExecSession {
id: string;
status: 'active' | 'completed' | 'terminated';
startedAt: string;
command?: string;
}
export interface SpritesSessionsResult {
sessions: ExecSession[];
count: number;
}
type SpritesSessionsInput = {
name: string;
};
function getSpritesToken(): string {
const token = process.env.SPRITES_TOKEN;
if (!token) {
throw new Error(
'SPRITES_TOKEN environment variable is required. Get your token from https://sprites.dev'
);
}
return token;
}
export const spritesSessionsTool = tool({
description:
'List active execution sessions for a sprite. Useful for monitoring running commands or attaching to existing sessions.',
inputSchema: jsonSchema<SpritesSessionsInput>({
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the sprite to list sessions for',
},
},
required: ['name'],
additionalProperties: false,
}),
async execute({ name }): Promise<SpritesSessionsResult> {
if (!name || typeof name !== 'string') {
throw new Error('Sprite name is required and must be a string');
}
const token = getSpritesToken();
let response: Response;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
response = await fetch(
`${SPRITES_API_BASE}/sprites/${encodeURIComponent(name)}/exec/sessions`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'User-Agent': 'TPMJS/1.0',
},
signal: controller.signal,
}
);
clearTimeout(timeoutId);
} catch (error) {
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw new Error(`Request to list sessions for sprite "${name}" timed out`);
}
throw new Error(`Failed to list sessions for sprite "${name}": ${error.message}`);
}
throw new Error(`Failed to list sessions for sprite "${name}": Unknown network error`);
}
if (!response.ok) {
if (response.status === 404) {
throw new Error(`Sprite "${name}" not found`);
}
if (response.status === 401) {
throw new Error('Invalid SPRITES_TOKEN. Check your API token at https://sprites.dev');
}
const errorText = await response.text().catch(() => 'Unknown error');
throw new Error(
`Failed to list sessions for sprite "${name}": HTTP ${response.status} - ${errorText}`
);
}
let data: unknown;
try {
data = (await response.json()) as Record<string, unknown>;
} catch {
throw new Error('Failed to parse response from Sprites API');
}
const sessionsArray = Array.isArray(data) ? data : (data as Record<string, unknown>).sessions;
const sessions: ExecSession[] = (Array.isArray(sessionsArray) ? sessionsArray : []).map(
(s: Record<string, unknown>) => ({
id: s.id as string,
status: (s.status as ExecSession['status']) || 'active',
startedAt: (s.startedAt as string) || (s.started_at as string) || '',
command: s.command as string | undefined,
})
);
return {
sessions,
count: sessions.length,
};
},
});
export default spritesSessionsTool;

View file

@ -0,0 +1,11 @@
{
"extends": "@tpmjs/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"incremental": false,
"composite": false
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View file

@ -0,0 +1,10 @@
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
dts: true,
clean: true,
treeshake: true,
splitting: false,
});

View file

@ -48,7 +48,7 @@
],
"tools": [
{
"exportName": "ticketCategorizeTool",
"name": "ticketCategorizeTool",
"description": "Categorizes support tickets by type, priority, and product area. Suggests routing based on category and identifies urgent issues requiring immediate attention.",
"parameters": [
{

View file

@ -42,7 +42,7 @@ Execute a tool from the TPMJS registry by its toolId.
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `toolId` | string | Yes | Tool identifier (format: `package::exportName`) |
| `toolId` | string | Yes | Tool identifier (format: `package::name`) |
| `params` | object | Yes | Parameters to pass to the tool |
| `env` | object | No | Environment variables (API keys) if required |

View file

@ -44,13 +44,13 @@
],
"tools": [
{
"exportName": "registryExecuteTool",
"name": "registryExecuteTool",
"description": "Execute a tool from the TPMJS registry by toolId. Use registrySearchTool first to find toolIds.",
"parameters": [
{
"name": "toolId",
"type": "string",
"description": "Tool identifier from registrySearchTool (format: 'package::exportName')",
"description": "Tool identifier from registrySearchTool (format: 'package::name')",
"required": true
},
{

View file

@ -44,7 +44,7 @@
],
"tools": [
{
"exportName": "registrySearchTool",
"name": "registrySearchTool",
"description": "Search the TPMJS tool registry to find AI SDK tools. Returns tool metadata including toolId for use with registryExecuteTool.",
"parameters": [
{
@ -68,7 +68,7 @@
],
"returns": {
"type": "object",
"description": "Search results with tool metadata including toolId, packageName, exportName, description, requiredEnvVars"
"description": "Search results with tool metadata including toolId, packageName, name, description, requiredEnvVars"
},
"aiAgent": {
"useCase": "Use when you need to find a tool for a specific task. Search returns toolIds that can be executed with registryExecuteTool.",

View file

@ -30,7 +30,7 @@
],
"tools": [
{
"exportName": "searchTpmjsToolsTool",
"name": "searchTpmjsToolsTool",
"description": "Search the TPMJS tool registry to find AI SDK tools by keyword, category, or description. Returns tool metadata for dynamic loading.",
"parameters": [
{
@ -54,7 +54,7 @@
],
"returns": {
"type": "object",
"description": "Search results with tool metadata including packageName, exportName, version, importUrl"
"description": "Search results with tool metadata including packageName, name, version, importUrl"
},
"aiAgent": {
"useCase": "Use when you need a tool that isn't currently available. Search for tools by keyword or domain.",

View file

@ -51,7 +51,7 @@
],
"tools": [
{
"exportName": "executeCode",
"name": "executeCode",
"description": "Execute code synchronously in a secure sandbox. Supports 42+ languages including Python, JavaScript, TypeScript, Go, Rust, and more.",
"parameters": [
{
@ -99,7 +99,7 @@
}
},
{
"exportName": "executeCodeAsync",
"name": "executeCodeAsync",
"description": "Execute code asynchronously in a secure sandbox. Returns a job_id immediately for tracking.",
"parameters": [
{
@ -128,7 +128,7 @@
}
},
{
"exportName": "runCode",
"name": "runCode",
"description": "Execute code with automatic language detection from shebang line (e.g., #!/usr/bin/env python3).",
"parameters": [
{
@ -151,7 +151,7 @@
}
},
{
"exportName": "runCodeAsync",
"name": "runCodeAsync",
"description": "Execute code asynchronously with automatic language detection from shebang.",
"parameters": [
{
@ -173,7 +173,7 @@
}
},
{
"exportName": "listJobs",
"name": "listJobs",
"description": "List all active jobs for your API key. Jobs are retained for 3 minutes after completion.",
"parameters": [],
"returns": {
@ -188,7 +188,7 @@
}
},
{
"exportName": "getJob",
"name": "getJob",
"description": "Get status and results of a specific async job.",
"parameters": [
{
@ -210,7 +210,7 @@
}
},
{
"exportName": "cancelJob",
"name": "cancelJob",
"description": "Cancel a running or pending async job.",
"parameters": [
{
@ -232,7 +232,7 @@
}
},
{
"exportName": "listLanguages",
"name": "listLanguages",
"description": "List all 42+ supported programming languages and their aliases.",
"parameters": [],
"returns": {

View file

@ -1,6 +1,6 @@
{
"name": "@tpmjs/types",
"version": "0.2.0",
"version": "0.2.1",
"description": "Shared TypeScript types and Zod schemas for TPMJS",
"author": "TPMJS",
"license": "MIT",

View file

@ -14,6 +14,7 @@ export const TPMJS_CATEGORIES = [
'statistics',
'ops',
'agent',
'sandbox',
'utilities',
'html',
'compliance',
@ -101,44 +102,23 @@ export type TpmjsAiAgent = z.infer<typeof TpmjsAiAgentSchema>;
* Optional fields (auto-extracted if not provided):
* - description: A description of what the tool does (20-500 chars) - auto-extracted from tool
*
* @deprecated fields (now auto-extracted, kept for backward compatibility):
* @deprecated fields (now auto-extracted):
* - parameters: Tool input parameters - auto-extracted from inputSchema
* - returns: Tool return type - auto-extracted from tool
* - aiAgent: AI agent guidance - auto-extracted from tool
* - exportName: Renamed to 'name' - kept for backward compatibility with published packages
*/
export const TpmjsToolDefinitionSchema = z
.object({
// Required: The export name of the tool from the package
// Accepts both 'name' and legacy 'exportName' field
name: z.string().min(1).optional(),
// @deprecated - renamed to 'name', kept for backward compatibility
exportName: z.string().min(1).optional(),
// Optional - auto-extracted from tool if not provided
description: z
.string()
.min(20, 'Description must be at least 20 characters')
.max(500)
.optional(),
// @deprecated - now auto-extracted from tool's inputSchema
parameters: z.array(TpmjsParameterSchema).optional(),
// @deprecated - now auto-extracted from tool
returns: TpmjsReturnsSchema.optional(),
// @deprecated - now auto-extracted from tool
aiAgent: TpmjsAiAgentSchema.optional(),
})
.transform((data) => ({
// Transform exportName to name for backward compatibility
name: data.name || data.exportName || '',
description: data.description,
parameters: data.parameters,
returns: data.returns,
aiAgent: data.aiAgent,
}))
.refine((data) => data.name.length > 0, {
message: 'Either name or exportName is required',
path: ['name'],
});
export const TpmjsToolDefinitionSchema = z.object({
// Required: The export name of the tool from the package
name: z.string().min(1, 'Tool name is required'),
// Optional - auto-extracted from tool if not provided
description: z.string().min(20, 'Description must be at least 20 characters').max(500).optional(),
// @deprecated - now auto-extracted from tool's inputSchema
parameters: z.array(TpmjsParameterSchema).optional(),
// @deprecated - now auto-extracted from tool
returns: TpmjsReturnsSchema.optional(),
// @deprecated - now auto-extracted from tool
aiAgent: TpmjsAiAgentSchema.optional(),
});
export type TpmjsToolDefinition = z.infer<typeof TpmjsToolDefinitionSchema>;