feat(cli): add feedback command for quick CLI feedback submission - #5988
feat(cli): add feedback command for quick CLI feedback submission#5988kanadgupta wants to merge 11 commits into
Conversation
The vendored effect clone in .repos/ drowns out workspace results in editor-wide search. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This reverts commit 8c53f2e.
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>
There was a problem hiding this comment.
💡 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".
| const { exitCode, stdout } = await runSupabase( | ||
| [ | ||
| "btw", | ||
| "cli-e2e golden path (feedback.e2e.test.ts)", | ||
| "--profile", | ||
| "supabase-staging", |
There was a problem hiding this comment.
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 👍 / 👎.
| const output = yield* Output; | ||
| if (output.interactive) { | ||
| const typed = yield* output.promptText("What's on your mind?", { |
There was a problem hiding this comment.
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 👍 / 👎.
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@830e565f2a1760aa99018a864a7c5d6c4e020c88Preview package for commit |
There was a problem hiding this comment.
💡 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!"); |
There was a problem hiding this comment.
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 👍 / 👎.
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
--sentinel.interfaces_feedbacktable (feat: table for collecting interfaces feedback supabase#48420) viasupabase-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.is_agent/agent_namevia@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.SUPABASE_PROJECT_ID→<workdir>/supabase/.temp/project-ref(the filesupabase linkwrites) →null. This mirrors the soft-load half ofLegacyProjectRefResolver.resolveOptional, but reads the file directly rather than going through the resolver, which requiresLegacyPlatformApiFactoryfor 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.--output-formatmodes are supported; the e2e golden path pins--profile supabase-stagingso 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, whichextractChangedFlagNamesstructurally excludes from theflagstelemetry property. There is a regression test asserting the message content never appears in captured analytics events.Reviewer-relevant context
src/shared/feedback/database.types.tsis generated (supabase gen types) and excluded from formatting/knip; the new.prettierignoreexists because oxfmt reads it by default.functions download/deleteprecedent of exporting the wrapped handler for integration tests, and theissuecommand's precedent for TS-only command wiring (no Go-parity telemetry flush).feedback.command.ts, merged the connection constants intofeedback-submitter.layer.ts, and hoisted the duplicatedmockContextualAnalyticstest helper intotests/helpers/mocks.ts(updating the three pre-existing copies per the hoist-before-you-duplicate rule).LegacyCliConfig.projectId: it is a bareSUPABASE_PROJECT_IDenv passthrough — it does not readconfig.tomlor the linked-project file, so it isNonein a linked project unless that env var is set. An earlier revision of this branch used it directly as "the linked project ref", which meantproject_refwas alwaysnullin practice. TheAGENTS.mdrow that described it as resolving project-id fromconfig.tomlis corrected here, since that phrasing is what made the field look project-aware.services.integration.test.tsnow uses an isolated temp workdir instead ofprocess.cwd(), fixing machine-dependent behavior when the developer has localsupabase startstate.🤖 Generated with Claude Code