Metadata-Version: 2.4
Name: time2
Version: 2.5.2
Summary: Local-first task, planning, audio, AI insight, and budget tracker built with Streamlit.
Author: time2 contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/a4das/time2
Project-URL: Documentation, https://github.com/a4das/time2#readme
Project-URL: Issues, https://github.com/a4das/time2/issues
Keywords: streamlit,tasks,planning,local-first,tailscale,whisper,llm,budget
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Scheduling
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: streamlit>=1.45
Requires-Dist: ipython>=8.0
Provides-Extra: whisper
Requires-Dist: openai-whisper>=20231117; extra == "whisper"
Provides-Extra: llm
Requires-Dist: llama-cpp-python>=0.3.0; extra == "llm"
Provides-Extra: all
Requires-Dist: openai-whisper>=20231117; extra == "all"
Requires-Dist: llama-cpp-python>=0.3.0; extra == "all"
Dynamic: license-file

# time2

<p align="center">
  <strong>A local-first attention-friendly life/work tracker for tasks, mind states, energy, audio transcripts, AI review, and monthly budgeting.</strong>
</p>

<p align="center">
  <img alt="Python" src="https://img.shields.io/badge/Python-3.10%2B-blue">
  <img alt="Streamlit" src="https://img.shields.io/badge/Streamlit-1.45%2B-red">
  <img alt="Storage" src="https://img.shields.io/badge/Storage-Local%20JSON-green">
  <img alt="AI" src="https://img.shields.io/badge/AI-Local%20or%20API-purple">
  <img alt="Network" src="https://img.shields.io/badge/Network-Tailscale%20Recommended-lightgrey">
</p>

## Why This Exists

time2 is not a normal todo list. It is a local-only Streamlit app designed
for the kind of real-life tracking that helps with time blindness,
avoidance, energy swings, spontaneous work, and memory gaps.

The app keeps pending work visible, but it also keeps evidence of what happened:
sessions, comments, reschedules, cancelled work, completed work, mind states,
audio logs, transcripts, budget entries, and AI-ready summaries.

The current version is intentionally simple and hackable:

- Python and Streamlit.
- Dataclasses for the core model.
- Local JSON files.
- Optional one-file-per-task and one-file-per-mind-log storage.
- Optional local Whisper transcription with automatic language detection.
- Optional LLM insights through local `llama-cpp-python` or an OpenAI-compatible API endpoint.
- No cloud database.
- No public deployment.
- Tailscale recommended for private outside access.

## Highlights

| Area | What it does |
| --- | --- |
| Task tracking | Tasks/events with project, area, priority, energy, planned window, deadline, status, comments, sessions, and history. |
| Reserved tasks | Save unscheduled brown backlog tasks without planned date/deadline, then give them natural colors when scheduled later. |
| Progress history | Done tasks stay on the Victory Board; cancelled tasks stay visible; reschedules keep reasons. |
| Spontaneous work | `Now doing` creates an active task immediately and starts a session. |
| Planning review | Day/range view shows planned, done, cancelled, left, spontaneous work, sessions, comments, and mind logs; sorting is limited to priority, planned date/time, or deadline date/time. |
| Eisenhower Matrix | Urgency comes from deadline; importance comes from priority; tasks can be moved/edited from the matrix. |
| E2 Plot | Adds energy as a third axis so you can see urgency, importance, and energy cost/gain together. |
| Mind Log | Standalone mind-state entries with text, audio, and transcripts. |
| Audio everywhere | Task, project, mind-log, and budget entries can upload or record audio. |
| Transcripts | Whisper transcription is optional, visible, can auto-detect spoken language, and can be re-run later. |
| Budget | Monthly budget files with categories, limits, spending entries, audio notes, transcripts, overspending, and previous month loading. |
| AI Insights | Tunable deterministic scores, attention support detectors, and optional local/API LLM analysis for days/ranges. |
| AI Chat | Multiple saved local or API-backed chats over selected task, mind-state, audio, budget, and date-range context. |
| Reports/PDF | Download task, dashboard, period, mind-state, budget, chat, and raw snapshot reports as PDF/HTML/TXT/JSON. |
| Backups | Manual and timed JSON backups. |
| Portable launch | JupyterLab launcher notebook/script plus terminal command. |

## Screens And Workflows

time2 currently has these tabs:

- `Add`
- `Planning`
- `Deadlines`
- `Matrix`
- `E2 Plot`
- `Mind Log`
- `Pending`
- `Victory Board`
- `Cancelled`
- `Dashboard`
- `Budget`
- `AI Insights`
- `AI Chat`
- `Reports`
- `Settings`
- `Data`

The app is built around a simple loop:

1. Capture what you planned to do.
2. Capture what you actually did.
3. Keep the history visible instead of hiding it.
4. Record reasons and mind states when things move.
5. Review the day/range later with data, transcripts, and AI-ready summaries.

## Quick Start From JupyterLab

1. Unzip or clone this folder somewhere local.
2. Open JupyterLab in the same folder.
3. Install the base requirements:

```python
%pip install -r requirements.txt
```

4. Open `time2_jupyter_launcher.ipynb`.
5. Run the launch cell.

The app opens at:

```text
http://127.0.0.1:8503
```

It also appears inside JupyterLab as an iframe.

If your Jupyter kernel is already running from the app folder, this also works:

```python
%run time2_jupyter_launcher.py
```

## Install As A Python Package

After the package is published, a normal user can install and run it with:

```bash
python -m pip install time2
time2 doctor
time2 run --open-browser
```

The `time2` command includes helper checks:

```bash
time2 doctor --optional
time2 doctor --optional --install-missing
time2 install-optionals --whisper
time2 install-optionals --llm
time2 install-optionals --all
```

Optional installs ask before changing the current Python environment.

Private access helper commands:

```bash
time2 tailscale install
time2 tailscale login
time2 run --tailscale --open-browser
time2 tailscale serve-status
```

Tailscale is system software. The CLI detects whether it is installed, prints
the install command/link, and asks before running a package-manager install.
The web app also has `Settings -> Private access with Tailscale` for status,
sign-in, and Serve setup.

## Quick Start From Terminal

```bash
pip install -r requirements.txt
python -m streamlit run time2_streamlit_app.py --server.address 127.0.0.1 --server.port 8503 --server.headless true
```

Then open:

```text
http://127.0.0.1:8503
```

## First Run

On a fresh laptop or fresh unzip, if `time2_settings.json` does not exist, the
app opens a first-run setup screen.

Choose the data folder there. The app creates this structure:

```text
chosen_data_folder/
  time2_data.json
  time2_tasks/
  time2_mind_logs/
  time2_audio/
  time2_budget/
  time2_backups/
  time2_ai_cache/
  time2_chats/
  time2_exports/
```

The data folder can be changed later in `Settings -> Storage and backups` using
the `Choose folder` buttons.

## Optional Whisper Transcription

Audio recording/upload works with only `requirements.txt`.

Install Whisper only when you want local transcription:

```bash
pip install -r requirements-whisper.txt
```

The default mode is `Auto detect`, so Whisper can infer whether the recording is
English, German, Spanish, Bengali, Hindi, or another language it recognizes. You
can still force one of these common languages from the app:

- Auto detect
- English
- German
- Spanish
- Bengali
- Hindi

Whisper can take a minute or two depending on audio length and laptop speed. The
app saves the audio first, then stores transcript status:

- `done`
- `failed`
- `missing_dependency`
- `not_requested`

If a transcript is missing, use the relevant `Transcribe this audio now` button.

## Optional Local LLM Insights

Install the LLM dependency only on the laptop that will run the local model:

```bash
pip install -r requirements-llm.txt
```

Default model path:

```text
./Models/Qwen2.5-7B-Instruct-Q4_K_M.gguf
```

You can choose a `.gguf` file from the app in:

```text
Settings -> LLM defaults
```

You can also use an OpenAI-compatible API instead of a local GGUF model. Configure it in:

```text
Settings -> LLM defaults
```

The API mode supports a base URL such as `http://127.0.0.1:8000/v1`, a model
name, an optional API key, timeout, answer length, temperature, and top-p. API
mode sends the selected AI context to that endpoint, so use a trusted local or
private server for sensitive data.

The same LLM settings are reused in `AI Chat`, where you can choose date ranges,
data types, projects, task states, context limits, temperature, top-p, repeat
penalty, seed, answer length, and chat history length.

The app still works without `llama-cpp-python` and without a model. In that case
you still get deterministic summaries, plots, scores, data-availability checks,
and next-action candidates.

## Private Access From Outside Home

The recommended free private-access setup is Tailscale.

Keep Streamlit bound locally on the home laptop:

```bash
python -m streamlit run time2_streamlit_app.py --server.address 127.0.0.1 --server.port 8503 --server.headless true
```

If you want to do everything from JupyterLab, open and run:

```text
time2_tailscale_jupyter_launcher.ipynb
```

It starts Streamlit, starts Tailscale Serve, and prints the private
`https://...ts.net` URL.

The terminal equivalent is:

```bash
tailscale serve --bg http://127.0.0.1:8503
```

See [docs/TAILSCALE_PRIVATE_ACCESS.md](docs/TAILSCALE_PRIVATE_ACCESS.md).

## Important Files

| Path | Purpose |
| --- | --- |
| `time2_streamlit_app.py` | Tiny Streamlit entrypoint. |
| `time2_jupyter_launcher.py` | Portable Jupyter launcher script. |
| `time2_jupyter_launcher.ipynb` | Notebook launcher for JupyterLab. |
| `time2_tailscale_jupyter_launcher.py` | Jupyter-only launcher that starts Streamlit and Tailscale Serve. |
| `time2_tailscale_jupyter_launcher.ipynb` | Notebook for private outside access through Tailscale Serve. |
| `time2_ai_cache_worker.py` | Optional background AI cache refresher. |
| `time2_app/config.py` | Defaults: app title, settings, options, colors, storage defaults. |
| `time2_app/utils.py` | General helpers: IDs, timestamps, parsing, settings loading, theme CSS. |
| `time2_app/models.py` | Dataclasses and model behavior for tasks, sessions, comments, mind logs, audio logs, board state. |
| `time2_app/storage.py` | JSON persistence, folders, backups, task files, mind files, audio files. |
| `time2_app/budget.py` | Budget entries, month-end logic, monthly files, budget reports. |
| `time2_app/ai.py` | Deterministic reports, local LLM calls, AI cache. |
| `time2_app/chat.py` | Saved AI chats, selected context assembly, and read-only chat prompts. |
| `time2_app/reports.py` | PDF/HTML/TXT/JSON report generation. |
| `time2_app/transcription.py` | Optional Whisper transcription helpers with auto-detect support. |
| `time2_app/tailscale_utils.py` | Optional Tailscale detection, sign-in, and Serve helpers. |
| `time2_app/cli.py` | `time2` command-line interface for install checks, running, and Tailscale helpers. |
| `time2_app/components.py` | Streamlit custom component registration. |
| `time2_app/views.py` | Streamlit view functions, task editor controls, settings screens, and report views. |
| `time2_app/app.py` | Top-level tab composition and app bootstrapping. |
| `pyproject.toml` | Python package metadata, dependencies, optional extras, console script, and wheel data files. |
| `MANIFEST.in` | Source distribution include list for docs, examples, and components. |
| `docs/MANUAL.md` | User manual. |
| `docs/DEVELOPER_GUIDE.md` | Detailed code and next-version developer guide. |
| `docs/MODULES.md` | Compact module dependency guide. |
| `docs/CODE_WALKTHROUGH.md` | Code walkthrough by layer. |
| `docs/AI_INSIGHTS.md` | Local AI setup and AI roadmap. |
| `docs/TAILSCALE_PRIVATE_ACCESS.md` | Private access notes. |
| `docs/PACKAGING.md` | Build, TestPyPI, PyPI, and pip-install release guide. |

## Runtime Data

Runtime files are intentionally local and are not needed for a clean install.

| Path | Purpose |
| --- | --- |
| `time2_settings.json` | App settings and chosen data/storage folders. |
| `time2_data.json` | Main board JSON. |
| `time2_tasks/` | Optional one-file-per-task JSON files. |
| `time2_mind_logs/` | Optional one-file-per-mind-log JSON files. |
| `time2_audio/` | Uploaded and browser-recorded audio files. |
| `time2_budget/` | Monthly budget JSON files named `budget_YYYY_MM.json`. |
| `time2_backups/` | Timed/manual backup JSON files. |
| `time2_ai_cache/` | Cached AI report payloads. |
| `time2_chats/` | Saved AI Chat conversations. |
| `time2_exports/` | Saved report exports. |

## Data Model Summary

The model is deliberately readable:

- `Time2Item`: one task/event/spontaneous item.
- `Time2Session`: one work session on a task.
- `Time2Reschedule`: one planned-date/time movement.
- `Time2Comment`: notes, blockers, reflections, reasons.
- `Time2MindLog`: standalone mind-state check-in with optional transcript.
- `Time2AudioLog`: stored audio metadata and transcript status/text.
- `Time2Board`: the container that owns tasks, mind logs, and audio logs.
- `BudgetEntry`: one income, expense, or savings entry with optional audio and transcript.

## Development Rules

The code is modular on purpose. When changing it:

- Add new settings in `config.py`, normalize them in `utils.py`, expose them in `views.py`.
- Add new task fields in `models.py`, then update `from_dict()`/`to_dict()` compatibility.
- Keep disk paths and persistence in `storage.py`.
- Keep budget month-file logic in `budget.py`.
- Keep saved chat context and prompt assembly in `chat.py`.
- Keep PDF/HTML/TXT/JSON export generation in `reports.py`.
- Keep optional Whisper loading in `transcription.py`.
- Keep optional Tailscale command helpers in `tailscale_utils.py`.
- Keep install/run command behavior in `cli.py`.
- Keep deterministic AI data assembly in `ai.py`.
- Keep tab placement in `app.py`.
- Keep view rendering and form controls in `views.py`.

Before packaging:

```bash
python -m py_compile time2_streamlit_app.py time2_jupyter_launcher.py time2_ai_cache_worker.py time2_app/*.py
```

## Documentation

Start here:

- [User Manual](docs/MANUAL.md)
- [Developer Guide](docs/DEVELOPER_GUIDE.md)
- [Module Guide](docs/MODULES.md)
- [Code Walkthrough](docs/CODE_WALKTHROUGH.md)
- [AI Insights](docs/AI_INSIGHTS.md)
- [Tailscale Private Access](docs/TAILSCALE_PRIVATE_ACCESS.md)
- [Packaging And Publishing](docs/PACKAGING.md)

## Current Limitations

- No app-level login yet.
- No built-in encryption-at-rest yet.
- No SQLite database yet.
- No multi-user file locking yet.
- No online deployment target yet.
- Whisper and LLM features depend on optional local packages and local model files.

For internet access, keep it private with Tailscale until app-level accounts and
database-level concurrency are added.

## Suggested Next Version Work

Good candidates for the next version:

- Add local accounts and user ownership.
- Move data to SQLite while keeping JSON export/import.
- Add file locking or transaction safety for multiple users.
- Add budget-entry editing/deletion.
- Add transcript search across tasks, mind logs, project audio, and budget audio.
- Add AI summaries over transcripts.
- Add calendar export/import.
- Add charts for budget and energy trends.
- Add automated nightly backup verification.

## License

MIT License. See [LICENSE](LICENSE).

Runtime data is intentionally excluded from Git by `.gitignore`. Do not commit
personal task files, mind logs, budget files, transcripts, audio files, backups,
settings, or local model files.
