Skip to content
This repository was archived by the owner on Apr 7, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
88cc8e4
chore(ci): deploy docker image
albttx Mar 10, 2026
2b47876
Update .github/workflows/docker.yml
albttx Mar 10, 2026
b535860
Update .github/workflows/docker.yml
albttx Mar 10, 2026
b1e2a56
fix: recover @greptile-apps errors
albttx Mar 16, 2026
4744915
fix(issues): normalize HTML entities in @mention tokens before agent …
Mar 20, 2026
61f53b6
feat: add ReportsToPicker for agent management
DanielSousa Mar 20, 2026
dfb8329
Merge branch 'master' into feature/change-reports-to
DanielSousa Mar 20, 2026
de10269
fix: update ReportsToPicker to display terminated status and improve …
DanielSousa Mar 20, 2026
17b6f6c
fix: enhance ReportsToPicker to handle unknown and terminated managers
DanielSousa Mar 20, 2026
4587627
refactor: improve layout and truncation in ReportsToPicker
DanielSousa Mar 20, 2026
5e414ff
fix: add pi_local to isLocalAdapter and ENABLED_INVITE_ADAPTERS guards
lucas-stellet Mar 20, 2026
e37e9df
fix: address greptile review — add pi_local to effectiveAdapterComman…
lucas-stellet Mar 20, 2026
4ebc12a
docs(api): fix goal status value and document checkout re-claim pattern
aronprins Mar 23, 2026
f42aebd
docs(api): add Routines reference
aronprins Mar 23, 2026
f87db64
docs(api/routines): address three review findings
aronprins Mar 23, 2026
8b4850a
Merge pull request #1622 from aronprins/docs/api-routines-and-fixes
cryppadotta Mar 23, 2026
e204e03
Add CLI company import export e2e test
Mar 22, 2026
5a73556
Use positional source arg for company import
Mar 23, 2026
e6df9fa
Support GitHub shorthand refs for company import
Mar 23, 2026
5dfdbe9
Add merge-history project import option
Mar 21, 2026
f23d611
Route existing-company CLI imports through safe routes
Mar 23, 2026
e680112
Merge pull request #1632 from paperclipai/pr/pap-768-merge-history
cryppadotta Mar 23, 2026
1376fc8
Merge pull request #1631 from paperclipai/pr/pap-768-company-import-s…
cryppadotta Mar 23, 2026
37c2c4a
Add browser-based board CLI auth flow
Mar 23, 2026
298713f
Fix duplicate auth login company flag
Mar 23, 2026
01b6b7e
fix: make cli auth migration 0044 idempotent
Mar 23, 2026
7f9a764
Address Greptile review on board CLI auth
Mar 23, 2026
080c9e4
Merge pull request #1635 from paperclipai/pr/pap-768-board-cli-auth
cryppadotta Mar 23, 2026
119dd0e
Merge pull request #542 from albttx/dockerize
cryppadotta Mar 23, 2026
b5610f6
Merge pull request #1382 from lucas-stellet/fix/pi-local-missing-from…
cryppadotta Mar 23, 2026
3a79d94
Merge pull request #1380 from DanielSousa/feature/change-reports-to
cryppadotta Mar 23, 2026
ef0846e
Remove priority icon from issue rows across the app
Mar 21, 2026
0b9f003
Increase monospace font size and add dark mode background for inline …
Mar 21, 2026
f8dd4dc
Reduce monospace font size from 1.1em to 1em
Mar 21, 2026
cd7c6ee
Fix login form not being detected by 1Password
Mar 21, 2026
8232456
Fix markdown mention chips
Mar 21, 2026
49ace2f
Allow custom markdown mention links in editor
Mar 21, 2026
0e8e162
Fix mention pills by allowing custom URL schemes in Lexical LinkNode
Mar 21, 2026
db42adf
Make agent instructions tab responsive on mobile
Mar 22, 2026
bd0b760
Fix atomic markdown mention deletion
Mar 22, 2026
42c8d9b
Fix oversized toggle switches on mobile
Mar 22, 2026
e61f00d
Add missing data-slot="toggle" to Routines toggle buttons
Mar 22, 2026
bdecb1b
Sort agents alphabetically by name in all views
Mar 22, 2026
0b960b0
Suppress same-page issue toasts
Mar 22, 2026
e73bc81
fix: prevent documents row from causing horizontal scroll on mobile
Mar 22, 2026
d73c8df
fix: improve pill contrast by using WCAG contrast ratios on composite…
Mar 23, 2026
e0d2c4b
Ignore .paperclip in dev restart detection
Mar 21, 2026
5a1e17f
Fix issue workspace reuse after isolation
Mar 21, 2026
02c779b
Use issue participation for agent history
Mar 21, 2026
eac3f3f
Honor explicit failed-run session resume
Mar 21, 2026
75c7eb3
Ignore test-only paths in dev restart tracking
Mar 22, 2026
a315838
fix: preserve agent instructions on adapter switch
Mar 22, 2026
1adfd30
fix: recover managed agent instructions from disk
Mar 23, 2026
3b2cb3a
Show all companies' agents on instance heartbeats page
Mar 23, 2026
0bb1ee3
Recover agent instructions from disk
Mar 23, 2026
43b21c6
Ignore .paperclip paths in restart tracking
Mar 23, 2026
2daae75
Include all agents on heartbeats page regardless of interval config
Mar 23, 2026
c0c1fd1
Add "Disable All" button to heartbeats settings page
Mar 23, 2026
19154d0
Clarify Codex instruction sources
Mar 23, 2026
d8b4086
fix providers
Mar 23, 2026
8fa4b6a
added a script to generate company assets
Mar 23, 2026
2e76a2a
Add routine support to recurring task portability
Mar 23, 2026
c41dd2e
Reduce portability warning fan-out
Mar 23, 2026
220946b
Default recurring task exports to checked
Mar 23, 2026
ac376d0
Add TUI import summaries
Mar 23, 2026
a339b48
fix: dedupe company skill inventory refreshes
Mar 23, 2026
1246ccf
Add nested import picker
Mar 23, 2026
06f5632
Polish import adapter defaults
Mar 23, 2026
c02dc73
Confirm company imports after preview
Mar 23, 2026
2a6e1cf
Fix imported GitHub skill file paths
Mar 23, 2026
56a39fe
Add importing & exporting company guide
Mar 23, 2026
66d84cc
Add companies.sh import wrapper
Mar 23, 2026
9786ebb
Revert "Add companies.sh import wrapper"
Mar 23, 2026
dcead97
Fix company zip imports
Mar 23, 2026
f9927bd
Disable imported timer heartbeats
Mar 23, 2026
b5fde73
Open imported company after import
Mar 23, 2026
159c5b4
Preserve sidebar order in company portability
Mar 23, 2026
6f1ce3b
Document imported heartbeat defaults
Mar 23, 2026
a3f568d
Improve generated company org chart assets
Mar 23, 2026
c3f4e18
Keep sidebar ordering with portability branch
Mar 23, 2026
6960ab1
Address Greptile review on UI polish PR
Mar 23, 2026
55b26ed
Address Greptile review on agent runtime PR
Mar 23, 2026
92c29f2
Address Greptile review on portability PR
Mar 23, 2026
dd1d9be
fix(server): check MIGRATION_AUTO_APPLY before MIGRATION_PROMPT
devinfoley Mar 23, 2026
7576c5e
Update ui/src/pages/Auth.tsx
cryppadotta Mar 24, 2026
2cc2d44
Remove lockfile changes from UI polish PR
Mar 24, 2026
36574bd
chore: add GitHub PR template
devinfoley Mar 24, 2026
5222a49
chore: expand thinking path placeholder for depth
devinfoley Mar 24, 2026
85d2c54
fix(ci): refresh lockfile in PR jobs
Mar 24, 2026
22067c7
revert: drop PR workflow lockfile refresh
Mar 24, 2026
fa084e1
Merge pull request #1653 from paperclipai/pr/pap-795-ui-polish
cryppadotta Mar 24, 2026
4096db8
chore(lockfile): refresh pnpm-lock.yaml (#1667)
github-actions[bot] Mar 24, 2026
87b3cac
Address valid Greptile portability follow-ups
Mar 24, 2026
c8f8f67
fix: address latest Greptile runtime review
Mar 24, 2026
f2637e6
Merge pull request #1654 from paperclipai/pr/pap-795-agent-runtime
cryppadotta Mar 24, 2026
eeb7e1a
Merge pull request #1655 from paperclipai/pr/pap-795-company-portability
cryppadotta Mar 24, 2026
e4e5b61
Fix imported agent bundle frontmatter leakage
Mar 24, 2026
a346ad2
Fix instructions tab state on agent switch
Mar 24, 2026
7c54b6e
Extract mention-aware link node helper and add tests
Mar 24, 2026
08bdc3d
Handle nested imported AGENTS edge case
Mar 24, 2026
a3f4e6f
Preserve prompts panel width on agent switch
Mar 24, 2026
f92d2c3
Merge pull request #1668 from paperclipai/pr/pap-803-imported-agent-f…
cryppadotta Mar 24, 2026
70bd55a
Merge pull request #1669 from paperclipai/pr/pap-803-agent-instructio…
cryppadotta Mar 24, 2026
32c76e0
Merge pull request #1670 from paperclipai/pr/pap-803-mention-aware-li…
cryppadotta Mar 24, 2026
8ae954b
Merge pull request #1666 from paperclipai/chore/pr-template
devinfoley Mar 24, 2026
fd4df4d
fix(docker): add plugin-sdk to Dockerfile build
devinfoley Mar 24, 2026
59e29af
Merge pull request #1672 from paperclipai/fix/docker-plugin-sdk
devinfoley Mar 24, 2026
730a67b
fix(issues): decode HTML entities in @mention tokens instead of strip…
amit221 Mar 24, 2026
53f0988
Merge origin/master into fix/issue-1255
amit221 Mar 24, 2026
2735ef1
fix(issues): decode @mention entities without lockfile or new deps
amit221 Mar 24, 2026
98a5e28
test(issues): document Greptile mid-token case vs old strip behavior
amit221 Mar 24, 2026
14ffbe3
test(issues): shorten mid-token entity test comment
amit221 Mar 24, 2026
a9dcea0
fix(codex): check native auth before warning about missing API key
devinfoley Mar 24, 2026
5561a9c
Improve CLI API connection errors
Mar 24, 2026
67841a0
Remove noisy "Loaded agent instructions file" log from all adapters
Mar 24, 2026
c4838cc
Render join requests inline in inbox like approvals and other work items
Mar 24, 2026
5602576
Fix embedded Postgres initdb failure in Docker slim containers
Mar 24, 2026
eb73fc7
Seed onboarding project and issue goal context
Mar 24, 2026
44fbf83
Preserve task assignment grants for joined agents
Mar 24, 2026
3447e20
Fix agent mention pill vertical misalignment with project mention pill
Mar 24, 2026
06b85d6
test(codex): add coverage for native auth detection in environment probe
devinfoley Mar 24, 2026
4ff460d
Fix embedded-postgres patch env lookup
Mar 24, 2026
f352f3f
Force embedded-postgres messages locale to C
Mar 24, 2026
4b66837
Regenerate embedded-postgres vendor patch
Mar 24, 2026
58c511a
test(codex): isolate auth tests from host OPENAI_API_KEY
devinfoley Mar 24, 2026
331e1f0
Merge pull request #1704 from paperclipai/pr/pap-817-cli-api-connecti…
cryppadotta Mar 24, 2026
de5985b
Merge pull request #1705 from paperclipai/pr/pap-817-remove-instructi…
cryppadotta Mar 24, 2026
6250d53
Merge pull request #1706 from paperclipai/pr/pap-817-inline-join-requ…
cryppadotta Mar 24, 2026
8bebc95
Merge pull request #1707 from paperclipai/pr/pap-817-embedded-postgre…
cryppadotta Mar 24, 2026
04a0708
chore(lockfile): refresh pnpm-lock.yaml (#1712)
github-actions[bot] Mar 24, 2026
add6ca5
Merge pull request #1709 from paperclipai/pr/pap-817-join-request-tas…
cryppadotta Mar 24, 2026
d38d5e1
Merge pull request #1710 from paperclipai/pr/pap-817-agent-mention-pi…
cryppadotta Mar 24, 2026
03f44d0
Merge pull request #1708 from paperclipai/pr/pap-817-onboarding-goal-…
cryppadotta Mar 24, 2026
0ce4134
fix(codex): use actual CODEX_HOME in auth detail message
devinfoley Mar 24, 2026
4da8329
test(codex): move OPENAI_API_KEY stub to beforeEach for all tests
devinfoley Mar 24, 2026
4eecd23
fix(codex): use codexHomeDir() fallback for accurate auth detail path
devinfoley Mar 24, 2026
1696ff0
fix(codex): use path.join for auth detail message path
devinfoley Mar 24, 2026
fea892c
Merge pull request #1702 from paperclipai/fix/codex-auth-check
devinfoley Mar 24, 2026
ff8b839
Merge pull request #1658 from paperclipai/fix/migration-auto-apply-pr…
devinfoley Mar 24, 2026
0a952dc
fix(docker): copy patches directory into deps stage
devinfoley Mar 24, 2026
b1d12d2
Merge pull request #1730 from paperclipai/fix/docker-patches
devinfoley Mar 24, 2026
cbca599
Merge pull request #1363 from amit221/fix/issue-1255
devinfoley Mar 25, 2026
9637351
docs(release): add v2026.325.0 changelog
Mar 25, 2026
db3883d
Merge pull request #1748 from paperclipai/pr/pap-849-release-changelog
cryppadotta Mar 25, 2026
eeec52a
Fix Codex skill injection to use ~/.codex/skills/ instead of cwd
devinfoley Mar 25, 2026
623ab1c
Fix skill injection to use effective CODEX_HOME, not shared home
devinfoley Mar 25, 2026
f6ac6e4
Clarify docs: skills go to $CODEX_HOME/skills/, defaulting to ~/.codex
devinfoley Mar 25, 2026
4c6b9c1
Fix stale reference to resolveCodexSkillsHome in fallback path
devinfoley Mar 25, 2026
72bc4ab
fix(opencode): prevent opencode.json config pollution in workspace
devinfoley Mar 26, 2026
1549799
Move OPENCODE_DISABLE_PROJECT_CONFIG after envConfig loop
devinfoley Mar 26, 2026
c5c6c62
Merge pull request #1786 from paperclipai/fix/opencode-disable-projec…
devinfoley Mar 26, 2026
80766e5
Clarify docs: skills go to the effective CODEX_HOME, not ~/.codex
devinfoley Mar 26, 2026
083d7c9
fix(cursor): check native auth before warning about missing API key
devinfoley Mar 26, 2026
6ebfc0f
Merge pull request #1782 from paperclipai/fix/codex-skill-injection-l…
devinfoley Mar 26, 2026
bd60ea4
refactor: use async fs.readFile in readCursorAuthInfo for consistency
devinfoley Mar 26, 2026
1a4ed8c
Merge pull request #1794 from paperclipai/fix/cursor-native-auth-check
devinfoley Mar 26, 2026
9e9eec9
ci: validate Dockerfile deps stage in PR policy (#1799)
devinfoley Mar 26, 2026
8ea175f
sync: merge upstream/master (2026-03-26)
Mar 26, 2026
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
49 changes: 49 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## Thinking Path

<!--
Required. Trace your reasoning from the top of the project down to this
specific change. Start with what Paperclip is, then narrow through the
subsystem, the problem, and why this PR exists. Use blockquote style.
Aim for 5–8 steps. See CONTRIBUTING.md for full examples.
-->

> - Paperclip orchestrates AI agents for zero-human companies
> - [Which subsystem or capability is involved]
> - [What problem or gap exists]
> - [Why it needs to be addressed]
> - This pull request ...
> - The benefit is ...

## What Changed

<!-- Bullet list of concrete changes. One bullet per logical unit. -->

-

## Verification

<!--
How can a reviewer confirm this works? Include test commands, manual
steps, or both. For UI changes, include before/after screenshots.
-->

-

## Risks

<!--
What could go wrong? Mention migration safety, breaking changes,
behavioral shifts, or "Low risk" if genuinely minor.
-->

-

## Checklist

- [ ] I have included a thinking path that traces from project context to this change
- [ ] I have run tests locally and they pass
- [ ] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after screenshots
- [ ] I have updated relevant documentation to reflect my changes
- [ ] I have considered and documented any risks above
- [ ] I will address all Greptile and reviewer comments before requesting merge
55 changes: 55 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Docker

on:
push:
branches:
- "master"
tags:
- "v*"

permissions:
contents: read
packages: write

jobs:
build-and-push:
runs-on: ubuntu-latest
timeout-minutes: 30
concurrency:
group: docker-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Login to GitHub Container Registry
uses: docker/login-action@v3

Check warning on line 26 in .github/workflows/docker.yml

View check run for this annotation

GitHub Advanced Security / CodeQL

Unpinned tag for a non-immutable Action in workflow

Unpinned 3rd party Action 'Docker' step [Uses Step](1) uses 'docker/login-action' with ref 'v3', not a pinned commit hash

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Docker' step
Uses Step
uses 'docker/login-action' with ref 'v3', not a pinned commit hash
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Check warning on line 33 in .github/workflows/docker.yml

View check run for this annotation

GitHub Advanced Security / CodeQL

Unpinned tag for a non-immutable Action in workflow

Unpinned 3rd party Action 'Docker' step [Uses Step](1) uses 'docker/setup-buildx-action' with ref 'v3', not a pinned commit hash

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Docker' step
Uses Step
uses 'docker/setup-buildx-action' with ref 'v3', not a pinned commit hash

- name: Docker meta
id: meta
uses: docker/metadata-action@v5

Check warning on line 37 in .github/workflows/docker.yml

View check run for this annotation

GitHub Advanced Security / CodeQL

Unpinned tag for a non-immutable Action in workflow

Unpinned 3rd party Action 'Docker' step [Uses Step: meta](1) uses 'docker/metadata-action' with ref 'v5', not a pinned commit hash

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Docker' step
Uses Step: meta
uses 'docker/metadata-action' with ref 'v5', not a pinned commit hash
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha

- name: Build and push
uses: docker/build-push-action@v6

Check warning on line 47 in .github/workflows/docker.yml

View check run for this annotation

GitHub Advanced Security / CodeQL

Unpinned tag for a non-immutable Action in workflow

Unpinned 3rd party Action 'Docker' step [Uses Step](1) uses 'docker/build-push-action' with ref 'v6', not a pinned commit hash

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Docker' step
Uses Step
uses 'docker/build-push-action' with ref 'v6', not a pinned commit hash
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
40 changes: 40 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,46 @@ jobs:
with:
node-version: 24

- name: Validate Dockerfile deps stage
run: |
missing=0

# Extract only the deps stage from the Dockerfile
deps_stage="$(awk '/^FROM .* AS deps$/{found=1; next} found && /^FROM /{exit} found{print}' Dockerfile)"

if [ -z "$deps_stage" ]; then
echo "::error::Could not extract deps stage from Dockerfile (expected 'FROM ... AS deps')"
exit 1
fi

# Derive workspace search roots from pnpm-workspace.yaml (exclude dev-only packages)
search_roots="$(grep '^ *- ' pnpm-workspace.yaml | sed 's/^ *- //' | sed 's/\*$//' | grep -v 'examples' | grep -v 'create-paperclip-plugin' | tr '\n' ' ')"

if [ -z "$search_roots" ]; then
echo "::error::Could not derive workspace roots from pnpm-workspace.yaml"
exit 1
fi

# Check all workspace package.json files are copied in the deps stage
for pkg in $(find $search_roots -maxdepth 2 -name package.json -not -path '*/examples/*' -not -path '*/create-paperclip-plugin/*' -not -path '*/node_modules/*' 2>/dev/null | sort -u); do
dir="$(dirname "$pkg")"
if ! echo "$deps_stage" | grep -q "^COPY ${dir}/package.json"; then
echo "::error::Dockerfile deps stage missing: COPY ${pkg} ${dir}/"
missing=1
fi
done

# Check patches directory is copied if it exists
if [ -d patches ] && ! echo "$deps_stage" | grep -q '^COPY patches/'; then
echo "::error::Dockerfile deps stage missing: COPY patches/ patches/"
missing=1
fi

if [ "$missing" -eq 1 ]; then
echo "Dockerfile deps stage is out of sync. Update it to include the missing files."
exit 1
fi

- name: Validate dependency resolution when manifests change
run: |
changed="$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}")"
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ COPY packages/adapters/gemini-local/package.json packages/adapters/gemini-local/
COPY packages/adapters/openclaw-gateway/package.json packages/adapters/openclaw-gateway/
COPY packages/adapters/opencode-local/package.json packages/adapters/opencode-local/
COPY packages/adapters/pi-local/package.json packages/adapters/pi-local/
COPY packages/plugins/sdk/package.json packages/plugins/sdk/
COPY patches/ patches/

RUN pnpm install --frozen-lockfile

Expand All @@ -28,6 +30,7 @@ WORKDIR /app
COPY --from=deps /app /app
COPY . .
RUN pnpm --filter @paperclipai/ui build
RUN pnpm --filter @paperclipai/plugin-sdk build
RUN pnpm --filter @paperclipai/server build
RUN test -f server/dist/index.js || (echo "ERROR: server build output missing" && exit 1)

Expand Down
Binary file added admin-final.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added admin-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added agent-running.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions cli/src/__tests__/auth-command-registration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Command } from "commander";
import { describe, expect, it } from "vitest";
import { registerClientAuthCommands } from "../commands/client/auth.js";

describe("registerClientAuthCommands", () => {
it("registers auth commands without duplicate company-id flags", () => {
const program = new Command();
const auth = program.command("auth");

expect(() => registerClientAuthCommands(auth)).not.toThrow();

const login = auth.commands.find((command) => command.name() === "login");
expect(login).toBeDefined();
expect(login?.options.filter((option) => option.long === "--company-id")).toHaveLength(1);
});
});
53 changes: 53 additions & 0 deletions cli/src/__tests__/board-auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import {
getStoredBoardCredential,
readBoardAuthStore,
removeStoredBoardCredential,
setStoredBoardCredential,
} from "../client/board-auth.js";

function createTempAuthPath(): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-cli-auth-"));
return path.join(dir, "auth.json");
}

describe("board auth store", () => {
it("returns an empty store when the file does not exist", () => {
const authPath = createTempAuthPath();
expect(readBoardAuthStore(authPath)).toEqual({
version: 1,
credentials: {},
});
});

it("stores and retrieves credentials by normalized api base", () => {
const authPath = createTempAuthPath();
setStoredBoardCredential({
apiBase: "http://localhost:3100/",
token: "token-123",
userId: "user-1",
storePath: authPath,
});

expect(getStoredBoardCredential("http://localhost:3100", authPath)).toMatchObject({
apiBase: "http://localhost:3100",
token: "token-123",
userId: "user-1",
});
});

it("removes stored credentials", () => {
const authPath = createTempAuthPath();
setStoredBoardCredential({
apiBase: "http://localhost:3100",
token: "token-123",
storePath: authPath,
});

expect(removeStoredBoardCredential("http://localhost:3100", authPath)).toBe(true);
expect(getStoredBoardCredential("http://localhost:3100", authPath)).toBeNull();
});
});
Loading
Loading