@tenonhq/dovetail-dashboard 0.0.14 → 0.0.16
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/package.json +1 -1
- package/public/claude-plans.css +48 -2
- package/public/claude-plans.js +125 -0
package/package.json
CHANGED
package/public/claude-plans.css
CHANGED
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
.cp-detail-header { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
|
|
106
106
|
.cp-detail-header h2 { font-size: 20px; margin: 0; }
|
|
107
107
|
.cp-stamp { font-size: 11px; color: var(--text-muted); margin-left: auto; }
|
|
108
|
-
.cp-tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
|
|
108
|
+
.cp-tabs { display: flex; gap: 0; align-items: center; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
|
|
109
109
|
.cp-tab {
|
|
110
110
|
background: transparent;
|
|
111
111
|
border: none;
|
|
@@ -148,8 +148,8 @@
|
|
|
148
148
|
}
|
|
149
149
|
.cp-artifact-head {
|
|
150
150
|
display: flex;
|
|
151
|
-
justify-content: space-between;
|
|
152
151
|
align-items: center;
|
|
152
|
+
gap: 8px;
|
|
153
153
|
margin-bottom: 12px;
|
|
154
154
|
}
|
|
155
155
|
.cp-artifact-title { font-weight: 600; font-size: 14px; }
|
|
@@ -641,3 +641,49 @@
|
|
|
641
641
|
white-space: nowrap;
|
|
642
642
|
}
|
|
643
643
|
.cp-pr-badge:hover { background: rgba(100,140,190,0.25); color: var(--text); }
|
|
644
|
+
|
|
645
|
+
/* ─── Resume button in plan detail header ──────────────────────────────────── */
|
|
646
|
+
.cp-resume-btn {
|
|
647
|
+
display: inline-flex;
|
|
648
|
+
align-items: center;
|
|
649
|
+
padding: 3px 10px;
|
|
650
|
+
border-radius: 4px;
|
|
651
|
+
font-size: 12px;
|
|
652
|
+
font-family: inherit;
|
|
653
|
+
font-weight: 600;
|
|
654
|
+
letter-spacing: 0.02em;
|
|
655
|
+
background: rgba(74, 140, 92, 0.15);
|
|
656
|
+
color: #92d3a4;
|
|
657
|
+
border: 1px solid rgba(74, 140, 92, 0.4);
|
|
658
|
+
cursor: pointer;
|
|
659
|
+
white-space: nowrap;
|
|
660
|
+
transition: background 0.15s, color 0.15s;
|
|
661
|
+
}
|
|
662
|
+
.cp-resume-btn:hover {
|
|
663
|
+
background: rgba(74, 140, 92, 0.28);
|
|
664
|
+
color: var(--text);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/* ─── Toast notification ────────────────────────────────────────────────────── */
|
|
668
|
+
.cp-toast {
|
|
669
|
+
position: fixed;
|
|
670
|
+
bottom: 20px;
|
|
671
|
+
right: 20px;
|
|
672
|
+
background: var(--card-bg);
|
|
673
|
+
border: 1px solid rgba(74, 140, 92, 0.5);
|
|
674
|
+
border-left: 3px solid #4a8c5c;
|
|
675
|
+
color: #92d3a4;
|
|
676
|
+
padding: 9px 16px;
|
|
677
|
+
border-radius: 4px;
|
|
678
|
+
font-size: 13px;
|
|
679
|
+
font-family: inherit;
|
|
680
|
+
z-index: 9999;
|
|
681
|
+
opacity: 0;
|
|
682
|
+
transform: translateY(6px);
|
|
683
|
+
transition: opacity 0.2s, transform 0.2s;
|
|
684
|
+
pointer-events: none;
|
|
685
|
+
}
|
|
686
|
+
.cp-toast--visible {
|
|
687
|
+
opacity: 1;
|
|
688
|
+
transform: translateY(0);
|
|
689
|
+
}
|
package/public/claude-plans.js
CHANGED
|
@@ -66,6 +66,18 @@
|
|
|
66
66
|
setTimeout(function () { el.remove(); }, 4000);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function showToast(msg) {
|
|
70
|
+
var el = document.createElement("div");
|
|
71
|
+
el.className = "cp-toast";
|
|
72
|
+
el.textContent = msg;
|
|
73
|
+
document.body.appendChild(el);
|
|
74
|
+
setTimeout(function () { el.classList.add("cp-toast--visible"); }, 10);
|
|
75
|
+
setTimeout(function () {
|
|
76
|
+
el.classList.remove("cp-toast--visible");
|
|
77
|
+
setTimeout(function () { el.remove(); }, 300);
|
|
78
|
+
}, 2200);
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
function renderMarkdown(md, target) {
|
|
70
82
|
if (!window.marked || !window.DOMPurify) {
|
|
71
83
|
target.textContent = md;
|
|
@@ -99,6 +111,84 @@
|
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
|
|
114
|
+
/* ─── Copy helpers ─────────────────────────────────────────────────────────── */
|
|
115
|
+
|
|
116
|
+
function fallbackCopy(text) {
|
|
117
|
+
var ta = document.createElement("textarea");
|
|
118
|
+
ta.value = text;
|
|
119
|
+
ta.style.cssText = "position:fixed;left:-9999px;top:-9999px;opacity:0";
|
|
120
|
+
document.body.appendChild(ta);
|
|
121
|
+
ta.select();
|
|
122
|
+
try { document.execCommand("copy"); } catch (_) {}
|
|
123
|
+
ta.remove();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function makeCopyBtn(label, getText) {
|
|
127
|
+
var btn = document.createElement("button");
|
|
128
|
+
btn.className = "cp-copy-btn";
|
|
129
|
+
btn.textContent = label;
|
|
130
|
+
btn.addEventListener("click", function (e) {
|
|
131
|
+
e.stopPropagation();
|
|
132
|
+
var text = getText();
|
|
133
|
+
var flash = function () {
|
|
134
|
+
btn.textContent = "Copied!";
|
|
135
|
+
btn.classList.add("cp-copy-btn--copied");
|
|
136
|
+
setTimeout(function () {
|
|
137
|
+
btn.textContent = label;
|
|
138
|
+
btn.classList.remove("cp-copy-btn--copied");
|
|
139
|
+
}, 1500);
|
|
140
|
+
};
|
|
141
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
142
|
+
navigator.clipboard.writeText(text).then(flash).catch(function () {
|
|
143
|
+
fallbackCopy(text);
|
|
144
|
+
flash();
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
fallbackCopy(text);
|
|
148
|
+
flash();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
return btn;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function addTabsCopyAll(plan, artifacts) {
|
|
155
|
+
var existing = document.getElementById("cp-tabs-copy-all");
|
|
156
|
+
if (existing) existing.remove();
|
|
157
|
+
|
|
158
|
+
var btn = makeCopyBtn("Copy All", function () {
|
|
159
|
+
if (state.activeTab === "artifacts") {
|
|
160
|
+
return artifacts.map(function (a) {
|
|
161
|
+
return "# " + a.title + "\n\n" + a.content;
|
|
162
|
+
}).join("\n\n---\n\n");
|
|
163
|
+
}
|
|
164
|
+
return plan.content_md && plan.content_md.trim()
|
|
165
|
+
? plan.content_md
|
|
166
|
+
: els.planPanel.innerText.trim();
|
|
167
|
+
});
|
|
168
|
+
btn.id = "cp-tabs-copy-all";
|
|
169
|
+
btn.style.marginLeft = "auto";
|
|
170
|
+
var tabsEl = document.querySelector(".cp-tabs");
|
|
171
|
+
if (tabsEl) tabsEl.appendChild(btn);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function addPlanSectionCopyBtns() {
|
|
175
|
+
var structured = els.planPanel.querySelector(".cp-structured");
|
|
176
|
+
if (!structured) return;
|
|
177
|
+
var children = Array.from(structured.children);
|
|
178
|
+
children.forEach(function (child) {
|
|
179
|
+
child.classList.add("cp-c-copy-wrap");
|
|
180
|
+
var group = document.createElement("div");
|
|
181
|
+
group.className = "cp-copy-btn-group";
|
|
182
|
+
var btn = makeCopyBtn("Copy", (function (el) {
|
|
183
|
+
return function () { return el.innerText.trim(); };
|
|
184
|
+
})(child));
|
|
185
|
+
group.appendChild(btn);
|
|
186
|
+
child.appendChild(group);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* ─────────────────────────────────────────────────────────────────────────── */
|
|
191
|
+
|
|
102
192
|
function renderRail() {
|
|
103
193
|
var plans = sortedPlans();
|
|
104
194
|
els.count.textContent = String(plans.length);
|
|
@@ -165,6 +255,8 @@
|
|
|
165
255
|
if (!state.selectedSlug || !state.plans.has(state.selectedSlug)) {
|
|
166
256
|
els.detailEmpty.style.display = "block";
|
|
167
257
|
els.detailBody.hidden = true;
|
|
258
|
+
var orphan = document.getElementById("cp-tabs-copy-all");
|
|
259
|
+
if (orphan) orphan.remove();
|
|
168
260
|
return;
|
|
169
261
|
}
|
|
170
262
|
var plan = state.plans.get(state.selectedSlug);
|
|
@@ -193,6 +285,28 @@
|
|
|
193
285
|
els.detailStamp.insertAdjacentElement("afterend", prBadge);
|
|
194
286
|
}
|
|
195
287
|
|
|
288
|
+
var existingResumeBtn = document.getElementById("cp-resume-btn");
|
|
289
|
+
if (existingResumeBtn) existingResumeBtn.remove();
|
|
290
|
+
var resumeBtn = document.createElement("button");
|
|
291
|
+
resumeBtn.id = "cp-resume-btn";
|
|
292
|
+
resumeBtn.className = "cp-resume-btn";
|
|
293
|
+
resumeBtn.textContent = "Resume";
|
|
294
|
+
resumeBtn.title = "Copy /resume command to clipboard";
|
|
295
|
+
resumeBtn.addEventListener("click", function () {
|
|
296
|
+
var cmd = "/resume " + plan.slug;
|
|
297
|
+
var finish = function () { showToast("Copied! Paste into Claude."); };
|
|
298
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
299
|
+
navigator.clipboard.writeText(cmd).then(finish).catch(function () {
|
|
300
|
+
fallbackCopy(cmd);
|
|
301
|
+
finish();
|
|
302
|
+
});
|
|
303
|
+
} else {
|
|
304
|
+
fallbackCopy(cmd);
|
|
305
|
+
finish();
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
els.detailStatus.insertAdjacentElement("afterend", resumeBtn);
|
|
309
|
+
|
|
196
310
|
if (plan.content_html) {
|
|
197
311
|
els.planPanel.innerHTML = window.DOMPurify
|
|
198
312
|
? window.DOMPurify.sanitize(plan.content_html)
|
|
@@ -201,6 +315,9 @@
|
|
|
201
315
|
renderMarkdown(plan.content_md, els.planPanel);
|
|
202
316
|
}
|
|
203
317
|
|
|
318
|
+
addPlanSectionCopyBtns();
|
|
319
|
+
addTabsCopyAll(plan, artifacts);
|
|
320
|
+
|
|
204
321
|
els.artifactsPanel.innerHTML = "";
|
|
205
322
|
if (artifacts.length === 0) {
|
|
206
323
|
var empty = document.createElement("div");
|
|
@@ -222,6 +339,14 @@
|
|
|
222
339
|
kind.textContent = artifact.kind;
|
|
223
340
|
head.appendChild(title);
|
|
224
341
|
head.appendChild(kind);
|
|
342
|
+
|
|
343
|
+
var copyGroup = document.createElement("div");
|
|
344
|
+
copyGroup.className = "cp-copy-btn-group cp-copy-btn-group--artifact";
|
|
345
|
+
copyGroup.appendChild(makeCopyBtn("Copy", (function (content) {
|
|
346
|
+
return function () { return content; };
|
|
347
|
+
})(artifact.content)));
|
|
348
|
+
head.appendChild(copyGroup);
|
|
349
|
+
|
|
225
350
|
card.appendChild(head);
|
|
226
351
|
|
|
227
352
|
var body = document.createElement("div");
|