@spark-apps/quickpeek 1.1.2 → 1.2.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/mcp.mjs ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+
3
+ // QuickPeek MCP server — demo-video generation over stdio.
4
+ //
5
+ // .mjs, not .js: this package is CommonJS (the CLI bundle is CJS), so a
6
+ // plain .js here would be parsed as CommonJS and its imports would fail.
7
+ //
8
+ // A thin bootstrap: transport wiring, the protocol-stdout proxy, and
9
+ // dispatch. Tool schemas and handlers live in src/mcp/ (bundled by tsup
10
+ // into dist/mcp-tools.mjs), calling the command functions directly rather
11
+ // than shelling out to the `qp` CLI.
12
+ //
13
+ // Deliberately NO delete tools: outputs are new files and the server never
14
+ // removes anything a user recorded.
15
+
16
+ import { readFileSync } from 'node:fs';
17
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
18
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
19
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
20
+ import { TOOL_HANDLERS, TOOLS } from './dist/mcp-tools.mjs';
21
+
22
+ const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'));
23
+
24
+ // Captured once, before anything ever patches process.stdout.write
25
+ // (withSilencedStdout in dist/mcp-tools.mjs mutates it during tool calls).
26
+ const REAL_STDOUT_WRITE = process.stdout.write.bind(process.stdout);
27
+
28
+ // The transport resolves `.write` dynamically off whatever stdout object it
29
+ // is handed — the SAME property withSilencedStdout mutates. Recording a
30
+ // demo takes minutes and prints throughout, so a silenced call would
31
+ // otherwise swallow or misdirect unrelated protocol responses. This proxy
32
+ // always uses the pristine write captured above.
33
+ const protocolStdout = new Proxy(process.stdout, {
34
+ get(target, prop, receiver) {
35
+ if (prop === 'write') return REAL_STDOUT_WRITE;
36
+ const value = Reflect.get(target, prop, receiver);
37
+ return typeof value === 'function' ? value.bind(target) : value;
38
+ },
39
+ });
40
+
41
+ const server = new Server(
42
+ { name: 'quickpeek', version: pkg.version },
43
+ { capabilities: { tools: {} } }
44
+ );
45
+
46
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
47
+
48
+ function toErrorResult(e) {
49
+ return {
50
+ content: [{ type: 'text', text: e?.message ?? String(e) }],
51
+ isError: true,
52
+ };
53
+ }
54
+
55
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
56
+ const { name, arguments: args } = request.params;
57
+ const handler = TOOL_HANDLERS[name];
58
+ if (!handler) return toErrorResult(new Error(`Unknown tool: ${name}`));
59
+ try {
60
+ return await handler(args ?? {});
61
+ } catch (e) {
62
+ // Never crash the server on a tool failure — surface it as a tool error.
63
+ return toErrorResult(e);
64
+ }
65
+ });
66
+
67
+ async function main() {
68
+ const transport = new StdioServerTransport(process.stdin, protocolStdout);
69
+ await server.connect(transport);
70
+ }
71
+
72
+ main().catch((e) => {
73
+ console.error(`quickpeek-mcp failed to start: ${e?.message ?? e}`);
74
+ process.exit(1);
75
+ });
package/package.json CHANGED
@@ -1,64 +1,80 @@
1
- {
2
- "name": "@spark-apps/quickpeek",
3
- "version": "1.1.2",
4
- "description": "Auto-generate demo videos for your web app with AI",
5
- "main": "dist/qp.js",
6
- "bin": {
7
- "quickpeek": "dist/qp.js",
8
- "qp": "dist/qp.js"
9
- },
10
- "files": [
11
- "dist",
12
- "README.md"
13
- ],
14
- "scripts": {
15
- "dev": "npx tsx src/qp.ts",
16
- "build": "tsup",
17
- "build:tsc": "tsc --noEmit",
18
- "lint": "biome check src",
19
- "lint:fix": "biome check --write src",
20
- "format": "biome format --write src",
21
- "test": "vitest run",
22
- "clean": "rm -rf dist",
23
- "publish:cli": "npm publish --access public"
24
- },
25
- "keywords": [
26
- "demo",
27
- "video",
28
- "screen-recording",
29
- "playwright",
30
- "ai",
31
- "tts",
32
- "voiceover",
33
- "automation",
34
- "cli",
35
- "documentation"
36
- ],
37
- "license": "MIT",
38
- "dependencies": {
39
- "chalk": "^5.6.2",
40
- "dotenv": "^17.3.1",
41
- "figlet": "^1.11.0",
42
- "gradient-string": "^3.0.0",
43
- "msedge-tts": "^2.0.4",
44
- "ora": "^9.3.0",
45
- "playwright": "^1.58.2"
46
- },
47
- "devDependencies": {
48
- "@biomejs/biome": "^2.4.8",
49
- "@types/node": "^20.19.37",
50
- "tsup": "^8.5.1",
51
- "tsx": "^4.21.0",
52
- "typescript": "^5.9.3",
53
- "vitest": "^4.1.0"
54
- },
55
- "engines": {
56
- "node": ">=18.0.0"
57
- },
58
- "pnpm": {
59
- "onlyBuiltDependencies": [
60
- "esbuild",
61
- "msedge-tts"
62
- ]
63
- }
64
- }
1
+ {
2
+ "name": "@spark-apps/quickpeek",
3
+ "version": "1.2.0",
4
+ "description": "Auto-generate demo videos for your web app with AI",
5
+ "main": "dist/qp.js",
6
+ "bin": {
7
+ "quickpeek": "dist/qp.js",
8
+ "qp": "dist/qp.js",
9
+ "quickpeek-mcp": "./mcp.mjs"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.mts",
14
+ "import": "./dist/index.mjs",
15
+ "default": "./dist/index.mjs"
16
+ },
17
+ "./web": {
18
+ "types": "./dist/web.d.mts",
19
+ "import": "./dist/web.mjs",
20
+ "default": "./dist/web.mjs"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "mcp.mjs"
27
+ ],
28
+ "scripts": {
29
+ "dev": "npx tsx src/qp.ts",
30
+ "build": "tsup",
31
+ "build:tsc": "tsc --noEmit",
32
+ "lint": "biome check src",
33
+ "lint:fix": "biome check --write src",
34
+ "format": "biome format --write src",
35
+ "test": "vitest run",
36
+ "clean": "rm -rf dist",
37
+ "publish:cli": "npm publish --access public"
38
+ },
39
+ "keywords": [
40
+ "demo",
41
+ "video",
42
+ "screen-recording",
43
+ "playwright",
44
+ "ai",
45
+ "tts",
46
+ "voiceover",
47
+ "automation",
48
+ "cli",
49
+ "documentation"
50
+ ],
51
+ "license": "MIT",
52
+ "dependencies": {
53
+ "@modelcontextprotocol/sdk": "^1.29.0",
54
+ "@spark-apps/video-kit": "^0.1.0",
55
+ "chalk": "^5.6.2",
56
+ "dotenv": "^17.3.1",
57
+ "figlet": "^1.11.0",
58
+ "gradient-string": "^3.0.0",
59
+ "msedge-tts": "^2.0.4",
60
+ "ora": "^9.3.0",
61
+ "playwright": "1.62.1"
62
+ },
63
+ "devDependencies": {
64
+ "@biomejs/biome": "^2.4.8",
65
+ "@types/node": "^20.19.37",
66
+ "tsup": "^8.5.1",
67
+ "tsx": "^4.21.0",
68
+ "typescript": "^5.9.3",
69
+ "vitest": "^4.1.0"
70
+ },
71
+ "engines": {
72
+ "node": ">=18.0.0"
73
+ },
74
+ "pnpm": {
75
+ "onlyBuiltDependencies": [
76
+ "esbuild",
77
+ "msedge-tts"
78
+ ]
79
+ }
80
+ }