Repository navigation
v0.4.3
Chats open instantly from a 24-hour cache kept in sync, download only what is new, and read as one calm conversation.
- Opening a chat downloads only what is new (#42). The app tells the daemon how much of the transcript it already holds (
since, and a fingerprint of the last message), and the snapshot carries only the messages after it; when the copies do not line up, it carries everything, as before. A newGET /sessions/:id/transcriptanswers the same without ever starting an omp: a live session from memory, a closed one from the transcript the daemon saves when its omp exits (idle, the daemon stopping, omp leaving), as long as the session file has not changed since. Saved transcripts are kept while their session was active in the last 24 hours. Daemons list this as thetranscript-syncfeature. - Every session active in the last 24 hours stays cached on the phone and up to date, so chats open at once (#43). The cache holds the daemon's own messages, state and summary instead of rendered items, kept by time (no 40-session or 400-item limit, no clipped tool output). With a daemon that has
transcript-sync, the app refreshes stale copies in the background, one at a time and only with what is new: after the session list loads, every minute in the foreground, when it comes back to the foreground and when a chat is left. A chat paints the end of its copy first (transcript, model, todos), in the same time whatever the session's length, then merges the daemon's delta and puts the rest of the copy under it; a delta that does not fit is fetched again whole, never spliced. The old item caches are deleted. - The chat is one calm conversation column (#44, #47). OMP's turn has no bubble, avatar or name: it opens with a one-line divider that says how it ended and how long it took ("Done in 3m 12s", "Failed", "Stopped"; while it runs, what OMP is doing now in a brand-gradient shimmer and the time so far), and tapping the divider folds the turn's work away, leaving the answer. The work is quiet grey one-line rows: each stretch of tool calls is named by the kinds of work it did, not by counts ("Ran commands", "Read files, edited files, ran commands"); it opens in place onto one row per call (kind, a short summary, a diff stat), and a call opens in place onto its command output in a capped terminal block, its diff with coloured edge bars, or the first lines of what it read, with the full call one tap away. Thinking is a "Thought" row that opens in place onto compact grey text. The reply is prose straight on the page, closed by a copy button and the time; the user's message is a right-aligned rounded bubble on a tinted surface. Replies are set at 15/24 with bold headings and generous space above them, close list items, tables with horizontal hairlines only and roomy cells (flush with the prose; a table that nearly fits is pulled in, a wide one scrolls), code blocks as a soft rounded panel labelled with the language or "Code", soft-wrapped by default, with a wrap toggle and a copy button, inline code as a light tint, links in cyan. Text follows the system font size within per-kind caps (prose further than code), rows grow instead of clipping, and table columns and list numbers are measured at the current size. A row opened by a tap keeps its header in place, and the jump to the newest message is a small circle (a pill when it counts new messages). Radii follow one scale (8 / 12 / 16 / 20 / 28).
- Release review fixes (#48):
- A streaming reply no longer shows its first words twice. omp 18 writes each event's message out late, so
message_startalready carries words whose deltas follow; updates now settle the deltas against the event's own content, for text and thinking alike. - Attaching the older part of a cached chat under its tail, or a snapshot arriving mid-turn, no longer wipes the reply that is streaming, the prompt just sent or a running tool card.
- Sessions are dated by their last real use. Closing omp (a daemon restart, the idle reaper, a resume) rewrites the session file, which made every session it had open look used "now", reordered Home and kept their copies longer; opening a session or a state echo no longer counts either. The daemon remembers the file as its own omp left it and counts a newer file time only when someone else wrote it.
- The phone's copy is appended to, not rewritten: messages are kept one per line, written off the JS thread, and a delta no longer parses and rewrites the whole multi-MB copy (about 200 ms of work per delta on a 4.9 MB copy, now about 1 ms). Older copies are converted at their next save.
- The background pass skips the chat on screen (it saves its own copy), sweeps expired copies after every pass, and a list asked for by Home and the computer's probe at once is fetched once.
- Past the daemon's 5,000-message cap a live session keeps the transcript's own indices, so deltas still line up instead of resending everything on every open.
- A chat whose computer cannot be reached says so after 5 s, says it shows the saved copy, and turns sending off until the link is back.
- The model sheet's search field and the composer's model chip grow with large system font sizes; changing the font size no longer drops you out of the chat.
- Computers with the same name are told apart by address on Home and in the remove confirmation, and a non-tailnet address is labelled LAN instead of Tailscale.
- A streaming reply no longer shows its first words twice. omp 18 writes each event's message out late, so
中文
对话从保持同步的 24 小时缓存中即开即显,只下载新增内容,并以一条安静的对话流呈现。
- 打开对话只下载新增的部分(#42)。App 告诉 daemon 自己已有多少条消息(
since,以及最后一条消息的指纹),快照就只带其后的消息;两边对不上时照旧发送全部。新增GET /sessions/:id/transcript,返回同样的内容,且从不为此启动 omp:活动会话从内存返回,已关闭的会话从 omp 退出时(空闲回收、daemon 停止、omp 自行退出)保存的记录返回,前提是会话文件此后没有变化。保存的记录在会话最近 24 小时内有活动时保留。daemon 以transcript-sync功能声明这一点。 - 最近 24 小时内有活动的会话都缓存在手机上并保持最新,对话即开即显(#43)。缓存保存的是 daemon 的消息、状态和会话摘要,而不是渲染后的条目,按时间保留(不再限 40 个会话、400 条,也不再截断工具输出)。对支持
transcript-sync的 daemon,App 在后台逐个刷新过期的副本,只取新增部分:会话列表加载后、前台时每分钟、回到前台时、离开对话时。打开对话先显示缓存的末尾(记录、模型、待办),无论会话多长都一样快,再合并 daemon 的增量并补上缓存中更早的部分;对不上的增量会重新整份获取,绝不拼接出错的记录。旧的条目缓存会被删除。 - 对话改为一条安静的对话流(#44、#47)。OMP 的回合不再有气泡、头像或名字:开头是一行分隔线,说明这一轮如何结束、用了多久(“已完成,用时 3分12秒”“处理失败”“已停止”;运行中显示 OMP 正在做什么,带品牌渐变的流光,以及已用时间),点它可以收起这一轮的过程,只留下回答。过程是一行一行的灰色小字:每段连续的工具调用按做了哪类事命名,不写次数(“执行了命令”“读取了文件、修改了文件、执行了命令”),点开在原处列出每次调用(类别、简短摘要、改动行数);每次调用又可在原处展开为限高的终端输出、带彩色边条的 diff,或读取内容的开头几行,完整内容一点即达。思考是一行“思考”,点开在原处显示紧凑的灰色文字。回复是直接排在页面上的正文,末尾是复制按钮和时间;用户消息是右侧带浅色底的圆角气泡。回复正文 15/24,标题加粗且上方留白充足,列表项紧凑,表格只有水平细线、单元格宽松(与正文对齐;差一点放得下的表格会收进栏内,宽表格横向滚动),代码块是一块柔和的圆角面板,标注语言或“代码”,默认自动换行,带换行切换和复制按钮,行内代码是浅色底,链接为青色。文字跟随系统字号,各类文字有各自上限(正文放大得比代码多),行高随之增长而不被裁切,表格列宽和列表序号按当前字号计算。点开某一行时它的标题保持原位;跳到最新消息的按钮是一个小圆钮(有新消息时变为显示条数的胶囊)。圆角统一为 8 / 12 / 16 / 20 / 28。
- 发布评审修复(#48):
- 流式回复不再把开头几个词显示两遍。omp 18 写出事件里的消息较晚,
message_start已经带有随后才发增量的文字;现在每次更新都把增量与事件自带的内容对齐,正文和思考都一样。 - 把缓存对话较早的部分接到末尾之下,或在一轮进行中收到快照时,不再清掉正在流式输出的回复、刚发出的消息或正在运行的工具卡片。
- 会话按最后一次真正使用的时间排序。omp 关闭时(daemon 重启、空闲回收、恢复会话)会重写会话文件,过去这会让它打开过的每个会话都显示为“刚刚”使用、打乱首页顺序并延长其缓存;打开会话或状态回显也不再算作使用。daemon 会记下自己的 omp 退出时文件的样子,只有别人写过文件时才把更新的文件时间算作活动。
- 手机上的副本改为追加而不是重写:每行一条消息,在 JS 线程之外写入,增量不再解析并重写整份几 MB 的副本(4.9 MB 的副本每次增量约 200 ms 的工作降到约 1 ms)。旧格式的副本会在下次保存时转换。
- 后台同步跳过正在显示的对话(它自己保存副本),每轮之后清理过期副本;首页和电脑探测同时请求会话列表时只请求一次。
- 超过 daemon 的 5,000 条消息上限后,活动会话仍使用整份记录的序号,增量依然对得上,不会每次打开都重发全部。
- 连不上电脑时,对话会在 5 秒后说明无法连接、当前显示的是保存的副本,并在恢复连接前停用发送。
- 系统字号较大时,模型面板的搜索框和输入框下的模型标签会随之变大;修改字号不再把你带离对话。
- 同名的电脑在首页和移除确认中按地址区分;不在 tailnet 上的地址显示为“局域网”而不是 Tailscale。
- 流式回复不再把开头几个词显示两遍。omp 18 写出事件里的消息较晚,
What's Changed
- Delta snapshots, a transcript served without omp, and a 24 h phone cache kept in sync by @Rinai-R in #45
- Set the transcript at chat scale: calm headings, compact tables, light code blocks (#44) by @Rinai-R in #46
- Rebuild the chat flow as one calm conversation layout (#47) by @Rinai-R in #49
- Release review fixes for 0.4.3 by @Rinai-R in #50
- Release v0.4.3 by @Rinai-R in #51
Full Changelog: v0.4.2...v0.4.3