@leftoff/cli 0.9.9-beta.2 → 0.9.9-beta.3
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/CHANGELOG.md +1 -0
- package/bin/leftoff.js +342 -342
- package/mod/.claude-plugin/plugin.json +1 -1
- package/mod/hooks/register.js +1 -1
- package/package.json +1 -1
- package/ui/app.js +6 -4
- package/ui/start.js +7 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leftoff",
|
|
3
|
-
"version": "0.9.9-beta.
|
|
3
|
+
"version": "0.9.9-beta.3",
|
|
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.9-beta.
|
|
31
|
+
const MOD_VERSION = '0.9.9-beta.3' // 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.9-beta.
|
|
3
|
+
"version": "0.9.9-beta.3",
|
|
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.js
CHANGED
|
@@ -16,7 +16,7 @@ import { navHideStep, NAVHIDE_TYPING } from './navhide.js'
|
|
|
16
16
|
import { openLightbox } from './lightbox.js' // 0.9.8: the image preview
|
|
17
17
|
import { openPdfView, pdfThumb } from './pdfview.js' // 0.9.8: the PDF preview (pdf.js loads on the first PDF)
|
|
18
18
|
import { isBlank, composerKey, isTouchUi, composerHeight, composerBoxHtml } from './composer.js' // 0.9.8 the Live composer
|
|
19
|
-
import { startPageHtml, startPick, startAsksBanner, headlessBarHtml, startsSettingHtml } from './start.js' // 0.9.9 New session
|
|
19
|
+
import { startPageHtml, startPick, startAsksBanner, headlessBarHtml, startsSettingHtml, startViewerLocal as startViewerAt } from './start.js' // 0.9.9 New session
|
|
20
20
|
import { attachPlan, skippedText, shortName, prepareFile, uploadFile, fetchAttachment, fmtSize, attachKind, pastedName, ATTACH_MAX_FILES } from './attach.js' // 0.9.8 attachments
|
|
21
21
|
import { wireTips } from './tips.js'
|
|
22
22
|
import { mountUpdateBar, takeCarry } from './update-bar.js' // 0.9.8 "Leftoff updated · Refresh"
|
|
@@ -841,7 +841,7 @@ async function viewBoard() {
|
|
|
841
841
|
'<a class="btn primary" href="#/catchup/new">' + icon('coffee') + 'Catch me up</a>' +
|
|
842
842
|
'<a class="btn" href="#/digest">' + icon('newspaper') + 'Today’s digest →</a></div></div>'
|
|
843
843
|
html += syncDetails() + staleLine(sessions)
|
|
844
|
-
html += restoreAsksBanner() + startAsksBanner(state.starts, { esc, icon, local:
|
|
844
|
+
html += restoreAsksBanner() + startAsksBanner(state.starts, { esc, icon, local: startViewerLocal(state.starts && state.starts.viewer), clock, busy: startUi.busy }) + restoreBanner()
|
|
845
845
|
// Needs you (v0.4.4): every session waiting on you, whatever the filters, longest wait first.
|
|
846
846
|
const needs = needsItems(sessions)
|
|
847
847
|
html += needsStrip(needs, needOpts())
|
|
@@ -3397,7 +3397,7 @@ async function viewSettings() {
|
|
|
3397
3397
|
phone: phonePane(relay, remote, unavailable),
|
|
3398
3398
|
security: '<div class="section" id="answering">Other devices</div>' + (answeringSection(remote, relay) ||
|
|
3399
3399
|
'<div class="full hint">Nothing reaches this board from elsewhere until <a href="#/settings/phone">Phone & remote</a> is on.</div>') +
|
|
3400
|
-
startsSettingHtml(starts, { esc, local:
|
|
3400
|
+
startsSettingHtml(starts, { esc, local: startViewerLocal(starts && starts.viewer) }) +
|
|
3401
3401
|
// a changed machine key needs a click here, so Other machines stays up top then
|
|
3402
3402
|
(peers && (peers.peers || []).some((x) => x.trust === 'key_changed') ? machinesSection(peers) : '') +
|
|
3403
3403
|
advanced('security', (peers && (peers.peers || []).some((x) => x.trust === 'key_changed') ? '' : machinesSection(peers)) +
|
|
@@ -4165,12 +4165,14 @@ async function render() {
|
|
|
4165
4165
|
|
|
4166
4166
|
// ------------------------------------------------------------ New session (0.9.9, ui/start.js)
|
|
4167
4167
|
|
|
4168
|
+
// this Mac's own browser, or the hosted board open on it (the direct door)
|
|
4169
|
+
function startViewerLocal(v) { return startViewerAt(v, state.viewerLocal !== false) }
|
|
4168
4170
|
const startUi = { data: null, machine: null, repo: null, where: 'repo', allRepos: false, ask: null, busy: new Set(), sending: false, poll: null }
|
|
4169
4171
|
async function viewNewSession() {
|
|
4170
4172
|
try { startUi.data = await api('GET', '/v1/start') } catch (e) { if (!startUi.data) throw e }
|
|
4171
4173
|
const fa = document.activeElement
|
|
4172
4174
|
const kf = fa && fa.classList && fa.classList.contains('start-text') ? { a: fa.selectionStart, b: fa.selectionEnd } : null
|
|
4173
|
-
$app.innerHTML = startPageHtml(startUi.data, startUi, { esc, icon, emoji: mEmoji, local:
|
|
4175
|
+
$app.innerHTML = startPageHtml(startUi.data, startUi, { esc, icon, emoji: mEmoji, local: startViewerLocal(startUi.data.viewer), clock, draft: (state.drafts && state.drafts.start) || '', busy: startUi.sending })
|
|
4174
4176
|
const ta = $app.querySelector('.start-text')
|
|
4175
4177
|
if (ta) { fitComposer(ta); if (kf && !ta.disabled) { ta.focus({ preventScroll: true }); try { ta.setSelectionRange(kf.a, kf.b) } catch {} } }
|
|
4176
4178
|
}
|
package/ui/start.js
CHANGED
|
@@ -8,6 +8,13 @@ import { composerBoxHtml } from './composer.js'
|
|
|
8
8
|
|
|
9
9
|
const REPOS_SHOWN = 6
|
|
10
10
|
|
|
11
|
+
// At this Mac: its own browser (the daemon says local), or your hosted board
|
|
12
|
+
// open on it through the direct door (local and direct). boardLocal is the
|
|
13
|
+
// board's own read of where it runs; the direct door overrides it.
|
|
14
|
+
export function startViewerLocal(viewer, boardLocal = true) {
|
|
15
|
+
return !!(viewer && viewer.local) && (boardLocal || viewer.direct === true)
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
// The choice the page shows: what you picked, else this Mac (or the first
|
|
12
19
|
// online one), its newest repo, and "In the repo".
|
|
13
20
|
export function startPick(data, ui = {}) {
|