From 0c241ab7aa30eedb867d7f3c8bb7386f179fac5d Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Sun, 1 Nov 2026 08:03:44 +0800 Subject: [PATCH] Release v0.2.19 Changelog fragments consumed (29): - changelog.d/1886-memory-code-points.fixed.md - changelog.d/1887-memory-counter.fixed.md - changelog.d/1890-generate-canonical-gate.fixed.md - changelog.d/1892-pool-no-dossier.changed.md - changelog.d/1895-host-limits-code-points.fixed.md - changelog.d/1896-waited-label-seconds.fixed.md - changelog.d/1899-experience-text-code-points.fixed.md - changelog.d/1900-team-dossier-off-the-poll.fixed.md - changelog.d/1901-task-text-code-points.fixed.md - changelog.d/1906-own-chat-left-out.fixed.md - changelog.d/1907-host-cut-code-points.fixed.md - changelog.d/1910-team-read-retry.fixed.md - changelog.d/1912-archive-cut-boundary.fixed.md - changelog.d/1913-dossier-refresh-on-open.fixed.md - changelog.d/1916-code-unit-cuts.fixed.md - changelog.d/1918-clip-reason-optional.fixed.md - changelog.d/1919-stack-summary-cut.fixed.md - changelog.d/1923-published-name-cut.fixed.md - changelog.d/1928-room-share-history-cut.fixed.md - changelog.d/1930-host-line-bounds.fixed.md - changelog.d/1932-join-notice-fit.fixed.md - changelog.d/1933-room-share-stranger-text-bound.fixed.md - changelog.d/1937-peer-name-well-formed.fixed.md - changelog.d/1939-notice-push.fixed.md - changelog.d/1940-peer-display-name-well-formed.fixed.md - changelog.d/1943-inbound-line-text-wf.fixed.md - changelog.d/1945-group-text-code-point-bound.fixed.md - changelog.d/1946-empty-notice-join.fixed.md - changelog.d/1950-seat-line-text-wf.fixed.md --- CHANGELOG.md | 40 +++++++++++++++++++ changelog.d/1886-memory-code-points.fixed.md | 1 - changelog.d/1887-memory-counter.fixed.md | 1 - .../1890-generate-canonical-gate.fixed.md | 1 - changelog.d/1892-pool-no-dossier.changed.md | 1 - .../1895-host-limits-code-points.fixed.md | 1 - .../1896-waited-label-seconds.fixed.md | 1 - .../1899-experience-text-code-points.fixed.md | 1 - .../1900-team-dossier-off-the-poll.fixed.md | 1 - .../1901-task-text-code-points.fixed.md | 1 - changelog.d/1906-own-chat-left-out.fixed.md | 1 - .../1907-host-cut-code-points.fixed.md | 1 - changelog.d/1910-team-read-retry.fixed.md | 1 - .../1912-archive-cut-boundary.fixed.md | 1 - .../1913-dossier-refresh-on-open.fixed.md | 4 -- changelog.d/1916-code-unit-cuts.fixed.md | 1 - .../1918-clip-reason-optional.fixed.md | 1 - changelog.d/1919-stack-summary-cut.fixed.md | 1 - changelog.d/1923-published-name-cut.fixed.md | 1 - .../1928-room-share-history-cut.fixed.md | 1 - changelog.d/1930-host-line-bounds.fixed.md | 1 - changelog.d/1932-join-notice-fit.fixed.md | 1 - ...33-room-share-stranger-text-bound.fixed.md | 1 - .../1937-peer-name-well-formed.fixed.md | 1 - changelog.d/1939-notice-push.fixed.md | 1 - ...940-peer-display-name-well-formed.fixed.md | 1 - .../1943-inbound-line-text-wf.fixed.md | 1 - .../1945-group-text-code-point-bound.fixed.md | 1 - changelog.d/1946-empty-notice-join.fixed.md | 1 - changelog.d/1950-seat-line-text-wf.fixed.md | 1 - core/package-lock.json | 4 +- core/package.json | 2 +- patches/ds-bot/0007-version-and-tooling.patch | 6 +-- 33 files changed, 46 insertions(+), 38 deletions(-) delete mode 100644 changelog.d/1886-memory-code-points.fixed.md delete mode 100644 changelog.d/1887-memory-counter.fixed.md delete mode 100644 changelog.d/1890-generate-canonical-gate.fixed.md delete mode 100644 changelog.d/1892-pool-no-dossier.changed.md delete mode 100644 changelog.d/1895-host-limits-code-points.fixed.md delete mode 100644 changelog.d/1896-waited-label-seconds.fixed.md delete mode 100644 changelog.d/1899-experience-text-code-points.fixed.md delete mode 100644 changelog.d/1900-team-dossier-off-the-poll.fixed.md delete mode 100644 changelog.d/1901-task-text-code-points.fixed.md delete mode 100644 changelog.d/1906-own-chat-left-out.fixed.md delete mode 100644 changelog.d/1907-host-cut-code-points.fixed.md delete mode 100644 changelog.d/1910-team-read-retry.fixed.md delete mode 100644 changelog.d/1912-archive-cut-boundary.fixed.md delete mode 100644 changelog.d/1913-dossier-refresh-on-open.fixed.md delete mode 100644 changelog.d/1916-code-unit-cuts.fixed.md delete mode 100644 changelog.d/1918-clip-reason-optional.fixed.md delete mode 100644 changelog.d/1919-stack-summary-cut.fixed.md delete mode 100644 changelog.d/1923-published-name-cut.fixed.md delete mode 100644 changelog.d/1928-room-share-history-cut.fixed.md delete mode 100644 changelog.d/1930-host-line-bounds.fixed.md delete mode 100644 changelog.d/1932-join-notice-fit.fixed.md delete mode 100644 changelog.d/1933-room-share-stranger-text-bound.fixed.md delete mode 100644 changelog.d/1937-peer-name-well-formed.fixed.md delete mode 100644 changelog.d/1939-notice-push.fixed.md delete mode 100644 changelog.d/1940-peer-display-name-well-formed.fixed.md delete mode 100644 changelog.d/1943-inbound-line-text-wf.fixed.md delete mode 100644 changelog.d/1945-group-text-code-point-bound.fixed.md delete mode 100644 changelog.d/1946-empty-notice-join.fixed.md delete mode 100644 changelog.d/1950-seat-line-text-wf.fixed.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5984923..7e945be69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,46 @@ New entries are written as one fragment file per change in [changelog.d/](change ## [Unreleased] +## [0.2.19] - 2026-11-01 + +### Changed + +- Project board: a role-pool entry in the team block reads `@id` beside its rank instead of a Dossier control — `project-team` answers rows keyed by the Project's own Bots, so the old pool click opened a dossier the host never sent; the Chief and my-agent rows keep theirs ([#1892](https://github.com/ThinkFlowLab/FlyBot/issues/1892)). + +### Fixed + +- The Project memory box now counts its 600-character bound in characters rather than UTF-16 units, so a note of 600 emoji — 1,200 units — is saved instead of refused as *A Project memory entry is at most 600 characters*, and 601 characters is still refused in both writers ([#1886](https://github.com/ThinkFlowLab/FlyBot/issues/1886)). +- The Project settings memory box warns about its bound before the click: a `N/600` counter under the field counts code points like the host, a 601st code point turns the counter and the Save button into their over-limit state, and an empty or whitespace-only box disables Save, so neither state calls `project-memory-write` or writes anything ([#1887](https://github.com/ThinkFlowLab/FlyBot/issues/1887)). +- CI now runs `node scripts/ds-bot-patches.mjs canonical`, which fails when `generate` would rewrite `patches/ds-bot/`: `check` proves the committed series applies and reproduces `core/`, not that it is the split the generator writes, so a drifted series landed green between #1883 and #1889. `npm run verify` runs the same gate. ([#1890](https://github.com/ThinkFlowLab/FlyBot/issues/1890)) +- Host character limits count code points, so a character outside the BMP costs one instead of two ([#1895](https://github.com/ThinkFlowLab/FlyBot/issues/1895)): a memory entry at 300, a `MEMORY.md` at 4,000 and its size note, a scheduled task's name at 120, a Bot-to-Bot message at 20,000, and the Project memory entry at 600 in both writers now measure what a reader counts, and a refusal prints that code-point number. +- The Project board's wait label now carries seconds under a minute, so a card that waited 40 seconds reads `40s` instead of `0m`; the three duration metrics (PR merge time, issue close time, task completion) use the same label, and a span over zero never floors to `0s`. Unknown and negative spans still render nothing. ([#1896](https://github.com/ThinkFlowLab/FlyBot/issues/1896)) +- An incident entry's `trigger`, `wrong` and `right` are bounded at 600 characters counted as code points, not UTF-16 units ([#1899](https://github.com/ThinkFlowLab/FlyBot/issues/1899)): 300 emoji no longer fill the 600 budget, a 600-character emoji entry is stored rather than refused as 1,200 units, and an entry already on disk that is over 600 UTF-16 units but within 600 characters loads again through the same check on the read path. +- Project board: the five-second refresh no longer re-reads the team dossier — `project-team` is read once when the board opens and handed back to each poll, so an open board stops re-reading persona and memory files (about 192 KB a minute) for an answer only an edit changes; a dossier that fails to read now leaves the rows, the done group and the tasks on screen with an empty team block instead of showing "No Project yet" ([#1900](https://github.com/ThinkFlowLab/FlyBot/issues/1900)). +- The task board's typed question and answer (2,000) and its handoff, evidence and lease bounds (300, 200, 200) now count characters rather than UTF-16 units ([#1901](https://github.com/ThinkFlowLab/FlyBot/issues/1901)), so a 2,000-character emoji question is accepted instead of refused as 4,000. +- `read_own_chat` now says what a cap left out instead of reading as the whole chat: a search that fills its 20 hits ends with `N more not shown; search with narrower words, or read around one of these anchors.`, and a bare read of a part with more than 12 messages is headed `newest 12 of 15, oldest first`. The caps stay; exactly at the cap nothing is added. ([#1906](https://github.com/ThinkFlowLab/FlyBot/issues/1906)) +- A clipped or excerpted line no longer ends on half of an emoji ([#1907](https://github.com/ThinkFlowLab/FlyBot/issues/1907)): the host cuts `read_own_chat`, checkpoint and handoff lines, the memory review input and the error sentences on a code point boundary, so what a client receives is the whole character instead of a replacement character. +- Project board: a refused `project-team` read at open is no answer yet, not an empty team — the next five-second poll asks again, the block fills when the answer lands, and it stays frozen for the rest of the open; before this the refusal was normalised to `{ rows: [] }` and served by every later poll ([#1910](https://github.com/ThinkFlowLab/FlyBot/issues/1910)). +- A decision or a meeting archive no longer stores half of an emoji ([#1912](https://github.com/ThinkFlowLab/FlyBot/issues/1912)): the host's one `cut` helper stops a bounded prefix before the surrogate pair it would split, and every archive writer now uses it instead of `slice(0, max)` — `decisions.jsonl`, `decisions/-.md`, and the claim line, diagnostics report, activity-feed label and browser text beside them — so the stored record round-trips through UTF-8 as the whole character instead of U+FFFD. +- The Project board's Dossier panel now re-reads the team dossier when it opens, so a memory head written + after the board opened is one click away instead of stale until the board is closed and reopened. A + refused refresh keeps the rows the panel already had, and the five-second poll still does not read the + dossier. +- Eight more places stopped storing or showing half of an emoji ([#1916](https://github.com/ThinkFlowLab/FlyBot/issues/1916)): the claim cue's fallback reference, the task lead's name in a member's prompt, a failed group Session's error text, `read_own_chat`'s query and anchor, an open page's address and title, a diagnostics browser-log line, and a friend's Bot name now cut on a code point boundary. The rule itself moved to `core/src/shared/text-boundary.js`, so the shared label code and the host's `cut` use one implementation instead of two. +- The memory review now keeps whole characters in what it shows the model and writes to the log ([#1918](https://github.com/ThinkFlowLab/FlyBot/issues/1918)): the two bounds in `core/src/host/memory.js` — the 800-unit context line and the 3,000-unit two-ended user line — go through the shared boundary rule, so a cut that lands inside an emoji steps back instead of leaving half a pair, and the tail it keeps is never longer than the budget it had. The exported `clip` in `core/src/host/text.js` also makes its reason optional: a two-argument call now reads `… (cut)` instead of the literal `… (cut; undefined)`, while a call that passes a reason keeps `… (cut; )` byte for byte. +- The diagnostics report's stack summary stopped showing half of an emoji ([#1919](https://github.com/ThinkFlowLab/FlyBot/issues/1919)): the `
Stack: …` line now cuts the message on a code point boundary, so the character the 80-unit bound would split is left out of the summary entirely and the line shows a whole-character prefix instead of ending in U+FFFD. +- A friend's Bot name no longer shows half of an emoji ([#1923](https://github.com/ThinkFlowLab/FlyBot/issues/1923)): the published name stored from the roster, the group member line, the room label `othersInRoom` returns and the envelope's name, handle, ownerName and roster fields now cut on a code point boundary, so such a value that straddles its 60 (or 40) cap keeps the whole character instead of U+FFFD. The envelope's message body and its fitTransport shrink loop are untouched. +- A room-share envelope keeps whole characters in the text it copies to another owner's FlyBot ([#1928](https://github.com/ThinkFlowLab/FlyBot/issues/1928)): the history line a join copies (bounded at 2,000 units on both the host that builds the envelope and the guest that copies it) and a line fitted to Bot Social's 4,000-character transport limit now stop before a character that straddles their bound instead of leaving half of it, so a guest no longer reads U+FFFD where the sender typed an emoji — a family emoji fitted to the transport reproduces the old break. The 18,000-unit bound on a line envelope's body goes through the same rule for consistency; it is not reachable on its own because the transport fit already shortens the body to 4,000. +- The host's own bounded lines no longer end in half of an emoji ([#1930](https://github.com/ThinkFlowLab/FlyBot/issues/1930)): the busy acknowledgment's 600-unit task text and 1,500-unit message text, `cleanName`'s 60-unit peer name (the one that lands in `fenceUntrusted`'s `from="…"` attribute), the `list_bots` group line's 100-unit notice and 120-unit job line, the group answer echo at 300 and a rework card's note at 200 now cut on a code point boundary, so a value whose cap falls inside a surrogate pair keeps the whole character instead of U+FFFD. Every cap is unchanged. +- A join to a shared room keeps the group notice even when the room's Bot roster has to shrink to fit ([#1932](https://github.com/ThinkFlowLab/FlyBot/issues/1932)): the roster used to be trimmed after the notice, and the notice was cut by the whole envelope's overflow, so a room with enough Bots emptied it and a guest never heard an edited or cleared notice — an explicit clear (an empty notice) was dropped along with it. The roster now gives its rows first, the notice is cut only by what is left over once the roster cannot give more, and a present empty notice arrives as the clear it is. No limit changes: a join still fits Bot Social's 4,000-character transport. +- A joined room's notice and the pane line copied from another owner's FlyBot keep whole characters ([#1933](https://github.com/ThinkFlowLab/FlyBot/issues/1933); [#1928](https://github.com/ThinkFlowLab/FlyBot/issues/1928) covered the envelopes, and these are the two host-side readers it left on a raw code-unit cut): the guest bounds the notice it stores at its own 2,000 units and the history line it draws at the same 2,000-unit bound it already stores, both by backing up to a code point boundary, so a text whose 2,000th unit is half of a surrogate pair no longer leaves that half in the notice or in the pane — it reads as U+FFFD no more. The pane used to be shown the sender's raw `entry.text`, longer than the line the guest's own log kept; it now draws exactly the bounded prefix the log holds. +- A peer name that arrives with half of a surrogate pair — a string JSON accepts but is not well formed — is now made well formed before it is cleaned, so the message header a person reads (`[Message from …]`), the `from="…"` attribute of an untrusted-message fence and the recorded `senderName` carry the replacement character instead of a lone half that would not survive a UTF-8 round trip. The same repair now happens when a shared room's envelope is parsed: the notice, a roster entry's name and owner name and a copied chat line are handed on well formed, so the room's standing prompt and the guest's copy of a line no longer carry a broken character. The 60-character name bound, the notice's 2,000-character bound and their code point boundaries are unchanged ([#1937](https://github.com/ThinkFlowLab/FlyBot/issues/1937)). +- The notice the host edits in a group's settings now reaches the friends' Bots already in the room ([#1939](https://github.com/ThinkFlowLab/FlyBot/issues/1939)): editing or clearing it pushes one room-share `join` with the same roster and only the notice changed, and a settings save that leaves the notice alone sends nothing. +- A peer's display name is now made well formed before it is cleaned: when a roster name, an owner or lead label, an inviter name or a face seat arrives with half of a surrogate pair — a string JSON accepts but that is not well formed — the label carries the replacement character instead of a lone half that shows as an empty box and does not survive a UTF-8 round trip. The 60-character name bound and its code-point boundaries are unchanged, so a name that is already well formed comes back exactly as it was ([#1940](https://github.com/ThinkFlowLab/FlyBot/issues/1940)). +- A line that arrives from another home with half of a surrogate pair in its body now has the body made well formed before it is used: the stored room line, the line the pane draws and the text handed to the Bot that was called all carry the replacement character instead of a lone half that would not survive a UTF-8 round trip. The line is still accepted and still calls that Bot — a broken character never silences a peer's message — and a body that is already well formed, including one with a real emoji, is passed through exactly as it arrived ([#1943](https://github.com/ThinkFlowLab/FlyBot/issues/1943)). +- A group's notice and name are now cut on a code point instead of a UTF-16 unit ([#1945](https://github.com/ThinkFlowLab/FlyBot/issues/1945)): a 2000-unit notice or a 60-unit name that ended in a whole emoji used to store a lone surrogate, which every encoder downstream turned into U+FFFD; the bound now drops the straddling character whole, the way every other cut in the host already did. +- A room whose roster had to shrink to fit one share envelope no longer drops the host's cleared notice ([#1946](https://github.com/ThinkFlowLab/FlyBot/issues/1946)): the roster now gives while the envelope overflows with the notice field in place, so an explicit empty notice — the host clearing it — reaches the guest as empty instead of disappearing and reading as "change nothing". +- A line that a remote seat writes into a room of this home is now made well formed before it is used: the stored room line, the line the pane draws and the text handed to the Bot the line calls all carry the replacement character instead of half of a surrogate pair that would not survive a UTF-8 round trip. The line is still accepted and still calls that Bot, and a body that is already well formed — a real emoji included — is passed through exactly as it arrived ([#1950](https://github.com/ThinkFlowLab/FlyBot/issues/1950)). + ## [0.2.18] - 2026-10-31 ### Added diff --git a/changelog.d/1886-memory-code-points.fixed.md b/changelog.d/1886-memory-code-points.fixed.md deleted file mode 100644 index 49843305e..000000000 --- a/changelog.d/1886-memory-code-points.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The Project memory box now counts its 600-character bound in characters rather than UTF-16 units, so a note of 600 emoji — 1,200 units — is saved instead of refused as *A Project memory entry is at most 600 characters*, and 601 characters is still refused in both writers ([#1886](https://github.com/ThinkFlowLab/FlyBot/issues/1886)). diff --git a/changelog.d/1887-memory-counter.fixed.md b/changelog.d/1887-memory-counter.fixed.md deleted file mode 100644 index 67c27c137..000000000 --- a/changelog.d/1887-memory-counter.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The Project settings memory box warns about its bound before the click: a `N/600` counter under the field counts code points like the host, a 601st code point turns the counter and the Save button into their over-limit state, and an empty or whitespace-only box disables Save, so neither state calls `project-memory-write` or writes anything ([#1887](https://github.com/ThinkFlowLab/FlyBot/issues/1887)). diff --git a/changelog.d/1890-generate-canonical-gate.fixed.md b/changelog.d/1890-generate-canonical-gate.fixed.md deleted file mode 100644 index d81c49c0a..000000000 --- a/changelog.d/1890-generate-canonical-gate.fixed.md +++ /dev/null @@ -1 +0,0 @@ -CI now runs `node scripts/ds-bot-patches.mjs canonical`, which fails when `generate` would rewrite `patches/ds-bot/`: `check` proves the committed series applies and reproduces `core/`, not that it is the split the generator writes, so a drifted series landed green between #1883 and #1889. `npm run verify` runs the same gate. ([#1890](https://github.com/ThinkFlowLab/FlyBot/issues/1890)) diff --git a/changelog.d/1892-pool-no-dossier.changed.md b/changelog.d/1892-pool-no-dossier.changed.md deleted file mode 100644 index 0e13e7783..000000000 --- a/changelog.d/1892-pool-no-dossier.changed.md +++ /dev/null @@ -1 +0,0 @@ -Project board: a role-pool entry in the team block reads `@id` beside its rank instead of a Dossier control — `project-team` answers rows keyed by the Project's own Bots, so the old pool click opened a dossier the host never sent; the Chief and my-agent rows keep theirs ([#1892](https://github.com/ThinkFlowLab/FlyBot/issues/1892)). diff --git a/changelog.d/1895-host-limits-code-points.fixed.md b/changelog.d/1895-host-limits-code-points.fixed.md deleted file mode 100644 index 260fbcbed..000000000 --- a/changelog.d/1895-host-limits-code-points.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Host character limits count code points, so a character outside the BMP costs one instead of two ([#1895](https://github.com/ThinkFlowLab/FlyBot/issues/1895)): a memory entry at 300, a `MEMORY.md` at 4,000 and its size note, a scheduled task's name at 120, a Bot-to-Bot message at 20,000, and the Project memory entry at 600 in both writers now measure what a reader counts, and a refusal prints that code-point number. diff --git a/changelog.d/1896-waited-label-seconds.fixed.md b/changelog.d/1896-waited-label-seconds.fixed.md deleted file mode 100644 index e3618fc92..000000000 --- a/changelog.d/1896-waited-label-seconds.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The Project board's wait label now carries seconds under a minute, so a card that waited 40 seconds reads `40s` instead of `0m`; the three duration metrics (PR merge time, issue close time, task completion) use the same label, and a span over zero never floors to `0s`. Unknown and negative spans still render nothing. ([#1896](https://github.com/ThinkFlowLab/FlyBot/issues/1896)) diff --git a/changelog.d/1899-experience-text-code-points.fixed.md b/changelog.d/1899-experience-text-code-points.fixed.md deleted file mode 100644 index b1e758b0a..000000000 --- a/changelog.d/1899-experience-text-code-points.fixed.md +++ /dev/null @@ -1 +0,0 @@ -An incident entry's `trigger`, `wrong` and `right` are bounded at 600 characters counted as code points, not UTF-16 units ([#1899](https://github.com/ThinkFlowLab/FlyBot/issues/1899)): 300 emoji no longer fill the 600 budget, a 600-character emoji entry is stored rather than refused as 1,200 units, and an entry already on disk that is over 600 UTF-16 units but within 600 characters loads again through the same check on the read path. diff --git a/changelog.d/1900-team-dossier-off-the-poll.fixed.md b/changelog.d/1900-team-dossier-off-the-poll.fixed.md deleted file mode 100644 index 802061e11..000000000 --- a/changelog.d/1900-team-dossier-off-the-poll.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Project board: the five-second refresh no longer re-reads the team dossier — `project-team` is read once when the board opens and handed back to each poll, so an open board stops re-reading persona and memory files (about 192 KB a minute) for an answer only an edit changes; a dossier that fails to read now leaves the rows, the done group and the tasks on screen with an empty team block instead of showing "No Project yet" ([#1900](https://github.com/ThinkFlowLab/FlyBot/issues/1900)). diff --git a/changelog.d/1901-task-text-code-points.fixed.md b/changelog.d/1901-task-text-code-points.fixed.md deleted file mode 100644 index 06e49ca8a..000000000 --- a/changelog.d/1901-task-text-code-points.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The task board's typed question and answer (2,000) and its handoff, evidence and lease bounds (300, 200, 200) now count characters rather than UTF-16 units ([#1901](https://github.com/ThinkFlowLab/FlyBot/issues/1901)), so a 2,000-character emoji question is accepted instead of refused as 4,000. diff --git a/changelog.d/1906-own-chat-left-out.fixed.md b/changelog.d/1906-own-chat-left-out.fixed.md deleted file mode 100644 index d2d54f278..000000000 --- a/changelog.d/1906-own-chat-left-out.fixed.md +++ /dev/null @@ -1 +0,0 @@ -`read_own_chat` now says what a cap left out instead of reading as the whole chat: a search that fills its 20 hits ends with `N more not shown; search with narrower words, or read around one of these anchors.`, and a bare read of a part with more than 12 messages is headed `newest 12 of 15, oldest first`. The caps stay; exactly at the cap nothing is added. ([#1906](https://github.com/ThinkFlowLab/FlyBot/issues/1906)) diff --git a/changelog.d/1907-host-cut-code-points.fixed.md b/changelog.d/1907-host-cut-code-points.fixed.md deleted file mode 100644 index 9e685c210..000000000 --- a/changelog.d/1907-host-cut-code-points.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A clipped or excerpted line no longer ends on half of an emoji ([#1907](https://github.com/ThinkFlowLab/FlyBot/issues/1907)): the host cuts `read_own_chat`, checkpoint and handoff lines, the memory review input and the error sentences on a code point boundary, so what a client receives is the whole character instead of a replacement character. diff --git a/changelog.d/1910-team-read-retry.fixed.md b/changelog.d/1910-team-read-retry.fixed.md deleted file mode 100644 index 2aa231270..000000000 --- a/changelog.d/1910-team-read-retry.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Project board: a refused `project-team` read at open is no answer yet, not an empty team — the next five-second poll asks again, the block fills when the answer lands, and it stays frozen for the rest of the open; before this the refusal was normalised to `{ rows: [] }` and served by every later poll ([#1910](https://github.com/ThinkFlowLab/FlyBot/issues/1910)). diff --git a/changelog.d/1912-archive-cut-boundary.fixed.md b/changelog.d/1912-archive-cut-boundary.fixed.md deleted file mode 100644 index d99f9a3da..000000000 --- a/changelog.d/1912-archive-cut-boundary.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A decision or a meeting archive no longer stores half of an emoji ([#1912](https://github.com/ThinkFlowLab/FlyBot/issues/1912)): the host's one `cut` helper stops a bounded prefix before the surrogate pair it would split, and every archive writer now uses it instead of `slice(0, max)` — `decisions.jsonl`, `decisions/-.md`, and the claim line, diagnostics report, activity-feed label and browser text beside them — so the stored record round-trips through UTF-8 as the whole character instead of U+FFFD. diff --git a/changelog.d/1913-dossier-refresh-on-open.fixed.md b/changelog.d/1913-dossier-refresh-on-open.fixed.md deleted file mode 100644 index 7b469a792..000000000 --- a/changelog.d/1913-dossier-refresh-on-open.fixed.md +++ /dev/null @@ -1,4 +0,0 @@ -The Project board's Dossier panel now re-reads the team dossier when it opens, so a memory head written -after the board opened is one click away instead of stale until the board is closed and reopened. A -refused refresh keeps the rows the panel already had, and the five-second poll still does not read the -dossier. diff --git a/changelog.d/1916-code-unit-cuts.fixed.md b/changelog.d/1916-code-unit-cuts.fixed.md deleted file mode 100644 index 217fc9f74..000000000 --- a/changelog.d/1916-code-unit-cuts.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Eight more places stopped storing or showing half of an emoji ([#1916](https://github.com/ThinkFlowLab/FlyBot/issues/1916)): the claim cue's fallback reference, the task lead's name in a member's prompt, a failed group Session's error text, `read_own_chat`'s query and anchor, an open page's address and title, a diagnostics browser-log line, and a friend's Bot name now cut on a code point boundary. The rule itself moved to `core/src/shared/text-boundary.js`, so the shared label code and the host's `cut` use one implementation instead of two. diff --git a/changelog.d/1918-clip-reason-optional.fixed.md b/changelog.d/1918-clip-reason-optional.fixed.md deleted file mode 100644 index 6e5a7c389..000000000 --- a/changelog.d/1918-clip-reason-optional.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The memory review now keeps whole characters in what it shows the model and writes to the log ([#1918](https://github.com/ThinkFlowLab/FlyBot/issues/1918)): the two bounds in `core/src/host/memory.js` — the 800-unit context line and the 3,000-unit two-ended user line — go through the shared boundary rule, so a cut that lands inside an emoji steps back instead of leaving half a pair, and the tail it keeps is never longer than the budget it had. The exported `clip` in `core/src/host/text.js` also makes its reason optional: a two-argument call now reads `… (cut)` instead of the literal `… (cut; undefined)`, while a call that passes a reason keeps `… (cut; )` byte for byte. diff --git a/changelog.d/1919-stack-summary-cut.fixed.md b/changelog.d/1919-stack-summary-cut.fixed.md deleted file mode 100644 index 1a71ca9db..000000000 --- a/changelog.d/1919-stack-summary-cut.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The diagnostics report's stack summary stopped showing half of an emoji ([#1919](https://github.com/ThinkFlowLab/FlyBot/issues/1919)): the `
Stack: …` line now cuts the message on a code point boundary, so the character the 80-unit bound would split is left out of the summary entirely and the line shows a whole-character prefix instead of ending in U+FFFD. diff --git a/changelog.d/1923-published-name-cut.fixed.md b/changelog.d/1923-published-name-cut.fixed.md deleted file mode 100644 index 1e6505ad7..000000000 --- a/changelog.d/1923-published-name-cut.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A friend's Bot name no longer shows half of an emoji ([#1923](https://github.com/ThinkFlowLab/FlyBot/issues/1923)): the published name stored from the roster, the group member line, the room label `othersInRoom` returns and the envelope's name, handle, ownerName and roster fields now cut on a code point boundary, so such a value that straddles its 60 (or 40) cap keeps the whole character instead of U+FFFD. The envelope's message body and its fitTransport shrink loop are untouched. diff --git a/changelog.d/1928-room-share-history-cut.fixed.md b/changelog.d/1928-room-share-history-cut.fixed.md deleted file mode 100644 index 0c4a2de86..000000000 --- a/changelog.d/1928-room-share-history-cut.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A room-share envelope keeps whole characters in the text it copies to another owner's FlyBot ([#1928](https://github.com/ThinkFlowLab/FlyBot/issues/1928)): the history line a join copies (bounded at 2,000 units on both the host that builds the envelope and the guest that copies it) and a line fitted to Bot Social's 4,000-character transport limit now stop before a character that straddles their bound instead of leaving half of it, so a guest no longer reads U+FFFD where the sender typed an emoji — a family emoji fitted to the transport reproduces the old break. The 18,000-unit bound on a line envelope's body goes through the same rule for consistency; it is not reachable on its own because the transport fit already shortens the body to 4,000. diff --git a/changelog.d/1930-host-line-bounds.fixed.md b/changelog.d/1930-host-line-bounds.fixed.md deleted file mode 100644 index c21990582..000000000 --- a/changelog.d/1930-host-line-bounds.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The host's own bounded lines no longer end in half of an emoji ([#1930](https://github.com/ThinkFlowLab/FlyBot/issues/1930)): the busy acknowledgment's 600-unit task text and 1,500-unit message text, `cleanName`'s 60-unit peer name (the one that lands in `fenceUntrusted`'s `from="…"` attribute), the `list_bots` group line's 100-unit notice and 120-unit job line, the group answer echo at 300 and a rework card's note at 200 now cut on a code point boundary, so a value whose cap falls inside a surrogate pair keeps the whole character instead of U+FFFD. Every cap is unchanged. diff --git a/changelog.d/1932-join-notice-fit.fixed.md b/changelog.d/1932-join-notice-fit.fixed.md deleted file mode 100644 index 9b2b2699f..000000000 --- a/changelog.d/1932-join-notice-fit.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A join to a shared room keeps the group notice even when the room's Bot roster has to shrink to fit ([#1932](https://github.com/ThinkFlowLab/FlyBot/issues/1932)): the roster used to be trimmed after the notice, and the notice was cut by the whole envelope's overflow, so a room with enough Bots emptied it and a guest never heard an edited or cleared notice — an explicit clear (an empty notice) was dropped along with it. The roster now gives its rows first, the notice is cut only by what is left over once the roster cannot give more, and a present empty notice arrives as the clear it is. No limit changes: a join still fits Bot Social's 4,000-character transport. diff --git a/changelog.d/1933-room-share-stranger-text-bound.fixed.md b/changelog.d/1933-room-share-stranger-text-bound.fixed.md deleted file mode 100644 index 4e56bd9fd..000000000 --- a/changelog.d/1933-room-share-stranger-text-bound.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A joined room's notice and the pane line copied from another owner's FlyBot keep whole characters ([#1933](https://github.com/ThinkFlowLab/FlyBot/issues/1933); [#1928](https://github.com/ThinkFlowLab/FlyBot/issues/1928) covered the envelopes, and these are the two host-side readers it left on a raw code-unit cut): the guest bounds the notice it stores at its own 2,000 units and the history line it draws at the same 2,000-unit bound it already stores, both by backing up to a code point boundary, so a text whose 2,000th unit is half of a surrogate pair no longer leaves that half in the notice or in the pane — it reads as U+FFFD no more. The pane used to be shown the sender's raw `entry.text`, longer than the line the guest's own log kept; it now draws exactly the bounded prefix the log holds. diff --git a/changelog.d/1937-peer-name-well-formed.fixed.md b/changelog.d/1937-peer-name-well-formed.fixed.md deleted file mode 100644 index 045003623..000000000 --- a/changelog.d/1937-peer-name-well-formed.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A peer name that arrives with half of a surrogate pair — a string JSON accepts but is not well formed — is now made well formed before it is cleaned, so the message header a person reads (`[Message from …]`), the `from="…"` attribute of an untrusted-message fence and the recorded `senderName` carry the replacement character instead of a lone half that would not survive a UTF-8 round trip. The same repair now happens when a shared room's envelope is parsed: the notice, a roster entry's name and owner name and a copied chat line are handed on well formed, so the room's standing prompt and the guest's copy of a line no longer carry a broken character. The 60-character name bound, the notice's 2,000-character bound and their code point boundaries are unchanged ([#1937](https://github.com/ThinkFlowLab/FlyBot/issues/1937)). diff --git a/changelog.d/1939-notice-push.fixed.md b/changelog.d/1939-notice-push.fixed.md deleted file mode 100644 index 206c13ac5..000000000 --- a/changelog.d/1939-notice-push.fixed.md +++ /dev/null @@ -1 +0,0 @@ -The notice the host edits in a group's settings now reaches the friends' Bots already in the room ([#1939](https://github.com/ThinkFlowLab/FlyBot/issues/1939)): editing or clearing it pushes one room-share `join` with the same roster and only the notice changed, and a settings save that leaves the notice alone sends nothing. diff --git a/changelog.d/1940-peer-display-name-well-formed.fixed.md b/changelog.d/1940-peer-display-name-well-formed.fixed.md deleted file mode 100644 index 5444f8284..000000000 --- a/changelog.d/1940-peer-display-name-well-formed.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A peer's display name is now made well formed before it is cleaned: when a roster name, an owner or lead label, an inviter name or a face seat arrives with half of a surrogate pair — a string JSON accepts but that is not well formed — the label carries the replacement character instead of a lone half that shows as an empty box and does not survive a UTF-8 round trip. The 60-character name bound and its code-point boundaries are unchanged, so a name that is already well formed comes back exactly as it was ([#1940](https://github.com/ThinkFlowLab/FlyBot/issues/1940)). diff --git a/changelog.d/1943-inbound-line-text-wf.fixed.md b/changelog.d/1943-inbound-line-text-wf.fixed.md deleted file mode 100644 index 94fa40423..000000000 --- a/changelog.d/1943-inbound-line-text-wf.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A line that arrives from another home with half of a surrogate pair in its body now has the body made well formed before it is used: the stored room line, the line the pane draws and the text handed to the Bot that was called all carry the replacement character instead of a lone half that would not survive a UTF-8 round trip. The line is still accepted and still calls that Bot — a broken character never silences a peer's message — and a body that is already well formed, including one with a real emoji, is passed through exactly as it arrived ([#1943](https://github.com/ThinkFlowLab/FlyBot/issues/1943)). diff --git a/changelog.d/1945-group-text-code-point-bound.fixed.md b/changelog.d/1945-group-text-code-point-bound.fixed.md deleted file mode 100644 index ca3d56bd1..000000000 --- a/changelog.d/1945-group-text-code-point-bound.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A group's notice and name are now cut on a code point instead of a UTF-16 unit ([#1945](https://github.com/ThinkFlowLab/FlyBot/issues/1945)): a 2000-unit notice or a 60-unit name that ended in a whole emoji used to store a lone surrogate, which every encoder downstream turned into U+FFFD; the bound now drops the straddling character whole, the way every other cut in the host already did. diff --git a/changelog.d/1946-empty-notice-join.fixed.md b/changelog.d/1946-empty-notice-join.fixed.md deleted file mode 100644 index ee9733556..000000000 --- a/changelog.d/1946-empty-notice-join.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A room whose roster had to shrink to fit one share envelope no longer drops the host's cleared notice ([#1946](https://github.com/ThinkFlowLab/FlyBot/issues/1946)): the roster now gives while the envelope overflows with the notice field in place, so an explicit empty notice — the host clearing it — reaches the guest as empty instead of disappearing and reading as "change nothing". diff --git a/changelog.d/1950-seat-line-text-wf.fixed.md b/changelog.d/1950-seat-line-text-wf.fixed.md deleted file mode 100644 index 2f54d52d8..000000000 --- a/changelog.d/1950-seat-line-text-wf.fixed.md +++ /dev/null @@ -1 +0,0 @@ -A line that a remote seat writes into a room of this home is now made well formed before it is used: the stored room line, the line the pane draws and the text handed to the Bot the line calls all carry the replacement character instead of half of a surrogate pair that would not survive a UTF-8 round trip. The line is still accepted and still calls that Bot, and a body that is already well formed — a real emoji included — is passed through exactly as it arrived ([#1950](https://github.com/ThinkFlowLab/FlyBot/issues/1950)). diff --git a/core/package-lock.json b/core/package-lock.json index d28bc5689..64ad6259f 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -1,12 +1,12 @@ { "name": "ds-bot", - "version": "0.2.18", + "version": "0.2.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ds-bot", - "version": "0.2.18", + "version": "0.2.19", "license": "Apache-2.0", "dependencies": { "@larksuiteoapi/node-sdk": "1.76.0" diff --git a/core/package.json b/core/package.json index eefef18d5..4b7be1ea1 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "ds-bot", - "version": "0.2.18", + "version": "0.2.19", "description": "DS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chats", "keywords": [ "dsh-plugin", diff --git a/patches/ds-bot/0007-version-and-tooling.patch b/patches/ds-bot/0007-version-and-tooling.patch index 3807b3be1..3c87ece6d 100644 --- a/patches/ds-bot/0007-version-and-tooling.patch +++ b/patches/ds-bot/0007-version-and-tooling.patch @@ -68,14 +68,14 @@ diff --git a/package-lock.json b/package-lock.json { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.18", ++ "version": "0.2.19", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.18", ++ "version": "0.2.19", "license": "Apache-2.0", + "dependencies": { + "@larksuiteoapi/node-sdk": "1.76.0" @@ -706,7 +706,7 @@ diff --git a/package.json b/package.json { "name": "ds-bot", - "version": "0.1.5", -+ "version": "0.2.18", ++ "version": "0.2.19", "description": "DS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chats", "keywords": [ "dsh-plugin",