Skip to content

fix(cli): stable conversation-id resolution across chats runs - #28

Open
sinjab wants to merge 1 commit into
mingnz:mainfrom
sinjab:fix/stable-conversation-id-resolution
Open

sinjab wants to merge 1 commit into
mingnz:mainfrom
sinjab:fix/stable-conversation-id-resolution

Conversation

@sinjab

@sinjab sinjab commented Oct 10, 2026

Copy link
Copy Markdown

Problem

chats re-derives short IDs on every run (assignShortIds picks the shortest unique suffix per run), so a short ID captured earlier β€” in a script, a shell history, or an earlier command in the same session β€” can stop resolving with a bare Short ID '…' not found, even though the conversation is right there in the index.

Two aggravations in the same path:

  • the conversations API returns duplicate rows for the same thread (different letter-prefixed display rows), so even a valid suffix can look ambiguous when the matches all point at one thread;
  • conversely, in 1:1 threads every conversation ID embeds the current user's org GUID as its tail, so tails of that GUID match every 1:1 chat and must be reported as ambiguous, not silently picked.

Change

resolveConversationId now:

  1. dedupes candidate matches by full conversation ID before counting them;
  2. falls back to unique-suffix matching (β‰₯ 4 chars, the same minimum chats uses) against both the assigned short ID and the conversation-ID body β€” stale short IDs and id tails still resolve;
  3. on a genuinely ambiguous suffix, lists the matching conversations and exits instead of picking one;
  4. still passes full IDs (containing :) through untouched.

The function is exported and accepts an injectable chat index (resolveConversationId(id, chats?)) for testing β€” no fs mocking needed.

Tests

9 new unit tests in tests/resolve-conversation-id.test.ts: passthrough, exact match, duplicate-rows dedupe, stale-short-id suffix fallback, shared-thread suffix, id-body suffix, ambiguous listing, miss exit, and the <4-char guard. 102 total, all green; biome check and tsup build clean.

Independent of #27 (touches a different region of cli.ts).

Short IDs are re-derived on every `chats` run, so a short ID captured
earlier (in a script, a note, or an earlier command) can stop resolving
with a bare 'Short ID not found'.

resolveConversationId now:
- dedupes the chat index by full conversation ID before matching (the
  conversations API returns duplicate rows for the same thread),
- falls back to unique-suffix matching (>= 4 characters, the same
  minimum `chats` uses) against both the short ID and the
  conversation-ID body, so stale short IDs and id tails still resolve,
- lists the matching conversations and exits when a suffix is
  ambiguous (e.g. the current user's org-id tail is shared by every
  1:1 thread).

The resolver is exported and takes an injectable chat index for
testing; covered by 9 new unit tests.
@sinjab

sinjab commented Oct 15, 2026

Copy link
Copy Markdown
Author

Friendly ping β€” happy to rebase this onto current main if anything has drifted. I'm also sending a few follow-up PRs (#30–#32: --json output, HTML send, file attachments) built on this line of work; no rush, just letting you know they're coming.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants