@agentforge-ai/cli 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: browser-automation
3
+ description: Built-in browser automation skill for AgentForge agents. Navigate web pages, interact with elements, extract content, and take screenshots using Playwright.
4
+ version: 1.0.0
5
+ tags:
6
+ - web
7
+ - browser
8
+ - automation
9
+ - scraping
10
+ ---
11
+
12
+ # Browser Automation
13
+
14
+ **Built-in AgentForge Skill** — Automate web browsers to navigate, interact, extract data, and capture screenshots.
15
+
16
+ ## Overview
17
+
18
+ The Browser Automation skill gives agents the ability to interact with web pages programmatically using Playwright. This is essential for:
19
+
20
+ 1. **Web scraping** — Extract text, data, and structured content from any website
21
+ 2. **Form filling** — Automate login flows, form submissions, and multi-step workflows
22
+ 3. **Visual verification** — Take screenshots for visual QA or documentation
23
+ 4. **Research** — Navigate and read web pages to gather information
24
+ 5. **Testing** — Verify web application behavior
25
+
26
+ ## Supported Actions
27
+
28
+ | Action | Description | Key Parameters |
29
+ |--------|-------------|----------------|
30
+ | `navigate` | Go to a URL | `url` (required) |
31
+ | `click` | Click an element | `selector` (CSS selector) |
32
+ | `type` | Type text into an input | `selector`, `text` |
33
+ | `screenshot` | Capture the page | `fullPage` (optional) |
34
+ | `snapshot` | Get accessibility tree | — |
35
+ | `extractText` | Extract page text | `selector` (optional) |
36
+ | `evaluate` | Run JavaScript | `js` (code string) |
37
+ | `wait` | Wait for element/time | `selector` or `timeMs` |
38
+ | `scroll` | Scroll the page | `direction`, `amount` |
39
+ | `select` | Select dropdown option | `selector`, `value` |
40
+ | `hover` | Hover over element | `selector` |
41
+ | `goBack` | Navigate back | — |
42
+ | `goForward` | Navigate forward | — |
43
+ | `reload` | Reload the page | — |
44
+ | `close` | Close the session | — |
45
+
46
+ ## How to Use
47
+
48
+ ### Setup
49
+
50
+ ```typescript
51
+ import { createBrowserTool, MCPServer } from '@agentforge-ai/core';
52
+
53
+ // Create browser tool with default config
54
+ const { tool, shutdown } = createBrowserTool({ headless: true });
55
+
56
+ // Register with MCP server
57
+ const server = new MCPServer({ name: 'my-tools' });
58
+ server.registerTool(tool);
59
+
60
+ // Or use the convenience function
61
+ import { registerBrowserTool } from '@agentforge-ai/core';
62
+ const { shutdown: cleanup } = registerBrowserTool(server, { headless: true });
63
+ ```
64
+
65
+ ### Docker Sandbox Mode
66
+
67
+ For secure, isolated browser execution (recommended for production):
68
+
69
+ ```typescript
70
+ const { tool, shutdown } = createBrowserTool({
71
+ sandboxMode: true,
72
+ headless: true,
73
+ });
74
+ ```
75
+
76
+ This launches the browser inside a Docker container with:
77
+ - Isolated network and filesystem
78
+ - 2GB shared memory for stability
79
+ - Automatic cleanup on shutdown
80
+
81
+ ### Direct Import
82
+
83
+ ```typescript
84
+ import { createBrowserTool } from '@agentforge-ai/core/browser';
85
+ ```
86
+
87
+ ## Agent Instructions
88
+
89
+ When a user asks you to interact with a web page:
90
+
91
+ 1. **Navigate** to the target URL first
92
+ 2. **Wait** for key elements to load before interacting
93
+ 3. Use **snapshot** to understand the page structure (accessibility tree)
94
+ 4. Use **extractText** to get readable content from the page
95
+ 5. Use **click** and **type** to interact with forms and buttons
96
+ 6. Use **screenshot** to capture visual state when needed
97
+ 7. Always **close** sessions when done to free resources
98
+
99
+ ### Tips for Reliable Automation
100
+
101
+ - Prefer `#id` selectors over class-based selectors
102
+ - Use `waitForSelector` before clicking or typing
103
+ - For SPAs, wait after navigation for content to render
104
+ - Use `extractText` with a selector to get specific section content
105
+ - Take screenshots before and after critical actions for verification
106
+
107
+ ## Configuration Options
108
+
109
+ | Option | Type | Default | Description |
110
+ |--------|------|---------|-------------|
111
+ | `headless` | boolean | `true` | Run browser without UI |
112
+ | `defaultTimeout` | number | `30000` | Navigation timeout (ms) |
113
+ | `browserType` | string | `'chromium'` | Browser engine |
114
+ | `viewportWidth` | number | `1280` | Viewport width |
115
+ | `viewportHeight` | number | `720` | Viewport height |
116
+ | `userAgent` | string | — | Custom user agent |
117
+ | `persistState` | boolean | `false` | Save cookies/state |
118
+ | `statePath` | string | — | Path for state file |
119
+ | `sandboxMode` | boolean | `false` | Docker isolation |
120
+ | `maxSessions` | number | `5` | Max concurrent sessions |
121
+
122
+ ## Session Management
123
+
124
+ Each session gets its own isolated browser context with separate cookies, storage, and state. Use `sessionId` to manage multiple concurrent browsing sessions:
125
+
126
+ ```typescript
127
+ // Session A: logged into site X
128
+ await tool.handler({ action: { kind: 'navigate', url: 'https://site-x.com' }, sessionId: 'session-a' });
129
+
130
+ // Session B: logged into site Y (completely isolated)
131
+ await tool.handler({ action: { kind: 'navigate', url: 'https://site-y.com' }, sessionId: 'session-b' });
132
+ ```
133
+
134
+ ## Prerequisites
135
+
136
+ - **Playwright**: `npm install playwright && npx playwright install chromium`
137
+ - **Docker** (optional): Required only for `sandboxMode`
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "browser-automation",
3
+ "version": "1.0.0",
4
+ "description": "Built-in browser automation skill for AgentForge agents. Navigate web pages, interact with elements, extract content, and take screenshots using Playwright.",
5
+ "category": "web",
6
+ "author": "AgentForge",
7
+ "isBuiltIn": true,
8
+ "tools": ["browser"],
9
+ "dependencies": ["playwright"],
10
+ "agentInstructions": "You have access to the Browser Automation tool. Use it to navigate web pages, click elements, type text, extract page content, take screenshots, and wait for elements. Each session has isolated cookies and state. Always close sessions when done."
11
+ }
@@ -0,0 +1,93 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * browser-automation — Built-in AgentForge Skill
5
+ *
6
+ * Provides browser automation capabilities for agents using Playwright.
7
+ * Supports navigation, interaction, text extraction, screenshots, and more.
8
+ *
9
+ * This skill wraps the @agentforge-ai/core browser tool for use in the
10
+ * skills system. For direct programmatic access, use:
11
+ *
12
+ * import { createBrowserTool } from '@agentforge-ai/core/browser';
13
+ */
14
+
15
+ export const tools = [
16
+ {
17
+ name: 'browser',
18
+ description:
19
+ 'Interact with web pages using browser automation. ' +
20
+ 'Supports: navigate, click, type, screenshot, snapshot (accessibility tree), ' +
21
+ 'evaluate JS, wait, scroll, select, hover, goBack, goForward, reload, close, extractText. ' +
22
+ 'Each session has isolated cookies and state.',
23
+ inputSchema: z.object({
24
+ action: z.discriminatedUnion('kind', [
25
+ z.object({ kind: z.literal('navigate'), url: z.string().url() }),
26
+ z.object({ kind: z.literal('click'), selector: z.string() }),
27
+ z.object({
28
+ kind: z.literal('type'),
29
+ selector: z.string(),
30
+ text: z.string(),
31
+ }),
32
+ z.object({
33
+ kind: z.literal('screenshot'),
34
+ fullPage: z.boolean().optional(),
35
+ }),
36
+ z.object({ kind: z.literal('snapshot') }),
37
+ z.object({ kind: z.literal('evaluate'), js: z.string() }),
38
+ z.object({
39
+ kind: z.literal('wait'),
40
+ selector: z.string().optional(),
41
+ timeMs: z.number().optional(),
42
+ }),
43
+ z.object({
44
+ kind: z.literal('scroll'),
45
+ direction: z.enum(['up', 'down']),
46
+ amount: z.number().optional(),
47
+ }),
48
+ z.object({
49
+ kind: z.literal('select'),
50
+ selector: z.string(),
51
+ value: z.string(),
52
+ }),
53
+ z.object({ kind: z.literal('hover'), selector: z.string() }),
54
+ z.object({ kind: z.literal('goBack') }),
55
+ z.object({ kind: z.literal('goForward') }),
56
+ z.object({ kind: z.literal('reload') }),
57
+ z.object({ kind: z.literal('close') }),
58
+ z.object({
59
+ kind: z.literal('extractText'),
60
+ selector: z.string().optional(),
61
+ }),
62
+ ]),
63
+ sessionId: z.string().optional(),
64
+ }),
65
+ outputSchema: z.object({
66
+ success: z.boolean(),
67
+ action: z.string(),
68
+ data: z.union([z.string(), z.record(z.unknown())]).optional(),
69
+ screenshot: z.string().optional(),
70
+ error: z.string().optional(),
71
+ currentUrl: z.string().optional(),
72
+ pageTitle: z.string().optional(),
73
+ latencyMs: z.number(),
74
+ }),
75
+ handler: async (input: {
76
+ action: { kind: string; [key: string]: unknown };
77
+ sessionId?: string;
78
+ }) => {
79
+ // Dynamic import to avoid requiring Playwright at skill load time
80
+ const { createBrowserTool } = await import('@agentforge-ai/core');
81
+ const { tool, shutdown } = createBrowserTool({ headless: true });
82
+
83
+ try {
84
+ const result = await tool.handler(input as any);
85
+ return result;
86
+ } finally {
87
+ await shutdown();
88
+ }
89
+ },
90
+ },
91
+ ];
92
+
93
+ export default { tools };
@@ -1,3 +1,13 @@
1
+ ---
2
+ name: skill-creator
3
+ description: Built-in skill for creating, managing, and discovering AgentForge skills. Allows agents to generate new skills from natural language descriptions.
4
+ version: 1.0.0
5
+ tags:
6
+ - utility
7
+ - meta
8
+ - creation
9
+ ---
10
+
1
11
  # Skill Creator
2
12
 
3
13
  **Built-in AgentForge Skill** — Create, manage, and discover skills for your agents.
@@ -7,264 +17,93 @@
7
17
  The Skill Creator is a default skill that ships with every AgentForge project. It allows you to:
8
18
 
9
19
  1. **Create new skills** from natural language descriptions
10
- 2. **Browse example skills** to understand the skill format
11
- 3. **Validate skills** before installing them
12
- 4. **Generate skill code** using your connected LLM
13
-
14
- ## Usage
15
-
16
- ### Via CLI
17
-
18
- ```bash
19
- # Create a new skill interactively
20
- agentforge skills create
21
-
22
- # Ask the agent to create a skill
23
- agentforge chat my-agent
24
- > Create a skill that can fetch weather data for any city
25
-
26
- # List available example skills
27
- agentforge skills search examples
28
- ```
29
-
30
- ### Via Dashboard
31
-
32
- Navigate to **Skills** in the sidebar, then click **"Create Skill"** to use the visual skill builder.
20
+ 2. **Browse available skills** in the AgentForge registry
21
+ 3. **Validate skills** to ensure they follow the Agent Skills Specification
33
22
 
34
- ### Via Agent Chat
23
+ ## How to Create a Skill
35
24
 
36
- When chatting with an agent that has the Skill Creator tool enabled, simply ask:
25
+ When a user asks you to create a skill:
37
26
 
38
- > "Create a skill that can [description of what you want]"
27
+ 1. Ask for the skill name (kebab-case), description, and tags
28
+ 2. Generate the SKILL.md with proper frontmatter and instructions
29
+ 3. Create supporting files in references/ and scripts/ directories
30
+ 4. Save to the workspace/skills/ directory
39
31
 
40
- The agent will generate the skill definition, validate it, and offer to install it.
32
+ ### Skill Structure
41
33
 
42
- ## Skill Format
43
-
44
- Every AgentForge skill is a directory with the following structure:
34
+ Every AgentForge skill follows the Agent Skills Specification:
45
35
 
46
36
  ```
47
37
  skills/
48
38
  my-skill/
49
- SKILL.md # Documentation and instructions
50
- index.ts # Main skill entry point
51
- config.json # Skill metadata and configuration
39
+ SKILL.md # Instructions and metadata (frontmatter)
40
+ references/ # Supporting documentation (optional)
41
+ scripts/ # Executable scripts (optional)
42
+ assets/ # Images and other files (optional)
52
43
  ```
53
44
 
54
- ### config.json
45
+ ### SKILL.md Format
55
46
 
56
- ```json
57
- {
58
- "name": "my-skill",
59
- "version": "1.0.0",
60
- "description": "What this skill does",
61
- "category": "utility",
62
- "author": "Your Name",
63
- "tools": ["tool-name-1", "tool-name-2"],
64
- "dependencies": [],
65
- "agentInstructions": "Additional instructions for agents using this skill"
66
- }
67
- ```
47
+ ```markdown
48
+ ---
49
+ name: my-skill
50
+ description: What this skill does
51
+ version: 1.0.0
52
+ tags:
53
+ - category1
54
+ - category2
55
+ ---
68
56
 
69
- ### index.ts
57
+ # My Skill
70
58
 
71
- ```typescript
72
- import { z } from 'zod';
59
+ Instructions for the agent on how to use this skill.
73
60
 
74
- export const tools = [
75
- {
76
- name: 'my-tool',
77
- description: 'What this tool does',
78
- inputSchema: z.object({
79
- param1: z.string().describe('Description of param1'),
80
- }),
81
- outputSchema: z.object({
82
- result: z.string(),
83
- }),
84
- handler: async (input: { param1: string }) => {
85
- // Your tool logic here
86
- return { result: `Processed: ${input.param1}` };
87
- },
88
- },
89
- ];
90
-
91
- export default { tools };
61
+ ## Steps
62
+ 1. Step one
63
+ 2. Step two
92
64
  ```
93
65
 
94
- ## Example Skills
95
-
96
- ### 1. Web Search Skill
66
+ ## CLI Commands
97
67
 
98
- ```typescript
99
- // skills/web-search/index.ts
100
- import { z } from 'zod';
101
-
102
- export const tools = [
103
- {
104
- name: 'web-search',
105
- description: 'Search the web for information',
106
- inputSchema: z.object({
107
- query: z.string().describe('Search query'),
108
- maxResults: z.number().optional().default(5),
109
- }),
110
- outputSchema: z.object({
111
- results: z.array(z.object({
112
- title: z.string(),
113
- url: z.string(),
114
- snippet: z.string(),
115
- })),
116
- }),
117
- handler: async (input) => {
118
- // Implement with your preferred search API
119
- const response = await fetch(
120
- `https://api.search.example/search?q=${encodeURIComponent(input.query)}&limit=${input.maxResults}`
121
- );
122
- const data = await response.json();
123
- return { results: data.results };
124
- },
125
- },
126
- ];
127
- ```
128
-
129
- ### 2. Calculator Skill
130
-
131
- ```typescript
132
- // skills/calculator/index.ts
133
- import { z } from 'zod';
134
-
135
- export const tools = [
136
- {
137
- name: 'calculate',
138
- description: 'Evaluate a mathematical expression',
139
- inputSchema: z.object({
140
- expression: z.string().describe('Math expression to evaluate (e.g., "2 + 2 * 3")'),
141
- }),
142
- outputSchema: z.object({
143
- result: z.number(),
144
- expression: z.string(),
145
- }),
146
- handler: async (input) => {
147
- const result = Function('"use strict"; return (' + input.expression + ')')();
148
- return { result: Number(result), expression: input.expression };
149
- },
150
- },
151
- ];
152
- ```
153
-
154
- ### 3. File Reader Skill
155
-
156
- ```typescript
157
- // skills/file-reader/index.ts
158
- import { z } from 'zod';
159
- import { readFile } from 'fs/promises';
160
-
161
- export const tools = [
162
- {
163
- name: 'read-file',
164
- description: 'Read the contents of a file',
165
- inputSchema: z.object({
166
- path: z.string().describe('Path to the file'),
167
- encoding: z.string().optional().default('utf-8'),
168
- }),
169
- outputSchema: z.object({
170
- content: z.string(),
171
- size: z.number(),
172
- }),
173
- handler: async (input) => {
174
- const content = await readFile(input.path, input.encoding as BufferEncoding);
175
- return { content, size: content.length };
176
- },
177
- },
178
- ];
179
- ```
68
+ ```bash
69
+ # Create a new skill interactively
70
+ agentforge skills create
180
71
 
181
- ### 4. JSON Transformer Skill
72
+ # Install a skill from the registry
73
+ agentforge skills install <name>
182
74
 
183
- ```typescript
184
- // skills/json-transformer/index.ts
185
- import { z } from 'zod';
75
+ # List installed skills
76
+ agentforge skills list
186
77
 
187
- export const tools = [
188
- {
189
- name: 'transform-json',
190
- description: 'Transform JSON data using a jq-like expression',
191
- inputSchema: z.object({
192
- data: z.string().describe('JSON string to transform'),
193
- path: z.string().describe('Dot-notation path to extract (e.g., "users.0.name")'),
194
- }),
195
- outputSchema: z.object({
196
- result: z.any(),
197
- }),
198
- handler: async (input) => {
199
- const obj = JSON.parse(input.data);
200
- const parts = input.path.split('.');
201
- let current: any = obj;
202
- for (const part of parts) {
203
- current = current?.[part] ?? current?.[Number(part)];
204
- }
205
- return { result: current };
206
- },
207
- },
208
- ];
209
- ```
78
+ # Browse the registry
79
+ agentforge skills list --registry
210
80
 
211
- ### 5. HTTP Request Skill
81
+ # Search for skills
82
+ agentforge skills search <query>
212
83
 
213
- ```typescript
214
- // skills/http-request/index.ts
215
- import { z } from 'zod';
84
+ # Get skill details
85
+ agentforge skills info <name>
216
86
 
217
- export const tools = [
218
- {
219
- name: 'http-request',
220
- description: 'Make an HTTP request to any URL',
221
- inputSchema: z.object({
222
- url: z.string().url().describe('URL to request'),
223
- method: z.enum(['GET', 'POST', 'PUT', 'DELETE']).default('GET'),
224
- headers: z.record(z.string()).optional(),
225
- body: z.string().optional(),
226
- }),
227
- outputSchema: z.object({
228
- status: z.number(),
229
- body: z.string(),
230
- headers: z.record(z.string()),
231
- }),
232
- handler: async (input) => {
233
- const response = await fetch(input.url, {
234
- method: input.method,
235
- headers: input.headers,
236
- body: input.body,
237
- });
238
- const body = await response.text();
239
- const headers: Record<string, string> = {};
240
- response.headers.forEach((v, k) => { headers[k] = v; });
241
- return { status: response.status, body, headers };
242
- },
243
- },
244
- ];
87
+ # Remove a skill
88
+ agentforge skills remove <name>
245
89
  ```
246
90
 
247
- ## Creating Skills with AI
248
-
249
- When you ask an agent to create a skill, the Skill Creator tool will:
250
-
251
- 1. **Parse your request** — Understand what the skill should do
252
- 2. **Generate the code** — Create `index.ts` with proper Zod schemas
253
- 3. **Create metadata** — Generate `config.json` with name, description, category
254
- 4. **Write documentation** — Generate `SKILL.md` with usage instructions
255
- 5. **Validate** — Ensure the skill compiles and schemas are correct
256
- 6. **Install** — Save to your `skills/` directory and register with Convex
257
-
258
91
  ## Categories
259
92
 
260
- Skills are organized by category:
93
+ Skills are organized by tags:
261
94
 
262
- | Category | Description | Examples |
263
- |----------|-------------|---------|
264
- | `utility` | General-purpose tools | Calculator, JSON transformer |
95
+ | Tag | Description | Examples |
96
+ |-----|-------------|---------|
265
97
  | `web` | Web interaction | HTTP requests, web search, scraping |
266
- | `file` | File operations | Read, write, transform files |
98
+ | `files` | File operations | Read, write, organize files |
267
99
  | `data` | Data processing | CSV parsing, data analysis |
268
- | `integration` | External services | Slack, GitHub, email |
269
- | `ai` | AI-powered tools | Summarization, translation |
270
- | `custom` | User-defined | Anything else |
100
+ | `development` | Dev tools | Code review, git workflow, linting |
101
+ | `api` | API interaction | REST testing, API integration |
102
+ | `utility` | General-purpose | Calculator, text processing |
103
+
104
+ ## Guidelines
105
+
106
+ - Skills are instruction-based — they teach agents HOW to do things
107
+ - The Mastra Workspace provides the tools (filesystem, sandbox, search)
108
+ - Skills provide the knowledge and procedures
109
+ - Follow the Agent Skills Specification for compatibility