From d204a768029bd64dabd177fd4f534989a20265f9 Mon Sep 17 00:00:00 2001 From: OpenClaw Bot Date: Sat, 23 May 2026 22:24:08 +0200 Subject: [PATCH] Add Rank AI-ready prompt copy button --- public/app.js | 39 +++++++++++++++++++++++++++++++++++++++ public/index.html | 6 ++++-- public/styles.css | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/public/app.js b/public/app.js index 83caffd..fd258dc 100644 --- a/public/app.js +++ b/public/app.js @@ -62,6 +62,27 @@ const sampleBacklog = { { title: 'AI explains why an idea moved', description: 'Every ranking should show a reason, risk, and what evidence would change the decision.', labels: ['Trust', 'AI'], impact: 9, effort: 6, confidence: 6, urgency: 8 } ] }; +const aiReadyPrompt = `You are preparing features for Rank / Prioritix, a prioritization workbench that imports Prioritix Feature Set v1 JSON. Convert my messy backlog, notes, stakeholder requests, or product ideas into valid JSON only — no markdown, no commentary. + +Return this exact shape: +{ + "format": "prioritix-feature-set-v1", + "name": "Short project or backlog name", + "features": [ + { + "title": "Clear feature title", + "description": "Plain-language reason this feature matters and what outcome it supports.", + "labels": ["Category", "Optional second category"], + "impact": 1-10, + "effort": 1-10, + "confidence": 1-10, + "urgency": 1-10, + "notes": "Risks, assumptions, dependencies, or evidence that would change the ranking." + } + ] +} + +Scoring guidance: impact means user/business value, effort means delivery difficulty, confidence means how sure the evidence is, urgency means time sensitivity. Use the full 1-10 range honestly. Split vague bundles into separate features. Merge duplicates. Label polish as polish, bets as validation/research, and must-have product work as core. If evidence is weak, lower confidence rather than pretending. Keep titles short enough to scan on a card.`; function loadSampleBacklog(){ const input = $('#featureSetInput'); if(!input) return; @@ -69,6 +90,23 @@ function loadSampleBacklog(){ document.querySelector('#feature-sets')?.scrollIntoView({ behavior:'smooth', block:'start' }); toast('Sample backlog loaded. Import it or replace it with your own chaos.'); } +async function copyAiPrompt(){ + const status = $('#aiPromptStatus'); + try { + await navigator.clipboard.writeText(aiReadyPrompt); + if(status) status.textContent = 'Copied. Paste it into any AI, then paste the returned JSON back here.'; + toast('AI-ready prompt copied'); + } catch { + const input = $('#featureSetInput'); + if(input){ + input.value = aiReadyPrompt; + input.focus(); + input.select(); + } + if(status) status.textContent = 'Clipboard blocked — the prompt is selected in the text area for manual copy.'; + toast('Clipboard blocked. Prompt selected for manual copy.'); + } +} const $ = (sel, root=document) => root.querySelector(sel); const $$ = (sel, root=document) => Array.from(root.querySelectorAll(sel)); @@ -188,6 +226,7 @@ function openDetail(id){ const idea=state.ideas.find(i=>i.id===id); if(!idea) re function closeDetail(){ detail.classList.remove('open'); detail.setAttribute('aria-hidden','true'); state.selected=null; } async function archiveIdea(id=state.selected){ if(!id) return; const previous=state.ideas.find(i=>i.id===id); try{ await api(`/api/ideas/${id}`,{method:'PATCH',body:{archived:true,status:'remove'}}); state.ideas = state.ideas.filter(i=>i.id!==id); closeDetail(); render(); toast('Removed', previous ? () => undoIdea({...previous, archived:false}) : null); } catch(error){ toast(error.message); } } $('#sampleBacklog')?.addEventListener('click', loadSampleBacklog); +$('#copyAiPrompt')?.addEventListener('click', copyAiPrompt); $('#featureSetFile')?.addEventListener('change', async e => { const file = e.currentTarget.files?.[0]; if(!file) return; diff --git a/public/index.html b/public/index.html index 1e9d3a9..9fba48c 100644 --- a/public/index.html +++ b/public/index.html @@ -6,7 +6,7 @@ Rank — Work your ideas before they work you - +
@@ -142,9 +142,11 @@ }'>
+
+

Copies a prompt that makes another AI return import-ready Rank JSON.

@@ -219,6 +221,6 @@ - + diff --git a/public/styles.css b/public/styles.css index 632e85f..60d12fd 100644 --- a/public/styles.css +++ b/public/styles.css @@ -19,7 +19,7 @@ button,input,textarea{font:inherit} button{cursor:pointer} a{color:inherit;text- .shortcut-hint{margin:10px 2px 0;color:var(--slate-600);font-size:12px}.shortcut-hint kbd{display:inline-grid;place-items:center;min-width:22px;height:20px;padding:0 5px;border:1px solid var(--border);border-bottom-width:2px;border-radius:4px;background:#fff;color:var(--navy-950);font-weight:800}.timeline-line.drag-over{outline:2px dashed var(--blue-600);outline-offset:8px;background:linear-gradient(90deg,rgba(22,163,74,.06),rgba(37,99,235,.06),rgba(245,158,11,.06),rgba(124,58,237,.06))}.node[draggable="true"]{cursor:grab}.node[draggable="true"]:active{cursor:grabbing}.toast{display:flex;align-items:center;gap:12px}.toast button{border:1px solid rgba(255,255,255,.35);background:rgba(255,255,255,.12);color:#fff;border-radius:4px;padding:6px 9px;font-weight:800}.detail label input[name="labels"]{width:100%;border:1px solid var(--border);border-radius:6px;padding:11px 12px;background:#F8FAFC;color:var(--slate-900);margin-top:6px}.profile-menu button.selected{background:#F0E9FF;color:var(--purple-600);font-weight:900} @media(max-width:680px){.workspace{padding:10px}.topbar{padding:12px;gap:12px}.project-title h1{font-size:21px}.sorting-grid{grid-template-columns:1fr 1fr;gap:9px}.zone{min-height:142px;padding:12px}.zone-icon{font-size:30px}.zone strong{font-size:14px}.zone span{font-size:12px}.capture-strip form,.deck-actions,.detail-grid,.detail-actions{grid-template-columns:1fr}.timeline{overflow-x:auto}.timeline-line{min-width:760px}.feature-card{min-height:160px}.feature-card::before,.feature-card::after{display:none}} -.feature-set-panel{display:grid;grid-template-columns:minmax(280px,.9fr) minmax(420px,1.4fr);gap:16px;background:linear-gradient(135deg,rgba(6,27,51,.96),rgba(9,38,75,.92));color:white;border:1px solid rgba(255,255,255,.12);border-radius:var(--radius);box-shadow:var(--shadow);padding:16px;margin-bottom:18px;overflow:hidden;position:relative}.feature-set-panel::before{content:"";position:absolute;inset:auto -80px -120px auto;width:260px;height:260px;background:radial-gradient(circle,rgba(69,184,255,.25),transparent 65%);pointer-events:none}.feature-set-copy{position:relative;z-index:1}.feature-set-copy .section-label{color:#A7D8FF}.feature-set-copy h2{margin:7px 0 8px;font-size:22px;letter-spacing:-.03em}.feature-set-copy p{margin:0;color:#D9E8FF;line-height:1.5;font-size:13px}.feature-set-copy code{background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.10);border-radius:4px;padding:1px 5px;color:#fff}.feature-set-actions{position:relative;z-index:1;display:grid;gap:10px}.feature-set-actions textarea{width:100%;min-height:178px;resize:vertical;border:1px solid rgba(255,255,255,.16);border-radius:6px;background:rgba(2,8,23,.64);color:#EAF6FF;padding:12px;font-family:"JetBrains Mono","SFMono-Regular",ui-monospace,monospace;font-size:12px;line-height:1.45;outline:none}.feature-set-actions textarea:focus{border-color:#45B8FF;box-shadow:0 0 0 3px rgba(69,184,255,.16)}.feature-set-toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.feature-set-toolbar button,.file-pick{border:1px solid rgba(255,255,255,.20);border-radius:6px;background:rgba(255,255,255,.10);color:white;padding:10px 12px;font-weight:850;box-shadow:0 10px 24px rgba(0,0,0,.12)}.feature-set-toolbar button:hover,.file-pick:hover{background:rgba(255,255,255,.16)}.file-pick input{position:absolute;inline-size:1px;block-size:1px;opacity:0;pointer-events:none}@media(max-width:1050px){.feature-set-panel{grid-template-columns:1fr}.feature-set-actions textarea{min-height:220px}} +.feature-set-panel{display:grid;grid-template-columns:minmax(280px,.9fr) minmax(420px,1.4fr);gap:16px;background:linear-gradient(135deg,rgba(6,27,51,.96),rgba(9,38,75,.92));color:white;border:1px solid rgba(255,255,255,.12);border-radius:var(--radius);box-shadow:var(--shadow);padding:16px;margin-bottom:18px;overflow:hidden;position:relative}.feature-set-panel::before{content:"";position:absolute;inset:auto -80px -120px auto;width:260px;height:260px;background:radial-gradient(circle,rgba(69,184,255,.25),transparent 65%);pointer-events:none}.feature-set-copy{position:relative;z-index:1}.feature-set-copy .section-label{color:#A7D8FF}.feature-set-copy h2{margin:7px 0 8px;font-size:22px;letter-spacing:-.03em}.feature-set-copy p{margin:0;color:#D9E8FF;line-height:1.5;font-size:13px}.feature-set-copy code{background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.10);border-radius:4px;padding:1px 5px;color:#fff}.feature-set-actions{position:relative;z-index:1;display:grid;gap:10px}.feature-set-actions textarea{width:100%;min-height:178px;resize:vertical;border:1px solid rgba(255,255,255,.16);border-radius:6px;background:rgba(2,8,23,.64);color:#EAF6FF;padding:12px;font-family:"JetBrains Mono","SFMono-Regular",ui-monospace,monospace;font-size:12px;line-height:1.45;outline:none}.feature-set-actions textarea:focus{border-color:#45B8FF;box-shadow:0 0 0 3px rgba(69,184,255,.16)}.feature-set-toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.feature-set-toolbar button,.file-pick{border:1px solid rgba(255,255,255,.20);border-radius:6px;background:rgba(255,255,255,.10);color:white;padding:10px 12px;font-weight:850;box-shadow:0 10px 24px rgba(0,0,0,.12)}.feature-set-toolbar button:hover,.file-pick:hover{background:rgba(255,255,255,.16)}.feature-set-toolbar .ai-prompt-button{background:linear-gradient(135deg,#0B63F6,#7C3AED);border-color:rgba(255,255,255,.24)}.ai-prompt-status{margin:-2px 0 0;color:#BFD7F2;font-size:12px;line-height:1.4}.file-pick input{position:absolute;inline-size:1px;block-size:1px;opacity:0;pointer-events:none}@media(max-width:1050px){.feature-set-panel{grid-template-columns:1fr}.feature-set-actions textarea{min-height:220px}} .mobile-home{display:none}.review-panel{background:white;border:1px solid var(--border);border-radius:6px;box-shadow:var(--shadow-soft);padding:18px;margin-top:18px}.placed-card{margin:10px auto 0;padding:9px 10px;border:1px solid var(--border);border-radius:12px;background:white;box-shadow:var(--shadow-soft);text-align:left;max-width:170px}.placed-card small{display:block!important;color:var(--slate-600)!important;font-size:10px!important;text-transform:uppercase;letter-spacing:.04em}.placed-card strong{display:block!important;margin:2px 0 0!important;color:var(--slate-900)!important;font-size:12px!important}.review-hero{text-align:center;padding:10px 0 16px}.success-mark{width:76px;height:76px;margin:0 auto 12px;border-radius:50%;display:grid;place-items:center;background:linear-gradient(135deg,#16A34A,#22C55E);color:white;font-size:44px;font-weight:900;box-shadow:0 18px 40px rgba(22,163,74,.22)}.review-hero h2{margin:0 0 4px;font-size:24px}.review-hero p{margin:0;color:var(--slate-600)}.review-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.review-stats div,.review-row{border:1px solid var(--border);border-radius:8px;background:#FBFCFF;padding:12px}.review-stats strong{display:block;color:var(--navy-950)}.review-stats span{color:var(--slate-600);font-size:12px}.review-groups{display:grid;gap:8px;margin:12px 0}.review-row{display:grid;grid-template-columns:34px 1fr auto;align-items:center}.review-row span{color:var(--node-color);font-size:22px}.review-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px}.review-actions a,.review-actions button{display:grid;place-items:center;border:1px solid var(--border);border-radius:6px;background:white;color:var(--navy-950);padding:12px;font-weight:900}.review-actions button{background:linear-gradient(135deg,var(--blue-600),var(--purple-600));color:white;border:0}.roadmap-list{display:grid;gap:13px}.roadmap-phase{position:relative;padding-left:18px;border-left:3px solid var(--node-color)}.roadmap-phase h3{margin:0 0 8px;color:var(--node-color);font-size:13px}.roadmap-item{width:100%;display:grid;grid-template-columns:34px 1fr auto;gap:10px;align-items:center;text-align:left;border:1px solid var(--border);border-radius:16px;background:white;padding:12px;box-shadow:var(--shadow-soft)}.roadmap-dot{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;border:3px solid var(--node-color);color:var(--node-color);font-weight:900}.roadmap-item strong{display:block;color:var(--slate-900)}.roadmap-item small{display:block;color:var(--slate-600);margin-top:2px}.roadmap-empty{border:1px dashed var(--border);border-radius:14px;color:var(--slate-400);padding:14px;text-align:center;background:#FBFCFF}.roadmap-utilities{border:1px solid var(--border);border-radius:14px;padding:12px;color:var(--slate-600);font-size:12px}.roadmap-utilities a{color:var(--blue-600);font-weight:900}