Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/clickup-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@northguild/worktree": minor
---

Add `worktree branch --clickup <ID>` to start a worktree from a ClickUp task, with `clickup.apiToken` and `clickup.workspaceId` config keys set by `worktree config`.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ line, `worktree: no default for <value>; pass <flag>`.
the worktree, starts nothing and exits `1`.
- **Source branch:** `defaultSourceBranch`, else `origin/main` with a warning.
- **Removal** has no default: `remove <branch> -f`.
- **Bounded calls:** GitHub, Jira and Linear requests 15 s, `git fetch` 60 s, `gh auth token` and the session listing
- **Bounded calls:** GitHub, Jira, Linear and ClickUp requests 15 s, `git fetch` 60 s, `gh auth token` and the session listing
10 s, the install 10 min. A command still running at its bound is sent SIGTERM, then SIGKILL 2 s later, so
one that ignores SIGTERM cannot hold the run open.

Expand All @@ -315,7 +315,7 @@ worktree branch --github 42 --json --agent-file brief.md
"warnings":[]}
```

- `issue` is `{provider:"github",number,url}`, `{provider:"jira",key,url}`, `{provider:"linear",key,url}`, or `null`.
- `issue` is `{provider:"github",number,url}`, `{provider:"jira",key,url}`, `{provider:"linear",key,url}`, `{provider:"clickup",key,url}`, or `null`.
- `assigned` is `null` when no assignment was attempted. `herdr` and `agent` are `null` when skipped, and
`agent.command` leaves the brief out. `agent.name` is `null` where this CLI named nothing (a detached start).
- `installed` is `{ran:false,reason}` when skipped. A failed install still prints the whole document, with
Expand Down Expand Up @@ -469,4 +469,4 @@ MIT
- [x] Integrate with GitHub for automated branch naming
- [x] Integrate with JIRA for automated branch naming
- [x] Integrate with Linear for automated branch naming
- [ ] Integrate with ClickUp for automated branch naming
- [x] Integrate with ClickUp for automated branch naming
4 changes: 2 additions & 2 deletions context/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ confusing errors rather than obvious ones — see the prerequisites and *Prepare
bin/ oclif entry point — bin/run.js, produced by tsc
src/commands/ one file per CLI command; each default-exports a BaseCommand subclass
src/lib/ CLI helpers — git integration, validators, env, types, constants, cli
src/integrations/ GitHub, Jira and Linear integrations
src/integrations/ GitHub, Jira, Linear and ClickUp integrations
scripts/ version-sync script, run by `pnpm sync-version`; `release-notes.mjs`, which publish.yml uses to cut a version's CHANGELOG section
.changeset/ Changesets config and pending release notes (`.changeset/<name>.md`)
patches/ pnpm patches applied through `patchedDependencies` in `pnpm-workspace.yaml`; `nextra-theme-docs@4.6.1` makes its layout's `children` optional, which zod >=4.4 otherwise rejects at prerender. Drop it once nextra ships a fix
Expand Down Expand Up @@ -81,7 +81,7 @@ untrue on one of these surfaces is fixed by the phase that makes it untrue, not
| Surface | Who reads it | What has to reach it |
|---|---|---|
| [`README.md`](../README.md) | someone deciding whether to install; npm renders it as the package page | the fast path — a new command, a renamed flag, a change to what the tool is for |
| `docs/src/app/docs/` | users looking something up, at https://northguild.github.io/worktree | any user-visible CLI behaviour. One page per command under `commands/` (7), plus `configuration/`, `getting-started/`, `faq/`, and `guides/` (8) |
| `docs/src/app/docs/` | users looking something up, at https://northguild.github.io/worktree | any user-visible CLI behaviour. One page per command under `commands/` (7), plus `configuration/`, `getting-started/`, `faq/`, and `guides/` (9) |
| [`docs/README.md`](../docs/README.md) | someone working on the docs app | how the docs app is run or built |
| [`docs/worker/README.md`](../docs/worker/README.md) | someone working on the chat proxy | the Worker's routes, secrets or deploy |
| `skills/worktree/SKILL.md` | agents that install the skill with `npx skills add`; shipped in the npm package; also embedded in the docs chat system prompt | a command or flag change that the skill describes — **but see the caveat below** |
Expand Down
36 changes: 30 additions & 6 deletions docs/src/app/docs/commands/branch/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ worktree branch --github <issue-number> --assign
worktree branch --github <issue-number> --no-assign
worktree branch --jira <issue-id>
worktree branch --linear <issue-id>
worktree branch --clickup <task-id>
worktree branch <name> --agent "<prompt>"
worktree branch <name> --agent-file <path>
worktree branch <name> --agent-stdin
Expand All @@ -39,6 +40,8 @@ worktree branch --jira DEV-123
worktree branch --jira dev-123
worktree branch --linear ENG-123
worktree branch --linear eng-123
worktree branch --clickup 9hx
worktree branch --clickup DEV-123
worktree branch feature/add-bulk-actions --agent "add bulk actions to the table"
worktree branch --github 42 --agent "implement the issue"
worktree branch --github 42 --agent-file brief.md
Expand Down Expand Up @@ -119,9 +122,9 @@ worktree config github.autoAssign true # always assign, stop asking
- The assignment happens before the worktree is created, so the question is never buried behind creation
output or a launched editor. Assigning is idempotent — GitHub does not replace existing assignees — so
retrying after a failed creation is harmless.
- `--assign` and `--no-assign` both require `--github`, `--jira` or `--linear`; on their own there is no issue to act
on. `--assign --jira` and `--assign --linear` warn that assignment is not supported for that provider yet
and carry on.
- `--assign` and `--no-assign` both require one of `--github`, `--jira`, `--linear` or `--clickup`; on their own there is no issue to act
on. `--assign --jira`, `--assign --linear` and `--assign --clickup` warn that assignment is not supported for that
provider yet and carry on.

## Installing dependencies

Expand Down Expand Up @@ -175,7 +178,7 @@ Jira authentication requires three configuration keys:
## Linear Issue Branching

Use the `--linear` flag (short: `-l`) to create a suggested branch name from an issue in your Linear workspace. It
cannot be combined with `--github` or `--jira`. See the [Linear guide](/docs/guides/linear-integration).
cannot be combined with `--github`, `--jira` or `--clickup`. See the [Linear guide](/docs/guides/linear-integration).

- The issue identifier can be passed in any case (`eng-123`, `ENG-123`, etc.).
- The generated name is pre-filled in the prompt and still editable.
Expand All @@ -189,6 +192,27 @@ If no prefix is configured, `worktree` falls back to an empty prefix and still g
Linear authentication requires one configuration key, `northguild.worktree.linear.apiKey`, your Linear personal
API key. Without it the command offers to run `worktree config`, and when there is still no key (or the run is non-interactive) exits `2` with `missing_value`. Assigning the issue is not supported yet.

## ClickUp Task Branching

Use the `--clickup` flag (short: `-c`) to create a suggested branch name from a task in your ClickUp Workspace. It
cannot be combined with `--github`, `--jira` or `--linear`. See the [ClickUp guide](/docs/guides/clickup-integration).

- Pass the task id in either form: the short id in the task's URL and ID field (`9hx`, typed without `CU-`; case
matters), or a custom id (`DEV-123`, sent to ClickUp as typed and upper-cased in the branch name) when your Workspace has custom task ids switched on.
Anything else, including `CU-9hx`, exits `2` with `invalid_value` before any request.
- A custom id needs `clickup.workspaceId`; without it the command exits `2` with `missing_value`.
- A short id becomes `CU-<id>` in the branch name (`feature/CU-9hx-fix-login`); a custom id is upper-cased
(`fix/DEV-123-fix-login`).
- The generated name is pre-filled in the prompt and still editable.
- ClickUp's tags pick the optional prefix, by exact name and ignoring case:
- `branchPrefix.bugfix` for a `bug` tag
- `branchPrefix.chore` for a `chore` or `maintenance` tag, when there is no `bug` tag
- `branchPrefix.feature` for anything else, including no tag

ClickUp authentication requires one configuration key, `northguild.worktree.clickup.apiToken`, your ClickUp personal
API token. Without it the command offers to run `worktree config`, and when there is still no token (or the run is
non-interactive) exits `2` with `missing_value`. Assigning the task is not supported yet.

## Agent Dispatch

Use the `--agent` flag (short: `-a`) to hand the new worktree to a coding agent with a prompt, called the
Expand Down Expand Up @@ -284,7 +308,7 @@ person goes to stderr instead: the spinner lines, the env-file list, notes and w
| Key | Value |
| --- | --- |
| `path`, `branch`, `source` | the worktree's absolute path, its branch, and the ref it was created from |
| `issue` | `{provider:"github", number, url}`, `{provider:"jira", key, url}` or `{provider:"linear", key, url}`; `null` when no issue was used. `url` is `null` when it is not known |
| `issue` | `{provider:"github", number, url}`, `{provider:"jira", key, url}`, `{provider:"linear", key, url}` or `{provider:"clickup", key, url}`; `null` when no issue was used. `url` is `null` when it is not known |
| `assigned` | `true` or `false` once an assignment was attempted; `null` when none was (no issue, `--no-assign`, or a configured `false`) |
| `envFilesCopied` | the env files copied, relative to the repository root; `[]` when there were none |
| `installed` | `{ran:true, command, inferred, ok}`, plus `reason` when `ok` is `false`; `{ran:false, reason}` when the step was skipped |
Expand All @@ -307,7 +331,7 @@ describing it goes to stderr as usual:
| `code` | Means | Exit |
| --- | --- | --- |
| `missing_value` | a value with no default was not given; `details` names it and the flag | `2` |
| `invalid_value` | a value or flag combination was refused: a bad branch name, an empty brief, a malformed `--github`, `--jira` or `--linear` issue id, a `--github` number that is a pull request | `2` |
| `invalid_value` | a value or flag combination was refused: a bad branch name, an empty brief, a malformed `--github`, `--jira`, `--linear` or `--clickup` issue id, a `--github` number that is a pull request | `2` |
| `not_found` | something named does not exist, such as the `--source` branch | `2` |
| `timeout` | a call that is bounded did not answer in time | `1` |
| `failed` | anything else | `1` |
Expand Down
9 changes: 5 additions & 4 deletions docs/src/app/docs/commands/config/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ worktree config --missing --names <comma-separated-keys>
worktree config --yes --names <comma-separated-keys>
```

`--list` shows `github.token`, `jira.apiToken` and `linear.apiKey` as `<key>=***` when set, so a listing is safe to
`--list` shows `github.token`, `jira.apiToken`, `linear.apiKey` and `clickup.apiToken` as `<key>=***` when set, so a listing is safe to
paste or screen-share. `worktree config <key>` with no value prints the current value and nothing else, secrets
included, so `token=$(worktree config github.token)` works in a script. A key with no value prints nothing and
exits `0`.
Expand All @@ -29,7 +29,7 @@ exits `0`.
- With `--list`, it only prints config names that currently have no value.
- Without `--list`, it only prompts for missing values.
- `--names` limits prompting to specific config keys. Naming keys is asking for them, so the optional group
confirms (Jira, GitHub, Linear, prefixes, opener, editor, Herdr, agent, post-create) are not asked for them.
confirms (Jira, GitHub, Linear, ClickUp, prefixes, opener, editor, Herdr, agent, post-create) are not asked for them.
- `--yes` (`-y`) makes the run [non-interactive](/docs/commands/branch#non-interactive-runs): nothing is asked.
Each key takes its default, or the value it already holds, and the run fails with exit `2` naming
`worktree config <key> <value>` for a key with neither, such as a token. Without `--names` the optional groups have no default and the run fails naming `--names <keys>`.
Expand Down Expand Up @@ -82,9 +82,10 @@ regardless, so a machine can be configured before Herdr is installed.
yes/no. The `github.autoAssign` prompt has three choices: "Yes, always", "No, never" and "Ask me each
time". The last leaves the key unset, clearing any stored answer, which is the "ask me" state — so
`--missing` goes on offering the prompt until you settle it either way. Leaving the `github.token`,
`jira.apiToken` or `linear.apiKey` prompt empty, or answering with only spaces, keeps any token you already have,
`jira.apiToken`, `linear.apiKey` or `clickup.apiToken` prompt empty, or answering with only spaces, keeps any token you already have,
rather than clearing it. A pasted value is stored without surrounding whitespace.
A direct `worktree config github.token " "` (likewise `jira.apiToken` and `linear.apiKey`) with a value that is only
`clickup.workspaceId` is optional and only matters for custom task ids such as `DEV-123`: an empty answer skips it and writes nothing, a non-interactive run skips it rather than failing, and under `--missing` pressing Enter skips its prompt too.
A direct `worktree config github.token " "` (likewise `jira.apiToken`, `linear.apiKey` and `clickup.apiToken`) with a value that is only
whitespace is refused with exit `2`, and nothing is stored.

## Agent Key
Expand Down
15 changes: 15 additions & 0 deletions docs/src/app/docs/configuration/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ title: Configuration
- `jira.email` (Your Jira email address)
- `jira.apiToken` (Jira API token)
- `linear.apiKey` (Linear personal API key, example: `lin_api_...`)
- `clickup.apiToken` (ClickUp personal API token, example: `pk_...`)
- `clickup.workspaceId` (optional; your ClickUp Workspace id, a number, needed only for custom task ids like `DEV-123`)
- `branchPrefix.feature` (example: `feature/`)
- `branchPrefix.bugfix` (example: `fix/`)
- `branchPrefix.chore` (example: `chore/`)
Expand Down Expand Up @@ -168,6 +170,8 @@ worktree config jira.host https://company.atlassian.net
worktree config jira.email your-email@example.com
worktree config jira.apiToken <api-token>
worktree config linear.apiKey <api-key>
worktree config clickup.apiToken <api-token>
worktree config clickup.workspaceId <workspace-id>
worktree config branchPrefix.feature feature/
worktree config branchPrefix.bugfix fix/
worktree config branchPrefix.chore chore/
Expand Down Expand Up @@ -222,10 +226,21 @@ worktree config github.autoAssign true
`chore` or `maintenance` uses `branchPrefix.chore`, anything else uses `branchPrefix.feature`.
- Issue identifiers are case-insensitive (both `eng-123` and `ENG-123` work).

## ClickUp Integration Notes

- `worktree branch --clickup <task-id>` reads tasks from the ClickUp Workspace your token belongs to.
- `clickup.apiToken` is required. `clickup.workspaceId` is optional and is needed only when you pass a custom task id
such as `DEV-123`; a short id such as `9hx` never needs it. An empty answer to its prompt skips it.
- The branch prefix comes from the task's tags: `bug` uses `branchPrefix.bugfix`,
`chore` or `maintenance` uses `branchPrefix.chore`, anything else uses `branchPrefix.feature`.
- A short id is case-sensitive and typed without `CU-` (`9hx`); the branch name gains `CU-`. A custom id is
sent to ClickUp as typed and upper-cased in the branch name (`dev-123` gives `DEV-123` in the name).

## Recommended Team Baseline

1. Agree on one source branch (`origin/main` for most teams).
2. Standardize branch naming conventions.
3. Keep editor command consistent across local setups.
4. For Jira integration, share workspace URL and branch prefix conventions.
5. For Linear integration, share which labels map to bug and chore work, since the label decides the prefix.
6. For ClickUp integration, share which tags map to bug and chore work, since the tag decides the prefix, and whether your Workspace uses custom task ids (then also the workspace id).
1 change: 1 addition & 0 deletions docs/src/app/docs/guides/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const meta: MetaRecord = {
"github-issue-integration": "GitHub Issue Integration",
"jira-integration": "Jira Issue Integration",
"linear-integration": "Linear Issue Integration",
"clickup-integration": "ClickUp Task Integration",
"context-switching": "Context Switching",
"team-conventions": "Team Conventions",
"env-files": "Environment Files",
Expand Down
Loading
Loading