PHPackages                             tcrawf/zebra - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. tcrawf/zebra

ActiveProject[CLI &amp; Console](/categories/cli)

tcrawf/zebra
============

A time tracking CLI tool.

1.5.0-alpha(2mo ago)02GPL-3.0-onlyPHPPHP ^8.4CI failing

Since Dec 3Pushed 2mo agoCompare

[ Source](https://github.com/tcrawf/zebra)[ Packagist](https://packagist.org/packages/tcrawf/zebra)[ Docs](https://github.com/tcrawf/zebra)[ RSS](/packages/tcrawf-zebra/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (22)Versions (16)Used By (0)

Zebra - Time Tracking CLI Tool
==============================

[](#zebra---time-tracking-cli-tool)

A powerful command-line time tracking application built with PHP 8.4.

Zebra helps you track time spent on activities, which belong to projects. It supports both local and remote (Zebra API) project management.

About
-----

[](#about)

This library is based on [Watson](https://github.com/jazzband/Watson), a wonderful Python-based CLI time tracking tool. Zebra written as a PHP port/reimplementation in order to provide additional zebra specific features. Pull requests are welcome!

**Note**: Zebra is intended for use by employees of Liip, who have access to Zebra, Liip's proprietary management system.

Features
--------

[](#features)

- **Time Tracking**: Start, stop, and manage time tracking sessions (frames)
- **Project Management**: Support for both local and Zebra API projects
- **Activity Tracking**: Track time against activities (activities belong to projects)
- **Timesheet Management**: Create, edit, list, sync, and manage timesheet entries
- **Reporting**: Generate reports and aggregate time spent by project and day
- **Frame Management**: Add, edit, remove, and view time tracking frames
- **Backup &amp; Restore**: Automatic daily backups and manual backup/restore functionality
- **User Management**: Initialize and manage user information and roles
- **Configuration**: Manage application settings via CLI or config file
- **Autocompletion**: Shell autocompletion support for commands
- **PHAR Support**: Can be built as a standalone PHAR executable

Requirements
------------

[](#requirements)

- PHP 8.4 or higher
- Composer (for development)
- Zebra API token (for remote project synchronization)
- Valid timezone identifier

Installation
------------

[](#installation)

### Via Composer (Packagist)

[](#via-composer-packagist)

**Note**: This package is currently in alpha. To install via Composer, you must specify the stability level:

```
composer create-project tcrawf/zebra --stability=alpha
```

Or specify a specific version:

```
composer create-project tcrawf/zebra:1.0.6-alpha
```

### From Source

[](#from-source)

1. Clone the repository:

```
git clone
cd zebra
```

2. Install dependencies:

```
composer install
```

3. Install the PHAR to your system (optional, but highly recommended):

```
./bin/zebra install
```

This will build the PHAR (if needed) and install the `zebra` executable to:

- `~/.local/bin/zebra` on Unix/Linux/macOS
- `~/bin/zebra` on Windows

Make sure the install directory is in your PATH.

### Configuration

[](#configuration)

Zebra requires three environment variables:

1. **ZEBRA\_TOKEN**: Your Zebra API authentication token
2. **ZEBRA\_BASE\_URI**: The base URI for the Zebra API (e.g., `https://api.example.com`)
3. **TZ**: Your timezone identifier (e.g., `Europe/Zurich`, `America/New_York`)

You can set these in one of two ways:

#### Option 1: Environment Variables

[](#option-1-environment-variables)

```
export ZEBRA_TOKEN=your_token_here
export ZEBRA_BASE_URI=https://api.example.com
export TZ=Europe/Zurich
```

#### Option 2: .env File

[](#option-2-env-file)

Create a `.env` file in the project root:

```
ZEBRA_TOKEN=your_token_here
ZEBRA_BASE_URI=https://api.example.com
TZ=Europe/Zurich
```

**Note**: Environment variables take precedence over `.env` file values.

For a list of valid timezone identifiers, see: [https://en.wikipedia.org/wiki/List\_of\_tz\_database\_time\_zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)

Usage
-----

[](#usage)

Zebra provides a command-line interface for tracking time. Activities belong to projects, and you track time against activities.

### Available Commands

[](#available-commands)

#### Time Tracking

[](#time-tracking)

- **start** - Start tracking time for an activity
- **stop** - Stop the currently running time tracking session
- **status** - Display the current tracking status
- **cancel** - Cancel the last start command (time will not be recorded)
- **restart** - Restart tracking time for a previously stopped activity
- **add** - Add time to an activity that was not tracked live

#### Frame Management

[](#frame-management)

- **frames** - Display all frame IDs
- **edit** - Edit an existing frame
- **remove** - Remove a frame

#### Project &amp; Activity Management

[](#project--activity-management)

- **projects** - Display all available projects or add/edit a local project
- **activities** - Display all available activities or add/edit a local activity
- **delete-project** - Delete a local project
- **delete-activity** - Delete a local activity

#### Timesheet Management

[](#timesheet-management)

- **timesheet:create** - Create a new timesheet entry
- **timesheet:from-frames** - Create timesheet entries from frames
- **timesheet:edit** - Edit an existing timesheet entry
- **timesheet:list** - List timesheet entries
- **timesheet:push** - Push local timesheets to Zebra API
- **timesheet:pull** - Pull timesheets from Zebra API
- **timesheet:delete** - Delete a timesheet entry
- **timesheet:merge** - Merge multiple timesheet entries

#### Reporting

[](#reporting)

- **report** - Display a report of time spent on each project
- **aggregate** - Display a report aggregated by day
- **log** - Display each recorded session during a given timespan

#### User &amp; Configuration

[](#user--configuration)

- **user** - Display current user information or initialize a new user
- **roles** - Display available roles for the current user
- **config** - Get and set configuration options
- **refresh** - Refresh all data (user data, projects, and activities) from Zebra API

#### Backup &amp; Restore

[](#backup--restore)

- **backup** - Backup frames, timesheets, and local projects (automatic daily backups enabled)
- **restore** - Restore from a backup
- **delete-backup** - Delete a backup

#### Installation

[](#installation-1)

- **install** - Build and install the zebra PHAR to a platform-appropriate directory

### Getting Help

[](#getting-help)

For detailed usage information and available options for any command, use:

```
zebra  --help
```

For example:

```
zebra start --help
zebra add --help
zebra report --help
```

### Example Output

[](#example-output)

Here's an example of time tracking entries displayed by Zebra:

```
+----------+---------------+----------+---------------------+--------------------------------------------------------------------------+
| UUID     | Time frame    | Duration | Activity            | Description                                                              |
+----------+---------------+----------+---------------------+--------------------------------------------------------------------------+
| 673669d4 | 08:32 - 08:40 | 7m       | proj_minor          | PROJ-560/PROJ-602: Kicked off the day by power-reviewing returned        |
|          |               |          |                     | tickets to keep momentum high.                                           |
| 80f79d41 | 08:40 - 08:43 | 3m       | proj_minor          | PROJ-560: Tackled a login glitch for Alex — quick diagnosis, quick fix.  |
| 227fbdb2 | 08:43 - 08:48 | 4m       | proj_support        | Helped Sam jump-start ddev after a few hiccups — rapid-fire support.     |
| 666b2daa | 08:48 - 09:00 | 12m      | administration      | Strategic sync with Lara about a recent incident; captured Kai's sharp   |
|          |               |          |                     | insights on development direction.                                       |
| e36be0ed | 09:00 - 09:40 | 40m      | proj_minor          | PROJ-560: Continued hunting down Alex's login issue — deeper dives,      |
|          |               |          |                     | broader checks.                                                          |
| 476357de | 09:52 - 10:36 | 43m      | proj_minor          | PROJ-560: Investigated a stubborn login failure on dev environment.      |
|          |               |          |                     | Reproduced sessions, probed configs, and narrowed down server-side       |
|          |               |          |                     | suspicions.                                                              |
| b47d080e | 10:36 - 11:27 | 51m      | proj_minor          | PROJ-560: Reconstructed the issue locally using Apache. Identified a     |
|          |               |          |                     | likely conflict with the shield module. Tested alternative approaches    |
|          |               |          |                     | and authentication setups.                                               |
| a09ac150 | 11:27 - 11:37 | 10m      | proj_minor          | PROJ-602: Integrated ticket feedback — polishing edges for smooth UX.    |
| 669a4afb | 11:37 - 12:14 | 36m      | proj_minor          | PROJ-560: Shield disabled, mystery persists. Diving deeper into root     |
|          |               |          |                     | causes.                                                                  |
| 868b7128 | 12:48 - 12:57 | 8m       | proj_minor          | PROJ-560: Experimented with a Symfony component downgrade to rule out    |
|          |               |          |                     | regression issues.                                                       |
| d60d4d90 | 12:57 - 13:27 | 29m      | administration       | High-energy sync with D. Rivera on modern developer workflows and AI's  |
|          |               |          |                     | role in shaping them.                                                    |
| 502f00dd | 13:27 - 13:47 | 20m      | edu                 | Research dive — exploring emerging patterns and tooling.                 |
| e590e4d2 | 13:47 - 14:23 | 35m      | proj_minor          | PROJ-602: Delivered feedback integration with a sharper, cleaner         |
|          |               |          |                     | implementation.                                                          |
| 033c5331 | 14:23 - 15:00 | 37m      | proj_minor          | PROJ-560: Tracked login failure to a custom redirect. Untangled session  |
|          |               |          |                     | flow so users regain seamless access.                                    |
| 4eaa1473 | 15:17 - 17:22 | 2h 5m    | proj_minor          | PROJ-601: Engineered a robust filename override solution — aligning UX,  |
|          |               |          |                     | backend rules, and editor behaviour.                                     |
| 6322b1fe | 17:22 - 17:32 | 9m       | proj_minor          | PROJ-601: Finalised refinements for the filename override mechanism.     |
| 69aadede | 17:32 - 17:40 | 7m       | administration      | Logged and wrapped up the day's achievements — timesheet complete.       |
+----------+---------------+----------+---------------------+--------------------------------------------------------------------------+

```

### Configuration

[](#configuration-1)

Configuration is stored in `~/.config/zebra/config.json`. Use the `config` command to manage settings:

```
zebra config --help
```

Development
-----------

[](#development)

### Project Structure

[](#project-structure)

```
zebra/
├── bin/                 # CLI entry points
├── src/                 # Source code
│   ├── Activity/        # Activity domain
│   ├── Cache/           # Cache management
│   ├── Client/          # HTTP client and API exceptions
│   ├── Command/         # CLI commands
│   ├── Config/          # Configuration management
│   ├── EntityKey/       # Entity key handling
│   ├── Exception/       # Custom exceptions
│   ├── FileStorage/     # File storage abstractions
│   ├── Frame/           # Frame domain
│   ├── Project/         # Project domain
│   ├── Report/          # Reporting services
│   ├── Role/            # Role domain
│   ├── Timesheet/       # Timesheet domain
│   ├── Timezone/        # Timezone formatting
│   ├── Track/           # Time tracking logic
│   ├── User/            # User domain
│   └── Uuid/            # UUID handling
├── tests/               # Test suite
├── build/               # Built PHAR files
└── vendor/              # Composer dependencies

```

### Architecture

[](#architecture)

Zebra follows a clean architecture pattern with:

- **Repository Pattern**: Data access abstraction
- **Dependency Injection**: Constructor injection with readonly properties
- **Factory Pattern**: Object creation factories
- **File Storage**: File-based persistence extending `AbstractFileStorage`
- **Interface-First Design**: Interfaces defined before implementations

### Code Style

[](#code-style)

This project follows **PSR-12 Extended Coding Style Guide**:

- PHP 8.4+ with strict types (`declare(strict_types=1);`)
- PSR-12 formatting standards
- All files must have `declare(strict_types=1);` at the top
- One newline at the end of files (no more, no less)

#### Check Code Style

[](#check-code-style)

```
composer run phpcs-check
```

#### Auto-fix Code Style Issues

[](#auto-fix-code-style-issues)

```
composer run phpcbf-fix
```

### Static Analysis

[](#static-analysis)

Run PHPStan for static analysis:

```
composer run phpstan
```

Generate a baseline (for first-time setup):

```
composer run phpstan-baseline
```

### Testing

[](#testing)

Run the test suite:

```
composer run test
```

Generate test coverage report:

```
composer run test-coverage
```

Coverage report will be generated in `coverage/` directory.

**Note:** Code coverage requires a PHP coverage driver to be installed. PHPUnit supports:

- **PCOV** (recommended for performance)
- **Xdebug**
- **phpdbg**

Install PCOV (recommended):

```
# Debian/Ubuntu
sudo apt-get install php-pcov

# Or via PECL
pecl install pcov
```

Install Xdebug:

```
# Debian/Ubuntu
sudo apt-get install php-xdebug

# Or via PECL
pecl install xdebug
```

After installation, restart your PHP CLI or ensure the extension is enabled in your PHP configuration.

### Development Workflow

[](#development-workflow)

1. **Make Changes**: Edit source code following PSR-12 standards
2. **Check Style**: Run `composer run phpcs-check`
3. **Fix Style**: Run `composer run phpcbf-fix` if needed
4. **Run Tests**: Run `composer run test` to ensure all tests pass
5. **Test Coverage**: Run `composer run test-coverage` to generate coverage reports
6. **Static Analysis**: Run `composer run phpstan` to catch type errors

Dependencies
------------

[](#dependencies)

### Runtime Dependencies

[](#runtime-dependencies)

- **nesbot/carbon**: Date/time handling (normalized to UTC)
- **guzzlehttp/guzzle**: HTTP client for API communication
- **vlucas/phpdotenv**: Environment variable management
- **symfony/console**: CLI framework

### Development Dependencies

[](#development-dependencies)

- **phpunit/phpunit**: Testing framework
- **phpstan/phpstan**: Static analysis
- **squizlabs/php\_codesniffer**: Code style checking
- **slevomat/coding-standard**: Additional code style rules
- **humbug/box**: PHAR building tool
- **mikey179/vfsstream**: Virtual filesystem for testing

Configuration Storage
---------------------

[](#configuration-storage)

- **Application Config**: `~/.config/zebra/config.json`
- **Cache**: `~/.cache/zebra/` (managed automatically)
- **Frame Storage**: `~/.zebra/` (managed automatically)
- **Timesheet Storage**: `~/.zebra/timesheets.json` (managed automatically)
- **Backups**: `~/.zebra/backups/` (managed automatically)

Timezone Handling
-----------------

[](#timezone-handling)

All timestamps are normalized to UTC internally. The application uses the `TZ` environment variable to display times in your local timezone. Make sure to set `TZ` to a valid timezone identifier.

API Integration
---------------

[](#api-integration)

Zebra integrates with the Zebra API for:

- User authentication and information
- Project synchronization
- Activity management
- Timesheet synchronization (push/pull)

API requests are authenticated using the `ZEBRA_TOKEN` environment variable and use the `ZEBRA_BASE_URI` environment variable to determine the API endpoint. Use the `refresh` command to synchronize user data, projects, and activities from the API.

Troubleshooting
---------------

[](#troubleshooting)

### Xdebug Warning

[](#xdebug-warning)

If you see a warning about Xdebug being enabled, you can:

- Disable Xdebug: `php -d xdebug.mode=off bin/zebra`
- Suppress the warning: `ZEBRA_SILENT_XDEBUG_WARNING=1 bin/zebra`

### Missing Environment Variables

[](#missing-environment-variables)

If you get errors about missing `ZEBRA_TOKEN`, `ZEBRA_BASE_URI`, or `TZ`:

1. Check that your `.env` file exists in the project root
2. Verify the variables are set correctly
3. Ensure environment variables are exported in your shell

**Note**: The application will start without `ZEBRA_TOKEN` or `ZEBRA_BASE_URI`, but will warn when these are needed for API requests. This is a security precaution to prevent accidental API calls.

### PHAR Execution Issues

[](#phar-execution-issues)

If running from PHAR:

- Ensure the PHAR file has execute permissions: `chmod +x build/zebra`
- The `.env` file should be in the current working directory when running the PHAR

### Backup Issues

[](#backup-issues)

- Backups are automatically created daily when you run any command
- Manual backups can be created with `zebra backup`
- Use `zebra restore` to restore from a backup
- Backup files are stored in `~/.zebra/backups/`

License
-------

[](#license)

This project is licensed under the GNU General Public License v3.0 (GPL-3.0). See the [LICENSE](LICENSE) file for details.

Author
------

[](#author)

Trent Crawford ()

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance87

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Recently: every ~23 days

Total

14

Last Release

65d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/dc02eeb7834d6f9c4d19a5afea40bc548e37bb2e9cffb33ee99887c5ce19617c?d=identicon)[tcrawford](/maintainers/tcrawford)

---

Top Contributors

[![trent-crawford](https://avatars.githubusercontent.com/u/63054411?v=4)](https://github.com/trent-crawford "trent-crawford (31 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tcrawf-zebra/health.svg)

```
[![Health](https://phpackages.com/badges/tcrawf-zebra/health.svg)](https://phpackages.com/packages/tcrawf-zebra)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.7k509.9M17.0k](/packages/laravel-framework)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)[statamic/cli

Statamic CLI Tool

7587.7k](/packages/statamic-cli)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[concrete5/core

Concrete core subtree split

19159.3k48](/packages/concrete5-core)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

7310.3k29](/packages/open-dxp-opendxp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
