@mexty/cli 1.4.0 → 1.4.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.
@@ -226,4 +226,266 @@ Blocks can be marked as "insertable by agent" which allows AI systems to:
226
226
  4. Commit and publish with `mexty save`
227
227
  5. Share or publish to marketplace
228
228
 
229
+ ## CLI Commands
230
+
231
+ The MEXTY CLI provides a complete toolkit for block development and publishing:
232
+
233
+ ### Installation
234
+
235
+ ```bash
236
+ npm install -g @mexty/cli
237
+ ```
238
+
239
+ ### Authentication
240
+
241
+ ```bash
242
+ mexty login
243
+ ```
244
+
245
+ Authenticate with your MEXTY account to access all CLI features.
246
+
247
+ ### Block Creation
248
+
249
+ ```bash
250
+ mexty create block --name "Block Name" --description "Description" --category "category"
251
+ ```
252
+
253
+ - Creates a new block via the API
254
+ - Automatically generates a GitHub repository
255
+ - Clones the repository locally
256
+ - Changes to the block directory
257
+ - Sets up the development environment
258
+
259
+ **Example:**
260
+
261
+ ```bash
262
+ mexty create block --name "Weather Widget" --description "A beautiful weather display component" --category "widget"
263
+ ```
264
+
265
+ ### Development & Saving
266
+
267
+ ```bash
268
+ mexty save
269
+ ```
270
+
271
+ - Stages all changes (`git add .`)
272
+ - Prompts for commit message
273
+ - Commits changes to git
274
+ - Pushes to GitHub
275
+ - Triggers the save-and-bundle process to build the block
276
+
277
+ ### Publishing to Marketplace
278
+
279
+ ```bash
280
+ mexty publish [--agent]
281
+ ```
282
+
283
+ - Builds and bundles the block
284
+ - Publishes to the marketplace (free only via CLI)
285
+ - Makes block discoverable by all users
286
+ - Optional `--agent` flag makes block insertable by AI agents (requires Mext staff permissions)
287
+
288
+ **Example:**
289
+
290
+ ```bash
291
+ mexty publish --agent
292
+ ```
293
+
294
+ ### Block Management
295
+
296
+ ```bash
297
+ mexty delete <blockId>
298
+ ```
299
+
300
+ Deletes a block (requires ownership).
301
+
302
+ ### Command Workflow
303
+
304
+ 1. **Create a new block:**
305
+
306
+ ```bash
307
+ mexty create block --name "My Widget" --description "An awesome widget" --category "utility"
308
+ ```
309
+
310
+ 2. **Develop your block:**
311
+
312
+ - Edit `src/block.tsx` to implement your component
313
+ - Define TypeScript interfaces for props
314
+ - Test locally with `npm start`
315
+
316
+ 3. **Save your progress:**
317
+
318
+ ```bash
319
+ mexty save
320
+ ```
321
+
322
+ 4. **Publish to marketplace:**
323
+ ```bash
324
+ mexty publish --agent
325
+ ```
326
+
327
+ ### CLI Features
328
+
329
+ - **Automatic GitHub Integration**: Creates and manages repositories
330
+ - **TypeScript Support**: Full TypeScript development environment
331
+ - **Props Schema Detection**: Automatically generates props schema from TypeScript interfaces
332
+ - **Federation Bundling**: Creates optimized bundles for embedding
333
+ - **Marketplace Publishing**: One-command publishing to the marketplace
334
+ - **AI Agent Integration**: Optional agent insertability for automated content creation
335
+
229
336
  This system enables rapid creation of interactive content while maintaining consistency, reusability, and ease of customization for end users.
337
+
338
+ # @mexty/realtime
339
+
340
+ React hooks for real-time collaborative features using Yjs and Hocuspocus.
341
+
342
+ ## Installation
343
+
344
+ ```bash
345
+ npm install @mexty/realtime
346
+ ```
347
+
348
+ ## Usage
349
+
350
+ ```tsx
351
+ import { useCollabSpace } from "@mexty/realtime";
352
+
353
+ // 🧠 Example 1: Collaborative JSON document editor
354
+ export function DocumentEditor({ blockId }: { blockId: string }) {
355
+ const { state, update } = useCollabSpace(`block:${blockId}`, {
356
+ document: {
357
+ title: "Untitled",
358
+ content: "Write something...",
359
+ },
360
+ game: { weights: [] },
361
+ });
362
+
363
+ // ✅ Partial update usage
364
+ const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
365
+ update({ document: { ...state.document, title: e.target.value } });
366
+ };
367
+
368
+ // ✅ Functional update usage
369
+ const resetContent = () => {
370
+ update((prev) => ({
371
+ ...prev,
372
+ document: { ...prev.document, content: "" },
373
+ }));
374
+ };
375
+
376
+ return (
377
+ <div className="p-4 border rounded space-y-3">
378
+ <h2 className="text-lg font-bold">Collaborative Document</h2>
379
+ <input
380
+ type="text"
381
+ className="border p-2 w-full"
382
+ value={state.document.title}
383
+ onChange={handleTitleChange}
384
+ />
385
+ <textarea
386
+ className="border p-2 w-full h-32"
387
+ value={state.document.content}
388
+ onChange={(e) =>
389
+ update({ document: { ...state.document, content: e.target.value } })
390
+ }
391
+ />
392
+ <button
393
+ onClick={resetContent}
394
+ className="bg-blue-500 text-white px-3 py-1 rounded"
395
+ >
396
+ Reset Content
397
+ </button>
398
+ </div>
399
+ );
400
+ }
401
+
402
+ // 🧩 Example 2: Multiplayer tower game state
403
+ export function TowerGame({ blockId }: { blockId: string }) {
404
+ const { state, update } = useCollabSpace(`block:${blockId}`, {
405
+ document: {},
406
+ game: { weights: [] as { team: string; pos: number }[] },
407
+ });
408
+
409
+ // ✅ Append new weight (functional update)
410
+ const addWeight = (team: string) => {
411
+ update((prev) => ({
412
+ ...prev,
413
+ game: {
414
+ ...prev.game,
415
+ weights: [...prev.game.weights, { team, pos: Math.random() * 100 }],
416
+ },
417
+ }));
418
+ };
419
+
420
+ // ✅ Clear game state (partial update)
421
+ const resetGame = () => {
422
+ update({ game: { weights: [] } });
423
+ };
424
+
425
+ return (
426
+ <div className="p-4 border rounded space-y-3">
427
+ <h2 className="text-lg font-bold">Tower Game</h2>
428
+ <button
429
+ onClick={() => addWeight("blue")}
430
+ className="bg-blue-600 text-white px-3 py-1 rounded"
431
+ >
432
+ Add Blue Weight
433
+ </button>
434
+ <button
435
+ onClick={() => addWeight("red")}
436
+ className="bg-red-600 text-white px-3 py-1 rounded"
437
+ >
438
+ Add Red Weight
439
+ </button>
440
+ <button
441
+ onClick={resetGame}
442
+ className="bg-gray-600 text-white px-3 py-1 rounded"
443
+ >
444
+ Reset Game
445
+ </button>
446
+
447
+ <pre className="bg-gray-100 p-2 text-sm rounded overflow-auto">
448
+ {JSON.stringify(state.game, null, 2)}
449
+ </pre>
450
+ </div>
451
+ );
452
+ }
453
+ ```
454
+
455
+ ## API
456
+
457
+ ### `useCollabSpace(documentName, initialState, options?)`
458
+
459
+ #### Parameters
460
+
461
+ - `documentName: string` - Unique identifier for the collaborative document
462
+ - `initialState: T` - Initial state object for the collaborative space
463
+ - `options?: CollabSpaceOptions` - Optional configuration
464
+
465
+ #### Returns
466
+
467
+ - `state: T` - Current collaborative state
468
+ - `update: (updateFn: UpdateFunction<T>) => void` - Function to update state
469
+ - `isConnected: boolean` - WebSocket connection status
470
+ - `connectionStatus: 'connecting' | 'connected' | 'disconnected' | 'error'` - Detailed connection status
471
+ - `userId: string` - Anonymous user ID (persisted in localStorage)
472
+
473
+ #### Options
474
+
475
+ ```tsx
476
+ interface CollabSpaceOptions {
477
+ websocketUrl?: string;
478
+ onConnect?: () => void;
479
+ onDisconnect?: () => void;
480
+ onError?: (error: Error) => void;
481
+ }
482
+ ```
483
+
484
+ ## Features
485
+
486
+ - 🔄 Real-time collaborative state synchronization
487
+ - 🆔 Anonymous user authentication with persistent IDs
488
+ - 🔗 Automatic WebSocket connection management
489
+ - 📱 React hooks for easy integration
490
+ - 🎯 TypeScript support with full type safety
491
+ - 🏗️ Built on Yjs and Hocuspocus for reliability
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mexty/cli",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "MEXT CLI for managing blocks and repositories",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -113,6 +113,20 @@ export async function createCommand(
113
113
  chalk.gray(` Block Type: ${block.blockType || block._doc?.blockType}`)
114
114
  );
115
115
 
116
+ // Add the block to user's structure
117
+ console.log(chalk.yellow("📚 Adding block to your library..."));
118
+ try {
119
+ await apiClient.addBlockToStructure(block.id || block._id);
120
+ console.log(chalk.green(`✅ Block added to your library!`));
121
+ } catch (structureError: any) {
122
+ console.warn(
123
+ chalk.yellow(
124
+ `⚠️ Block created but couldn't add to library: ${structureError.message}`
125
+ )
126
+ );
127
+ console.log(chalk.gray(" The block is still accessible via the API"));
128
+ }
129
+
116
130
  // Handle both plain objects and Mongoose documents
117
131
  const gitUrl = block.gitUrl || block._doc?.gitUrl;
118
132
  if (gitUrl) {
package/src/utils/api.ts CHANGED
@@ -283,6 +283,17 @@ class ApiClient {
283
283
  return data;
284
284
  }
285
285
 
286
+ async addBlockToStructure(
287
+ blockId: string,
288
+ parentPath?: string
289
+ ): Promise<any> {
290
+ const response = await this.client.post("/api/structure/add-block", {
291
+ blockId,
292
+ parentPath: parentPath || "/",
293
+ });
294
+ return response.data;
295
+ }
296
+
286
297
  async logout(): Promise<void> {
287
298
  try {
288
299
  await this.client.post("/api/auth/logout");