Know when feedback is actually live
Applied means a developer committed a fix. Live means that commit is running on the site. Those are different states, sometimes days apart — and the person who left the comment cares about the second one.
Applied is not live
When pointer apply --mark runs, the comment is recorded as
Applied with the commit SHA and a link to the commit. That answers
“did anyone act on my feedback?” — not “is the fix on the
site?”. The commit still has to be pushed, merged, built, and deployed before the
person who left the comment can see it.
Pointer closes that last mile by marking a comment live when a build that contains
its commit is reported. Once that happens, the comment card shows a
✓ live pill (with the deployed SHA) instead of completed,
and the person who left it knows the fix has actually shipped.
The primary path: pointer status --deployed
From inside the repository that was deployed:
npx pointer-feedback status --deployed [sha]
# sha defaults to HEAD
What it does, in order:
-
Resolves the deployed SHA with
git rev-parse(the argument you pass, orHEAD). - Fetches the project's applied-but-not-yet-deployed comments — comments with a commit SHA and no deploy date yet.
-
Computes ancestry locally: for each candidate commit,
git merge-base --is-ancestor <commitSha> <deployedSha>. -
Reports the build to
POST /api/projects/<key>/buildswith the deployed SHA and the list of contained commit SHAs. The server stamps each matching comment with its deploy date and the build that carried it.
Why the CLI owns this
- The server has no clone of your repository. “Does this build contain that commit?” is a git-ancestry question, and it can only be answered where the repository actually is. The CLI answers it locally and sends the server a plain list of SHAs — the server stays ignorant of git entirely.
- Production usually ships without the widget. The install guidance disables the widget in production builds unless you deliberately want feedback there, so the widget's automatic beacon (below) is absent exactly where “is it live yet?” matters most. The CLI works from CI or by hand, for any deployed SHA.
Reporting from CI
Run the command as the last step of your deploy pipeline, in a checkout of the repository
that was just deployed. The project and server come from the committable
.pointer/config.json; the API key comes from the environment
(POINTER_API_KEY) because .pointer/credentials.env is gitignored
and never reaches CI on its own.
# GitHub Actions deploy job
- name: Report deployed build
run: npx pointer-feedback status --deployed
env:
POINTER_API_KEY: ${{ secrets.POINTER_API_KEY }}
Other CI systems are the same shape: a step that runs after the deploy, inside the
repository checkout, with POINTER_API_KEY in the environment.
| Exit code | Meaning |
|---|---|
0 |
Build reported. Prints how many comments were marked deployed. |
1 |
The report could not be read from or sent to the server. |
2 |
The argument is not a commit in this repository, or HEAD could not be read (run it inside the deployed repository). |
3 |
No API key found (missing POINTER_API_KEY). |
The secondary path: the widget beacon
If the widget does ship to a page, it reports the page's build automatically: the
Vite plugin stamps <html
data-build-sha="…"> at build time from git rev-parse HEAD, and the
widget posts that SHA once per page load — but only when a signed-in user is present, since
the report is an authenticated call, and it is fire-and-forget: a failure is never shown to
a visitor.
The beacon has a hard limit the CLI path does not: a browser cannot compute ancestry, so
the widget can only match an exact commit. A comment is marked live by the
beacon only when the page's build SHA equals the comment's commit SHA — not when
the commit is merely contained in the build. That is why the beacon is the secondary path
and status --deployed is the primary one.
Reporting the same build twice is safe
A comment's deploy date is written once, by the first build that carried
the fix — a later build never moves it, so “when did this go live?” keeps
answering with the deploy that actually shipped it, not the most recent one. Re-running
status --deployed on a build you already reported is a no-op: the build is
not duplicated, already-deployed comments are skipped, and the server answers
firstSeen: false with an empty list of ids. A deploy step that runs on every
retry of a job costs nothing.
The HTTP endpoint, for scripting
The CLI wraps a single call. Self-hosters and other tooling can report a build directly:
POST /api/projects/<key>/builds
Content-Type: application/json
{ "sha": "<deployed sha>",
"containsCommitShas": ["<commit>", "…"] }
- SHAs are 7–40 hex characters, trimmed and lowercased. Up to 200 contained SHAs per report; one malformed entry fails the whole call rather than being silently dropped.
-
The response is
{ sha, firstSeen, deployedCommentIds }— the ids of the comments this report marked live. -
The call requires an authenticated, non-quick-access account: reporting a build is a
lifecycle action, so stakeholder quick-access accounts are refused with
403. It is rate-limited per user, well above what a real deploy pipeline needs. -
An empty
containsCommitShaslist matches the exact SHA only — that is what the widget beacon sends.