@jakkrichm/create-nexus-devflow 2.0.23 → 2.0.25
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/dist/lib/dashboard.js +29 -13
- package/dist/lib/dashboard.js.map +1 -1
- package/dist/lib/update.d.ts +9 -3
- package/dist/lib/update.js +127 -20
- package/dist/lib/update.js.map +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/convert-any-to-md/SKILL.md +80 -0
- package/template/.agents/skills/convert-any-to-md/references/setup.md +29 -0
- package/template/.agents/skills/convert-any-to-md/scripts/convert_any_to_md.py +487 -0
- package/template/.agents/skills/convert-any-to-md/scripts/requirements.txt +3 -0
- package/template/.claude/skills/convert-any-to-md/SKILL.md +80 -0
package/dist/lib/dashboard.js
CHANGED
|
@@ -494,7 +494,7 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
494
494
|
<body>
|
|
495
495
|
<main class="shell">
|
|
496
496
|
<div class="brand">
|
|
497
|
-
<svg class="brand-mark" viewBox="0 0 48 48" role="img" aria-label="Nexus-DevFlow">
|
|
497
|
+
<svg class="brand-mark" viewBox="0 0 48 48" role="img" aria-label="Nexus-DevFlow" aria-hidden="true">
|
|
498
498
|
<path fill="#155eef" d="M4 4h25.2L16.3 44H4zM39.7 4H44v40H26.8z"></path>
|
|
499
499
|
</svg>
|
|
500
500
|
<span>Nexus-DevFlow</span>
|
|
@@ -523,7 +523,7 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
523
523
|
<article class="card wide card-enter" style="animation-delay: 0.08s;">
|
|
524
524
|
<div class="card-head"><span class="label">Current Work</span><span class="pill" id="work-pill">Loading</span></div>
|
|
525
525
|
<div class="value" id="work-title">Reading living spec...</div>
|
|
526
|
-
<div class="progress"><span class="progress-bar" id="work-progress-bar"></span></div>
|
|
526
|
+
<div class="progress"><span class="progress-bar" id="work-progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Loading checklist steps..."></span></div>
|
|
527
527
|
<div class="muted" id="work-meta">Loading checklist steps...</div>
|
|
528
528
|
</article>
|
|
529
529
|
|
|
@@ -538,28 +538,28 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
538
538
|
|
|
539
539
|
<article class="card card-enter" style="animation-delay: 0.16s;">
|
|
540
540
|
<div class="card-head"><span class="label">Findings</span><span class="value" id="findings-count">-</span></div>
|
|
541
|
-
<ul id="findings-list"><li class="empty">Loading findings...</li></ul>
|
|
541
|
+
<ul id="findings-list" aria-live="polite"><li class="empty">Loading findings...</li></ul>
|
|
542
542
|
</article>
|
|
543
543
|
|
|
544
544
|
<article class="card card-enter" style="animation-delay: 0.20s;">
|
|
545
545
|
<div class="card-head"><span class="label">Completion</span><span class="pill" id="completion-pill">Loading</span></div>
|
|
546
|
-
<ul id="completion-list"><li class="empty">Checking readiness...</li></ul>
|
|
546
|
+
<ul id="completion-list" aria-live="polite"><li class="empty">Checking readiness...</li></ul>
|
|
547
547
|
</article>
|
|
548
548
|
|
|
549
549
|
<article class="card card-enter" style="animation-delay: 0.24s;">
|
|
550
550
|
<div class="card-head"><span class="label">Attention</span><span class="value" id="warnings-count">-</span></div>
|
|
551
|
-
<ul id="warnings-list"><li class="empty">Loading warnings...</li></ul>
|
|
551
|
+
<ul id="warnings-list" aria-live="polite"><li class="empty">Loading warnings...</li></ul>
|
|
552
552
|
</article>
|
|
553
553
|
|
|
554
554
|
<article class="card full card-enter" style="animation-delay: 0.28s;">
|
|
555
555
|
<div class="card-head"><span class="label">Completed Work Archive</span><span class="value" id="history-count">-</span></div>
|
|
556
556
|
<div class="muted">Categorized history of features, fixes, and rollbacks.</div>
|
|
557
|
-
<ul id="history-list"><li class="empty">Loading history archive...</li></ul>
|
|
557
|
+
<ul id="history-list" tabindex="0" aria-label="Completed work archive"><li class="empty">Loading history archive...</li></ul>
|
|
558
558
|
</article>
|
|
559
559
|
|
|
560
560
|
<article class="card full code-panel next-action card-enter" style="animation-delay: 0.32s;" id="next-panel">
|
|
561
561
|
<span class="label">Next Action</span>
|
|
562
|
-
<div class="command" id="next-command">Loading...</div>
|
|
562
|
+
<div class="command" id="next-command" aria-live="polite">Loading...</div>
|
|
563
563
|
<div class="muted" id="next-reason"></div>
|
|
564
564
|
</article>
|
|
565
565
|
</section>
|
|
@@ -573,10 +573,10 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
573
573
|
let isFirstLoad = true;
|
|
574
574
|
let refreshing = false;
|
|
575
575
|
|
|
576
|
-
function setPill(id, value) {
|
|
576
|
+
function setPill(id, value, label = value) {
|
|
577
577
|
const node = byId(id);
|
|
578
578
|
if (!node) return;
|
|
579
|
-
const formatted = String(
|
|
579
|
+
const formatted = String(label || '').replaceAll("_", " ");
|
|
580
580
|
const newClass = "pill " + (value || 'idle');
|
|
581
581
|
|
|
582
582
|
if (!isFirstLoad && (node.textContent !== formatted || !node.className.includes(value))) {
|
|
@@ -654,24 +654,36 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
654
654
|
|
|
655
655
|
byId('live-dot').style.background = '#0b7a53';
|
|
656
656
|
byId('live-dot').classList.add('is-live');
|
|
657
|
-
byId('live-label').textContent = '
|
|
657
|
+
byId('live-label').textContent = 'Connected';
|
|
658
658
|
|
|
659
659
|
byId('project-name').textContent = data.project?.name || 'Nexus-DevFlow';
|
|
660
660
|
byId('project-path').textContent = data.project?.root || '';
|
|
661
661
|
|
|
662
|
-
|
|
662
|
+
const healthIssues = (data.warnings || []).map((warning) => warning.message).concat(
|
|
663
|
+
(data.findings?.blockers || []).map((finding) => "Blocking finding " + finding.id + ": " + finding.title)
|
|
664
|
+
);
|
|
665
|
+
const healthCount = healthIssues.length;
|
|
666
|
+
setPill(
|
|
667
|
+
'health-pill',
|
|
668
|
+
data.health || 'ok',
|
|
669
|
+
healthCount === 0 ? 'Clear' : healthCount + (healthCount === 1 ? ' issue' : ' issues')
|
|
670
|
+
);
|
|
671
|
+
|
|
663
672
|
byId('val-version').textContent = data.devflow?.version ? 'v' + data.devflow.version : '-';
|
|
664
673
|
byId('val-adapters').textContent = (data.devflow?.adapters || []).join(', ') || 'none';
|
|
665
674
|
|
|
666
675
|
const work = data.currentWork || {};
|
|
667
676
|
setPill('work-pill', work.state || 'idle');
|
|
668
677
|
byId('work-title').textContent = work.title || 'No active run in progress';
|
|
669
|
-
|
|
678
|
+
const workSummary = work.state === 'active'
|
|
670
679
|
? (work.completed + ' of ' + work.total + ' steps completed')
|
|
671
680
|
: 'Workspace is idle. Run /feature or /fix to start a new delivery run.';
|
|
681
|
+
byId('work-meta').textContent = workSummary;
|
|
672
682
|
|
|
673
683
|
const pct = work.total > 0 ? Math.round((work.completed / work.total) * 100) : 0;
|
|
674
684
|
const progressBar = byId('work-progress-bar');
|
|
685
|
+
progressBar.setAttribute('aria-valuenow', String(pct));
|
|
686
|
+
progressBar.setAttribute('aria-valuetext', workSummary);
|
|
675
687
|
|
|
676
688
|
const prevPct = prevData?.currentWork ? (prevData.currentWork.total > 0 ? Math.round((prevData.currentWork.completed / prevData.currentWork.total) * 100) : 0) : 0;
|
|
677
689
|
if (!isFirstLoad && pct > prevPct) {
|
|
@@ -689,7 +701,7 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
689
701
|
progressBar.style.width = pct + '%';
|
|
690
702
|
|
|
691
703
|
const git = data.git || {};
|
|
692
|
-
setPill('git-pill', git.clean ? 'ok' : 'warning');
|
|
704
|
+
setPill('git-pill', git.clean ? 'ok' : 'warning', !git.branch ? 'Unavailable' : git.clean ? 'Clean' : (git.changedFiles + ' changed'));
|
|
693
705
|
byId('git-branch').textContent = git.branch || 'unknown';
|
|
694
706
|
byId('git-changed').textContent = git.clean ? 'clean' : (git.changedFiles + ' changed files');
|
|
695
707
|
byId('git-upstream').textContent = git.upstream || 'none';
|
|
@@ -748,6 +760,10 @@ const DASHBOARD_HTML = `<!doctype html>
|
|
|
748
760
|
cmdNode.textContent = next.command || '/feature';
|
|
749
761
|
byId('next-reason').textContent = next.reason || 'Ready for next feature';
|
|
750
762
|
|
|
763
|
+
if (isFirstLoad) {
|
|
764
|
+
requestAnimationFrame(() => document.body.classList.add('hydrated'));
|
|
765
|
+
}
|
|
766
|
+
|
|
751
767
|
prevData = {
|
|
752
768
|
...data,
|
|
753
769
|
historyCount: historyItems.length
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../lib/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAWhD,MAAM,cAAc,GAAG,WAAW,CAAC;AAEnC,KAAK,UAAU,oBAAoB,CACjC,YAAoB,OAAO,CAAC,GAAG,EAAE,EACjC,UAAkC,EAAE;IAEpC,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QACrD,KAAK,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,CAAC,KAAY,EAAQ,EAAE;YACrC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,MAAM,WAAW,GAAG,GAAS,EAAE;YAC7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO;QACL,GAAG,EAAE,UAAU,cAAc,IAAI,OAAO,CAAC,IAAI,EAAE;QAC/C,KAAK,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,WAAmB,EACnB,OAA6B,EAC7B,QAA6B;IAE7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACzC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,2BAA2B,EAAE,uBAAuB,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC;IAElF,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;QACrB,QAAQ,CAAC,SAAS,CAChB,yBAAyB,EACzB,8JAA8J,CAC/J,CAAC;QACF,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,0BAA0B,EAAE,cAAc,CAAC,CAAC;QAChF,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACpD,YAAY,CACV,QAAQ,EACR,MAAM,EACN,GAAG,EACH,iCAAiC,EACjC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAC9B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,YAAY,CACV,QAAQ,EACR,MAAM,EACN,GAAG,EACH,iCAAiC,EACjC,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC;aACvF,CAAC,IAAI,CACP,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC/C,YAAY,CACV,QAAQ,EACR,MAAM,EACN,GAAG,EACH,iCAAiC,EACjC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAC/B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,YAAY,CACV,QAAQ,EACR,MAAM,EACN,GAAG,EACH,iCAAiC,EACjC,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC;aAClF,CAAC,IAAI,CACP,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,2BAA2B,EAAE,EAAE,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,2BAA2B,EAAE,cAAc,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,YAAY,CACnB,QAA6B,EAC7B,MAAc,EACd,UAAkB,EAClB,WAAmB,EACnB,IAAY;IAEZ,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACxD,QAAQ,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAmB;IAC5C,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACrB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YAED,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3C,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,UAAU,CAAC;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO;QACvC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC;QAC1B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAEV,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,cAAc,GAAW
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../lib/dashboard.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/update.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface Manifest {
|
|
|
18
18
|
discoveriesDir: string;
|
|
19
19
|
};
|
|
20
20
|
lifecycle: {
|
|
21
|
+
fastTrackStages: string[];
|
|
21
22
|
mainlineStages: string[];
|
|
22
23
|
companionCommands: string[];
|
|
23
24
|
};
|
|
@@ -54,12 +55,17 @@ export declare function prepareUpdate({ targetDir, templateRoot, version, adapte
|
|
|
54
55
|
version: string;
|
|
55
56
|
adapter?: string;
|
|
56
57
|
}): Promise<PreparedUpdate>;
|
|
57
|
-
export
|
|
58
|
+
export interface ApplyUpdateOptions {
|
|
58
59
|
replaceConflicts?: boolean;
|
|
59
|
-
|
|
60
|
+
now?: () => Date;
|
|
61
|
+
}
|
|
62
|
+
export interface ApplyUpdateResult {
|
|
60
63
|
appliedCount: number;
|
|
61
64
|
removedCount: number;
|
|
62
|
-
|
|
65
|
+
backupDir: string | null;
|
|
66
|
+
}
|
|
67
|
+
export declare function writeControlIgnore(targetDir: string): Promise<void>;
|
|
68
|
+
export declare function applyPreparedUpdate(prepared: PreparedUpdate, { replaceConflicts, now }?: ApplyUpdateOptions): Promise<ApplyUpdateResult>;
|
|
63
69
|
export declare function cleanEmptyParentDirectories(targetDir: string, filePath: string): Promise<void>;
|
|
64
70
|
export declare function writeInstallManifest(targetDir: string, manifest: Manifest): Promise<void>;
|
|
65
71
|
export declare function copyFileAtomic(targetDir: string, relativePath: string, sourcePath: string): Promise<void>;
|
package/dist/lib/update.js
CHANGED
|
@@ -44,6 +44,13 @@ export function createManifest(version, adapters, templateFiles) {
|
|
|
44
44
|
discoveriesDir: "devflow/discoveries"
|
|
45
45
|
},
|
|
46
46
|
lifecycle: {
|
|
47
|
+
fastTrackStages: [
|
|
48
|
+
"feature",
|
|
49
|
+
"fix",
|
|
50
|
+
"implement",
|
|
51
|
+
"check",
|
|
52
|
+
"complete"
|
|
53
|
+
],
|
|
47
54
|
mainlineStages: [
|
|
48
55
|
"00-discover",
|
|
49
56
|
"10-define",
|
|
@@ -55,11 +62,6 @@ export function createManifest(version, adapters, templateFiles) {
|
|
|
55
62
|
"70-release"
|
|
56
63
|
],
|
|
57
64
|
companionCommands: [
|
|
58
|
-
"feature",
|
|
59
|
-
"fix",
|
|
60
|
-
"implement",
|
|
61
|
-
"check",
|
|
62
|
-
"complete",
|
|
63
65
|
"devflow",
|
|
64
66
|
"doctor",
|
|
65
67
|
"overview",
|
|
@@ -238,42 +240,146 @@ export async function prepareUpdate({ targetDir, templateRoot, version, adapter
|
|
|
238
240
|
orphanedFiles
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
|
-
|
|
243
|
+
function formatTimestamp(date) {
|
|
244
|
+
return date.toISOString().replace(/\.\d{3}Z$/, "Z").replaceAll(":", "-");
|
|
245
|
+
}
|
|
246
|
+
function sanitizeSegment(value) {
|
|
247
|
+
return String(value).replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
248
|
+
}
|
|
249
|
+
export async function writeControlIgnore(targetDir) {
|
|
250
|
+
const ignoreFile = targetPath(targetDir, `${CONTROL_DIR}/.gitignore`);
|
|
251
|
+
await assertNoSymlinkParents(targetDir, `${CONTROL_DIR}/.gitignore`);
|
|
252
|
+
await fs.mkdir(path.dirname(ignoreFile), { recursive: true });
|
|
253
|
+
await fs.writeFile(ignoreFile, "backups/\nstaging/\n", "utf8");
|
|
254
|
+
}
|
|
255
|
+
export async function applyPreparedUpdate(prepared, { replaceConflicts = false, now = () => new Date() } = {}) {
|
|
242
256
|
if (prepared.conflictList.length > 0 && !replaceConflicts) {
|
|
243
257
|
throw new Error(`Cannot apply update with ${prepared.conflictList.length} conflict(s). Pass force/replace option or resolve conflicts.`);
|
|
244
258
|
}
|
|
245
|
-
const
|
|
246
|
-
...prepared.createList,
|
|
259
|
+
const replacements = [
|
|
247
260
|
...prepared.updateList,
|
|
248
261
|
...(replaceConflicts ? prepared.conflictList.map((item) => item.relativePath) : [])
|
|
249
262
|
];
|
|
250
|
-
|
|
263
|
+
const removals = prepared.orphanedFiles;
|
|
264
|
+
const existingOperations = [...replacements, ...removals];
|
|
265
|
+
const previousVersion = prepared.previousManifest?.version || "legacy";
|
|
266
|
+
const nextVersion = prepared.nextManifest.version;
|
|
267
|
+
const identifier = `${formatTimestamp(now())}-${sanitizeSegment(previousVersion)}-to-${sanitizeSegment(nextVersion)}-${crypto.randomBytes(4).toString("hex")}`;
|
|
268
|
+
const backupDir = existingOperations.length > 0
|
|
269
|
+
? targetPath(prepared.targetDir, `${CONTROL_DIR}/backups/${identifier}`)
|
|
270
|
+
: null;
|
|
271
|
+
const stagingDir = targetPath(prepared.targetDir, `${CONTROL_DIR}/staging/${identifier}`);
|
|
272
|
+
const previousManifestFile = targetPath(prepared.targetDir, MANIFEST_PATH);
|
|
273
|
+
const writeTargets = [...prepared.createList, ...replacements];
|
|
274
|
+
await fs.mkdir(stagingDir, { recursive: true });
|
|
251
275
|
for (const relativePath of writeTargets) {
|
|
252
276
|
const templateFile = prepared.templateFiles.get(relativePath);
|
|
253
|
-
if (!templateFile)
|
|
277
|
+
if (!templateFile)
|
|
254
278
|
continue;
|
|
279
|
+
const stageFile = path.join(stagingDir, ...relativePath.split("/"));
|
|
280
|
+
await fs.mkdir(path.dirname(stageFile), { recursive: true });
|
|
281
|
+
await fs.copyFile(templateFile.source, stageFile);
|
|
282
|
+
if ((await hashFile(stageFile)) !== templateFile.hash) {
|
|
283
|
+
throw new Error(`Template file changed during staging: ${relativePath}`);
|
|
255
284
|
}
|
|
256
|
-
await copyFileAtomic(prepared.targetDir, relativePath, templateFile.source);
|
|
257
|
-
appliedCount++;
|
|
258
285
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
286
|
+
if (backupDir) {
|
|
287
|
+
for (const relativePath of existingOperations) {
|
|
288
|
+
const backupFile = path.join(backupDir, "files", ...relativePath.split("/"));
|
|
289
|
+
await fs.mkdir(path.dirname(backupFile), { recursive: true });
|
|
290
|
+
const sourceFile = targetPath(prepared.targetDir, relativePath);
|
|
291
|
+
try {
|
|
292
|
+
await fs.copyFile(sourceFile, backupFile);
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
if (error.code !== "ENOENT") {
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
262
300
|
try {
|
|
263
|
-
await fs.
|
|
264
|
-
removedCount++;
|
|
265
|
-
await cleanEmptyParentDirectories(prepared.targetDir, fileToRemove);
|
|
301
|
+
await fs.copyFile(previousManifestFile, path.join(backupDir, "nexus-devflow.json"));
|
|
266
302
|
}
|
|
267
303
|
catch (error) {
|
|
268
304
|
if (error.code !== "ENOENT") {
|
|
269
305
|
throw error;
|
|
270
306
|
}
|
|
271
307
|
}
|
|
308
|
+
await fs.mkdir(backupDir, { recursive: true });
|
|
309
|
+
await fs.writeFile(path.join(backupDir, "backup.json"), `${JSON.stringify({
|
|
310
|
+
fromVersion: previousVersion,
|
|
311
|
+
toVersion: nextVersion,
|
|
312
|
+
replaced: replacements,
|
|
313
|
+
removed: removals
|
|
314
|
+
}, null, 2)}\n`, "utf8");
|
|
315
|
+
}
|
|
316
|
+
let appliedCount = 0;
|
|
317
|
+
let removedCount = 0;
|
|
318
|
+
try {
|
|
319
|
+
for (const relativePath of writeTargets) {
|
|
320
|
+
const stageFile = path.join(stagingDir, ...relativePath.split("/"));
|
|
321
|
+
await copyFileAtomic(prepared.targetDir, relativePath, stageFile);
|
|
322
|
+
appliedCount++;
|
|
323
|
+
}
|
|
324
|
+
for (const relativePath of removals) {
|
|
325
|
+
const fileToRemove = targetPath(prepared.targetDir, relativePath);
|
|
326
|
+
try {
|
|
327
|
+
await fs.unlink(fileToRemove);
|
|
328
|
+
removedCount++;
|
|
329
|
+
await cleanEmptyParentDirectories(prepared.targetDir, fileToRemove);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
if (error.code !== "ENOENT") {
|
|
333
|
+
throw error;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
await writeInstallManifest(prepared.targetDir, prepared.nextManifest);
|
|
338
|
+
await writeControlIgnore(prepared.targetDir);
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
try {
|
|
342
|
+
for (const relativePath of prepared.createList) {
|
|
343
|
+
const fileToRemove = targetPath(prepared.targetDir, relativePath);
|
|
344
|
+
try {
|
|
345
|
+
await fs.unlink(fileToRemove);
|
|
346
|
+
}
|
|
347
|
+
catch { }
|
|
348
|
+
}
|
|
349
|
+
if (backupDir) {
|
|
350
|
+
for (const relativePath of existingOperations) {
|
|
351
|
+
const backupFile = path.join(backupDir, "files", ...relativePath.split("/"));
|
|
352
|
+
try {
|
|
353
|
+
await copyFileAtomic(prepared.targetDir, relativePath, backupFile);
|
|
354
|
+
}
|
|
355
|
+
catch { }
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (prepared.previousManifest) {
|
|
359
|
+
await writeInstallManifest(prepared.targetDir, prepared.previousManifest);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
try {
|
|
363
|
+
await fs.unlink(previousManifestFile);
|
|
364
|
+
}
|
|
365
|
+
catch { }
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
catch (rollbackError) {
|
|
369
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
370
|
+
const rbMsg = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
|
|
371
|
+
throw new Error(`Update failed: ${msg}. Rollback also failed: ${rbMsg}`);
|
|
372
|
+
}
|
|
373
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
374
|
+
throw new Error(`Update failed and was rolled back: ${msg}`);
|
|
375
|
+
}
|
|
376
|
+
finally {
|
|
377
|
+
await fs.rm(stagingDir, { recursive: true, force: true });
|
|
272
378
|
}
|
|
273
|
-
await writeInstallManifest(prepared.targetDir, prepared.nextManifest);
|
|
274
379
|
return {
|
|
275
380
|
appliedCount,
|
|
276
|
-
removedCount
|
|
381
|
+
removedCount,
|
|
382
|
+
backupDir
|
|
277
383
|
};
|
|
278
384
|
}
|
|
279
385
|
export async function cleanEmptyParentDirectories(targetDir, filePath) {
|
|
@@ -299,6 +405,7 @@ export async function writeInstallManifest(targetDir, manifest) {
|
|
|
299
405
|
const manifestFile = targetPath(targetDir, MANIFEST_PATH);
|
|
300
406
|
await fs.mkdir(path.dirname(manifestFile), { recursive: true });
|
|
301
407
|
await fs.writeFile(manifestFile, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
408
|
+
await writeControlIgnore(targetDir);
|
|
302
409
|
}
|
|
303
410
|
export async function copyFileAtomic(targetDir, relativePath, sourcePath) {
|
|
304
411
|
await assertNoSymlinkParents(targetDir, relativePath);
|
package/dist/lib/update.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../lib/update.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../lib/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: convert-any-to-md
|
|
3
|
+
description: '[Devflow] Converts any document (.xlsx, .pdf, .docx, .txt, .csv, .log, .json, .yaml, etc.) or mixed folders into clean Markdown in devflow/reference. Use whenever documents need to be analyzed, summarized, searched, or extracted from.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Convert Any Document to Markdown
|
|
7
|
+
|
|
8
|
+
## When to use this skill
|
|
9
|
+
|
|
10
|
+
Trigger this skill any time there is a document (`.xlsx`, `.pdf`, `.docx`, `.txt`, `.csv`, `.log`, `.json`, `.yaml`, etc.) or a folder of documents that needs to be analyzed, summarized, reviewed, or extracted from.
|
|
11
|
+
|
|
12
|
+
Instead of parsing complex binary XML formats (`.docx`, `.xlsx`) or print layouts (`.pdf`) directly, this skill automatically detects the file type, extracts embedded text and images, and outputs standardized Markdown into **`devflow/reference/`** (or a specified output path).
|
|
13
|
+
|
|
14
|
+
Use this skill for:
|
|
15
|
+
- Single files: `.xlsx`, `.pdf`, `.docx`, `.txt`, `.csv`, `.log`, `.json`, `.yaml`, etc.
|
|
16
|
+
- Folder batch mode: A directory containing a mix of multiple file types.
|
|
17
|
+
|
|
18
|
+
## Setup (once per environment)
|
|
19
|
+
|
|
20
|
+
Before the first conversion in a given environment, follow [`references/setup.md`](references/setup.md) to ensure Python, `markitdown`, `pymupdf`, and `openpyxl` are installed:
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
python -m pip install -r .agents/skills/convert-any-to-md/scripts/requirements.txt
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
The conversion script lives at `.agents/skills/convert-any-to-md/scripts/convert_any_to_md.py`.
|
|
29
|
+
|
|
30
|
+
### Default Destination (`devflow/reference/`)
|
|
31
|
+
|
|
32
|
+
By default, all converted Markdown files and extracted image folders (`img/`) are placed inside **`devflow/reference/`**:
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\document.pdf"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Output:
|
|
39
|
+
```text
|
|
40
|
+
devflow/reference/
|
|
41
|
+
└── document/
|
|
42
|
+
├── img/
|
|
43
|
+
│ ├── page001_img001.png
|
|
44
|
+
│ └── ...
|
|
45
|
+
└── document.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Specifying Custom Output Destination (`-o`)
|
|
49
|
+
|
|
50
|
+
To direct output to a specific folder:
|
|
51
|
+
|
|
52
|
+
```powershell
|
|
53
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\document.docx" -o "C:\custom\path"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Folder Batch Mode (`--recursive`)
|
|
57
|
+
|
|
58
|
+
To convert an entire folder (including mixed file types):
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\documents_folder"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Add `--recursive` to scan subdirectories:
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\documents_folder" --recursive
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Format Support & Behavior
|
|
71
|
+
|
|
72
|
+
| Format | Handler | Image Extraction | Output Structure |
|
|
73
|
+
| :--- | :--- | :--- | :--- |
|
|
74
|
+
| `.xlsx` | MarkItDown + OpenPyXL | Extracts sheet embedded images | `<name>/<name>.md` + `img/` |
|
|
75
|
+
| `.pdf` | MarkItDown + PyMuPDF | Extracts page images into appendix | `<name>/<name>.md` + `img/` |
|
|
76
|
+
| `.docx` | MarkItDown + ZIP Media | Extracts word media images | `<name>/<name>.md` + `img/` |
|
|
77
|
+
| `.txt`, `.csv`, `.json`, `.yaml`, `.log` | Plaintext Formatter | N/A | `<name>/<name>.md` |
|
|
78
|
+
|
|
79
|
+
> [!NOTE]
|
|
80
|
+
> Legacy binary formats (`.xls`, `.doc`) are not supported directly. Ask the user to re-save them as `.xlsx` / `.docx` first.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Environment Setup for convert-any-to-md
|
|
2
|
+
|
|
3
|
+
Follow these steps to set up the Python dependencies for document conversion.
|
|
4
|
+
|
|
5
|
+
## 1. Prerequisites
|
|
6
|
+
|
|
7
|
+
- Python 3.10+
|
|
8
|
+
- pip
|
|
9
|
+
|
|
10
|
+
## 2. Installation
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
|
|
14
|
+
```powershell
|
|
15
|
+
python -m pip install -r .agents/skills/convert-any-to-md/scripts/requirements.txt
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This installs:
|
|
19
|
+
- `markitdown[xlsx]`
|
|
20
|
+
- `pymupdf` (for PDF image extraction)
|
|
21
|
+
- `openpyxl` (for Excel parsing)
|
|
22
|
+
|
|
23
|
+
## 3. Verification
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
python -c "from markitdown import MarkItDown; import fitz; import openpyxl; print('Dependencies OK')"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Expect `Dependencies OK` to print cleanly.
|
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Convert any document (.xlsx, .pdf, .docx, .txt, .csv, .log, .json, .yaml, etc.)
|
|
3
|
+
or a directory of mixed files into clean Markdown, outputting by default into `devflow/reference/`.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python convert_any_to_md.py <input> [-o OUTPUT] [--recursive]
|
|
7
|
+
|
|
8
|
+
Arguments:
|
|
9
|
+
<input> Path to a single document or a directory.
|
|
10
|
+
-o, --output Target output directory (default: devflow/reference).
|
|
11
|
+
--recursive Recursively process subdirectories when input is a directory.
|
|
12
|
+
|
|
13
|
+
Exit codes:
|
|
14
|
+
0 - All requested conversions succeeded
|
|
15
|
+
1 - One or more conversions failed (partial success in batch mode)
|
|
16
|
+
2 - Required dependency missing
|
|
17
|
+
3 - Invalid input path
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import argparse
|
|
21
|
+
import hashlib
|
|
22
|
+
import posixpath
|
|
23
|
+
import re
|
|
24
|
+
import shutil
|
|
25
|
+
import sys
|
|
26
|
+
import zipfile
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from xml.etree import ElementTree as ET
|
|
29
|
+
|
|
30
|
+
EXIT_OK = 0
|
|
31
|
+
EXIT_CONVERSION_FAILED = 1
|
|
32
|
+
EXIT_MISSING_DEPENDENCY = 2
|
|
33
|
+
EXIT_INVALID_INPUT = 3
|
|
34
|
+
|
|
35
|
+
# Namespaces for OOXML
|
|
36
|
+
_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships"
|
|
37
|
+
_MAIN_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
38
|
+
_R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
39
|
+
_A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main"
|
|
40
|
+
|
|
41
|
+
# MarkItDown placeholder pattern for docx
|
|
42
|
+
_PLACEHOLDER_IMAGE_RE = re.compile(
|
|
43
|
+
r'!\[([^\]]*)\]\(data:image/[a-zA-Z0-9.+-]+;base64[^)]*\)'
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Sheet header pattern for xlsx
|
|
47
|
+
_SHEET_HEADER_RE = re.compile(r"^## (.+)$", re.MULTILINE)
|
|
48
|
+
|
|
49
|
+
SUPPORTED_TEXT_EXTS = {
|
|
50
|
+
".txt", ".log", ".csv", ".tsv", ".json", ".yaml", ".yml",
|
|
51
|
+
".md", ".markdown", ".py", ".js", ".ts", ".html", ".xml", ".css"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
IGNORE_EXTS = {
|
|
55
|
+
".exe", ".dll", ".so", ".dylib", ".bin", ".zip", ".tar", ".gz",
|
|
56
|
+
".7z", ".rar", ".iso", ".pyc", ".class", ".o", ".obj"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
def get_markitdown():
|
|
60
|
+
"""Lazy import MarkItDown if available."""
|
|
61
|
+
try:
|
|
62
|
+
from markitdown import MarkItDown
|
|
63
|
+
return MarkItDown()
|
|
64
|
+
except ImportError:
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
# ============================================================================
|
|
68
|
+
# Excel Handler
|
|
69
|
+
# ============================================================================
|
|
70
|
+
|
|
71
|
+
def _normalize_rel_path(base_dir: str, target: str) -> str:
|
|
72
|
+
if target.startswith("/"):
|
|
73
|
+
return target.lstrip("/")
|
|
74
|
+
return posixpath.normpath(posixpath.join(base_dir, target))
|
|
75
|
+
|
|
76
|
+
def _xlsx_sheet_media(xlsx_path: Path):
|
|
77
|
+
try:
|
|
78
|
+
with zipfile.ZipFile(xlsx_path) as z:
|
|
79
|
+
names = set(z.namelist())
|
|
80
|
+
if "xl/workbook.xml" not in names or "xl/_rels/workbook.xml.rels" not in names:
|
|
81
|
+
return {}
|
|
82
|
+
workbook_xml = z.read("xl/workbook.xml")
|
|
83
|
+
workbook_rels_xml = z.read("xl/_rels/workbook.xml.rels")
|
|
84
|
+
|
|
85
|
+
sheet_rid = {}
|
|
86
|
+
for sheet_el in ET.fromstring(workbook_xml).iter(f"{{{_MAIN_NS}}}sheet"):
|
|
87
|
+
name = sheet_el.get("name")
|
|
88
|
+
rid = sheet_el.get(f"{{{_R_NS}}}id")
|
|
89
|
+
if name and rid:
|
|
90
|
+
sheet_rid[name] = rid
|
|
91
|
+
|
|
92
|
+
rid_target = {}
|
|
93
|
+
for rel in ET.fromstring(workbook_rels_xml).findall(f"{{{_REL_NS}}}Relationship"):
|
|
94
|
+
rid_target[rel.get("Id")] = rel.get("Target")
|
|
95
|
+
|
|
96
|
+
result = {}
|
|
97
|
+
for sheet_name, rid in sheet_rid.items():
|
|
98
|
+
target = rid_target.get(rid)
|
|
99
|
+
if not target:
|
|
100
|
+
continue
|
|
101
|
+
sheet_path = _normalize_rel_path("xl", target)
|
|
102
|
+
if sheet_path not in names or "/" not in sheet_path:
|
|
103
|
+
continue
|
|
104
|
+
sheet_dir, sheet_file = sheet_path.rsplit("/", 1)
|
|
105
|
+
sheet_rels_path = f"{sheet_dir}/_rels/{sheet_file}.rels"
|
|
106
|
+
if sheet_rels_path not in names:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
drawing_rid = None
|
|
110
|
+
for d in ET.fromstring(z.read(sheet_path)).iter(f"{{{_MAIN_NS}}}drawing"):
|
|
111
|
+
drawing_rid = d.get(f"{{{_R_NS}}}id")
|
|
112
|
+
break
|
|
113
|
+
if not drawing_rid:
|
|
114
|
+
continue
|
|
115
|
+
|
|
116
|
+
drawing_target = None
|
|
117
|
+
for rel in ET.fromstring(z.read(sheet_rels_path)).findall(f"{{{_REL_NS}}}Relationship"):
|
|
118
|
+
if rel.get("Id") == drawing_rid:
|
|
119
|
+
drawing_target = rel.get("Target")
|
|
120
|
+
break
|
|
121
|
+
if not drawing_target:
|
|
122
|
+
continue
|
|
123
|
+
drawing_path = _normalize_rel_path(sheet_dir, drawing_target)
|
|
124
|
+
if drawing_path not in names or "/" not in drawing_path:
|
|
125
|
+
continue
|
|
126
|
+
drawing_dir, drawing_file = drawing_path.rsplit("/", 1)
|
|
127
|
+
drawing_rels_path = f"{drawing_dir}/_rels/{drawing_file}.rels"
|
|
128
|
+
if drawing_rels_path not in names:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
drawing_rel_map = {}
|
|
132
|
+
for rel in ET.fromstring(z.read(drawing_rels_path)).findall(f"{{{_REL_NS}}}Relationship"):
|
|
133
|
+
drawing_rel_map[rel.get("Id")] = rel.get("Target")
|
|
134
|
+
|
|
135
|
+
media_paths = []
|
|
136
|
+
for blip in ET.fromstring(z.read(drawing_path)).iter(f"{{{_A_NS}}}blip"):
|
|
137
|
+
embed_rid = blip.get(f"{{{_R_NS}}}embed")
|
|
138
|
+
if not embed_rid:
|
|
139
|
+
continue
|
|
140
|
+
rel_target = drawing_rel_map.get(embed_rid)
|
|
141
|
+
if not rel_target:
|
|
142
|
+
continue
|
|
143
|
+
media_path = _normalize_rel_path(drawing_dir, rel_target)
|
|
144
|
+
if media_path in names:
|
|
145
|
+
media_paths.append(media_path)
|
|
146
|
+
|
|
147
|
+
if media_paths:
|
|
148
|
+
result[sheet_name] = media_paths
|
|
149
|
+
return result
|
|
150
|
+
except Exception:
|
|
151
|
+
return {}
|
|
152
|
+
|
|
153
|
+
def extract_xlsx_images(xlsx_path: Path, img_dir: Path):
|
|
154
|
+
sheet_media = _xlsx_sheet_media(xlsx_path)
|
|
155
|
+
if not sheet_media:
|
|
156
|
+
return {}
|
|
157
|
+
|
|
158
|
+
written = {}
|
|
159
|
+
with zipfile.ZipFile(xlsx_path) as z:
|
|
160
|
+
names_in_zip = set(z.namelist())
|
|
161
|
+
for sheet_idx, (sheet_name, media_paths) in enumerate(sheet_media.items(), start=1):
|
|
162
|
+
safe_name = re.sub(r"[^A-Za-z0-9_.-]+", "_", sheet_name).strip("_") or "sheet"
|
|
163
|
+
safe_prefix = f"sheet{sheet_idx:03d}_{safe_name}"
|
|
164
|
+
files = []
|
|
165
|
+
for idx, media_path in enumerate(media_paths, start=1):
|
|
166
|
+
if media_path not in names_in_zip:
|
|
167
|
+
continue
|
|
168
|
+
ext = Path(media_path).suffix.lstrip(".").lower() or "bin"
|
|
169
|
+
if ext == "jpg":
|
|
170
|
+
ext = "jpeg"
|
|
171
|
+
fname = f"{safe_prefix}_img{idx:03d}.{ext}"
|
|
172
|
+
dest = img_dir / fname
|
|
173
|
+
img_dir.mkdir(parents=True, exist_ok=True)
|
|
174
|
+
with z.open(media_path) as src, open(dest, "wb") as dst:
|
|
175
|
+
shutil.copyfileobj(src, dst)
|
|
176
|
+
files.append(fname)
|
|
177
|
+
if files:
|
|
178
|
+
written[sheet_name] = files
|
|
179
|
+
return written
|
|
180
|
+
|
|
181
|
+
def convert_excel(file_path: Path, out_dir: Path, md_engine) -> bool:
|
|
182
|
+
img_dir = out_dir / "img"
|
|
183
|
+
sheet_images = extract_xlsx_images(file_path, img_dir)
|
|
184
|
+
|
|
185
|
+
if md_engine:
|
|
186
|
+
res = md_engine.convert(str(file_path))
|
|
187
|
+
text = res.text_content
|
|
188
|
+
else:
|
|
189
|
+
text = f"# {file_path.stem}\n\n*(MarkItDown engine not available. Basic conversion applied)*\n"
|
|
190
|
+
|
|
191
|
+
if sheet_images:
|
|
192
|
+
matches = list(_SHEET_HEADER_RE.finditer(text))
|
|
193
|
+
if matches:
|
|
194
|
+
parts = []
|
|
195
|
+
last_end = 0
|
|
196
|
+
for i, m in enumerate(matches):
|
|
197
|
+
sheet_name = m.group(1).strip()
|
|
198
|
+
next_start = matches[i + 1].start() if i + 1 < len(matches) else len(text)
|
|
199
|
+
section = text[last_end:next_start]
|
|
200
|
+
last_end = next_start
|
|
201
|
+
|
|
202
|
+
if sheet_name in sheet_images:
|
|
203
|
+
img_lines = ["\n\n#### Images in this sheet\n"]
|
|
204
|
+
for fname in sheet_images[sheet_name]:
|
|
205
|
+
img_lines.append(f"\n")
|
|
206
|
+
section = section.rstrip() + "\n" + "".join(img_lines)
|
|
207
|
+
parts.append(section)
|
|
208
|
+
text = "".join(parts)
|
|
209
|
+
|
|
210
|
+
out_md = out_dir / f"{file_path.stem}.md"
|
|
211
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
212
|
+
out_md.write_text(text, encoding="utf-8")
|
|
213
|
+
return True
|
|
214
|
+
|
|
215
|
+
# ============================================================================
|
|
216
|
+
# PDF Handler
|
|
217
|
+
# ============================================================================
|
|
218
|
+
|
|
219
|
+
def extract_pdf_images(pdf_path: Path, img_dir: Path):
|
|
220
|
+
try:
|
|
221
|
+
import fitz
|
|
222
|
+
except ImportError:
|
|
223
|
+
return {}
|
|
224
|
+
|
|
225
|
+
written_by_page = {}
|
|
226
|
+
try:
|
|
227
|
+
doc = fitz.open(str(pdf_path))
|
|
228
|
+
except Exception:
|
|
229
|
+
return written_by_page
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
for page_index in range(len(doc)):
|
|
233
|
+
page = doc[page_index]
|
|
234
|
+
page_label = page_index + 1
|
|
235
|
+
raw_images = []
|
|
236
|
+
try:
|
|
237
|
+
xobjects = page.get_images(full=True)
|
|
238
|
+
except Exception:
|
|
239
|
+
xobjects = []
|
|
240
|
+
|
|
241
|
+
for img in xobjects:
|
|
242
|
+
xref = img[0]
|
|
243
|
+
try:
|
|
244
|
+
base_image = doc.extract_image(xref)
|
|
245
|
+
except Exception:
|
|
246
|
+
continue
|
|
247
|
+
img_bytes = base_image.get("image") or b""
|
|
248
|
+
if not img_bytes:
|
|
249
|
+
continue
|
|
250
|
+
ext = (base_image.get("ext") or "png").lower()
|
|
251
|
+
raw_images.append((img_bytes, ext))
|
|
252
|
+
|
|
253
|
+
if not raw_images:
|
|
254
|
+
continue
|
|
255
|
+
|
|
256
|
+
saved_files = []
|
|
257
|
+
img_dir.mkdir(parents=True, exist_ok=True)
|
|
258
|
+
for idx, (img_bytes, ext) in enumerate(raw_images, start=1):
|
|
259
|
+
fname = f"page{page_label:03d}_img{idx:03d}.{ext}"
|
|
260
|
+
dest = img_dir / fname
|
|
261
|
+
dest.write_bytes(img_bytes)
|
|
262
|
+
saved_files.append(fname)
|
|
263
|
+
|
|
264
|
+
if saved_files:
|
|
265
|
+
written_by_page[page_label] = saved_files
|
|
266
|
+
finally:
|
|
267
|
+
doc.close()
|
|
268
|
+
return written_by_page
|
|
269
|
+
|
|
270
|
+
def convert_pdf(file_path: Path, out_dir: Path, md_engine) -> bool:
|
|
271
|
+
img_dir = out_dir / "img"
|
|
272
|
+
page_images = extract_pdf_images(file_path, img_dir)
|
|
273
|
+
|
|
274
|
+
if md_engine:
|
|
275
|
+
res = md_engine.convert(str(file_path))
|
|
276
|
+
text = res.text_content
|
|
277
|
+
else:
|
|
278
|
+
text = f"# {file_path.stem}\n\n*(MarkItDown engine not available)*\n"
|
|
279
|
+
|
|
280
|
+
if page_images:
|
|
281
|
+
appendix = ["\n\n## Extracted Images\n"]
|
|
282
|
+
for page_num in sorted(page_images.keys()):
|
|
283
|
+
appendix.append(f"\n### Page {page_num}\n")
|
|
284
|
+
for fname in page_images[page_num]:
|
|
285
|
+
appendix.append(f"\n")
|
|
286
|
+
text = text.rstrip() + "".join(appendix)
|
|
287
|
+
|
|
288
|
+
out_md = out_dir / f"{file_path.stem}.md"
|
|
289
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
290
|
+
out_md.write_text(text, encoding="utf-8")
|
|
291
|
+
return True
|
|
292
|
+
|
|
293
|
+
# ============================================================================
|
|
294
|
+
# Word Handler
|
|
295
|
+
# ============================================================================
|
|
296
|
+
|
|
297
|
+
def _word_ordered_media(docx_path: Path):
|
|
298
|
+
try:
|
|
299
|
+
with zipfile.ZipFile(docx_path) as z:
|
|
300
|
+
if "word/document.xml" not in z.namelist() or "word/_rels/document.xml.rels" not in z.namelist():
|
|
301
|
+
return []
|
|
302
|
+
rels_xml = z.read("word/_rels/document.xml.rels")
|
|
303
|
+
doc_xml = z.read("word/document.xml")
|
|
304
|
+
except Exception:
|
|
305
|
+
return []
|
|
306
|
+
|
|
307
|
+
try:
|
|
308
|
+
rels_root = ET.fromstring(rels_xml)
|
|
309
|
+
doc_root = ET.fromstring(doc_xml)
|
|
310
|
+
except Exception:
|
|
311
|
+
return []
|
|
312
|
+
|
|
313
|
+
rel_map = {rel.get("Id"): rel.get("Target") for rel in rels_root.findall(f"{{{_REL_NS}}}Relationship")}
|
|
314
|
+
ordered_rel_ids = []
|
|
315
|
+
for elem in doc_root.iter():
|
|
316
|
+
tag = elem.tag.rsplit("}", 1)[-1]
|
|
317
|
+
rid = elem.get(f"{{{_R_NS}}}embed") if tag == "blip" else (elem.get(f"{{{_R_NS}}}id") if tag == "imagedata" else None)
|
|
318
|
+
if rid:
|
|
319
|
+
ordered_rel_ids.append(rid)
|
|
320
|
+
|
|
321
|
+
ordered_media = []
|
|
322
|
+
for rid in ordered_rel_ids:
|
|
323
|
+
target = rel_map.get(rid)
|
|
324
|
+
if not target or "media/" not in target:
|
|
325
|
+
continue
|
|
326
|
+
media_path = target.lstrip("/") if target.startswith("/") else posixpath.normpath(target if target.startswith("word/") else posixpath.join("word", target))
|
|
327
|
+
ordered_media.append((rid, media_path))
|
|
328
|
+
return ordered_media
|
|
329
|
+
|
|
330
|
+
def extract_word_images(docx_path: Path, img_dir: Path):
|
|
331
|
+
ordered_media = _word_ordered_media(docx_path)
|
|
332
|
+
if not ordered_media:
|
|
333
|
+
return []
|
|
334
|
+
|
|
335
|
+
written = []
|
|
336
|
+
with zipfile.ZipFile(docx_path) as z:
|
|
337
|
+
names_in_zip = set(z.namelist())
|
|
338
|
+
for idx, (rid, media_path) in enumerate(ordered_media, start=1):
|
|
339
|
+
if media_path not in names_in_zip:
|
|
340
|
+
continue
|
|
341
|
+
ext = Path(media_path).suffix.lstrip(".").lower() or "bin"
|
|
342
|
+
if ext == "jpg":
|
|
343
|
+
ext = "jpeg"
|
|
344
|
+
fname = f"img{idx:03d}.{ext}"
|
|
345
|
+
dest = img_dir / fname
|
|
346
|
+
img_dir.mkdir(parents=True, exist_ok=True)
|
|
347
|
+
with z.open(media_path) as src, open(dest, "wb") as dst:
|
|
348
|
+
shutil.copyfileobj(src, dst)
|
|
349
|
+
written.append(fname)
|
|
350
|
+
return written
|
|
351
|
+
|
|
352
|
+
def convert_word(file_path: Path, out_dir: Path, md_engine) -> bool:
|
|
353
|
+
img_dir = out_dir / "img"
|
|
354
|
+
images = extract_word_images(file_path, img_dir)
|
|
355
|
+
|
|
356
|
+
if md_engine:
|
|
357
|
+
res = md_engine.convert(str(file_path))
|
|
358
|
+
text = res.text_content
|
|
359
|
+
else:
|
|
360
|
+
text = f"# {file_path.stem}\n\n*(MarkItDown engine not available)*\n"
|
|
361
|
+
|
|
362
|
+
if images:
|
|
363
|
+
img_idx = 0
|
|
364
|
+
def replace_img(match):
|
|
365
|
+
nonlocal img_idx
|
|
366
|
+
alt_text = match.group(1)
|
|
367
|
+
if img_idx < len(images):
|
|
368
|
+
fname = images[img_idx]
|
|
369
|
+
img_idx += 1
|
|
370
|
+
return f""
|
|
371
|
+
return match.group(0)
|
|
372
|
+
|
|
373
|
+
text = _PLACEHOLDER_IMAGE_RE.sub(replace_img, text)
|
|
374
|
+
|
|
375
|
+
out_md = out_dir / f"{file_path.stem}.md"
|
|
376
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
377
|
+
out_md.write_text(text, encoding="utf-8")
|
|
378
|
+
return True
|
|
379
|
+
|
|
380
|
+
# ============================================================================
|
|
381
|
+
# Plaintext Handler
|
|
382
|
+
# ============================================================================
|
|
383
|
+
|
|
384
|
+
def convert_text(file_path: Path, out_dir: Path) -> bool:
|
|
385
|
+
try:
|
|
386
|
+
content = file_path.read_text(encoding="utf-8", errors="replace")
|
|
387
|
+
except Exception as exc:
|
|
388
|
+
print(f"ERROR reading {file_path}: {exc}", file=sys.stderr)
|
|
389
|
+
return False
|
|
390
|
+
|
|
391
|
+
ext = file_path.suffix.lower()
|
|
392
|
+
if ext in {".md", ".markdown"}:
|
|
393
|
+
md_text = content
|
|
394
|
+
else:
|
|
395
|
+
lang_map = {
|
|
396
|
+
".py": "python", ".js": "javascript", ".ts": "typescript",
|
|
397
|
+
".json": "json", ".yaml": "yaml", ".yml": "yaml",
|
|
398
|
+
".html": "html", ".xml": "xml", ".css": "css", ".csv": "csv"
|
|
399
|
+
}
|
|
400
|
+
lang = lang_map.get(ext, "")
|
|
401
|
+
if lang:
|
|
402
|
+
md_text = f"# {file_path.name}\n\n```{lang}\n{content}\n```\n"
|
|
403
|
+
else:
|
|
404
|
+
md_text = f"# {file_path.name}\n\n{content}\n"
|
|
405
|
+
|
|
406
|
+
out_md = out_dir / f"{file_path.stem}.md"
|
|
407
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
408
|
+
out_md.write_text(md_text, encoding="utf-8")
|
|
409
|
+
return True
|
|
410
|
+
|
|
411
|
+
# ============================================================================
|
|
412
|
+
# Main Router
|
|
413
|
+
# ============================================================================
|
|
414
|
+
|
|
415
|
+
def convert_single_file(file_path: Path, base_out_dir: Path, md_engine) -> bool:
|
|
416
|
+
ext = file_path.suffix.lower()
|
|
417
|
+
out_dir = base_out_dir / file_path.stem
|
|
418
|
+
|
|
419
|
+
if ext in IGNORE_EXTS:
|
|
420
|
+
return True
|
|
421
|
+
|
|
422
|
+
print(f"Converting [{ext or 'text'}] {file_path.name} -> {out_dir}")
|
|
423
|
+
|
|
424
|
+
if ext == ".xlsx":
|
|
425
|
+
return convert_excel(file_path, out_dir, md_engine)
|
|
426
|
+
elif ext == ".pdf":
|
|
427
|
+
return convert_pdf(file_path, out_dir, md_engine)
|
|
428
|
+
elif ext == ".docx":
|
|
429
|
+
return convert_word(file_path, out_dir, md_engine)
|
|
430
|
+
elif ext in SUPPORTED_TEXT_EXTS or ext == "":
|
|
431
|
+
return convert_text(file_path, out_dir)
|
|
432
|
+
else:
|
|
433
|
+
# Fallback to text conversion for unknown extensions
|
|
434
|
+
return convert_text(file_path, out_dir)
|
|
435
|
+
|
|
436
|
+
def main():
|
|
437
|
+
parser = argparse.ArgumentParser(
|
|
438
|
+
description="Convert documents to Markdown and save to devflow/reference/"
|
|
439
|
+
)
|
|
440
|
+
parser.add_argument("input", help="Path to a file or directory to convert")
|
|
441
|
+
parser.add_argument(
|
|
442
|
+
"-o", "--output",
|
|
443
|
+
default="devflow/reference",
|
|
444
|
+
help="Target output directory (default: devflow/reference)"
|
|
445
|
+
)
|
|
446
|
+
parser.add_argument(
|
|
447
|
+
"--recursive",
|
|
448
|
+
action="store_true",
|
|
449
|
+
help="Recursively process subdirectories"
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
args = parser.parse_args()
|
|
453
|
+
input_path = Path(args.input).resolve()
|
|
454
|
+
base_out_dir = Path(args.output).resolve()
|
|
455
|
+
|
|
456
|
+
if not input_path.exists():
|
|
457
|
+
print(f"ERROR: Input path not found: {input_path}", file=sys.stderr)
|
|
458
|
+
sys.exit(EXIT_INVALID_INPUT)
|
|
459
|
+
|
|
460
|
+
md_engine = get_markitdown()
|
|
461
|
+
|
|
462
|
+
if input_path.is_file():
|
|
463
|
+
success = convert_single_file(input_path, base_out_dir, md_engine)
|
|
464
|
+
sys.exit(EXIT_OK if success else EXIT_CONVERSION_FAILED)
|
|
465
|
+
elif input_path.is_dir():
|
|
466
|
+
pattern = "**/*" if args.recursive else "*"
|
|
467
|
+
files = [p for p in input_path.glob(pattern) if p.is_file()]
|
|
468
|
+
|
|
469
|
+
if not files:
|
|
470
|
+
print(f"No files found in {input_path}")
|
|
471
|
+
sys.exit(EXIT_OK)
|
|
472
|
+
|
|
473
|
+
success_count = 0
|
|
474
|
+
fail_count = 0
|
|
475
|
+
for f in files:
|
|
476
|
+
if f.suffix.lower() in IGNORE_EXTS:
|
|
477
|
+
continue
|
|
478
|
+
if convert_single_file(f, base_out_dir, md_engine):
|
|
479
|
+
success_count += 1
|
|
480
|
+
else:
|
|
481
|
+
fail_count += 1
|
|
482
|
+
|
|
483
|
+
print(f"\nBatch summary: {success_count} succeeded, {fail_count} failed.")
|
|
484
|
+
sys.exit(EXIT_OK if fail_count == 0 else EXIT_CONVERSION_FAILED)
|
|
485
|
+
|
|
486
|
+
if __name__ == "__main__":
|
|
487
|
+
main()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: convert-any-to-md
|
|
3
|
+
description: '[Devflow] Converts any document (.xlsx, .pdf, .docx, .txt, .csv, .log, .json, .yaml, etc.) or mixed folders into clean Markdown in devflow/reference. Use whenever documents need to be analyzed, summarized, searched, or extracted from.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Convert Any Document to Markdown
|
|
7
|
+
|
|
8
|
+
## When to use this skill
|
|
9
|
+
|
|
10
|
+
Trigger this skill any time there is a document (`.xlsx`, `.pdf`, `.docx`, `.txt`, `.csv`, `.log`, `.json`, `.yaml`, etc.) or a folder of documents that needs to be analyzed, summarized, reviewed, or extracted from.
|
|
11
|
+
|
|
12
|
+
Instead of parsing complex binary XML formats (`.docx`, `.xlsx`) or print layouts (`.pdf`) directly, this skill automatically detects the file type, extracts embedded text and images, and outputs standardized Markdown into **`devflow/reference/`** (or a specified output path).
|
|
13
|
+
|
|
14
|
+
Use this skill for:
|
|
15
|
+
- Single files: `.xlsx`, `.pdf`, `.docx`, `.txt`, `.csv`, `.log`, `.json`, `.yaml`, etc.
|
|
16
|
+
- Folder batch mode: A directory containing a mix of multiple file types.
|
|
17
|
+
|
|
18
|
+
## Setup (once per environment)
|
|
19
|
+
|
|
20
|
+
Before the first conversion in a given environment, follow [`references/setup.md`](references/setup.md) to ensure Python, `markitdown`, `pymupdf`, and `openpyxl` are installed:
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
python -m pip install -r .agents/skills/convert-any-to-md/scripts/requirements.txt
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
The conversion script lives at `.agents/skills/convert-any-to-md/scripts/convert_any_to_md.py`.
|
|
29
|
+
|
|
30
|
+
### Default Destination (`devflow/reference/`)
|
|
31
|
+
|
|
32
|
+
By default, all converted Markdown files and extracted image folders (`img/`) are placed inside **`devflow/reference/`**:
|
|
33
|
+
|
|
34
|
+
```powershell
|
|
35
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\document.pdf"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Output:
|
|
39
|
+
```text
|
|
40
|
+
devflow/reference/
|
|
41
|
+
└── document/
|
|
42
|
+
├── img/
|
|
43
|
+
│ ├── page001_img001.png
|
|
44
|
+
│ └── ...
|
|
45
|
+
└── document.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Specifying Custom Output Destination (`-o`)
|
|
49
|
+
|
|
50
|
+
To direct output to a specific folder:
|
|
51
|
+
|
|
52
|
+
```powershell
|
|
53
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\document.docx" -o "C:\custom\path"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Folder Batch Mode (`--recursive`)
|
|
57
|
+
|
|
58
|
+
To convert an entire folder (including mixed file types):
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\documents_folder"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Add `--recursive` to scan subdirectories:
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
python .agents/skills/convert-any-to-md/scripts/convert_any_to_md.py "C:\path\to\documents_folder" --recursive
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Format Support & Behavior
|
|
71
|
+
|
|
72
|
+
| Format | Handler | Image Extraction | Output Structure |
|
|
73
|
+
| :--- | :--- | :--- | :--- |
|
|
74
|
+
| `.xlsx` | MarkItDown + OpenPyXL | Extracts sheet embedded images | `<name>/<name>.md` + `img/` |
|
|
75
|
+
| `.pdf` | MarkItDown + PyMuPDF | Extracts page images into appendix | `<name>/<name>.md` + `img/` |
|
|
76
|
+
| `.docx` | MarkItDown + ZIP Media | Extracts word media images | `<name>/<name>.md` + `img/` |
|
|
77
|
+
| `.txt`, `.csv`, `.json`, `.yaml`, `.log` | Plaintext Formatter | N/A | `<name>/<name>.md` |
|
|
78
|
+
|
|
79
|
+
> [!NOTE]
|
|
80
|
+
> Legacy binary formats (`.xls`, `.doc`) are not supported directly. Ask the user to re-save them as `.xlsx` / `.docx` first.
|