@vibelord/lanes 1.0.2 → 1.0.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.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/payload/lanes/VERSION +1 -1
  3. package/payload/lanes/bin/lanes +21 -8
  4. package/payload/lanes/container/env.sh +1 -1
  5. package/payload/lanes/container/lane +5 -5
  6. package/payload/lanes/container/lane-signal +4 -4
  7. package/payload/lanes/docs/ARCHITECTURE.md +14 -7
  8. package/payload/lanes/docs/DESIGN.md +3 -3
  9. package/payload/lanes/docs/INSTALL.md +37 -2
  10. package/payload/lanes/docs/RUNBOOK.md +52 -23
  11. package/payload/lanes/docs/SHARING.md +239 -4
  12. package/payload/lanes/holders.lock +10 -0
  13. package/payload/lanes/install/enable-studio-host.sh +14 -0
  14. package/payload/lanes/install/host-install.sh +5 -2
  15. package/payload/lanes/install/services.py +101 -4
  16. package/payload/lanes/install.sh +1 -1
  17. package/payload/lanes/libexec/agent_state.py +1 -1
  18. package/payload/lanes/libexec/cursor_sync.py +2 -2
  19. package/payload/lanes/libexec/economy_poll.py +3 -3
  20. package/payload/lanes/libexec/lanes_lib.py +1 -1
  21. package/payload/lanes/libexec/notify.py +3 -3
  22. package/payload/lanes/libexec/registrations.py +1 -1
  23. package/payload/lanes/libexec/session_actions.py +1 -1
  24. package/payload/lanes/libexec/sidebar.py +7 -7
  25. package/payload/lanes/libexec/statusd.py +25 -10
  26. package/payload/lanes/libexec/studio_host.py +1608 -0
  27. package/payload/lanes/systemd/lanes-economy.service +1 -1
  28. package/payload/lanes/systemd/lanes-studio-host-enrol.service +11 -0
  29. package/payload/lanes/systemd/lanes-studio-host-enrol.timer +10 -0
  30. package/payload/lanes/systemd/lanes-studio-host.service +37 -0
  31. package/payload/lanes/web/README.md +2 -2
  32. package/payload/lanes/zellij/config.kdl +1 -1
  33. package/payload/manifest.json +4 -3
@@ -5,7 +5,7 @@ After=lanes-statusd.service
5
5
  # No installer enables this unit. It reads the production daemon's control port, so switching it on is an operator
6
6
  # action: systemctl --user enable --now lanes-economy.service (RUNBOOK "Economy projection (opt-in)").
7
7
  # It runs on the HOST, not in the daemon's container: point LANES_THROTTLE_CONTAINER at that container for the log,
8
- # and use LANES_THROTTLE_CONTROL=none unless the control port is reachable from the host (RUNBOOK, DEF-1444).
8
+ # and use LANES_THROTTLE_CONTROL=none unless the control port is reachable from the host (RUNBOOK, DEF-1525).
9
9
  [Service]
10
10
  ExecStart=/usr/bin/python3 -S -E "@REPO@/libexec/economy_poll.py" --interval 10
11
11
  Restart=on-failure
@@ -0,0 +1,11 @@
1
+ [Unit]
2
+ Description=lanes: adopt a deploy receipt or registration key for the co-located Studio Host, then start it
3
+ Documentation=https://github.com/bwllaming/bw-tools/blob/main/lanes/docs/SHARING.md
4
+
5
+ [Service]
6
+ Type=oneshot
7
+ # Acts only on something NEW (an unadopted receipt, a key not tried in the last hour, a fresh enrolment the Host
8
+ # has not started with); otherwise one log line and exit 0. Never restarts a Host that refused the same enrolment.
9
+ ExecStart=/bin/sh "@REPO@/install/enable-studio-host.sh" --retry
10
+ Nice=5
11
+ Slice=lanes.slice
@@ -0,0 +1,10 @@
1
+ [Unit]
2
+ Description=lanes: retry the co-located Studio Host's enrolment every 5 minutes (opt-in, enabled by enable-studio-host.sh)
3
+
4
+ [Timer]
5
+ OnActiveSec=1min
6
+ OnUnitActiveSec=5min
7
+ AccuracySec=30s
8
+
9
+ [Install]
10
+ WantedBy=timers.target
@@ -0,0 +1,37 @@
1
+ [Unit]
2
+ Description=lanes: Throttle Studio Host co-located on this lanes server (opt-in: install/enable-studio-host.sh)
3
+ Documentation=https://github.com/bwllaming/bw-tools/blob/main/lanes/docs/SHARING.md
4
+ # The Host reads the harness's status.json; it starts after the observer and asks for it, but does not die with it.
5
+ After=lanes-statusd.service
6
+ Wants=lanes-statusd.service
7
+
8
+ [Service]
9
+ Type=simple
10
+ # The binary is the installer-selected, sha256-verified link (`lanes studio-host install`, holders.lock).
11
+ # The config the installer wrote, in lanes-server mode (design §8.10 C2): %h/.config/…, or under $XDG_CONFIG_HOME
12
+ # when the installing account set one. services.py ALWAYS pins XDG_CONFIG_HOME/XDG_DATA_HOME above (the installer's,
13
+ # else %h/.config and %h/.local/share), so the user manager's own environment never moves the credential.
14
+ ExecStart="@THROTTLE_RC@" studio host --config "@STUDIO_HOST_CONFIG@"
15
+ Restart=on-failure
16
+ # 2 s growing to 60 s, as `throttle-rc studio service` renders it. RestartSteps=/RestartMaxDelaySec= need
17
+ # systemd 254; an older manager ignores them with a warning, keeps RestartSec=2, and its start limit stops a loop.
18
+ RestartSec=2
19
+ RestartSteps=5
20
+ RestartMaxDelaySec=60
21
+ # Exit 3 is the Host's TYPED refusal (not enrolled yet, revoked, another Host holds the lock). Restarting into it
22
+ # fixes nothing, so it is a clean stop. Waiting for enrolment is exactly this state: lanes-studio-host-enrol.timer
23
+ # starts the unit again once a deploy receipt or a registration key has enrolled the machine.
24
+ SuccessExitStatus=3
25
+ # The Host's graceful stop (detach every channel, then `stopped`) runs on SIGINT.
26
+ KillSignal=SIGINT
27
+ # The Host only, never the cgroup: tmux clients it attached stay with their lanes; it reaps its own on a clean stop.
28
+ KillMode=process
29
+ TimeoutStopSec=20
30
+ # Deliberately no NoNewPrivileges= (design §8.9): it is inherited for life by anything the Host's children start.
31
+ Nice=5
32
+ MemoryHigh=512M
33
+ MemoryMax=1G
34
+ Slice=lanes.slice
35
+
36
+ [Install]
37
+ WantedBy=default.target
@@ -60,7 +60,7 @@ The lane filter bar sends `Esc /` and the query as UTF-8 (`TextEncoder`), droppi
60
60
  Attention counts come from the picker sidebar's pane title (`WS · ◆1 ◇2 ▸6`, written by the sidebar as OSC 2):
61
61
  `parseCounts` (also `window.__lanesParseCounts`) feeds the picker subtitle, `document.title`, the Lanes button's
62
62
  `data-count` and the workspace cards, inside the existing `refresh()` / `renderCards()` — no fetch, file or timer.
63
- Until plan Task 26 (2026-10-04) this reader was inert (DEF-1450): `bin/lanes` `mobile_workspace_tab` gave the
63
+ Until plan Task 26 (2026-10-04) this reader was inert (DEF-1531): `bin/lanes` `mobile_workspace_tab` gave the
64
64
  picker pane a fixed `name="Lanes"`, and Zellij reports a pane's layout name instead of its OSC 2 title, so
65
65
  `pickerTitle()` read `Lanes`, `parseCounts` returned null and the shell showed no counts ("Choose a lane to continue").
66
66
  Task 26 dropped that `name=` (pinned by `tests/unit/test_layout.py`) for sessions laid out since: an existing
@@ -90,7 +90,7 @@ re-opens this contract: re-read `startWsControl` and `installSoftKeyboardCapture
90
90
  explanations live here rather than in the shipped files. MEASURED 2026-10-04 with `wc -c` after LNS-31 (plan Task
91
91
  31) met Tasks 13/28: `mobile.js` 21 964 B (23 268 B before its comments moved to Code notes below) and `mobile.css`
92
92
  18 945 B. A laptop or tablet also fetches `browser.js` (3 641 B) and `browser.css` (1 947 B); `test_web_view` pins
93
- that download at `LAPTOP_TABLET_JS_RATCHET` and `LAPTOP_TABLET_CSS_CAP` (DEF-1488).
93
+ that download at `LAPTOP_TABLET_JS_RATCHET` and `LAPTOP_TABLET_CSS_CAP` (DEF-1569).
94
94
 
95
95
  ## Code notes
96
96
 
@@ -212,7 +212,7 @@ keybinds clear-defaults=true {
212
212
  }
213
213
  }
214
214
  // Markdown preview (spec §5.4): the newest markdown file the focused lane named, in a floating pane that closes
215
- // when the pager quits. Both Run forms parse on Zellij 0.45.1 (measured 2026-10-04, DEF-1453); the multi-line
215
+ // when the pager quits. Both Run forms parse on Zellij 0.45.1 (measured 2026-10-04, DEF-1534); the multi-line
216
216
  // children are the pinned style, and test_ctrl_alt_m_is_the_multi_line_floating_run_block pins them. "lanes"
217
217
  // is found on the view server's PATH
218
218
  // (bin/lanes clean_env: this checkout's bin/), because this file is read in place, never rendered per host.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@vibelord/lanes",
3
- "version": "1.0.2",
4
- "commit": "a8c1fcdf78e24125b9d4c0b32618a16448445acc",
5
- "digest": "sha256:162bffbf04a2c3a478fe1fce82b9953e609b5450edd106bba28e265df9ba464a",
3
+ "version": "1.0.3",
4
+ "commit": "77ee54d454b851134f0aed88534762c8b457b34c",
5
+ "digest": "sha256:9d8f4e272d733e6405d471bdab9d950615670f41e181c56c96297fe5ed451ced",
6
6
  "executables": [
7
7
  "bin/lanes",
8
8
  "client/install.sh",
@@ -18,6 +18,7 @@
18
18
  "holders/tmux.sh",
19
19
  "holders/zmx.sh",
20
20
  "install.sh",
21
+ "install/enable-studio-host.sh",
21
22
  "install/enable-web.sh",
22
23
  "install/host-install.sh",
23
24
  "libexec/connection.py",