viberadar 0.3.133 → 0.3.135

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.
@@ -45,6 +45,7 @@ const child_process_1 = require("child_process");
45
45
  const readline = __importStar(require("readline"));
46
46
  const chokidar_1 = __importDefault(require("chokidar"));
47
47
  const scanner_1 = require("../scanner");
48
+ const docx_1 = require("../docx");
48
49
  const DASHBOARD_HTML = fs.readFileSync(path.join(__dirname, '../ui/dashboard.html'), 'utf-8');
49
50
  // ─── Agent CLI commands ───────────────────────────────────────────────────────
50
51
  const WIN = process.platform === 'win32';
@@ -3650,6 +3651,105 @@ function startServer({ data: initialData, port, projectRoot }) {
3650
3651
  res.end(JSON.stringify({ configured: !!token, projectName: projName || null }));
3651
3652
  return;
3652
3653
  }
3654
+ // ── Export docs as Markdown ──────────────────────────────────────────────
3655
+ if (url.startsWith('/api/docs/export/md') && req.method === 'GET') {
3656
+ try {
3657
+ const urlObj = new URL(url, 'http://localhost');
3658
+ const featureKey = urlObj.searchParams.get('feature');
3659
+ const docReport = currentData.documentation;
3660
+ if (!docReport) {
3661
+ res.writeHead(400, jsonH);
3662
+ res.end(JSON.stringify({ error: 'Documentation not available' }));
3663
+ return;
3664
+ }
3665
+ let features = docReport.features.filter((f) => f.docExists);
3666
+ if (featureKey)
3667
+ features = features.filter((f) => f.key === featureKey);
3668
+ if (!features.length) {
3669
+ res.writeHead(400, jsonH);
3670
+ res.end(JSON.stringify({ error: 'No documented features found' }));
3671
+ return;
3672
+ }
3673
+ const sections = [];
3674
+ for (const f of features) {
3675
+ const docDir = path.join(projectRoot, 'docs', 'features', f.key);
3676
+ try {
3677
+ const entries = fs.readdirSync(docDir);
3678
+ const versions = entries
3679
+ .map((e) => { const m = e.match(/^v(\d+)\.md$/); return m ? { file: e, n: parseInt(m[1], 10) } : null; })
3680
+ .filter((x) => x !== null)
3681
+ .sort((a, b) => b.n - a.n);
3682
+ if (versions.length) {
3683
+ const content = fs.readFileSync(path.join(docDir, versions[0].file), 'utf-8');
3684
+ if (features.length > 1)
3685
+ sections.push(`---\n\n# ${f.label}\n\n${content.trim()}`);
3686
+ else
3687
+ sections.push(content.trim());
3688
+ }
3689
+ }
3690
+ catch { /* skip */ }
3691
+ }
3692
+ const projName = (() => { try {
3693
+ return JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8')).name || 'docs';
3694
+ }
3695
+ catch {
3696
+ return 'docs';
3697
+ } })();
3698
+ const filename = featureKey ? `${featureKey}.md` : `${projName}-docs.md`;
3699
+ const mdContent = Buffer.from(sections.join('\n\n'), 'utf-8');
3700
+ res.writeHead(200, {
3701
+ 'Content-Type': 'text/markdown; charset=utf-8',
3702
+ 'Content-Disposition': `attachment; filename="${filename}"`,
3703
+ 'Content-Length': mdContent.length,
3704
+ });
3705
+ res.end(mdContent);
3706
+ }
3707
+ catch (err) {
3708
+ res.writeHead(500, jsonH);
3709
+ res.end(JSON.stringify({ error: err.message }));
3710
+ }
3711
+ return;
3712
+ }
3713
+ // ── Export docs as DOCX ──────────────────────────────────────────────────
3714
+ if (url.startsWith('/api/docs/export/docx') && req.method === 'GET') {
3715
+ try {
3716
+ const urlObj = new URL(url, 'http://localhost');
3717
+ const featureKey = urlObj.searchParams.get('feature');
3718
+ const docReport = currentData.documentation;
3719
+ if (!docReport) {
3720
+ res.writeHead(400, jsonH);
3721
+ res.end(JSON.stringify({ error: 'Documentation not available' }));
3722
+ return;
3723
+ }
3724
+ let features = docReport.features.filter((f) => f.docExists);
3725
+ if (featureKey)
3726
+ features = features.filter((f) => f.key === featureKey);
3727
+ if (!features.length) {
3728
+ res.writeHead(400, jsonH);
3729
+ res.end(JSON.stringify({ error: 'No documented features found' }));
3730
+ return;
3731
+ }
3732
+ const docxBuf = (0, docx_1.buildDocx)(features, projectRoot);
3733
+ const projName = (() => { try {
3734
+ return JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf-8')).name || 'docs';
3735
+ }
3736
+ catch {
3737
+ return 'docs';
3738
+ } })();
3739
+ const filename = featureKey ? `${featureKey}.docx` : `${projName}-docs.docx`;
3740
+ res.writeHead(200, {
3741
+ 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
3742
+ 'Content-Disposition': `attachment; filename="${filename}"`,
3743
+ 'Content-Length': docxBuf.length,
3744
+ });
3745
+ res.end(docxBuf);
3746
+ }
3747
+ catch (err) {
3748
+ res.writeHead(500, jsonH);
3749
+ res.end(JSON.stringify({ error: err.message }));
3750
+ }
3751
+ return;
3752
+ }
3653
3753
  // Verify Vercel token before saving
3654
3754
  if (url === '/api/docs/deploy/verify-token' && req.method === 'POST') {
3655
3755
  let body = '';