From 7d6a01c2002854c706e773553c149af16aff88bf Mon Sep 17 00:00:00 2001 From: Ryan Burnette Date: Sat, 9 May 2026 09:34:45 -0400 Subject: [PATCH] feat(basecamp): add installer Co-authored-by: AJ ONeal --- basecamp/README.md | 128 +++++++++++++++++++++++++++++++++++++++++ basecamp/install.ps1 | 46 +++++++++++++++ basecamp/install.sh | 44 ++++++++++++++ basecamp/releases.conf | 2 + test/install.sh | 3 + 5 files changed, 223 insertions(+) create mode 100644 basecamp/README.md create mode 100644 basecamp/install.ps1 create mode 100644 basecamp/install.sh create mode 100644 basecamp/releases.conf diff --git a/basecamp/README.md b/basecamp/README.md new file mode 100644 index 0000000..075951c --- /dev/null +++ b/basecamp/README.md @@ -0,0 +1,128 @@ +--- +title: basecamp +homepage: https://github.com/basecamp/basecamp-cli +tagline: | + basecamp: CLI for Basecamp 3 — manage projects, todos, messages, cards, and more from the terminal. +--- + +To update or switch versions, run `webi basecamp@stable` (or `@v0.7`, +`@beta`, etc). + +### Files + +These are the files / directories that are created and/or modified with this +install: + +```text +~/.config/envman/PATH.env +~/.local/bin/basecamp +~/.local/opt/basecamp-VERSION/bin/basecamp +~/.local/opt/basecamp-VERSION/completions/ +``` + +## Cheat Sheet + +> `basecamp` is the official CLI for Basecamp 3. It provides full API coverage +> for projects, todos, messages, cards, schedule, files, and more — all from the +> command line. + +### How to authenticate + +```sh +basecamp auth login +``` + +For headless environments (CI, remote servers): + +```sh +basecamp auth login --device-code +``` + +Check auth status: + +```sh +basecamp auth status +``` + +### How to list projects and todos + +```sh +basecamp projects list --md + +basecamp todos list --assignee me --in PROJECT_ID --md +``` + +Cross-project view of your assigned work: + +```sh +basecamp assignments --md +``` + +### How to create and complete todos + +```sh +basecamp todo "Write release notes" --in PROJECT_ID --list TODOLIST_ID --assignee me --due tomorrow + +basecamp done TODO_ID +``` + +### How to post a message or comment + +```sh +basecamp message "Sprint Update" "Shipped v2.1 to production." --in PROJECT_ID + +basecamp comment RECORDING_ID "Looks good." --in PROJECT_ID +``` + +### How to move cards through a workflow + +```sh +basecamp cards columns --in PROJECT_ID --md + +basecamp cards move CARD_ID --to COLUMN_ID --in PROJECT_ID +``` + +### How to set up per-project defaults + +Create `.basecamp/config.json` in your repo (commit it): + +```json +{ + "project_id": "12345", + "todolist_id": "67890" +} +``` + +Then trust it once: + +```sh +basecamp config trust +``` + +After that, you can omit `--in` for most commands in that repo. + +### Shell completions + +Completions for bash, fish, and zsh ship with the installer. Find them at: + +```text +~/.local/opt/basecamp-VERSION/completions/ +``` + +Bash: + +```sh +echo "source ~/.local/opt/basecamp-VERSION/completions/basecamp.bash" >> ~/.bashrc +``` + +Fish: + +```sh +ln -s ~/.local/opt/basecamp-VERSION/completions/basecamp.fish ~/.config/fish/completions/ +``` + +Zsh: + +```sh +echo "fpath+=( ~/.local/opt/basecamp-VERSION/completions )" >> ~/.zshrc +``` diff --git a/basecamp/install.ps1 b/basecamp/install.ps1 new file mode 100644 index 0000000..52a6eb8 --- /dev/null +++ b/basecamp/install.ps1 @@ -0,0 +1,46 @@ +#!/usr/bin/env pwsh + +$pkg_cmd_name = "basecamp" + +$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\basecamp.exe" +$pkg_dst = "$pkg_dst_cmd" + +$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION\bin\basecamp.exe" +$pkg_src_bin = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION\bin" +$pkg_src_dir = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION" +$pkg_src = "$pkg_src_cmd" + +New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null +$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE" + +if (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) { + Write-Output "Downloading basecamp from $Env:WEBI_PKG_URL to $pkg_download" + & curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part" + & Move-Item "$pkg_download.part" "$pkg_download" +} + +if (!(Test-Path -Path "$pkg_src_cmd")) { + Write-Output "Installing basecamp" + + Push-Location .local\tmp + + Remove-Item -Path ".\basecamp-*" -Recurse -ErrorAction Ignore + Remove-Item -Path ".\basecamp.exe" -Recurse -ErrorAction Ignore + + Write-Output "Unpacking $pkg_download" + & tar xf "$pkg_download" + + New-Item "$pkg_src_bin" -ItemType Directory -Force | Out-Null + Move-Item -Path ".\basecamp.exe" -Destination "$pkg_src_bin" + + New-Item "$pkg_src_dir\completions" -ItemType Directory -Force | Out-Null + if (Test-Path -Path ".\completions") { + Copy-Item -Path ".\completions\*" -Destination "$pkg_src_dir\completions" -Recurse + } + + Pop-Location +} + +Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'" +Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | Out-Null +Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse diff --git a/basecamp/install.sh b/basecamp/install.sh new file mode 100644 index 0000000..e2c14d8 --- /dev/null +++ b/basecamp/install.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# shellcheck disable=SC2034 + +set -e +set -u + +__init_basecamp() { + pkg_cmd_name="basecamp" + + pkg_src_dir="$HOME/.local/opt/basecamp-v$WEBI_VERSION" + pkg_src_cmd="$pkg_src_dir/bin/basecamp" + pkg_src="$pkg_src_cmd" + + pkg_dst_cmd="$HOME/.local/bin/basecamp" + pkg_dst="$pkg_dst_cmd" + + pkg_install() { + mkdir -p "$(dirname "$pkg_src_cmd")" + mkdir -p "$pkg_src_dir/completions" + + if test -f ./basecamp; then + mv ./basecamp "$pkg_src_cmd" + elif test -e ./basecamp-*/basecamp; then + mv ./basecamp-*/basecamp "$pkg_src_cmd" + elif test -e ./basecamp-*; then + mv ./basecamp-* "$pkg_src_cmd" + else + echo >&2 "failed to find 'basecamp' executable" + return 1 + fi + + if test -d ./completions; then + cp -a ./completions/. "$pkg_src_dir/completions/" + fi + } + + pkg_get_current_version() { + basecamp --version 2> /dev/null | + head -n 1 | + cut -d' ' -f3 + } +} + +__init_basecamp diff --git a/basecamp/releases.conf b/basecamp/releases.conf new file mode 100644 index 0000000..2ce2196 --- /dev/null +++ b/basecamp/releases.conf @@ -0,0 +1,2 @@ +github_releases = basecamp/basecamp-cli +exclude = .bundle .txt diff --git a/test/install.sh b/test/install.sh index 877eb5f..4acfc3e 100644 --- a/test/install.sh +++ b/test/install.sh @@ -10,6 +10,7 @@ __rmrf_local() { arc \ archiver \ awless \ + basecamp \ bat \ btop \ caddy \ @@ -107,6 +108,7 @@ __rmrf_local() { arc \ archiver \ awless \ + basecamp \ bat \ caddy \ chromedriver \ @@ -206,6 +208,7 @@ __test() { arc \ archiver \ awless \ + basecamp \ bat \ caddy \ chromedriver \