@vibelord/lanes 1.0.0 → 1.0.1
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/payload/lanes/README.md +56 -1
- package/payload/lanes/VERSION +1 -1
- package/payload/lanes/bin/lanes +281 -104
- package/payload/lanes/client/lanes-launch +44 -2
- package/payload/lanes/container/env.sh +8 -0
- package/payload/lanes/container/lane +19 -2
- package/payload/lanes/docs/ARCHITECTURE.md +86 -1
- package/payload/lanes/docs/DESIGN.md +72 -0
- package/payload/lanes/docs/INSTALL.md +39 -0
- package/payload/lanes/docs/RUNBOOK.md +94 -1
- package/payload/lanes/holders/ssh.sh +18 -0
- package/payload/lanes/install/enable-phone.sh +15 -6
- package/payload/lanes/install/enable-web.sh +19 -6
- package/payload/lanes/libexec/agent_state.py +214 -0
- package/payload/lanes/libexec/connection.py +178 -0
- package/payload/lanes/libexec/cursor_sync.py +139 -6
- package/payload/lanes/libexec/device_sync.py +134 -0
- package/payload/lanes/libexec/lanes_lib.py +158 -5
- package/payload/lanes/libexec/registrations.py +148 -0
- package/payload/lanes/libexec/session_actions.py +47 -15
- package/payload/lanes/libexec/sidebar.py +372 -61
- package/payload/lanes/libexec/statusd.py +126 -33
- package/payload/lanes/libexec/tokens.py +279 -0
- package/payload/lanes/libexec/tokens.sh +11 -0
- package/payload/lanes/libexec/view.sh +9 -8
- package/payload/lanes/web/README.md +15 -0
- package/payload/lanes/web/browser.css +22 -0
- package/payload/lanes/web/browser.js +73 -0
- package/payload/lanes/web/mobile.css +65 -33
- package/payload/lanes/web/mobile.js +23 -5
- package/payload/lanes/workspaces.example/README.md +9 -3
- package/payload/lanes/zellij/config.kdl +61 -3
- package/payload/manifest.json +6 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* LNS-31 laptop/tablet extras, outside the phone's mobile.css budget (spec §8). No scroll-time paint. */
|
|
2
|
+
/* Tablet (LNS-31): the dock joins the top bar; the workspace sheet is a left panel */
|
|
3
|
+
html.lanes-tablet, html.lanes-tablet.lanes-keyboard { --lanes-dock: 0px; }
|
|
4
|
+
.lanes-tablet .lanes-dock { position: static; display: flex; gap: 4px; width: auto; height: 48px; padding: 0; border: 0; background: none; }
|
|
5
|
+
.lanes-tablet .lanes-dock .lanes-button { flex-direction: row; gap: 6px; min-height: 44px; padding: 0 10px; }
|
|
6
|
+
.lanes-tablet .lanes-dock .lanes-button span { font-size: 13px; }
|
|
7
|
+
.lanes-tablet .lanes-terminal-input { width: 140px; height: 44px; }
|
|
8
|
+
.lanes-tablet .lanes-input-label { flex-direction: row; }
|
|
9
|
+
.lanes-tablet .lanes-filter-bar { flex: 0 1 220px; }
|
|
10
|
+
.lanes-tablet .lanes-sheet { align-items: stretch; padding: 0; }
|
|
11
|
+
.lanes-tablet .lanes-sheet-panel {
|
|
12
|
+
width: min(400px, 85vw); max-height: none; border: 1px solid var(--lanes-border); border-left: 0;
|
|
13
|
+
border-radius: 0 24px 24px 0; padding: calc(20px + var(--lanes-safe-top)) 16px calc(8px + var(--lanes-safe-bottom)) calc(16px + var(--lanes-safe-left));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Desktop (LNS-31): the plain client plus a Lanes chip and its overlay bar; system colours */
|
|
17
|
+
.lanes-chip, .lanes-bar { position: fixed; z-index: 600; color-scheme: dark; font: 13px system-ui, sans-serif; }
|
|
18
|
+
.lanes-chip { top: 4px; right: 8px; padding: 2px 10px; border: 1px solid GrayText; border-radius: 12px; background: Canvas; color: CanvasText; opacity: .7; cursor: pointer; }
|
|
19
|
+
.lanes-chip:hover, .lanes-chip[aria-expanded="true"] { opacity: 1; }
|
|
20
|
+
.lanes-bar { top: 0; left: 0; right: 0; height: 34px; display: flex; gap: 8px; align-items: center; padding: 0 80px 0 8px; background: Canvas; border-bottom: 1px solid GrayText; }
|
|
21
|
+
.lanes-bar[hidden] { display: none; }
|
|
22
|
+
.lanes-bar select { max-width: 40%; height: 26px; border: 1px solid GrayText; border-radius: 6px; background: Canvas; color: CanvasText; font: inherit; }
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* LNS-31 laptop/tablet extras; see docs/ARCHITECTURE.md (Web and phone). */
|
|
2
|
+
function laneBarModel(d) {
|
|
3
|
+
const panes = (d?.panes || []).filter(p => !p.is_plugin), at = d?.active_pane || {}, ws = new Map();
|
|
4
|
+
const first = t => t && panes.find(p => p.tab_position === t.position);
|
|
5
|
+
for (const t of d?.tabs || []) {
|
|
6
|
+
const name = t.name.replace(/ ☰$/, '');
|
|
7
|
+
ws.set(name, {...ws.get(name), name, [name === t.name ? 'view' : 'picker']: t});
|
|
8
|
+
}
|
|
9
|
+
const here = [...ws.values()].find(g => [g.view, g.picker].some(t => t && t.position === at.tab_position));
|
|
10
|
+
const item = (label, p, current = p?.pane_id === at.pane_id) => p && {label, pane: p.pane_id, current};
|
|
11
|
+
return {
|
|
12
|
+
workspaces: [...ws.values()].map(g => item(g.name, first(g.view) || first(g.picker), g === here)).filter(Boolean),
|
|
13
|
+
lanes: [item('☰ Choose a lane', first(here?.picker)), ...panes.filter(p => p.tab_position === here?.view?.position)
|
|
14
|
+
.map(p => item(p.title || `Pane ${p.pane_id}`, p))].filter(Boolean),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
// Tablet: upstream starts single pane on every load; once, send its own switch-to-desktop prefs.
|
|
18
|
+
function laneFullRender(api, send) {
|
|
19
|
+
let done;
|
|
20
|
+
return () => {
|
|
21
|
+
const s = api.getState?.();
|
|
22
|
+
if (done || !s?.initialPrefsSent || s.renderMode !== 'single-pane') return false;
|
|
23
|
+
done = s.renderMode = 'full';
|
|
24
|
+
s.fitEnabled = true;
|
|
25
|
+
send({type: 'SetMobileRenderPreferences', single_pane: false, fit: true});
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (typeof module === 'object') module.exports = {laneBarModel, laneFullRender};
|
|
30
|
+
(() => {
|
|
31
|
+
const mode = globalThis.document?.documentElement.dataset.lanesShell;
|
|
32
|
+
if (mode !== 'desktop' && mode !== 'tablet') return;
|
|
33
|
+
const send = p => window.__zjSendControl?.(p), focus = () => window.term?.focus();
|
|
34
|
+
const make = (tag, props) => Object.assign(document.createElement(tag), props);
|
|
35
|
+
const ready = api => {
|
|
36
|
+
const setData = api.setData, after = mode === 'tablet' ? tablet(api) : desktop(api);
|
|
37
|
+
api.setData = v => {setData.call(api, v); after();};
|
|
38
|
+
after();
|
|
39
|
+
};
|
|
40
|
+
const tablet = api => {
|
|
41
|
+
const full = laneFullRender(api, send);
|
|
42
|
+
return () => full() && dispatchEvent(new Event('zellij:rendering-resize'));
|
|
43
|
+
};
|
|
44
|
+
// Desktop: the chip toggles an overlay bar (no refit); picks send the phone picker's FocusPane.
|
|
45
|
+
const desktop = api => {
|
|
46
|
+
let last;
|
|
47
|
+
const picks = ['Workspace', 'Lane'].map(title => make('select', {title, onchange() {
|
|
48
|
+
send({type: 'FocusPane', pane_id: +this.value, is_plugin: false});
|
|
49
|
+
focus();
|
|
50
|
+
}}));
|
|
51
|
+
const bar = make('nav', {className: 'lanes-bar', hidden: true});
|
|
52
|
+
const render = () => {
|
|
53
|
+
const m = !bar.hidden && laneBarModel(api.getState()?.data), sig = JSON.stringify(m);
|
|
54
|
+
if (!m || sig === last) return;
|
|
55
|
+
last = sig;
|
|
56
|
+
[m.workspaces, m.lanes].forEach((l, i) => picks[i].replaceChildren(...l.map(o => new Option(o.label, o.pane, 0, o.current))));
|
|
57
|
+
};
|
|
58
|
+
const chip = make('button', {className: 'lanes-chip', textContent: 'Lanes', ariaExpanded: false, onclick() {
|
|
59
|
+
chip.ariaExpanded = !(bar.hidden = !bar.hidden);
|
|
60
|
+
last = '';
|
|
61
|
+
render();
|
|
62
|
+
window.term?.focus();
|
|
63
|
+
}});
|
|
64
|
+
chip.addEventListener('mousedown', ev => ev.preventDefault()); // the terminal keeps the keys
|
|
65
|
+
bar.addEventListener('keydown', ev => ev.key === 'Escape' && focus());
|
|
66
|
+
bar.append(...picks);
|
|
67
|
+
document.body.append(bar, chip);
|
|
68
|
+
return render;
|
|
69
|
+
};
|
|
70
|
+
const ui = () => window.__zjMobileUi; // set synchronously after the client appends its mobile root
|
|
71
|
+
if (ui()) return ready(ui());
|
|
72
|
+
new MutationObserver((_, o) => ui() && (o.disconnect(), ready(ui()))).observe(document.body, {childList: true});
|
|
73
|
+
})();
|
|
@@ -1,15 +1,70 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* BEGIN lanes tokens (generated by libexec/tokens.py --css; do not edit by hand) */
|
|
2
2
|
html.lanes-mobile {
|
|
3
|
-
--lanes-
|
|
4
|
-
--lanes-
|
|
5
|
-
--lanes-
|
|
6
|
-
--lanes-
|
|
7
|
-
--lanes-
|
|
8
|
-
--lanes-accent: #b4e3bf;
|
|
9
|
-
--lanes-current: #1a2721;
|
|
10
|
-
--lanes-current-border: #4b6955;
|
|
3
|
+
--lanes-surface: #101318;
|
|
4
|
+
--lanes-surface-raised: #191e25;
|
|
5
|
+
--lanes-line: #2c333d;
|
|
6
|
+
--lanes-accent-wash: #1a2721;
|
|
7
|
+
--lanes-accent-line: #4b6955;
|
|
11
8
|
--lanes-press: #26332c;
|
|
12
|
-
--lanes-chip: #
|
|
9
|
+
--lanes-chip: #ffffff0f;
|
|
10
|
+
--lanes-ink: #edf1f5;
|
|
11
|
+
--lanes-ink-dim: #9ca7b5;
|
|
12
|
+
--lanes-ink-faint: #6b7683;
|
|
13
|
+
--lanes-accent: #b4e3bf;
|
|
14
|
+
--lanes-on-accent: #101318;
|
|
15
|
+
--lanes-on-accent-urgent: #7a1a12;
|
|
16
|
+
--lanes-tone-urgent: #f28b7d;
|
|
17
|
+
--lanes-tone-attention: #e5b84a;
|
|
18
|
+
--lanes-tone-working: #7fb3f2;
|
|
19
|
+
--lanes-tone-done: #6fd39a;
|
|
20
|
+
--lanes-scrim: #000000a6;
|
|
21
|
+
--lanes-shadow: 0 -16px 80px #0007;
|
|
22
|
+
color-scheme: dark;
|
|
23
|
+
}
|
|
24
|
+
html.lanes-mobile:root[data-zj-theme="light"] {
|
|
25
|
+
--lanes-surface: #f3f5f2;
|
|
26
|
+
--lanes-surface-raised: #ffffff;
|
|
27
|
+
--lanes-line: #d5ded6;
|
|
28
|
+
--lanes-accent-wash: #e5f0e6;
|
|
29
|
+
--lanes-accent-line: #acc9b4;
|
|
30
|
+
--lanes-press: #d8e9db;
|
|
31
|
+
--lanes-chip: #edf3ec;
|
|
32
|
+
--lanes-ink: #17241b;
|
|
33
|
+
--lanes-ink-dim: #56616d;
|
|
34
|
+
--lanes-ink-faint: #7f8a96;
|
|
35
|
+
--lanes-accent: #2f6b45;
|
|
36
|
+
--lanes-on-accent: #ffffff;
|
|
37
|
+
--lanes-on-accent-urgent: #ffd3cc;
|
|
38
|
+
--lanes-tone-urgent: #b7322a;
|
|
39
|
+
--lanes-tone-attention: #8a5a00;
|
|
40
|
+
--lanes-tone-working: #2456a8;
|
|
41
|
+
--lanes-tone-done: #1b7142;
|
|
42
|
+
--lanes-scrim: #1a222b80;
|
|
43
|
+
--lanes-shadow: 0 -16px 80px #0003;
|
|
44
|
+
color-scheme: light;
|
|
45
|
+
}
|
|
46
|
+
html.lanes-mobile:root {
|
|
47
|
+
--lanes-bg: var(--lanes-surface);
|
|
48
|
+
--lanes-panel: var(--lanes-surface-raised);
|
|
49
|
+
--lanes-border: var(--lanes-line);
|
|
50
|
+
--lanes-text: var(--lanes-ink);
|
|
51
|
+
--lanes-muted: var(--lanes-ink-dim);
|
|
52
|
+
--lanes-current: var(--lanes-accent-wash);
|
|
53
|
+
--lanes-current-border: var(--lanes-accent-line);
|
|
54
|
+
--zj-bg: var(--lanes-surface);
|
|
55
|
+
--zj-surface: var(--lanes-surface-raised);
|
|
56
|
+
--zj-border: var(--lanes-line);
|
|
57
|
+
--zj-text: var(--lanes-ink);
|
|
58
|
+
--zj-text-dim: var(--lanes-ink-dim);
|
|
59
|
+
--zj-green: var(--lanes-tone-done);
|
|
60
|
+
--zj-blue: var(--lanes-tone-working);
|
|
61
|
+
--zj-red: var(--lanes-tone-urgent);
|
|
62
|
+
--zj-yellow: var(--lanes-tone-attention);
|
|
63
|
+
}
|
|
64
|
+
/* END lanes tokens */
|
|
65
|
+
/* Non-colour layout variables; colours come from the generated token block above.
|
|
66
|
+
Safe areas apply in Home Screen mode and on both sides of landscape Safari. */
|
|
67
|
+
html.lanes-mobile {
|
|
13
68
|
--lanes-safe-top: env(safe-area-inset-top, 0px);
|
|
14
69
|
--lanes-safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
15
70
|
--lanes-safe-left: env(safe-area-inset-left, 0px);
|
|
@@ -21,32 +76,9 @@ html.lanes-mobile {
|
|
|
21
76
|
--lanes-vw: 100vw;
|
|
22
77
|
--lanes-offset-top: 0px;
|
|
23
78
|
--lanes-offset-left: 0px;
|
|
24
|
-
color-scheme: dark;
|
|
25
79
|
-webkit-text-size-adjust: 100%;
|
|
26
80
|
overscroll-behavior: none;
|
|
27
81
|
}
|
|
28
|
-
html.lanes-mobile:root {
|
|
29
|
-
--zj-bg: var(--lanes-bg);
|
|
30
|
-
--zj-surface: var(--lanes-panel);
|
|
31
|
-
--zj-border: var(--lanes-border);
|
|
32
|
-
--zj-text: var(--lanes-text);
|
|
33
|
-
--zj-text-dim: var(--lanes-muted);
|
|
34
|
-
--zj-green: var(--lanes-accent);
|
|
35
|
-
--zj-blue: var(--lanes-accent);
|
|
36
|
-
}
|
|
37
|
-
html.lanes-mobile:root[data-zj-theme="light"] {
|
|
38
|
-
--lanes-bg: #f3f5f2;
|
|
39
|
-
--lanes-panel: #ffffff;
|
|
40
|
-
--lanes-border: #d5ded6;
|
|
41
|
-
--lanes-text: #17241b;
|
|
42
|
-
--lanes-muted: #59695f;
|
|
43
|
-
--lanes-accent: #356544;
|
|
44
|
-
--lanes-current: #e5f0e6;
|
|
45
|
-
--lanes-current-border: #acc9b4;
|
|
46
|
-
--lanes-press: #d8e9db;
|
|
47
|
-
--lanes-chip: #edf3ec;
|
|
48
|
-
color-scheme: light;
|
|
49
|
-
}
|
|
50
82
|
html.lanes-keyboard {
|
|
51
83
|
--lanes-dock: 48px;
|
|
52
84
|
--lanes-keys: 48px;
|
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
/* Lanes
|
|
2
|
-
*
|
|
1
|
+
/* Lanes browser shell over the pinned Zellij 0.45.1 client's window hooks; auth, input, rendering and transport
|
|
2
|
+
* stay upstream. LNS-31: phone (today's rule or a coarse landscape phone), tablet (other touch), desktop. */
|
|
3
|
+
function laneShellMode({userAgent, coarse, width, height} = {}) {
|
|
4
|
+
if (/iPhone|iPod|Android.*Mobile/i.test(userAgent) || (coarse && (width <= 600 || height <= 500))) return 'phone';
|
|
5
|
+
return coarse ? 'tablet' : 'desktop';
|
|
6
|
+
}
|
|
7
|
+
if (typeof module === 'object') module.exports = {laneShellMode};
|
|
3
8
|
(() => {
|
|
4
9
|
'use strict';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
if (typeof document === 'undefined') return;
|
|
11
|
+
const mode = laneShellMode({userAgent: navigator.userAgent, coarse: matchMedia('(pointer: coarse)').matches,
|
|
12
|
+
width: innerWidth, height: innerHeight});
|
|
8
13
|
const root = document.documentElement;
|
|
14
|
+
root.dataset.lanesShell = mode; // web/browser.js: the desktop bar and the tablet's full rendering
|
|
15
|
+
if (mode !== 'phone') { // laptop/tablet extras: a phone never fetches them
|
|
16
|
+
const add = (tag, props) => document.head.append(Object.assign(document.createElement(tag), props));
|
|
17
|
+
add('link', {rel: 'stylesheet', href: '/lanes-assets/browser.css'});
|
|
18
|
+
add('script', {src: '/lanes-assets/browser.js'});
|
|
19
|
+
}
|
|
20
|
+
if (mode === 'desktop') return;
|
|
9
21
|
root.classList.add('lanes-mobile');
|
|
22
|
+
if (mode === 'tablet') {
|
|
23
|
+
// iPad Safari's UA is desktop: ask for the mobile UI (a stored 'off' stays).
|
|
24
|
+
root.classList.add('lanes-tablet');
|
|
25
|
+
try {localStorage.getItem('zellij:mobile-ui') || localStorage.setItem('zellij:mobile-ui', 'on');} catch (_) {}
|
|
26
|
+
}
|
|
10
27
|
|
|
11
28
|
// Only a browser's native tap/focus on an input may summon the keyboard. Zellij
|
|
12
29
|
// otherwise refocuses a hidden input on touchstart, touchend, click and server
|
|
@@ -234,6 +251,7 @@
|
|
|
234
251
|
else if (!ev.shiftKey && document.activeElement === last) {ev.preventDefault(); first.focus();}
|
|
235
252
|
});
|
|
236
253
|
shell.append(header, dock, sheet); document.body.append(shell);
|
|
254
|
+
if (mode === 'tablet') more.before(dock);
|
|
237
255
|
root.classList.add('lanes-ready');
|
|
238
256
|
// Upstream cancels pointerdown on extra keys, which also suppresses their
|
|
239
257
|
// touch click in Safari. Cancel mousedown instead: keep typing focus while
|
|
@@ -13,10 +13,16 @@ Copy this folder to `~/.config/lanes/workspaces/` and edit it.
|
|
|
13
13
|
| `catalog.json` | The boards, in tab order: `id` (also the uploads/watch-folder name), `title` (the tab), `manifest`. |
|
|
14
14
|
| `workspaces.<board>.json` | Where the board's lanes come from: one or more `repositories`, each naming the workspace **container** (`host`) and the board's terminal registry (`registry`: the repository's `.vscode/terminals.json`). Optional per repository: `prefix` (prepended to lane titles), `displayNames`, `bindingOverrides` (tmux socket/session for a terminal whose registry entry has none), `cursor` (a second file to project the board into, for boards whose registry lives outside a repository). `monitor` adds the full-pane Throttle monitor tab. |
|
|
15
15
|
| `commit-targets.json` | Only for `lanes cursor-commit`: repository, branch and author for committing the normalized registries. |
|
|
16
|
+
| `registered-sessions.json` | Optional, created by **Add to workspace** or `lanes register`: `version: 1`, plus `sessions` records with `id`, `workspace`, `name`, `container`, `tmux: {socket, session}`, and `folder`. Preserve this file in site backups. |
|
|
16
17
|
|
|
17
|
-
A lane is whatever the registry says it is: `lanes sync` (every two minutes, read-only) turns each
|
|
18
|
-
lane with a stable id `<board>--<slug of the terminal name
|
|
19
|
-
|
|
18
|
+
A lane is whatever the registry says it is: `lanes sync` (every two minutes, read-only) turns each repository
|
|
19
|
+
terminal into a lane with a stable id `<board>--<slug of the terminal name>` (with the repository `prefix`). A
|
|
20
|
+
`displayNames` entry, which the sidebar `R` key and `lanes rename <lane-id> <name>` write into the repository's block
|
|
21
|
+
of `workspaces.<board>.json` (first write keeps a `.bak-<UTC>` copy beside it), changes only the shown name, never the
|
|
22
|
+
id. Add a terminal to `.vscode/terminals.json` for an editor-defined lane.
|
|
23
|
+
Alternatively, use **+** beside a discovered session to register its existing binding and ID in a workspace
|
|
24
|
+
using the same container. Sync includes these local registrations; they never run a create command.
|
|
25
|
+
Repository declarations take precedence when they declare the same binding. Legacy Docker shells cannot be adopted.
|
|
20
26
|
|
|
21
27
|
After editing: `lanes sync && lanes doctor`.
|
|
22
28
|
|
|
@@ -331,12 +331,70 @@ env {
|
|
|
331
331
|
FORCE_COLOR "3"
|
|
332
332
|
FORCE_HYPERLINK "1"
|
|
333
333
|
}
|
|
334
|
+
osc8_hyperlinks true
|
|
335
|
+
// BEGIN lanes tokens (generated by libexec/tokens.py --kdl; do not edit by hand)
|
|
336
|
+
themes {
|
|
337
|
+
lanes-dark {
|
|
338
|
+
text_unselected { base "#edf1f5"; background "#101318"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
339
|
+
text_selected { base "#edf1f5"; background "#1a2721"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
340
|
+
ribbon_selected { base "#101318"; background "#b4e3bf"; emphasis_0 "#7a1a12"; emphasis_1 "#101318"; emphasis_2 "#101318"; emphasis_3 "#101318"; }
|
|
341
|
+
ribbon_unselected { base "#9ca7b5"; background "#191e25"; emphasis_0 "#f28b7d"; emphasis_1 "#edf1f5"; emphasis_2 "#e5b84a"; emphasis_3 "#7fb3f2"; }
|
|
342
|
+
table_title { base "#b4e3bf"; background "#101318"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
343
|
+
table_cell_selected { base "#edf1f5"; background "#1a2721"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
344
|
+
table_cell_unselected { base "#edf1f5"; background "#101318"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
345
|
+
list_selected { base "#edf1f5"; background "#1a2721"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
346
|
+
list_unselected { base "#edf1f5"; background "#101318"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
347
|
+
frame_selected { base "#b4e3bf"; background "#101318"; emphasis_0 "#e5b84a"; emphasis_1 "#6fd39a"; emphasis_2 "#7fb3f2"; emphasis_3 "#f28b7d"; }
|
|
348
|
+
frame_highlight { base "#e5b84a"; background "#101318"; emphasis_0 "#f28b7d"; emphasis_1 "#6fd39a"; emphasis_2 "#b4e3bf"; emphasis_3 "#7fb3f2"; }
|
|
349
|
+
exit_code_success { base "#6fd39a"; background "#101318"; emphasis_0 "#6fd39a"; emphasis_1 "#6fd39a"; emphasis_2 "#6fd39a"; emphasis_3 "#6fd39a"; }
|
|
350
|
+
exit_code_error { base "#f28b7d"; background "#101318"; emphasis_0 "#f28b7d"; emphasis_1 "#f28b7d"; emphasis_2 "#f28b7d"; emphasis_3 "#f28b7d"; }
|
|
351
|
+
multiplayer_user_colors { player_1 "#7fb3f2"; player_2 "#e5b84a"; player_3 "#6fd39a"; player_4 "#f28b7d"; player_5 "#b4e3bf"; player_6 "#c9a6ff"; player_7 "#6fd6d0"; player_8 "#f7cf7f"; player_9 "#8fe0a3"; player_10 "#ff9d96"; }
|
|
352
|
+
}
|
|
353
|
+
lanes-light {
|
|
354
|
+
text_unselected { base "#17241b"; background "#f3f5f2"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
355
|
+
text_selected { base "#17241b"; background "#e5f0e6"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
356
|
+
ribbon_selected { base "#ffffff"; background "#2f6b45"; emphasis_0 "#ffd3cc"; emphasis_1 "#ffffff"; emphasis_2 "#ffffff"; emphasis_3 "#ffffff"; }
|
|
357
|
+
ribbon_unselected { base "#56616d"; background "#ffffff"; emphasis_0 "#b7322a"; emphasis_1 "#17241b"; emphasis_2 "#8a5a00"; emphasis_3 "#2456a8"; }
|
|
358
|
+
table_title { base "#2f6b45"; background "#f3f5f2"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
359
|
+
table_cell_selected { base "#17241b"; background "#e5f0e6"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
360
|
+
table_cell_unselected { base "#17241b"; background "#f3f5f2"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
361
|
+
list_selected { base "#17241b"; background "#e5f0e6"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
362
|
+
list_unselected { base "#17241b"; background "#f3f5f2"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
363
|
+
frame_selected { base "#2f6b45"; background "#f3f5f2"; emphasis_0 "#8a5a00"; emphasis_1 "#1b7142"; emphasis_2 "#2456a8"; emphasis_3 "#b7322a"; }
|
|
364
|
+
frame_highlight { base "#8a5a00"; background "#f3f5f2"; emphasis_0 "#b7322a"; emphasis_1 "#1b7142"; emphasis_2 "#2f6b45"; emphasis_3 "#2456a8"; }
|
|
365
|
+
exit_code_success { base "#1b7142"; background "#f3f5f2"; emphasis_0 "#1b7142"; emphasis_1 "#1b7142"; emphasis_2 "#1b7142"; emphasis_3 "#1b7142"; }
|
|
366
|
+
exit_code_error { base "#b7322a"; background "#f3f5f2"; emphasis_0 "#b7322a"; emphasis_1 "#b7322a"; emphasis_2 "#b7322a"; emphasis_3 "#b7322a"; }
|
|
367
|
+
multiplayer_user_colors { player_1 "#2456a8"; player_2 "#8a5a00"; player_3 "#1b7142"; player_4 "#b7322a"; player_5 "#2f6b45"; player_6 "#7a3fb8"; player_7 "#0f7b7b"; player_8 "#8f5a00"; player_9 "#1b7a38"; player_10 "#c2332a"; }
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
theme_dark "lanes-dark"
|
|
371
|
+
theme_light "lanes-light"
|
|
334
372
|
web_client {
|
|
335
373
|
font "monospace"
|
|
374
|
+
theme {
|
|
375
|
+
background "#101318"
|
|
376
|
+
foreground "#edf1f5"
|
|
377
|
+
black "#7d8896"
|
|
378
|
+
red "#f28b7d"
|
|
379
|
+
green "#6fd39a"
|
|
380
|
+
yellow "#e5b84a"
|
|
381
|
+
blue "#7fb3f2"
|
|
382
|
+
magenta "#c9a6ff"
|
|
383
|
+
cyan "#6fd6d0"
|
|
384
|
+
white "#9ca7b5"
|
|
385
|
+
bright_black "#8a95a3"
|
|
386
|
+
bright_red "#ff9d96"
|
|
387
|
+
bright_green "#8fe0a3"
|
|
388
|
+
bright_yellow "#f7cf7f"
|
|
389
|
+
bright_blue "#a5cbff"
|
|
390
|
+
bright_magenta "#dcc6ff"
|
|
391
|
+
bright_cyan "#9ae6e0"
|
|
392
|
+
bright_white "#edf1f5"
|
|
393
|
+
selection_background "#1a2721"
|
|
394
|
+
selection_foreground "#edf1f5"
|
|
395
|
+
}
|
|
336
396
|
}
|
|
337
|
-
|
|
338
|
-
theme_dark "tokyo-night"
|
|
339
|
-
theme_light "catppuccin-latte"
|
|
397
|
+
// END lanes tokens
|
|
340
398
|
default_mode "normal"
|
|
341
399
|
mouse_mode true
|
|
342
400
|
copy_clipboard "system"
|
package/payload/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibelord/lanes",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"commit": "
|
|
5
|
-
"digest": "sha256:
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"commit": "7eefe03dd9362ca62d05abd2d23cbc958d6af346",
|
|
5
|
+
"digest": "sha256:09b4d87fb5687fe5e72140baa68f9518ec96cbf9a3b08c55d7f9e99afb55b295",
|
|
6
6
|
"executables": [
|
|
7
7
|
"bin/lanes",
|
|
8
8
|
"client/install.sh",
|
|
@@ -13,14 +13,17 @@
|
|
|
13
13
|
"container/lane",
|
|
14
14
|
"container/lane-run",
|
|
15
15
|
"holders/exec.sh",
|
|
16
|
+
"holders/ssh.sh",
|
|
16
17
|
"holders/tmux.sh",
|
|
17
18
|
"holders/zmx.sh",
|
|
18
19
|
"install.sh",
|
|
19
20
|
"install/enable-web.sh",
|
|
20
21
|
"install/host-install.sh",
|
|
22
|
+
"libexec/connection.py",
|
|
21
23
|
"libexec/sidebar",
|
|
22
24
|
"libexec/sidebar.py",
|
|
23
25
|
"libexec/statusd.py",
|
|
26
|
+
"libexec/tokens.py",
|
|
24
27
|
"libexec/view.sh",
|
|
25
28
|
"sudo/host-guard.sh",
|
|
26
29
|
"sudo/one-time-root.sh"
|