跳到內容

0.61.1

本頁內容尚未翻譯。

The comms log no longer pulls a reader back to the end (todo #123)

Section titled “The comms log no longer pulls a reader back to the end (todo #123)”

With the comms log following new output, a small scroll up was undone by the next entry, and a wheel or trackpad fling that started at the end could be pulled back in the middle of its own motion: the log counted a reader as “at the end” until they were more than 80 px away (the end sentinel’s margin), and only a finger on the log (touch) held it. A flick of the wheel, the first pixels of any scroll up, and the arrow keys all raced the next entry.

  • A user’s move up (a scroll event the log did not make itself) leaves the end at once: the log stops following, the “N new” button appears, and entries that arrive do not move the reader. Scrolling back to the very end follows again, as does crossing back into the sentinel’s margin.

  • A wheel up, an Up, Page Up, or Home key, a finger, and the fling after them hold the log until 250 ms pass with no input and no scroll; one that never left the end then lands there in one jump. A wheel down at the end holds nothing: an entry lands at once, so the tail of the fling has no new room to glide into.

  • A log that shrinks under its end (an entry takes its real height) clamps the browser’s scroll offset to the end, which is not a move up; the resize observer resyncs the log’s own record of its offset even while a finger holds it.

  • The log’s momentum stays in the log (the report that the log at its end “keeps sliding and bobbing”): .chat-scroll now has overscroll-behavior: contain in every view, not only on a phone and in Zen. The Standard and Geek page is taller than the window by design (the footer follows the log’s panel: 996 px in 800 at 1280 wide), so a trackpad’s momentum tail at the log’s end used to chain to the page and slide it toward the footer, bouncing at the page’s end. In real Chrome at 1280×800, 1512×900, and Geek 1512×900, a tapering wheel fling at the log’s end moved the page by 196, 187, and 183 px before and by 0 now.

  • A scroll up of a few pixels in a quiet log stays where the reader left it. Once the log had been still for 600 ms the end sentinel was reconnected, and its first notice (“inside the margin”) re-pinned the log, which jumped back to the end 250 ms later. The sentinel now acts only when it crosses the margin; a return to the very end still follows, in steps of any size (it needed more than half a pixel before). Shift+Space (page up) holds the log like Page Up.

  • A reader a little above the end whose log shrinks under them (the live line clears, an entry takes its real height), so that the browser puts the log at its very end, follows again instead of staying at the end with the “N new” button.

Traces from a real Chrome (a wheel scroll up of 50 px with entries arriving every 300 ms: the log was back at the end a second later before, and stays 50 px above it after; the up, down, and tail flings and the touch flings are unchanged on a desktop width, a phone width, and Geek) are kept with the review notes of this change. Headless Chrome cannot make a trackpad’s momentum phase, so the wheel traces use decaying deltas as the stand-in; tests/chat-scroll.test.ts drives the real mount of the log with the same sequences.

The head’s broadcast cards read as what they are (todo #124, spec)

Section titled “The head’s broadcast cards read as what they are (todo #124, spec)”
  • A card’s parts are labelled. What the boss said (his own words from the event the relay names), what the head sent, to whom, and when with how many handled it are separate lines; the whole texts are one tap away. A card from before this release has no “You said” part and shows the head’s first line.
  • A tower that acted is no longer “waiting” for ever. The server records when a tower’s run took the head’s message (已收到) and when it sent anything in the turn that message started (已處理, with the note that it answered someone else, not the head). An order it hands to a main counts too. A tower_reply to the head does not count: it is refused at the tool and records nothing. The card’s count reads 已處理 k/N / “k/N handled” (an answer is a handling); 等回覆 now means the tower has not taken the message.
  • A correction replaces the order it names. The head’s tower_send takes an optional supersedes (an earlier ask id); the page folds the replaced broadcasts under the newest one, struck, with 更正了前 2 則 / 已被下一則更正 (the ids are only in a tooltip). A name that is not an earlier ask is refused before any tower is opened for it. The head is told to set it by its tool description, brief, and prompt.
  • The head’s line leaves out the boss’s copy cleanly. When the head quotes the boss word for word, the copy goes from the card’s line with its quotation marks and the full stop after them (no 「…」).
  • A bounded snapshot. A tower’s copy of a message equal to the first tower’s is sent once, and whole texts go for the newest broadcasts up to 24,000 units; older cards show the first line. Worst case for the asks of one snapshot: 190,659 bytes.
  • A reply to the head is not shown as an answer. The head’s gate takes only a tower_send naming its ask, so tower_reply to the head is now refused at the tool, before anything is sent, with the sentence on how to answer (tower_send {head: true, inReplyTo}); the card no longer says 已回覆 for a reply the head never got. The card of such a tower stays at 已收到 until it sends tower_send {head: true, inReplyTo}. 回覆沒送到主塔台 / “its reply did not reach the head” shows only for the rare reply that got through the tool without being known as one to the head. The tower prompt and the tower_reply description say the same.

asks.json asks gain sent, boss, supersedes, read, acted, and missed (a field of the wrong type is ignored on read); older files read unchanged.

The notice for messages that wait says what waits, for whom, and until when (todo #122)

Section titled “The notice for messages that wait says what waits, for whom, and until when (todo #122)”

The Link button’s notice for Straw Link messages that had not reached a tower read “Team X’s inbox has 4 messages waiting: no tower is open on the project”. It used a word the boss never meets (inbox), stated one cause as fact, and named no sender, age, workspace or deadline. It now reads, for example:

  • English: “Team moldplan: box n2knna sent 4 messages, the oldest 3h ago, for the tower of workspace “MP Center”. They are not delivered yet; they go through as soon as the tower can take them, and the oldest is dropped on 11/13.”

  • 繁體中文: 「團隊 moldplan:box n2knna 傳來 4 則訊息,3 小時前起就在等,要交給「MP Center」工作區的塔台,還沒送達。塔台能接手時就會自動送達;11/13 起會開始丟棄。」(one sentence serves one message and many, as zh-TW has no singular; 「3 分鐘前」 replaces 「3 分前」 everywhere an age shows)

  • Who, how many, since when. The sender of the oldest message (several senders: that one and “and 2 more”), the count, and the age of the oldest in whole minutes, hours or days, so the notice changes only when its words do.

  • For which tower. The label of the workspace the sender asked for when it is a workspace of this computer, else the project’s folder name. A workspace id that is no longer open is never shown. Messages that wait for different towers are separate notices.

  • Until when. The date the oldest message is dropped: its arrival plus the store’s 7 days (INBOX_MAX_AGE_MS).

  • No word about a tower being open or closed. To the boss a workspace’s tower always exists; the copy says only that the message is not delivered yet. The pi notice of the same event (Straw Link: a message from … is not delivered yet; it waits for the tower of …) follows.

  • The notice that a message waited for an ally run (more than 10 minutes) no longer says “inbox” either; the “waiting for an idle tower” notice already had no such word.

The notice has no button: the “Show towers” route would not make a tower take the message.

Data: the inbox alert’s data is now {count, from, others, since, drop, ageMin, workspace?, project} (was {count}), and its id is inbox/<team>/<id of the workspace asked for>/<state>: a name that is no workspace here is not in it, so ghost names make one notice.

An attended computer wakes the tower of a workspace it already has (todo #122, the boss’s ruling of 2026-11-07)

Section titled “An attended computer wakes the tower of a workspace it already has (todo #122, the boss’s ruling of 2026-11-07)”

To the boss a workspace’s tower always exists, so a teammate’s message no longer waits with a notice just because the tower of an existing workspace had not been started. Before, only an unattended computer did anything about it, and only for a dispatch sender.

  • Who and what. A message from a teammate at reply or higher (a member with no link.trust entry is at reply, so every member qualifies; a sender who left the roster is dropped before this) makes the server give the tower to a workspace this computer already has: one with a pane inside the project, or the workspace the sender named (id, else label). It never makes a workspace or a base for it, moves no focus and types into no other pane. The one thing it may make is the tower’s tab in that existing workspace, when the workspace has none (the boss confirmed this: a wake may add the tower tab). With no such workspace it makes nothing. A workspace name the sender wrote that is no workspace of this computer (or is the head or a sub workspace) costs no wake.
  • No storm. One wake runs at a time per project and workspace asked for (by its id, so no made-up name adds one), a sender has at most 3 in flight, and the next try waits a minute after the last ended, then two, four, and so on: up to 30 minutes when it worked or found no workspace, 10 when it failed. A none is tried again at once when a workspace with a pane inside the project appears. With towerRuns switched off nothing is woken. A message that arrives while one runs adds nothing.
  • The link log gets tower-wake and then tower-woke, tower-wake-none (no workspace) or tower-wake-failed (with the error) when the state changes, not at each try. It has no message text.
  • The notice appears only when the wake did not work. While a wake runs, and for two minutes after the first that worked, there is neither a Link button notice nor a pi notice. After that:
    • No such workspace: “…This computer has no workspace for it to wake the tower of. Open the project’s workspace and the messages go through.” (「這台電腦上沒有可以叫醒塔台的工作區。開啟專案的工作區,訊息就會送達。」)
    • Tower runs are switched off: “…Tower runs are switched off on this computer, so nothing can wake the tower. Switch them on and the messages go through.” (「這台電腦停用了塔台執行功能,所以沒有東西能叫醒塔台。啟用後訊息就會送達。」)
    • The wake failed: “…Waking the tower did not work (); it is tried again later.” (「叫醒塔台沒有成功(<原因>);稍後會再試。」). The reason is one of three plain sentences (the tower service is still starting; the project folder is missing or not allowed here; something went wrong, link.log has the details), never the server’s own English.
    • The wake worked but the tower has not taken the message in two minutes: the plain copy above, on the page and in pi.
  • Unattended computers are unchanged: only a dispatch sender opens a tower, and it may make a workspace. A failed wake of an attended computer is not told to the sender.

Data: the inbox alert’s data gains wake ("none", "off" or "failed") and, for a failed wake, reason ("service", "project" or "other"). The holder’s openTower seam takes a fourth argument, "open" or "wake", and answers "no-workspace" for a wake that found no workspace.