wmcp-annotate 1.0.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.
- package/AGENTS.md +108 -0
- package/IMPLEMENTATION_PLAN.md +187 -0
- package/LAUNCH.md +217 -0
- package/PRD.md +199 -0
- package/PROMPT.md +62 -0
- package/README.md +140 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +46 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +24 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/suggest.d.ts +3 -0
- package/dist/commands/suggest.d.ts.map +1 -0
- package/dist/commands/suggest.js +36 -0
- package/dist/commands/suggest.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +39 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/analyzer.d.ts +10 -0
- package/dist/lib/analyzer.d.ts.map +1 -0
- package/dist/lib/analyzer.js +80 -0
- package/dist/lib/analyzer.js.map +1 -0
- package/dist/lib/generator.d.ts +12 -0
- package/dist/lib/generator.d.ts.map +1 -0
- package/dist/lib/generator.js +136 -0
- package/dist/lib/generator.js.map +1 -0
- package/dist/lib/output.d.ts +6 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +35 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/scanner.d.ts +19 -0
- package/dist/lib/scanner.d.ts.map +1 -0
- package/dist/lib/scanner.js +159 -0
- package/dist/lib/scanner.js.map +1 -0
- package/dist/lib/validator.d.ts +13 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +178 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/types.d.ts +109 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/docs/index.html +563 -0
- package/marketing/email-outreach.md +183 -0
- package/marketing/landing-page.md +165 -0
- package/marketing/social-posts.md +192 -0
- package/package.json +58 -0
- package/scripts/publish.sh +33 -0
- package/specs/generate-command.md +147 -0
- package/specs/scan-command.md +92 -0
- package/specs/suggest-command.md +120 -0
- package/specs/validate-command.md +108 -0
- package/src/commands/generate.ts +48 -0
- package/src/commands/scan.ts +28 -0
- package/src/commands/suggest.ts +39 -0
- package/src/commands/validate.ts +44 -0
- package/src/index.ts +51 -0
- package/src/lib/analyzer.ts +90 -0
- package/src/lib/generator.ts +149 -0
- package/src/lib/output.ts +40 -0
- package/src/lib/scanner.ts +185 -0
- package/src/lib/validator.ts +192 -0
- package/src/types.ts +124 -0
- package/tsconfig.json +20 -0
package/PROMPT.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# PROMPT.md - wmcp-annotate
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Build a production-ready CLI tool called `wmcp-annotate` that helps developers make their websites WebMCP-compatible.
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
WebMCP (Web Model Context Protocol) is a new W3C standard shipped in Chrome 146 (February 2026) by Google and Microsoft. It lets websites declare structured tools that AI agents can call directly.
|
|
8
|
+
|
|
9
|
+
**Problem:** 99% of websites don't have WebMCP annotations. Developers need tooling to adopt the standard quickly.
|
|
10
|
+
|
|
11
|
+
**Solution:** `wmcp-annotate` automates the process of scanning, suggesting, generating, and validating WebMCP tool definitions.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
Read these spec files for detailed requirements:
|
|
15
|
+
- `specs/scan-command.md` - Scan websites for actionable elements
|
|
16
|
+
- `specs/suggest-command.md` - AI-powered tool definition suggestions
|
|
17
|
+
- `specs/generate-command.md` - Generate JavaScript/TypeScript code
|
|
18
|
+
- `specs/validate-command.md` - Validate WebMCP compliance
|
|
19
|
+
|
|
20
|
+
## Current Task
|
|
21
|
+
Check `IMPLEMENTATION_PLAN.md` for the current task. Complete it, run tests, update the plan, and commit.
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
1. Follow the tech stack in AGENTS.md
|
|
25
|
+
2. Run backpressure commands after each task
|
|
26
|
+
3. Write tests before or with implementation
|
|
27
|
+
4. Keep code clean and well-documented
|
|
28
|
+
5. Commit after each completed task
|
|
29
|
+
6. Update IMPLEMENTATION_PLAN.md with progress
|
|
30
|
+
|
|
31
|
+
## WebMCP Reference
|
|
32
|
+
```javascript
|
|
33
|
+
// Declarative (HTML)
|
|
34
|
+
<form data-mcp-tool="searchProducts" data-mcp-description="Search products">
|
|
35
|
+
<input name="query" data-mcp-required />
|
|
36
|
+
</form>
|
|
37
|
+
|
|
38
|
+
// Imperative (JavaScript)
|
|
39
|
+
navigator.modelContext.registerTool({
|
|
40
|
+
name: "searchProducts",
|
|
41
|
+
description: "Search for products",
|
|
42
|
+
readOnly: true,
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
query: { type: "string" }
|
|
47
|
+
},
|
|
48
|
+
required: ["query"]
|
|
49
|
+
},
|
|
50
|
+
async execute({ query }) {
|
|
51
|
+
// Implementation
|
|
52
|
+
return { content: [{ type: "text", text: "results" }] };
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Success Criteria
|
|
58
|
+
- All 4 commands working (scan, suggest, generate, validate)
|
|
59
|
+
- Tests passing
|
|
60
|
+
- Published to npm as `wmcp-annotate`
|
|
61
|
+
- README with examples
|
|
62
|
+
- Working on real websites
|
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# wmcp-annotate
|
|
2
|
+
|
|
3
|
+
> Make any website AI-agent ready in 5 minutes
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/wmcp-annotate)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**wmcp-annotate** automatically analyzes websites and generates [WebMCP](https://webmcp.link) tool annotations, enabling AI agents to interact with any web application through the new W3C standard.
|
|
9
|
+
|
|
10
|
+
## Why?
|
|
11
|
+
|
|
12
|
+
Google and Microsoft shipped [WebMCP in Chrome 146](https://webmcp.link) (February 2026). This W3C standard lets websites declare structured tools that AI agents can call directly—no DOM scraping, 89% token reduction vs screenshots.
|
|
13
|
+
|
|
14
|
+
**The problem:** 99% of websites don't have WebMCP annotations yet.
|
|
15
|
+
|
|
16
|
+
**The solution:** `wmcp-annotate` automates the entire process.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Install
|
|
22
|
+
npm install -g wmcp-annotate
|
|
23
|
+
|
|
24
|
+
# Scan a website
|
|
25
|
+
wmcp-annotate scan https://your-site.com
|
|
26
|
+
|
|
27
|
+
# Get AI-powered tool suggestions
|
|
28
|
+
wmcp-annotate suggest https://your-site.com
|
|
29
|
+
|
|
30
|
+
# Generate ready-to-use code
|
|
31
|
+
wmcp-annotate generate https://your-site.com --format typescript
|
|
32
|
+
|
|
33
|
+
# Validate your implementation
|
|
34
|
+
wmcp-annotate validate https://your-site.com
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Commands
|
|
38
|
+
|
|
39
|
+
### `scan` - Analyze a website
|
|
40
|
+
|
|
41
|
+
Identifies forms, buttons, links, and API calls that could become WebMCP tools.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
wmcp-annotate scan https://example.com
|
|
45
|
+
wmcp-annotate scan https://example.com --depth 3 --output scan.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `suggest` - Get tool definitions
|
|
49
|
+
|
|
50
|
+
AI-powered analysis to generate WebMCP tool definitions.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
wmcp-annotate suggest https://example.com
|
|
54
|
+
wmcp-annotate suggest --scan-file scan.json --output suggestions.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `generate` - Create implementation code
|
|
58
|
+
|
|
59
|
+
Outputs ready-to-use JavaScript/TypeScript code.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
wmcp-annotate generate https://example.com --format js
|
|
63
|
+
wmcp-annotate generate https://example.com --format typescript
|
|
64
|
+
wmcp-annotate generate https://example.com --format react
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Output example:**
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
navigator.modelContext.registerTool({
|
|
71
|
+
name: "searchProducts",
|
|
72
|
+
description: "Search for products by keyword",
|
|
73
|
+
readOnly: true,
|
|
74
|
+
inputSchema: {
|
|
75
|
+
type: "object",
|
|
76
|
+
properties: {
|
|
77
|
+
query: { type: "string", description: "Search keywords" }
|
|
78
|
+
},
|
|
79
|
+
required: ["query"]
|
|
80
|
+
},
|
|
81
|
+
async execute({ query }) {
|
|
82
|
+
// Auto-generated implementation
|
|
83
|
+
const form = document.querySelector('#search-form');
|
|
84
|
+
form.querySelector('input[name="query"]').value = query;
|
|
85
|
+
form.submit();
|
|
86
|
+
// ...
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `validate` - Check compliance
|
|
92
|
+
|
|
93
|
+
Validates your WebMCP implementation against the W3C spec.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
wmcp-annotate validate https://example.com
|
|
97
|
+
wmcp-annotate validate https://example.com --strict --ci
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**CI Integration:**
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
# .github/workflows/webmcp.yml
|
|
104
|
+
- name: Validate WebMCP
|
|
105
|
+
run: npx wmcp-annotate validate ${{ env.DEPLOY_URL }} --ci
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Pricing
|
|
109
|
+
|
|
110
|
+
| Plan | Price | Features |
|
|
111
|
+
|------|-------|----------|
|
|
112
|
+
| **Open Source** | Free | Scan, generate, validate. 10 AI suggestions/day |
|
|
113
|
+
| **Pro** | $49/mo | Unlimited AI, inject command, CI integration |
|
|
114
|
+
| **Enterprise** | $499/mo | Team workspaces, SSO, audit logs, priority support |
|
|
115
|
+
|
|
116
|
+
## Enterprise
|
|
117
|
+
|
|
118
|
+
For enterprise licensing, custom integrations, or implementation support:
|
|
119
|
+
|
|
120
|
+
📧 [enterprise@avatarconsulting.com](mailto:enterprise@avatarconsulting.com)
|
|
121
|
+
|
|
122
|
+
## Why wmcp-annotate?
|
|
123
|
+
|
|
124
|
+
- **First mover**: Built for the WebMCP standard from day one
|
|
125
|
+
- **AI-powered**: Smart tool suggestions, not just DOM parsing
|
|
126
|
+
- **Framework support**: React, Vue, Svelte, vanilla JS
|
|
127
|
+
- **CI-ready**: GitHub Actions integration out of the box
|
|
128
|
+
- **Enterprise-grade**: Audit logs, SSO, team workspaces
|
|
129
|
+
|
|
130
|
+
## Contributing
|
|
131
|
+
|
|
132
|
+
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT © [Avatar Consulting](https://avatarconsulting.com)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
Built with ❤️ by [Avatar Consulting](https://avatarconsulting.com) — AI Transformation for Financial Services
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,aAAa,CAAC;AAQlE,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCtG"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { generator } from '../lib/generator.js';
|
|
2
|
+
import { analyzer } from '../lib/analyzer.js';
|
|
3
|
+
import { scanner } from '../lib/scanner.js';
|
|
4
|
+
import { readInput } from '../lib/output.js';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
export async function generateCommand(url, options) {
|
|
8
|
+
const spinner = ora('Generating...').start();
|
|
9
|
+
try {
|
|
10
|
+
// Get suggestions (from file or live analysis)
|
|
11
|
+
let suggestions;
|
|
12
|
+
if (options.suggestFile) {
|
|
13
|
+
spinner.text = 'Loading suggestions file...';
|
|
14
|
+
suggestions = await readInput(options.suggestFile);
|
|
15
|
+
}
|
|
16
|
+
else if (url) {
|
|
17
|
+
spinner.text = `Scanning ${url}...`;
|
|
18
|
+
const scanResult = await scanner.scan(url, { depth: 1 });
|
|
19
|
+
spinner.text = 'Generating tool suggestions...';
|
|
20
|
+
suggestions = await analyzer.suggest(scanResult);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw new Error('Either URL or --suggest-file is required');
|
|
24
|
+
}
|
|
25
|
+
spinner.text = `Generating ${options.format.toUpperCase()} code...`;
|
|
26
|
+
const code = await generator.generate(suggestions, {
|
|
27
|
+
format: options.format,
|
|
28
|
+
module: options.module,
|
|
29
|
+
});
|
|
30
|
+
spinner.succeed(`Generated code for ${suggestions.tools.length} tools`);
|
|
31
|
+
if (options.output) {
|
|
32
|
+
const fs = await import('fs/promises');
|
|
33
|
+
await fs.writeFile(options.output, code, 'utf-8');
|
|
34
|
+
console.log(chalk.green(`\\nSaved to ${options.output}`));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log('\\n' + code);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
spinner.fail('Generation failed');
|
|
42
|
+
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAuB,EAAE,OAAwB;IACrF,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,CAAC;IAE7C,IAAI,CAAC;QACH,+CAA+C;QAC/C,IAAI,WAA0B,CAAC;QAC/B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,GAAG,6BAA6B,CAAC;YAC7C,WAAW,GAAG,MAAM,SAAS,CAAgB,OAAO,CAAC,WAAW,CAAC,CAAC;QACpE,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,KAAK,CAAC;YACpC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAEzD,OAAO,CAAC,IAAI,GAAG,gCAAgC,CAAC;YAChD,WAAW,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,cAAc,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE;YACjD,MAAM,EAAE,OAAO,CAAC,MAAuC;YACvD,MAAM,EAAE,OAAO,CAAC,MAAuB;SACxC,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,CAAC,sBAAsB,WAAW,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;QAExE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACvC,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAM3D,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { scanner } from '../lib/scanner.js';
|
|
2
|
+
import { writeOutput } from '../lib/output.js';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export async function scanCommand(url, options) {
|
|
6
|
+
const spinner = ora(`Scanning ${url}...`).start();
|
|
7
|
+
try {
|
|
8
|
+
const result = await scanner.scan(url, {
|
|
9
|
+
depth: parseInt(options.depth, 10),
|
|
10
|
+
verbose: options.verbose,
|
|
11
|
+
});
|
|
12
|
+
spinner.succeed(`Found ${result.elements.length} elements and ${result.apiCalls.length} API calls`);
|
|
13
|
+
await writeOutput(result, options);
|
|
14
|
+
if (!options.output) {
|
|
15
|
+
console.log(chalk.dim('\\nUse --output to save results to a file'));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
spinner.fail('Scan failed');
|
|
20
|
+
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,OAAoB;IACjE,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAElD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YACrC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,QAAQ,CAAC,MAAM,iBAAiB,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY,CAAC,CAAC;QAEpG,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../src/commands/suggest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA6B,MAAM,aAAa,CAAC;AAO7E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BpG"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { analyzer } from '../lib/analyzer.js';
|
|
2
|
+
import { scanner } from '../lib/scanner.js';
|
|
3
|
+
import { writeOutput, readInput } from '../lib/output.js';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
export async function suggestCommand(url, options) {
|
|
7
|
+
const spinner = ora('Analyzing...').start();
|
|
8
|
+
try {
|
|
9
|
+
// Get scan results (from file or live scan)
|
|
10
|
+
let scanResult;
|
|
11
|
+
if (options.scanFile) {
|
|
12
|
+
spinner.text = 'Loading scan file...';
|
|
13
|
+
scanResult = await readInput(options.scanFile);
|
|
14
|
+
}
|
|
15
|
+
else if (url) {
|
|
16
|
+
spinner.text = `Scanning ${url}...`;
|
|
17
|
+
scanResult = await scanner.scan(url, { depth: 1 });
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
throw new Error('Either URL or --scan-file is required');
|
|
21
|
+
}
|
|
22
|
+
spinner.text = 'Generating tool suggestions with AI...';
|
|
23
|
+
const result = await analyzer.suggest(scanResult);
|
|
24
|
+
spinner.succeed(`Generated ${result.tools.length} tool suggestions`);
|
|
25
|
+
await writeOutput(result, options);
|
|
26
|
+
if (!options.output) {
|
|
27
|
+
console.log(chalk.dim('\\nUse --output to save results to a file'));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
spinner.fail('Suggestion failed');
|
|
32
|
+
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest.js","sourceRoot":"","sources":["../../src/commands/suggest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAuB,EAAE,OAAuB;IACnF,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5C,IAAI,CAAC;QACH,4CAA4C;QAC5C,IAAI,UAAsB,CAAC;QAC3B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,GAAG,sBAAsB,CAAC;YACtC,UAAU,GAAG,MAAM,SAAS,CAAa,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,GAAG,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,GAAG,YAAY,GAAG,KAAK,CAAC;YACpC,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,wCAAwC,CAAC;QACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAElD,OAAO,CAAC,OAAO,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAC;QAErE,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAMrE,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC1F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { validator } from '../lib/validator.js';
|
|
2
|
+
import { writeOutput } from '../lib/output.js';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export async function validateCommand(url, options) {
|
|
6
|
+
const spinner = ora(`Validating ${url}...`).start();
|
|
7
|
+
try {
|
|
8
|
+
const result = await validator.validate(url);
|
|
9
|
+
const { summary } = result;
|
|
10
|
+
if (summary.errors > 0) {
|
|
11
|
+
spinner.fail(`Validation failed: ${summary.errors} errors, ${summary.warnings} warnings`);
|
|
12
|
+
}
|
|
13
|
+
else if (summary.warnings > 0) {
|
|
14
|
+
spinner.warn(`Validation passed with ${summary.warnings} warnings`);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
spinner.succeed(`Validation passed: ${summary.total} tools validated`);
|
|
18
|
+
}
|
|
19
|
+
await writeOutput(result, options);
|
|
20
|
+
// Handle CI mode
|
|
21
|
+
if (options.ci) {
|
|
22
|
+
if (summary.errors > 0 || (options.strict && summary.warnings > 0)) {
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Print summary
|
|
27
|
+
console.log('\\n' + chalk.bold('Summary:'));
|
|
28
|
+
console.log(` Total tools: ${summary.total}`);
|
|
29
|
+
console.log(` Valid: ${chalk.green(summary.valid)}`);
|
|
30
|
+
console.log(` Warnings: ${chalk.yellow(summary.warnings)}`);
|
|
31
|
+
console.log(` Errors: ${chalk.red(summary.errors)}`);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
spinner.fail('Validation failed');
|
|
35
|
+
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,OAAwB;IACzE,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,GAAG,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAE3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,MAAM,YAAY,OAAO,CAAC,QAAQ,WAAW,CAAC,CAAC;QAC5F,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,0BAA0B,OAAO,CAAC,QAAQ,WAAW,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,OAAO,CAAC,sBAAsB,OAAO,CAAC,KAAK,kBAAkB,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEnC,iBAAiB;QACjB,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;gBACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAExD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { scanCommand } from './commands/scan.js';
|
|
4
|
+
import { suggestCommand } from './commands/suggest.js';
|
|
5
|
+
import { generateCommand } from './commands/generate.js';
|
|
6
|
+
import { validateCommand } from './commands/validate.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('wmcp-annotate')
|
|
10
|
+
.description('Make any website AI-agent ready with WebMCP annotations')
|
|
11
|
+
.version('1.0.0');
|
|
12
|
+
program
|
|
13
|
+
.command('scan <url>')
|
|
14
|
+
.description('Analyze a website for WebMCP opportunities')
|
|
15
|
+
.option('-d, --depth <number>', 'How many pages deep to crawl', '1')
|
|
16
|
+
.option('-o, --output <file>', 'Output file')
|
|
17
|
+
.option('-f, --format <format>', 'Output format: json, table, markdown', 'json')
|
|
18
|
+
.option('-v, --verbose', 'Show detailed progress')
|
|
19
|
+
.action(scanCommand);
|
|
20
|
+
program
|
|
21
|
+
.command('suggest [url]')
|
|
22
|
+
.description('Generate AI-powered WebMCP tool suggestions')
|
|
23
|
+
.option('-s, --scan-file <file>', 'Use existing scan output')
|
|
24
|
+
.option('-o, --output <file>', 'Output file')
|
|
25
|
+
.option('-f, --format <format>', 'Output format: json, yaml', 'json')
|
|
26
|
+
.action(suggestCommand);
|
|
27
|
+
program
|
|
28
|
+
.command('generate [url]')
|
|
29
|
+
.description('Generate WebMCP registration code')
|
|
30
|
+
.option('-s, --suggest-file <file>', 'Use existing suggestions')
|
|
31
|
+
.option('-o, --output <file>', 'Output file')
|
|
32
|
+
.option('-f, --format <format>', 'Output format: js, ts, react, vue', 'js')
|
|
33
|
+
.option('-m, --module <type>', 'Module format: esm, cjs', 'esm')
|
|
34
|
+
.action(generateCommand);
|
|
35
|
+
program
|
|
36
|
+
.command('validate <url>')
|
|
37
|
+
.description('Validate WebMCP implementation')
|
|
38
|
+
.option('-o, --output <file>', 'Output file')
|
|
39
|
+
.option('-f, --format <format>', 'Output format: json, table, markdown', 'json')
|
|
40
|
+
.option('--strict', 'Fail on warnings')
|
|
41
|
+
.option('--ci', 'Exit code 1 on any issues')
|
|
42
|
+
.action(validateCommand);
|
|
43
|
+
program.parse();
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,EAAE,GAAG,CAAC;KACnE,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,uBAAuB,EAAE,sCAAsC,EAAE,MAAM,CAAC;KAC/E,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC;KACjD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,wBAAwB,EAAE,0BAA0B,CAAC;KAC5D,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,CAAC;KACpE,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,2BAA2B,EAAE,0BAA0B,CAAC;KAC/D,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,uBAAuB,EAAE,mCAAmC,EAAE,IAAI,CAAC;KAC1E,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,EAAE,KAAK,CAAC;KAC/D,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,uBAAuB,EAAE,sCAAsC,EAAE,MAAM,CAAC;KAC/E,MAAM,CAAC,UAAU,EAAE,kBAAkB,CAAC;KACtC,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC;KAC3C,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ScanResult, SuggestResult } from '../types.js';
|
|
2
|
+
declare class Analyzer {
|
|
3
|
+
private client;
|
|
4
|
+
private getClient;
|
|
5
|
+
suggest(scanResult: ScanResult): Promise<SuggestResult>;
|
|
6
|
+
private analyzeElement;
|
|
7
|
+
}
|
|
8
|
+
export declare const analyzer: Analyzer;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/lib/analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAA8B,MAAM,aAAa,CAAC;AAEzF,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAA0B;IAExC,OAAO,CAAC,SAAS;IAWX,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;YAkB/C,cAAc;CAoD7B;AAED,eAAO,MAAM,QAAQ,UAAiB,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
class Analyzer {
|
|
3
|
+
client = null;
|
|
4
|
+
getClient() {
|
|
5
|
+
if (!this.client) {
|
|
6
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error('ANTHROPIC_API_KEY environment variable is required');
|
|
9
|
+
}
|
|
10
|
+
this.client = new Anthropic({ apiKey });
|
|
11
|
+
}
|
|
12
|
+
return this.client;
|
|
13
|
+
}
|
|
14
|
+
async suggest(scanResult) {
|
|
15
|
+
const tools = [];
|
|
16
|
+
for (const element of scanResult.elements) {
|
|
17
|
+
const suggestion = await this.analyzeElement(element);
|
|
18
|
+
if (suggestion) {
|
|
19
|
+
tools.push(suggestion);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
version: '1.0.0',
|
|
24
|
+
url: scanResult.url,
|
|
25
|
+
suggestedAt: new Date().toISOString(),
|
|
26
|
+
tools,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async analyzeElement(element) {
|
|
30
|
+
const client = this.getClient();
|
|
31
|
+
const prompt = `Analyze this website element and generate a WebMCP tool definition.
|
|
32
|
+
|
|
33
|
+
Element:
|
|
34
|
+
- Type: ${element.type}
|
|
35
|
+
- Label: ${element.label}
|
|
36
|
+
- Selector: ${element.selector}
|
|
37
|
+
${element.inputs ? `- Inputs: ${JSON.stringify(element.inputs)}` : ''}
|
|
38
|
+
|
|
39
|
+
Generate a WebMCP tool definition with:
|
|
40
|
+
1. name: camelCase, action-oriented verb (e.g., searchProducts, addToCart)
|
|
41
|
+
2. description: 1-2 sentences explaining what it does
|
|
42
|
+
3. readOnly: true if it's a search/view action, false for create/update/delete
|
|
43
|
+
4. inputSchema: JSON Schema for the inputs
|
|
44
|
+
|
|
45
|
+
Respond with valid JSON only:
|
|
46
|
+
{
|
|
47
|
+
"name": "...",
|
|
48
|
+
"description": "...",
|
|
49
|
+
"readOnly": true/false,
|
|
50
|
+
"inputSchema": { ... }
|
|
51
|
+
}`;
|
|
52
|
+
try {
|
|
53
|
+
const response = await client.messages.create({
|
|
54
|
+
model: 'claude-sonnet-4-20250514',
|
|
55
|
+
max_tokens: 1024,
|
|
56
|
+
messages: [{ role: 'user', content: prompt }],
|
|
57
|
+
});
|
|
58
|
+
const content = response.content[0];
|
|
59
|
+
if (content.type !== 'text')
|
|
60
|
+
return null;
|
|
61
|
+
const json = JSON.parse(content.text);
|
|
62
|
+
return {
|
|
63
|
+
name: json.name,
|
|
64
|
+
description: json.description,
|
|
65
|
+
readOnly: json.readOnly,
|
|
66
|
+
inputSchema: json.inputSchema,
|
|
67
|
+
sourceElement: {
|
|
68
|
+
type: element.type,
|
|
69
|
+
selector: element.selector,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error('Analysis failed for element:', element.selector, error);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export const analyzer = new Analyzer();
|
|
80
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/lib/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAG1C,MAAM,QAAQ;IACJ,MAAM,GAAqB,IAAI,CAAC;IAEhC,SAAS;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;YAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAsB;QAClC,MAAM,KAAK,GAAqB,EAAE,CAAC;QAEnC,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,OAAO;YAChB,GAAG,EAAE,UAAU,CAAC,GAAG;YACnB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACrC,KAAK;SACN,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,OAAY;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAEhC,MAAM,MAAM,GAAG;;;UAGT,OAAO,CAAC,IAAI;WACX,OAAO,CAAC,KAAK;cACV,OAAO,CAAC,QAAQ;EAC5B,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;EAcnE,CAAC;QAEC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC5C,KAAK,EAAE,0BAA0B;gBACjC,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;YAEzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAEtC,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,aAAa,EAAE;oBACb,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;iBAC3B;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SuggestResult } from '../types.js';
|
|
2
|
+
interface GenerateOptions {
|
|
3
|
+
format: 'js' | 'ts' | 'react' | 'vue';
|
|
4
|
+
module: 'esm' | 'cjs';
|
|
5
|
+
}
|
|
6
|
+
declare class Generator {
|
|
7
|
+
generate(suggestions: SuggestResult, options: GenerateOptions): Promise<string>;
|
|
8
|
+
private prepareToolData;
|
|
9
|
+
}
|
|
10
|
+
export declare const generator: Generator;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/lib/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAGjE,UAAU,eAAe;IACvB,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;CACvB;AAwGD,cAAM,SAAS;IACP,QAAQ,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBrF,OAAO,CAAC,eAAe;CAexB;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|