Skip to content

feat(cli): add feedback command for quick CLI feedback submission - #5988

Open
kanadgupta wants to merge 11 commits into
developfrom
kanad-claude-2026-07-22/feedback-command
Open

feat(cli): add feedback command for quick CLI feedback submission#5988
kanadgupta wants to merge 11 commits into
developfrom
kanad-claude-2026-07-22/feedback-command

Conversation

@kanadgupta

@kanadgupta kanadgupta commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

Adds a TS-only supabase feedback [message...] command (alias: supabase btw, from the original brainstorm) to the legacy shell so users — and agents — can send quick, low-friction feedback to the Supabase team without filing a GitHub issue.

supabase btw "when I run multiple stacks in parallel I get port conflicts"

Part of CLI-1946.

How it works

  • Message resolution: positional args → piped stdin (non-TTY) → interactive prompt (TTY, text mode) → error. Messages starting with a dash use the -- sentinel.
  • Transport: fire-and-forget PostgREST insert into the new interfaces_feedback table (feat: table for collecting interfaces feedback supabase#48420) via supabase-js, mirroring how the docs feedback widget submits. The committed key is a publishable (anon) key and writes are gated by insert-only RLS, so it is safe to ship in the binary. 10s timeout.
  • Submission context: CLI version, user agent, OS/arch, agent detection (is_agent/agent_name via @vercel/detect-agent, to support the activation analysis in AI-961), and the linked project ref. source: "cli" distinguishes CLI rows from the future MCP path. The access token is never sent.
  • Project ref resolution: SUPABASE_PROJECT_ID<workdir>/supabase/.temp/project-ref (the file supabase link writes) → null. This mirrors the soft-load half of LegacyProjectRefResolver.resolveOptional, but reads the file directly rather than going through the resolver, which requires LegacyPlatformApiFactory for its prompt path — feedback must keep working when the user is not logged in. A broken ref file degrades to "unlinked" rather than failing the submission.
  • Environments: the feedback backend follows the resolved profile the same way the Management API URL does (staging profiles → staging project). Production intentionally reuses the staging project until a dedicated one is provisioned (tracked in CLI-1998).
  • All three --output-format modes are supported; the e2e golden path pins --profile supabase-staging so test rows never land in production once it exists.

Privacy note for reviewers

The feedback message itself goes only to interfaces_feedback — never to PostHog. It is a positional argument, which extractChangedFlagNames structurally excludes from the flags telemetry property. There is a regression test asserting the message content never appears in captured analytics events.

Reviewer-relevant context

  • src/shared/feedback/database.types.ts is generated (supabase gen types) and excluded from formatting/knip; the new .prettierignore exists because oxfmt reads it by default.
  • Follows the functions download/delete precedent of exporting the wrapped handler for integration tests, and the issue command's precedent for TS-only command wiring (no Go-parity telemetry flush).
  • A follow-up DRY pass consolidated the profile→environment mapping into feedback.command.ts, merged the connection constants into feedback-submitter.layer.ts, and hoisted the duplicated mockContextualAnalytics test helper into tests/helpers/mocks.ts (updating the three pre-existing copies per the hoist-before-you-duplicate rule).
  • Heads-up on LegacyCliConfig.projectId: it is a bare SUPABASE_PROJECT_ID env passthrough — it does not read config.toml or the linked-project file, so it is None in a linked project unless that env var is set. An earlier revision of this branch used it directly as "the linked project ref", which meant project_ref was always null in practice. The AGENTS.md row that described it as resolving project-id from config.toml is corrected here, since that phrasing is what made the field look project-aware.
  • services.integration.test.ts now uses an isolated temp workdir instead of process.cwd(), fixing machine-dependent behavior when the developer has local supabase start state.

🤖 Generated with Claude Code

kanadgupta and others added 10 commits July 28, 2026 08:17
The vendored effect clone in .repos/ drowns out workspace results in
editor-wide search.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LegacyCliConfig.projectId is a bare SUPABASE_PROJECT_ID env passthrough, so
the feedback submission's project_ref was null in a linked project unless
that env var happened to be set. Fall back to <workdir>/supabase/.temp/
project-ref, the file supabase link writes, mirroring the soft-load half of
LegacyProjectRefResolver.resolveOptional. The file is read directly rather
than through the resolver so the command keeps working unauthenticated; a
broken ref file degrades to unlinked instead of failing the submission.

The previous integration test injected projectId straight into the config
mock, so it only proved the handler forwarded the field and never exercised
resolution -- despite being named for the workdir-linked scenario that did
not work. Replace it with coverage that seeds the real file, plus env
precedence, unlinked, and unreadable-file cases.

Also correct the AGENTS.md row claiming LegacyCliConfig reads project-id
from config.toml, which is what made this field look project-aware.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kanadgupta
kanadgupta marked this pull request as ready for review July 29, 2026 05:25
@kanadgupta
kanadgupta requested a review from a team as a code owner July 29, 2026 05:25
@kanadgupta
kanadgupta requested review from gregnr and mattrossman July 29, 2026 05:28

@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: 656f13a667

ℹ️ 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 on lines +18 to +23
const { exitCode, stdout } = await runSupabase(
[
"btw",
"cli-e2e golden path (feedback.e2e.test.ts)",
"--profile",
"supabase-staging",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Gate the real feedback submission as a live test

This unconditional e2e invocation posts a persistent row to the real staging project, so the default test:e2e target now depends on external network/backend availability and pollutes staging on every run. Move this coverage to a gated *.live.test.ts suite, or replace the transport with a local boundary; repository guidance explicitly reserves real-backend subprocess tests for the gated live project.

AGENTS.md reference: apps/cli/AGENTS.md:L414-L417

Useful? React with 👍 / 👎.

Comment on lines +33 to +35
const output = yield* Output;
if (output.interactive) {
const typed = yield* output.promptText("What's on your mind?", {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require a TTY before opening the feedback prompt

When stdin is non-TTY and its piped content is empty or whitespace while stdout remains a terminal—for example, printf ' ' | supabase feedback—the pipe read falls through but output.interactive is still true because the text output layer derives it from stdout. This then opens a Clack prompt against an exhausted non-TTY stdin instead of returning LegacyFeedbackEmptyMessageError, potentially cancelling, failing, or hanging rather than producing the documented exit code 1; require stdin.isTTY before prompting.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@830e565f2a1760aa99018a864a7c5d6c4e020c88

Preview package for commit 830e565.

@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: 830e565f2a

ℹ️ 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".

.pipe(Effect.tapError(() => sending.fail()));

yield* sending.clear();
yield* output.success("Thanks for the feedback!");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor the legacy machine-output flag

When this command is invoked as supabase feedback "message" -o json (or with yaml, toml, or env), legacy/cli/root.ts selects legacyQuietProgressTextOutputLayer, whose format remains text; this unconditional output.success therefore writes a human-readable Clack success line instead of the requested machine payload. Handle LegacyOutputFlag with the corresponding encoder before this call, or reject unsupported formats, so scripts do not receive unparsable stdout.

AGENTS.md reference: apps/cli/AGENTS.md:L390-L392

Useful? React with 👍 / 👎.

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.

1 participant