decoupled-cli 2.4.1 → 2.4.2
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 +242 -10
- package/package.json +1 -1
- package/dist/commands/download.d.ts +0 -4
- package/dist/commands/download.d.ts.map +0 -1
- package/dist/commands/download.js +0 -127
- package/dist/commands/download.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# Decoupled Drupal CLI (decoupled-cli)
|
|
2
2
|
|
|
3
|
-
A command-line interface for managing Decoupled Drupal spaces, monitoring usage, and
|
|
3
|
+
A command-line interface for managing Decoupled Drupal spaces, monitoring usage, and enabling AI assistants to interact with your platform through the Model Context Protocol (MCP).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 **Secure Authentication** - OAuth (Google/GitHub) and Personal Access Tokens
|
|
8
|
+
- 🤖 **AI Integration** - Model Context Protocol support for Claude Code and Cursor
|
|
9
|
+
- 📦 **Space Management** - Create, clone, delete, and monitor Drupal spaces
|
|
10
|
+
- 📊 **Usage Monitoring** - Track storage, bandwidth, and API requests
|
|
11
|
+
- 🚀 **Quick Start** - AI-powered space creation with generated content
|
|
12
|
+
- 📥 **Content Import** - Import content models and data to Drupal
|
|
4
13
|
|
|
5
14
|
## Installation
|
|
6
15
|
|
|
@@ -128,6 +137,72 @@ The CLI stores configuration in `~/.decoupled-cli/config.json`:
|
|
|
128
137
|
|
|
129
138
|
Actual tokens are stored securely using the system keychain (macOS Keychain, Windows Credential Manager, or Linux Secret Service).
|
|
130
139
|
|
|
140
|
+
## AI Integration with MCP
|
|
141
|
+
|
|
142
|
+
The CLI supports the Model Context Protocol (MCP), enabling AI assistants in **Claude Code** and **Cursor** to manage your Drupal spaces using natural language.
|
|
143
|
+
|
|
144
|
+
### Setup
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Log in first (if not already)
|
|
148
|
+
decoupled-cli auth login
|
|
149
|
+
|
|
150
|
+
# Configure MCP for Claude Code
|
|
151
|
+
decoupled-cli mcp configure --ide claude-code
|
|
152
|
+
|
|
153
|
+
# Or configure for Cursor
|
|
154
|
+
decoupled-cli mcp configure --ide cursor
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
After configuration, restart your IDE and you can interact with your platform naturally:
|
|
158
|
+
|
|
159
|
+
**Example conversations:**
|
|
160
|
+
```
|
|
161
|
+
You: "Show me all my Drupal spaces"
|
|
162
|
+
AI: Lists all your spaces with status and URLs
|
|
163
|
+
|
|
164
|
+
You: "Create a blog space called Tech News"
|
|
165
|
+
AI: Creates the space and returns the ID and URL
|
|
166
|
+
|
|
167
|
+
You: "What's my current storage usage?"
|
|
168
|
+
AI: Shows organization-wide usage statistics
|
|
169
|
+
|
|
170
|
+
You: "Clone space 5 and name it Staging"
|
|
171
|
+
AI: Clones the space with all content
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Available MCP Commands
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Configure MCP for an IDE
|
|
178
|
+
decoupled-cli mcp configure [--ide <claude-code|cursor>]
|
|
179
|
+
|
|
180
|
+
# Show configuration status
|
|
181
|
+
decoupled-cli mcp status
|
|
182
|
+
|
|
183
|
+
# Remove MCP configuration
|
|
184
|
+
decoupled-cli mcp remove
|
|
185
|
+
|
|
186
|
+
# Show config without writing (for manual setup)
|
|
187
|
+
decoupled-cli mcp configure --show-only
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### What AI Can Do
|
|
191
|
+
|
|
192
|
+
- **Read Operations:**
|
|
193
|
+
- List all spaces with details
|
|
194
|
+
- Get space information
|
|
195
|
+
- View usage statistics
|
|
196
|
+
- Check organization details
|
|
197
|
+
|
|
198
|
+
- **Write Operations:**
|
|
199
|
+
- Create new spaces
|
|
200
|
+
- Clone existing spaces
|
|
201
|
+
- Delete spaces
|
|
202
|
+
- Import content models and data
|
|
203
|
+
|
|
204
|
+
All operations use your existing authentication and permissions.
|
|
205
|
+
|
|
131
206
|
## Commands
|
|
132
207
|
|
|
133
208
|
### Spaces Management
|
|
@@ -289,6 +364,58 @@ decoupled-cli spaces retry 123
|
|
|
289
364
|
decoupled-cli spaces refresh-usage 123
|
|
290
365
|
```
|
|
291
366
|
|
|
367
|
+
### Content Management
|
|
368
|
+
|
|
369
|
+
#### Import Content
|
|
370
|
+
```bash
|
|
371
|
+
# Import content model and data from JSON file
|
|
372
|
+
decoupled-cli content import --file content-import.json
|
|
373
|
+
|
|
374
|
+
# Preview import without applying changes
|
|
375
|
+
decoupled-cli content import --file content-import.json --preview
|
|
376
|
+
|
|
377
|
+
# Show example import JSON structure
|
|
378
|
+
decoupled-cli content import --example
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Import JSON Format:**
|
|
382
|
+
```json
|
|
383
|
+
{
|
|
384
|
+
"model": [
|
|
385
|
+
{
|
|
386
|
+
"bundle": "blog_post",
|
|
387
|
+
"label": "Blog Post",
|
|
388
|
+
"description": "Blog article content type",
|
|
389
|
+
"body": true,
|
|
390
|
+
"fields": [
|
|
391
|
+
{
|
|
392
|
+
"id": "subtitle",
|
|
393
|
+
"label": "Subtitle",
|
|
394
|
+
"type": "string"
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"id": "featured_image",
|
|
398
|
+
"label": "Featured Image",
|
|
399
|
+
"type": "image"
|
|
400
|
+
}
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
],
|
|
404
|
+
"content": [
|
|
405
|
+
{
|
|
406
|
+
"id": "post1",
|
|
407
|
+
"type": "node.blog_post",
|
|
408
|
+
"path": "/blog/my-first-post",
|
|
409
|
+
"values": {
|
|
410
|
+
"title": "My First Post",
|
|
411
|
+
"body": "<p>Post content here</p>",
|
|
412
|
+
"subtitle": "An introduction"
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
]
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
292
419
|
### Usage Monitoring
|
|
293
420
|
|
|
294
421
|
#### Organization Usage
|
|
@@ -506,6 +633,7 @@ decoupled-cli auth test --permissions
|
|
|
506
633
|
|
|
507
634
|
The CLI directly uses the Decoupled Drupal API with these endpoints:
|
|
508
635
|
|
|
636
|
+
**Space Management:**
|
|
509
637
|
- `GET /api/spaces` - List spaces
|
|
510
638
|
- `POST /api/spaces` - Create space
|
|
511
639
|
- `GET /api/spaces/{id}` - Get space details
|
|
@@ -514,17 +642,121 @@ The CLI directly uses the Decoupled Drupal API with these endpoints:
|
|
|
514
642
|
- `POST /api/spaces/{id}/clone` - Clone space
|
|
515
643
|
- `POST /api/spaces/{id}/archive` - Archive space
|
|
516
644
|
- `POST /api/spaces/{id}/unarchive` - Unarchive space
|
|
645
|
+
|
|
646
|
+
**Content Operations:**
|
|
647
|
+
- `POST /api/spaces/{id}/content-import` - Import content model and data
|
|
648
|
+
|
|
649
|
+
**Usage & Monitoring:**
|
|
517
650
|
- `GET /api/usage` - Get usage data
|
|
518
|
-
-
|
|
651
|
+
- `GET /api/organization` - Get organization details
|
|
652
|
+
|
|
653
|
+
**MCP (Model Context Protocol):**
|
|
654
|
+
- `GET /api/mcp/sse` - SSE connection for MCP clients
|
|
655
|
+
- `POST /api/mcp/messages` - JSON-RPC 2.0 message handler
|
|
656
|
+
|
|
657
|
+
**Authentication:**
|
|
658
|
+
- Token management endpoints (web interface only at `/organization/tokens`)
|
|
519
659
|
|
|
520
660
|
## Contributing
|
|
521
661
|
|
|
522
662
|
The CLI is built with:
|
|
523
|
-
- Node.js/TypeScript
|
|
524
|
-
- Commander.js
|
|
525
|
-
-
|
|
526
|
-
-
|
|
527
|
-
-
|
|
528
|
-
-
|
|
529
|
-
|
|
530
|
-
|
|
663
|
+
- **Node.js/TypeScript** - Core runtime and type safety
|
|
664
|
+
- **Commander.js** - CLI framework and command parsing
|
|
665
|
+
- **Inquirer** - Interactive prompts
|
|
666
|
+
- **Axios** - HTTP requests for API calls
|
|
667
|
+
- **Keytar** - Secure credential storage (system keychain)
|
|
668
|
+
- **Chalk** - Colored terminal output
|
|
669
|
+
- **CLI-table3** - Formatted table output
|
|
670
|
+
- **Open** - Cross-platform browser opening
|
|
671
|
+
|
|
672
|
+
### Development
|
|
673
|
+
|
|
674
|
+
```bash
|
|
675
|
+
# Clone repository
|
|
676
|
+
git clone https://github.com/nextagencyio/decoupled-dashboard.git
|
|
677
|
+
cd decoupled-dashboard/cli
|
|
678
|
+
|
|
679
|
+
# Install dependencies
|
|
680
|
+
npm install
|
|
681
|
+
|
|
682
|
+
# Build TypeScript
|
|
683
|
+
npm run build
|
|
684
|
+
|
|
685
|
+
# Run locally
|
|
686
|
+
npm start -- [command]
|
|
687
|
+
|
|
688
|
+
# Watch mode for development
|
|
689
|
+
npm run dev
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### Project Structure
|
|
693
|
+
|
|
694
|
+
```
|
|
695
|
+
cli/
|
|
696
|
+
├── src/
|
|
697
|
+
│ ├── commands/ # CLI command implementations
|
|
698
|
+
│ │ ├── auth.ts # Authentication commands
|
|
699
|
+
│ │ ├── auth-interactive.ts # OAuth flow
|
|
700
|
+
│ │ ├── spaces.ts # Space management
|
|
701
|
+
│ │ ├── content.ts # Content import
|
|
702
|
+
│ │ ├── mcp.ts # MCP configuration
|
|
703
|
+
│ │ ├── usage.ts # Usage statistics
|
|
704
|
+
│ │ ├── org.ts # Organization management
|
|
705
|
+
│ │ ├── health.ts # Health checks
|
|
706
|
+
│ │ └── config.ts # CLI configuration
|
|
707
|
+
│ ├── lib/ # Shared utilities
|
|
708
|
+
│ │ ├── api.ts # API client
|
|
709
|
+
│ │ └── config.ts # Config management
|
|
710
|
+
│ └── index.ts # CLI entry point
|
|
711
|
+
├── examples/ # Example files
|
|
712
|
+
│ └── content-import-sample.json
|
|
713
|
+
└── package.json
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
## Version & Updates
|
|
717
|
+
|
|
718
|
+
```bash
|
|
719
|
+
# Check current version
|
|
720
|
+
decoupled-cli --version
|
|
721
|
+
|
|
722
|
+
# Update to latest
|
|
723
|
+
npm install -g decoupled-cli@latest
|
|
724
|
+
|
|
725
|
+
# View changelog
|
|
726
|
+
npm view decoupled-cli versions
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
**Current Version:** 2.4.1
|
|
730
|
+
|
|
731
|
+
**Recent Changes:**
|
|
732
|
+
- Added Model Context Protocol (MCP) support
|
|
733
|
+
- Implemented OAuth authentication flow
|
|
734
|
+
- Added content import functionality
|
|
735
|
+
- Removed legacy AI configuration files
|
|
736
|
+
|
|
737
|
+
## Getting Help
|
|
738
|
+
|
|
739
|
+
```bash
|
|
740
|
+
# General help
|
|
741
|
+
decoupled-cli --help
|
|
742
|
+
|
|
743
|
+
# Command-specific help
|
|
744
|
+
decoupled-cli [command] --help
|
|
745
|
+
|
|
746
|
+
# Examples
|
|
747
|
+
decoupled-cli spaces --help
|
|
748
|
+
decoupled-cli mcp configure --help
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
**Additional Resources:**
|
|
752
|
+
- Documentation: Check the main repository docs
|
|
753
|
+
- Issues: Report bugs on GitHub
|
|
754
|
+
- Support: Contact through the dashboard
|
|
755
|
+
|
|
756
|
+
## License
|
|
757
|
+
|
|
758
|
+
MIT
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
Made with ❤️ by the Decoupled.io team
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decoupled-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "Command-line interface for managing Decoupled Drupal spaces, deploying content, and automating workflows. Features AI-powered quick-start, content import, and CI/CD integration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/commands/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,QAAA,MAAM,eAAe,SAA0B,CAAC;AAiGhD,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.downloadCommand = void 0;
|
|
40
|
-
const commander_1 = require("commander");
|
|
41
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
-
const fs = __importStar(require("fs"));
|
|
43
|
-
const path = __importStar(require("path"));
|
|
44
|
-
const downloadCommand = new commander_1.Command('download');
|
|
45
|
-
exports.downloadCommand = downloadCommand;
|
|
46
|
-
downloadCommand
|
|
47
|
-
.description('Download AI configuration files')
|
|
48
|
-
.argument('<file>', 'AI config file to download (cursorrules, claude, gemini)')
|
|
49
|
-
.action(async (file) => {
|
|
50
|
-
try {
|
|
51
|
-
// Normalize the file argument
|
|
52
|
-
const availableFiles = {
|
|
53
|
-
'cursorrules': { filename: '.cursorrules', displayName: 'Cursor Rules' },
|
|
54
|
-
'cursor': { filename: '.cursorrules', displayName: 'Cursor Rules' },
|
|
55
|
-
'claude': { filename: 'CLAUDE.md', displayName: 'Claude Code Configuration' },
|
|
56
|
-
'gemini': { filename: 'GEMINI.md', displayName: 'Google Gemini Configuration' }
|
|
57
|
-
};
|
|
58
|
-
const normalizedFile = file.toLowerCase();
|
|
59
|
-
if (!availableFiles[normalizedFile]) {
|
|
60
|
-
console.error(chalk_1.default.red(`❌ Unknown file: ${file}`));
|
|
61
|
-
console.log(chalk_1.default.gray('\nAvailable files:'));
|
|
62
|
-
Object.entries(availableFiles).forEach(([key, config]) => {
|
|
63
|
-
console.log(chalk_1.default.gray(` • ${key} → ${config.filename} (${config.displayName})`));
|
|
64
|
-
});
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
const fileConfig = availableFiles[normalizedFile];
|
|
68
|
-
const sourceFileName = fileConfig.filename;
|
|
69
|
-
const displayName = fileConfig.displayName;
|
|
70
|
-
// Get the directory where the CLI is installed
|
|
71
|
-
const cliDir = path.resolve(__dirname, '../..');
|
|
72
|
-
const examplesDir = path.join(cliDir, 'examples');
|
|
73
|
-
const sourcePath = path.join(examplesDir, sourceFileName);
|
|
74
|
-
// Check if source file exists
|
|
75
|
-
if (!fs.existsSync(sourcePath)) {
|
|
76
|
-
console.error(chalk_1.default.red(`❌ Source file not found: ${sourcePath}`));
|
|
77
|
-
process.exit(1);
|
|
78
|
-
}
|
|
79
|
-
// Destination path (current working directory)
|
|
80
|
-
const destPath = path.join(process.cwd(), sourceFileName);
|
|
81
|
-
// Check if destination file already exists
|
|
82
|
-
if (fs.existsSync(destPath)) {
|
|
83
|
-
const { default: inquirer } = await Promise.resolve().then(() => __importStar(require('inquirer')));
|
|
84
|
-
const answers = await inquirer.prompt([
|
|
85
|
-
{
|
|
86
|
-
type: 'confirm',
|
|
87
|
-
name: 'overwrite',
|
|
88
|
-
message: `File ${sourceFileName} already exists. Overwrite?`,
|
|
89
|
-
default: false
|
|
90
|
-
}
|
|
91
|
-
]);
|
|
92
|
-
if (!answers.overwrite) {
|
|
93
|
-
console.log(chalk_1.default.yellow('Operation cancelled.'));
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// Read and write the file
|
|
98
|
-
const content = fs.readFileSync(sourcePath, 'utf8');
|
|
99
|
-
fs.writeFileSync(destPath, content, 'utf8');
|
|
100
|
-
console.log(chalk_1.default.green(`✅ Downloaded ${displayName}`));
|
|
101
|
-
console.log(chalk_1.default.gray(`📁 Saved to: ${destPath}`));
|
|
102
|
-
// Show file size and first few lines as preview
|
|
103
|
-
const stats = fs.statSync(destPath);
|
|
104
|
-
const lines = content.split('\n');
|
|
105
|
-
const previewLines = lines.slice(0, 3).join('\n');
|
|
106
|
-
console.log(chalk_1.default.gray(`📊 Size: ${stats.size} bytes`));
|
|
107
|
-
console.log(chalk_1.default.gray('📄 Preview:'));
|
|
108
|
-
console.log(chalk_1.default.dim(previewLines + (lines.length > 3 ? '\n...' : '')));
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
console.error(chalk_1.default.red('❌ Failed to download file:'), error instanceof Error ? error.message : String(error));
|
|
112
|
-
process.exit(1);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
// Add help examples
|
|
116
|
-
downloadCommand.addHelpText('after', `
|
|
117
|
-
Examples:
|
|
118
|
-
decoupled-cli download cursorrules Download .cursorrules file for Cursor AI
|
|
119
|
-
decoupled-cli download claude Download CLAUDE.md configuration
|
|
120
|
-
decoupled-cli download gemini Download GEMINI.md configuration
|
|
121
|
-
|
|
122
|
-
Available Files:
|
|
123
|
-
• cursorrules/.cursor → .cursorrules (Cursor AI configuration)
|
|
124
|
-
• claude → CLAUDE.md (Claude Code configuration)
|
|
125
|
-
• gemini → GEMINI.md (Google Gemini configuration)
|
|
126
|
-
`);
|
|
127
|
-
//# sourceMappingURL=download.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/commands/download.ts"],"names":[],"mappings":"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"}
|