Skip to content

feat(chat): add chat update command for editing campfire messages#462

Merged
jeremy merged 1 commit into
basecamp:mainfrom
nnemirovsky:feat/chat-update
Jul 22, 2026
Merged

feat(chat): add chat update command for editing campfire messages#462
jeremy merged 1 commit into
basecamp:mainfrom
nnemirovsky:feat/chat-update

Conversation

@nnemirovsky

@nnemirovsky nnemirovsky commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds basecamp chat update <id|url> [content] for editing existing campfire lines in place, mirroring the shape of chat post. Until now the CLI could only post or delete chat lines — editing required deleting and reposting, which bumps the message and is disruptive in active rooms.

Backed by the SDK's CampfiresService.UpdateLine (PUT /chats/{c}/lines/{l}, returns 204). Verified live: the command round-trips an edit against a real campfire line and re-fetches the canonical post-update line.

Content handling

Chat edits always render as rich text server-side. Content is resolved into the exact body sent, in four explicit modes validated before any request:

  • default — Markdown converted to HTML unconditionally, then @mentions resolved (matches messages). Fixes a class of bug where **bold** with no mention was previously sent raw.
  • --content-type text/html — HTML supplied as-is, then @mentions resolved.
  • --content-type text/plain — serialized verbatim via richtext.PlainToHTML (HTML-special chars escaped, line breaks preserved as <br>), mention resolution skipped.
  • anything else — rejected with a usage error.

--content-type is applied client-side only; the SDK PUT carries just content, and the server coerces every edit to rich text.

URL, host & argument safety

  • URL arguments route through the shared urlarg parser (which gains a CampfireID field for the chat-line route) plus a new hostutil.IsTrustedBasecampHost gate (http/https only). A pasted card/todo/message URL, a chat-line collection URL (/chats/{c}/lines), a boundary-evading line ID, an untrusted/look-alike host, or an account mismatch is rejected rather than silently misinterpreted.
  • Project resolution is deferred and best-effort: with --room or a URL in hand, the PUT proceeds on the chat + line IDs alone, so a stale/unreachable default project can't fail the edit — it only drops --in from breadcrumbs.
  • Missing <id|url> yields a purpose-specific usage error rather than the generic arg-count rewrite.

SDK dependency

Pinned to the v0.8.0 SDK release, which carries CampfiresService.UpdateLine (basecamp/basecamp-sdk#295) — no fork, no replace. go.mod, go.sum, sdk-provenance.json, and API-COVERAGE.md all point at the release.

Test plan

  • bin/ci green on the committed tree (unit, e2e, surface, skill drift, provenance, bare-groups, tidy, lint)
  • Live edit round-trip against a real campfire line (PUT 204 + re-fetch)

Copilot AI review requested due to automatic review settings May 4, 2026 10:32
@github-actions github-actions Bot added commands CLI command implementations tests Tests (unit and e2e) skills Agent skills deps labels May 4, 2026
@github-actions github-actions Bot added the enhancement New feature or request label May 4, 2026
@nnemirovsky
nnemirovsky marked this pull request as ready for review May 4, 2026 10:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new basecamp chat update / basecamp campfire update command so existing campfire lines can be edited in place, extending the chat command set to cover the SDK’s new UpdateLine capability.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Changes:

  • Adds the new chat update subcommand, including project/room resolution, optional rich-text content type handling, and mention resolution behavior aligned with chat post.
  • Updates command metadata and generated CLI surface/docs so the new action appears in help, skill docs, and smoke coverage.
  • Temporarily swaps the SDK dependency to a forked revision that exposes CampfiresService.UpdateLine.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
skills/basecamp/SKILL.md Adds a chat update example to the Basecamp skill docs.
internal/commands/commands.go Registers update in the chat command catalog.
internal/commands/chat.go Implements the new chat line update command and wires it into chat.
internal/commands/chat_test.go Adds unit coverage for update request payloads and empty-content rejection.
go.sum Updates module checksums for the temporary SDK fork.
go.mod Adds the temporary replace to the forked SDK revision.
e2e/smoke/smoke_campfire.bats Adds smoke coverage for editing an existing campfire message.
e2e/chat.bats Adds a CLI error-path test for missing chat update arguments.
.surface Regenerates command/flag surface metadata for the new subcommand.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/commands/chat.go Outdated
Comment thread go.mod Outdated
Comment thread go.mod Outdated
Comment thread internal/commands/chat_test.go
Comment thread go.mod Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="e2e/smoke/smoke_campfire.bats">

<violation number="1" location="e2e/smoke/smoke_campfire.bats:57">
P3: The new update smoke test does not verify that the message body actually changed, so a no-op update could still pass.</violation>
</file>

<file name="e2e/chat.bats">

<violation number="1" location="e2e/chat.bats:103">
P2: Missing-argument test is under-specified: it only checks for a non-zero exit, so unrelated failures would still make it pass.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread e2e/chat.bats
Comment thread e2e/smoke/smoke_campfire.bats
Copilot AI review requested due to automatic review settings May 4, 2026 11:06
@github-actions github-actions Bot added docs and removed deps labels May 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/commands/chat.go Outdated
Comment thread internal/commands/chat.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/commands/chat.go Outdated
Comment thread internal/commands/chat.go Outdated
Comment thread go.mod Outdated
Comment thread go.mod Outdated
@github-actions github-actions Bot added the sdk SDK wrapper and provenance label May 4, 2026
@nnemirovsky
nnemirovsky requested a review from Copilot May 4, 2026 11:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/commands/chat.go Outdated
Comment thread go.mod Outdated
Comment thread API-COVERAGE.md
@nnemirovsky
nnemirovsky marked this pull request as draft May 4, 2026 11:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5065671927

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/commands/chat.go Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 15:29
@jeremy
jeremy force-pushed the feat/chat-update branch from 5065671 to 5e0f97e Compare July 22, 2026 15:29
@jeremy
jeremy force-pushed the feat/chat-update branch from 5e0f97e to 210101a Compare July 22, 2026 15:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.

Comment thread internal/urlarg/urlarg.go Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 15:34
@jeremy
jeremy force-pushed the feat/chat-update branch from 210101a to 2a6bb02 Compare July 22, 2026 15:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a6bb02b90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/commands/chat.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.

Comment thread internal/commands/chat.go Outdated
Comment thread e2e/chat.bats
Copilot AI review requested due to automatic review settings July 22, 2026 15:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

internal/commands/chat.go:834

  • When effectiveChatID is already known (via URL or --room), this still sets projectHint from app.Config.ProjectID and then resolves it for breadcrumbs. That makes chat update --room ... perform an unnecessary project lookup and can fail the update entirely if the configured project is stale/unresolvable (even though the PUT only needs chat+line IDs). Consider only using URL / explicit flag values for breadcrumb project resolution, not the config default.
				projectHint = app.Flags.Project
			}
			if projectHint == "" {
				projectHint = app.Config.ProjectID
			}

Copilot AI review requested due to automatic review settings July 22, 2026 16:00
@jeremy
jeremy force-pushed the feat/chat-update branch from 2a6bb02 to 56f28ee Compare July 22, 2026 16:00

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 56f28ee7ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread go.mod Outdated
Copilot AI review requested due to automatic review settings July 22, 2026 16:23
@jeremy
jeremy force-pushed the feat/chat-update branch from 56f28ee to beaa578 Compare July 22, 2026 16:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.

Comment thread internal/hostutil/hostutil.go Outdated
Comment thread internal/version/sdk-provenance.json
Adds 'basecamp chat update <id|url> [content]' for editing existing
campfire lines in place via PUT /chats/{c}/lines/{l}, backed by the
SDK's CampfiresService.UpdateLine.

Content handling has four explicit modes, validated before any request:
- default: Markdown converted to HTML unconditionally, then @mentions
  resolved (edits always render as rich text server-side);
- --content-type text/html: HTML supplied as-is, then @mentions resolved;
- --content-type text/plain: serialized verbatim via richtext.PlainToHTML
  (escaped, line breaks preserved as <br>), mention resolution skipped;
- any other value: rejected with a usage error.

--content-type is applied client-side only; the SDK PUT carries just the
content, and the server coerces every edit to rich text.

URL arguments route through the shared urlarg parser (which gains a
CampfireID field for the chat-line route) plus a hostutil trusted-host
gate, so a pasted card/todo URL, a boundary-evading line ID, or a
look-alike on an untrusted host is rejected rather than silently
misinterpreted; a URL whose account differs from the configured account
is refused. The 204 PUT is followed by a GetLine re-fetch so the response
carries the canonical post-update line.

Bumps the SDK to CampfiresService.UpdateLine (basecamp/basecamp-sdk#295,
merge commit 09f7b326), pinned to the merge commit pending a release tag.
Wires up the surface snapshot, catalog, e2e + smoke coverage, and the
basecamp skill documentation.
Copilot AI review requested due to automatic review settings July 22, 2026 16:31
@jeremy
jeremy force-pushed the feat/chat-update branch from beaa578 to 829c824 Compare July 22, 2026 16:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.

@jeremy
jeremy merged commit cde4cf2 into basecamp:main Jul 22, 2026
26 checks passed
@jeremy

jeremy commented Jul 22, 2026

Copy link
Copy Markdown
Member

Thanks @nnemirovsky!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands CLI command implementations deps docs enhancement New feature or request sdk SDK wrapper and provenance sdk-update-required skills Agent skills tests Tests (unit and e2e)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants