design-learn-server 0.1.1
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/README.md +123 -0
- package/package.json +29 -0
- package/src/cli.js +152 -0
- package/src/mcp/index.js +556 -0
- package/src/pipeline/index.js +335 -0
- package/src/playwrightSupport.js +65 -0
- package/src/preview/index.js +204 -0
- package/src/server.js +1385 -0
- package/src/stdio.js +464 -0
- package/src/storage/fileStore.js +45 -0
- package/src/storage/index.js +983 -0
- package/src/storage/paths.js +113 -0
- package/src/storage/sqliteStore.js +114 -0
- package/src/uipro/bm25.js +121 -0
- package/src/uipro/config.js +264 -0
- package/src/uipro/csv.js +90 -0
- package/src/uipro/data/charts.csv +26 -0
- package/src/uipro/data/colors.csv +97 -0
- package/src/uipro/data/icons.csv +101 -0
- package/src/uipro/data/landing.csv +31 -0
- package/src/uipro/data/products.csv +97 -0
- package/src/uipro/data/prompts.csv +24 -0
- package/src/uipro/data/stacks/flutter.csv +53 -0
- package/src/uipro/data/stacks/html-tailwind.csv +56 -0
- package/src/uipro/data/stacks/nextjs.csv +53 -0
- package/src/uipro/data/stacks/nuxt-ui.csv +51 -0
- package/src/uipro/data/stacks/nuxtjs.csv +59 -0
- package/src/uipro/data/stacks/react-native.csv +52 -0
- package/src/uipro/data/stacks/react.csv +54 -0
- package/src/uipro/data/stacks/shadcn.csv +61 -0
- package/src/uipro/data/stacks/svelte.csv +54 -0
- package/src/uipro/data/stacks/swiftui.csv +51 -0
- package/src/uipro/data/stacks/vue.csv +50 -0
- package/src/uipro/data/styles.csv +59 -0
- package/src/uipro/data/typography.csv +58 -0
- package/src/uipro/data/ux-guidelines.csv +100 -0
- package/src/uipro/index.js +581 -0
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Design-Learn Server (Skeleton)
|
|
2
|
+
|
|
3
|
+
A minimal single-process server entry that registers REST, WebSocket, and MCP (SSE) routes.
|
|
4
|
+
|
|
5
|
+
## Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
node src/server.js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start (npx)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx design-learn-server --port 3000 --data-dir ./data
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## MCP stdio (npx)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx design-learn-server design-learn-mcp
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Optional flags:
|
|
24
|
+
- `--auth-token <token>` for MCP auth
|
|
25
|
+
- `--server-name <name>` / `--server-version <ver>`
|
|
26
|
+
- `--no-health-check` to disable startup health check
|
|
27
|
+
|
|
28
|
+
Optional port override:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
PORT=3000 node src/server.js
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Endpoints
|
|
35
|
+
|
|
36
|
+
- `GET /api/health` -> health check JSON
|
|
37
|
+
- `POST /api/import/browser` -> enqueue browser plugin import (alias: `/api/designs/import`)
|
|
38
|
+
- `POST /api/import/url` -> enqueue Playwright URL extraction
|
|
39
|
+
- `GET /api/import/jobs` -> list import jobs
|
|
40
|
+
- `GET /api/import/jobs/:id` -> fetch job status
|
|
41
|
+
- `GET /api/import/stream` -> SSE progress stream (optional `jobId=...`)
|
|
42
|
+
- `GET /api/designs` -> list designs
|
|
43
|
+
- `POST /api/designs` -> create design
|
|
44
|
+
- `GET /api/designs/:id` -> fetch design
|
|
45
|
+
- `PATCH /api/designs/:id` -> update design
|
|
46
|
+
- `DELETE /api/designs/:id` -> delete design
|
|
47
|
+
- `GET /api/snapshots` -> list snapshots
|
|
48
|
+
- `GET /api/snapshots/:id` -> fetch snapshot
|
|
49
|
+
- `POST /api/snapshots/import` -> enqueue snapshot import
|
|
50
|
+
- `GET /api/config` -> fetch config
|
|
51
|
+
- `PUT /api/config` -> update config
|
|
52
|
+
- `POST /api/previews` -> enqueue component preview
|
|
53
|
+
- `GET /api/previews/:componentId` -> fetch component preview
|
|
54
|
+
- `GET /api/previews/jobs` -> list preview jobs
|
|
55
|
+
- `GET /api/previews/jobs/:id` -> fetch preview job status
|
|
56
|
+
- `GET /mcp` / `POST /mcp` / `DELETE /mcp` -> MCP Streamable HTTP (SSE streaming)
|
|
57
|
+
- `WS /ws` -> WebSocket upgrade endpoint (handshake only)
|
|
58
|
+
|
|
59
|
+
## Extraction pipeline
|
|
60
|
+
|
|
61
|
+
### Browser plugin import
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
curl -X POST http://localhost:3000/api/import/browser \\
|
|
65
|
+
-H 'Content-Type: application/json' \\
|
|
66
|
+
-d '{\"source\":\"browser-extension\",\"website\":{\"url\":\"https://example.com\",\"title\":\"Example\"},\"snapshot\":{\"html\":\"<html></html>\",\"css\":\"body{}\"}}'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### URL extraction (Playwright)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
curl -X POST http://localhost:3000/api/import/url \\
|
|
73
|
+
-H 'Content-Type: application/json' \\
|
|
74
|
+
-d '{\"url\":\"https://example.com\"}'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If `playwright` or `scripts/lib/extractor.js` is missing, the job will fail with `playwright_not_installed` or `extractor_script_missing`.
|
|
78
|
+
|
|
79
|
+
### Progress stream
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
curl -N http://localhost:3000/api/import/stream
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Data storage
|
|
86
|
+
|
|
87
|
+
- SQLite metadata: `<dataDir>/database.sqlite`
|
|
88
|
+
- File storage: `<dataDir>/designs`
|
|
89
|
+
- `dataDir` defaults to `./data`, override with `DESIGN_LEARN_DATA_DIR` or `DATA_DIR` (supports `~` expansion)
|
|
90
|
+
|
|
91
|
+
## Search indexes
|
|
92
|
+
|
|
93
|
+
- Optional: set `DESIGN_LEARN_USE_INDEX=1` to read component/rule indexes.
|
|
94
|
+
- Rebuild indexes: `node scripts/rebuild-index.js`
|
|
95
|
+
|
|
96
|
+
## Migrations
|
|
97
|
+
|
|
98
|
+
- Schema version is tracked via SQLite `PRAGMA user_version` (current: 1).
|
|
99
|
+
- For breaking changes, back up `database.sqlite` and the `designs/` folder before upgrading.
|
|
100
|
+
|
|
101
|
+
## MCP auth & versioning
|
|
102
|
+
|
|
103
|
+
- Auth: set `MCP_AUTH_TOKEN` to require `Authorization: Bearer <token>` on MCP requests.
|
|
104
|
+
- Version: `MCP_SERVER_VERSION` controls the MCP server version advertised to clients (default `0.1.0`).
|
|
105
|
+
- Compatibility: prefer additive changes (new tools/resources/prompts) and keep existing contracts stable.
|
|
106
|
+
|
|
107
|
+
## Backend quick check
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
./scripts/verify-backend.sh
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## MCP quick check
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
node scripts/verify-mcp.js --url http://localhost:3000/mcp
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
With auth:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
node scripts/verify-mcp.js --url http://localhost:3000/mcp --auth-token YOUR_TOKEN
|
|
123
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "design-learn-server",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Design-Learn server skeleton for REST/WS/MCP routes",
|
|
6
|
+
"main": "src/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"design-learn-server": "src/cli.js",
|
|
9
|
+
"design-learn-mcp": "src/stdio.js",
|
|
10
|
+
"design-learn-stdio": "src/stdio.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"start": "node src/server.js",
|
|
21
|
+
"dev": "node src/server.js"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
25
|
+
"better-sqlite3": "^11.10.0",
|
|
26
|
+
"playwright": "^1.57.0",
|
|
27
|
+
"zod": "^3.24.1"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const http = require('http');
|
|
4
|
+
|
|
5
|
+
function printHelp() {
|
|
6
|
+
console.log(`Design-Learn MCP Server
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
design-learn-server [options]
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
--port <number> 服务端口(默认 3100)
|
|
13
|
+
--data-dir <path> 数据目录(默认 ./data)
|
|
14
|
+
--auth-token <token> MCP 鉴权令牌(可选)
|
|
15
|
+
--server-name <name> MCP Server Name(可选)
|
|
16
|
+
--server-version <ver> MCP Server Version(可选)
|
|
17
|
+
--health-check 启动后执行健康检查(默认开启)
|
|
18
|
+
--no-health-check 关闭健康检查
|
|
19
|
+
-h, --help 查看帮助
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseArgs(argv) {
|
|
24
|
+
const args = { healthCheck: true };
|
|
25
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
26
|
+
const arg = argv[i];
|
|
27
|
+
if (arg === '--port') {
|
|
28
|
+
args.port = Number(argv[i + 1]);
|
|
29
|
+
i += 1;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (arg === '--data-dir') {
|
|
33
|
+
args.dataDir = argv[i + 1];
|
|
34
|
+
i += 1;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (arg === '--auth-token') {
|
|
38
|
+
args.authToken = argv[i + 1];
|
|
39
|
+
i += 1;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (arg === '--server-name') {
|
|
43
|
+
args.serverName = argv[i + 1];
|
|
44
|
+
i += 1;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (arg === '--server-version') {
|
|
48
|
+
args.serverVersion = argv[i + 1];
|
|
49
|
+
i += 1;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (arg === '--health-check') {
|
|
53
|
+
args.healthCheck = true;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (arg === '--no-health-check') {
|
|
57
|
+
args.healthCheck = false;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (arg === '-h' || arg === '--help') {
|
|
61
|
+
args.help = true;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return args;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function applyEnv(options) {
|
|
69
|
+
if (options.port) {
|
|
70
|
+
process.env.PORT = String(options.port);
|
|
71
|
+
}
|
|
72
|
+
if (options.dataDir) {
|
|
73
|
+
process.env.DESIGN_LEARN_DATA_DIR = options.dataDir;
|
|
74
|
+
process.env.DATA_DIR = options.dataDir;
|
|
75
|
+
}
|
|
76
|
+
if (options.authToken) {
|
|
77
|
+
process.env.MCP_AUTH_TOKEN = options.authToken;
|
|
78
|
+
}
|
|
79
|
+
if (options.serverName) {
|
|
80
|
+
process.env.MCP_SERVER_NAME = options.serverName;
|
|
81
|
+
}
|
|
82
|
+
if (options.serverVersion) {
|
|
83
|
+
process.env.MCP_SERVER_VERSION = options.serverVersion;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sleep(ms) {
|
|
88
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function pingHealth(port) {
|
|
92
|
+
return new Promise((resolve) => {
|
|
93
|
+
const req = http.request(
|
|
94
|
+
{
|
|
95
|
+
hostname: '127.0.0.1',
|
|
96
|
+
port,
|
|
97
|
+
path: '/api/health',
|
|
98
|
+
method: 'GET',
|
|
99
|
+
timeout: 1200,
|
|
100
|
+
},
|
|
101
|
+
(res) => {
|
|
102
|
+
res.resume();
|
|
103
|
+
resolve(res.statusCode === 200);
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
req.on('error', () => resolve(false));
|
|
107
|
+
req.on('timeout', () => {
|
|
108
|
+
req.destroy();
|
|
109
|
+
resolve(false);
|
|
110
|
+
});
|
|
111
|
+
req.end();
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function waitForHealth(port, attempts = 5, delayMs = 300) {
|
|
116
|
+
for (let i = 0; i < attempts; i += 1) {
|
|
117
|
+
const ok = await pingHealth(port);
|
|
118
|
+
if (ok) return true;
|
|
119
|
+
await sleep(delayMs);
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function main() {
|
|
125
|
+
const args = parseArgs(process.argv.slice(2));
|
|
126
|
+
if (args.help) {
|
|
127
|
+
printHelp();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
applyEnv(args);
|
|
132
|
+
|
|
133
|
+
const port = Number(process.env.PORT || 3100);
|
|
134
|
+
require('./server');
|
|
135
|
+
|
|
136
|
+
console.log(`[design-learn-mcp] ready: http://localhost:${port}`);
|
|
137
|
+
console.log(`[design-learn-mcp] endpoints: /api/health /mcp /api/import/*`);
|
|
138
|
+
|
|
139
|
+
if (args.healthCheck) {
|
|
140
|
+
const ok = await waitForHealth(port);
|
|
141
|
+
if (ok) {
|
|
142
|
+
console.log('[design-learn-mcp] health check ok');
|
|
143
|
+
} else {
|
|
144
|
+
console.warn('[design-learn-mcp] health check failed');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main().catch((error) => {
|
|
150
|
+
console.error('[design-learn-mcp] failed to start', error);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|