myaidev-method 0.2.19 ā 0.2.23
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/CHANGELOG.md +123 -5
- package/README.md +205 -13
- package/TECHNICAL_ARCHITECTURE.md +64 -2
- package/USER_GUIDE.md +453 -48
- package/bin/cli.js +187 -2
- package/content-rules.example.md +80 -0
- package/dist/mcp/mcp-config.json +138 -1
- package/dist/mcp/mcp-launcher.js +237 -0
- package/dist/mcp/openstack-server.js +1607 -0
- package/dist/server/.tsbuildinfo +1 -1
- package/dist/server/auth/layers.d.ts +1 -1
- package/dist/server/auth/services/AuthService.d.ts +1 -1
- package/dist/server/auth/services/TokenService.js.map +1 -1
- package/dist/server/auth/services/example.d.ts +5 -5
- package/package.json +17 -17
- package/src/config/workflows.js +532 -0
- package/src/index.js +21 -8
- package/src/lib/payloadcms-utils.js +206 -0
- package/src/lib/update-manager.js +2 -1
- package/src/lib/visual-config-utils.js +321 -295
- package/src/lib/visual-generation-utils.js +1080 -740
- package/src/lib/workflow-installer.js +512 -0
- package/src/libs/security/authorization-checker.js +606 -0
- package/src/mcp/openstack-server.js +1607 -0
- package/src/scripts/configure-wordpress-mcp.js +8 -3
- package/src/scripts/generate-visual-cli.js +365 -235
- package/src/scripts/openstack-setup.sh +110 -0
- package/src/scripts/ping.js +250 -0
- package/src/scripts/security/environment-detect.js +425 -0
- package/src/scripts/wordpress/publish-to-wordpress.js +165 -0
- package/src/server/auth/services/TokenService.ts +1 -1
- package/src/templates/claude/agents/content-rules-setup.md +657 -0
- package/src/templates/claude/agents/content-writer.md +328 -1
- package/src/templates/claude/agents/openstack-vm-manager.md +281 -0
- package/src/templates/claude/agents/osint-researcher.md +1075 -0
- package/src/templates/claude/agents/penetration-tester.md +908 -0
- package/src/templates/claude/agents/security-auditor.md +244 -0
- package/src/templates/claude/agents/security-setup.md +1094 -0
- package/src/templates/claude/agents/visual-content-generator.md +182 -4
- package/src/templates/claude/agents/webapp-security-tester.md +581 -0
- package/src/templates/claude/commands/myai-configure.md +85 -1
- package/src/templates/claude/commands/myai-content-rules-setup.md +204 -0
- package/src/templates/claude/commands/myai-openstack.md +229 -0
- package/src/templates/claude/commands/sc:security-exploit.md +464 -0
- package/src/templates/claude/commands/sc:security-recon.md +281 -0
- package/src/templates/claude/commands/sc:security-report.md +756 -0
- package/src/templates/claude/commands/sc:security-scan.md +441 -0
- package/src/templates/claude/commands/sc:security-setup.md +501 -0
- package/src/templates/codex/commands/myai-content-rules-setup.md +85 -0
- package/src/templates/gemini/commands/myai-content-rules-setup.toml +57 -0
- package/.claude/mcp/sparc-orchestrator-server.js +0 -607
- package/.claude/mcp/wordpress-server.js +0 -1277
- package/src/agents/content-writer-prompt.md +0 -164
- package/src/agents/content-writer.json +0 -70
- package/src/templates/claude/mcp_config.json +0 -30
- package/src/templates/claude/slash_commands.json +0 -166
- package/src/templates/scripts/configure-wordpress-mcp.js +0 -181
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MyAIDev Method - Security Environment Detection
|
|
5
|
+
*
|
|
6
|
+
* Detects execution environment and recommends setup approach
|
|
7
|
+
* @module security/environment-detect
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Environment types
|
|
15
|
+
*/
|
|
16
|
+
const EnvType = {
|
|
17
|
+
KALI_NATIVE: 'kali_native',
|
|
18
|
+
KALI_DOCKER: 'kali_docker',
|
|
19
|
+
UBUNTU_NATIVE: 'ubuntu_native',
|
|
20
|
+
DEBIAN_NATIVE: 'debian_native',
|
|
21
|
+
FEDORA_NATIVE: 'fedora_native',
|
|
22
|
+
DOCKER_CONTAINER: 'docker_container',
|
|
23
|
+
UNKNOWN: 'unknown'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Environment detection class
|
|
28
|
+
*/
|
|
29
|
+
class EnvironmentDetector {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.osInfo = {};
|
|
32
|
+
this.containerInfo = {};
|
|
33
|
+
this.toolsInfo = {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Detect execution environment
|
|
38
|
+
*/
|
|
39
|
+
async detect() {
|
|
40
|
+
console.log('š Detecting security testing environment...\n');
|
|
41
|
+
|
|
42
|
+
// Detect OS
|
|
43
|
+
this.detectOS();
|
|
44
|
+
|
|
45
|
+
// Detect container environment
|
|
46
|
+
this.detectContainer();
|
|
47
|
+
|
|
48
|
+
// Check Docker availability
|
|
49
|
+
this.detectDocker();
|
|
50
|
+
|
|
51
|
+
// Check existing tools
|
|
52
|
+
this.detectTools();
|
|
53
|
+
|
|
54
|
+
// Generate recommendation
|
|
55
|
+
const recommendation = this.generateRecommendation();
|
|
56
|
+
|
|
57
|
+
// Display results
|
|
58
|
+
this.displayResults(recommendation);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
os: this.osInfo,
|
|
62
|
+
container: this.containerInfo,
|
|
63
|
+
tools: this.toolsInfo,
|
|
64
|
+
recommendation
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Detect operating system
|
|
70
|
+
*/
|
|
71
|
+
detectOS() {
|
|
72
|
+
try {
|
|
73
|
+
// Check if /etc/os-release exists
|
|
74
|
+
if (fs.existsSync('/etc/os-release')) {
|
|
75
|
+
const osRelease = fs.readFileSync('/etc/os-release', 'utf8');
|
|
76
|
+
|
|
77
|
+
// Parse OS release file
|
|
78
|
+
const lines = osRelease.split('\n');
|
|
79
|
+
for (const line of lines) {
|
|
80
|
+
const [key, value] = line.split('=');
|
|
81
|
+
if (value) {
|
|
82
|
+
this.osInfo[key] = value.replace(/"/g, '');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Determine OS type
|
|
87
|
+
const id = this.osInfo.ID || '';
|
|
88
|
+
if (id.includes('kali')) {
|
|
89
|
+
this.osInfo.type = EnvType.KALI_NATIVE;
|
|
90
|
+
} else if (id.includes('ubuntu')) {
|
|
91
|
+
this.osInfo.type = EnvType.UBUNTU_NATIVE;
|
|
92
|
+
} else if (id.includes('debian')) {
|
|
93
|
+
this.osInfo.type = EnvType.DEBIAN_NATIVE;
|
|
94
|
+
} else if (id.includes('fedora') || id.includes('rhel') || id.includes('centos')) {
|
|
95
|
+
this.osInfo.type = EnvType.FEDORA_NATIVE;
|
|
96
|
+
} else {
|
|
97
|
+
this.osInfo.type = EnvType.UNKNOWN;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Get kernel version
|
|
102
|
+
try {
|
|
103
|
+
this.osInfo.kernel = execSync('uname -r', { encoding: 'utf8' }).trim();
|
|
104
|
+
} catch (err) {
|
|
105
|
+
this.osInfo.kernel = 'unknown';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Detect package manager
|
|
109
|
+
if (this.commandExists('apt')) {
|
|
110
|
+
this.osInfo.packageManager = 'apt';
|
|
111
|
+
} else if (this.commandExists('dnf')) {
|
|
112
|
+
this.osInfo.packageManager = 'dnf';
|
|
113
|
+
} else if (this.commandExists('yum')) {
|
|
114
|
+
this.osInfo.packageManager = 'yum';
|
|
115
|
+
} else if (this.commandExists('pacman')) {
|
|
116
|
+
this.osInfo.packageManager = 'pacman';
|
|
117
|
+
} else {
|
|
118
|
+
this.osInfo.packageManager = 'unknown';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
} catch (err) {
|
|
122
|
+
console.error('Error detecting OS:', err.message);
|
|
123
|
+
this.osInfo.type = EnvType.UNKNOWN;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Detect container environment
|
|
129
|
+
*/
|
|
130
|
+
detectContainer() {
|
|
131
|
+
try {
|
|
132
|
+
// Check for /.dockerenv
|
|
133
|
+
if (fs.existsSync('/.dockerenv')) {
|
|
134
|
+
this.containerInfo.isContainer = true;
|
|
135
|
+
this.containerInfo.type = 'docker';
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Check cgroup for docker/container
|
|
140
|
+
if (fs.existsSync('/proc/1/cgroup')) {
|
|
141
|
+
const cgroup = fs.readFileSync('/proc/1/cgroup', 'utf8');
|
|
142
|
+
if (cgroup.includes('docker')) {
|
|
143
|
+
this.containerInfo.isContainer = true;
|
|
144
|
+
this.containerInfo.type = 'docker';
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (cgroup.includes('kubepods')) {
|
|
148
|
+
this.containerInfo.isContainer = true;
|
|
149
|
+
this.containerInfo.type = 'kubernetes';
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.containerInfo.isContainer = false;
|
|
155
|
+
} catch (err) {
|
|
156
|
+
this.containerInfo.isContainer = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Detect Docker availability
|
|
162
|
+
*/
|
|
163
|
+
detectDocker() {
|
|
164
|
+
try {
|
|
165
|
+
if (this.commandExists('docker')) {
|
|
166
|
+
const version = execSync('docker --version', { encoding: 'utf8' }).trim();
|
|
167
|
+
this.containerInfo.dockerAvailable = true;
|
|
168
|
+
this.containerInfo.dockerVersion = version;
|
|
169
|
+
|
|
170
|
+
// Check if Docker daemon is running
|
|
171
|
+
try {
|
|
172
|
+
execSync('docker ps', { encoding: 'utf8', stdio: 'ignore' });
|
|
173
|
+
this.containerInfo.dockerRunning = true;
|
|
174
|
+
} catch (err) {
|
|
175
|
+
this.containerInfo.dockerRunning = false;
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
this.containerInfo.dockerAvailable = false;
|
|
179
|
+
}
|
|
180
|
+
} catch (err) {
|
|
181
|
+
this.containerInfo.dockerAvailable = false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Detect existing security tools
|
|
187
|
+
*/
|
|
188
|
+
detectTools() {
|
|
189
|
+
const essentialTools = [
|
|
190
|
+
'nmap',
|
|
191
|
+
'masscan',
|
|
192
|
+
'sqlmap',
|
|
193
|
+
'nikto',
|
|
194
|
+
'hydra',
|
|
195
|
+
'john',
|
|
196
|
+
'hashcat',
|
|
197
|
+
'metasploit-framework',
|
|
198
|
+
'burpsuite',
|
|
199
|
+
'zaproxy'
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
const commandMap = {
|
|
203
|
+
'metasploit-framework': 'msfconsole',
|
|
204
|
+
'burpsuite': 'burpsuite',
|
|
205
|
+
'zaproxy': 'zaproxy'
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const installed = [];
|
|
209
|
+
const missing = [];
|
|
210
|
+
|
|
211
|
+
for (const tool of essentialTools) {
|
|
212
|
+
const command = commandMap[tool] || tool;
|
|
213
|
+
if (this.commandExists(command)) {
|
|
214
|
+
installed.push(tool);
|
|
215
|
+
} else {
|
|
216
|
+
missing.push(tool);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this.toolsInfo.installed = installed;
|
|
221
|
+
this.toolsInfo.missing = missing;
|
|
222
|
+
this.toolsInfo.installCount = installed.length;
|
|
223
|
+
this.toolsInfo.totalCount = essentialTools.length;
|
|
224
|
+
this.toolsInfo.percentInstalled = Math.round((installed.length / essentialTools.length) * 100);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check if command exists
|
|
229
|
+
*/
|
|
230
|
+
commandExists(command) {
|
|
231
|
+
try {
|
|
232
|
+
execSync(`which ${command}`, { stdio: 'ignore' });
|
|
233
|
+
return true;
|
|
234
|
+
} catch (err) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Generate setup recommendation
|
|
241
|
+
*/
|
|
242
|
+
generateRecommendation() {
|
|
243
|
+
const rec = {
|
|
244
|
+
approach: '',
|
|
245
|
+
reason: '',
|
|
246
|
+
steps: [],
|
|
247
|
+
estimatedTime: '',
|
|
248
|
+
diskSpace: ''
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// If already Kali Linux
|
|
252
|
+
if (this.osInfo.type === EnvType.KALI_NATIVE) {
|
|
253
|
+
rec.approach = 'verify_tools';
|
|
254
|
+
rec.reason = 'Kali Linux detected - most tools pre-installed';
|
|
255
|
+
rec.steps = [
|
|
256
|
+
'Update package lists: sudo apt update',
|
|
257
|
+
'Upgrade packages: sudo apt upgrade',
|
|
258
|
+
'Verify tool installations',
|
|
259
|
+
'Install any missing tools'
|
|
260
|
+
];
|
|
261
|
+
rec.estimatedTime = '10-15 minutes';
|
|
262
|
+
rec.diskSpace = '~500MB';
|
|
263
|
+
return rec;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// If Kali Docker available
|
|
267
|
+
if (this.containerInfo.dockerAvailable && this.containerInfo.dockerRunning) {
|
|
268
|
+
rec.approach = 'kali_docker';
|
|
269
|
+
rec.reason = 'Docker available - isolated environment recommended';
|
|
270
|
+
rec.steps = [
|
|
271
|
+
'Pull Kali Linux Docker image',
|
|
272
|
+
'Create persistent volume',
|
|
273
|
+
'Start Kali container with capabilities',
|
|
274
|
+
'Install kali-linux-default package',
|
|
275
|
+
'Verify tool installations'
|
|
276
|
+
];
|
|
277
|
+
rec.estimatedTime = '20-30 minutes';
|
|
278
|
+
rec.diskSpace = '~3GB';
|
|
279
|
+
return rec;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// If Docker available but not running
|
|
283
|
+
if (this.containerInfo.dockerAvailable && !this.containerInfo.dockerRunning) {
|
|
284
|
+
rec.approach = 'kali_docker';
|
|
285
|
+
rec.reason = 'Docker installed but not running';
|
|
286
|
+
rec.steps = [
|
|
287
|
+
'Start Docker service: sudo systemctl start docker',
|
|
288
|
+
'Pull Kali Linux Docker image',
|
|
289
|
+
'Create persistent volume',
|
|
290
|
+
'Start Kali container',
|
|
291
|
+
'Install security tools'
|
|
292
|
+
];
|
|
293
|
+
rec.estimatedTime = '25-35 minutes';
|
|
294
|
+
rec.diskSpace = '~3GB';
|
|
295
|
+
return rec;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Native installation (no Docker)
|
|
299
|
+
if (this.osInfo.type === EnvType.UBUNTU_NATIVE ||
|
|
300
|
+
this.osInfo.type === EnvType.DEBIAN_NATIVE) {
|
|
301
|
+
rec.approach = 'native_install';
|
|
302
|
+
rec.reason = 'Native Linux installation - direct tool installation';
|
|
303
|
+
rec.steps = [
|
|
304
|
+
'Update package lists',
|
|
305
|
+
'Install network scanning tools (nmap, masscan)',
|
|
306
|
+
'Install web testing tools (sqlmap, nikto)',
|
|
307
|
+
'Install exploitation tools (metasploit)',
|
|
308
|
+
'Install password tools (john, hashcat, hydra)',
|
|
309
|
+
'Verify installations'
|
|
310
|
+
];
|
|
311
|
+
rec.estimatedTime = '45-60 minutes';
|
|
312
|
+
rec.diskSpace = '~2GB';
|
|
313
|
+
return rec;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Fedora/RHEL/CentOS
|
|
317
|
+
if (this.osInfo.type === EnvType.FEDORA_NATIVE) {
|
|
318
|
+
rec.approach = 'native_install';
|
|
319
|
+
rec.reason = 'Fedora/RHEL system - native installation with DNF';
|
|
320
|
+
rec.steps = [
|
|
321
|
+
'Enable EPEL repository',
|
|
322
|
+
'Update system: sudo dnf update',
|
|
323
|
+
'Install security tools via DNF',
|
|
324
|
+
'Install remaining tools from source',
|
|
325
|
+
'Verify installations'
|
|
326
|
+
];
|
|
327
|
+
rec.estimatedTime = '45-60 minutes';
|
|
328
|
+
rec.diskSpace = '~2GB';
|
|
329
|
+
return rec;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Fallback - recommend Docker
|
|
333
|
+
rec.approach = 'install_docker_first';
|
|
334
|
+
rec.reason = 'Unknown environment - Docker installation recommended';
|
|
335
|
+
rec.steps = [
|
|
336
|
+
'Install Docker: curl -fsSL https://get.docker.com | sh',
|
|
337
|
+
'Start Docker service',
|
|
338
|
+
'Follow Kali Docker setup',
|
|
339
|
+
'Install security tools in container'
|
|
340
|
+
];
|
|
341
|
+
rec.estimatedTime = '30-45 minutes';
|
|
342
|
+
rec.diskSpace = '~3.5GB';
|
|
343
|
+
return rec;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Display detection results
|
|
348
|
+
*/
|
|
349
|
+
displayResults(recommendation) {
|
|
350
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
351
|
+
console.log('š Environment Detection Results');
|
|
352
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
353
|
+
|
|
354
|
+
// OS Information
|
|
355
|
+
console.log('š Operating System:');
|
|
356
|
+
console.log(` Name: ${this.osInfo.NAME || 'Unknown'}`);
|
|
357
|
+
console.log(` Version: ${this.osInfo.VERSION || 'Unknown'}`);
|
|
358
|
+
console.log(` ID: ${this.osInfo.ID || 'Unknown'}`);
|
|
359
|
+
console.log(` Kernel: ${this.osInfo.kernel || 'Unknown'}`);
|
|
360
|
+
console.log(` Package Manager: ${this.osInfo.packageManager || 'Unknown'}\n`);
|
|
361
|
+
|
|
362
|
+
// Container Information
|
|
363
|
+
console.log('š³ Container Environment:');
|
|
364
|
+
console.log(` Running in Container: ${this.containerInfo.isContainer ? 'Yes' : 'No'}`);
|
|
365
|
+
if (this.containerInfo.isContainer) {
|
|
366
|
+
console.log(` Container Type: ${this.containerInfo.type}`);
|
|
367
|
+
}
|
|
368
|
+
console.log(` Docker Available: ${this.containerInfo.dockerAvailable ? 'Yes' : 'No'}`);
|
|
369
|
+
if (this.containerInfo.dockerAvailable) {
|
|
370
|
+
console.log(` Docker Version: ${this.containerInfo.dockerVersion}`);
|
|
371
|
+
console.log(` Docker Running: ${this.containerInfo.dockerRunning ? 'Yes' : 'No'}`);
|
|
372
|
+
}
|
|
373
|
+
console.log();
|
|
374
|
+
|
|
375
|
+
// Security Tools
|
|
376
|
+
console.log('š ļø Security Tools:');
|
|
377
|
+
console.log(` Installed: ${this.toolsInfo.installCount}/${this.toolsInfo.totalCount} (${this.toolsInfo.percentInstalled}%)`);
|
|
378
|
+
if (this.toolsInfo.installed.length > 0) {
|
|
379
|
+
console.log(` Found: ${this.toolsInfo.installed.slice(0, 5).join(', ')}${this.toolsInfo.installed.length > 5 ? '...' : ''}`);
|
|
380
|
+
}
|
|
381
|
+
console.log();
|
|
382
|
+
|
|
383
|
+
// Recommendation
|
|
384
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
385
|
+
console.log('š Recommended Setup Approach');
|
|
386
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
387
|
+
console.log(`⨠Approach: ${recommendation.approach.toUpperCase().replace(/_/g, ' ')}`);
|
|
388
|
+
console.log(`š Reason: ${recommendation.reason}`);
|
|
389
|
+
console.log(`ā±ļø Estimated Time: ${recommendation.estimatedTime}`);
|
|
390
|
+
console.log(`š¾ Disk Space: ${recommendation.diskSpace}\n`);
|
|
391
|
+
|
|
392
|
+
console.log('š Setup Steps:');
|
|
393
|
+
recommendation.steps.forEach((step, index) => {
|
|
394
|
+
console.log(` ${index + 1}. ${step}`);
|
|
395
|
+
});
|
|
396
|
+
console.log();
|
|
397
|
+
|
|
398
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Main execution
|
|
404
|
+
*/
|
|
405
|
+
async function main() {
|
|
406
|
+
const detector = new EnvironmentDetector();
|
|
407
|
+
const result = await detector.detect();
|
|
408
|
+
|
|
409
|
+
// Save results to JSON for programmatic use
|
|
410
|
+
const outputPath = '/tmp/security-env-detect.json';
|
|
411
|
+
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
|
|
412
|
+
console.log(`š Results saved to: ${outputPath}\n`);
|
|
413
|
+
|
|
414
|
+
process.exit(0);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Run if executed directly
|
|
418
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
419
|
+
main().catch(err => {
|
|
420
|
+
console.error('ā Error:', err.message);
|
|
421
|
+
process.exit(1);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export { EnvironmentDetector, EnvType };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Publish markdown content to WordPress
|
|
4
|
+
*
|
|
5
|
+
* Usage: node publish-to-wordpress.js <file-path> [--status draft|publish]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from "fs";
|
|
9
|
+
import { resolve } from "path";
|
|
10
|
+
import matter from "gray-matter";
|
|
11
|
+
import dotenv from "dotenv";
|
|
12
|
+
import { marked } from "marked";
|
|
13
|
+
import { GutenbergConverter } from "../../mcp/gutenberg-converter.js";
|
|
14
|
+
import { WordPressMCP } from "../../mcp/wordpress-integration.js";
|
|
15
|
+
|
|
16
|
+
// Load environment variables
|
|
17
|
+
dotenv.config();
|
|
18
|
+
|
|
19
|
+
// Parse command line arguments
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
const filePath = args[0];
|
|
22
|
+
const statusIndex = args.indexOf("--status");
|
|
23
|
+
const requestedStatus =
|
|
24
|
+
statusIndex !== -1 && args[statusIndex + 1] ? args[statusIndex + 1] : "draft";
|
|
25
|
+
|
|
26
|
+
if (!filePath) {
|
|
27
|
+
console.error("Error: File path is required");
|
|
28
|
+
console.error(
|
|
29
|
+
"Usage: node publish-to-wordpress.js <file-path> [--status draft|publish]",
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Validate WordPress configuration
|
|
35
|
+
if (
|
|
36
|
+
!process.env.WORDPRESS_URL ||
|
|
37
|
+
!process.env.WORDPRESS_USERNAME ||
|
|
38
|
+
!process.env.WORDPRESS_APP_PASSWORD
|
|
39
|
+
) {
|
|
40
|
+
console.error("Error: WordPress configuration is incomplete");
|
|
41
|
+
console.error("Required environment variables:");
|
|
42
|
+
console.error(" - WORDPRESS_URL");
|
|
43
|
+
console.error(" - WORDPRESS_USERNAME");
|
|
44
|
+
console.error(" - WORDPRESS_APP_PASSWORD");
|
|
45
|
+
console.error(
|
|
46
|
+
"\nRun /myai-configure wordpress to set up your WordPress connection",
|
|
47
|
+
);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function publishToWordPress() {
|
|
52
|
+
try {
|
|
53
|
+
// Read and parse markdown file
|
|
54
|
+
const absolutePath = resolve(filePath);
|
|
55
|
+
const fileContent = readFileSync(absolutePath, "utf-8");
|
|
56
|
+
const { data: frontmatter, content } = matter(fileContent);
|
|
57
|
+
|
|
58
|
+
console.log("š Processing file:", filePath);
|
|
59
|
+
console.log("š Title:", frontmatter.title || "No title");
|
|
60
|
+
|
|
61
|
+
// Extract interactive blocks before markdown conversion
|
|
62
|
+
// const { markdown: cleanMarkdown, interactiveBlocks } =
|
|
63
|
+
// GutenbergConverter.extractInteractiveBlocks(content);
|
|
64
|
+
|
|
65
|
+
// if (interactiveBlocks.length > 0) {
|
|
66
|
+
// console.log(
|
|
67
|
+
// ` Interactive blocks: ${interactiveBlocks.length} found`,
|
|
68
|
+
// );
|
|
69
|
+
// }
|
|
70
|
+
|
|
71
|
+
// Convert markdown to HTML using marked (preserves placeholders)
|
|
72
|
+
const html = marked.parse(content);
|
|
73
|
+
|
|
74
|
+
// Convert HTML to Gutenberg blocks
|
|
75
|
+
let htmlContent = GutenbergConverter.htmlToGutenberg(html);
|
|
76
|
+
|
|
77
|
+
// Restore interactive blocks as raw HTML blocks
|
|
78
|
+
// if (interactiveBlocks.length > 0) {
|
|
79
|
+
// htmlContent = GutenbergConverter.restoreInteractiveBlocks(
|
|
80
|
+
// htmlContent,
|
|
81
|
+
// interactiveBlocks,
|
|
82
|
+
// );
|
|
83
|
+
// }
|
|
84
|
+
|
|
85
|
+
// Prepare WordPress configuration
|
|
86
|
+
const config = {
|
|
87
|
+
endpoint: {
|
|
88
|
+
url: process.env.WORDPRESS_URL,
|
|
89
|
+
api_version: "wp/v2",
|
|
90
|
+
authentication: {
|
|
91
|
+
username: process.env.WORDPRESS_USERNAME,
|
|
92
|
+
password: process.env.WORDPRESS_APP_PASSWORD,
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
defaults: {
|
|
96
|
+
post_status: requestedStatus,
|
|
97
|
+
format: "standard",
|
|
98
|
+
comment_status: "open",
|
|
99
|
+
ping_status: "open",
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Initialize WordPress client
|
|
104
|
+
const wp = new WordPressMCP(config);
|
|
105
|
+
|
|
106
|
+
// Prepare post data
|
|
107
|
+
const postParams = {
|
|
108
|
+
title: frontmatter.title || "Untitled",
|
|
109
|
+
content: htmlContent,
|
|
110
|
+
status: requestedStatus,
|
|
111
|
+
excerpt: frontmatter.meta_description || "",
|
|
112
|
+
slug: frontmatter.slug || "",
|
|
113
|
+
use_gutenberg: process.env.USE_GUTENBERG === "true",
|
|
114
|
+
// Note: Tags and categories require ID mapping which will be added in future versions
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
console.log("š Publishing to WordPress...");
|
|
118
|
+
console.log(" URL:", process.env.WORDPRESS_URL);
|
|
119
|
+
console.log(" Status:", requestedStatus);
|
|
120
|
+
console.log(
|
|
121
|
+
" Format:",
|
|
122
|
+
postParams.use_gutenberg ? "Gutenberg" : "Classic",
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Create the post
|
|
126
|
+
const result = await wp.createPost(postParams);
|
|
127
|
+
|
|
128
|
+
// Success!
|
|
129
|
+
console.log("\nā
Successfully published to WordPress!");
|
|
130
|
+
console.log("\nš Post Details:");
|
|
131
|
+
console.log(" Post ID:", result.id);
|
|
132
|
+
console.log(" Title:", result.title.rendered);
|
|
133
|
+
console.log(" Status:", result.status);
|
|
134
|
+
console.log(" Slug:", result.slug);
|
|
135
|
+
|
|
136
|
+
console.log("\nš URLs:");
|
|
137
|
+
console.log(" View:", result.link);
|
|
138
|
+
console.log(
|
|
139
|
+
" Edit:",
|
|
140
|
+
`${process.env.WORDPRESS_URL}/wp-admin/post.php?post=${result.id}&action=edit`,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
return result;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error("\nā Error publishing to WordPress:");
|
|
146
|
+
console.error(error.message);
|
|
147
|
+
|
|
148
|
+
if (error.message.includes("401")) {
|
|
149
|
+
console.error("\nš Authentication failed. Please check:");
|
|
150
|
+
console.error(" 1. Your WordPress username is correct");
|
|
151
|
+
console.error(" 2. Your Application Password is valid");
|
|
152
|
+
console.error(" 3. Application Passwords are enabled on your site");
|
|
153
|
+
} else if (error.message.includes("404")) {
|
|
154
|
+
console.error("\nš WordPress site not found. Please check:");
|
|
155
|
+
console.error(" 1. Your WORDPRESS_URL is correct");
|
|
156
|
+
console.error(" 2. The site is accessible");
|
|
157
|
+
console.error(" 3. The REST API is enabled");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Run the publisher
|
|
165
|
+
publishToWordPress();
|
|
@@ -6,7 +6,7 @@ import { AuthError, JWTPayload } from "../../../shared/types.js";
|
|
|
6
6
|
const TOKEN_EXPIRY_DAYS = 7;
|
|
7
7
|
const ALGORITHM = "RS256";
|
|
8
8
|
|
|
9
|
-
let keyPair: { publicKey: jose.
|
|
9
|
+
let keyPair: { publicKey: jose.CryptoKey; privateKey: jose.CryptoKey } | null = null;
|
|
10
10
|
|
|
11
11
|
export class TokenService extends Context.Tag("TokenService")<
|
|
12
12
|
TokenService,
|