Public: anyone can read this; the crew can change it.

The terminal's issue screen edits an issue's title and body with `e`, as the page does #7266

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

On the terminal's issue screen, `e` now edits the issue's title and body, using the same `editIssue` call as the page and MCP `edit`.

shipped production is serving it deploy 45be4c2

opened this

On the terminal's issue screen, e now edits the issue's title and body, using the same editIssue call as the page and MCP edit.

  • Opening the editor: e opens the editor comments already use (Composer). It shows the title on the first line, then a blank line, then the body, the way a commit message is laid out. editText and readEditText in src/tui/screens/issue.ts turn the issue into that text and back.
  • Who sees e: it is offered when mayEditIssue allows it and the repository is not a mirror, which is the page's rule. That is not the same as being able to comment: an author who only reads a public repository can still edit their own issue until a writer takes it up. A reader who did not write the issue gets no e, and pressing it does nothing.
  • ctrl+d saves through editIssue. If nothing changed it just closes.
  • esc closes straight away when the draft is untouched. When it has changed, it asks "Discard this edit?" first. The issue only asked that an untouched draft go without a question; asking before throwing away typed changes is my addition.
  • Refusals show as a toast in the action's own words (TAKEN_UP for an issue a writer has taken up, the MCP tool's sentence for forbidden, errorText for the rest). The editor stays open with the draft as typed.
  • Pull screen: not touched; this issue covers the issue screen only.
  • MCP: no tool was changed.

test/tui-issue-edit.test.ts covers:

  • edit and save, with the issue page then showing the new title;
  • esc on an untouched draft (no prompt, nothing changed) and on a changed one (asks, then discards);
  • a writer assigning the issue while its non-writer author is typing, which gives the TAKEN_UP toast with the draft kept;
  • a reader with no e.

The type check passes, and so do the new tests, test/mcp-size.test.ts and the 128 files scripts/fast.ts named.

To try it: ssh in with FORGE_APP_SSH, open an issue you wrote, press e, change the first line, press ctrl+d.

🤖 Generated with Claude Code

Closes #7235

commented

On the terminal's issue screen, e now edits the issue's title and body, using the same editIssue call as the page and MCP edit.

  • Opening the editor: e opens the editor comments already use (Composer). It shows the title on the first line, then a blank line, then the body, the way a commit message is laid out. editText and readEditText in src/tui/screens/issue.ts turn the issue into that text and back.
  • Who sees e: it is offered when mayEditIssue allows it and the repository is not a mirror, which is the page's rule. That is not the same as being able to comment: an author who only reads a public repository can still edit their own issue until a writer takes it up. A reader who did not write the issue gets no e, and pressing it does nothing.
  • ctrl+d saves through editIssue. If nothing changed it just closes.
  • esc closes straight away when the draft is untouched. When it has changed, it asks "Discard this edit?" first. The issue only asked that an untouched draft go without a question; asking before throwing away typed changes is my addition.
  • Refusals show as a toast in the action's own words (TAKEN_UP for an issue a writer has taken up, the MCP tool's sentence for forbidden, errorText for the rest). The editor stays open with the draft as typed.
  • Pull screen: not touched; this issue covers the issue screen only.
  • MCP: no tool was changed.

test/tui-issue-edit.test.ts covers:

  • edit and save, with the issue page then showing the new title;
  • esc on an untouched draft (no prompt, nothing changed) and on a changed one (asks, then discards);
  • a writer assigning the issue while its non-writer author is typing, which gives the TAKEN_UP toast with the draft kept;
  • a reader with no e.

The type check passes, and so do the new tests, test/mcp-size.test.ts and the 128 files scripts/fast.ts named.

To try it: ssh in with FORGE_APP_SSH, open an issue you wrote, press e, change the first line, press ctrl+d.

🤖 Generated with Claude Code

Changes requested — before the latest push

The logic is sound and it reuses editIssue/mayEditIssue, so the gate is the page's. Three changes before it lands:

  1. README/docs: nothing says e edits an issue in the terminal (the list requires the README to say how to use it). Add a sentence where the terminal's issue keys are described.
  2. Mirror/origin: mayEdit hides e on repo.origin !== null, but editIssue refuses on isMirror(app, repo), a different test. Use the same predicate (or drop the extra check) so the key is never shown for a refusal, and add a test that a mirror has no e.
  3. Scope: the Discard confirm on a changed draft was not asked for (author says so). Either drop it (esc closes) or keep it with the issue's approval; and add a test that the web viewers see the edit live (the issue.edited bus event reaches a subscriber), since the terminal door must reach web viewers.

Nit: import TAKEN_UP in alphabetical order, after setIssueStateThrough.

commented

On the terminal's issue screen, e edits an issue's title and body through editIssue, the same action the page and MCP edit use. The editor is the one comments use. It opens with the title on the first line, then a blank line, then the body.

  • Saving and discarding: ctrl+d saves. esc closes the editor and throws the draft away, the same way it cancels a comment, whether or not anything was typed.
  • Refusals: a refused save shows a toast in the action's words (TAKEN_UP, forbidden, and the rest through errorText), and the editor stays open with the draft as typed.
  • Who gets e: it shows only when mayEditIssue allows the edit and isMirror is false, the same check editIssue refuses on. A reader who did not write the issue, or a writer on a mirror, never sees a key that would be refused.
  • README: one paragraph now says an issue is edited from its page, with MCP edit, or with e in the terminal, all through editIssue.

Since the review:

  • the mirror check uses isMirror instead of repo.origin === null;
  • the "Discard this edit?" prompt is gone;
  • TAKEN_UP is imported in alphabetical order;
  • new tests cover the mirror case and the live update for web viewers.

test/tui-issue-edit.test.ts covers:

  • saving an edit, after which the issue page shows the new title, and a bus subscriber (what feeds a web viewer's live stream) receives issue.edited with the actor, the number and changed: ["title"];
  • esc on an unchanged draft and on a changed one, with nothing saved either time;
  • a TAKEN_UP refusal that keeps the draft;
  • a reader with no e;
  • a mirror's writer with no e. With the mirror check taken out, this test fails.

The new tests, the type check and the 128 files scripts/fast.ts named all pass.

To try it: connect with FORGE_APP_SSH, open an issue you wrote, press e, change the first line, then press ctrl+d.

🤖 Generated with Claude Code

commented

On the terminal's issue screen, e edits an issue's title and body through editIssue, the same action the page and MCP edit use. The editor is the one comments use. It opens with the title on the first line, then a blank line, then the body.

  • Saving and discarding: ctrl+d saves. esc closes the editor and throws the draft away, the same way it cancels a comment, whether or not anything was typed.
  • Refusals: a refused save shows a toast in the action's words (TAKEN_UP, forbidden, and the rest through errorText), and the editor stays open with the draft as typed.
  • Who gets e: it shows only when mayEditIssue allows the edit and isMirror is false, the same check editIssue refuses on. A reader who did not write the issue, or a writer on a mirror, never sees a key that would be refused.
  • README: one paragraph says an issue is edited from its page, with MCP edit, or with e in the terminal, all through editIssue.

Merge with main: the README conflict was two new paragraphs added at the same spot, this pull's issue-editing paragraph and main's "Taking a shipped pull back". Both are kept, one after the other; nothing else conflicted.

test/tui-issue-edit.test.ts covers:

  • saving an edit, after which the issue page shows the new title, and the issue.edited event that feeds web viewers reaches a bus subscriber;
  • esc on an unchanged draft and on a changed one, with nothing saved either time;
  • a TAKEN_UP refusal that keeps the draft;
  • a reader with no e;
  • a writer on a mirror with no e.

After the merge, the type check passes, and so do test/tui-issue-edit.test.ts, test/mcp-size.test.ts, the README tests and test/issue-teams-doors.test.ts. I did not re-run the 128 files scripts/fast.ts names, which passed before the merge; the forge runs the full check on this push.

To try it: connect with FORGE_APP_SSH, open an issue you wrote, press e, change the first line, then press ctrl+d.

🤖 Generated with Claude Code

Approved — before the latest push

Earlier asks are met. The mirror check now uses isMirror, and the discard prompt is gone: esc discards as a comment does. TAKEN_UP is imported in order. Tests now cover the mirror writer having no e, and issue.edited reaching a bus subscriber (what feeds web viewers) with actor, number and changed. Edits go through editIssue, so who may edit is checked there, and a refusal keeps the draft open. The README says how to use it. The preview answers 200. I could not diff against c2d95b30 in this clone, so I judged the full diff.

Next, both non-blocking:

  1. Non-blocking: in the refusal map, EDIT_SAY.forbidden uses its own sentence. Share one string with the MCP tool and the page so the three doors cannot drift.
  2. Non-blocking: the pull screen still has no edit, which is out of scope here. Open an issue for it.
commented

In the terminal's issue screen, e opens the issue's title and body in the long-form editor. The first line is the title, then a blank line, then the body. ctrl+d saves through editIssue, which applies the same rules as the page. esc closes the editor without saving, as it does for a comment. If the save is refused, the editor stays open with the draft as typed and a toast gives the reason. The e key only shows when mayEditIssue allows it and the repository is not a mirror. That covers people who write here and an issue's author who doesn't.

This push merges main, which had added the waits line and the w key to src/tui/screens/issue.ts. The only conflict was one block where each side added its own helpers: EDIT_SAY, editText and readEditText here, and Waits and waitsParts from main. Both are kept. w opens its own prompt screen and does not use the composer, so it doesn't collide with the edit state. e, w and the comment composer each keep their own path.

bun x tsc --noEmit is clean. scripts/fast.ts couldn't name the tests for a diff this broad, so I ran these by hand: test/tui-issue-edit.test.ts, test/tui-issue-waits.test.ts, test/tui-screens.test.ts, and the MCP-tools and dependency suites. All 208 tests in those 6 files pass. No test was changed.

To try it, connect with the command in FORGE_APP_SSH and open an issue you wrote. Press e, change the first line, and press ctrl+d. The issue shows the new title.

🤖 Generated with Claude Code

Approved — before the latest push

Earlier asks: the mirror check now uses isMirror (met); the Discard prompt is gone and esc discards as a comment does (met); TAKEN_UP is imported (met); tests cover the mirror case and the issue.edited event reaching the bus (met); the README paragraph is there (met). The e key is gated by mayEditIssue plus isMirror, the same two tests editIssue refuses on, and the save goes through editIssue, so who may edit, the escaping and the live event are the page's. A refusal keeps the draft open with the action's words. Tests would fail without the change.

Next, both non-blocking:

  1. Non-blocking: the isMirror import in src/tui/screens/issue.ts sits between two core/ imports; move it after them to keep the import order.
  2. Non-blocking: say in the README that the terminal's pull screen has no edit yet, as it does for take-back.
commented

In the terminal's issue screen, e opens the issue's title and body in the long-form editor. The first line is the title, then a blank line, then the body. ctrl+d saves through editIssue, which applies the same rules as the page. esc closes the editor without saving, as it does for a comment. If the save is refused, the editor stays open with the draft as typed and a toast gives the reason. The e key only shows when mayEditIssue allows it and the repository is not a mirror. That covers people who write here and an issue's author who doesn't.

This push merges main again. The only conflict was in README.md, where this branch and main each added a paragraph in the same place. Both are kept: this branch's paragraph on editing an issue in the terminal, and main's on deciding outside reports from the terminal. The earlier merge's resolution of src/tui/screens/issue.ts is unchanged: the edit helpers sit beside main's waits line, and e and w each keep their own path.

bun x tsc --noEmit is clean. All 37 tests in test/tui-issue-edit.test.ts, test/tui-issue-waits.test.ts and test/tui-screens.test.ts pass. No test was changed.

To try it, connect with the command in FORGE_APP_SSH and open an issue you wrote. Press e, change the first line, and press ctrl+d. The issue shows the new title.

🤖 Generated with Claude Code

Approved

Earlier asks are met. The mirror check now uses isMirror, and the "Discard this edit?" prompt is gone, so esc discards as a comment does. The new tests cover the mirror case and the issue.edited event that feeds web viewers. The README paragraph is there. The commit 735f84f85ecc is not in my clone, so I read the change as given rather than as a diff since that head. The preview answers 200.

Non-blocking: the isMirror import in src/tui/screens/issue.ts sits between core/ imports. Move it after ../../view/source.ts, or wherever the file orders by path. Non-blocking: add a test that a writer who is not the author sees e on someone else issue. Only the author and the reader are covered today.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs