init reference
The init journey, the files it writes, sharing, embed/remove/status/open, CI mode, flags and exit codes.
The initialization command
Run the initialization command from the root directory of your project repository:
npx -y @pinsay/cli@latest init
Prefer short commands? Install once with npm i -g @pinsay/cli and every
npx @pinsay/cli <command> on this page becomes just pinsay <command>.
Running without flags starts an interactive setup assistant that authenticates your session, links or creates a project, detects your AI tool, sets the repo up for the Chrome extension (or embeds the widget with --embed), and installs AI agent skills.
Walkthrough of interactive prompts
Running init guides you through a streamlined setup that asks only what cannot be determined automatically:
-
Header line: The CLI greets you with
PinSay setup · <folder name>. -
Sign in: If you do not have an active session, the CLI opens your browser immediately to approve sign-in (or paste an API key with hidden input if using
--keywithout a value). Once approved, the key is saved automatically. -
Project selection: The CLI fetches your workspace's projects. Workspace admins can choose an existing project or select
+ Create a new project…(with an auto-suggested slugified key). Workspace members pick from existing projects. Quick-access accounts cannot connect repositories and are instructed to sign in with a full account. -
AI tool selection: The CLI automatically detects AI coding tools from repository markers (e.g.
.claude/,CLAUDE.md,.cursor/,.windsurf/,.opencode/,.gemini/). If exactly one tool is detected, it is used automatically without prompting. If none or several are detected, an interactive selection prompt lets you choose or toggle them. -
Share framework names?: Before writing any changes, the CLI asks for your consent:
Pressing Enter or y chooses Yes; pressing n chooses No with a single keypress.? Share your project's framework names with PinSay? (Y/n) Only names like react, vite, dotnet and your AI tool, plus a "setup done" signal. Never your code or your files. -
The plan and confirm: The CLI prints a concise plan summarizing the project, account and key storage location, widget delivery (Chrome extension by default), skills, files to be created, and what will be shared. It then asks:
Nothing is written or sent until you confirm with Enter or y. Pressing n cancels immediately without touching any files.? Go ahead? (Y/n) -
Progress & quick check: A single in-place progress line executes setup in seconds. The quick check runs silently at the end and only prints warnings or errors if any check fails; otherwise it confirms:
✔ Everything checks out. -
One next step: The setup finishes with a single highlighted
Next:line pointing you to the next action (such as opening the Chrome Web Store extension link).
What the command writes to your repository
Running init writes the following files and hides all of them from git: with the Chrome extension path git status stays clean; embedding with --embed adds the widget edit to git status.
| File path | Purpose & contents | Git status |
|---|---|---|
.pinsay/config.json |
Stores project key, AI tool choice, delivery, and CLI version. | Hidden (commit with git add -f to share with your team) |
.pinsay/credentials.env |
Contains your personal PINSAY_API_KEY=pnsy_... by default, written with restrictive permissions (0600). |
Hidden (never commit it) |
.pinsay/stack.json |
Recorded frontend, backend, and AI tool tokens discovered from package.json. Remains local to your machine. |
Hidden (commit with git add -f to share with your team) |
.git/info/exclude |
Your clone's own ignore list, never committed. PinSay keeps a marked block there that hides .pinsay/ and the skill files. Your .gitignore is not touched. |
Never committed |
.pinsay/.gitignore |
Ignores the .pinsay/ folder and itself. |
Hidden |
| Skills directory | Installs AI agent skills (such as pinsay-init and feedback processing skills) into your editor's skills folder (e.g. .claude/skills/ or tool equivalent). |
Hidden |
Widget delivery: Chrome extension by default, embed when wanted
By default, npx @pinsay/cli init sets up your repository for the PinSay Chrome extension: reviewers inspect and comment on any page without changing your application code, recording "delivery": "extension" in .pinsay/config.json.
If you want the widget script and element embedded directly into your application source, run:
npx @pinsay/cli embed
You can also initialize and embed in one step by running npx @pinsay/cli init --embed.
Deterministic embedding (Vite & static HTML)
When running embed (or init --embed), the CLI performs automated, idempotent widget injection for supported stacks:
-
Vite: Injects a guarded script snippet into
index.htmlreading from%VITE_PINSAY_*%placeholders, and setsVITE_PINSAY_SERVERandVITE_PINSAY_PROJECTin your.env.development/.env.localfiles (plus empty stubs in.env.example). Re-runningembedreplaces the block cleanly rather than duplicating it. -
Static HTML: Injects the
<script src=".../widget.js" defer></script>tag and<pinsay-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
For frameworks with custom root layouts (Next.js App/Pages Router, Angular, Create React App, monorepos), direct string injection is not automated. Instead, running embed prompts you to hand off to your AI tool:
Next: in claude-code, run /pinsay-init to add the widget.
Your configuration is already stored in .pinsay/config.json. Your AI agent safely mounts the widget following your framework's native patterns and component lifecycle.
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, an API key is required (--key, PINSAY_API_KEY, or an already-saved key), and you should specify --project <key> (or --create <name> for admins).
npx -y @pinsay/cli@latest init \
--yes \
--key "$PINSAY_API_KEY" \
--project my-web-app \
--tool claude-code
Sharing in CI mode: Without a terminal, stack sharing defaults to Yes (sharing framework names and the AI tool). If you want to share nothing about your project other than the bare "setup done" signal, pass --no-share-stack.
Adding --json outputs structured JSON containing setup details and automatically implies --yes.
CLI flags reference
| Flag | Description |
|---|---|
--embed |
Embeds the feedback widget directly into application HTML and development configuration. |
--share-stack |
Consents to sharing detected framework names, AI tool name, and usage events with PinSay. |
--no-share-stack |
Declines sharing framework names, AI tool name, or usage events (sends only a bare "setup done" signal). |
--dry-run |
Simulates the initialization, displays the planned actions, and exits without writing files, opening browsers, or sending network mutations. |
--no-color |
Disables terminal ANSI colors and formatting escapes. |
--key <key> |
Your PinSay API key (pnsy_...). If passed without a value interactively, prompts with hidden input. |
--project <key> |
The project key to connect this codebase to. |
--create <name> |
Creates a new project with the given name (admin only). |
--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. |
--html <path> |
Path to the target HTML file for static injection (defaults to index.html; implies --embed). |
--pin |
Pins the widget to the current server build with SRI hash verification (implies --embed). |
--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. |
--delivery <mode> |
(Old, still accepted) extension (default) or embed. |
--no-inject |
(Old, still accepted) Default behavior; no code modified unless --embed is requested. |
--scope <scope> |
(Old, still accepted) repo, the only location. |
--local-credentials |
(Old, still accepted) Default behavior; credentials stored in repo file. |
Exit codes
| Code | Status | Meaning & typical trigger |
|---|---|---|
0 |
Success | Setup completed successfully; config and skills written to disk. |
1 |
General Error | Unexpected runtime failure or internal error. |
2 |
Invalid Usage | Unknown command, invalid flag, paused workspace (HTTP 423), or missing required configuration. |
3 |
Auth Failure | Invalid or revoked API key, or the authenticated account lacks project permissions (e.g. quick-access account). |
4 |
Network / Server | Can't reach PinSay (offline, DNS/timeout failure, or server trouble HTTP 5xx). |
Embedding the widget: embed
The embed command adds the feedback widget directly to your application without re-running full project setup:
npx @pinsay/cli embed [--html <file>] [--pin] [--path <app>] [--project <key>] [--dry-run] [--yes] [--json]
It reads the project from .pinsay/config.json (or --project) and requires no sign-in. It shows the files it will change and asks Go ahead? first (--yes skips). For Vite or static HTML, it updates the files directly and records delivery: "embed" in config. For other stacks, it provides instructions to run /pinsay-init with your AI agent.
Removing PinSay from a repo: remove
To completely remove PinSay configuration, skill files, and embedded code from the current repository:
npx @pinsay/cli remove [--dry-run] [--yes] [--json]
remove deletes the .pinsay/ directory, installed PinSay skill files, exclude blocks from .git/info/exclude, and injected widget snippets from HTML and development env files. It prompts for confirmation with default No (use --yes in automated environments). It works offline and does not affect comments on the server.
Checking status: status
Running status with no arguments displays a fast overview of your authenticated session, the connected project, and pending comments:
npx @pinsay/cli status
Example output:
Signed in Jane Doe (jane@example.com) · key from this repo
Project My App (my-app)
Pending 3 comments to apply → npx @pinsay/cli apply
(Note: status <number> <state> and status --deployed [sha] for managing comment statuses and CI deployment markers.)
Opening the dashboard: open
Jump directly to your project's comments in the PinSay web dashboard:
npx @pinsay/cli open [--project <key>] [--print]
open launches your system's default browser directly to <dashboard URL>/comments?project=<key> without requiring network roundtrips. Pass --print to output the target URL without launching a browser.
Managing credentials: login & logout
Credentials live in the repository only. Run npx @pinsay/cli login inside each repository to sign in for it, and npx @pinsay/cli logout to remove its key. A machine-wide key saved by an older version is deleted by npx @pinsay/cli update.
Keeping the AI skills up to date
init copies the AI skills 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 @pinsay/cli@latest doctorreports astalewarning naming each file that is behind.npx -y @pinsay/cli@latest update --checklists what would change and writes nothing.npx -y @pinsay/cli@latest 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
PinSay__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.