tui3: Traffic row ages and press to open the message - #1500
Open
santoshkumarradha wants to merge 169 commits into
Open
santoshkumarradha wants to merge 169 commits into
santoshkumarradha wants to merge 169 commits into
Conversation
…ommand is in the manual
Tile bodies hang from the top under one blank row; a waiting tile ends in its question and an Answer button. The Spaces row is one evenly padded segmented control ending in + New space. The foot mirrors the head, the grid is centred between the two rules, and the head and toolbar end where the grid ends. The toolbar says what the hovered control does. Cards and popovers share one padding, keep their primary action last, and stay inside the frame and off the foot. A filter or space with nothing in it keeps the head and offers the way back. The tile look's border field is renamed so it no longer reads as the live-state edge.
…r matches exactly
…strip has a door to the wall A tile's top border now carries only its space dots and title. Under the pointer or the keyboard's focus its bottom border becomes a labelled action row (Open or Answer, Select, Spaces, Close, each with its key), in cells fixed by the tile's width, dropping buttons from the right on narrow tiles. The selection box is drawn on the top border only in the selection mode, on every tile. ? opens a help sheet listing every act the page has in four groups; every row is a press that does what its key does. The next-needing-you key moves to n. The toolbar gains a Help button, dropped last on narrow frames. The tab strip draws a door to the wall after the new-chat +, lit while the wall is up, which opens and closes it and names alt+v in the hint slot.
Every word the wall, the strip chip, the dock and the help sheet draw now says team: the Teams row, + New team, the New team card, the Teams popover, Add to teams and Team settings. The files, types, helpers, hit kinds and tests are renamed to match, and /wall and its manual line mention teams.
…eams.json teams.json is version 2: every team has a random id, a parent, a reserved manager and its colour, and fields a later build writes are kept through a load and a save. The active team, each team's place on the wall, the popovers and every pointer target name a team by id, so deleting or reordering one never retargets another. teamSetParent refuses loops and missing parents, and a deleted team hands its children to its parent. The first build's spaces.json is read once, written as teams.json with the colours it was drawn with, and renamed to spaces.json.migrated.
The new-team card still offers the shared folder's name, and otherwise a pleasant word at once, while one call on the naming role asks the agent for a one to three word name over the chosen conversations' titles. It runs off the update loop, says naming beside the field, and replaces the word only if the person has not typed; a failure or five seconds without an answer keeps the word. A team is never renamed afterwards except in its settings.
/new, which the strip's + and the start page also take, and a folder typed on home put the conversation they mint into the active team and save it, at the moment it first has its key. Switching to a conversation that already exists changes no team. A member closed before it had a name is not drawn on the strip, and saving refreshes each member's name from its tab.
A press on the chip opens a menu under it on every page, the conversations view included: each team and All with its open count, then Add or Remove this conversation for the shown team, New team, which opens the card with the conversation in front picked, and Team settings. The arrows, enter and esc drive it, and a press off it only puts it away. With teams but none shown the chip is a quiet Teams, so the first team can be chosen from the strip, and teams are read once at start so it is there from the first frame.
The new chat page covers opening the conversations view, reading a tile, the action row, selection, teams (making and naming one, colours, membership, showing one, auto-join, settings and delete), the strip's team switcher, where teams are kept, and every key. keys.md names alt+v and the view's keys, and the tasks page's handover heading answers the question about handing work to a team of workers, which the new page would otherwise take.
TestWallRenderPrintsFrame prints the new-team card while a name is asked for, and TestTeamMenuPrintsFrame prints a 120-column chat with the switcher open. The last test still named after spaces is renamed.
One call on the naming role, the same door and billing as NameTeam, with one fall-through rung at most. The model is given conversation titles and folders and the existing teams by short ref, and answers JSON of new teams and additions. The answer is validated strictly: unknown refs and repeats are dropped, names are cleaned as team names, a new team of fewer than two is dropped, and a new team named like an existing one becomes additions to it, so nothing is ever renamed or removed.
The Teams row ends in an Organize button on All (o), counting the conversations in no team from five, and reading Organized once a run found nothing and nothing changed. It opens a card of suggestions, each ticked: a folder pass that is free and exact, merged with one ProposeTeams call off the update loop with a ten second bound, the folder pass winning. Without a model answer the folder pass is shown alone and says so. Apply makes the ticked teams in one save, and the Teams row offers Undo (u) for six seconds, which restores the exact prior list. The help sheet and the key map list o and u.
Where the button is, where suggestions come from, the folders-only and nothing-to-suggest states, ticking and applying, Undo, and the o and u keys.
internal/teams holds the Team and Member types, teams.json v2 with migration from spaces.json, repairs, unknown-field round trip and atomic save, all through config.ProfilePath. Writes go through Update, a read-modify-write under an exclusive filelock with a bounded wait. Members get stable per-team handles, a team has at most one manager who is always a member, each team has an append-only Traffic log with rotation, and Digest renders a team for its manager's context.
The store moved out: team and teamMember are aliases of teams.Team and teams.Member, load, save, the tree walks, the set-aside of an unreadable file and the hue arithmetic call the package. The interface keeps the palette's reserved hues, drawing, naming and the strip. No change in what the wall or the strip does; the frame law now also names the store's disk doors.
Each edit the interface makes to the teams goes through teams.Update (app.teamEdit): the change is made to what the window holds, then again to the file as it is on disk under the lock, and the window adopts what was written. A manager, handle or member another process wrote since the window loaded is kept. Members take their tab's title on the way, so an untitled member gets a handle once it has a title. Organize's Undo takes back exactly what Apply did instead of saving the old list.
A team shown puts its manager first: the manager's own tab named for the team (a diamond and the team name), or a quiet + Manager word button while it has none, which starts a conversation in the team's folder and makes it the manager (AddMember then SetManager). The team switcher and a tile's Teams popover offer Make manager on a member and Remove manager on the manager. The manager's tile is pinned first on the wall and marked.
… start While this window holds a conversation in a team, a clock of its own reads each such team's Traffic log off the loop (beside the door line), paging forward from a cursor, and folds it into a cache; a first look reads the tail, so a window opening never acts on what came before it. The same read adopts a teams file another process changed and titles members that joined untitled. With the manager in front, the frame gives the right of the body to the team's traffic, newest at the bottom, each row a door to its member; on a narrow frame the column is a two-cell edge that lays the traffic over the body. The composer's placeholder says to the manager. KindStop ends the current turn of a conversation this window holds, as the person's stop does; KindStart, in the window holding the manager, opens a conversation in the team's folder under the manager's handle and sends the brief marked as the manager's. Each is done once per entry id.
What a manager is, who outranks whom, the five manager verbs and the member's post with their approval defaults, and when team messages arrive. Claude-Session: https://claude.ai/code/session_0197RHyWZLcLUSyoJusXMoaF
A conversation finds its teams by its own conversation key (the transcript
path, cleaned and symlink-resolved, the key tui3 stores a member under) and
is a manager where Team.Manager is that key.
A manager is armed with team_status, team_read, team_send, team_stop and
team_start; a member of a managed team with team_post. They arrive through
armFamily at the first step boundary that finds the team, never in belt(),
so the fixed prefix is unchanged. Every write is one AppendTraffic entry per
the Traffic contract (note, directive, stop, start). team_start asks under
the shipped default; the rest sit on the builtin approval floor.
At every step boundary, Traffic addressed to this conversation since its
cursor is delivered as one marked session note ("◆ from manager: ...",
"from @web: ..."), once: the cursor lives in the session folder's team.json,
and a fresh conversation starts at its birth or its own start, so history is
not replayed. A manager's turn carries teams.Digest with its brief in a note
of its own, read beside the work at turn start; member states come from each
member's journal tail.
Claude-Session: https://claude.ai/code/session_0197RHyWZLcLUSyoJusXMoaF
teamsSwapped now uses the same held-conversation check as the local open, so a busy transcript this window already holds is brought forward instead of said as another window.
At 110 columns the column is 27 cells and a work row kept six letters of its title, `@scrape +2 Please … ▸ now`: the age, the reply times and two cells of air took the room. Under 32 cells the ages and reply times move to the hint line, before its click, and the air after the handle closes to one cell, so the row reads `@scrape +2 Please provi… ▸`. A band row is cut at a clause rather than leaving ` · …`.
The Teams tab saves on the far machine, so one sentence that said every row belongs to this machine was false there.
A title that is only the session id was title-cased and drawn on home. homeName now calls that chat new conversation, and the sessions place uses the same helper.
Widening the window so more disappears left the hint naming more until the pointer moved. A size change now clears the nav word hover and the more hover.
The age moves to the hint at every width so the arrow and the names keep their cells, and a narrow column cuts only the words, at a word.
A place's head is the nav, the rule and a blank, so the page starts one row higher. Row zero stays where it is.
…tcome "just once" read as both "do it now" and "set it up once", and the card never said whether the proposal was a reminder, a repeating check, a watch or a rule.
…eads A clipped summary was raising a gap the person had already chosen. The check now sees that answer, so just once is only now and not a missing setup.
The old result said nothing was set up, and the model went looking through codeaf for a reminder the person had declined to repeat.
…heck answered only now
Brings in #1410, #1440, #1426, #1389, #1388, #1422, #1334, #1424, #1425 and #1415. Conflicts resolved keeping both sides: the keys row carries dev's project and low-credit line at its right end and the dock in what they leave; the strip's home chip takes dev's word on the one top bar's lead; the chats place joins dev's restored esc and double-space manual.
The icon law (internal/iconlaw) refused ten literals the conversations wall and the teams added: the menu's empty radio, the organize check, the traffic's finished and failed marks, the zoom's closing corners, the dock's square and the tile cell. Each is now the vocabulary's slot through palette.glyph, app.icon, the frame's pieces, or the table's own spelling where the mark is a shape and not a state.
Dev's #1424 pinned the strip's home chip at tabLead, where dev's places bar stands; on this branch the places bar moved to the strip's lead (placeBarLead, DESIGN.md's one top bar), and the chip stays with it. The tests now ask for placeBarLead and the lowercase word, which is the invariant #1424 was after: the same cells in both views.
…ation Brings dev in through #1429. This branch's header stands: the places on the top line, the chat strip only inside a chat, no home piece on the strip. Dev's rules folded in: space space opens home and esc returns to the chat (manual follows, with chats at alt+3 here), the rail's run rows, the attribution-model setting, the plan digest on a person's turn. The side column's Traffic marks and the teams page's marks ask the glyph door, as the icon law requires.
… node renderer Dev's #1410 drew a run's plan rows through the rail's family renderer (railEntryRows, stems, folds); this branch's side column has no forest and draws every task as one line (DESIGN.md, One side column). The adapter keeps dev's rule, one renderer for every task, and draws each lent node through railEntryRow, a level in under the row that carries its run.
…int lines do The hint law (eschint_test.go) found three lines saying esc clears once this branch and dev met. The manual quotes follow.
…gation # Conflicts: # internal/tui3/onetopbar_test.go
…e keeps its live lines The side column draws every task as one line (DESIGN.md, One side column), so dev's rail tests that pinned handles, connectors and a live line under a part now pin the one line, its indent and its shape beside a node's. A task's page has the room the column gave up and draws each part's under-lines again (planPageLines). The head taking the pointer drops home's project underline, and the stopped-frame guard gives the nav room for its clock.
The age sits at the right on the same ladder as a task row, and the words are what a narrow column cuts. A press on the row opens the chat the message belongs to, at that message.
Member
Author
|
@AbirAbbas the third one in the order: #1429, then #1494, then this. It is small (Traffic row ages and press to open the message). Merge after #1494 with that branch deleted, and it targets dev on its own. Spark full suite and test laws are green at af36b0b (OPENROUTER_API_KEY unset). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #1494. It targets #1494's branch for now; once #1494 merges, it targets dev.
Two changes to the Traffic rows in the right column:
2m,3h), dimmed. The arrow and names are never cut; only the message words are.▸still opens a thread.Evidence: fresh Spark clone at af36b0b with
OPENROUTER_API_KEYunset.internal/tui3,session,teams,remote,manual,config,standing,e2e,iconlaw,cmd/codeafandmake test-lawsall pass. gofmt and the change notes check are clean.🤖 Generated with Claude Code