opencode-db 0.7.0__tar.gz → 0.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opencode_db-0.7.0/opencode_db.egg-info → opencode_db-0.7.3}/PKG-INFO +6 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3}/README.md +129 -51
- {opencode_db-0.7.0 → opencode_db-0.7.3/docs}/README_PYPI.md +5 -2
- opencode_db-0.7.3/opencode_db/__init__.py +5 -0
- opencode_db-0.7.3/opencode_db/__main__.py +6 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/cli.py +9 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/commands/__init__.py +18 -16
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_costs.py +7 -7
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_delete.py +3 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_export.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_help.py +2 -2
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_info.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_list.py +5 -5
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_projects.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_prune.py +3 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_search.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_stats.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_todos.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_tree.py +3 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_vacuum.py +3 -3
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db/commands}/cmd_view.py +4 -4
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/db.py +2 -2
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/formatters.py +2 -2
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/i18n.py +1 -1
- opencode_db-0.7.3/opencode_db/runtime.py +55 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/utils.py +2 -2
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db.egg-info}/PKG-INFO +6 -3
- opencode_db-0.7.3/opencode_db.egg-info/SOURCES.txt +41 -0
- opencode_db-0.7.3/opencode_db.egg-info/entry_points.txt +2 -0
- opencode_db-0.7.3/opencode_db.egg-info/top_level.txt +1 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3}/pyproject.toml +6 -14
- {opencode_db-0.7.0 → opencode_db-0.7.3}/tests/test_commands.py +81 -81
- {opencode_db-0.7.0 → opencode_db-0.7.3}/tests/test_db.py +1 -1
- {opencode_db-0.7.0 → opencode_db-0.7.3}/tests/test_formatters.py +1 -1
- {opencode_db-0.7.0 → opencode_db-0.7.3}/tests/test_i18n.py +2 -2
- opencode_db-0.7.3/tests/test_runtime.py +21 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3}/tests/test_utils.py +1 -1
- opencode_db-0.7.0/opencode_db.egg-info/SOURCES.txt +0 -37
- opencode_db-0.7.0/opencode_db.egg-info/entry_points.txt +0 -2
- opencode_db-0.7.0/opencode_db.egg-info/top_level.txt +0 -22
- {opencode_db-0.7.0 → opencode_db-0.7.3}/LICENSE +0 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/config.py +0 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3/opencode_db}/markdown_to_ansi.py +0 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3}/opencode_db.egg-info/dependency_links.txt +0 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3}/opencode_db.egg-info/requires.txt +0 -0
- {opencode_db-0.7.0 → opencode_db-0.7.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-db
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: OpenCode database CLI manager — browse, export, analyze, clean up sessions
|
|
5
5
|
Project-URL: Homepage, https://github.com/VasilevNStas/opencode-db
|
|
6
6
|
Project-URL: Source, https://github.com/VasilevNStas/opencode-db
|
|
@@ -17,12 +17,15 @@ Dynamic: license-file
|
|
|
17
17
|
# opencode-db
|
|
18
18
|
|
|
19
19
|
[](https://www.python.org/downloads/)
|
|
20
|
-
[](LICENSE)
|
|
20
|
+
[](https://github.com/VasilevNStas/opencode-db/blob/master/LICENSE)
|
|
21
21
|
|
|
22
22
|
**CLI for OpenCode's local database.** OpenCode saves every agent session, conversation, token usage, and cost in a local SQLite file. This tool lets you inspect, export, analyze, and clean up that data.
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
pip install opencode-db
|
|
26
|
+
|
|
27
|
+
# recommended if your system python3 is older than 3.12:
|
|
28
|
+
uv tool install opencode-db
|
|
26
29
|
```
|
|
27
30
|
|
|
28
31
|
## Quick start
|
|
@@ -54,6 +57,6 @@ pip install opencode-db # zero external dependencies
|
|
|
54
57
|
|
|
55
58
|
## Requirements
|
|
56
59
|
|
|
57
|
-
- Python 3.12+
|
|
60
|
+
- Python 3.12+ — the CLI checks the interpreter at startup and exits with a clear message instead of an `ImportError` on older versions
|
|
58
61
|
- [OpenCode](https://opencode.ai) (must have been run at least once)
|
|
59
62
|
- macOS / Linux
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
**OpenCode stores everything in a local SQLite database.** Every agent session, conversation, token usage, and cost is saved automatically. `opencode-db` is the CLI tool to work with that database — list sessions, export conversations to Markdown, track token costs, prune old data, and more.
|
|
10
10
|
|
|
11
|
+
[Русская версия](docs/README.ru.md)
|
|
12
|
+
|
|
11
13
|
```
|
|
12
14
|
opencode-db help # full reference with examples
|
|
13
15
|
opencode-db list # list recent sessions
|
|
@@ -22,9 +24,10 @@ opencode-db costs --total # total token costs
|
|
|
22
24
|
|
|
23
25
|
### Requirements
|
|
24
26
|
|
|
25
|
-
- Python 3.12+
|
|
27
|
+
- Python 3.12+ — `opencode-db` refuses to start on older interpreters with a clear message (no cryptic `ImportError`)
|
|
26
28
|
- OpenCode (must have been run at least once — the database is created automatically)
|
|
27
29
|
- macOS / Linux
|
|
30
|
+
- [`uv`](https://docs.astral.sh/uv/) — optional, but recommended for installing and running on systems whose default `python3` is older than 3.12
|
|
28
31
|
|
|
29
32
|
### Database location
|
|
30
33
|
|
|
@@ -51,13 +54,26 @@ opencode-db --db-path /path/to/opencode.db stats
|
|
|
51
54
|
|
|
52
55
|
The `--db-path` flag takes precedence over the environment variable.
|
|
53
56
|
|
|
54
|
-
###
|
|
57
|
+
### Recommended: uv
|
|
58
|
+
|
|
59
|
+
If your system `python3` is older than 3.12 (for example, macOS ships 3.9), use `uv` — it installs the tool into an isolated environment with a supported interpreter:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv tool install opencode-db
|
|
63
|
+
# with enhanced Markdown rendering:
|
|
64
|
+
uv tool install "opencode-db[rich]"
|
|
65
|
+
|
|
66
|
+
# one-off run without installing:
|
|
67
|
+
uvx opencode-db stats
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### One-command install
|
|
55
71
|
|
|
56
72
|
```bash
|
|
57
73
|
curl -fsSL https://raw.githubusercontent.com/VasilevNStas/opencode-db/master/install.sh | sh
|
|
58
74
|
```
|
|
59
75
|
|
|
60
|
-
Downloads everything to `~/.local/share/opencode-db/` and creates `~/.local/bin/opencode-db`.
|
|
76
|
+
Downloads everything to `~/.local/share/opencode-db/` and creates `~/.local/bin/opencode-db`. The installer looks for Python 3.12+ (including interpreters managed by `uv` or `pyenv`) and writes the discovered path into the launcher shebang.
|
|
61
77
|
|
|
62
78
|
### pip / pipx install
|
|
63
79
|
|
|
@@ -67,7 +83,7 @@ pipx install opencode-db
|
|
|
67
83
|
pip install opencode-db
|
|
68
84
|
```
|
|
69
85
|
|
|
70
|
-
[Zero external dependencies](https://treyhunner.com/2015/12/python-imports-and-path-manipulation/) — pure Python standard library only.
|
|
86
|
+
[Zero external dependencies](https://treyhunner.com/2015/12/python-imports-and-path-manipulation/) — pure Python standard library only (`rich` is optional).
|
|
71
87
|
|
|
72
88
|
### Manual install
|
|
73
89
|
|
|
@@ -82,12 +98,22 @@ git clone https://github.com/VasilevNStas/opencode-db.git ~/.local/share/opencod
|
|
|
82
98
|
```bash
|
|
83
99
|
cat > ~/.local/bin/opencode-db << 'SCRIPT'
|
|
84
100
|
#!/usr/bin/env python3
|
|
85
|
-
import
|
|
101
|
+
import os
|
|
102
|
+
import sys
|
|
103
|
+
|
|
104
|
+
if sys.version_info < (3, 12):
|
|
105
|
+
print(
|
|
106
|
+
"opencode-db requires Python 3.12+; current: %s (%s)"
|
|
107
|
+
% (".".join(map(str, sys.version_info[:3])), sys.executable),
|
|
108
|
+
file=sys.stderr,
|
|
109
|
+
)
|
|
110
|
+
raise SystemExit(1)
|
|
111
|
+
|
|
86
112
|
PKG_DIR = os.path.expanduser("~/.local/share/opencode-db")
|
|
87
113
|
if PKG_DIR not in sys.path:
|
|
88
114
|
sys.path.insert(0, PKG_DIR)
|
|
89
|
-
import
|
|
90
|
-
sys.exit(
|
|
115
|
+
from opencode_db.cli import main
|
|
116
|
+
sys.exit(main())
|
|
91
117
|
SCRIPT
|
|
92
118
|
chmod +x ~/.local/bin/opencode-db
|
|
93
119
|
```
|
|
@@ -483,49 +509,56 @@ Example output:
|
|
|
483
509
|
## Project architecture
|
|
484
510
|
|
|
485
511
|
```
|
|
486
|
-
|
|
512
|
+
opencode-db/
|
|
513
|
+
├── opencode_db/ ← Python package (installed as opencode_db)
|
|
514
|
+
│ ├── __init__.py ← package init + Python version guard
|
|
515
|
+
│ ├── __main__.py ← python3 -m opencode_db
|
|
516
|
+
│ ├── cli.py ← argparse + command dispatcher
|
|
517
|
+
│ ├── config.py ← constants and paths
|
|
518
|
+
│ ├── db.py ← SQLite queries
|
|
519
|
+
│ ├── formatters.py ← tables, JSON, Markdown, snapshots
|
|
520
|
+
│ ├── i18n.py ← localization (EN/RU, 280 keys)
|
|
521
|
+
│ ├── markdown_to_ansi.py ← Markdown → ANSI renderer for `view`
|
|
522
|
+
│ ├── runtime.py ← Python 3.12+ version guard
|
|
523
|
+
│ ├── utils.py ← date/token formatting, validation
|
|
524
|
+
│ └── commands/
|
|
525
|
+
│ ├── __init__.py ← command registry
|
|
526
|
+
│ ├── cmd_list.py ← opencode-db list
|
|
527
|
+
│ ├── cmd_info.py ← opencode-db info
|
|
528
|
+
│ ├── cmd_export.py ← opencode-db export
|
|
529
|
+
│ ├── cmd_delete.py ← opencode-db delete
|
|
530
|
+
│ ├── cmd_costs.py ← opencode-db costs
|
|
531
|
+
│ ├── cmd_prune.py ← opencode-db prune
|
|
532
|
+
│ ├── cmd_search.py ← opencode-db search
|
|
533
|
+
│ ├── cmd_tree.py ← opencode-db tree
|
|
534
|
+
│ ├── cmd_projects.py ← opencode-db projects
|
|
535
|
+
│ ├── cmd_stats.py ← opencode-db stats
|
|
536
|
+
│ ├── cmd_todos.py ← opencode-db todos
|
|
537
|
+
│ ├── cmd_vacuum.py ← opencode-db vacuum
|
|
538
|
+
│ ├── cmd_view.py ← opencode-db view
|
|
539
|
+
│ └── cmd_help.py ← opencode-db help
|
|
487
540
|
│
|
|
488
|
-
|
|
489
|
-
│
|
|
490
|
-
|
|
491
|
-
├──
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
├──
|
|
495
|
-
├──
|
|
496
|
-
├──
|
|
497
|
-
├──
|
|
498
|
-
|
|
499
|
-
│
|
|
500
|
-
├── commands/
|
|
501
|
-
│ └── __init__.py ← command registry
|
|
502
|
-
│
|
|
503
|
-
├── cmd_list.py ← opencode-db list
|
|
504
|
-
├── cmd_info.py ← opencode-db info
|
|
505
|
-
├── cmd_export.py ← opencode-db export
|
|
506
|
-
├── cmd_delete.py ← opencode-db delete
|
|
507
|
-
├── cmd_costs.py ← opencode-db costs
|
|
508
|
-
├── cmd_prune.py ← opencode-db prune
|
|
509
|
-
├── cmd_search.py ← opencode-db search
|
|
510
|
-
├── cmd_tree.py ← opencode-db tree
|
|
511
|
-
├── cmd_projects.py ← opencode-db projects
|
|
512
|
-
├── cmd_stats.py ← opencode-db stats
|
|
513
|
-
├── cmd_todos.py ← opencode-db todos
|
|
514
|
-
├── cmd_vacuum.py ← opencode-db vacuum
|
|
515
|
-
└── cmd_help.py ← opencode-db help
|
|
516
|
-
|
|
517
|
-
README.md ← this file (English)
|
|
518
|
-
README.ru.md ← documentation in Russian
|
|
519
|
-
opencode-db-commands.json ← OpenCode TUI custom commands config
|
|
541
|
+
├── docs/
|
|
542
|
+
│ ├── README.ru.md ← documentation in Russian
|
|
543
|
+
│ └── README_PYPI.md ← PyPI page
|
|
544
|
+
├── contrib/
|
|
545
|
+
│ └── opencode-db-commands.json ← OpenCode TUI custom commands config
|
|
546
|
+
├── tests/
|
|
547
|
+
├── README.md ← this file (English)
|
|
548
|
+
├── LICENSE
|
|
549
|
+
├── Makefile
|
|
550
|
+
├── pyproject.toml
|
|
551
|
+
└── install.sh
|
|
520
552
|
```
|
|
521
553
|
|
|
522
554
|
### How it works
|
|
523
555
|
|
|
524
|
-
1. The
|
|
525
|
-
2. `
|
|
526
|
-
3.
|
|
527
|
-
4. `
|
|
528
|
-
5.
|
|
556
|
+
1. The console script `opencode-db` (or `python3 -m opencode_db`) imports `opencode_db.cli` and calls `main()`.
|
|
557
|
+
2. `runtime.require_python()` checks the interpreter before importing `cli`/`db`; on Python < 3.12 it prints a clear message with remediation steps instead of failing with `ImportError`.
|
|
558
|
+
3. `cli.py` builds an `argparse` parser with subparsers from every command module and dispatches the call.
|
|
559
|
+
4. Each command is a separate `opencode_db/commands/cmd_*.py` module exporting two functions: `register(subparsers)` and `run(args, db)`.
|
|
560
|
+
5. `db.py` opens a connection to OpenCode's SQLite database (`~/.local/share/opencode/opencode.db`).
|
|
561
|
+
6. Destructive operations (`delete`, `prune`) always require confirmation (or `--force`).
|
|
529
562
|
|
|
530
563
|
### Database schema (key tables)
|
|
531
564
|
|
|
@@ -558,7 +591,7 @@ This runs the command directly and shows the output — **no tokens are consumed
|
|
|
558
591
|
|
|
559
592
|
### Custom `/db` command (uses AI, consumes tokens)
|
|
560
593
|
|
|
561
|
-
Add the commands from `opencode-db-commands.json` to your project's `opencode.json`:
|
|
594
|
+
Add the commands from `contrib/opencode-db-commands.json` to your project's `opencode.json`:
|
|
562
595
|
|
|
563
596
|
```json
|
|
564
597
|
{
|
|
@@ -586,7 +619,7 @@ Then in the TUI:
|
|
|
586
619
|
|
|
587
620
|
A ready-to-use config file is provided at:
|
|
588
621
|
```
|
|
589
|
-
~/.local/share/opencode-db/opencode-db-commands.json
|
|
622
|
+
~/.local/share/opencode-db/contrib/opencode-db-commands.json
|
|
590
623
|
```
|
|
591
624
|
|
|
592
625
|
---
|
|
@@ -617,7 +650,7 @@ opencode-db --lang en help # English help text
|
|
|
617
650
|
opencode-db --lang en stats # English statistics
|
|
618
651
|
```
|
|
619
652
|
|
|
620
|
-
The `--lang` flag applies to any command. All
|
|
653
|
+
The `--lang` flag applies to any command. All 280 UI strings are translated. Data content (session titles, project names, etc.) remains in its original language.
|
|
621
654
|
|
|
622
655
|
The language can also be set via environment variable `OPENCODE_DB_LANG=en`.
|
|
623
656
|
|
|
@@ -659,13 +692,57 @@ Use a longer prefix or the full session ID (use `list --json` to find it).
|
|
|
659
692
|
|
|
660
693
|
If the database is being used by another process (e.g., OpenCode is running), VACUUM may fail. Close OpenCode and try again.
|
|
661
694
|
|
|
695
|
+
### `ImportError: cannot import name 'UTC' from 'datetime'`
|
|
696
|
+
|
|
697
|
+
This means `opencode-db` is running on Python older than 3.12 (for example, the system Python 3.9). Check:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
python3 --version
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Fix with `uv` (recommended):
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
uv python install 3.13
|
|
707
|
+
uv tool install opencode-db
|
|
708
|
+
opencode-db stats
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
Or run the repository checkout with an explicit interpreter:
|
|
712
|
+
|
|
713
|
+
```bash
|
|
714
|
+
uvx --from . opencode-db stats
|
|
715
|
+
# alternative for a persistent dev environment:
|
|
716
|
+
uv run --python 3.13 opencode-db stats
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
After changing the interpreter, rerun `install.sh` to regenerate the `~/.local/bin/opencode-db` launcher.
|
|
720
|
+
|
|
662
721
|
---
|
|
663
722
|
|
|
664
723
|
## Development
|
|
665
724
|
|
|
725
|
+
### Local development
|
|
726
|
+
|
|
727
|
+
Requires Python 3.12+ and `pytest`/`ruff`:
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
git clone https://github.com/VasilevNStas/opencode-db.git
|
|
731
|
+
cd opencode-db
|
|
732
|
+
|
|
733
|
+
uv venv --python 3.13
|
|
734
|
+
source .venv/bin/activate
|
|
735
|
+
uv pip install -e ".[rich]"
|
|
736
|
+
uv pip install pytest ruff==0.17.1
|
|
737
|
+
|
|
738
|
+
make check # check-python + ruff + 191 tests
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
`make check` fails fast with a clear message if the active interpreter is older than 3.12.
|
|
742
|
+
|
|
666
743
|
### Adding a new command
|
|
667
744
|
|
|
668
|
-
1. Create `cmd_xxx.py`:
|
|
745
|
+
1. Create `opencode_db/commands/cmd_xxx.py`:
|
|
669
746
|
|
|
670
747
|
```python
|
|
671
748
|
def register(subparsers):
|
|
@@ -677,7 +754,7 @@ def run(args, db):
|
|
|
677
754
|
return 0
|
|
678
755
|
```
|
|
679
756
|
|
|
680
|
-
2. Register it in `commands/__init__.py`:
|
|
757
|
+
2. Register it in `opencode_db/commands/__init__.py`:
|
|
681
758
|
|
|
682
759
|
```python
|
|
683
760
|
import cmd_xxx
|
|
@@ -692,10 +769,11 @@ The command will appear in `--help` automatically.
|
|
|
692
769
|
python3 ~/.local/share/opencode-db list
|
|
693
770
|
```
|
|
694
771
|
|
|
695
|
-
Or
|
|
772
|
+
Or from the repository root (Python 3.12+):
|
|
696
773
|
|
|
697
774
|
```bash
|
|
698
775
|
python3 -m opencode_db list
|
|
776
|
+
uvx --from . opencode-db list
|
|
699
777
|
```
|
|
700
778
|
|
|
701
779
|
---
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# opencode-db
|
|
2
2
|
|
|
3
3
|
[](https://www.python.org/downloads/)
|
|
4
|
-
[](LICENSE)
|
|
4
|
+
[](https://github.com/VasilevNStas/opencode-db/blob/master/LICENSE)
|
|
5
5
|
|
|
6
6
|
**CLI for OpenCode's local database.** OpenCode saves every agent session, conversation, token usage, and cost in a local SQLite file. This tool lets you inspect, export, analyze, and clean up that data.
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
pip install opencode-db
|
|
10
|
+
|
|
11
|
+
# recommended if your system python3 is older than 3.12:
|
|
12
|
+
uv tool install opencode-db
|
|
10
13
|
```
|
|
11
14
|
|
|
12
15
|
## Quick start
|
|
@@ -38,6 +41,6 @@ pip install opencode-db # zero external dependencies
|
|
|
38
41
|
|
|
39
42
|
## Requirements
|
|
40
43
|
|
|
41
|
-
- Python 3.12+
|
|
44
|
+
- Python 3.12+ — the CLI checks the interpreter at startup and exits with a clear message instead of an `ImportError` on older versions
|
|
42
45
|
- [OpenCode](https://opencode.ai) (must have been run at least once)
|
|
43
46
|
- macOS / Linux
|
|
@@ -7,14 +7,20 @@
|
|
|
7
7
|
- Единообразный интерфейс
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
10
12
|
import argparse
|
|
11
13
|
import os
|
|
12
14
|
import sys
|
|
13
15
|
from typing import Any, Literal
|
|
14
16
|
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
from .runtime import require_python
|
|
18
|
+
|
|
19
|
+
require_python()
|
|
20
|
+
|
|
21
|
+
from . import commands # noqa: E402
|
|
22
|
+
from .db import get_db # noqa: E402
|
|
23
|
+
from .i18n import _, set_lang # noqa: E402
|
|
18
24
|
|
|
19
25
|
|
|
20
26
|
def build_parser() -> argparse.ArgumentParser:
|
|
@@ -5,25 +5,27 @@
|
|
|
5
5
|
- run(args, db) — выполняет команду
|
|
6
6
|
|
|
7
7
|
Добавление новой команды:
|
|
8
|
-
1. Создать cmd_xxx.py
|
|
9
|
-
2. Добавить import cmd_xxx
|
|
8
|
+
1. Создать opencode_db/commands/cmd_xxx.py
|
|
9
|
+
2. Добавить `from . import cmd_xxx`
|
|
10
10
|
3. Добавить "xxx": cmd_xxx в COMMANDS
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
from . import (
|
|
14
|
+
cmd_costs,
|
|
15
|
+
cmd_delete,
|
|
16
|
+
cmd_export,
|
|
17
|
+
cmd_help,
|
|
18
|
+
cmd_info,
|
|
19
|
+
cmd_list,
|
|
20
|
+
cmd_projects,
|
|
21
|
+
cmd_prune,
|
|
22
|
+
cmd_search,
|
|
23
|
+
cmd_stats,
|
|
24
|
+
cmd_todos,
|
|
25
|
+
cmd_tree,
|
|
26
|
+
cmd_vacuum,
|
|
27
|
+
cmd_view,
|
|
28
|
+
)
|
|
27
29
|
|
|
28
30
|
# Словарь {имя_команды: модуль}
|
|
29
31
|
# Модуль должен иметь register(subparsers) и run(args, db)
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
7
|
|
|
8
|
-
from db import SessionError, get_session_info, get_session_title, parse_model
|
|
9
|
-
from i18n import _
|
|
10
|
-
from utils import build_help_epilog, format_cost, format_tokens
|
|
8
|
+
from ..db import SessionError, get_session_info, get_session_title, parse_model
|
|
9
|
+
from ..i18n import _
|
|
10
|
+
from ..utils import build_help_epilog, format_cost, format_tokens
|
|
11
11
|
|
|
12
12
|
_COSTS_EXAMPLES = [
|
|
13
13
|
("", "help.costs.e0"),
|
|
@@ -57,7 +57,7 @@ def _show_session(db, session_id, as_json) -> int:
|
|
|
57
57
|
cost = info["cost"] or 0
|
|
58
58
|
|
|
59
59
|
if as_json:
|
|
60
|
-
from formatters import print_json
|
|
60
|
+
from ..formatters import print_json
|
|
61
61
|
|
|
62
62
|
print_json(
|
|
63
63
|
{
|
|
@@ -115,7 +115,7 @@ def _show_total(db, project_id, as_json) -> int:
|
|
|
115
115
|
total_tr = row["tr"] or 0
|
|
116
116
|
|
|
117
117
|
if as_json:
|
|
118
|
-
from formatters import print_json
|
|
118
|
+
from ..formatters import print_json
|
|
119
119
|
|
|
120
120
|
print_json(
|
|
121
121
|
{
|
|
@@ -165,7 +165,7 @@ def _show_list(db, project_id, limit, as_json) -> int:
|
|
|
165
165
|
).fetchall()
|
|
166
166
|
|
|
167
167
|
if as_json:
|
|
168
|
-
from formatters import print_json
|
|
168
|
+
from ..formatters import print_json
|
|
169
169
|
|
|
170
170
|
data = []
|
|
171
171
|
for r in rows:
|
|
@@ -183,7 +183,7 @@ def _show_list(db, project_id, limit, as_json) -> int:
|
|
|
183
183
|
print_json(data)
|
|
184
184
|
return 0
|
|
185
185
|
|
|
186
|
-
from formatters import print_table_simple
|
|
186
|
+
from ..formatters import print_table_simple
|
|
187
187
|
|
|
188
188
|
table = []
|
|
189
189
|
for r in rows:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
|
|
5
|
-
from db import (
|
|
5
|
+
from ..db import (
|
|
6
6
|
SessionError,
|
|
7
7
|
get_message_count,
|
|
8
8
|
get_part_count,
|
|
@@ -11,8 +11,8 @@ from db import (
|
|
|
11
11
|
get_session_title,
|
|
12
12
|
parse_model,
|
|
13
13
|
)
|
|
14
|
-
from i18n import _
|
|
15
|
-
from utils import build_help_epilog, confirm, format_cost, format_ts, parse_date, parse_time_spec
|
|
14
|
+
from ..i18n import _
|
|
15
|
+
from ..utils import build_help_epilog, confirm, format_cost, format_ts, parse_date, parse_time_spec
|
|
16
16
|
|
|
17
17
|
_DELETE_EXAMPLES = [
|
|
18
18
|
("<session_id>", "help.delete.e0"),
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import argparse
|
|
10
10
|
import os
|
|
11
11
|
|
|
12
|
-
from db import (
|
|
12
|
+
from ..db import (
|
|
13
13
|
SessionError,
|
|
14
14
|
get_latest_session,
|
|
15
15
|
get_messages,
|
|
@@ -18,9 +18,9 @@ from db import (
|
|
|
18
18
|
get_session_title,
|
|
19
19
|
parse_model,
|
|
20
20
|
)
|
|
21
|
-
from formatters import collect_snapshot, format_part_to_md, update_log
|
|
22
|
-
from i18n import _
|
|
23
|
-
from utils import build_help_epilog, format_cost, format_ts, format_ts_short
|
|
21
|
+
from ..formatters import collect_snapshot, format_part_to_md, update_log
|
|
22
|
+
from ..i18n import _
|
|
23
|
+
from ..utils import build_help_epilog, format_cost, format_ts, format_ts_short
|
|
24
24
|
|
|
25
25
|
_EXPORT_EXAMPLES = [
|
|
26
26
|
("<session_id>", "help.export.e0"),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
|
|
5
|
-
from db import (
|
|
5
|
+
from ..db import (
|
|
6
6
|
SessionError,
|
|
7
7
|
get_children_sessions,
|
|
8
8
|
get_message_count,
|
|
@@ -14,8 +14,8 @@ from db import (
|
|
|
14
14
|
get_session_todos,
|
|
15
15
|
parse_model,
|
|
16
16
|
)
|
|
17
|
-
from i18n import _
|
|
18
|
-
from utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
17
|
+
from ..i18n import _
|
|
18
|
+
from ..utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
19
19
|
|
|
20
20
|
_INFO_EXAMPLES = [
|
|
21
21
|
("<session_id>", "help.info.e0"),
|
|
@@ -104,7 +104,7 @@ def run(args, db) -> int:
|
|
|
104
104
|
if parent:
|
|
105
105
|
data["parent"] = {"id": parent["id"], "title": parent["title"]}
|
|
106
106
|
|
|
107
|
-
from formatters import print_json
|
|
107
|
+
from ..formatters import print_json
|
|
108
108
|
|
|
109
109
|
print_json(data)
|
|
110
110
|
return 0
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
-
import db as db_module
|
|
7
|
-
from db import get_session_title, parse_model
|
|
8
|
-
from formatters import print_json, print_table_simple
|
|
9
|
-
from i18n import _
|
|
10
|
-
from utils import build_help_epilog, format_ts
|
|
6
|
+
from .. import db as db_module
|
|
7
|
+
from ..db import get_session_title, parse_model
|
|
8
|
+
from ..formatters import print_json, print_table_simple
|
|
9
|
+
from ..i18n import _
|
|
10
|
+
from ..utils import build_help_epilog, format_ts
|
|
11
11
|
|
|
12
12
|
_LIST_EXAMPLES = [
|
|
13
13
|
("", "help.list.e0"),
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
-
from i18n import _
|
|
7
|
-
from utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
6
|
+
from ..i18n import _
|
|
7
|
+
from ..utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
8
8
|
|
|
9
9
|
_PROJECTS_EXAMPLES = [
|
|
10
10
|
("", "help.projects.e0"),
|
|
@@ -37,7 +37,7 @@ def run(args, db) -> Literal[0]:
|
|
|
37
37
|
""").fetchall()
|
|
38
38
|
|
|
39
39
|
if args.json:
|
|
40
|
-
from formatters import print_json
|
|
40
|
+
from ..formatters import print_json
|
|
41
41
|
|
|
42
42
|
data = []
|
|
43
43
|
for r in rows:
|
|
@@ -59,7 +59,7 @@ def run(args, db) -> Literal[0]:
|
|
|
59
59
|
print_json(data)
|
|
60
60
|
return 0
|
|
61
61
|
|
|
62
|
-
from formatters import print_table_simple
|
|
62
|
+
from ..formatters import print_table_simple
|
|
63
63
|
|
|
64
64
|
table = []
|
|
65
65
|
for r in rows:
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
5
|
+
from ..i18n import _
|
|
6
|
+
from ..utils import build_help_epilog
|
|
7
|
+
from .cmd_delete import run as delete_run
|
|
8
8
|
|
|
9
9
|
_PRUNE_EXAMPLES = [
|
|
10
10
|
("--older-than 90d", "help.prune.e0"),
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
import json
|
|
5
5
|
|
|
6
|
-
from db import SessionError, resolve_session_id
|
|
7
|
-
from i18n import _
|
|
8
|
-
from utils import build_help_epilog, format_ts
|
|
6
|
+
from ..db import SessionError, resolve_session_id
|
|
7
|
+
from ..i18n import _
|
|
8
|
+
from ..utils import build_help_epilog, format_ts
|
|
9
9
|
|
|
10
10
|
_SEARCH_EXAMPLES = [
|
|
11
11
|
('"text"', "help.search.e0"),
|
|
@@ -103,7 +103,7 @@ def run(args, db) -> int:
|
|
|
103
103
|
break
|
|
104
104
|
|
|
105
105
|
if args.json:
|
|
106
|
-
from formatters import print_json
|
|
106
|
+
from ..formatters import print_json
|
|
107
107
|
|
|
108
108
|
print_json(results)
|
|
109
109
|
return 0
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
-
from db import parse_model
|
|
7
|
-
from i18n import _
|
|
8
|
-
from utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
6
|
+
from ..db import parse_model
|
|
7
|
+
from ..i18n import _
|
|
8
|
+
from ..utils import build_help_epilog, format_cost, format_tokens, format_ts
|
|
9
9
|
|
|
10
10
|
_STATS_EXAMPLES = [
|
|
11
11
|
("", "help.stats.e0"),
|
|
@@ -64,7 +64,7 @@ def run(args, db) -> Literal[0]:
|
|
|
64
64
|
""").fetchall()
|
|
65
65
|
|
|
66
66
|
if args.json:
|
|
67
|
-
from formatters import print_json
|
|
67
|
+
from ..formatters import print_json
|
|
68
68
|
|
|
69
69
|
data = {
|
|
70
70
|
"sessions": session_count,
|