Skip to content

feat(cli): add profiles - default team/project stored in local SQLite - #57

Merged
bougyman merged 3 commits into
mainfrom
56-profiles-default-team-project
Aug 10, 2026
Merged

feat(cli): add profiles - default team/project stored in local SQLite#57
bougyman merged 3 commits into
mainfrom
56-profiles-default-team-project

Conversation

@bougyman

Copy link
Copy Markdown
Member

Summary

Closes #56.

Full design in documents/phase-9-plan.adoc.

  • LinearCli.Profiles: named team/project bundles in ~/.linear_cli/profiles.db (separate from Oban's own oban.db), with at most one active profile enforced by a partial unique index. Uses Exqlite.Sqlite3 directly rather than a new Ecto.Repo - interactive mode's supervisor is deliberately empty, and Oban's own migrations are only ever run externally via mix ecto.migrate; neither fits a one-shot CLI with no deploy step.
  • New lc profile create/list/use/show/delete.
  • issue create/issue list fall back to the active profile's team/project when --team/--project are omitted - an explicit flag still always wins.

Test plan

  • mix test - 197/198 passed (1 pre-existing, unrelated failure in LinearCli.GitTest - confirmed it fails identically with these changes stashed out, a local git-environment flake)
  • mix format --check-formatted - clean
  • Manual smoke test: lc profile create/list/use/show/delete end to end
  • New tests: LinearCli.ProfilesTest (data layer) and LinearCli.CLI.ProfileDefaultsTest (the fallback wiring in make_da_issue!/1 and issue_list/1, including that an explicit flag overrides the active profile)
  • Fixed a real test-isolation gap found along the way: test_helper.exs now clears the test profiles db once at suite start, since a stray active profile left on disk by an earlier run was leaking into unrelated tests

Refs #56.

Design for a new profiles feature: named, switchable team/project
bundles stored in a new local SQLite file (~/.linear_cli/profiles.db,
separate from Oban's own oban.db), backing lc profile
create/list/use/show/delete and filling in --team/--project defaults
for issue create/issue list when the flag is omitted. Implementation
commits follow on this branch.
Refs #56.

LinearCli.Profiles: named team/project bundles in ~/.linear_cli/profiles.db
(dev/test get their own file paths in config/runtime.exs), with at most
one active profile enforced by a partial unique index. Uses Exqlite
directly rather than a new Ecto.Repo - interactive mode's supervisor is
deliberately empty (see LinearCli.Application), and Oban's own migrations
are only ever run externally via mix ecto.migrate, neither of which fits
a one-shot CLI with no deploy step.

New `lc profile create/list/use/show/delete` command. issue create and
issue list now fall back to the active profile's team/project when
--team/--project are omitted; an explicit flag still always wins.

Readme documents the new commands. test_helper.exs clears the test
profiles db once at suite start so a stray active profile from an earlier
run can't leak into unrelated tests.
Copilot AI lite review requested due to automatic review settings August 10, 2026 15:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a first-class “profiles” feature to the Linear CLI so users can persist and switch default team/project selections (stored locally in a dedicated SQLite DB) and have issue create / issue list automatically fall back to the active profile when flags are omitted.

Changes:

  • Introduces LinearCli.Profiles backed by ~/.linear_cli/profiles.db, including schema bootstrapping and an “exactly one active” invariant via a partial unique index.
  • Adds lc profile create/list/use/show/delete wiring (Optimus spec, dispatch, commands) plus profile rendering in Display.
  • Wires profile defaults into IssueHelpers.make_da_issue!/1 and Commands.issue_list/1, with new tests and test-suite DB cleanup.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Readme.adoc Documents the new profiles feature and basic CLI usage.
documents/phase-9-plan.adoc Adds the phase-9 design document describing decisions and intended behavior.
app/test/test_helper.exs Removes the test profiles DB at suite start to prevent cross-run leakage.
app/test/linear_cli/profiles_test.exs Adds unit tests for LinearCli.Profiles CRUD/activation behavior.
app/test/linear_cli/cli/profile_defaults_test.exs Adds integration-ish tests for default fallback behavior in issue_list and make_da_issue!.
app/lib/linear_cli/profiles.ex Implements the profiles SQLite data layer (create/list/activate/active/delete/default_*).
app/lib/linear_cli/cli/issue_helpers.ex Applies profile fallback for omitted :team/:project during issue creation.
app/lib/linear_cli/cli/display.ex Adds text output formatting for Profiles.Profile.
app/lib/linear_cli/cli/commands.ex Adds profile_* commands and applies profile fallback in issue_list/1.
app/lib/linear_cli/cli.ex Registers the new profile command, aliases, and dispatch clauses.
app/config/runtime.exs Configures :profiles_db_path per env (dev/test/prod).
app/.gitignore Ignores local dev/test profiles DB files.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/lib/linear_cli/profiles.ex
…file on a failed switch

activate/1 deactivated every profile before checking whether the target
name existed, so `lc profile use <unknown>` left no profile active at
all instead of leaving the previous one in place - a user-visible state
change on a command that's supposed to fail. Wraps both updates in a
transaction and rolls back on :not_found.
@bougyman
bougyman merged commit 554e336 into main Aug 10, 2026
2 checks passed
@bougyman
bougyman deleted the 56-profiles-default-team-project branch August 10, 2026 16:38
bougyman added a commit that referenced this pull request Aug 11, 2026
…61)

## Summary

Closes #60.

Full design in `documents/phase-10-plan.adoc`.

- `LinearCli.Favorites`: a new `favorites` table in the same local
sqlite file `LinearCli.Profiles` (#56/#57) already uses - storing
resolved team keys and project ids (not raw search text, so filtering
never needs re-fuzzy-matching).
- New `lc team favorite/unfavorite <TEAM>` and `lc project
favorite/unfavorite <PROJECT>`.
- `team list`/`project list` default to favorites-only once any favorite
of that kind exists; `--all` opts back out to today's full list.
Invisible to anyone who's never favorited anything.

This is the prerequisite for #59 (bare issue numbers resolved via
favorited teams, Phase 11) - not part of this PR.

## Test plan

- [x] `mix test` - full suite green apart from one pre-existing,
unrelated flake in `LinearCli.GitTest` (confirmed it fails identically
on `main` before this branch's changes)
- [x] `mix format --check-formatted` - clean
- [x] New tests: `LinearCli.FavoritesTest` (data layer) and
`LinearCli.CLI.FavoritesCommandsTest` (10 tests, full
`LinearCli.CLI.main/2` invocations - favorite/unfavorite for both teams
and projects, favorites-only-by-default filtering, `--all` override, and
the zero-favorites case explicitly asserted unchanged)
- [x] `Readme.adoc` documents the new commands
bougyman pushed a commit that referenced this pull request Aug 11, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.8.4](v0.8.3...v0.8.4)
(2026-08-11)


### Features

* **cli:** add favorite teams/projects, filtering list views by them
([#61](#61))
([6c858d9](6c858d9))
* **cli:** add profiles - default team/project stored in local SQLite
([#57](#57))
([554e336](554e336))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Aug 11, 2026
bougyman pushed a commit that referenced this pull request Aug 11, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.0.0](v1.0.0...v1.0.0)
(2026-08-11)


### ⚠ BREAKING CHANGES

* graduate to 1.0.0 - disable pre-major version bumping
([#70](#70))
* **cd:** parallelize Burrito target builds and fix Trivy/Podman image
scanning ([#68](#68))
* **ci:** rename release.yaml to main.yaml, workflow name to "main"
([#38](#38))
* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))

### Features

* add mix githooks.install to activate the repo's git hooks
([#51](#51))
([9b35472](9b35472))
* **api:** add LinearCli.Api GraphQL client (Phase 1)
([723f3f6](723f3f6))
* **ci:** add a full SBOM - app deps, OTP/Elixir runtime, container OS
packages ([#54](#54))
([e296fdd](e296fdd))
* **cli:** add favorite teams/projects, filtering list views by them
([#61](#61))
([6c858d9](6c858d9))
* **cli:** add issue create/develop/pr/take/update write commands (Phase
6)
([1649618](1649618))
* **cli:** add profiles - default team/project stored in local SQLite
([#57](#57))
([554e336](554e336))
* **cli:** add project update - post a status update to a project
([#43](#43))
([30dc6dc](30dc6dc))
* **cli:** make version respect --output json
([#33](#33))
([b160aad](b160aad))
* **cli:** resolve bare issue numbers via active profile, favorited
teams, or a team prompt
([#65](#65))
([8b183da](8b183da))
* **cli:** support Ruby's short subcommand aliases
([#15](#15))
([9fca6b5](9fca6b5))
* initial commit with ash submodule
([c2ceafb](c2ceafb))
* **linear:** add Ash domain resources for
Issue/Project/Team/User/Label/WorkflowState/Comment (Phase 2)
([e2a27f3](e2a27f3))
* **oban:** add scheduled monthly project rollover (Phase 7)
([11afb43](11afb43))
* phase 4 from initial plan -&gt; complete
([012866e](012866e))
* phase 8 - packaging, releasing, and CI
([#1](#1))
([905c238](905c238))
* scaffold Elixir port and enforce conventional commits
([a4d03a0](a4d03a0))


### Bug Fixes

* **ci:** consolidate the release pipeline into one workflow/DAG
([ba821bb](ba821bb))
* **ci:** create releases as drafts so assets survive Immutable Releases
([#19](#19))
([8572623](8572623))
* **ci:** package release binaries with the wrapper scripts
([#24](#24))
([5fb24a4](5fb24a4))
* **ci:** rebuild the release pipeline to stop the version-bump runaway
loop ([#30](#30))
([c311fd4](c311fd4))
* **ci:** relabel the release PR as tagged after we tag it ourselves
([ab1408e](ab1408e))
* **ci:** skip commit-subject validation in the post-merge pipeline
([#41](#41))
([3d00a85](3d00a85))
* **cli:** reject unrecognized flags instead of treating them as issue
ids ([#2](#2))
([#4](#4))
([e697ff6](e697ff6))
* **deps:** update ash to a non-vulnerable version
([#63](#63))
([b838e2a](b838e2a))


### Performance Improvements

* **linear:** fan out find-by-ids and per-team project fetches (Phase 5)
([fb00153](fb00153))


### Documentation

* add Readme/LICENSE, feat: wire up the issue list --project picker
([#12](#12))
([eb42c69](eb42c69))


### Miscellaneous Chores

* **ci:** rename release.yaml to main.yaml, workflow name to "main"
([#38](#38))
([2581a40](2581a40))
* graduate to 1.0.0 - disable pre-major version bumping
([#70](#70))
([87a65ae](87a65ae))


### Continuous Integration

* **cd:** parallelize Burrito target builds and fix Trivy/Podman image
scanning ([#68](#68))
([5cc829a](5cc829a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add profiles: switchable default team/project stored in local SQLite

2 participants