@vurb/core 3.2.0 → 3.2.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.
Files changed (81) hide show
  1. package/README.md +677 -677
  2. package/dist/cli/constants.js +58 -58
  3. package/dist/cli/templates/config.js +26 -26
  4. package/dist/cli/templates/core.js +168 -168
  5. package/dist/cli/templates/middleware.js +25 -25
  6. package/dist/cli/templates/presenter.js +1 -1
  7. package/dist/cli/templates/presenter.js.map +1 -1
  8. package/dist/cli/templates/prompt.js +1 -1
  9. package/dist/cli/templates/prompt.js.map +1 -1
  10. package/dist/cli/templates/readme.js +142 -142
  11. package/dist/cli/templates/testing.js +84 -84
  12. package/dist/cli/templates/tools.js +46 -46
  13. package/dist/cli/templates/vectors/database.js +69 -69
  14. package/dist/cli/templates/vectors/oauth.js +63 -63
  15. package/dist/cli/templates/vectors/openapi.js +97 -97
  16. package/dist/cli/templates/vectors/workflow.js +1 -1
  17. package/dist/cli/templates/vectors/workflow.js.map +1 -1
  18. package/dist/client/createTypedRegistry.js +1 -1
  19. package/dist/converters/ConverterBase.d.ts +1 -1
  20. package/dist/converters/ConverterBase.js +1 -1
  21. package/dist/core/StandardSchema.d.ts +1 -1
  22. package/dist/core/StandardSchema.js +1 -1
  23. package/dist/core/builder/GroupedToolBuilder.d.ts +2 -2
  24. package/dist/core/builder/GroupedToolBuilder.js +2 -2
  25. package/dist/core/builder/defineTool.d.ts +1 -1
  26. package/dist/core/builder/defineTool.js +1 -1
  27. package/dist/core/createGroup.d.ts +1 -1
  28. package/dist/core/createGroup.js +1 -1
  29. package/dist/core/initVurb.d.ts +1 -1
  30. package/dist/core/initVurb.js +1 -1
  31. package/dist/core/registry/ToolRegistry.d.ts +1 -1
  32. package/dist/core/registry/ToolRegistry.js +1 -1
  33. package/dist/core/response.d.ts +1 -1
  34. package/dist/core/response.js +1 -1
  35. package/dist/core/result.d.ts +1 -1
  36. package/dist/core/result.js +1 -1
  37. package/dist/domain/Annotations.d.ts +1 -1
  38. package/dist/domain/Icon.d.ts +1 -1
  39. package/dist/domain/Prompt.d.ts +1 -1
  40. package/dist/domain/Prompt.js +1 -1
  41. package/dist/domain/PromptArgument.d.ts +1 -1
  42. package/dist/domain/PromptArgument.js +1 -1
  43. package/dist/domain/Resource.d.ts +1 -1
  44. package/dist/domain/Resource.js +1 -1
  45. package/dist/domain/Role.d.ts +1 -1
  46. package/dist/domain/Role.js +1 -1
  47. package/dist/domain/Tool.d.ts +1 -1
  48. package/dist/domain/Tool.js +1 -1
  49. package/dist/domain/ToolAnnotations.d.ts +1 -1
  50. package/dist/fsm/StateMachineGate.d.ts +1 -1
  51. package/dist/fsm/StateMachineGate.js +1 -1
  52. package/dist/introspection/GovernanceObserver.d.ts +1 -1
  53. package/dist/introspection/GovernanceObserver.js +1 -1
  54. package/dist/introspection/SemanticProbe.js +49 -49
  55. package/dist/observability/DebugObserver.d.ts +1 -1
  56. package/dist/observability/DebugObserver.js +1 -1
  57. package/dist/presenter/Presenter.d.ts +4 -4
  58. package/dist/presenter/Presenter.js +3 -3
  59. package/dist/presenter/ResponseBuilder.d.ts +2 -2
  60. package/dist/presenter/ResponseBuilder.js +2 -2
  61. package/dist/presenter/definePresenter.d.ts +1 -1
  62. package/dist/presenter/definePresenter.js +1 -1
  63. package/dist/presenter/suggest.d.ts +1 -1
  64. package/dist/presenter/suggest.js +1 -1
  65. package/dist/presenter/typeHelpers.d.ts +1 -1
  66. package/dist/presenter/typeHelpers.js +1 -1
  67. package/dist/presenter/ui.d.ts +2 -2
  68. package/dist/presenter/ui.js +2 -2
  69. package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -1
  70. package/dist/prompt/PromptMessage.d.ts +2 -2
  71. package/dist/prompt/PromptMessage.js +2 -2
  72. package/dist/prompt/PromptRegistry.d.ts +1 -1
  73. package/dist/prompt/PromptRegistry.js +1 -1
  74. package/dist/server/DevServer.d.ts +1 -1
  75. package/dist/server/DevServer.js +1 -1
  76. package/dist/server/autoDiscover.js +1 -1
  77. package/dist/server/startServer.d.ts +1 -1
  78. package/dist/server/startServer.js +1 -1
  79. package/dist/testing/MvaMetaSymbol.d.ts +1 -1
  80. package/dist/testing/MvaMetaSymbol.js +1 -1
  81. package/package.json +1 -1
@@ -33,63 +33,63 @@ export const VALID_TRANSPORTS = ['stdio', 'sse'];
33
33
  export const VALID_VECTORS = ['vanilla', 'prisma', 'n8n', 'openapi', 'oauth'];
34
34
  // ─── Help Text ───────────────────────────────────────────────────
35
35
  /** @internal exported for testing */
36
- export const HELP = `
37
- vurb — Vurb CLI
38
-
39
- USAGE
40
- vurb create <name> Scaffold a new Vurb server
41
- vurb dev --server <entry> Start HMR dev server with auto-reload
42
- vurb lock Generate or update ${LOCKFILE_NAME}
43
- vurb lock --check Verify lockfile is up to date (CI gate)
44
- vurb deploy Bundle, compress & deploy to Edge
45
- vurb remote Show current remote configuration
46
- vurb inspect Launch the real-time TUI dashboard
47
- vurb insp --demo Launch TUI with built-in simulator
48
-
49
- CREATE OPTIONS
50
- --transport <stdio|sse> Transport layer (default: stdio)
51
- --vector <type> Ingestion vector: vanilla, prisma, n8n, openapi, oauth
52
- --testing Include test suite (default: true)
53
- --no-testing Skip test suite
54
- --yes, -y Skip prompts, use defaults
55
-
56
- DEV OPTIONS
57
- --server, -s <path> Path to server entrypoint (default: auto-detect)
58
- --dir, -d <path> Directory to watch for changes (default: auto-detect from server)
59
-
60
- DEPLOY OPTIONS
61
- --server, -s <path> Path to server entrypoint (default: auto-detect)
62
- --token <token> Override VURB_DEPLOY_TOKEN (connection token)
63
-
64
- REMOTE OPTIONS
65
- vurb remote <url> Override API endpoint (default: Vinkius Cloud)
66
- vurb remote --server-id <id> Set target server UUID
67
-
68
- INSPECTOR OPTIONS
69
- --demo, -d Launch with built-in simulator (no server needed)
70
- --out, -o <mode> Output: tui (default), stderr (headless ECS/K8s)
71
- --pid, -p <pid> Connect to a specific server PID
72
- --path <path> Custom IPC socket/pipe path
73
-
74
- LOCK OPTIONS
75
- --server, -s <path> Path to server entrypoint
76
- --name, -n <name> Server name for lockfile header
77
- --cwd <dir> Project root directory
78
-
79
- GLOBAL
80
- --help, -h Show this help message
81
-
82
- EXAMPLES
83
- vurb create my-server
84
- vurb create my-server -y
85
- vurb create my-server --vector prisma --transport sse
86
- vurb dev --server ./src/server.ts
87
- vurb dev --server ./src/server.ts --dir ./src/tools
88
- vurb lock --server ./src/server.ts
89
- vurb deploy
90
- vurb remote --server-id abc-123-def
91
- vurb remote http://localhost:8080 --server-id abc-123-def
92
- vurb inspect --demo
93
- vurb insp --pid 12345
36
+ export const HELP = `
37
+ vurb — Vurb CLI
38
+
39
+ USAGE
40
+ vurb create <name> Scaffold a new Vurb server
41
+ vurb dev --server <entry> Start HMR dev server with auto-reload
42
+ vurb lock Generate or update ${LOCKFILE_NAME}
43
+ vurb lock --check Verify lockfile is up to date (CI gate)
44
+ vurb deploy Bundle, compress & deploy to Edge
45
+ vurb remote Show current remote configuration
46
+ vurb inspect Launch the real-time TUI dashboard
47
+ vurb insp --demo Launch TUI with built-in simulator
48
+
49
+ CREATE OPTIONS
50
+ --transport <stdio|sse> Transport layer (default: stdio)
51
+ --vector <type> Ingestion vector: vanilla, prisma, n8n, openapi, oauth
52
+ --testing Include test suite (default: true)
53
+ --no-testing Skip test suite
54
+ --yes, -y Skip prompts, use defaults
55
+
56
+ DEV OPTIONS
57
+ --server, -s <path> Path to server entrypoint (default: auto-detect)
58
+ --dir, -d <path> Directory to watch for changes (default: auto-detect from server)
59
+
60
+ DEPLOY OPTIONS
61
+ --server, -s <path> Path to server entrypoint (default: auto-detect)
62
+ --token <token> Override VURB_DEPLOY_TOKEN (connection token)
63
+
64
+ REMOTE OPTIONS
65
+ vurb remote <url> Override API endpoint (default: Vinkius Cloud)
66
+ vurb remote --server-id <id> Set target server UUID
67
+
68
+ INSPECTOR OPTIONS
69
+ --demo, -d Launch with built-in simulator (no server needed)
70
+ --out, -o <mode> Output: tui (default), stderr (headless ECS/K8s)
71
+ --pid, -p <pid> Connect to a specific server PID
72
+ --path <path> Custom IPC socket/pipe path
73
+
74
+ LOCK OPTIONS
75
+ --server, -s <path> Path to server entrypoint
76
+ --name, -n <name> Server name for lockfile header
77
+ --cwd <dir> Project root directory
78
+
79
+ GLOBAL
80
+ --help, -h Show this help message
81
+
82
+ EXAMPLES
83
+ vurb create my-server
84
+ vurb create my-server -y
85
+ vurb create my-server --vector prisma --transport sse
86
+ vurb dev --server ./src/server.ts
87
+ vurb dev --server ./src/server.ts --dir ./src/tools
88
+ vurb lock --server ./src/server.ts
89
+ vurb deploy
90
+ vurb remote --server-id abc-123-def
91
+ vurb remote http://localhost:8080 --server-id abc-123-def
92
+ vurb inspect --demo
93
+ vurb insp --pid 12345
94
94
  `.trim();
95
95
  //# sourceMappingURL=constants.js.map
@@ -85,47 +85,47 @@ export function tsconfig() {
85
85
  }
86
86
  /** Generate `.gitignore` */
87
87
  export function gitignore() {
88
- return `node_modules/
89
- dist/
90
- *.tsbuildinfo
91
- .env
92
- .env.local
93
- coverage/
88
+ return `node_modules/
89
+ dist/
90
+ *.tsbuildinfo
91
+ .env
92
+ .env.local
93
+ coverage/
94
94
  `;
95
95
  }
96
96
  /** Generate `.env.example` with vector-specific vars */
97
97
  export function envExample(config) {
98
- let env = `# ── Vurb Server Environment ─────────────────────
99
- # Copy this to .env and fill in your values.
100
-
101
- # Server
102
- NODE_ENV=development
98
+ let env = `# ── Vurb Server Environment ─────────────────────
99
+ # Copy this to .env and fill in your values.
100
+
101
+ # Server
102
+ NODE_ENV=development
103
103
  `;
104
104
  if (config.vector === 'prisma') {
105
- env += `
106
- # Database (Prisma)
107
- DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
105
+ env += `
106
+ # Database (Prisma)
107
+ DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
108
108
  `;
109
109
  }
110
110
  if (config.vector === 'n8n') {
111
- env += `
112
- # n8n Workflow Automation
113
- N8N_BASE_URL=http://localhost:5678
114
- N8N_API_KEY=your-api-key-here
111
+ env += `
112
+ # n8n Workflow Automation
113
+ N8N_BASE_URL=http://localhost:5678
114
+ N8N_API_KEY=your-api-key-here
115
115
  `;
116
116
  }
117
117
  if (config.vector === 'oauth') {
118
- env += `
119
- # OAuth Device Flow (RFC 8628)
120
- OAUTH_CLIENT_ID=your-client-id
121
- OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
122
- OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
118
+ env += `
119
+ # OAuth Device Flow (RFC 8628)
120
+ OAUTH_CLIENT_ID=your-client-id
121
+ OAUTH_AUTH_ENDPOINT=https://api.example.com/oauth/device/code
122
+ OAUTH_TOKEN_ENDPOINT=https://api.example.com/oauth/device/token
123
123
  `;
124
124
  }
125
125
  if (config.transport === 'sse') {
126
- env += `
127
- # Streamable HTTP Transport
128
- PORT=3001
126
+ env += `
127
+ # Streamable HTTP Transport
128
+ PORT=3001
129
129
  `;
130
130
  }
131
131
  return env;
@@ -1,186 +1,186 @@
1
1
  /** Generate `src/vurb.ts` — The one-file context center */
2
2
  export function vurbTs() {
3
- return `/**
4
- * Vurb Instance — Context Initialization
5
- *
6
- * Define your context type ONCE. Every f.query(), f.mutation(),
7
- * f.presenter(), f.prompt(), and f.middleware() call inherits
8
- * AppContext — zero generic repetition anywhere in the codebase.
9
- */
10
- import { initVurb } from 'vurb';
11
- import type { AppContext } from './context.js';
12
-
13
- export const f = initVurb<AppContext>();
3
+ return `/**
4
+ * Vurb Instance — Context Initialization
5
+ *
6
+ * Define your context type ONCE. Every f.query(), f.mutation(),
7
+ * f.presenter(), f.prompt(), and f.middleware() call inherits
8
+ * AppContext — zero generic repetition anywhere in the codebase.
9
+ */
10
+ import { initVurb } from '@vurb/core';
11
+ import type { AppContext } from './context.js';
12
+
13
+ export const f = initVurb<AppContext>();
14
14
  `;
15
15
  }
16
16
  /** Generate `src/context.ts` — Application context type + factory */
17
17
  export function contextTs() {
18
- return `/**
19
- * Application Context — Shared State for Every Tool Handler
20
- *
21
- * Every f.query() / f.mutation() handler receives (input, ctx)
22
- * where ctx is this AppContext. Extend it with your own services
23
- * (DB client, auth, external APIs, etc.)
24
- */
25
-
26
- export interface AppContext {
27
- /** Current user role for RBAC checks */
28
- role: 'ADMIN' | 'USER' | 'GUEST';
29
-
30
- /** Tenant identifier (multi-tenancy) */
31
- tenantId: string;
32
- }
33
-
34
- /**
35
- * Create the application context for each tool invocation.
36
- *
37
- * In production, hydrate this from the MCP session metadata,
38
- * JWT tokens, or environment variables.
39
- */
40
- export function createContext(): AppContext {
41
- return {
42
- role: 'ADMIN',
43
- tenantId: 'default',
44
- };
45
- }
18
+ return `/**
19
+ * Application Context — Shared State for Every Tool Handler
20
+ *
21
+ * Every f.query() / f.mutation() handler receives (input, ctx)
22
+ * where ctx is this AppContext. Extend it with your own services
23
+ * (DB client, auth, external APIs, etc.)
24
+ */
25
+
26
+ export interface AppContext {
27
+ /** Current user role for RBAC checks */
28
+ role: 'ADMIN' | 'USER' | 'GUEST';
29
+
30
+ /** Tenant identifier (multi-tenancy) */
31
+ tenantId: string;
32
+ }
33
+
34
+ /**
35
+ * Create the application context for each tool invocation.
36
+ *
37
+ * In production, hydrate this from the MCP session metadata,
38
+ * JWT tokens, or environment variables.
39
+ */
40
+ export function createContext(): AppContext {
41
+ return {
42
+ role: 'ADMIN',
43
+ tenantId: 'default',
44
+ };
45
+ }
46
46
  `;
47
47
  }
48
48
  /** Generate `src/server.ts` — Bootstrap with autoDiscover + transport */
49
49
  export function serverTs(config) {
50
50
  if (config.transport === 'stdio') {
51
51
  // Simplified: one-liner bootstrap via startServer()
52
- return `/**
53
- * Server Bootstrap — Vurb
54
- *
55
- * Tools are auto-discovered from src/tools/.
56
- * Drop a file, it becomes a tool.
57
- */
58
- import { fileURLToPath } from 'node:url';
59
- import { autoDiscover, PromptRegistry, startServer } from 'vurb';
60
- import { createContext } from './context.js';
61
- import { f } from './vurb.js';
62
- import { GreetPrompt } from './prompts/greet.js';
63
-
64
- // ── Registry ─────────────────────────────────────────────
65
- const registry = f.registry();
66
- const prompts = new PromptRegistry();
67
-
68
- // ── Auto-Discover & Register ─────────────────────────────
69
- await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
70
- prompts.register(GreetPrompt);
71
-
72
- // ── Start ────────────────────────────────────────────────
73
- await startServer({
74
- name: '${config.name}',
75
- registry,
76
- prompts,
77
- contextFactory: () => createContext(),
78
- });
52
+ return `/**
53
+ * Server Bootstrap — Vurb
54
+ *
55
+ * Tools are auto-discovered from src/tools/.
56
+ * Drop a file, it becomes a tool.
57
+ */
58
+ import { fileURLToPath } from 'node:url';
59
+ import { autoDiscover, PromptRegistry, startServer } from '@vurb/core';
60
+ import { createContext } from './context.js';
61
+ import { f } from './vurb.js';
62
+ import { GreetPrompt } from './prompts/greet.js';
63
+
64
+ // ── Registry ─────────────────────────────────────────────
65
+ const registry = f.registry();
66
+ const prompts = new PromptRegistry();
67
+
68
+ // ── Auto-Discover & Register ─────────────────────────────
69
+ await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
70
+ prompts.register(GreetPrompt);
71
+
72
+ // ── Start ────────────────────────────────────────────────
73
+ await startServer({
74
+ name: '${config.name}',
75
+ registry,
76
+ prompts,
77
+ contextFactory: () => createContext(),
78
+ });
79
79
  `;
80
80
  }
81
81
  // Streamable HTTP transport — manual setup required (startServer is stdio-only)
82
- return `/**
83
- * Server Bootstrap — Vurb with Streamable HTTP Transport
84
- *
85
- * Tools are auto-discovered from src/tools/.
86
- * Drop a file, it becomes a tool.
87
- */
88
- import { fileURLToPath } from 'node:url';
89
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
90
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
91
- import { createServer } from 'node:http';
92
- import { autoDiscover, PromptRegistry } from 'vurb';
93
- import { createContext } from './context.js';
94
- import { f } from './vurb.js';
95
- import { GreetPrompt } from './prompts/greet.js';
96
-
97
- // ── Registry ─────────────────────────────────────────────
98
- const registry = f.registry();
99
- const prompts = new PromptRegistry();
100
-
101
- // ── Auto-Discover & Register ─────────────────────────────
102
- await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
103
- prompts.register(GreetPrompt);
104
-
105
- // ── Server ───────────────────────────────────────────────
106
- const server = new McpServer(
107
- { name: '${config.name}', version: '0.1.0' },
108
- );
109
-
110
- registry.attachToServer(server, {
111
- contextFactory: () => createContext(),
112
- prompts,
113
- });
114
-
115
- // ── Transport ────────────────────────────────────────────
116
- const PORT = Number(process.env['PORT'] ?? 3001);
117
- const sessions = new Map<string, StreamableHTTPServerTransport>();
118
-
119
- const httpServer = createServer(async (req, res) => {
120
- try {
121
- const url = new URL(req.url ?? '/', \`http://localhost:\${PORT}\`);
122
-
123
- if (url.pathname !== '/mcp') {
124
- res.writeHead(404).end();
125
- return;
126
- }
127
-
128
- if (req.method === 'POST') {
129
- // Parse JSON body
130
- const chunks: Buffer[] = [];
131
- for await (const chunk of req) chunks.push(chunk as Buffer);
132
- const body = JSON.parse(Buffer.concat(chunks).toString());
133
-
134
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
135
-
136
- // Existing session — route to its transport
137
- if (sessionId && sessions.has(sessionId)) {
138
- const transport = sessions.get(sessionId)!;
139
- await transport.handleRequest(req, res, body);
140
- return;
141
- }
142
-
143
- // New session — create transport
144
- const transport = new StreamableHTTPServerTransport({
145
- sessionIdGenerator: () => crypto.randomUUID(),
146
- onsessioninitialized: (id) => {
147
- sessions.set(id, transport);
148
- },
149
- });
150
- transport.onclose = () => {
151
- const id = [...sessions.entries()].find(([, t]) => t === transport)?.[0];
152
- if (id) sessions.delete(id);
153
- };
154
- await server.connect(transport);
155
- await transport.handleRequest(req, res, body);
156
- } else if (req.method === 'GET') {
157
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
158
- if (sessionId && sessions.has(sessionId)) {
159
- const transport = sessions.get(sessionId)!;
160
- await transport.handleRequest(req, res);
161
- } else {
162
- res.writeHead(400).end('Missing or invalid session');
163
- }
164
- } else if (req.method === 'DELETE') {
165
- const sessionId = req.headers['mcp-session-id'] as string | undefined;
166
- if (sessionId && sessions.has(sessionId)) {
167
- const transport = sessions.get(sessionId)!;
168
- await transport.handleRequest(req, res);
169
- } else {
170
- res.writeHead(400).end('Missing or invalid session');
171
- }
172
- } else {
173
- res.writeHead(405).end();
174
- }
175
- } catch (err) {
176
- console.error('[Vurb] Unhandled error in HTTP handler:', err);
177
- if (!res.headersSent) res.writeHead(500).end();
178
- }
179
- });
180
-
181
- httpServer.listen(PORT, () => {
182
- console.error(\`⚡ Vurb server on http://localhost:\${PORT}/mcp\`);
183
- });
82
+ return `/**
83
+ * Server Bootstrap — Vurb with Streamable HTTP Transport
84
+ *
85
+ * Tools are auto-discovered from src/tools/.
86
+ * Drop a file, it becomes a tool.
87
+ */
88
+ import { fileURLToPath } from 'node:url';
89
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
90
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
91
+ import { createServer } from 'node:http';
92
+ import { autoDiscover, PromptRegistry } from '@vurb/core';
93
+ import { createContext } from './context.js';
94
+ import { f } from './vurb.js';
95
+ import { GreetPrompt } from './prompts/greet.js';
96
+
97
+ // ── Registry ─────────────────────────────────────────────
98
+ const registry = f.registry();
99
+ const prompts = new PromptRegistry();
100
+
101
+ // ── Auto-Discover & Register ─────────────────────────────
102
+ await autoDiscover(registry, fileURLToPath(new URL('./tools', import.meta.url)));
103
+ prompts.register(GreetPrompt);
104
+
105
+ // ── Server ───────────────────────────────────────────────
106
+ const server = new McpServer(
107
+ { name: '${config.name}', version: '0.1.0' },
108
+ );
109
+
110
+ registry.attachToServer(server, {
111
+ contextFactory: () => createContext(),
112
+ prompts,
113
+ });
114
+
115
+ // ── Transport ────────────────────────────────────────────
116
+ const PORT = Number(process.env['PORT'] ?? 3001);
117
+ const sessions = new Map<string, StreamableHTTPServerTransport>();
118
+
119
+ const httpServer = createServer(async (req, res) => {
120
+ try {
121
+ const url = new URL(req.url ?? '/', \`http://localhost:\${PORT}\`);
122
+
123
+ if (url.pathname !== '/mcp') {
124
+ res.writeHead(404).end();
125
+ return;
126
+ }
127
+
128
+ if (req.method === 'POST') {
129
+ // Parse JSON body
130
+ const chunks: Buffer[] = [];
131
+ for await (const chunk of req) chunks.push(chunk as Buffer);
132
+ const body = JSON.parse(Buffer.concat(chunks).toString());
133
+
134
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
135
+
136
+ // Existing session — route to its transport
137
+ if (sessionId && sessions.has(sessionId)) {
138
+ const transport = sessions.get(sessionId)!;
139
+ await transport.handleRequest(req, res, body);
140
+ return;
141
+ }
142
+
143
+ // New session — create transport
144
+ const transport = new StreamableHTTPServerTransport({
145
+ sessionIdGenerator: () => crypto.randomUUID(),
146
+ onsessioninitialized: (id) => {
147
+ sessions.set(id, transport);
148
+ },
149
+ });
150
+ transport.onclose = () => {
151
+ const id = [...sessions.entries()].find(([, t]) => t === transport)?.[0];
152
+ if (id) sessions.delete(id);
153
+ };
154
+ await server.connect(transport);
155
+ await transport.handleRequest(req, res, body);
156
+ } else if (req.method === 'GET') {
157
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
158
+ if (sessionId && sessions.has(sessionId)) {
159
+ const transport = sessions.get(sessionId)!;
160
+ await transport.handleRequest(req, res);
161
+ } else {
162
+ res.writeHead(400).end('Missing or invalid session');
163
+ }
164
+ } else if (req.method === 'DELETE') {
165
+ const sessionId = req.headers['mcp-session-id'] as string | undefined;
166
+ if (sessionId && sessions.has(sessionId)) {
167
+ const transport = sessions.get(sessionId)!;
168
+ await transport.handleRequest(req, res);
169
+ } else {
170
+ res.writeHead(400).end('Missing or invalid session');
171
+ }
172
+ } else {
173
+ res.writeHead(405).end();
174
+ }
175
+ } catch (err) {
176
+ console.error('[Vurb] Unhandled error in HTTP handler:', err);
177
+ if (!res.headersSent) res.writeHead(500).end();
178
+ }
179
+ });
180
+
181
+ httpServer.listen(PORT, () => {
182
+ console.error(\`⚡ Vurb server on http://localhost:\${PORT}/mcp\`);
183
+ });
184
184
  `;
185
185
  }
186
186
  //# sourceMappingURL=core.js.map
@@ -4,31 +4,31 @@
4
4
  */
5
5
  /** Generate `src/middleware/auth.ts` — RBAC middleware */
6
6
  export function authMiddlewareTs() {
7
- return `/**
8
- * Auth Middleware — RBAC Guard (Fluent API)
9
- *
10
- * Demonstrates f.middleware() — tRPC-style context derivation.
11
- * Rejects GUEST requests with a structured error.
12
- *
13
- * Usage in tools:
14
- * f.query('users.list')
15
- * .use(withAuth)
16
- * .handle(async (input, ctx) => {
17
- * // ctx now has ctx.role guaranteed non-GUEST
18
- * });
19
- *
20
- * In production, replace with JWT validation,
21
- * API key checks, or OAuth token verification.
22
- */
23
- import { f } from '../vurb.js';
24
- import { error } from 'vurb';
25
-
26
- export const withAuth = f.middleware(async (ctx) => {
27
- if (ctx.role === 'GUEST') {
28
- throw error('Access denied. Authentication required.');
29
- }
30
- return { verified: true as const };
31
- });
7
+ return `/**
8
+ * Auth Middleware — RBAC Guard (Fluent API)
9
+ *
10
+ * Demonstrates f.middleware() — tRPC-style context derivation.
11
+ * Rejects GUEST requests with a structured error.
12
+ *
13
+ * Usage in tools:
14
+ * f.query('users.list')
15
+ * .use(withAuth)
16
+ * .handle(async (input, ctx) => {
17
+ * // ctx now has ctx.role guaranteed non-GUEST
18
+ * });
19
+ *
20
+ * In production, replace with JWT validation,
21
+ * API key checks, or OAuth token verification.
22
+ */
23
+ import { f } from '../vurb.js';
24
+ import { error } from '@vurb/core';
25
+
26
+ export const withAuth = f.middleware(async (ctx) => {
27
+ if (ctx.role === 'GUEST') {
28
+ throw error('Access denied. Authentication required.');
29
+ }
30
+ return { verified: true as const };
31
+ });
32
32
  `;
33
33
  }
34
34
  //# sourceMappingURL=middleware.js.map
@@ -19,7 +19,7 @@ export function systemPresenterTs() {
19
19
  ' * - ui.markdown() server-rendered UI blocks',
20
20
  ' * - suggestActions() for HATEOAS-style affordances',
21
21
  ' */',
22
- "import { definePresenter, ui } from 'vurb';",
22
+ "import { definePresenter, ui } from '@vurb/core';",
23
23
  "import { z } from 'zod';",
24
24
  '',
25
25
  'export const SystemPresenter = definePresenter({',
@@ -1 +1 @@
1
- {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../../src/cli/templates/presenter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,MAAM,UAAU,iBAAiB;IAC7B,OAAO;QACH,KAAK;QACL,wDAAwD;QACxD,IAAI;QACJ,wDAAwD;QACxD,0DAA0D;QAC1D,sDAAsD;QACtD,kCAAkC;QAClC,IAAI;QACJ,2BAA2B;QAC3B,wCAAwC;QACxC,4EAA4E;QAC5E,8CAA8C;QAC9C,qDAAqD;QACrD,KAAK;QACL,6CAA6C;QAC7C,0BAA0B;QAC1B,EAAE;QACF,kDAAkD;QAClD,2BAA2B;QAC3B,wBAAwB;QACxB,mEAAmE;QACnE,+EAA+E;QAC/E,gEAAgE;QAChE,6EAA6E;QAC7E,SAAS;QACT,gFAAgF;QAChF,qBAAqB;QACrB,sBAAsB;QACtB,uGAAuG;QACvG,YAAY;QACZ,QAAQ;QACR,yDAAyD;QACzD,kFAAkF;QAClF,eAAe;QACf,KAAK;QACL,EAAE;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../../src/cli/templates/presenter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,MAAM,UAAU,iBAAiB;IAC7B,OAAO;QACH,KAAK;QACL,wDAAwD;QACxD,IAAI;QACJ,wDAAwD;QACxD,0DAA0D;QAC1D,sDAAsD;QACtD,kCAAkC;QAClC,IAAI;QACJ,2BAA2B;QAC3B,wCAAwC;QACxC,4EAA4E;QAC5E,8CAA8C;QAC9C,qDAAqD;QACrD,KAAK;QACL,mDAAmD;QACnD,0BAA0B;QAC1B,EAAE;QACF,kDAAkD;QAClD,2BAA2B;QAC3B,wBAAwB;QACxB,mEAAmE;QACnE,+EAA+E;QAC/E,gEAAgE;QAChE,6EAA6E;QAC7E,SAAS;QACT,gFAAgF;QAChF,qBAAqB;QACrB,sBAAsB;QACtB,uGAAuG;QACvG,YAAY;QACZ,QAAQ;QACR,yDAAyD;QACzD,kFAAkF;QAClF,eAAe;QACf,KAAK;QACL,EAAE;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC"}
@@ -15,7 +15,7 @@ export function greetPromptTs() {
15
15
  ' * - MCP prompts/list + prompts/get',
16
16
  ' */',
17
17
  "import { f } from '../vurb.js';",
18
- "import { PromptMessage } from 'vurb';",
18
+ "import { PromptMessage } from '@vurb/core';",
19
19
  '',
20
20
  "export const GreetPrompt = f.prompt('greet', {",
21
21
  " description: 'Generate a personalized greeting for a user',",
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/cli/templates/prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8DAA8D;AAC9D,MAAM,UAAU,aAAa;IACzB,OAAO;QACH,KAAK;QACL,yCAAyC;QACzC,IAAI;QACJ,kBAAkB;QAClB,+CAA+C;QAC/C,gDAAgD;QAChD,oDAAoD;QACpD,qCAAqC;QACrC,KAAK;QACL,iCAAiC;QACjC,uCAAuC;QACvC,EAAE;QACF,gDAAgD;QAChD,iEAAiE;QACjE,aAAa;QACb,+EAA+E;QAC/E,kBAAkB;QAClB,4DAA4D;QAC5D,4CAA4C;QAC5C,YAAY;QACZ,iBAAiB;QACjB,kDAAkD;QAClD,qBAAqB;QACrB,mCAAmC;QACnC,wFAAwF;QACxF,iDAAiD;QACjD,gBAAgB;QAChB,0DAA0D;QAC1D,YAAY;QACZ,SAAS;QACT,KAAK;QACL,EAAE;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/cli/templates/prompt.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8DAA8D;AAC9D,MAAM,UAAU,aAAa;IACzB,OAAO;QACH,KAAK;QACL,yCAAyC;QACzC,IAAI;QACJ,kBAAkB;QAClB,+CAA+C;QAC/C,gDAAgD;QAChD,oDAAoD;QACpD,qCAAqC;QACrC,KAAK;QACL,iCAAiC;QACjC,6CAA6C;QAC7C,EAAE;QACF,gDAAgD;QAChD,iEAAiE;QACjE,aAAa;QACb,+EAA+E;QAC/E,kBAAkB;QAClB,4DAA4D;QAC5D,4CAA4C;QAC5C,YAAY;QACZ,iBAAiB;QACjB,kDAAkD;QAClD,qBAAqB;QACrB,mCAAmC;QACnC,wFAAwF;QACxF,iDAAiD;QACjD,gBAAgB;QAChB,0DAA0D;QAC1D,YAAY;QACZ,SAAS;QACT,KAAK;QACL,EAAE;KACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC"}