@leftoff/cli 0.9.8-beta.17 → 0.9.8-beta.18
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/mod/.claude-plugin/plugin.json +1 -1
- package/mod/hooks/register.js +1 -1
- package/package.json +1 -1
- package/ui/app.css +10 -2
- package/ui/app.js +9 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leftoff",
|
|
3
|
-
"version": "0.9.8-beta.
|
|
3
|
+
"version": "0.9.8-beta.18",
|
|
4
4
|
"description": "Leftoff (formerly Checkpoints): WTF was I working on? Tracks every Claude Code session on this machine, writes a 3-line checkpoint when one goes quiet, and adds /cp (checkpoint now), /cp-name and a /leftoff pane. Talks to the local Leftoff daemon on 127.0.0.1:7429 and falls back to writing markdown in ~/checkpoints.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Joel"
|
package/mod/hooks/register.js
CHANGED
|
@@ -28,7 +28,7 @@ const END_TIMEOUT_MS = 1000
|
|
|
28
28
|
const MODEL_TIMEOUT_MS = 20000
|
|
29
29
|
|
|
30
30
|
// Module state. $.state is not used: the pane redraws with $.ui.invalidate.
|
|
31
|
-
const MOD_VERSION = '0.9.8-beta.
|
|
31
|
+
const MOD_VERSION = '0.9.8-beta.18' // keep in step with .claude-plugin/plugin.json
|
|
32
32
|
|
|
33
33
|
const st = {
|
|
34
34
|
internal: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leftoff/cli",
|
|
3
|
-
"version": "0.9.8-beta.
|
|
3
|
+
"version": "0.9.8-beta.18",
|
|
4
4
|
"description": "Leftoff: WTF was I working on? Tracks every Claude Code session, writes a 3-line checkpoint when one goes quiet, and gives you a daily digest and a board, on your Mac and (optionally) your phone.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
package/ui/app.css
CHANGED
|
@@ -2614,5 +2614,13 @@ html.pv-open, html.pv-open body { overflow: hidden; }
|
|
|
2614
2614
|
/* 0.9.8: a non-Live session's Live box offers the Live resume command */
|
|
2615
2615
|
.live-box.off .live-resume-row { position: relative; margin-top: 6px; }
|
|
2616
2616
|
.live-box.off .live-resume-row code { display: block; min-width: 0; overflow-wrap: anywhere; font-size: 12.5px; line-height: 1.5; padding: 12px 52px 12px 12px; min-height: 44px; box-sizing: border-box; border-radius: 8px; background: var(--card2); border: 1px solid var(--line); }
|
|
2617
|
-
.live-box.off .live-resume-row .copy-float { position: absolute; top:
|
|
2618
|
-
.live-box.off .live-resume-row .copy-float:
|
|
2617
|
+
.live-box.off .live-resume-row .copy-float { position: absolute; top: 50%; right: 2px; transform: translateY(-50%); width: 44px; height: 44px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
|
|
2618
|
+
.live-box.off .live-resume-row .copy-float::before { content: ''; position: absolute; inset: 7px; border-radius: 7px; border: 1px solid transparent; transition: background .12s, border-color .12s; }
|
|
2619
|
+
.live-box.off .live-resume-row .copy-float svg { position: relative; width: 16px; height: 16px; }
|
|
2620
|
+
.live-box.off .live-resume-row .copy-float:hover { color: var(--text); }
|
|
2621
|
+
.live-box.off .live-resume-row .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
|
|
2622
|
+
.live-box.off .live-resume-row .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
|
|
2623
|
+
.live-box.off .live-resume-row .copy-float.copied { color: var(--accent); }
|
|
2624
|
+
.live-box.off .live-resume-row .copy-float::after { content: attr(data-tip); position: absolute; bottom: calc(100% - 2px); right: 4px; padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; white-space: nowrap; opacity: 0; transform: translateY(3px); transition: opacity .12s, transform .12s; pointer-events: none; }
|
|
2625
|
+
@media (hover: hover) { .live-box.off .live-resume-row .copy-float:hover::after { opacity: 1; transform: none; transition-delay: .35s; } }
|
|
2626
|
+
.live-box.off .live-resume-row .copy-float:focus-visible::after, .live-box.off .live-resume-row .copy-float.copied::after { opacity: 1; transform: none; transition-delay: 0s; }
|
package/ui/app.js
CHANGED
|
@@ -1485,7 +1485,7 @@ function liveBoxHtml(s, v) {
|
|
|
1485
1485
|
return '<section class="live-box off" aria-label="Live link"><div class="live-head"><h2>Live <span class="pill soon">Beta</span></h2></div>' +
|
|
1486
1486
|
'<p class="faint">To send this session messages from here or your phone, and answer its permission prompts, start it with <code>leftoff live</code>' +
|
|
1487
1487
|
(how && how.line ? ' (or <code>' + esc(how.line) + '</code>)' : '') + '. Claude Code asks once to load the channel; channels are a research preview.</p>' +
|
|
1488
|
-
(s.liveResumeCommand ? '<p class="faint">Already running? Exit it in its terminal, then paste this to bring it back Live:</p><div class="live-resume-row"><code class="mono">' + esc(s.liveResumeCommand) + '</code><button type="button" class="copy-float" data-action="copy-cmd" data-cmd="' + esc(s.liveResumeCommand) + '" aria-label="Copy Live resume"
|
|
1488
|
+
(s.liveResumeCommand ? '<p class="faint">Already running? Exit it in its terminal, then paste this to bring it back Live:</p><div class="live-resume-row"><code class="mono">' + esc(s.liveResumeCommand) + '</code><button type="button" class="copy-float" data-action="copy-cmd" data-cmd="' + esc(s.liveResumeCommand) + '" aria-label="Copy Live resume" data-tip="Copy">' + icon('copy') + '</button></div>' : '') + '</section>'
|
|
1489
1489
|
}
|
|
1490
1490
|
const msgs = (v && v.messages) || []
|
|
1491
1491
|
const may = state.mayAnswer !== false
|
|
@@ -4864,7 +4864,14 @@ document.addEventListener('click', async (ev) => {
|
|
|
4864
4864
|
const id = btn.dataset.id || (card && card.dataset.id)
|
|
4865
4865
|
const s = state.sessions.find((x) => x.id === id) || (closedUi.data && closedUi.data.sessions.find((x) => x.id === id))
|
|
4866
4866
|
try {
|
|
4867
|
-
if (action === 'copy-cmd') {
|
|
4867
|
+
if (action === 'copy-cmd') {
|
|
4868
|
+
const ok = await copy(btn.dataset.cmd)
|
|
4869
|
+
if (ok && btn.classList.contains('copy-float')) { // 0.9.8: the floating copy shows a check for a moment, no tooltip
|
|
4870
|
+
clearTimeout(btn._copied); btn.classList.add('copied'); btn.innerHTML = icon('check'); btn.setAttribute('aria-label', 'Copied'); btn.dataset.tip = 'Copied'
|
|
4871
|
+
btn._copied = setTimeout(() => { btn.classList.remove('copied'); btn.innerHTML = icon('copy'); btn.setAttribute('aria-label', 'Copy Live resume'); btn.dataset.tip = 'Copy' }, 1500)
|
|
4872
|
+
}
|
|
4873
|
+
return
|
|
4874
|
+
}
|
|
4868
4875
|
// PRs (0.6.9)
|
|
4869
4876
|
if (action === 'prs-view') { const v = btn.dataset.view === 'team' ? 'team' : 'mine'; try { localStorage.setItem('leftoff.prsView', v) } catch {} location.hash = prsHash(v, prsUi.filter); return }
|
|
4870
4877
|
// 0.8.5: filters (in the hash), expand a PR in place, the Quiet group
|