Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ jobs:
- name: Typecheck
run: npm run typecheck

- name: Lint
run: npm run lint

- name: Format check
run: npm run format:check

- name: Build
run: npm run build

Expand Down
108 changes: 108 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: Release

# Push a version tag (e.g. v0.4.2) to cut a release. This builds, runs the full
# quality gate, verify-packs the tarball, then creates the GitHub release and
# uploads the .tgz asset that `plane upgrade` and the install URL depend on.
on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install
run: npm install

- name: Verify tag matches package.json version
id: version
run: |
PKG_VERSION="$(node -p "require('./package.json').version")"
TAG_VERSION="${GITHUB_REF_NAME#v}"
echo "Tag: $TAG_VERSION package.json: $PKG_VERSION"
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
echo "::error::Tag $GITHUB_REF_NAME does not match package.json version $PKG_VERSION. Bump package.json before tagging."
exit 1
fi
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"

- name: Typecheck
run: npm run typecheck

- name: Lint
run: npm run lint

- name: Format check
run: npm run format:check

- name: Build
run: npm run build

- name: Test
run: npm run test

- name: Verify pack (install tarball and smoke-test)
run: npm run verify-pack

- name: Pack release tarball
run: npm pack

- name: Extract changelog section
run: |
VERSION="${{ steps.version.outputs.version }}"
awk -v ver="## $VERSION" '
$0 == ver {flag=1; next}
/^## / && flag {flag=0}
flag {print}
' CHANGELOG.md > RELEASE_NOTES.md
if [ ! -s RELEASE_NOTES.md ]; then
echo "No changelog section found for $VERSION." > RELEASE_NOTES.md
fi
{
echo ""
echo "## Install / upgrade"
echo ""
echo '```'
echo "npm install -g https://github.com/${GITHUB_REPOSITORY}/releases/download/${GITHUB_REF_NAME}/plane-cli-${VERSION}.tgz"
echo '```'
echo ""
echo "Or if already installed: \`plane upgrade\`."
} >> RELEASE_NOTES.md

- name: Create GitHub release with tarball asset
uses: softprops/action-gh-release@v2
with:
name: ${{ github.ref_name }}
body_path: RELEASE_NOTES.md
files: plane-cli-${{ steps.version.outputs.version }}.tgz
fail_on_unmatched_files: true

- name: Verify release asset is reachable
run: |
VERSION="${{ steps.version.outputs.version }}"
URL="https://github.com/${GITHUB_REPOSITORY}/releases/download/${GITHUB_REF_NAME}/plane-cli-${VERSION}.tgz"
echo "Checking $URL"
for i in 1 2 3 4 5 6; do
CODE="$(curl -sILo /dev/null -w "%{http_code}" "$URL")"
if [ "$CODE" = "200" ]; then
echo "Asset reachable (HTTP 200)."
exit 0
fi
echo "Attempt $i: HTTP $CODE, retrying in 5s..."
sleep 5
done
echo "::error::Release asset $URL is not reachable. plane upgrade would 404."
exit 1
33 changes: 33 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CLAUDE.md

Entry point for AI agents working on `plane-cli`. Read the canonical context before touching code.

## Start here

- **[context/docs/briefs/agent.md](context/docs/briefs/agent.md)** — full briefing: what the project is, tech stack, architecture, Plane API quirks (issues vs work-items), config storage, command-resolution rules, and the release checklist. **Read this first.**
- **[context/docs/project/current-state.md](context/docs/project/current-state.md)** — living summary of the current repo state: version, command surface, behavioral guarantees, and where planning lives.
- **[docs/roadmap.md](docs/roadmap.md)** — shipped releases and the planned backlog.
- **[CHANGELOG.md](CHANGELOG.md)** — release history.

## How work flows here

- **User reports / feedback** → capture verbatim first with the `capture-user-report` skill ([skills/capture-user-report/SKILL.md](skills/capture-user-report/SKILL.md)) into `context/research/user-reports/`, then triage to `context/research/lessons-learned/`, then (optionally) a roadmap entry. See [AGENTS.md](AGENTS.md).
- **Cutting a release** → use the `release-plane-cli` skill ([skills/release-plane-cli/SKILL.md](skills/release-plane-cli/SKILL.md)). Prepare the edits, commit, and push a `vX.Y.Z` tag; the release workflow builds, verify-packs, creates the release, and uploads the `.tgz`.
- **Context folder** → `context/` is local working memory (research, plans, references), separate from the source tree. See [context/README.md](context/README.md).

## Dev quickstart

```bash
bun install # or: npm install
bun run typecheck
bun run lint
bun run format:check
bun run build
bun test
```

CI (`.github/workflows/ci.yml`) runs typecheck, lint, format:check, build, and test on every push and PR. Keep `src/` prettier-clean or CI fails.

## Boundaries

Commands live in `src/commands/` (thin handlers); shared logic in `src/core/`. No npm-registry publish, no standalone binaries, no server/infra management. Install is always from a GitHub release `.tgz` asset — never the bare `github:` form (broken Windows junctions).
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ This installs the `plane` command as a normal npm global CLI. It does not requir

On Linux and macOS, avoid `sudo npm install -g` for this CLI. If npm global installs fail with permission errors, use a user-level Node.js setup such as [`nvm`](https://github.com/nvm-sh/nvm) or [`fnm`](https://github.com/Schniz/fnm), or configure npm's global prefix to a user-owned directory.

### Windows / PowerShell

npm installs a `plane.ps1` shim alongside `plane.cmd`. On a default PowerShell setup, running `plane` may fail with:

```text
plane.ps1 cannot be loaded because running scripts is disabled on this system.
```

This is PowerShell's execution policy blocking the `.ps1` shim, not a problem with the CLI. Either:

- Call the `.cmd` shim directly: `plane.cmd where`, or
- Allow local scripts once (recommended): `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`, then run `plane` normally.

`cmd.exe` and Git Bash are unaffected.

---

## Quick start
Expand All @@ -51,7 +66,7 @@ Context (account, workspace, project) is sticky — set it once and every comman
| **Issues** | `issue list`, `mine`, `get`, `create`, `update`, `move`, `delete`, `close`, `reopen`, `open` |
| **Cycles** | `cycle list`, `current`, `issues`, `create`, `ensure`, `add`, `remove`, `delete` |
| **Modules** | `module list`, `issues`, `create`, `ensure`, `add`, `remove`, `delete` |
| **Labels** | `label list`, `create`, `update`, `delete`, `add`, `remove` |
| **Labels** | `label list`, `create`, `ensure`, `update`, `delete`, `add`, `remove` |
| **Comments** | `comment list`, `add`, `update`, `delete` |
| **Pages** | `page list`, `get`, `search`, `create`, `update`, `delete` |
| **States** | `state list` |
Expand Down
2 changes: 1 addition & 1 deletion dist/commands/cycle.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading