Skip to content

feat: [AI-8138] /datamates picker + onboarding banner - #1051

Closed
ralphstodomingo wants to merge 3 commits into
mainfrom
feat/AI-8138-datamates-picker
Closed

feat: [AI-8138] /datamates picker + onboarding banner#1051
ralphstodomingo wants to merge 3 commits into
mainfrom
feat/AI-8138-datamates-picker

Conversation

@ralphstodomingo

@ralphstodomingo ralphstodomingo commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Issue for this PR

No GitHub issue — internal ticket AI-8138 (epic AI-7523, datamates integration).

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds the first human-facing surface for datamates in the CLI:

  • /datamates palette command — a read-only picker listing the tenant's datamates (name, description, integrations) with an active-datamate ✓ marker. Selecting one wires the datamate MCP server; its tools appear with the Altimate badge. No create/edit/delete.
  • Onboarding banner — dismissable home-screen box promoting /datamates (KV key dismissed_datamates_banner, keyboard-dismissable via a palette command, auto-hidden once any datamate server is connected).

Why it's shaped this way: the TUI plugin thread has no Instance/MCP runtime (the server runs in a Worker), so the picker cannot wire MCP in-process. The wiring core is extracted out of the datamate_manager tool's add operation into connectDatamate(), and a new fork endpoint POST /altimate/datamate/connect (same precedent as reload-datamate) lets both surfaces share it exactly — IDE-gateway detection, reconnect-vs-add, MCP.connect so enabled-state persists, stale-entry reporting. The LLM tool's outputs are unchanged. datamate-config.ts holds config-only reads safe on the TUI thread; a guard test asserts the picker never imports the server-only module.

Known limitation (deliberate): in IDE-gateway mode a single datamate server serves every datamate, so no per-datamate ✓ is derivable from config — the dialog titles itself "(via extension gateway)". Cross-surface selection sync is a follow-up on the epic.

How did you verify your code works?

  • Typecheck clean; fork-feature-guard + datamate + TUI plugin-lifecycle tests pass (77/77). Wider-sweep failures reproduced identically at the base commit (pre-existing, unrelated).
  • Live TUI pass (tmux-driven) caught and fixed two defects: the loading-state dialog swap re-created the resource in a refetch loop, and the banner let a stale failed datamate entry suppress it. Both fixed in the second commit; picker, ✓ marker, and banner verified visually (screenshots below).
  • End-to-end against the hosted multi-tenant endpoint: POST /altimate/datamate/connect with a real datamate id → status: connected, 11 tools, correct remote entry (URL + 4 auth headers) written to the project's .altimate-code/altimate-code.json, and readWiredDatamates resolves the active id for the picker's ✓.

Screenshots / recordings

Headless TUI captures (tmux) from the verified flow:

Onboarding banner on home (shown when no datamate is connected; a stale failed entry no longer suppresses it)
banner

/datamates picker — tenant datamates with integration footers
picker

Reopened after connecting — active datamate carries the ✓, cursor lands on it
active

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🤖 Generated with Claude Code

- `/datamates` TUI palette command: read-only picker listing the tenant's
  datamates with an active marker; selecting one wires the datamate MCP
  server via the shared connect core
- extract `connectDatamate()` from the `datamate_manager` tool's `add`
  operation; the tool is now a thin formatter over it (behavior unchanged)
- new fork endpoint `POST /altimate/datamate/connect` — the TUI thread has
  no `Instance`/`MCP` runtime (server runs in a Worker), so the picker
  connects through the local server, same as the existing fork endpoints
- `datamate-config.ts`: config-only reads (`readWiredDatamates`) safe to
  import on the TUI thread; guard test asserts the picker never imports
  the server-only module
- dismissable home-screen banner promoting `/datamates` (KV-backed,
  keyboard-dismissable via palette command, hidden once a datamate server
  is connected)
- fork-feature-guard entries for registration, palette names, endpoint,
  and KV key

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ralphstodomingo ralphstodomingo self-assigned this Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 293a7f5c-850a-4dca-8d7b-554b19cbbd0a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Thanks for updating your PR! It now meets our contributing guidelines. 👍

ralphstodomingo and others added 2 commits July 30, 2026 13:04
…servers

Live TUI testing surfaced two defects:

- Swapping the top-level dialog component (DialogAlert fallback while
  loading) re-mounts the dialog factory, which re-creates the resource and
  refetches in a ~200ms loop, so the picker never left "Loading". Render a
  single DialogSelect for every state instead, with status states as
  sentinel rows — same device as the skills dialog's synthetic install row.
- The banner suppressed itself when any datamate MCP server existed,
  including a stale entry with status "failed" — the exact situation the
  picker fixes. Only a connected datamate server now hides the banner.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A stale `datamate` key neutralized with `enabled: false` was still
flipping the picker into gateway mode ("via extension gateway" title,
all rows checked). Skip disabled entries when computing wired state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ralphstodomingo

Copy link
Copy Markdown
Contributor Author

Closing for now — the demo was delivered on 2026-07-30, but the approach hasn't been cleared: product is revisiting datamates positioning in altimate-code (first-class citizen vs a more generic IDE↔SaaS bridge, and the intended user experience/value prop). The branch stays; this reopens if the current direction is confirmed. Status tracked on the internal ticket.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant