# Agent Rules ## Package Manager Use `pnpm` for all package management commands (not npm or yarn). Exception: End-user install instructions should use `npm install -g` (global) or `npm install -D` (project dev dependency) since npm is universal. ## Dependencies Always check for the latest npm version when adding dependencies. Use `pnpm add ` (without version) to get the latest, or verify with `npm view version` first. ## No Emojis Do not use emojis anywhere in this repository (code, comments, output, docs). ## Dashes Never use `--` or em dashes as dashes in prose, comments, or user-facing output. Rephrase the sentence instead. The only exception is CLI flags (e.g. `--port`). ## Boolean Environment Variables Document boolean env vars using only `0` and `1` in CLI help, SKILL.md, docs pages, and README. Code accepts `true`/`false` as well (and `skip` for `PORTLESS`), but these alternatives are not documented. ## Docs Updates When a change affects how humans or agents use portless (new/changed/removed commands, flags, behavior, or config), update all of these: 1. `README.md` (user-facing documentation) 2. `skills/portless/SKILL.md` (agent skill for using portless) 3. `packages/portless/src/cli.ts` (`--help` output) 4. `packages/portless/src/mcp.ts` (MCP tools and `portless mcp --help` output) Use the `technical-writer` skill (`.agents/skills/technical-writer/SKILL.md`) when you write or edit prose for this repo, including docs pages, READMEs, changelog entries, commit messages, PR descriptions, and issues. ## MCP Tools Any change to a CLI command, flag, output, or environment variable must update the MCP tools in `packages/portless/src/mcp.ts` in the same change. `mcp.test.ts` reads `portless --help` and each tool command's `--help`, and fails when a command or flag is neither handled by a tool nor listed as omitted. ## Releasing Releases are manual, single-PR affairs. The maintainer controls the changelog voice and format. To prepare a release: 1. Create a branch (e.g. `prepare-v1.2.0`) 2. Bump the version in `packages/portless/package.json` 3. Write the changelog entry in `CHANGELOG.md`, wrapped in `` and `` markers 4. Remove the `` and `` markers from the previous release entry (only the latest release should have markers) 5. Add a matching entry to `apps/docs/content/docs/changelog.mdx` 6. Open a PR and merge to `main` CI compares the version in `packages/portless/package.json` to what's on npm. If it differs, it builds, publishes, and creates the GitHub release automatically. The release body is extracted from the content between the markers. ## Windows Debugging A remote Windows Server 2022 EC2 instance is available for debugging Windows-specific issues. It uses AWS Systems Manager (SSM) with no SSH or open ports. Commands run via `aws ssm send-command` and return stdout/stderr. All scripts require `AWS_PROFILE=portless-debug` (or the profile must be set as default). Prefix every command with it or export it for the session: ```bash export AWS_PROFILE=portless-debug ``` ### Prerequisites The instance must be provisioned first (one-time, by a human): ```bash ./scripts/windows-debug/provision.sh ``` Requires: AWS CLI v2 configured with `ec2:*`, `iam:CreateRole`, `iam:AttachRolePolicy`, `ssm:SendCommand`, `ssm:GetCommandInvocation` permissions and a default VPC. ### Usage Start the instance (if stopped): ```bash ./scripts/windows-debug/start.sh ``` Run a command on Windows: ```bash ./scripts/windows-debug/run.sh "" ``` Sync the current git branch and rebuild: ```bash ./scripts/windows-debug/sync.sh ``` Stop the instance when done (avoids cost): ```bash ./scripts/windows-debug/stop.sh ``` ### Important notes **SSM agent takes a long time to come online.** After starting or restarting the instance, the SSM agent can take 5 to 10 minutes before it accepts commands. If `run.sh` returns `InvalidInstanceId`, wait and retry. Do not assume the instance is broken; poll with increasing intervals. **PowerShell uses `;` not `&&`.** The `run.sh` wrapper executes PowerShell, which does not support `&&` as a command separator. Use `;` instead: ```bash ./scripts/windows-debug/run.sh "cd C:\portless; pnpm test" ``` **OpenSSL may not be at the expected path.** The bootstrap installs OpenSSL to `C:\Program Files\OpenSSL-Win64\bin`, but this can fail silently. Git bundles its own OpenSSL at `C:\Program Files\Git\mingw64\bin`. If `openssl` is not found, add Git's path: ```bash ./scripts/windows-debug/run.sh '$env:PATH = "C:\Program Files\Git\mingw64\bin;$env:PATH"; openssl version' ``` **SSM runs as SYSTEM.** Commands execute as the SYSTEM account, not a normal user. This affects user-specific operations (e.g., `certutil -addstore -user Root` targets SYSTEM's trust store, not a real user's). Keep this in mind when testing user-facing features. ### Common Workflows Run unit tests on Windows: ```bash ./scripts/windows-debug/run.sh "cd C:\portless; pnpm test" ``` Run e2e tests on Windows: ```bash ./scripts/windows-debug/run.sh "cd C:\portless; pnpm test:e2e" ``` Check bootstrap progress (first boot only): ```bash ./scripts/windows-debug/run.sh "Get-Content C:\bootstrap.log" ``` The repo lives at `C:\portless` on the instance. Node.js 24, pnpm 11, Git, and OpenSSL are pre-installed. The `run.sh` wrapper automatically adds these tools to PATH. ## Source Code Reference Source code for dependencies is available in `opensrc/` for deeper understanding of implementation details. See `opensrc/sources.json` for the list of available packages and their versions. Use this source code when you need to understand how a package works internally, not just its types/interface. ### Fetching Additional Source Code To fetch source code for a package or repository you need to understand, run: ```bash npx opensrc # npm package (e.g., npx opensrc zod) npx opensrc pypi: # Python package (e.g., npx opensrc pypi:requests) npx opensrc crates: # Rust crate (e.g., npx opensrc crates:serde) npx opensrc / # GitHub repo (e.g., npx opensrc vercel/ai) ```