From 3962666f1184b671340ca0c32db622cb9c176b9a Mon Sep 17 00:00:00 2001 From: Aabhas Date: Fri, 8 May 2026 23:18:01 +0530 Subject: [PATCH 1/3] feat: professional multi-platform distribution via Homebrew, shell scripts, and GitHub Native release notes --- .github/workflows/release.yml | 63 +++++++++----------------------- .goreleaser.yaml | 58 ++++++++++++++++++++++++++++++ README.md | 68 ++++++++++++++++++----------------- install.ps1 | 25 +++++++++++++ install.sh | 57 +++++++++++++++++++++++++++++ 5 files changed, 192 insertions(+), 79 deletions(-) create mode 100644 .goreleaser.yaml create mode 100644 install.ps1 create mode 100755 install.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d9ddd79..1ad3dfa9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,54 +9,23 @@ permissions: contents: write jobs: - build: - runs-on: macos-latest - strategy: - matrix: - include: - - goarch: arm64 - asset: flow-darwin-arm64 - - goarch: amd64 - asset: flow-darwin-amd64 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Build ${{ matrix.asset }} - env: - GOOS: darwin - GOARCH: ${{ matrix.goarch }} - CGO_ENABLED: '0' - run: | - go build -trimpath \ - -ldflags "-s -w -X main.version=${GITHUB_REF_NAME}" \ - -o "${{ matrix.asset }}" . - - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.asset }} - path: ${{ matrix.asset }} - if-no-files-found: error - - release: - needs: build + goreleaser: runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v4 + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v5 with: - path: dist - merge-multiple: true - - name: Generate checksums - working-directory: dist - run: | - shasum -a 256 flow-darwin-* > SHA256SUMS - cat SHA256SUMS - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + go-version-file: go.mod + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 with: - files: | - dist/flow-darwin-arm64 - dist/flow-darwin-amd64 - dist/SHA256SUMS - generate_release_notes: true - fail_on_unmatched_files: true + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 00000000..32189a02 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,58 @@ +# .goreleaser.yaml +# Documentation at https://goreleaser.com +version: 2 + +before: + hooks: + - go mod tidy + +builds: + - env: + - CGO_ENABLED=0 + goos: + - darwin + - linux + - windows + goarch: + - amd64 + - arm64 + ldflags: + - -s -w -X main.version={{.Version}} + binary: flow + +archives: + - formats: + - tar.gz + # this name template makes the result look like flow_0.1.0_darwin_amd64.tar.gz + name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + files: + - LICENSE + - README.md + - CHANGELOG.md + +checksum: + name_template: 'checksums.txt' + +snapshot: + version_template: "{{ incpatch .Version }}-next" + +changelog: + use: github-native + +homebrew_casks: + - name: flow + repository: + owner: Facets-cloud + name: homebrew-tap + token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" + homepage: "https://github.com/Facets-cloud/flow" + description: "A complete task manager for Claude Code — and the working memory layer that turns every session from a brilliant new hire into the engineer on your team." + license: "MIT" + caveats: | + After installation, you must run: + flow init + to set up the SQLite database and wire flow into Claude Code. + hooks: + post: + install: | + system_command "/usr/bin/xattr", args: ["-d", "com.apple.quarantine", "#{staged_path}/flow"], sudo: true diff --git a/README.md b/README.md index 4dcae4e6..5adda487 100644 --- a/README.md +++ b/README.md @@ -43,14 +43,14 @@ the next one smarter. │ processes · business │ └─────▲──────────▲───────┘ │ │ - flow do │ scoop │ sweep - ┌────────┐ ─────────────────▶ ┌─────────┴──────────┴─────┐ - │ Task │ │ Claude session │ - │ brief │ ◀──── updates ───── │ loads brief + kb + │ - │ +notes │ │ notes + repo conventions│ - └────────┘ ─── flow done ───▶ └──────────────────────────┘ - (auto-sweep transcript - into kb on done) + flow do │ scoop │ sweep + ┌────────┐ ─────────────────▶ ┌─────────┴──────────┴─────┐ + │ Task │ │ Claude session │ + │ brief │ ◀──── updates ───── │ loads brief + kb + │ + │ +notes │ │ notes + repo conventions│ + └────────┘ ─── flow done ───▶ └──────────────────────────┘ + (auto-sweep transcript + into kb on done) ``` - **Scoop (live):** during a session the flow skill listens for @@ -90,7 +90,34 @@ back to the knowledge base on `flow done` like any other task. Same compounding mechanic — your weekly review session two months from now will know everything every prior weekly review surfaced. -## Install +## Installation + +### Homebrew (Recommended for macOS) + +```bash +brew install --cask Facets-cloud/tap/flow +flow init +``` + +### Quick Install (macOS & Linux) + +```bash +curl -fsSL https://raw.githubusercontent.com/Facets-cloud/flow/main/install.sh | bash +flow init +``` + +> [!IMPORTANT] +> **macOS Users**: Since the binary is currently unsigned, macOS will "quarantine" it. The install script automatically tries to remove this flag, but if you see a "Developer cannot be verified" error, run: +> `xattr -d com.apple.quarantine $(which flow)` + +### Windows (PowerShell) + +```powershell +iwr https://raw.githubusercontent.com/Facets-cloud/flow/main/install.ps1 | iex +flow init +``` + +### via Claude Code In any Claude Code session, paste this: @@ -102,24 +129,6 @@ and registers a SessionStart hook so every future Claude session loads the skill automatically. Then say **"let's get to work"** and follow along. -
-Manual install (curl + chmod + flow init) - -```bash -# 1. Download the binary for your Mac. -ARCH=arm64 # Apple Silicon (M1/M2/M3/M4) — use amd64 for Intel. - -curl -fsSL -o /usr/local/bin/flow \ - "https://github.com/Facets-cloud/flow/releases/latest/download/flow-darwin-${ARCH}" -chmod +x /usr/local/bin/flow -xattr -d com.apple.quarantine /usr/local/bin/flow 2>/dev/null || true - -# 2. Initialize. This is required — it creates ~/.flow/, the SQLite -# index, the knowledge base, AND installs the Claude skill + -# SessionStart hook. Without this step, Claude can't talk to flow. -flow init -``` - `flow init` is the step that wires flow into Claude Code. It: - Creates `~/.flow/` (database, kb, projects, tasks, playbooks) @@ -127,11 +136,6 @@ flow init - Adds a SessionStart hook to `~/.claude/settings.json` so every new Claude Code session auto-loads the skill -The `xattr` step removes Gatekeeper's quarantine attribute so macOS -doesn't refuse to run the unsigned binary. - -
- ## Upgrade In any Claude Code session: diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 00000000..6a9a1c56 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,25 @@ +$os = "windows" +$arch = if ($IsARM64) { "arm64" } else { "amd64" } + +Write-Host "Detecting latest version..." -ForegroundColor Cyan +$release = Invoke-RestMethod -Uri "https://api.github.com/repos/Facets-cloud/flow/releases/latest" +$version = $release.tag_name.Substring(1) + +$filename = "flow_${version}_${os}_${arch}.tar.gz" +$url = "https://github.com/Facets-cloud/flow/releases/latest/download/$filename" + +Write-Host "Downloading $filename..." -ForegroundColor Cyan +Invoke-WebRequest -Uri $url -OutFile "flow.tar.gz" + +Write-Host "Extracting..." -ForegroundColor Cyan +tar -xzf flow.tar.gz + +$dest = "$HOME\AppData\Local\Microsoft\WindowsApps" +Write-Host "Installing to $dest..." -ForegroundColor Cyan +Move-Item -Path "flow.exe" -Destination "$dest\flow.exe" -Force + +# Clean up +Remove-Item "flow.tar.gz" + +Write-Host "Done! To complete the setup, run:" -ForegroundColor Green +Write-Host " flow init" -ForegroundColor Green diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..b9333343 --- /dev/null +++ b/install.sh @@ -0,0 +1,57 @@ +#!/bin/bash +set -e + +# Detect OS +OS="$(uname -s | tr '[:upper:]' '[:lower:]')" +ARCH="$(uname -m)" + +case "${ARCH}" in + x86_64) ARCH="amd64" ;; + aarch64|arm64) ARCH="arm64" ;; + *) echo "Unsupported architecture: ${ARCH}"; exit 1 ;; +esac + +case "${OS}" in + linux|darwin) BIN_EXT="" ;; + msys*|mingw*|cygwin*) OS="windows"; BIN_EXT=".exe" ;; + *) echo "Unsupported operating system: ${OS}"; exit 1 ;; +esac + +echo "Detecting latest version..." +LATEST_VERSION=$(curl -s https://api.github.com/repos/Facets-cloud/flow/releases/latest | grep tag_name | cut -d '"' -f 4) +VERSION_NUMBER="${LATEST_VERSION#v}" + +FILENAME="flow_${VERSION_NUMBER}_${OS}_${ARCH}.tar.gz" +URL="https://github.com/Facets-cloud/flow/releases/latest/download/${FILENAME}" + +echo "Downloading ${FILENAME}..." +curl -L "${URL}" -o flow.tar.gz + +echo "Extracting..." +tar -xzf flow.tar.gz + +echo "Installing to /usr/local/bin/flow (may require sudo)..." +if [ "${OS}" = "windows" ]; then + # For Git Bash on Windows + mkdir -p /usr/bin + mv "flow${BIN_EXT}" /usr/bin/ +else + if [ -w /usr/local/bin ]; then + mv flow /usr/local/bin/ + else + sudo mv flow /usr/local/bin/ + fi +fi + +chmod +x /usr/local/bin/flow${BIN_EXT} + +# Remove macOS quarantine flag for unsigned binaries +if [ "${OS}" = "darwin" ]; then + xattr -d com.apple.quarantine /usr/local/bin/flow 2>/dev/null || true +fi + +# Clean up +rm flow.tar.gz + +echo "Done! To complete the setup, run:" +echo " flow init" From f83d8b4cf1f8dc2b589116d2b119f75e8436a14d Mon Sep 17 00:00:00 2001 From: Aabhas Date: Sat, 9 May 2026 20:52:30 +0530 Subject: [PATCH 2/3] chore: remove linux, windows builds, CGO, and install scripts for now --- .goreleaser.yaml | 6 +---- install.ps1 | 25 --------------------- install.sh | 57 ------------------------------------------------ 3 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 install.ps1 delete mode 100755 install.sh diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 32189a02..6ca1cf71 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -7,12 +7,8 @@ before: - go mod tidy builds: - - env: - - CGO_ENABLED=0 - goos: + - goos: - darwin - - linux - - windows goarch: - amd64 - arm64 diff --git a/install.ps1 b/install.ps1 deleted file mode 100644 index 6a9a1c56..00000000 --- a/install.ps1 +++ /dev/null @@ -1,25 +0,0 @@ -$os = "windows" -$arch = if ($IsARM64) { "arm64" } else { "amd64" } - -Write-Host "Detecting latest version..." -ForegroundColor Cyan -$release = Invoke-RestMethod -Uri "https://api.github.com/repos/Facets-cloud/flow/releases/latest" -$version = $release.tag_name.Substring(1) - -$filename = "flow_${version}_${os}_${arch}.tar.gz" -$url = "https://github.com/Facets-cloud/flow/releases/latest/download/$filename" - -Write-Host "Downloading $filename..." -ForegroundColor Cyan -Invoke-WebRequest -Uri $url -OutFile "flow.tar.gz" - -Write-Host "Extracting..." -ForegroundColor Cyan -tar -xzf flow.tar.gz - -$dest = "$HOME\AppData\Local\Microsoft\WindowsApps" -Write-Host "Installing to $dest..." -ForegroundColor Cyan -Move-Item -Path "flow.exe" -Destination "$dest\flow.exe" -Force - -# Clean up -Remove-Item "flow.tar.gz" - -Write-Host "Done! To complete the setup, run:" -ForegroundColor Green -Write-Host " flow init" -ForegroundColor Green diff --git a/install.sh b/install.sh deleted file mode 100755 index b9333343..00000000 --- a/install.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -set -e - -# Detect OS -OS="$(uname -s | tr '[:upper:]' '[:lower:]')" -ARCH="$(uname -m)" - -case "${ARCH}" in - x86_64) ARCH="amd64" ;; - aarch64|arm64) ARCH="arm64" ;; - *) echo "Unsupported architecture: ${ARCH}"; exit 1 ;; -esac - -case "${OS}" in - linux|darwin) BIN_EXT="" ;; - msys*|mingw*|cygwin*) OS="windows"; BIN_EXT=".exe" ;; - *) echo "Unsupported operating system: ${OS}"; exit 1 ;; -esac - -echo "Detecting latest version..." -LATEST_VERSION=$(curl -s https://api.github.com/repos/Facets-cloud/flow/releases/latest | grep tag_name | cut -d '"' -f 4) -VERSION_NUMBER="${LATEST_VERSION#v}" - -FILENAME="flow_${VERSION_NUMBER}_${OS}_${ARCH}.tar.gz" -URL="https://github.com/Facets-cloud/flow/releases/latest/download/${FILENAME}" - -echo "Downloading ${FILENAME}..." -curl -L "${URL}" -o flow.tar.gz - -echo "Extracting..." -tar -xzf flow.tar.gz - -echo "Installing to /usr/local/bin/flow (may require sudo)..." -if [ "${OS}" = "windows" ]; then - # For Git Bash on Windows - mkdir -p /usr/bin - mv "flow${BIN_EXT}" /usr/bin/ -else - if [ -w /usr/local/bin ]; then - mv flow /usr/local/bin/ - else - sudo mv flow /usr/local/bin/ - fi -fi - -chmod +x /usr/local/bin/flow${BIN_EXT} - -# Remove macOS quarantine flag for unsigned binaries -if [ "${OS}" = "darwin" ]; then - xattr -d com.apple.quarantine /usr/local/bin/flow 2>/dev/null || true -fi - -# Clean up -rm flow.tar.gz - -echo "Done! To complete the setup, run:" -echo " flow init" From 1fe821f8df7b2fe0d987dede1d6c27345efc155a Mon Sep 17 00:00:00 2001 From: Aabhas Date: Sat, 9 May 2026 20:54:19 +0530 Subject: [PATCH 3/3] docs: remove windows and linux install scripts --- README.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/README.md b/README.md index 5adda487..349b9f42 100644 --- a/README.md +++ b/README.md @@ -99,23 +99,7 @@ brew install --cask Facets-cloud/tap/flow flow init ``` -### Quick Install (macOS & Linux) -```bash -curl -fsSL https://raw.githubusercontent.com/Facets-cloud/flow/main/install.sh | bash -flow init -``` - -> [!IMPORTANT] -> **macOS Users**: Since the binary is currently unsigned, macOS will "quarantine" it. The install script automatically tries to remove this flag, but if you see a "Developer cannot be verified" error, run: -> `xattr -d com.apple.quarantine $(which flow)` - -### Windows (PowerShell) - -```powershell -iwr https://raw.githubusercontent.com/Facets-cloud/flow/main/install.ps1 | iex -flow init -``` ### via Claude Code