apero-kit-cli 1.4.1 → 1.5.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/bin/ak.js +1 -1
- package/package.json +1 -1
- package/src/commands/help.js +0 -11
- package/templates/scripts/plan-preview.cjs +271 -57
package/bin/ak.js
CHANGED
|
@@ -10,7 +10,7 @@ import { statusCommand } from '../src/commands/status.js';
|
|
|
10
10
|
import { doctorCommand } from '../src/commands/doctor.js';
|
|
11
11
|
import { helpCommand } from '../src/commands/help.js';
|
|
12
12
|
|
|
13
|
-
const VERSION = '1.4.
|
|
13
|
+
const VERSION = '1.4.2';
|
|
14
14
|
|
|
15
15
|
console.log(chalk.cyan.bold('\n Apero Kit CLI') + chalk.gray(` v${VERSION}\n`));
|
|
16
16
|
|
package/package.json
CHANGED
package/src/commands/help.js
CHANGED
|
@@ -703,17 +703,6 @@ function generateNav(activeSection, t, lang) {
|
|
|
703
703
|
</a>
|
|
704
704
|
`).join('')}
|
|
705
705
|
</div>
|
|
706
|
-
<div class="nav-section">
|
|
707
|
-
<h3>${t.resources}</h3>
|
|
708
|
-
<a href="https://github.com/Thanh-apero/apero-kit-cli" target="_blank">
|
|
709
|
-
<span class="icon">📦</span>
|
|
710
|
-
<span>${t.github}</span>
|
|
711
|
-
</a>
|
|
712
|
-
<a href="https://www.npmjs.com/package/apero-kit-cli" target="_blank">
|
|
713
|
-
<span class="icon">📥</span>
|
|
714
|
-
<span>${t.npm}</span>
|
|
715
|
-
</a>
|
|
716
|
-
</div>
|
|
717
706
|
</nav>`;
|
|
718
707
|
}
|
|
719
708
|
|
|
@@ -33,44 +33,13 @@ if (!fs.existsSync(fullPlanPath)) {
|
|
|
33
33
|
process.exit(1);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
// Inline code
|
|
45
|
-
.replace(/`([^`]+)`/g, '<code class="inline">$1</code>')
|
|
46
|
-
// Headers
|
|
47
|
-
.replace(/^### (.*$)/gm, '<h3>$1</h3>')
|
|
48
|
-
.replace(/^## (.*$)/gm, '<h2>$1</h2>')
|
|
49
|
-
.replace(/^# (.*$)/gm, '<h1>$1</h1>')
|
|
50
|
-
// Bold and italic
|
|
51
|
-
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
|
|
52
|
-
.replace(/\*([^*]+)\*/g, '<em>$1</em>')
|
|
53
|
-
// Links
|
|
54
|
-
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>')
|
|
55
|
-
// Lists
|
|
56
|
-
.replace(/^\s*[-*] (.*$)/gm, '<li>$1</li>')
|
|
57
|
-
.replace(/(<li>.*<\/li>)\n(?!<li>)/g, '$1</ul>\n')
|
|
58
|
-
.replace(/(?<!<\/li>\n)(<li>)/g, '<ul>$1')
|
|
59
|
-
// Numbered lists
|
|
60
|
-
.replace(/^\s*\d+\. (.*$)/gm, '<li class="numbered">$1</li>')
|
|
61
|
-
// Blockquotes
|
|
62
|
-
.replace(/^> (.*$)/gm, '<blockquote>$1</blockquote>')
|
|
63
|
-
// Horizontal rules
|
|
64
|
-
.replace(/^---+$/gm, '<hr>')
|
|
65
|
-
// Paragraphs
|
|
66
|
-
.replace(/\n\n/g, '</p><p>')
|
|
67
|
-
// Tables (simple)
|
|
68
|
-
.replace(/\|(.+)\|/g, (match) => {
|
|
69
|
-
const cells = match.split('|').filter(c => c.trim());
|
|
70
|
-
if (cells.every(c => /^[-:]+$/.test(c.trim()))) return ''; // Skip separator
|
|
71
|
-
const tag = 'td';
|
|
72
|
-
return '<tr>' + cells.map(c => `<${tag}>${c.trim()}</${tag}>`).join('') + '</tr>';
|
|
73
|
-
});
|
|
36
|
+
// Markdown to HTML - Uses marked.js on client-side for full GFM support
|
|
37
|
+
// Server just passes raw markdown, client renders with marked.js
|
|
38
|
+
function markdownToHtml(md, forEditor = false) {
|
|
39
|
+
// For editor preview pane, we'll render client-side with marked.js
|
|
40
|
+
// For static preview, we embed raw markdown and render on page load
|
|
41
|
+
const encodedMd = encodeURIComponent(md);
|
|
42
|
+
return `<div class="markdown-body" data-markdown="${encodedMd}"><noscript>${escapeHtml(md)}</noscript><div class="loading">Loading...</div></div>`;
|
|
74
43
|
}
|
|
75
44
|
|
|
76
45
|
function escapeHtml(text) {
|
|
@@ -134,6 +103,22 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
134
103
|
<meta charset="UTF-8">
|
|
135
104
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
136
105
|
<title>Plan Preview - ${path.basename(fullPlanPath)}</title>
|
|
106
|
+
|
|
107
|
+
<!-- marked.js - Markdown Parser -->
|
|
108
|
+
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
109
|
+
|
|
110
|
+
<!-- Prism.js - Syntax Highlighting -->
|
|
111
|
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
|
|
112
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
|
113
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script>
|
|
114
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-typescript.min.js"></script>
|
|
115
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script>
|
|
116
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script>
|
|
117
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-json.min.js"></script>
|
|
118
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-yaml.min.js"></script>
|
|
119
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-css.min.js"></script>
|
|
120
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-markdown.min.js"></script>
|
|
121
|
+
|
|
137
122
|
<style>
|
|
138
123
|
:root {
|
|
139
124
|
--bg: #0d1117;
|
|
@@ -467,6 +452,171 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
467
452
|
justify-content: space-between;
|
|
468
453
|
}
|
|
469
454
|
|
|
455
|
+
/* GitHub-style Markdown Body */
|
|
456
|
+
.markdown-body {
|
|
457
|
+
line-height: 1.7;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.markdown-body .loading {
|
|
461
|
+
color: var(--text-muted);
|
|
462
|
+
font-style: italic;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.markdown-body h1 {
|
|
466
|
+
font-size: 2em;
|
|
467
|
+
border-bottom: 1px solid var(--border);
|
|
468
|
+
padding-bottom: 0.3em;
|
|
469
|
+
margin: 24px 0 16px;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.markdown-body h2 {
|
|
473
|
+
font-size: 1.5em;
|
|
474
|
+
border-bottom: 1px solid var(--border);
|
|
475
|
+
padding-bottom: 0.3em;
|
|
476
|
+
margin: 24px 0 16px;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.markdown-body h3 {
|
|
480
|
+
font-size: 1.25em;
|
|
481
|
+
margin: 24px 0 16px;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.markdown-body h4 {
|
|
485
|
+
font-size: 1em;
|
|
486
|
+
margin: 24px 0 16px;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.markdown-body p {
|
|
490
|
+
margin: 0 0 16px;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.markdown-body ul, .markdown-body ol {
|
|
494
|
+
margin: 0 0 16px;
|
|
495
|
+
padding-left: 2em;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.markdown-body li {
|
|
499
|
+
margin: 4px 0;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.markdown-body li > p {
|
|
503
|
+
margin: 0;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/* Task Lists */
|
|
507
|
+
.markdown-body input[type="checkbox"] {
|
|
508
|
+
margin-right: 8px;
|
|
509
|
+
vertical-align: middle;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.markdown-body li.task-list-item {
|
|
513
|
+
list-style: none;
|
|
514
|
+
margin-left: -1.5em;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/* Tables - GitHub style */
|
|
518
|
+
.markdown-body table {
|
|
519
|
+
width: 100%;
|
|
520
|
+
border-collapse: collapse;
|
|
521
|
+
margin: 16px 0;
|
|
522
|
+
display: block;
|
|
523
|
+
overflow-x: auto;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.markdown-body thead {
|
|
527
|
+
background: var(--bg-tertiary);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.markdown-body th, .markdown-body td {
|
|
531
|
+
padding: 12px 16px;
|
|
532
|
+
border: 1px solid var(--border);
|
|
533
|
+
text-align: left;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.markdown-body th {
|
|
537
|
+
font-weight: 600;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.markdown-body tbody tr:nth-child(even) {
|
|
541
|
+
background: var(--bg-secondary);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.markdown-body tbody tr:hover {
|
|
545
|
+
background: rgba(88, 166, 255, 0.05);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/* Code blocks with Prism */
|
|
549
|
+
.markdown-body pre {
|
|
550
|
+
background: var(--code-bg);
|
|
551
|
+
border: 1px solid var(--border);
|
|
552
|
+
border-radius: 8px;
|
|
553
|
+
padding: 16px;
|
|
554
|
+
overflow-x: auto;
|
|
555
|
+
margin: 16px 0;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.markdown-body pre code {
|
|
559
|
+
background: none;
|
|
560
|
+
padding: 0;
|
|
561
|
+
border-radius: 0;
|
|
562
|
+
font-size: 13px;
|
|
563
|
+
color: var(--text);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.markdown-body code {
|
|
567
|
+
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
568
|
+
font-size: 85%;
|
|
569
|
+
background: var(--code-bg);
|
|
570
|
+
padding: 0.2em 0.4em;
|
|
571
|
+
border-radius: 4px;
|
|
572
|
+
color: var(--accent);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/* Blockquotes */
|
|
576
|
+
.markdown-body blockquote {
|
|
577
|
+
border-left: 4px solid var(--accent);
|
|
578
|
+
padding: 0 16px;
|
|
579
|
+
margin: 16px 0;
|
|
580
|
+
color: var(--text-muted);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.markdown-body blockquote > :first-child {
|
|
584
|
+
margin-top: 0;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.markdown-body blockquote > :last-child {
|
|
588
|
+
margin-bottom: 0;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/* Images */
|
|
592
|
+
.markdown-body img {
|
|
593
|
+
max-width: 100%;
|
|
594
|
+
height: auto;
|
|
595
|
+
border-radius: 8px;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/* Horizontal Rule */
|
|
599
|
+
.markdown-body hr {
|
|
600
|
+
border: none;
|
|
601
|
+
border-top: 2px solid var(--border);
|
|
602
|
+
margin: 32px 0;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/* Links */
|
|
606
|
+
.markdown-body a {
|
|
607
|
+
color: var(--accent);
|
|
608
|
+
text-decoration: none;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.markdown-body a:hover {
|
|
612
|
+
text-decoration: underline;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* Strikethrough */
|
|
616
|
+
.markdown-body del {
|
|
617
|
+
color: var(--text-muted);
|
|
618
|
+
}
|
|
619
|
+
|
|
470
620
|
/* Responsive */
|
|
471
621
|
@media (max-width: 768px) {
|
|
472
622
|
.sidebar { width: 100%; height: auto; position: relative; }
|
|
@@ -476,6 +626,16 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
476
626
|
.editor { min-height: 300px; }
|
|
477
627
|
.preview-pane { min-height: 300px; }
|
|
478
628
|
}
|
|
629
|
+
|
|
630
|
+
/* Print styles */
|
|
631
|
+
@media print {
|
|
632
|
+
.sidebar, .toolbar, .mode-toggle, .footer { display: none !important; }
|
|
633
|
+
.main { margin-left: 0; padding: 20px; }
|
|
634
|
+
body { background: white; color: black; }
|
|
635
|
+
.markdown-body pre { border: 1px solid #ddd; background: #f5f5f5; }
|
|
636
|
+
.markdown-body code { background: #f5f5f5; color: #333; }
|
|
637
|
+
.markdown-body a { color: #0366d6; }
|
|
638
|
+
}
|
|
479
639
|
</style>
|
|
480
640
|
</head>
|
|
481
641
|
<body>
|
|
@@ -535,6 +695,36 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
535
695
|
|
|
536
696
|
originalContent = editor.value;
|
|
537
697
|
|
|
698
|
+
// Configure marked.js for GitHub Flavored Markdown
|
|
699
|
+
marked.setOptions({
|
|
700
|
+
gfm: true,
|
|
701
|
+
breaks: true,
|
|
702
|
+
headerIds: true,
|
|
703
|
+
mangle: false
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// Custom renderer for syntax highlighting with Prism
|
|
707
|
+
const renderer = new marked.Renderer();
|
|
708
|
+
renderer.code = function(code, language) {
|
|
709
|
+
const lang = language || '';
|
|
710
|
+
const validLang = Prism.languages[lang] ? lang : 'plaintext';
|
|
711
|
+
let highlighted;
|
|
712
|
+
try {
|
|
713
|
+
highlighted = Prism.languages[validLang]
|
|
714
|
+
? Prism.highlight(code, Prism.languages[validLang], validLang)
|
|
715
|
+
: code;
|
|
716
|
+
} catch (e) {
|
|
717
|
+
highlighted = code;
|
|
718
|
+
}
|
|
719
|
+
return '<pre class="language-' + validLang + '"><code class="language-' + validLang + '">' + highlighted + '</code></pre>';
|
|
720
|
+
};
|
|
721
|
+
marked.setOptions({ renderer });
|
|
722
|
+
|
|
723
|
+
// Render markdown with marked.js
|
|
724
|
+
function renderMarkdown(md) {
|
|
725
|
+
return marked.parse(md);
|
|
726
|
+
}
|
|
727
|
+
|
|
538
728
|
// Live preview update
|
|
539
729
|
let updateTimeout;
|
|
540
730
|
editor.addEventListener('input', () => {
|
|
@@ -543,26 +733,15 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
543
733
|
|
|
544
734
|
clearTimeout(updateTimeout);
|
|
545
735
|
updateTimeout = setTimeout(() => {
|
|
546
|
-
preview.innerHTML =
|
|
547
|
-
|
|
736
|
+
preview.innerHTML = renderMarkdown(editor.value);
|
|
737
|
+
// Re-run Prism highlighting for any code blocks
|
|
738
|
+
Prism.highlightAllUnder(preview);
|
|
739
|
+
}, 150);
|
|
548
740
|
});
|
|
549
741
|
|
|
550
|
-
//
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
.replace(/\`\`\`(\\w+)?\\n([\\s\\S]*?)\`\`\`/g, '<pre><code>$2</code></pre>')
|
|
554
|
-
.replace(/\`([^\`]+)\`/g, '<code class="inline">$1</code>')
|
|
555
|
-
.replace(/^### (.*$)/gm, '<h3>$1</h3>')
|
|
556
|
-
.replace(/^## (.*$)/gm, '<h2>$1</h2>')
|
|
557
|
-
.replace(/^# (.*$)/gm, '<h1>$1</h1>')
|
|
558
|
-
.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>')
|
|
559
|
-
.replace(/\\*([^*]+)\\*/g, '<em>$1</em>')
|
|
560
|
-
.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href="$2">$1</a>')
|
|
561
|
-
.replace(/^\\s*[-*] (.*$)/gm, '<li>$1</li>')
|
|
562
|
-
.replace(/^> (.*$)/gm, '<blockquote>$1</blockquote>')
|
|
563
|
-
.replace(/^---+$/gm, '<hr>')
|
|
564
|
-
.replace(/\\n\\n/g, '</p><p>');
|
|
565
|
-
}
|
|
742
|
+
// Initial render
|
|
743
|
+
preview.innerHTML = renderMarkdown(editor.value);
|
|
744
|
+
Prism.highlightAllUnder(preview);
|
|
566
745
|
|
|
567
746
|
// Update status indicator
|
|
568
747
|
function updateStatus() {
|
|
@@ -632,7 +811,42 @@ function generatePage(files, currentFile, mode = 'preview') {
|
|
|
632
811
|
e.returnValue = '';
|
|
633
812
|
}
|
|
634
813
|
});
|
|
635
|
-
` :
|
|
814
|
+
` : `
|
|
815
|
+
// Preview mode: Render markdown on page load
|
|
816
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
817
|
+
// Configure marked.js
|
|
818
|
+
marked.setOptions({
|
|
819
|
+
gfm: true,
|
|
820
|
+
breaks: true,
|
|
821
|
+
headerIds: true,
|
|
822
|
+
mangle: false
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
// Custom renderer for syntax highlighting with Prism
|
|
826
|
+
const renderer = new marked.Renderer();
|
|
827
|
+
renderer.code = function(code, language) {
|
|
828
|
+
const lang = language || '';
|
|
829
|
+
const validLang = Prism.languages[lang] ? lang : 'plaintext';
|
|
830
|
+
let highlighted;
|
|
831
|
+
try {
|
|
832
|
+
highlighted = Prism.languages[validLang]
|
|
833
|
+
? Prism.highlight(code, Prism.languages[validLang], validLang)
|
|
834
|
+
: code;
|
|
835
|
+
} catch (e) {
|
|
836
|
+
highlighted = code;
|
|
837
|
+
}
|
|
838
|
+
return '<pre class="language-' + validLang + '"><code class="language-' + validLang + '">' + highlighted + '</code></pre>';
|
|
839
|
+
};
|
|
840
|
+
marked.setOptions({ renderer });
|
|
841
|
+
|
|
842
|
+
// Find all markdown bodies and render them
|
|
843
|
+
document.querySelectorAll('.markdown-body[data-markdown]').forEach(el => {
|
|
844
|
+
const rawMd = decodeURIComponent(el.dataset.markdown);
|
|
845
|
+
el.innerHTML = marked.parse(rawMd);
|
|
846
|
+
Prism.highlightAllUnder(el);
|
|
847
|
+
});
|
|
848
|
+
});
|
|
849
|
+
`}
|
|
636
850
|
</script>
|
|
637
851
|
</body>
|
|
638
852
|
</html>`;
|