@descix/cli 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.
Files changed (94) hide show
  1. package/README.md +95 -0
  2. package/SERVICE_README_sdk.md +399 -0
  3. package/agent-assets/guides/README.md +61 -0
  4. package/agent-assets/guides/dynamic-site-pattern.md +125 -0
  5. package/agent-assets/guides/knowledge-only-pattern.md +93 -0
  6. package/agent-assets/guides/microservice-pattern.md +152 -0
  7. package/agent-assets/guides/static-site-pattern.md +111 -0
  8. package/agent-assets/instructions/app-asset-validation.md +477 -0
  9. package/agent-assets/instructions/onboarding-flow.md +408 -0
  10. package/agent-assets/instructions/standard-folder-structure.md +125 -0
  11. package/agent-assets/reference/app-creation.md +381 -0
  12. package/agent-assets/reference/architecture.md +406 -0
  13. package/agent-assets/reference/local-dev.md +138 -0
  14. package/agent-assets/reference/mcp-integration.md +424 -0
  15. package/agent-assets/reference/workspace-config.md +415 -0
  16. package/agent-assets/rules/descix_mcp.template.mdc +243 -0
  17. package/bin/descix.js +3930 -0
  18. package/bin/mcp-server.js +382 -0
  19. package/descix-cli-1.0.0.tgz +0 -0
  20. package/lib/agent-files.js +162 -0
  21. package/lib/api-client.js +458 -0
  22. package/lib/auth-guard.js +67 -0
  23. package/lib/commands/app-wizard.js +627 -0
  24. package/lib/commands/auth.js +407 -0
  25. package/lib/commands/buy.js +207 -0
  26. package/lib/commands/clone.js +91 -0
  27. package/lib/commands/config.js +155 -0
  28. package/lib/commands/doctor.js +277 -0
  29. package/lib/commands/folder.js +291 -0
  30. package/lib/commands/init.js +257 -0
  31. package/lib/commands/kb.js +654 -0
  32. package/lib/commands/mcp.js +273 -0
  33. package/lib/commands/serve.js +12 -0
  34. package/lib/commands/status.js +239 -0
  35. package/lib/commands/update.js +653 -0
  36. package/lib/core/Chunker.js +610 -0
  37. package/lib/core/Hydrator.js +801 -0
  38. package/lib/core/PathContext.js +335 -0
  39. package/lib/core/Syncer.js +310 -0
  40. package/lib/core/index.js +32 -0
  41. package/lib/global-config.js +86 -0
  42. package/lib/google-storage-adc.js +511 -0
  43. package/lib/wallet-file.js +232 -0
  44. package/lib/wizard/setup.js +502 -0
  45. package/lib/workspace-config.js +712 -0
  46. package/lib/workspace-utils.js +126 -0
  47. package/package.json +41 -0
  48. package/templates/agent-claude.md +226 -0
  49. package/templates/agent-cline.md +133 -0
  50. package/templates/agent-copilot.md +133 -0
  51. package/templates/agent-cursor.md +133 -0
  52. package/templates/descix_mcp.mdc +122 -0
  53. package/templates/drive/README.md +42 -0
  54. package/templates/drive/app/assets/app_description.md +13 -0
  55. package/templates/drive/app/assets/icon.png +0 -0
  56. package/templates/drive/app/assets/system_instructions.md +17 -0
  57. package/templates/drive/app/kb/General/README.md +25 -0
  58. package/templates/drive/community/Apps/.gitkeep +4 -0
  59. package/templates/drive/community/community_assets/community_description.md +15 -0
  60. package/templates/drive/community/community_assets/icon.png +0 -0
  61. package/templates/drive_templates/README.md +104 -0
  62. package/templates/drive_templates/agent_app_template/assets/app_description.txt +13 -0
  63. package/templates/drive_templates/agent_app_template/assets/system_instructions.txt +17 -0
  64. package/templates/drive_templates/agent_app_template/kb/General/README.md +25 -0
  65. package/templates/drive_templates/agent_app_template/microservice/.gitkeep +10 -0
  66. package/templates/drive_templates/agent_app_template/site/.gitkeep +4 -0
  67. package/templates/drive_templates/community_template/Apps/.gitkeep +4 -0
  68. package/templates/drive_templates/community_template/community_assets/community_description.txt +15 -0
  69. package/templates/scaffolds/README.md +62 -0
  70. package/templates/scaffolds/microservice/Dockerfile +19 -0
  71. package/templates/scaffolds/microservice/SERVICE_README_sdk.md +399 -0
  72. package/templates/scaffolds/microservice/app.js +50 -0
  73. package/templates/scaffolds/microservice/app.yaml +8 -0
  74. package/templates/scaffolds/microservice/defaults-config.json +5 -0
  75. package/templates/scaffolds/microservice/dev-overrides.json.example +5 -0
  76. package/templates/scaffolds/microservice/manifest.json +49 -0
  77. package/templates/scaffolds/microservice/package-lock.json +2645 -0
  78. package/templates/scaffolds/microservice/package.json +29 -0
  79. package/templates/scaffolds/microservice/scripts/register.js +55 -0
  80. package/templates/scaffolds/microservice/services/apiFront.js +75 -0
  81. package/templates/scaffolds/microservice/services/commandHandlers/sampleCommands.js +57 -0
  82. package/templates/scaffolds/microservice/services/mcpClient.js +78 -0
  83. package/templates/scaffolds/microservice/services/utils.js +247 -0
  84. package/templates/scaffolds/microservice/setup-schema.json +18 -0
  85. package/templates/scaffolds/microservice/templates/SERVICE_README_TEMPLATE.md +143 -0
  86. package/templates/scaffolds/site/DeSciXAppSDK.js +62 -0
  87. package/templates/scaffolds/site/README.md +51 -0
  88. package/templates/scaffolds/site/app.js +22 -0
  89. package/templates/scaffolds/site/index.html +42 -0
  90. package/templates/scaffolds/site/styles.css +123 -0
  91. package/test-hydration.js +150 -0
  92. package/vendor/mcp/transports/http-sse-transport.js +196 -0
  93. package/vendor/mcp/transports/index.js +15 -0
  94. package/vendor/mcp/transports/stdio-transport.js +118 -0
@@ -0,0 +1,196 @@
1
+ /**
2
+ * HTTP+SSE Transport for MCP Server
3
+ *
4
+ * Handles JSON-RPC 2.0 over HTTP POST with SSE for streaming
5
+ * Used by remote MCP clients like ChatGPT, web-based agents
6
+ *
7
+ * Authentication: X-DeSciX-Signature header (wallet signature as API key)
8
+ */
9
+
10
+ import { User } from '../../../descix-cli/lib/api-client.js';
11
+
12
+ export class HttpSseTransport {
13
+ constructor(mcpServer, options = {}) {
14
+ this.mcpServer = mcpServer;
15
+ this.options = options;
16
+ this.apiClient = options.apiClient || null;
17
+ }
18
+
19
+ /**
20
+ * Create Express middleware for MCP HTTP endpoint
21
+ * @returns {Function} Express middleware
22
+ */
23
+ createMiddleware() {
24
+ return async (req, res, next) => {
25
+ // Handle MCP JSON-RPC requests
26
+ if (req.method !== 'POST') {
27
+ return res.status(405).json({
28
+ jsonrpc: '2.0',
29
+ id: null,
30
+ error: { code: -32600, message: 'Only POST requests are supported' }
31
+ });
32
+ }
33
+
34
+ try {
35
+ // Extract and validate signature-based auth
36
+ const signature = this.extractSignature(req);
37
+ let walletInfo = null;
38
+ let user = null;
39
+
40
+ if (signature) {
41
+ // Authenticate via API signature (O(1) lookup)
42
+ const authResult = await this.authenticateBySignature(signature);
43
+ if (authResult) {
44
+ user = authResult.user;
45
+ walletInfo = {
46
+ userId: user.id,
47
+ walletAddress: user.wallet_address,
48
+ signatureId: authResult.signatureRecord.id,
49
+ permissions: authResult.signatureRecord.permissions,
50
+ communities: authResult.signatureRecord.communities
51
+ };
52
+ }
53
+ }
54
+
55
+ // Handle the MCP request
56
+ const request = req.body;
57
+ const response = await this.mcpServer.handleRequest(request, user, walletInfo);
58
+
59
+ // Only send response if it's not a notification
60
+ if (response !== null) {
61
+ res.json(response);
62
+ } else {
63
+ res.status(204).end();
64
+ }
65
+ } catch (error) {
66
+ console.error('[MCP:HTTP] Error handling request:', error.message);
67
+ res.status(500).json({
68
+ jsonrpc: '2.0',
69
+ id: req.body?.id || null,
70
+ error: {
71
+ code: -32603,
72
+ message: 'Internal error',
73
+ data: error.message
74
+ }
75
+ });
76
+ }
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Create SSE endpoint for streaming responses
82
+ * @returns {Function} Express middleware for SSE
83
+ */
84
+ createSseMiddleware() {
85
+ return async (req, res, next) => {
86
+ // Set SSE headers
87
+ res.setHeader('Content-Type', 'text/event-stream');
88
+ res.setHeader('Cache-Control', 'no-cache');
89
+ res.setHeader('Connection', 'keep-alive');
90
+ res.setHeader('X-Accel-Buffering', 'no');
91
+
92
+ // Extract signature for auth
93
+ const signature = this.extractSignature(req);
94
+ let walletInfo = null;
95
+
96
+ if (signature) {
97
+ const authResult = await this.authenticateBySignature(signature);
98
+ if (authResult) {
99
+ walletInfo = {
100
+ userId: authResult.user.id,
101
+ walletAddress: authResult.user.wallet_address,
102
+ signatureId: authResult.signatureRecord.id,
103
+ permissions: authResult.signatureRecord.permissions
104
+ };
105
+ }
106
+ }
107
+
108
+ // Send initial connection event
109
+ res.write(`event: connected\ndata: ${JSON.stringify({ status: 'connected' })}\n\n`);
110
+
111
+ // Store connection info for potential use
112
+ req.mcpConnection = {
113
+ walletInfo,
114
+ sendEvent: (event, data) => {
115
+ res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
116
+ }
117
+ };
118
+
119
+ // Handle client disconnect
120
+ req.on('close', () => {
121
+ console.error('[MCP:SSE] Client disconnected');
122
+ });
123
+
124
+ // Keep connection alive with heartbeat
125
+ const heartbeat = setInterval(() => {
126
+ res.write(`: heartbeat\n\n`);
127
+ }, 30000);
128
+
129
+ req.on('close', () => {
130
+ clearInterval(heartbeat);
131
+ });
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Extract signature from request
137
+ * Supports header: X-DeSciX-Signature or Authorization: Bearer <signature>
138
+ */
139
+ extractSignature(req) {
140
+ // Check X-DeSciX-Signature header
141
+ const sigHeader = req.headers['x-descix-signature'];
142
+ if (sigHeader) return sigHeader;
143
+
144
+ // Check Authorization header
145
+ const authHeader = req.headers['authorization'];
146
+ if (authHeader && authHeader.startsWith('Signature ')) {
147
+ return authHeader.substring(10);
148
+ }
149
+
150
+ // Check query param (for SSE)
151
+ if (req.query?.signature) {
152
+ return req.query.signature;
153
+ }
154
+
155
+ return null;
156
+ }
157
+
158
+ /**
159
+ * Authenticate by signature via /apifront/
160
+ * @param {string} signature - Wallet signature
161
+ * @returns {Promise<{user, signatureRecord}|null>}
162
+ */
163
+ async authenticateBySignature(signature) {
164
+ if (!this.apiClient) {
165
+ console.error('[MCP:HTTP] No API client configured for signature auth');
166
+ return null;
167
+ }
168
+
169
+ try {
170
+ const result = await this.apiClient.invoke('authenticate_by_signature', {
171
+ signature
172
+ }, { allowGuest: true });
173
+
174
+ if (result?.success) {
175
+ return {
176
+ user: { id: result.user_id },
177
+ signatureRecord: {
178
+ id: result.signature_id,
179
+ name: result.signature_name,
180
+ permissions: result.permissions,
181
+ communities: result.communities
182
+ }
183
+ };
184
+ }
185
+ } catch (error) {
186
+ console.error('[MCP:HTTP] Signature auth failed:', error.message);
187
+ }
188
+
189
+ return null;
190
+ }
191
+ }
192
+
193
+ export default HttpSseTransport;
194
+
195
+
196
+
@@ -0,0 +1,15 @@
1
+ /**
2
+ * MCP Transport Layer
3
+ *
4
+ * Provides pluggable transport implementations for the DeSciX MCP Server:
5
+ * - StdioTransport: For CLI-based clients (Cursor, VS Code, Claude Desktop)
6
+ * - HttpSseTransport: For remote HTTP clients (ChatGPT, web agents)
7
+ *
8
+ * All transports use the same DeSciXMCPServer core with HTTP-only API calls.
9
+ */
10
+
11
+ export { StdioTransport } from './stdio-transport.js';
12
+ export { HttpSseTransport } from './http-sse-transport.js';
13
+
14
+
15
+
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Stdio Transport for MCP Server
3
+ *
4
+ * Uses the official @modelcontextprotocol/sdk for proper protocol handling.
5
+ * This wrapper bridges our DeSciXMCPServer with the official SDK's transport.
6
+ */
7
+
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+
10
+ /**
11
+ * StdioTransport - bridges DeSciXMCPServer to official MCP SDK transport
12
+ *
13
+ * Note: This is a thin wrapper. The actual MCP server should use the
14
+ * official Server class from @modelcontextprotocol/sdk for full compatibility.
15
+ */
16
+ export class StdioTransport {
17
+ constructor(mcpServer, options = {}) {
18
+ this.mcpServer = mcpServer;
19
+ this.options = options;
20
+ this.walletInfo = options.walletInfo || null;
21
+ this.transport = null;
22
+ }
23
+
24
+ /**
25
+ * Start the stdio transport using official SDK
26
+ */
27
+ async start() {
28
+ console.error('[MCP:Stdio] Starting with official MCP SDK transport...');
29
+
30
+ // Create the official stdio transport
31
+ this.transport = new StdioServerTransport();
32
+
33
+ // The transport handles the protocol - we need to connect it to our server
34
+ // This is a temporary bridge until we fully migrate to the SDK's Server class
35
+ console.error('[MCP:Stdio] Transport created, delegating to MCP server...');
36
+
37
+ // For now, we'll use manual message handling since our server has custom logic
38
+ // The official SDK uses a different architecture (Server class with handlers)
39
+
40
+ // Import readline for manual handling until full SDK migration
41
+ const readline = await import('readline');
42
+
43
+ const rl = readline.createInterface({
44
+ input: process.stdin,
45
+ terminal: false
46
+ });
47
+
48
+ console.error('[MCP:Stdio] Transport ready, waiting for JSON-RPC requests...');
49
+
50
+ rl.on('line', async (line) => {
51
+ if (!line.trim()) return;
52
+
53
+ try {
54
+ const request = JSON.parse(line);
55
+ console.error(`[MCP:Stdio] << ${request.method || 'unknown'} (id: ${request.id})`);
56
+
57
+ const response = await this.mcpServer.handleRequest(request, null, this.walletInfo);
58
+
59
+ if (response !== null) {
60
+ const json = JSON.stringify(response);
61
+ console.error(`[MCP:Stdio] >> Response (id: ${response.id}, ${json.length} bytes)`);
62
+ // Write to stdout with explicit flush
63
+ process.stdout.write(json + '\n', () => {
64
+ // Callback after write completes
65
+ });
66
+ }
67
+ } catch (error) {
68
+ console.error('[MCP:Stdio] Parse error:', error.message);
69
+ const errorResponse = {
70
+ jsonrpc: '2.0',
71
+ id: null,
72
+ error: {
73
+ code: -32700,
74
+ message: 'Parse error',
75
+ data: error.message
76
+ }
77
+ };
78
+ process.stdout.write(JSON.stringify(errorResponse) + '\n');
79
+ }
80
+ });
81
+
82
+ rl.on('close', () => {
83
+ console.error('[MCP:Stdio] Transport closed');
84
+ });
85
+
86
+ // Keep process alive
87
+ return new Promise((resolve) => {
88
+ rl.on('close', resolve);
89
+ process.on('SIGINT', () => {
90
+ rl.close();
91
+ resolve();
92
+ });
93
+ process.on('SIGTERM', () => {
94
+ rl.close();
95
+ resolve();
96
+ });
97
+ });
98
+ }
99
+
100
+ /**
101
+ * Stop the transport
102
+ */
103
+ stop() {
104
+ console.error('[MCP:Stdio] Transport stopped');
105
+ }
106
+
107
+ /**
108
+ * Update wallet info
109
+ */
110
+ setWalletInfo(walletInfo) {
111
+ this.walletInfo = walletInfo;
112
+ }
113
+ }
114
+
115
+ export default StdioTransport;
116
+
117
+
118
+