Mark tasks carrying an artifact or a link on the dashboard - #410
Draft
tildesrc wants to merge 1 commit into
Draft
Conversation
Scanning the task table told you a task's state and whose turn it was, but not whether it had a plan to read or a PR to open — you had to press `a` or `p` on each row to find out. Add a two-slot marks column, left of the name it annotates: `❏` when the task has an unhidden artifact, `➚` when it has a url. The header doubles as the legend. Artifacts are files rather than task columns, so presence has to ride along on the list response or the dashboard would need a request per row on every refresh. `GET /tasks` now reports `has_artifacts`, resolved once per response through a new bulk `ArtifactStore.tasks_with_artifacts`. It is concrete on the ABC (defaulting to `list()` per id, like `link_slug` defaults to a no-op), with the filesystem store overriding it with a single-pass `os.scandir` that stops at the first unhidden entry. Writing an artifact now bumps the change feed too — it stores no row of its own, so without that a newly written plan would not wake a parked long-poll and the mark would lag until an unrelated mutation. The dotfile rule that decides "unhidden" moves to `core.artifacts.is_hidden`, shared with the dashboard's existing "Show hidden" toggle. `❏` (U+274F) and `➚` (U+279A) rather than 📁/🔗 because both are East_Asian_Width=Neutral with no emoji presentation form: exactly one cell in every terminal. Emoji are Width=Wide, which would make the column's rendered width depend on the viewer's terminal and font. A test pins equal cell width across all four mark combinations to keep a later edit from regressing that. Tests that read row cells positionally now resolve the index by column label, so inserting a column doesn't renumber assertions across the file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Scanning the task table told you a task's state and whose turn it was, but not whether it had a plan to read or a PR to open — you had to press
aorpon each row to find out.This adds a two-slot marks column, left of the name it annotates:
❏when the task has an unhidden artifact,➚when it has a url. The header doubles as the legend.Getting the bit to the dashboard
Artifacts are files rather than task columns, so presence has to ride along on the list response or the dashboard would need a request per row on every refresh.
GET /tasksnow reportshas_artifacts, resolved once per response through a new bulkArtifactStore.tasks_with_artifacts. It's concrete on the ABC — defaulting tolist()per id, the waylink_slugdefaults to a no-op — so no adapter breaks by not knowing about it, and the filesystem store overrides it with a single-passos.scandirthat stops at the first unhidden entry.Writing an artifact now bumps the change feed too. An artifact stores no row of its own, so without that a newly written
plan.mdwouldn't wake a parked long-poll and the mark would lag until some unrelated mutation came along.The dotfile rule that decides "unhidden" moves to
core.artifacts.is_hidden, shared with the dashboard's existing "Show hidden" toggle rather than spelled out at each surface.Why these glyphs
❏(U+274F) and➚(U+279A) rather than 📁/🔗: both areEast_Asian_Width=Neutralwith no emoji presentation form, so they occupy exactly one cell in every terminal. Emoji areWidth=Wide, which makes the rendered column width depend on the viewer's terminal and font. A test pins equal cell width across all four mark combinations, so a later edit can't quietly regress it.Notes for the reviewer
has_artifactsis on the summary shape only, notTaskOut._task_outis sync and called from ~20 mutation handlers; making it async to add a listdir per mutation response isn't worth it for a field only the table needs, andGET /tasks/{id}/artifactsalready answers it exactly for one task.Ambiguous-width glyphs (the│ ├─ └─connectors, the–status placeholder, the snoozed·), which do drift in a CJK-configured terminal. Independent of this change and worth its own decision.Plan: the task's
plan.mdartifact.