myaidev-method 0.1.0 → 0.2.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.
- package/.env.example +20 -0
- package/PUBLISHING_GUIDE.md +521 -0
- package/README.md +123 -25
- package/package.json +25 -3
- package/src/lib/payloadcms-utils.js +394 -0
- package/src/lib/static-site-utils.js +377 -0
- package/src/scripts/astro-publish.js +209 -0
- package/src/scripts/docusaurus-publish.js +209 -0
- package/src/scripts/init-project.js +91 -0
- package/src/scripts/mintlify-publish.js +205 -0
- package/src/scripts/payloadcms-publish.js +202 -0
- package/src/templates/claude/agents/astro-publish.md +43 -0
- package/src/templates/claude/agents/docusaurus-publish.md +42 -0
- package/src/templates/claude/agents/mintlify-publish.md +42 -0
- package/src/templates/claude/agents/payloadcms-publish.md +134 -0
- package/src/templates/claude/commands/myai-astro-publish.md +54 -0
- package/src/templates/claude/commands/myai-docusaurus-publish.md +45 -0
- package/src/templates/claude/commands/myai-mintlify-publish.md +45 -0
- package/src/templates/claude/commands/myai-payloadcms-publish.md +45 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Site Publishing Utilities
|
|
3
|
+
* Unified utilities for publishing to static site generators
|
|
4
|
+
* Supports: Docusaurus, Mintlify, Astro
|
|
5
|
+
* Optimized for Claude Code 2.0 agent integration
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
9
|
+
import { join, dirname, basename } from 'path';
|
|
10
|
+
import { parse as parseEnv } from 'dotenv';
|
|
11
|
+
import grayMatter from 'gray-matter';
|
|
12
|
+
import simpleGit from 'simple-git';
|
|
13
|
+
|
|
14
|
+
// Platform configurations
|
|
15
|
+
const platformConfigs = {
|
|
16
|
+
docusaurus: {
|
|
17
|
+
contentDirs: {
|
|
18
|
+
docs: 'docs',
|
|
19
|
+
blog: 'blog',
|
|
20
|
+
pages: 'src/pages'
|
|
21
|
+
},
|
|
22
|
+
frontmatterFields: ['id', 'title', 'sidebar_label', 'sidebar_position', 'description', 'tags'],
|
|
23
|
+
configFile: 'docusaurus.config.js',
|
|
24
|
+
sidebarFile: 'sidebars.js',
|
|
25
|
+
fileExtensions: ['.md', '.mdx'],
|
|
26
|
+
requiresNavUpdate: false
|
|
27
|
+
},
|
|
28
|
+
mintlify: {
|
|
29
|
+
contentDirs: {
|
|
30
|
+
default: '.'
|
|
31
|
+
},
|
|
32
|
+
frontmatterFields: ['title', 'description', 'icon', 'iconType'],
|
|
33
|
+
configFile: 'mint.json',
|
|
34
|
+
requiresNavUpdate: true,
|
|
35
|
+
fileExtensions: ['.mdx'],
|
|
36
|
+
defaultExtension: '.mdx'
|
|
37
|
+
},
|
|
38
|
+
astro: {
|
|
39
|
+
contentDirs: {
|
|
40
|
+
content: 'src/content',
|
|
41
|
+
pages: 'src/pages'
|
|
42
|
+
},
|
|
43
|
+
frontmatterFields: ['title', 'description', 'pubDate', 'author', 'image', 'tags'],
|
|
44
|
+
configFile: 'astro.config.mjs',
|
|
45
|
+
collectionSchema: true,
|
|
46
|
+
fileExtensions: ['.md', '.mdx'],
|
|
47
|
+
requiresNavUpdate: false
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export class StaticSiteUtils {
|
|
52
|
+
constructor(config = {}) {
|
|
53
|
+
this.platform = config.platform;
|
|
54
|
+
|
|
55
|
+
// Load platform-specific configuration
|
|
56
|
+
if (!this.platform || !platformConfigs[this.platform]) {
|
|
57
|
+
throw new Error(`Invalid platform. Supported: ${Object.keys(platformConfigs).join(', ')}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.platformConfig = platformConfigs[this.platform];
|
|
61
|
+
|
|
62
|
+
// Load project path from config or .env
|
|
63
|
+
this.projectPath = config.projectPath || this.loadProjectPath();
|
|
64
|
+
|
|
65
|
+
// Load git configuration
|
|
66
|
+
const envConfig = this.loadEnvConfig();
|
|
67
|
+
this.gitUserName = config.gitUserName || envConfig.GIT_USER_NAME;
|
|
68
|
+
this.gitUserEmail = config.gitUserEmail || envConfig.GIT_USER_EMAIL;
|
|
69
|
+
this.gitRemote = config.gitRemote || envConfig.GIT_REMOTE_URL || 'origin';
|
|
70
|
+
|
|
71
|
+
// Initialize git
|
|
72
|
+
this.git = simpleGit(this.projectPath);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
loadEnvConfig() {
|
|
76
|
+
try {
|
|
77
|
+
const envPath = process.env.ENV_PATH || '.env';
|
|
78
|
+
if (existsSync(envPath)) {
|
|
79
|
+
const envContent = readFileSync(envPath, 'utf8');
|
|
80
|
+
return parseEnv(envContent);
|
|
81
|
+
}
|
|
82
|
+
return {};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
loadProjectPath() {
|
|
89
|
+
const envConfig = this.loadEnvConfig();
|
|
90
|
+
const envKey = `${this.platform.toUpperCase()}_PROJECT_PATH`;
|
|
91
|
+
return envConfig[envKey] || process.cwd();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Validate project structure
|
|
96
|
+
*/
|
|
97
|
+
validateProject() {
|
|
98
|
+
const configPath = join(this.projectPath, this.platformConfig.configFile);
|
|
99
|
+
|
|
100
|
+
if (!existsSync(configPath)) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`${this.platform} project not found. Missing ${this.platformConfig.configFile} in ${this.projectPath}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check if git repository
|
|
107
|
+
const gitPath = join(this.projectPath, '.git');
|
|
108
|
+
if (!existsSync(gitPath)) {
|
|
109
|
+
throw new Error(`Not a git repository: ${this.projectPath}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Transform frontmatter for platform-specific requirements
|
|
117
|
+
*/
|
|
118
|
+
transformFrontmatter(frontmatter) {
|
|
119
|
+
const allowedFields = this.platformConfig.frontmatterFields;
|
|
120
|
+
const transformed = {};
|
|
121
|
+
|
|
122
|
+
// Only include allowed fields
|
|
123
|
+
for (const field of allowedFields) {
|
|
124
|
+
if (frontmatter[field] !== undefined) {
|
|
125
|
+
transformed[field] = frontmatter[field];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Platform-specific transformations
|
|
130
|
+
switch (this.platform) {
|
|
131
|
+
case 'docusaurus':
|
|
132
|
+
// Generate id from title if not provided
|
|
133
|
+
if (!transformed.id && transformed.title) {
|
|
134
|
+
transformed.id = transformed.title
|
|
135
|
+
.toLowerCase()
|
|
136
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
137
|
+
.replace(/^-|-$/g, '');
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
|
|
141
|
+
case 'mintlify':
|
|
142
|
+
// Mintlify requires title
|
|
143
|
+
if (!transformed.title) {
|
|
144
|
+
throw new Error('title is required in frontmatter for Mintlify');
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
|
|
148
|
+
case 'astro':
|
|
149
|
+
// Add pubDate if not present
|
|
150
|
+
if (!transformed.pubDate) {
|
|
151
|
+
transformed.pubDate = new Date().toISOString();
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return transformed;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Determine target directory based on content type
|
|
161
|
+
*/
|
|
162
|
+
getTargetDirectory(options = {}) {
|
|
163
|
+
const contentType = options.type || 'docs';
|
|
164
|
+
const dirs = this.platformConfig.contentDirs;
|
|
165
|
+
|
|
166
|
+
const baseDir = dirs[contentType] || dirs.default || dirs.docs;
|
|
167
|
+
|
|
168
|
+
if (!baseDir) {
|
|
169
|
+
throw new Error(`Unknown content type: ${contentType}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const targetDir = join(this.projectPath, baseDir);
|
|
173
|
+
|
|
174
|
+
// Create directory if it doesn't exist
|
|
175
|
+
if (!existsSync(targetDir)) {
|
|
176
|
+
mkdirSync(targetDir, { recursive: true });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return targetDir;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Generate filename with appropriate extension
|
|
184
|
+
*/
|
|
185
|
+
generateFilename(title, originalFile) {
|
|
186
|
+
const ext = this.platformConfig.defaultExtension ||
|
|
187
|
+
this.platformConfig.fileExtensions[0] || '.md';
|
|
188
|
+
|
|
189
|
+
// If original file has allowed extension, use it
|
|
190
|
+
if (originalFile) {
|
|
191
|
+
const originalExt = originalFile.substring(originalFile.lastIndexOf('.'));
|
|
192
|
+
if (this.platformConfig.fileExtensions.includes(originalExt)) {
|
|
193
|
+
return basename(originalFile);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Generate from title
|
|
198
|
+
const slug = title
|
|
199
|
+
.toLowerCase()
|
|
200
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
201
|
+
.replace(/^-|-$/g, '');
|
|
202
|
+
|
|
203
|
+
return `${slug}${ext}`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Publish markdown content to static site
|
|
208
|
+
*/
|
|
209
|
+
async publishContent(markdownFile, options = {}) {
|
|
210
|
+
// Validate project
|
|
211
|
+
this.validateProject();
|
|
212
|
+
|
|
213
|
+
// Read and parse markdown
|
|
214
|
+
const fileContent = readFileSync(markdownFile, 'utf8');
|
|
215
|
+
const { data: frontmatter, content } = grayMatter(fileContent);
|
|
216
|
+
|
|
217
|
+
// Transform frontmatter
|
|
218
|
+
const transformedFrontmatter = this.transformFrontmatter(frontmatter);
|
|
219
|
+
|
|
220
|
+
// Get target directory
|
|
221
|
+
const targetDir = this.getTargetDirectory(options);
|
|
222
|
+
|
|
223
|
+
// Generate filename
|
|
224
|
+
const filename = options.filename ||
|
|
225
|
+
this.generateFilename(transformedFrontmatter.title, markdownFile);
|
|
226
|
+
|
|
227
|
+
const targetPath = join(targetDir, filename);
|
|
228
|
+
|
|
229
|
+
// Combine frontmatter and content
|
|
230
|
+
const output = grayMatter.stringify(content, transformedFrontmatter);
|
|
231
|
+
|
|
232
|
+
// Write file
|
|
233
|
+
writeFileSync(targetPath, output, 'utf8');
|
|
234
|
+
|
|
235
|
+
// Update navigation if required
|
|
236
|
+
if (this.platformConfig.requiresNavUpdate) {
|
|
237
|
+
await this.updateNavigation(filename, transformedFrontmatter, options);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Git operations
|
|
241
|
+
const gitResult = await this.gitCommitAndPush(targetPath, options);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
success: true,
|
|
245
|
+
file: targetPath,
|
|
246
|
+
platform: this.platform,
|
|
247
|
+
git: gitResult
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Update navigation configuration (Mintlify)
|
|
253
|
+
*/
|
|
254
|
+
async updateNavigation(filename, frontmatter, options = {}) {
|
|
255
|
+
if (this.platform !== 'mintlify') {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const mintJsonPath = join(this.projectPath, 'mint.json');
|
|
260
|
+
|
|
261
|
+
if (!existsSync(mintJsonPath)) {
|
|
262
|
+
console.warn('mint.json not found, skipping navigation update');
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
const mintConfig = JSON.parse(readFileSync(mintJsonPath, 'utf8'));
|
|
268
|
+
|
|
269
|
+
// Add to navigation if specified
|
|
270
|
+
if (options.navSection) {
|
|
271
|
+
const section = mintConfig.navigation?.find(nav => nav.group === options.navSection);
|
|
272
|
+
|
|
273
|
+
if (section) {
|
|
274
|
+
const pagePath = filename.replace(/\.mdx?$/, '');
|
|
275
|
+
|
|
276
|
+
if (!section.pages.includes(pagePath)) {
|
|
277
|
+
section.pages.push(pagePath);
|
|
278
|
+
writeFileSync(mintJsonPath, JSON.stringify(mintConfig, null, 2), 'utf8');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.warn(`Failed to update mint.json: ${error.message}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Git commit and push changes
|
|
289
|
+
*/
|
|
290
|
+
async gitCommitAndPush(filePath, options = {}) {
|
|
291
|
+
try {
|
|
292
|
+
// Configure git if credentials provided
|
|
293
|
+
if (this.gitUserName && this.gitUserEmail) {
|
|
294
|
+
await this.git.addConfig('user.name', this.gitUserName, false);
|
|
295
|
+
await this.git.addConfig('user.email', this.gitUserEmail, false);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Stage file
|
|
299
|
+
await this.git.add(filePath);
|
|
300
|
+
|
|
301
|
+
// Commit
|
|
302
|
+
const commitMessage = options.commitMessage ||
|
|
303
|
+
`Add/Update ${basename(filePath)} via myaidev-method`;
|
|
304
|
+
|
|
305
|
+
await this.git.commit(commitMessage);
|
|
306
|
+
|
|
307
|
+
// Push if not in dry-run mode
|
|
308
|
+
if (!options.dryRun && !options.noPush) {
|
|
309
|
+
const branch = options.branch || 'main';
|
|
310
|
+
await this.git.push(this.gitRemote, branch);
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
committed: true,
|
|
314
|
+
pushed: true,
|
|
315
|
+
branch,
|
|
316
|
+
message: commitMessage
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
committed: true,
|
|
322
|
+
pushed: false,
|
|
323
|
+
message: commitMessage
|
|
324
|
+
};
|
|
325
|
+
} catch (error) {
|
|
326
|
+
throw new Error(`Git operation failed: ${error.message}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Get git status
|
|
332
|
+
*/
|
|
333
|
+
async getGitStatus() {
|
|
334
|
+
try {
|
|
335
|
+
return await this.git.status();
|
|
336
|
+
} catch (error) {
|
|
337
|
+
throw new Error(`Failed to get git status: ${error.message}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* List content files in project
|
|
343
|
+
*/
|
|
344
|
+
listContent(contentType = 'docs') {
|
|
345
|
+
const targetDir = this.getTargetDirectory({ type: contentType });
|
|
346
|
+
const fs = await import('fs');
|
|
347
|
+
|
|
348
|
+
const files = fs.readdirSync(targetDir)
|
|
349
|
+
.filter(file => {
|
|
350
|
+
const ext = file.substring(file.lastIndexOf('.'));
|
|
351
|
+
return this.platformConfig.fileExtensions.includes(ext);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
return files.map(file => join(targetDir, file));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export default StaticSiteUtils;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Helper function to detect platform from project structure
|
|
362
|
+
*/
|
|
363
|
+
export function detectPlatform(projectPath = process.cwd()) {
|
|
364
|
+
const checks = {
|
|
365
|
+
docusaurus: join(projectPath, 'docusaurus.config.js'),
|
|
366
|
+
mintlify: join(projectPath, 'mint.json'),
|
|
367
|
+
astro: join(projectPath, 'astro.config.mjs')
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
for (const [platform, configPath] of Object.entries(checks)) {
|
|
371
|
+
if (existsSync(configPath)) {
|
|
372
|
+
return platform;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Astro Publishing Script
|
|
5
|
+
* Publish markdown content to Astro site
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { StaticSiteUtils } from '../lib/static-site-utils.js';
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
|
|
12
|
+
const options = {
|
|
13
|
+
file: null,
|
|
14
|
+
type: 'content',
|
|
15
|
+
projectPath: null,
|
|
16
|
+
branch: 'main',
|
|
17
|
+
noPush: false,
|
|
18
|
+
commitMessage: null,
|
|
19
|
+
json: args.includes('--json'),
|
|
20
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
21
|
+
dryRun: args.includes('--dry-run')
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Parse arguments
|
|
25
|
+
for (let i = 0; i < args.length; i++) {
|
|
26
|
+
switch (args[i]) {
|
|
27
|
+
case '--file':
|
|
28
|
+
case '-f':
|
|
29
|
+
options.file = args[++i];
|
|
30
|
+
break;
|
|
31
|
+
case '--type':
|
|
32
|
+
case '-t':
|
|
33
|
+
options.type = args[++i];
|
|
34
|
+
break;
|
|
35
|
+
case '--project':
|
|
36
|
+
case '-p':
|
|
37
|
+
options.projectPath = args[++i];
|
|
38
|
+
break;
|
|
39
|
+
case '--branch':
|
|
40
|
+
case '-b':
|
|
41
|
+
options.branch = args[++i];
|
|
42
|
+
break;
|
|
43
|
+
case '--no-push':
|
|
44
|
+
options.noPush = true;
|
|
45
|
+
break;
|
|
46
|
+
case '--message':
|
|
47
|
+
case '-m':
|
|
48
|
+
options.commitMessage = args[++i];
|
|
49
|
+
break;
|
|
50
|
+
case '--help':
|
|
51
|
+
case '-h':
|
|
52
|
+
printHelp();
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// If no file specified, check positional argument
|
|
58
|
+
if (!options.file && args.length > 0 && !args[0].startsWith('-')) {
|
|
59
|
+
options.file = args[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function printHelp() {
|
|
63
|
+
console.log(`
|
|
64
|
+
Astro Publishing Script
|
|
65
|
+
|
|
66
|
+
Usage: astro-publish [file] [options]
|
|
67
|
+
|
|
68
|
+
Arguments:
|
|
69
|
+
file Markdown file to publish (required)
|
|
70
|
+
|
|
71
|
+
Options:
|
|
72
|
+
--type, -t <type> Content type: content|pages (default: content)
|
|
73
|
+
--project, -p <path> Astro project path
|
|
74
|
+
--branch, -b <branch> Git branch to push to (default: main)
|
|
75
|
+
--no-push Commit but don't push to remote
|
|
76
|
+
--message, -m <msg> Custom commit message
|
|
77
|
+
--dry-run Validate without committing
|
|
78
|
+
--verbose, -v Show detailed progress
|
|
79
|
+
--json Output in JSON format
|
|
80
|
+
--help, -h Show this help
|
|
81
|
+
|
|
82
|
+
Examples:
|
|
83
|
+
# Publish to content collection
|
|
84
|
+
astro-publish article.md
|
|
85
|
+
|
|
86
|
+
# Publish to pages
|
|
87
|
+
astro-publish page.md --type pages
|
|
88
|
+
|
|
89
|
+
# Custom project path and branch
|
|
90
|
+
astro-publish article.md --project ./my-astro-site --branch develop
|
|
91
|
+
|
|
92
|
+
# Commit only (no push)
|
|
93
|
+
astro-publish article.md --no-push
|
|
94
|
+
`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function publishContent() {
|
|
98
|
+
try {
|
|
99
|
+
// Validate required options
|
|
100
|
+
if (!options.file) {
|
|
101
|
+
console.error('Error: Markdown file is required');
|
|
102
|
+
console.error('Run with --help for usage information');
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (options.verbose) {
|
|
107
|
+
console.error('Initializing Astro publishing...');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const site = new StaticSiteUtils({
|
|
111
|
+
platform: 'astro',
|
|
112
|
+
projectPath: options.projectPath
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (options.verbose) {
|
|
116
|
+
console.error('✓ Astro project detected');
|
|
117
|
+
console.error(`Publishing to: ${options.type}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Validate project
|
|
121
|
+
site.validateProject();
|
|
122
|
+
|
|
123
|
+
if (options.verbose) {
|
|
124
|
+
console.error('✓ Project structure validated');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Dry run - validate only
|
|
128
|
+
if (options.dryRun) {
|
|
129
|
+
if (options.verbose) {
|
|
130
|
+
console.error('✓ Dry run - validation successful');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const output = {
|
|
134
|
+
success: true,
|
|
135
|
+
dryRun: true,
|
|
136
|
+
file: options.file,
|
|
137
|
+
platform: 'astro',
|
|
138
|
+
type: options.type
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
if (options.json) {
|
|
142
|
+
console.log(JSON.stringify(output, null, 2));
|
|
143
|
+
} else {
|
|
144
|
+
console.log('Dry run successful - ready to publish');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Publish content
|
|
151
|
+
const result = await site.publishContent(options.file, {
|
|
152
|
+
type: options.type,
|
|
153
|
+
branch: options.branch,
|
|
154
|
+
noPush: options.noPush,
|
|
155
|
+
commitMessage: options.commitMessage
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
if (options.verbose) {
|
|
159
|
+
console.error(`✓ Content published successfully`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Prepare output
|
|
163
|
+
const output = {
|
|
164
|
+
success: true,
|
|
165
|
+
file: result.file,
|
|
166
|
+
platform: result.platform,
|
|
167
|
+
git: result.git,
|
|
168
|
+
timestamp: new Date().toISOString()
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
if (options.json) {
|
|
172
|
+
console.log(JSON.stringify(output, null, 2));
|
|
173
|
+
} else {
|
|
174
|
+
console.log('\\n' + '='.repeat(60));
|
|
175
|
+
console.log('Astro Publishing Result');
|
|
176
|
+
console.log('='.repeat(60));
|
|
177
|
+
console.log(`Status: ✓ Success`);
|
|
178
|
+
console.log(`File: ${result.file}`);
|
|
179
|
+
console.log(`Committed: ${result.git.committed ? 'Yes' : 'No'}`);
|
|
180
|
+
console.log(`Pushed: ${result.git.pushed ? 'Yes' : 'No'}`);
|
|
181
|
+
if (result.git.branch) {
|
|
182
|
+
console.log(`Branch: ${result.git.branch}`);
|
|
183
|
+
}
|
|
184
|
+
console.log('='.repeat(60));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
process.exit(0);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (options.json) {
|
|
190
|
+
console.log(JSON.stringify({
|
|
191
|
+
success: false,
|
|
192
|
+
error: error.message,
|
|
193
|
+
timestamp: new Date().toISOString()
|
|
194
|
+
}, null, 2));
|
|
195
|
+
} else {
|
|
196
|
+
console.error(`\\nError: ${error.message}`);
|
|
197
|
+
if (options.verbose) {
|
|
198
|
+
console.error(`Stack: ${error.stack}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
206
|
+
publishContent();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { publishContent };
|