Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
86 changes: 56 additions & 30 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,70 @@
# Repository Guidelines

## Project Structure & Module Organization
## Project Identity
This repo is the ShellTime CLI and daemon. Public-facing docs, command examples, and product references should use `ShellTime` and `shelltime.xyz`.

Code and imports currently use the module path `github.com/malamtime/cli`. Do not "fix" ShellTime branding in docs just because the module path says `malamtime`; the mismatch is intentional in the current repo state.

## Project Structure & Package Boundaries
This is a Go monorepo for the ShellTime CLI and daemon.
- `cmd/cli/main.go`: CLI entrypoint (`shelltime`)
- `cmd/daemon/main.go`: daemon entrypoint (`shelltime-daemon`)
- `commands/`: CLI command implementations (for example `sync.go`, `doctor.go`, `daemon.install.go`)
- `daemon/`: background services, socket handling, sync processors, OTEL handlers
- `model/`: core domain logic (config, API clients, crypto, shell integrations)
- `docs/`: user-facing docs (`CONFIG.md`, `CC_STATUSLINE.md`)
- `fixtures/`: test fixtures

Keep new code in the existing package boundary; avoid mixing CLI wiring, daemon internals, and model logic.
- `cmd/cli/main.go`: CLI entrypoint for `shelltime`
- `cmd/daemon/main.go`: daemon entrypoint for `shelltime-daemon`
- `commands/`: CLI command definitions and user-facing command behavior
- `daemon/`: background services, socket handling, processors, and OTEL handlers
- `model/`: config, API clients, shell integrations, crypto, and shared domain logic
- `docs/`: user-facing docs such as `CONFIG.md` and `CC_STATUSLINE.md`
- `fixtures/`: reusable test fixtures

Keep new code inside the existing package boundary. Do not mix CLI wiring, daemon internals, and model logic in the same package.

## Build, Test, and Development Commands

- `go build -o shelltime ./cmd/cli/main.go`: build the CLI binary
- `go build -o shelltime-daemon ./cmd/daemon/main.go`: build the daemon binary
- `go test -timeout 3m -coverprofile=coverage.txt -covermode=atomic ./...`: run full test suite with coverage (matches CI)
- `go test ./commands/...` (or `./daemon/...`, `./model/...`): package-level tests
- `go test -run TestName ./daemon/`: run a single test
- `go fmt ./... && go vet ./...`: format and static checks
- `mockery`: regenerate mocks (configured by `.mockery.yml`)
- `pp g`: regenerate PromptPal-generated types before tests/releases
- `go test -timeout 3m -coverprofile=coverage.txt -covermode=atomic ./...`: run the full suite with coverage
- `go test ./commands/...`: run command-package tests
- `go test ./daemon/...`: run daemon-package tests
- `go test ./model/...`: run model-package tests
- `go test -run TestName ./daemon/`: run a targeted daemon test
- `go fmt ./...`: format Go code
- `go vet ./...`: run static analysis
- `mockery`: regenerate mocks when interfaces change
- `pp g`: regenerate PromptPal-generated artifacts when relevant

Use Go 1.26, as declared in `go.mod`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Go 1.26 is not a released version (the current stable version is 1.23). This is likely a typo for the version actually declared in go.mod (e.g., 1.22 or 1.23).

Suggested change
Use Go 1.26, as declared in `go.mod`.
Use Go 1.23, as declared in go.mod.


## Coding Style & Naming Conventions
Use standard Go conventions and keep code `gofmt`-clean (tabs, canonical spacing/import grouping).
- File naming: lowercase with underscores or dotted qualifiers (for example `daemon.install.go`, `api.base.go`)
- Tests: `*_test.go` files with clear `TestXxx` names
- Commits and scopes should reflect touched package areas (`commands`, `daemon`, `model`, `docs`)
Use standard Go conventions and keep code `gofmt`-clean.

## Testing Guidelines
Testing uses Go `testing` plus `testify`.
- File naming: lowercase with underscores or dotted qualifiers such as `daemon.install.go` or `api.base.go`
- Tests: `*_test.go` with clear `TestXxx` names
- Prefer table-driven tests for pure logic
- Use suite-based tests (`suite.Suite`, `SetupTest`, `TearDownTest`) for stateful daemon flows
- Keep fixtures in `fixtures/` when payloads are reused
- Ensure `go test -timeout 3m -coverprofile=coverage.txt -covermode=atomic ./...` passes before opening PRs
- Use `testify` suites for stateful daemon flows
- Keep comments brief and only where they reduce real ambiguity

## Testing Guidance

- Put reusable payloads and fixtures under `fixtures/`
- Prefer package-level test runs while iterating, then run the full suite before finishing
- Ensure `go test -timeout 3m -coverprofile=coverage.txt -covermode=atomic ./...` passes before opening a PR or cutting a release

## Documentation Maintenance
When command behavior, setup flow, config formats, or integrations change, update the docs in the same change.

- `README.md`: concise user-facing overview, install/setup flow, current command surface, and links
- `docs/CONFIG.md`: detailed config semantics, file locations, defaults, and OTEL settings
- `docs/CC_STATUSLINE.md`: Claude Code statusline behavior, formatting, and platform notes
- `AGENTS.md`: contributor and agent workflow guidance for this repo

Do not leave `README.md` advertising commands that no longer exist, and do not document new commands only in code.

## Commit & Pull Request Guidelines
History follows Conventional Commits with scope, e.g. `fix(daemon): ...`, `feat(commands): ...`, `refactor(model): ...`.
- Write focused commits with one behavioral change each
- PRs should include: concise summary, why the change is needed, and test evidence
- Link related issues when applicable
- If behavior/output changes, include CLI examples or screenshots
- Regenerate artifacts (`pp g`, `mockery`) when relevant so CI stays green
History follows Conventional Commits with scope, for example:

- `fix(daemon): ...`
- `feat(commands): ...`
- `refactor(model): ...`
- `docs(readme): ...`

Keep commits focused on one behavioral change. PRs should include a short summary, why the change is needed, and test evidence. Link related issues when applicable. If behavior or output changes, include CLI examples or screenshots. Regenerate artifacts such as `pp g` and `mockery` when needed so CI remains green.
172 changes: 119 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,140 @@
[![codecov](https://codecov.io/gh/shelltime/cli/graph/badge.svg?token=N09WIJHNI2)](https://codecov.io/gh/shelltime/cli)
[![shelltime](https://api.shelltime.xyz/badge/AnnatarHe/count)](https://shelltime.xyz/users/AnnatarHe)

Track and analyze your DevOps workflow. [shelltime.xyz](https://shelltime.xyz)
ShellTime is a CLI and background daemon for tracking shell activity, syncing command history, and wiring AI coding tools into a shared telemetry stream. The public product and hosted service are ShellTime at [shelltime.xyz](https://shelltime.xyz).

The Go module path is `github.com/malamtime/cli`. That naming mismatch is intentional in this repo today; use `ShellTime` for product-facing docs and `github.com/malamtime/cli` for imports and module references.

## Install

```bash
curl -sSL https://shelltime.xyz/i | bash
```

## Setup
## Quick Start

The fastest setup path is:

```bash
shelltime init # Authenticate
shelltime hooks install # Enable automatic tracking
shelltime daemon install # Optional: background sync for <8ms latency
shelltime init
```

## Commands
`shelltime init` authenticates the CLI, installs shell hooks, installs the daemon, and attempts to configure Claude Code and Codex OTEL integration.

If you prefer the manual flow:

```bash
shelltime auth
shelltime hooks install
shelltime daemon install
shelltime cc install
shelltime codex install
```

## What ShellTime Does

- Tracks shell commands locally with masking and exclusion support.
- Syncs command history to ShellTime for search and analysis.
- Runs a background daemon for low-latency, non-blocking sync.
- Integrates with Claude Code and OpenAI Codex through OTEL forwarding.
- Shows live Claude Code statusline data for cost, quota, time, and context.
- Syncs supported dotfiles to and from the ShellTime service.

## Command Overview

### Core setup and auth

| Command | Description |
|---------|-------------|
| `shelltime init` | Bootstrap auth, hooks, daemon, and AI-code integrations |
| `shelltime auth` | Authenticate with `shelltime.xyz` |
| `shelltime doctor` | Check installation and environment health |
| `shelltime web` | Open the ShellTime dashboard in a browser |

### Tracking and sync

| Command | Description |
|---------|-------------|
| `shelltime track` | Record a shell command event |
| `shelltime sync` | Manually sync pending local data |
| `shelltime ls` | List locally saved commands |
| `shelltime gc` | Clean internal storage and logs |
| `shelltime rg "pattern"` | Search synced command history |

### AI helpers and integrations

| Command | Description |
|---------|-------------|
| `shelltime sync` | Sync pending commands to server |
| `shelltime rg "pattern"` | Search synced commands (alias: `grep`) |
| `shelltime q "prompt"` | AI-powered command suggestions |
| `shelltime doctor` | Diagnose installation issues |
| `shelltime web` | Open dashboard in browser |
| `shelltime gc` | Clean old tracking data |
| `shelltime ls` | List pending commands |
| `shelltime query "prompt"` | Ask AI for a suggested shell command |
| `shelltime q "prompt"` | Alias for `shelltime query` |
| `shelltime cc install` | Install Claude Code OTEL shell configuration |
| `shelltime cc uninstall` | Remove Claude Code OTEL shell configuration |
| `shelltime cc statusline` | Emit statusline JSON for Claude Code |
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 README describes cc statusline output as JSON when it actually emits formatted ANSI text

The command table says shelltime cc statusline will "Emit statusline JSON for Claude Code", but the command actually reads JSON from stdin and outputs formatted plain text with ANSI color codes and OSC8 hyperlinks (see commands/cc_statusline.go:108 where fmt.Println(output) prints the result of formatStatuslineOutput, which returns a strings.Join(parts, " | ") of color-formatted segments). The command's own Usage field correctly says "Output statusline for Claude Code (reads JSON from stdin)" at commands/cc_statusline.go:28. A user reading this table entry would expect the command to produce JSON output, which is incorrect.

Suggested change
| `shelltime cc statusline` | Emit statusline JSON for Claude Code |
| `shelltime cc statusline` | Output formatted statusline for Claude Code |
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

| `shelltime codex install` | Add ShellTime OTEL config to `~/.codex/config.toml` |
| `shelltime codex uninstall` | Remove ShellTime OTEL config from `~/.codex/config.toml` |

### Environment helpers

| Command | Description |
|---------|-------------|
| `shelltime hooks install` | Install shell hooks |
| `shelltime hooks uninstall` | Remove shell hooks |
| `shelltime daemon install` | Install the ShellTime daemon service |
| `shelltime daemon status` | Check daemon status |
| `shelltime daemon reinstall` | Reinstall the daemon service |
| `shelltime daemon uninstall` | Remove the daemon service |
| `shelltime alias import` | Import aliases from shell config files |
| `shelltime config view` | Show the merged current configuration |
| `shelltime schema` | Generate JSON schema for config autocompletion |
| `shelltime ios dl` | Open the ShellTime iOS App Store page |

### Dotfiles

| Command | Description |
|---------|-------------|
| `shelltime dotfiles push` | Push supported dotfiles to the server |
| `shelltime dotfiles pull` | Pull supported dotfiles to local config |

## Configuration

Config file: `~/.shelltime/config.yaml`
ShellTime stores data under `~/.shelltime/`.

- Main config: `~/.shelltime/config.yaml`
- Local overrides: `~/.shelltime/config.local.yaml`
- Also supported: `config.yml`, `config.toml`, `config.local.yml`, `config.local.toml`
- Generated schema: `~/.shelltime/config-schema.json`

Minimal example:

```yaml
token: "your-token"
flushCount: 10 # Commands before sync
gcTime: 14 # Days to retain data
dataMasking: true # Mask sensitive data
encrypted: false # E2E encryption (requires daemon)
token: "your-api-token"
flushCount: 10
gcTime: 14
dataMasking: true

# Exclude patterns (regex)
exclude:
- ".*password.*"
- "^export .*"

# AI permissions
ai:
agent:
view: false # Read-only commands
edit: false # File modifications
delete: false # Destructive commands
```

Local overrides: `~/.shelltime/config.local.yaml`
For the full configuration surface, defaults, OTEL settings, and AI options, see [docs/CONFIG.md](docs/CONFIG.md).

**[Full Configuration Guide](docs/CONFIG.md)** - Detailed documentation for all options
## Daemon Mode

## Why Daemon Mode?
The daemon keeps tracking fast by buffering and syncing in the background.

| Mode | Latency | Network Blocking |
|------|---------|------------------|
| Direct | ~100ms+ | Yes |
| Daemon | <8ms | No |

The daemon handles network sync in the background with automatic retry and buffering.

## Claude Code Statusline Integration
Use daemon mode if you want lower shell latency, retry handling, and background processing for sync and OTEL events.

Display real-time cost and context usage in [Claude Code's status bar](https://code.claude.com/docs/en/statusline).
## Claude Code Statusline

### Setup
ShellTime can provide a live statusline for [Claude Code](https://code.claude.com/docs/en/statusline).

Add to your Claude Code settings (`~/.claude/settings.json`):
Add this to `~/.claude/settings.json`:

```json
{
Expand All @@ -85,33 +147,37 @@ Add to your Claude Code settings (`~/.claude/settings.json`):
}
```

The status line will display:
Example output:

```
```text
🌿 main* | 🤖 Opus | 💰 $0.12 | 📊 $3.45 | 🚦 5h:23% 7d:12% | ⏱️ 5m30s | 📈 45%
```

| Section | Description |
|---------|-------------|
| 🌿 Git Branch | Current branch name (`*` if dirty) |
| 🤖 Model | Current model name |
| 💰 Session | Current session cost (clickable link to session detail) |
| 📊 Daily | Today's total cost (clickable link to coding agent page) |
| 🚦 Quota | Anthropic API quota utilization (macOS only, clickable link to usage settings) |
| ⏱️ Time | AI agent session duration (clickable link to user profile) |
| 📈 Context | Context window usage % |
For formatting details and platform notes, see [docs/CC_STATUSLINE.md](docs/CC_STATUSLINE.md).

For full details, see [Claude Code Statusline Guide](docs/CC_STATUSLINE.md).
## Security and Privacy

## Security
- Data masking can redact sensitive command content before upload.
- Exclusion patterns let you skip matching commands entirely.
- Optional end-to-end encryption is available for supported flows.
- Local config overrides can keep sensitive values out of the primary config file.

- **Data Masking**: Sensitive info automatically redacted
- **E2E Encryption**: Hybrid RSA/AES-GCM encryption (v0.1.12+)
- **Exclusion Patterns**: Regex-based command filtering
## Development

Common local commands:

```bash
go build -o shelltime ./cmd/cli/main.go
go build -o shelltime-daemon ./cmd/daemon/main.go
go test -timeout 3m -coverprofile=coverage.txt -covermode=atomic ./...
go fmt ./...
go vet ./...
```

## Links

- [Documentation](https://deepwiki.com/shelltime/cli)
- [Configuration Guide](docs/CONFIG.md)
- [Claude Code Statusline Guide](docs/CC_STATUSLINE.md)
- [Dashboard](https://shelltime.xyz)
- [Issues](https://github.com/shelltime/cli/issues)

Expand Down
Loading