Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
54059fd
docs: add SSOmatic 2.0 daemon + list-first UX design spec
tux86 Jun 11, 2026
b526728
docs: add SSOmatic 2.0 implementation plan
tux86 Jun 11, 2026
3979fa3
build(deps): upgrade ink, react, aws-sdk and toolchain to latest
tux86 Jun 11, 2026
dc21e32
refactor(aws): split settings into settings.ts with expiry-aware shape
tux86 Jun 11, 2026
e41f80a
feat(aws): add console signin URL and export-block builders
tux86 Jun 11, 2026
673f595
feat(cli): add daemon wire protocol and ndjson codec
tux86 Jun 11, 2026
b496390
feat(cli): add daemon runtime paths and single-instance detection
tux86 Jun 11, 2026
255a33d
feat(cli): add expiry-aware scheduler decision
tux86 Jun 11, 2026
641d33d
feat(cli): add unix-socket daemon server with subscribe/snapshot/refresh
tux86 Jun 11, 2026
b8a23f8
fix(cli): destroy all daemon connections on stop and surface handler …
tux86 Jun 11, 2026
5b4bfe9
feat(cli): add daemon entry, detached spawn, and socket client
tux86 Jun 11, 2026
a105d8e
fix(cli): make daemon refresh expiry-aware via role-credential expiry
tux86 Jun 11, 2026
6b864c6
fix(cli): close daemon log fd, guard cred expiry fallback, reset noti…
tux86 Jun 11, 2026
fd1d262
feat(cli): add status, export, refresh, and daemon subcommands
tux86 Jun 11, 2026
6f94800
feat(cli): route argv to subcommands, daemon, or TUI
tux86 Jun 11, 2026
9547310
feat(cli): add useDaemon hook for live socket state
tux86 Jun 11, 2026
5575ff6
feat(cli): add list-first dashboard component
tux86 Jun 11, 2026
afc4a77
feat(cli): replace menu UI with list-first dashboard, details, and se…
tux86 Jun 11, 2026
dbda704
fix(cli): stop global q-quit from firing during filter typing; surfac…
tux86 Jun 11, 2026
c5428de
refactor(cli): remove dead menu-era components and update CLAUDE.md
tux86 Jun 11, 2026
ef0d7b3
docs: rewrite README and refine npm metadata for v2 (dashboard + daemon)
tux86 Jun 11, 2026
5962e77
fix(cli): reply to refresh/setFavorite requests, harden socket, promp…
tux86 Jun 11, 2026
7304490
feat(cli): redesign dashboard — highlight cursor, auto-refresh (a/⟳),…
tux86 Jun 11, 2026
648ef6e
fix(cli): make dashboard footer keys stand out and tie a to the auto-…
tux86 Jun 11, 2026
bcb9106
fix(cli): harmonize shortcut footers across screens and make q quit o…
tux86 Jun 11, 2026
62748e0
fix(cli): harmonize shortcut footers; Esc=back on sub-screens, q quit…
tux86 Jun 11, 2026
c36e073
refactor(cli): replace daemon dependency with in-process auto-refresh…
tux86 Jun 11, 2026
5b0f16b
refactor(cli): remove background daemon, socket, and daemon CLI — sin…
tux86 Jun 11, 2026
c0d4b0b
feat(cli): add fire-gradient ASCII wordmark header
tux86 Jun 11, 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
62 changes: 54 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,46 @@

Distributed via npm (`npx ssomatic`). Settings (favorites, notifications, refresh interval) are persisted across sessions.

SSOmatic is a single-process TUI. While open it auto-refreshes the ⟳ (pinned) profiles' role credentials in an expiry-aware manner, and sends a desktop notification when an interactive SSO browser login is needed. No background process — quitting fully exits.

## Structure

```
ssomatic/
├── src/
│ ├── aws/ # Shared AWS logic (UI-agnostic)
│ │ ├── sso.ts # SSO profiles, tokens, refresh, settings
│ │ ├── sso.test.ts # Unit tests for sso.ts
│ │ ├── sso.ts # SSO profiles, tokens, refresh
│ │ ├── sso.test.ts
│ │ ├── settings.ts # Persistent settings (favorites, notifications, interval)
│ │ ├── settings.test.ts
│ │ ├── console.ts # AWS console URL builders
│ │ ├── console.test.ts
│ │ ├── profileState.ts # ProfileState types + local-state builder
│ │ ├── refreshScheduler.ts # Expiry-aware refresh decision (decideAction)
│ │ ├── aws.ts # STS identity utilities
│ │ ├── utils.ts # Clipboard, JSON formatting
│ │ └── utils.test.ts # Unit tests for utils.ts
│ │ └── utils.test.ts
│ └── cli/ # Terminal UI (React/Ink)
│ ├── index.tsx # Entry point
│ ├── components/ # Ink UI components
│ └── hooks/ # Ink hooks (useIdentity, useCopy)
│ ├── index.tsx # Entry point + argument router
│ ├── args.ts # CLI argument parsing
│ ├── args.test.ts
│ ├── commands/ # Non-TUI subcommands
│ │ ├── status.ts # `ssomatic status`
│ │ ├── status.test.ts
│ │ ├── export.ts # `ssomatic export <profile>`
│ │ └── refresh.ts # `ssomatic refresh [profile]`
│ ├── tui/ # TUI screens
│ │ ├── Dashboard.tsx # Main profile list view
│ │ ├── Details.tsx # Profile detail view
│ │ ├── Settings.tsx # Settings screen
│ │ └── useAutoRefresh.ts # Hook: in-process auto-refresh for ⟳ profiles
│ ├── components/ # Shared Ink UI components
│ │ ├── App.tsx # Root container
│ │ ├── ActionBar.tsx # Bottom action bar + ACTIONS constant
│ │ ├── Spinner.tsx
│ │ └── StatusMessage.tsx
│ └── hooks/ # Shared hooks
│ └── useCopy.tsx # Clipboard copy with feedback
├── dist/ # Build output
│ └── cli.js # Node CLI bundle (npm bin)
├── docs/screenshots/ # Demo GIFs for README
Expand All @@ -42,6 +67,8 @@ ssomatic/

## Commands

### Dev / Build / Test

```bash
bun install # Install dependencies
bun run start # Run CLI
Expand All @@ -51,11 +78,30 @@ bun run lint # Run ESLint
bun test # Run unit tests
```

## Keyboard Shortcuts
### Runtime CLI subcommands

```bash
ssomatic # Launch the interactive TUI
ssomatic status # Print profile statuses and exit
ssomatic refresh [profile] # Refresh a profile (or all favorites) now
ssomatic export <profile> # Print export AWS_* lines (use with eval $(ssomatic export <profile>))
ssomatic --version
```

## Keyboard Shortcuts (Dashboard)

| Key | Action |
|-----|--------|
| `Escape` | Back |
| `↑` / `↓` / `k` / `j` | Move cursor |
| `⏎` | Open details |
| `r` | Refresh the current profile |
| `a` | Toggle ⟳ auto-refresh |
| `c` | Copy export (`AWS_*` env vars) |
| `y` | Copy profile name |
| `o` | Open AWS console |
| `/` | Filter profiles |
| `s` | Open settings |
| `Esc` | Back |
| `q` | Quit |

## Commits & Releases
Expand Down
141 changes: 83 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
# SSOmatic

Interactive AWS SSO credential manager for your terminal.
Keep your AWS SSO credentials fresh — automatically. A fast terminal dashboard that auto-refreshes your pinned profiles while it's open.

[![npm version](https://img.shields.io/npm/v/ssomatic)](https://www.npmjs.com/package/ssomatic)
[![CI](https://github.com/tux86/ssomatic/actions/workflows/ci.yml/badge.svg)](https://github.com/tux86/ssomatic/actions/workflows/ci.yml)
[![Release](https://github.com/tux86/ssomatic/actions/workflows/release.yml/badge.svg)](https://github.com/tux86/ssomatic/actions/workflows/release.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![GitHub Stars](https://img.shields.io/github/stars/tux86/ssomatic)](https://github.com/tux86/ssomatic)
[![Bun](https://img.shields.io/badge/Bun-%23000000.svg?logo=bun&logoColor=white)](https://bun.sh)
[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)

---

## Why SSOmatic

- **k9s-style list-first dashboard** — all your SSO profiles at a glance with live expiry countdowns; navigate with j/k or arrow keys, no menus to dig through.
- **In-process auto-refresh for ⟳ pinned profiles** — pin a profile with `a` and expiry-aware refresh keeps its credentials ready before they expire, with no fixed-interval polling waste.
- **Notify-on-login, never surprise you** — when an interactive SSO login is required SSOmatic sends a desktop notification so you know to log in.
- **One-keystroke everything** — copy `export AWS_*` vars, open the AWS console, copy the profile name, or force a refresh — all from the dashboard without leaving your terminal.
- **Single process, clean exit** — quitting fully exits. No background processes to manage.

---

## Demo

<!-- TODO: re-record demo GIF for the v2 dashboard -->
<p align="center">
<img src="docs/screenshots/cli-demo.gif" alt="SSOmatic CLI Demo" width="720">
</p>

---

## Install

```bash
Expand All @@ -23,39 +40,72 @@ bunx ssomatic
npm install -g ssomatic
```

> **Upgrading from 1.x?** SSOmatic is now a CLI-only tool distributed via npm. The
> built-in web UI has been removed, and the Homebrew tap / standalone binaries are
> replaced by npm. Uninstall the old binary (`brew uninstall ssomatic`) and use
> `npx ssomatic` or `npm i -g ssomatic` instead. Your `~/.aws` profiles and saved
> settings are unaffected.
---

## Demo
## Quick Start

<p align="center">
<img src="docs/screenshots/cli-demo.gif" alt="SSOmatic CLI Demo" width="720">
</p>
```bash
# 1. Launch the dashboard
ssomatic

## Features
# 2. Navigate to a profile and press 'a' to pin it for auto-refresh
# 3. SSOmatic auto-refreshes pinned profiles while the dashboard is open
# 4. Press 'q' to quit when done
```

- **Auto-discovery** — Scans `~/.aws/config` for SSO profiles (legacy and sso_session)
- **Status dashboard** — View credential validity with expiry countdown
- **Multi-select refresh** — Refresh multiple profiles at once with SSO device auth
- **Auto-refresh daemon** — Background process to keep credentials fresh
- **Desktop notifications** — Alerts when credentials expire (macOS/Linux)
- **Persistent settings** — Notifications and favorites saved across sessions
While the dashboard is open, ⟳ pinned profiles are refreshed automatically when their credentials are close to expiry. When a browser login is required, you get a desktop notification and can log in directly from the TUI or with `ssomatic refresh <profile>`.

## Prerequisites
---

- [AWS CLI v2](https://aws.amazon.com/cli/) configured with SSO profiles in `~/.aws/config`
## Commands

| Command | Description |
|---------|-------------|
| `ssomatic` | Launch the interactive TUI |
| `ssomatic status` | Print profile statuses and exit |
| `ssomatic refresh [name]` | Refresh a profile (or all favorites) now |
| `ssomatic export <name>` | Print `export AWS_*` lines for `eval $(...)` |
| `ssomatic --version` | Print version and exit |

## Usage
**Shell trick — inject credentials into your current shell:**

Launch it (`ssomatic`, or `npx ssomatic` / `bunx ssomatic`) and use the interactive menu:
```bash
eval $(ssomatic export prod)
```

- **Check status** — see every SSO profile and whether its credentials are valid or expired
- **Refresh now** — log in and refresh one or more profiles (opens the SSO device-authorization flow)
- **Auto-refresh** — keep selected profiles refreshed automatically on an interval
- **Settings** — toggle notifications, set the default interval, and pick favorite profiles
---

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `↑` / `↓` or `j` / `k` | Move cursor |
| `Enter` | Open profile details |
| `r` | Refresh the current profile |
| `a` | Toggle ⟳ auto-refresh (pin/unpin) |
| `c` | Copy `export AWS_*` to clipboard |
| `y` | Copy profile name to clipboard |
| `o` | Open AWS console in browser |
| `/` | Filter profiles by name |
| `s` | Open settings |
| `Esc` | Back |
| `q` | Quit |

---

## How Auto-Refresh Works

SSOmatic tracks the role-credential expiry for each ⟳ pinned profile and refreshes only when the credentials are within the lead window of expiring (default: 5 minutes before expiry). No fixed interval; no wasted refreshes.

When an interactive SSO login is needed, a desktop notification is sent (`SSOmatic: <profile> needs login`). You authorize by logging in from the TUI or with `ssomatic refresh <profile>`.

---

## Prerequisites

- [AWS CLI v2](https://aws.amazon.com/cli/) configured with SSO profiles in `~/.aws/config`

---

## Development

Expand All @@ -66,39 +116,14 @@ git clone https://github.com/tux86/ssomatic.git
cd ssomatic
bun install

bun run start # Run from source
bun run dev # Run with --watch (auto-restart on changes)
bun run build # Build the Node CLI bundle (dist/cli.js)
bun run lint # Run ESLint
bun test # Run unit tests
```

## Project Structure

```
ssomatic/
├── src/
│ ├── aws/ # Shared AWS credential logic (sso.ts, aws.ts, utils.ts)
│ │ └── *.test.ts # Unit tests
│ └── cli/ # Terminal UI (React/Ink) — entry point
│ ├── index.tsx # Main app
│ ├── components/ # Ink UI components
│ └── hooks/ # useIdentity, useCopy
├── dist/ # Build output (dist/cli.js — the npm bin)
└── package.json
bun run start # Run from source
bun run dev # Run with --watch (auto-restart on changes)
bun run build # Build the Node CLI bundle (dist/cli.js)
bun run lint # Run ESLint
bun test # Run unit tests
```

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `↑/↓` or `j/k` | Navigate |
| `Enter` | Select |
| `Space` | Toggle selection |
| `a` | Select all / none |
| `c` | Copy URL |
| `Escape` | Back |
| `q` | Quit |
---

## Contributing

Expand Down
Loading
Loading