How do I add Pointer to my app?
Pointer mounts an in-browser feedback widget on your running application and connects your team's comment queue directly to your AI coding agents. This guide walks through prerequisites, the initialization command, interactive prompts, files written to disk, and non-interactive usage.
Prerequisites
- Node.js ≥ 18: Required to execute the initialization CLI.
- A Pointer account: An active account in your organization's workspace (see Workspaces).
-
An API key: Found in the Pointer web dashboard. Click your user avatar in the top navigation, navigate to Profile, scroll to the API Key section, and copy the key (prefixed with
ptr_). For details on storage and security, see API Keys.
The initialization command
Run the initialization command from the root directory of your project repository:
npx -y pointer-feedback init
Running without flags starts an interactive setup assistant that authenticates your session, links or creates a project, detects your dev server and frontend stack, configures widget embedding, and installs AI agent skills.
Walkthrough of interactive prompts
-
Pointer server URL: Defaults to
https://api.pointer.moamen.work(or the value ofPOINTER_SERVER/ existing.pointer/config.json). The CLI reaches out to the server's/api/brandingendpoint to discover the server name and product identity. -
API key prompt: You are asked to paste your API key (terminal input is hidden for security). The CLI exchanges this key with the server via
POST /api/auth/login-with-keyto verify permissions and prints your confirmed identity (e.g.✔ Signed in as Jane Developer (Developer)). You have up to 3 attempts before the command aborts. -
Project selection: The CLI retrieves your workspace's projects. You can select an existing project from the list or choose
+ Create a new project…. When creating a project, you provide a project name; the CLI suggests a slugified key matching^[a-z0-9-]+$and creates it immediately. -
Environment: Select the environment where this codebase runs (
local,staging, orproduction; defaults tolocal). -
Dev-server URL auto-detection (Step 4b): When configuring the
localenvironment, the CLI inspects your repository to detect the dev-server address:- Vite: Scans
vite.config.{js,ts,mjs,mts}forserver.portandserver.https, or checkspackage.jsondev scripts for--port. Defaults tohttp://localhost:5173. - Angular: Scans
angular.jsonunderarchitect.serve.options.portandssl, orpackage.jsonstart scripts. Defaults tohttp://localhost:4200. - Next.js: Inspects
package.jsondev scripts for-por--port, and checks.env/.env.localforPORT. Defaults tohttp://localhost:3000. - Create React App (CRA): Inspects
package.jsonstart scripts and.envforPORT. Defaults tohttp://localhost:3000.
Where does this app run in local?with the detected URL prefilled as the default. Press Enter to accept it or enter your custom URL. - Vite: Scans
-
AI tool selection: The CLI checks environment variables (such as
CLAUDECODE,ANTIGRAVITY_AGENT,TERM_PROGRAMfor Cursor,WINDSURF, orOPENCODE) and asks you to confirm your AI coding environment (claude-code,cursor,windsurf,opencode,antigravity, orother).
What the command writes to your repository
Running init creates or updates the following files in your repository:
| File path | Purpose & contents | Git status |
|---|---|---|
.pointer/config.json |
Stores project key, server URL, environment, AI tool choice, and CLI version. | Committed (safe) |
.pointer/credentials.env |
Contains your personal POINTER_API_KEY=ptr_... written with restrictive permissions (0600). |
Gitignored (never committed) |
.pointer/credentials.env.example |
Empty key template (POINTER_API_KEY=) so teammates know which variable is required. |
Committed |
.pointer/stack.json |
Recorded frontend, backend, and AI tool tokens discovered from package.json. |
Committed |
.gitignore |
Updated to ignore .pointer/ entirely while explicitly re-including safe files:
!.pointer/credentials.env.example,
!.pointer/stack.json,
!.pointer/pointer.sh, and
!.pointer/config.json.
|
Committed |
| Skills directory | Installs AI agent skills (such as pointer-init and feedback processing skills) into your editor's skills folder (e.g. .claude/skills/ or tool equivalent). |
Committed |
Deterministic widget injection & stack hand-off
How the feedback widget gets mounted into your application depends strictly on your frontend stack:
Deterministic injection (Vite & static HTML)
The CLI performs deterministic, automated widget injection for two stacks:
-
Vite: Injects an environment-guarded script snippet into
index.htmlreading from%VITE_POINTER_*%placeholders, and setsVITE_POINTER_ENABLED=true,VITE_POINTER_SERVER,VITE_POINTER_PROJECT, andVITE_POINTER_ENVin your.envfile (plus stub entries in.env.example). This prevents hard-coding production URLs into local builds. -
Static HTML: Injects the
<script src=".../pointer.js" defer></script>tag and<pointer-feedback ...>element directly before the closing</body>tag of yourindex.html(or the file passed to--html).
Hand-off for Next.js, Angular, CRA, and monorepos
Deterministic direct file injection is not supported for Next.js (App Router / Pages Router), Angular, Create React App, or monorepos because root layouts, server components, and multi-package trees vary too widely for rigid string substitution.
Instead of modifying your application code unpredictably, the CLI outputs a clear hand-off message:
ℹ <stack> detected — automatic injection isn't supported for this stack yet.
The pointer-init skill was installed for <tool>. Run it and it will mount the widget for you:
claude -> /pointer-init (or @pointer-init for cursor)
Config is already saved in .pointer/config.json, so the skill won't ask for the key or project again.
Your configuration is already stored in .pointer/config.json. You simply invoke the pointer-init skill inside your AI editor, and the agent mounts the widget safely following your framework's idioms.
Non-interactive mode (CI and automated setup)
To run init without interactive prompts (for CI pipelines, dev container provisioning, or automated setup scripts), supply --yes (or -y). When --yes is used, --key is mandatory, and you must supply either --project <key> or --create <name>.
npx -y pointer-feedback init \
--yes \
--server https://api.pointer.moamen.work \
--key "$POINTER_API_KEY" \
--project my-web-app \
--environment local \
--tool claude-code
Adding --json outputs structured JSON containing setup details and automatically implies --yes.
CLI flags reference
| Flag | Description |
|---|---|
--server <url> |
Pointer server URL (defaults to https://api.pointer.moamen.work). |
--key <key> |
Your Pointer API key (ptr_...). Required when running with --yes. |
--project <key> |
The project key to connect this codebase to. |
--create <name> |
Creates a new project with the given name instead of linking an existing one. |
--environment <env> |
Target environment (local, staging, or production; default: local). |
--tool <tool> |
AI tool to install skills for (claude-code, cursor, windsurf, opencode, antigravity, other). |
--skills-dir <path> |
Custom target directory for AI agent skills. |
--app-url <url> |
Explicit dev-server URL (e.g. http://localhost:3000), bypassing detection prompts. |
--no-app-url |
Skips assigning an application URL for the environment. |
--html <path> |
Path to the target HTML file for static injection (defaults to index.html). |
--no-inject |
Skips widget script injection into HTML/env files entirely. |
--no-skills |
Skips installing AI agent skills. |
-y, --yes |
Non-interactive mode. Fails immediately if required inputs are missing. |
--json |
Outputs results in JSON format and suppresses interactive prompts (implies --yes). |
-h, --help |
Displays usage documentation and flag summaries. |
Exit codes
| Code | Status | Meaning & typical trigger |
|---|---|---|
0 |
Success | Setup completed successfully; config and skills written to disk. |
1 |
General Error | Server unreachable, project key conflict, or unhandled runtime failure. |
2 |
Invalid Usage | Unknown command, invalid flag, or missing required flag (e.g. --key omitted with --yes). |
3 |
Auth Failure | Invalid or revoked API key, or the authenticated account lacks project creation permissions. |
Keeping the AI skills up to date
init copies the AI skills and pointer.sh into your repository, where they
stay exactly as they were on the day you installed them. The server keeps changing. A skill file
installed months ago is frozen prose describing an API that has moved on — and nothing about it
looks wrong, which is what makes it expensive.
Every served skill and script carries a version stamp, so your installed copy can be compared with the server’s:
npx -y pointer-feedback doctorreports astalewarning naming each file that is behind.npx -y pointer-feedback update --checklists what would change and writes nothing.npx -y pointer-feedback updaterefreshes them in place, preserving the.agents/symlinks.
A stale skill is a warning, never an error — it still works, it is just behind. Nothing updates silently: refreshing is always something you ask for.
Self-hosting: the stamp defaults to the API’s build version, so every deploy moves it. Set
Pointer__SkillVersion to invalidate installed copies after editing skill prose without
shipping new code.
Troubleshooting & common pitfalls
- Invalid API key (Exit 3): Verify that the API key was copied completely from your profile page and has not been regenerated. If you regenerated your key in the web dashboard, the previous key was revoked immediately.
- This account cannot create projects (Exit 3): Stakeholder or client accounts are scoped to viewing comments and cannot mint new projects. An organization owner or administrator must create the project or invite you with developer privileges.
-
Key already exists, choose another: Project keys must be unique within your organization. Provide a distinct slug or attach to the existing project with
--project <key>. - Comments blocked after deploy: If you enable origin enforcement on your project, ensure the deployed origin matches your configured environment URL. See Project Settings.
The pointer doctor diagnostic command is currently stubbed and will be expanded in an upcoming release. Direct deterministic widget injection for SSR and monorepo frameworks is intentionally delegated to the AI editor skill (pointer-init) rather than hardcoded in the CLI.