thevoidforge 21.0.6 → 21.0.8
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.
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
* Handles the simple key: value format used in PRD frontmatter blocks.
|
|
4
4
|
*/
|
|
5
5
|
export function parseFrontmatter(content) {
|
|
6
|
-
//
|
|
6
|
+
// Try ```yaml ... ``` block first (markdown code fence)
|
|
7
7
|
const yamlBlockMatch = content.match(/```yaml\s*\n([\s\S]*?)```/);
|
|
8
|
-
|
|
8
|
+
// Then try --- ... --- block (standard YAML frontmatter)
|
|
9
|
+
const dashBlockMatch = !yamlBlockMatch ? content.match(/^---\s*\n([\s\S]*?)\n---/) : null;
|
|
10
|
+
const match = yamlBlockMatch ?? dashBlockMatch;
|
|
11
|
+
if (!match) {
|
|
9
12
|
return { frontmatter: {}, body: content };
|
|
10
13
|
}
|
|
11
|
-
const yamlStr =
|
|
14
|
+
const yamlStr = match[1];
|
|
12
15
|
const frontmatter = {};
|
|
13
16
|
for (const line of yamlStr.split('\n')) {
|
|
14
17
|
const trimmed = line.trim();
|
package/dist/wizard/ui/app.js
CHANGED
|
@@ -669,6 +669,50 @@
|
|
|
669
669
|
}
|
|
670
670
|
});
|
|
671
671
|
|
|
672
|
+
// PRD file upload + drag-and-drop
|
|
673
|
+
const dropzone = $('#prd-dropzone');
|
|
674
|
+
const fileInput = $('#prd-file-input');
|
|
675
|
+
const prdTextarea = $('#prd-paste');
|
|
676
|
+
|
|
677
|
+
if (dropzone && fileInput) {
|
|
678
|
+
function handlePrdFile(file) {
|
|
679
|
+
const reader = new FileReader();
|
|
680
|
+
reader.onload = function (e) {
|
|
681
|
+
prdTextarea.value = e.target.result;
|
|
682
|
+
showStatus(prdStatus, 'success', 'Loaded: ' + file.name + ' (' + file.size + ' bytes)');
|
|
683
|
+
dropzone.style.borderColor = 'var(--accent, #5b5bf7)';
|
|
684
|
+
setTimeout(function () { dropzone.style.borderColor = ''; }, 2000);
|
|
685
|
+
};
|
|
686
|
+
reader.onerror = function () {
|
|
687
|
+
showStatus(prdStatus, 'error', 'Failed to read file');
|
|
688
|
+
};
|
|
689
|
+
reader.readAsText(file);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
dropzone.addEventListener('click', function () { fileInput.click(); });
|
|
693
|
+
dropzone.addEventListener('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') fileInput.click(); });
|
|
694
|
+
|
|
695
|
+
fileInput.addEventListener('change', function () {
|
|
696
|
+
if (fileInput.files && fileInput.files[0]) handlePrdFile(fileInput.files[0]);
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
dropzone.addEventListener('dragover', function (e) {
|
|
700
|
+
e.preventDefault();
|
|
701
|
+
dropzone.style.borderColor = 'var(--accent, #5b5bf7)';
|
|
702
|
+
dropzone.style.background = 'rgba(91, 91, 247, 0.05)';
|
|
703
|
+
});
|
|
704
|
+
dropzone.addEventListener('dragleave', function () {
|
|
705
|
+
dropzone.style.borderColor = '';
|
|
706
|
+
dropzone.style.background = '';
|
|
707
|
+
});
|
|
708
|
+
dropzone.addEventListener('drop', function (e) {
|
|
709
|
+
e.preventDefault();
|
|
710
|
+
dropzone.style.borderColor = '';
|
|
711
|
+
dropzone.style.background = '';
|
|
712
|
+
if (e.dataTransfer.files && e.dataTransfer.files[0]) handlePrdFile(e.dataTransfer.files[0]);
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
|
|
672
716
|
let cachedPrompt = null;
|
|
673
717
|
$('#copy-prd-prompt').addEventListener('click', async () => {
|
|
674
718
|
const promptCopyStatus = $('#prompt-copy-status');
|
|
@@ -177,18 +177,26 @@
|
|
|
177
177
|
|
|
178
178
|
<div class="tab-panel" id="tab-paste" role="tabpanel" aria-labelledby="tab-btn-paste">
|
|
179
179
|
<div class="card">
|
|
180
|
-
<p>Already have a PRD
|
|
180
|
+
<p>Already have a PRD? Drop the file here, upload it, or paste below.</p>
|
|
181
|
+
|
|
182
|
+
<div class="field">
|
|
183
|
+
<div id="prd-dropzone" style="border: 2px dashed var(--border, #333); border-radius: 8px; padding: 2rem; text-align: center; cursor: pointer; transition: border-color 0.2s, background 0.2s; margin-bottom: 12px;" role="button" tabindex="0" aria-label="Drop a PRD file here or click to upload">
|
|
184
|
+
<p style="margin: 0 0 8px 0; font-size: 1.1em;">Drop your PRD file here</p>
|
|
185
|
+
<p style="margin: 0; opacity: 0.6; font-size: 0.9em;">or click to browse (.md, .txt, .yaml)</p>
|
|
186
|
+
<input type="file" id="prd-file-input" accept=".md,.txt,.yaml,.yml,.markdown" style="display: none;">
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
181
189
|
|
|
182
190
|
<div class="field">
|
|
183
191
|
<label>PRD Generator Prompt</label>
|
|
184
|
-
<p class="field-hint" style="margin-bottom: 8px;">
|
|
192
|
+
<p class="field-hint" style="margin-bottom: 8px;">Or copy this prompt into ChatGPT, Gemini, or any AI — then paste the output below.</p>
|
|
185
193
|
<button class="btn btn-secondary" id="copy-prd-prompt" type="button">Copy Generator Prompt to Clipboard</button>
|
|
186
194
|
<div class="status-row" id="prompt-copy-status" role="status" aria-live="polite"></div>
|
|
187
195
|
</div>
|
|
188
196
|
|
|
189
197
|
<div class="field">
|
|
190
198
|
<label for="prd-paste">Your PRD</label>
|
|
191
|
-
<textarea id="prd-paste" rows="16" placeholder="Paste your PRD here.
|
|
199
|
+
<textarea id="prd-paste" rows="16" placeholder="Paste your PRD here. Start with YAML frontmatter: --- name: My Project type: full-stack framework: next.js database: postgres deploy: vps --- # My Project Description and requirements..."></textarea>
|
|
192
200
|
</div>
|
|
193
201
|
<button class="btn btn-secondary" id="validate-prd" type="button">Validate Frontmatter</button>
|
|
194
202
|
<div class="status-row" id="prd-status" role="status" aria-live="polite"></div>
|