feat: add project export and import functionality
- 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.
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
---
|
||||
name: kanban
|
||||
name: planka-skill
|
||||
description: Manage Planka project boards using the pcli CLI. Use when the user wants to interact with Planka boards, cards, lists, tasks, labels, or comments.
|
||||
compatibility: Requires pcli binary in PATH and PLANKA_URL + PLANKA_API_KEY environment variables set
|
||||
metadata:
|
||||
author: steve-cliff
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# pcli - Planka CLI
|
||||
@@ -15,11 +19,11 @@ export PLANKA_URL="https://planka.example.com"
|
||||
export PLANKA_API_KEY="your-api-key"
|
||||
```
|
||||
|
||||
Ensure `jq` and `pcli` are installed and in the path.
|
||||
Ensure `jq` is installed.
|
||||
|
||||
## Global Flags
|
||||
|
||||
All commands accept: `--format json|table`, `--url <url>`, `--api-key <key>`, `--log-level debug|info|warn|error`
|
||||
All commands (apart from import/export) accept: `--format json|table`, `--url <url>`, `--api-key <key>`, `--log-level debug|info|warn|error`
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -36,14 +40,38 @@ Returns summary of all boards, lists, and card counts (open/closed per list).
|
||||
```bash
|
||||
pcli project list
|
||||
pcli project get <project-id>
|
||||
pcli project create --name "Name" --type private # type: private or shared
|
||||
pcli project delete <project-id>
|
||||
|
||||
# Export/Import
|
||||
pcli project export <project-id-or-name> [--board <name-or-id>] > backup.json
|
||||
pcli project import --file backup.json
|
||||
pcli project import < backup.json
|
||||
```
|
||||
|
||||
Export outputs a portable JSON file (names, not IDs). Import creates all resources with fresh IDs.
|
||||
Import fails if the project+board name combination already exists on the target.
|
||||
Comments are exported with `(Original comment by <username>)` prefix for attribution.
|
||||
|
||||
**Note:** Export outputs its own envelope format (`{version, exportedAt, project}`) directly — not the standard `{data, error}` envelope. Import progress and errors go to stderr.
|
||||
|
||||
### Boards
|
||||
|
||||
```bash
|
||||
pcli board list
|
||||
pcli board get <board-id> # includes lists and cards
|
||||
pcli board actions <board-id> [--limit N]
|
||||
pcli board create --project <project-id> --name "Board Name" [--position N]
|
||||
pcli board delete <board-id>
|
||||
```
|
||||
|
||||
### Lists (Board Columns)
|
||||
|
||||
```bash
|
||||
pcli list create --board <board-id> --name "Column Name" [--type active|closed] [--position N]
|
||||
pcli list get <list-id>
|
||||
pcli list update <list-id> [--name "..."] [--type active|closed] [--color "..."] [--position N] [--board <board-id>]
|
||||
pcli list delete <list-id>
|
||||
```
|
||||
|
||||
### Cards
|
||||
@@ -99,15 +127,6 @@ pcli task update <task-id> [--name "..."] [--position N] [--completed]
|
||||
pcli task delete <task-id>
|
||||
```
|
||||
|
||||
### Lists
|
||||
|
||||
```bash
|
||||
pcli list create --board <board-id> --name "List Name" --position 65536 [--type active|closed]
|
||||
pcli list get <list-id>
|
||||
pcli list update <list-id> [--name "..."] [--position N] [--type active|closed] [--color "..."] [--board <board-id>]
|
||||
pcli list delete <list-id>
|
||||
```
|
||||
|
||||
### Labels
|
||||
|
||||
```bash
|
||||
@@ -116,45 +135,6 @@ pcli label update <label-id> [--name "..."] [--color "..."] [--position N]
|
||||
pcli label delete <label-id>
|
||||
```
|
||||
|
||||
## API Response Structure
|
||||
|
||||
### Board Get Response
|
||||
Board details include lists directly in `.data.lists[]`, not in an `included` section:
|
||||
```bash
|
||||
pcli board get <board-id> | jq '.data.lists[] | {id, name, position}'
|
||||
```
|
||||
|
||||
### Card List Labels
|
||||
Card list returns labels as **plain strings**, not objects:
|
||||
```bash
|
||||
# Labels are strings like "agent", NOT objects like {name: "agent"}
|
||||
pcli card list --board <board-id> | jq '.data[] | select(.labels[]? == "agent")'
|
||||
```
|
||||
|
||||
### Card Get Response
|
||||
Card get includes `taskLists` and `tasks` arrays (when they exist):
|
||||
```bash
|
||||
pcli card get <card-id> | jq '.data.taskLists[0].id'
|
||||
pcli card get <card-id> | jq '.data.tasks[] | {name, isCompleted}'
|
||||
```
|
||||
|
||||
### Finding Boards in a Project
|
||||
Use `board list --project` to find boards by project name:
|
||||
```bash
|
||||
pcli board list --project "<project-name>" | jq '.data[] | {id, name}'
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Project Configuration
|
||||
- Always strip quotes from yq output: `yq '.planka.project' project.yaml | tr -d '"'`
|
||||
- Exit with error if configured project cannot be found or created
|
||||
- The project name in project.yaml is the authoritative source
|
||||
|
||||
### Idempotent Operations
|
||||
- Use `2>/dev/null || true` for create operations that should not fail if resources already exist
|
||||
- Check for empty results before attempting operations: `if [ -z "$PROJECT_ID" ]; then`
|
||||
|
||||
## Extracting IDs from Output
|
||||
|
||||
All responses use `{"data": ..., "error": null}`. Extract IDs with jq:
|
||||
@@ -165,46 +145,24 @@ pcli card create --list <id> --name "X" | jq -r '.data.id'
|
||||
|
||||
# Array
|
||||
pcli card list --board <id> | jq -r '.data[].id'
|
||||
|
||||
# With error checking
|
||||
RESULT=$(pcli project list | jq -r --arg name "$PROJECT_NAME" '.data[] | select(.name == $name) | .id')
|
||||
if [ -z "$RESULT" ]; then
|
||||
echo "Not found"
|
||||
else
|
||||
echo "Found: $RESULT"
|
||||
fi
|
||||
```
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Bootstrap Project Infrastructure
|
||||
### Create a complete Kanban board
|
||||
|
||||
```bash
|
||||
# Read project configuration
|
||||
PROJECT_NAME=$(yq '.planka.project' project.yaml | tr -d '"')
|
||||
BOARD_NAME=$(yq '.planka.board' project.yaml | tr -d '"')
|
||||
# Create board
|
||||
BOARD_ID=$(pcli board create --project <project-id> --name "Development Board" | jq -r '.data.id')
|
||||
|
||||
# Find or create project (exit with error if fails)
|
||||
PROJECT_ID=$(pcli project list | jq -r --arg name "$PROJECT_NAME" '.data[] | select(.name == $name) | .id')
|
||||
if [ -z "$PROJECT_ID" ]; then
|
||||
echo "Error: Project '$PROJECT_NAME' not found and creation failed"
|
||||
exit 1
|
||||
fi
|
||||
# Create columns
|
||||
pcli list create --board $BOARD_ID --name "Backlog" --type "active" --position 0
|
||||
TODO_ID=$(pcli list create --board $BOARD_ID --name "To Do" --type "active" --position 65536 | jq -r '.data.id')
|
||||
PROGRESS_ID=$(pcli list create --board $BOARD_ID --name "In Progress" --type "active" --position 131072 | jq -r '.data.id')
|
||||
DONE_ID=$(pcli list create --board $BOARD_ID --name "Done" --type "closed" --position 196608 | jq -r '.data.id')
|
||||
|
||||
# Find or create board
|
||||
BOARD_ID=$(pcli board list --project "$PROJECT_NAME" | jq -r --arg name "$BOARD_NAME" '.data[] | select(.name == $name) | .id')
|
||||
if [ -z "$BOARD_ID" ]; then
|
||||
BOARD_ID=$(pcli board create --project $PROJECT_ID --name "$BOARD_NAME" | jq -r '.data.id')
|
||||
fi
|
||||
|
||||
# Create required lists (skip if exists)
|
||||
pcli list create --board $BOARD_ID --name "To Do" --position 131072 2>/dev/null || true
|
||||
pcli list create --board $BOARD_ID --name "In Progress" --position 262144 2>/dev/null || true
|
||||
pcli list create --board $BOARD_ID --name "Review" --position 327680 2>/dev/null || true
|
||||
pcli list create --board $BOARD_ID --name "Done" --position 393216 2>/dev/null || true
|
||||
|
||||
# Create agent label
|
||||
pcli label create --board $BOARD_ID --name "agent" --color "berry-red" 2>/dev/null || true
|
||||
# View the board
|
||||
pcli board get $BOARD_ID --format table
|
||||
```
|
||||
|
||||
### Create a card with a checklist
|
||||
@@ -223,3 +181,16 @@ pcli card list --list <source-list-id> | jq -r '.data[].id' | while read id; do
|
||||
pcli card move $id --list <target-list-id>
|
||||
done
|
||||
```
|
||||
|
||||
### Export and import a project
|
||||
|
||||
```bash
|
||||
# Export entire project
|
||||
pcli project export "My Project" > project-backup.json
|
||||
|
||||
# Export single board
|
||||
pcli project export "My Project" --board "Sprint Board" > board-backup.json
|
||||
|
||||
# Import to another instance (or same instance if project+board combo doesn't exist)
|
||||
pcli project import --file project-backup.json
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user