e973b2ce20
- Implemented `pcli project export` command to export project hierarchy as JSON. - Added `pcli project import` command to import project data from JSON. - Created user client to fetch user details for comment attribution. - Introduced new data structures for export and import processes. - Ensured name-based references in exports and handled conflicts during imports. - Added versioning and progress reporting for import operations. - Updated documentation and specifications for new features.
316 lines
7.8 KiB
Markdown
316 lines
7.8 KiB
Markdown
# pcli - Planka CLI
|
|
|
|
A command-line interface for interacting with the [Planka](https://planka.app/) project management API.
|
|
|
|
## Features
|
|
|
|
- **Single binary** - No runtime dependencies, just download and run
|
|
- **JSON-first output** - Machine-parseable by default, with optional table format for humans
|
|
- **Environment-based auth** - Configure once via environment variables
|
|
- **Full CRUD operations** - Manage cards, comments, tasks, labels, and more
|
|
- **Project export/import** - Portable JSON backup and migration between instances
|
|
- **Cursor-based pagination** - Automatic handling of paginated API responses
|
|
- **Structured logging** - Debug-level HTTP request/response logging available
|
|
|
|
## Installation
|
|
|
|
### From Source
|
|
|
|
```bash
|
|
git clone https://git.franklin.lab/steve.cliff/pcli.git
|
|
cd pcli
|
|
go build -o pcli
|
|
sudo mv pcli /usr/local/bin/
|
|
```
|
|
|
|
### Binary Download
|
|
|
|
Download the latest release from the [releases page](https://git.franklin.lab/steve.cliff/pcli/releases).
|
|
|
|
## Configuration
|
|
|
|
`pcli` requires two environment variables:
|
|
|
|
- `PLANKA_URL` - Base URL of your Planka instance (e.g., `https://planka.example.com`)
|
|
- `PLANKA_API_KEY` - User-level API key for authentication
|
|
|
|
### Setting Environment Variables
|
|
|
|
```bash
|
|
export PLANKA_URL="https://planka.example.com"
|
|
export PLANKA_API_KEY="D89VszVs_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
|
|
```
|
|
|
|
Or use command-line flags to override:
|
|
|
|
```bash
|
|
pcli --url https://planka.example.com --api-key your-api-key project list
|
|
```
|
|
|
|
### Getting an API Key
|
|
|
|
Generate an API key from your Planka user settings. The full key is only shown once at creation time (it is stored as a hash in the database), so store it securely.
|
|
|
|
## Usage
|
|
|
|
### Global Flags
|
|
|
|
- `--format` - Output format: `json` (default) or `table`
|
|
- `--url` - Planka API URL (overrides `PLANKA_URL`)
|
|
- `--api-key` - API key (overrides `PLANKA_API_KEY`)
|
|
- `--log-level` - Log level: `debug`, `info`, `warn` (default), `error`
|
|
|
|
### Projects
|
|
|
|
```bash
|
|
# List all projects
|
|
pcli project list
|
|
|
|
# Get a specific project
|
|
pcli project get <project-id>
|
|
|
|
# Create a project (type: private or shared)
|
|
pcli project create --name "My Project" --type private
|
|
|
|
# Export a project (all boards, or filter by board)
|
|
pcli project export <project-id-or-name> > backup.json
|
|
pcli project export "My Project" --board "Sprint Board" > board-backup.json
|
|
|
|
# Import a project from JSON
|
|
pcli project import --file backup.json
|
|
pcli project import < backup.json
|
|
```
|
|
|
|
**Note on project types:** Planka v2 accepts `private` or `shared` (not `public`). Use `private` for projects visible only to members, `shared` for projects visible to all users.
|
|
|
|
### Boards
|
|
|
|
```bash
|
|
# List all accessible boards
|
|
pcli board list
|
|
|
|
# List boards filtered by project name
|
|
pcli board list --project "project1"
|
|
|
|
# Get a board
|
|
pcli board get <board-id>
|
|
|
|
# List board actions (activity log)
|
|
pcli board actions <board-id> --limit 50
|
|
```
|
|
|
|
### Cards
|
|
|
|
```bash
|
|
# List cards by board (includes list names)
|
|
pcli card list --board <board-id>
|
|
|
|
# List cards by list
|
|
pcli card list --list <list-id>
|
|
|
|
# Get a card
|
|
pcli card get <card-id>
|
|
|
|
# Create a card
|
|
pcli card create --list <list-id> --name "Task name" --description "Details"
|
|
|
|
# Update a card
|
|
pcli card update <card-id> --name "New name" --description "Updated details"
|
|
|
|
# Delete a card
|
|
pcli card delete <card-id>
|
|
|
|
# Duplicate a card
|
|
pcli card duplicate <card-id> --name "Copy of task"
|
|
|
|
# Move a card to another list
|
|
pcli card move <card-id> --list <target-list-id> --position 65536
|
|
|
|
# Assign/unassign users
|
|
pcli card assign <card-id> --user <user-id>
|
|
pcli card unassign <card-id> --user <user-id>
|
|
|
|
# Add/remove labels
|
|
pcli card add-label <card-id> --label <label-id>
|
|
pcli card remove-label <card-id> --label <label-id>
|
|
|
|
# List card actions
|
|
pcli card actions <card-id> --limit 20
|
|
```
|
|
|
|
### Comments
|
|
|
|
```bash
|
|
# List comments on a card
|
|
pcli comment list --card <card-id>
|
|
|
|
# Create a comment
|
|
pcli comment create --card <card-id> --text "This is a comment"
|
|
|
|
# Update a comment
|
|
pcli comment update <comment-id> --text "Updated text"
|
|
|
|
# Delete a comment
|
|
pcli comment delete <comment-id>
|
|
```
|
|
|
|
### Task Lists
|
|
|
|
```bash
|
|
# Create a task list
|
|
pcli task-list create --card <card-id> --name "Checklist"
|
|
|
|
# Get a task list
|
|
pcli task-list get <task-list-id>
|
|
|
|
# Update a task list
|
|
pcli task-list update <task-list-id> --name "Updated name"
|
|
|
|
# Delete a task list
|
|
pcli task-list delete <task-list-id>
|
|
```
|
|
|
|
### Tasks
|
|
|
|
```bash
|
|
# Create a task
|
|
pcli task create --task-list <task-list-id> --name "Do something"
|
|
|
|
# Update a task
|
|
pcli task update <task-id> --completed true
|
|
|
|
# Delete a task
|
|
pcli task delete <task-id>
|
|
```
|
|
|
|
### Labels
|
|
|
|
```bash
|
|
# Create a label
|
|
pcli label create --board <board-id> --name "Bug" --color "berry-red"
|
|
|
|
# Update a label
|
|
pcli label update <label-id> --name "Critical Bug" --color "piggy-red"
|
|
|
|
# Delete a label
|
|
pcli label delete <label-id>
|
|
```
|
|
|
|
### Status
|
|
|
|
```bash
|
|
# Show status summary of all boards and their lists
|
|
pcli status
|
|
|
|
# Show status filtered by project name
|
|
pcli status --project "MyProject"
|
|
```
|
|
|
|
## Output Formats
|
|
|
|
### JSON (default)
|
|
|
|
All commands return JSON with a consistent envelope:
|
|
|
|
```json
|
|
{
|
|
"data": { ... },
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
On error:
|
|
|
|
```json
|
|
{
|
|
"data": null,
|
|
"error": "error message"
|
|
}
|
|
```
|
|
|
|
### Table
|
|
|
|
Use `--format=table` for human-readable output:
|
|
|
|
```bash
|
|
pcli --format=table project list
|
|
```
|
|
|
|
Output:
|
|
```
|
|
ID NAME DESCRIPTION HIDDEN
|
|
1357158568008091264 Development Project A project for... false
|
|
```
|
|
|
|
## Logging
|
|
|
|
Enable debug logging to see HTTP requests and responses:
|
|
|
|
```bash
|
|
pcli --log-level=debug card list --board <board-id>
|
|
```
|
|
|
|
Logs are written to stderr in JSON format and won't interfere with stdout output.
|
|
|
|
## Examples
|
|
|
|
### Create a card and add a comment
|
|
|
|
```bash
|
|
# Create the card
|
|
CARD_ID=$(pcli card create \
|
|
--list <list-id> \
|
|
--name "Implement feature X" \
|
|
--description "Details about feature X" \
|
|
| jq -r '.data.id')
|
|
|
|
# Add a comment
|
|
pcli comment create --card $CARD_ID --text "Started working on this"
|
|
```
|
|
|
|
### Move all cards from one list to another
|
|
|
|
```bash
|
|
# Get all cards from source list
|
|
pcli card list --list <source-list-id> | jq -r '.data[].id' | while read card_id; do
|
|
pcli card move $card_id --list <target-list-id>
|
|
done
|
|
```
|
|
|
|
### Export and import a project
|
|
|
|
```bash
|
|
# Export entire project to portable JSON
|
|
pcli project export "My Project" > project-backup.json
|
|
|
|
# Export a single board
|
|
pcli project export "My Project" --board "Sprint Board" > board-backup.json
|
|
|
|
# Import to another instance
|
|
PLANKA_URL=https://other.planka.example pcli project import --file project-backup.json
|
|
```
|
|
|
|
Export uses names (not IDs) so the file is portable across instances. Import creates all resources with fresh IDs. If the project already exists on the target, boards are added to it — but import fails if a board with the same name already exists under that project.
|
|
|
|
Comments are exported with a `(Original comment by <username>)` text prefix to preserve attribution, since user IDs are not portable.
|
|
|
|
## Future Enhancements
|
|
|
|
The following improvements are planned for future releases:
|
|
|
|
- **Concurrent Processing**: Use goroutines with worker pools for parallel board processing in the status command to improve performance with many boards
|
|
- **Rate Limiting**: Implement client-side rate limiting to prevent API abuse
|
|
- **Enhanced Error Context**: Include command context in all error messages for better debugging
|
|
- **Connection Pooling**: Add configurable HTTP client connection limits for better resource management
|
|
- **Input Validation**: Enhanced validation for all user inputs including URL formats and API key patterns
|
|
|
|
## API Compatibility
|
|
|
|
Built against Planka v2.0 API. See `planka-api.json` for the full OpenAPI specification.
|
|
|
|
**Note:** Planka v2 project types are `private` and `shared` (not `public` as in earlier versions).
|
|
|
|
## Contributing
|
|
|
|
Contributions welcome! Please open an issue or pull request on [GitLab](https://git.franklin.lab/steve.cliff/pcli).
|