Repository navigation
Project titles: display name per project, accepted by -p (T459, #249) - #295
Merged
Merged
Conversation
… (T459) ctrl+e on a Projects view or project picker row edits a project's title inline; the palette's set project title… does it from a project tab. tsk project title <name> <title> | --clear sets it from the CLI. A title replaces the folder name wherever tsk names the project; footers and --json keep the full path, and JSON rows gain project_title. Titles are unique ignoring case, resolve before basenames for -p, !p and the project verbs, and undo as one ctrl+u entry. Store v16 -> v17 adds the optional record title; a record lives while archived or titled, and concurrent saves merge title and archive field by field. Refs #249.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…adings, sort, palette; docs list every title rule (T459 review)
cursor Bot
pushed a commit
that referenced
this pull request
Nov 8, 2026
#295 left the picker rustdoc and a stranded clippy allow above PROJECT_TITLE_EDIT_FOOTER. Put the three-line doc back on the fn and keep the footer's one-line const doc. Co-authored-by: Saeed <smarzban@users.noreply.github.com>
3 of 5 tasks
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.
Summary
Project titles (T459, #249): a project can carry a display name that replaces its folder name wherever tsk names it, and
-paccepts it.ctrl+eon a Projects view row or a project picker row edits the title inline (single-line draft, prefilled with the title or folder name).Entersaves,Esccancels, an empty draft clears. A taken title refuses on the status row (title Site A is used by <path>) and the editor stays open. The footer shows the full path while editing. Palette: set project title… on a project tab or a Projects view row. Onectrl+uundoes a title change.tsk project title <name> <title>andtsk project title <name> --clear, with codesunknown-project,title-taken,invalid-title.-p,!p, and the project verbs match a title (case-insensitive) before a basename. Ambiguity refusals list a titled candidate asTitle (path).archived project Xmessages, andtsk listtext (--group project,--allscope headings,--sort project). Sorting by name uses the displayed name. Footers and JSONprojectkeep the full path; JSON rows (list, list T12, add) gainproject_title, omitted when the project has none.ProjectRecordgainstitle: Option<String>(skipped when none). No-op migration step pluscurrent_store_v17.json. A record lives while archived or titled; unarchive keeps a title, clearing a title keeps an archive. Concurrent saves mergearchivedandtitleper field (ProjectIntent), last writer wins per field, never dropping the other. NewUndoEntry::ProjectTitle { path, previous, title }; a stale one refuses withStaleProjectUndoand is pruned at save.Docs: board.md (Project titles section, palette row), keys.md, cli.md (scope, project title, JSON fields, refusal table), capture.md (
!p), storage.md (format 17), CONTEXT.md, llms.txt, CHANGELOG (Added, credit #249; the unreleased store-16 Breaking line now says 17), What's new notice id 7 (unreleased) gains a paragraph, tsk-cli skill wording (version stays 1.7.0, unreleased since v0.13.0 shipped 1.6.0; hash pin refreshed).Decisions and deviations
Decisions 1–9 of the brief are implemented as written, except where noted:
/(and\on Windows: the platform path separator, so-pcan always reach a title), a control character,desk/global(they are scope labels in--group projectand!p), and more than 80 characters. Whitespace is trimmed and inner runs collapse to one space.Enteron an untitled project's unchanged prefill saves nothing (otherwise every accidentalctrl+e,Enterwould write a title equal to the folder name).hererow before its first task refuses atctrl+e(<name> has no tasks yet: add one, then title it). Found in the PTY smoke; the store only keeps titles for projects it knows, matching how archive refuses (nothing to archive in X).ctrl+uwas inert; it now undoes the top entry when that entry is a title change, so a title set in the picker undoes there. Every other undo still waits for the board.Esc).project titlerefusals carry codes (per brief item 6);project archive|unarchivekeep their message-only refusals. cli.md and the skill say so.-p,!p, project verbs) collects all title matches and refuses two or more as ambiguous, listingTitle (path)for each, so it never picks one silently. Renaming either project clears it.Seed script and real run
Isolated state only (
TSK_STATE_DIRand--state-dirunder a fresh/tmp/tsk-459-*). The seed binary was the maintainer's currentmainbuild (store v16,tsk 0.13.0), copied to a scratch dir, not a tagged release.Before (v16 store, seeded by the previous build):
After (new build; first save migrates and keeps
tsk.json.v16):Board, driven in a PTY (110×30, pyte;
HERDR_ENVunset)3→ Projects view,ctrl+eon the tasklesshererow refuses;j,ctrl+e,ctrl+u,Site A,Entersaves;p, move to the otherwp-content,ctrl+e,site a,Enterrefuses with the editor open:Afterwards
tsk list --all --group projectshowsSite Aandwp-content.Tests
New:
domain::task::tests::project_titles_are_unique_ignoring_case_and_refuse_desk_slashes_and_controlsdomain::task::tests::a_project_record_lives_while_archived_or_titleddomain::task::tests::a_title_change_undoes_once_and_a_stale_one_refuses(incl. an undo that would recreate a duplicate)scope::project_title_tests::permissive_resolution_takes_a_title_first_and_labels_ambiguity(also: a title two projects share refuses in both resolvers)cli_archive::project_title_reaches_add_json_scope_headings_and_project_sort(add --jsoncreated and existing,--allheadings,--sort project)board_project_title::the_picker_and_the_projects_view_sort_by_the_titlescope_resolver::project_titles_resolve_first_and_label_ambiguitystore_persist::literal_v17_fixture_is_current_and_round_trips,literal_v16_fixture_migrates_to_v17_and_keeps_its_archived_project,project_titles_round_trip_through_the_store,project_title_and_archive_from_two_writers_merge_field_by_fieldcli_archive::project_title_sets_resolves_lists_refuses_a_duplicate_and_clears,project_title_usage_errors_exit_2_and_an_unknown_project_refusesboard_project_title::*(6): Projects view edit + duplicate + Esc + undo; unchanged folder name / empty clears; picker edit +ctrl+uin the picker; palette route; tasklesshererefusal; a failed save keeps the editor and draft through Cancelboard_project_title::the_projects_view_footer_offers_ctrl_e_title_and_a_click_opens_the_editorctrl+e titlebesidectrl+f archive(shed 2: at 80 columns↑↓ movesheds first; on the compact card it sheds with the sort). The Projects view verb row readsenter open · / search · ctrl+e title · : commands · ? help, and a click on it opens the editor.projects_index_titled_110x30,projects_index_title_edit_110x30,project_picker_title_edit_78x24,project_picker_110x30,project_picker_40x24;projects_index_110x30andprojects_preview_split_110x30gain thectrl+e titleverb.Updated: store version expectations (16 → 17), palette catalog lists (
set project title…), docs parity (new palette condition), queue/render call sites for theProjectNamesparameter.Revert-checked (fix hunk reverted by hand, test failed, fix restored): field-by-field merge of the title intent; the editor outliving the save; title-first resolution; the no-duplicate undo guard; refusing a shared title in resolution; the palette command's intent (the palette test drives
:+ query + Enter throughresolve_board_command); sorting by the shown name;project_titlein add JSON; titled--allheadings.Verification
cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test: pass.cd site && npm ci && npm test: 63/63 pass.cargo build --release: ok; real run and PTY board smoke above.Not run
HERDR_ENVunset); the board was driven in a PTY instead. Narrow-width picker editing was only covered by the 78×24 golden.HOMEwas not overridden for the real run (the harness refuses env injection ofHOME); isolation wasTSK_STATE_DIRplus--state-dir, and only CLI verbs and the board ran, none of which readHOMEfor state.x86_64-pc-windows-gnu) was run; CI covers it. On Windows\is also refused in a title.npm run test:paritypassed (80/80). The web demo cannot edit titles, so its Projects view verb row was left without the hint; parity does not compare that row. The parity PTY smoke was not run.Refs #249