opencode-db 0.5.0__tar.gz → 0.5.1__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.
Files changed (36) hide show
  1. {opencode_db-0.5.0/opencode_db.egg-info → opencode_db-0.5.1}/PKG-INFO +1 -1
  2. {opencode_db-0.5.0 → opencode_db-0.5.1}/README.md +1 -1
  3. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_costs.py +17 -2
  4. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_delete.py +15 -2
  5. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_export.py +17 -2
  6. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_help.py +28 -2
  7. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_info.py +14 -2
  8. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_list.py +16 -2
  9. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_projects.py +13 -2
  10. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_prune.py +15 -4
  11. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_search.py +14 -2
  12. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_stats.py +13 -2
  13. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_todos.py +16 -2
  14. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_tree.py +15 -2
  15. {opencode_db-0.5.0 → opencode_db-0.5.1}/cmd_vacuum.py +13 -2
  16. {opencode_db-0.5.0 → opencode_db-0.5.1}/i18n.py +23 -3
  17. {opencode_db-0.5.0 → opencode_db-0.5.1/opencode_db.egg-info}/PKG-INFO +1 -1
  18. {opencode_db-0.5.0 → opencode_db-0.5.1}/pyproject.toml +1 -1
  19. {opencode_db-0.5.0 → opencode_db-0.5.1}/utils.py +21 -0
  20. {opencode_db-0.5.0 → opencode_db-0.5.1}/LICENSE +0 -0
  21. {opencode_db-0.5.0 → opencode_db-0.5.1}/README_PYPI.md +0 -0
  22. {opencode_db-0.5.0 → opencode_db-0.5.1}/cli.py +0 -0
  23. {opencode_db-0.5.0 → opencode_db-0.5.1}/commands/__init__.py +0 -0
  24. {opencode_db-0.5.0 → opencode_db-0.5.1}/config.py +0 -0
  25. {opencode_db-0.5.0 → opencode_db-0.5.1}/db.py +0 -0
  26. {opencode_db-0.5.0 → opencode_db-0.5.1}/formatters.py +0 -0
  27. {opencode_db-0.5.0 → opencode_db-0.5.1}/opencode_db.egg-info/SOURCES.txt +0 -0
  28. {opencode_db-0.5.0 → opencode_db-0.5.1}/opencode_db.egg-info/dependency_links.txt +0 -0
  29. {opencode_db-0.5.0 → opencode_db-0.5.1}/opencode_db.egg-info/entry_points.txt +0 -0
  30. {opencode_db-0.5.0 → opencode_db-0.5.1}/opencode_db.egg-info/top_level.txt +0 -0
  31. {opencode_db-0.5.0 → opencode_db-0.5.1}/setup.cfg +0 -0
  32. {opencode_db-0.5.0 → opencode_db-0.5.1}/tests/test_commands.py +0 -0
  33. {opencode_db-0.5.0 → opencode_db-0.5.1}/tests/test_db.py +0 -0
  34. {opencode_db-0.5.0 → opencode_db-0.5.1}/tests/test_formatters.py +0 -0
  35. {opencode_db-0.5.0 → opencode_db-0.5.1}/tests/test_i18n.py +0 -0
  36. {opencode_db-0.5.0 → opencode_db-0.5.1}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-db
3
- Version: 0.5.0
3
+ Version: 0.5.1
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
@@ -409,7 +409,7 @@ Example output:
409
409
 
410
410
  ```
411
411
  ╔══════════════════════════════════════════════════════════╗
412
- ║ opencode-db — справка ║
412
+ ║ opencode-db — справка ║
413
413
  ╚══════════════════════════════════════════════════════════╝
414
414
 
415
415
  Использование: opencode-db <команда> [флаги]
@@ -3,13 +3,28 @@
3
3
  Стоимость берётся напрямую из поля session.cost БД OpenCode.
4
4
  """
5
5
 
6
+ import argparse
7
+
6
8
  from db import SessionError, get_session_info, get_session_title, parse_model
7
9
  from i18n import _
8
- from utils import format_cost, format_tokens
10
+ from utils import build_help_epilog, format_cost, format_tokens
11
+
12
+ _COSTS_EXAMPLES = [
13
+ ("", "help.costs.e0"),
14
+ ("<session_id>", "help.costs.e1"),
15
+ ("--total", "help.costs.e2"),
16
+ ("--project proj_xxx", "help.costs.e3"),
17
+ ("--json", "help.costs.e4"),
18
+ ]
9
19
 
10
20
 
11
21
  def register(subparsers) -> None:
12
- p = subparsers.add_parser("costs", help=_("help.cmd.costs"))
22
+ p = subparsers.add_parser(
23
+ "costs",
24
+ help=_("help.cmd.costs"),
25
+ formatter_class=argparse.RawDescriptionHelpFormatter,
26
+ epilog=build_help_epilog("costs", _COSTS_EXAMPLES),
27
+ )
13
28
  p.add_argument("session_id", nargs="?", help="Session ID")
14
29
  p.add_argument("--project", type=str, help="Filter by project")
15
30
  p.add_argument("--total", action="store_true", help="Total across all sessions")
@@ -1,5 +1,7 @@
1
1
  """Команда delete: удаление сессии."""
2
2
 
3
+ import argparse
4
+
3
5
  from db import (
4
6
  SessionError,
5
7
  get_message_count,
@@ -9,11 +11,22 @@ from db import (
9
11
  parse_model,
10
12
  )
11
13
  from i18n import _
12
- from utils import confirm, format_cost, format_ts
14
+ from utils import build_help_epilog, confirm, format_cost, format_ts
15
+
16
+ _DELETE_EXAMPLES = [
17
+ ("<session_id>", "help.delete.e0"),
18
+ ("<session_id> --dry-run", "help.delete.e1"),
19
+ ("<session_id> --force", "help.delete.e2"),
20
+ ]
13
21
 
14
22
 
15
23
  def register(subparsers) -> None:
16
- p = subparsers.add_parser("delete", help=_("help.cmd.delete"))
24
+ p = subparsers.add_parser(
25
+ "delete",
26
+ help=_("help.cmd.delete"),
27
+ formatter_class=argparse.RawDescriptionHelpFormatter,
28
+ epilog=build_help_epilog("delete", _DELETE_EXAMPLES),
29
+ )
17
30
  p.add_argument("session_id", help="Session ID to delete")
18
31
  p.add_argument("--dry-run", action="store_true", help="Preview without deleting")
19
32
  p.add_argument("--force", "-f", action="store_true", help="Skip confirmation")
@@ -6,6 +6,7 @@
6
6
  - export (без аргументов) — интерактивный выбор из списка
7
7
  """
8
8
 
9
+ import argparse
9
10
  import os
10
11
 
11
12
  from db import (
@@ -19,11 +20,25 @@ from db import (
19
20
  )
20
21
  from formatters import collect_snapshot, format_part_to_md, update_log
21
22
  from i18n import _
22
- from utils import format_cost, format_ts, format_ts_short
23
+ from utils import build_help_epilog, format_cost, format_ts, format_ts_short
24
+
25
+ _EXPORT_EXAMPLES = [
26
+ ("<session_id>", "help.export.e0"),
27
+ ("--latest", "help.export.e1"),
28
+ ("", "help.export.e2"),
29
+ ("--full", "help.export.e3"),
30
+ ("--force", "help.export.e4"),
31
+ ('--note "text"', "help.export.e5"),
32
+ ]
23
33
 
24
34
 
25
35
  def register(subparsers) -> None:
26
- p = subparsers.add_parser("export", help=_("help.cmd.export"))
36
+ p = subparsers.add_parser(
37
+ "export",
38
+ help=_("help.cmd.export"),
39
+ formatter_class=argparse.RawDescriptionHelpFormatter,
40
+ epilog=build_help_epilog("export", _EXPORT_EXAMPLES),
41
+ )
27
42
  p.add_argument(
28
43
  "session_id",
29
44
  nargs="?",
@@ -1,17 +1,37 @@
1
1
  """Команда help: подробная справка по opencode-db."""
2
2
 
3
+ import argparse
3
4
  from typing import Literal
4
5
 
5
6
  from i18n import _
7
+ from utils import build_help_epilog
8
+
9
+ _HELP_EXAMPLES = [
10
+ ("", "help.help.e0"),
11
+ ("<command>", "help.help.e1"),
12
+ ]
6
13
 
7
14
 
8
15
  def register(subparsers) -> None:
9
- p = subparsers.add_parser("help", help=_("help.cmd.help"))
16
+ p = subparsers.add_parser(
17
+ "help",
18
+ help=_("help.cmd.help"),
19
+ formatter_class=argparse.RawDescriptionHelpFormatter,
20
+ epilog=build_help_epilog("help", _HELP_EXAMPLES),
21
+ )
10
22
  p.add_argument("topic", nargs="?", help="Command name")
11
23
  p.add_argument("--json", action="store_true", help="JSON output")
12
24
 
13
25
 
14
26
  _COMMANDS = [
27
+ (
28
+ "help",
29
+ "help.cmd.help",
30
+ [
31
+ ("", "help.help.e0"),
32
+ ("<command>", "help.help.e1"),
33
+ ],
34
+ ),
15
35
  (
16
36
  "list",
17
37
  "help.cmd.list",
@@ -173,8 +193,14 @@ def _print_command_help(cmd_name) -> Literal[1] | Literal[0]:
173
193
 
174
194
  desc_key, examples = entry
175
195
  print()
176
- print(_("help.cmd_header", cmd=cmd_name, desc=_(desc_key)))
196
+ print(f" {'─' * 55}")
197
+ print(f" {_('help.cmd_header', cmd=cmd_name, desc=_(desc_key))}")
198
+ print(f" {'─' * 55}")
199
+ print()
200
+ print(f" {_('help.flags_header', cmd=cmd_name)}")
201
+ print(f" opencode-db {cmd_name} --help")
177
202
  print()
203
+ print(f" {_('help.usage_header', cmd=cmd_name)}")
178
204
  for flag, example_key in examples:
179
205
  example_desc = _(example_key)
180
206
  if flag:
@@ -1,5 +1,7 @@
1
1
  """Команда info: детальная информация о сессии."""
2
2
 
3
+ import argparse
4
+
3
5
  from db import (
4
6
  SessionError,
5
7
  get_children_sessions,
@@ -13,11 +15,21 @@ from db import (
13
15
  parse_model,
14
16
  )
15
17
  from i18n import _
16
- from utils import format_cost, format_tokens, format_ts
18
+ from utils import build_help_epilog, format_cost, format_tokens, format_ts
19
+
20
+ _INFO_EXAMPLES = [
21
+ ("<session_id>", "help.info.e0"),
22
+ ("<session_id> --json", "help.info.e1"),
23
+ ]
17
24
 
18
25
 
19
26
  def register(subparsers) -> None:
20
- p = subparsers.add_parser("info", help=_("help.cmd.info"))
27
+ p = subparsers.add_parser(
28
+ "info",
29
+ help=_("help.cmd.info"),
30
+ formatter_class=argparse.RawDescriptionHelpFormatter,
31
+ epilog=build_help_epilog("info", _INFO_EXAMPLES),
32
+ )
21
33
  p.add_argument("session_id", help="Session ID")
22
34
  p.add_argument("--json", action="store_true", help="JSON output")
23
35
 
@@ -1,16 +1,30 @@
1
1
  """Команда list: список сессий с фильтрацией и сортировкой."""
2
2
 
3
+ import argparse
3
4
  from typing import Literal
4
5
 
5
6
  import db as db_module
6
7
  from db import get_session_title, parse_model
7
8
  from formatters import print_json, print_table_simple
8
9
  from i18n import _
9
- from utils import format_ts
10
+ from utils import build_help_epilog, format_ts
11
+
12
+ _LIST_EXAMPLES = [
13
+ ("", "help.list.e0"),
14
+ ("--limit 10", "help.list.e1"),
15
+ ("--sort cost", "help.list.e2"),
16
+ ("--project proj_xxx", "help.list.e3"),
17
+ ("--json", "help.list.e4"),
18
+ ]
10
19
 
11
20
 
12
21
  def register(subparsers) -> None:
13
- p = subparsers.add_parser("list", help=_("help.cmd.list"))
22
+ p = subparsers.add_parser(
23
+ "list",
24
+ help=_("help.cmd.list"),
25
+ formatter_class=argparse.RawDescriptionHelpFormatter,
26
+ epilog=build_help_epilog("list", _LIST_EXAMPLES),
27
+ )
14
28
  p.add_argument("--limit", type=int, default=25, help="Max results (default 25)")
15
29
  p.add_argument("--offset", type=int, default=0, help="Offset")
16
30
  p.add_argument("--project", type=str, help="Filter by project ID")
@@ -1,13 +1,24 @@
1
1
  """Команда projects: список проектов со статистикой."""
2
2
 
3
+ import argparse
3
4
  from typing import Literal
4
5
 
5
6
  from i18n import _
6
- from utils import format_cost, format_tokens, format_ts
7
+ from utils import build_help_epilog, format_cost, format_tokens, format_ts
8
+
9
+ _PROJECTS_EXAMPLES = [
10
+ ("", "help.projects.e0"),
11
+ ("--json", "help.projects.e1"),
12
+ ]
7
13
 
8
14
 
9
15
  def register(subparsers) -> None:
10
- p = subparsers.add_parser("projects", help=_("help.cmd.projects"))
16
+ p = subparsers.add_parser(
17
+ "projects",
18
+ help=_("help.cmd.projects"),
19
+ formatter_class=argparse.RawDescriptionHelpFormatter,
20
+ epilog=build_help_epilog("projects", _PROJECTS_EXAMPLES),
21
+ )
11
22
  p.add_argument("--json", action="store_true", help="JSON output")
12
23
 
13
24
 
@@ -1,15 +1,26 @@
1
1
  """Команда prune: массовая очистка старых сессий."""
2
2
 
3
- # from db import get_session_info, get_session_title, parse_model, \
4
- # get_message_count, get_part_count
3
+ import argparse
5
4
  from typing import Literal
6
5
 
7
6
  from i18n import _
8
- from utils import confirm, format_ts, parse_time_spec
7
+ from utils import build_help_epilog, confirm, format_ts, parse_time_spec
8
+
9
+ _PRUNE_EXAMPLES = [
10
+ ("--older-than 90d", "help.prune.e0"),
11
+ ("--keep-last 20", "help.prune.e1"),
12
+ ("--dry-run", "help.prune.e2"),
13
+ ("--force", "help.prune.e3"),
14
+ ]
9
15
 
10
16
 
11
17
  def register(subparsers) -> None:
12
- p = subparsers.add_parser("prune", help=_("help.cmd.prune"))
18
+ p = subparsers.add_parser(
19
+ "prune",
20
+ help=_("help.cmd.prune"),
21
+ formatter_class=argparse.RawDescriptionHelpFormatter,
22
+ epilog=build_help_epilog("prune", _PRUNE_EXAMPLES),
23
+ )
13
24
  p.add_argument("--older-than", type=str, help="Delete sessions older than (30d, 6m, 1y)")
14
25
  p.add_argument("--keep-last", type=int, help="Keep N most recent sessions")
15
26
  p.add_argument("--project", type=str, help="Limit to project")
@@ -1,14 +1,26 @@
1
1
  """Команда search: поиск по тексту сообщений и частей."""
2
2
 
3
+ import argparse
3
4
  import json
4
5
 
5
6
  from db import SessionError, resolve_session_id
6
7
  from i18n import _
7
- from utils import format_ts
8
+ from utils import build_help_epilog, format_ts
9
+
10
+ _SEARCH_EXAMPLES = [
11
+ ('"text"', "help.search.e0"),
12
+ ('"text" --session ses_xxx', "help.search.e1"),
13
+ ('"text" --json', "help.search.e2"),
14
+ ]
8
15
 
9
16
 
10
17
  def register(subparsers) -> None:
11
- p = subparsers.add_parser("search", help=_("help.cmd.search"))
18
+ p = subparsers.add_parser(
19
+ "search",
20
+ help=_("help.cmd.search"),
21
+ formatter_class=argparse.RawDescriptionHelpFormatter,
22
+ epilog=build_help_epilog("search", _SEARCH_EXAMPLES),
23
+ )
12
24
  p.add_argument("query", help="Search text")
13
25
  p.add_argument("--session", type=str, help="Limit to session")
14
26
  p.add_argument("--limit", type=int, default=30, help="Max results")
@@ -1,14 +1,25 @@
1
1
  """Команда stats: общая статистика по базе данных."""
2
2
 
3
+ import argparse
3
4
  from typing import Literal
4
5
 
5
6
  from db import parse_model
6
7
  from i18n import _
7
- from utils import format_cost, format_tokens, format_ts
8
+ from utils import build_help_epilog, format_cost, format_tokens, format_ts
9
+
10
+ _STATS_EXAMPLES = [
11
+ ("", "help.stats.e0"),
12
+ ("--json", "help.stats.e1"),
13
+ ]
8
14
 
9
15
 
10
16
  def register(subparsers) -> None:
11
- p = subparsers.add_parser("stats", help=_("help.cmd.stats"))
17
+ p = subparsers.add_parser(
18
+ "stats",
19
+ help=_("help.cmd.stats"),
20
+ formatter_class=argparse.RawDescriptionHelpFormatter,
21
+ epilog=build_help_epilog("stats", _STATS_EXAMPLES),
22
+ )
12
23
  p.add_argument("--json", action="store_true", help="JSON output")
13
24
 
14
25
 
@@ -1,12 +1,26 @@
1
1
  """Команда todos: просмотр задач (todo) из сессий."""
2
2
 
3
+ import argparse
4
+
3
5
  from db import SessionError, resolve_session_id
4
6
  from i18n import _
5
- from utils import format_ts
7
+ from utils import build_help_epilog, format_ts
8
+
9
+ _TODOS_EXAMPLES = [
10
+ ("", "help.todos.e0"),
11
+ ("<session_id>", "help.todos.e1"),
12
+ ("--status pending", "help.todos.e2"),
13
+ ("--json", "help.todos.e3"),
14
+ ]
6
15
 
7
16
 
8
17
  def register(subparsers) -> None:
9
- p = subparsers.add_parser("todos", help=_("help.cmd.todos"))
18
+ p = subparsers.add_parser(
19
+ "todos",
20
+ help=_("help.cmd.todos"),
21
+ formatter_class=argparse.RawDescriptionHelpFormatter,
22
+ epilog=build_help_epilog("todos", _TODOS_EXAMPLES),
23
+ )
10
24
  p.add_argument("session_id", nargs="?", help="Session ID")
11
25
  p.add_argument(
12
26
  "--status",
@@ -1,12 +1,25 @@
1
1
  """Команда tree: дерево ветвления сессий."""
2
2
 
3
+ import argparse
4
+
3
5
  from db import SessionError, get_session_title, resolve_session_id
4
6
  from i18n import _
5
- from utils import format_ts
7
+ from utils import build_help_epilog, format_ts
8
+
9
+ _TREE_EXAMPLES = [
10
+ ("", "help.tree.e0"),
11
+ ("<session_id>", "help.tree.e1"),
12
+ ("--depth 3", "help.tree.e2"),
13
+ ]
6
14
 
7
15
 
8
16
  def register(subparsers) -> None:
9
- p = subparsers.add_parser("tree", help=_("help.cmd.tree"))
17
+ p = subparsers.add_parser(
18
+ "tree",
19
+ help=_("help.cmd.tree"),
20
+ formatter_class=argparse.RawDescriptionHelpFormatter,
21
+ epilog=build_help_epilog("tree", _TREE_EXAMPLES),
22
+ )
10
23
  p.add_argument("session_id", nargs="?", help="Start from this session")
11
24
  p.add_argument("--project", type=str, help="Filter by project")
12
25
  p.add_argument("--depth", type=int, default=5, help="Max depth")
@@ -1,15 +1,26 @@
1
1
  """Команда vacuum: оптимизация базы данных."""
2
2
 
3
+ import argparse
3
4
  import os
4
5
  from typing import Literal
5
6
 
6
7
  from config import OPENCODE_DB
7
8
  from i18n import _
8
- from utils import confirm
9
+ from utils import build_help_epilog, confirm
10
+
11
+ _VACUUM_EXAMPLES = [
12
+ ("", "help.vacuum.e0"),
13
+ ("--force", "help.vacuum.e1"),
14
+ ]
9
15
 
10
16
 
11
17
  def register(subparsers) -> None:
12
- p = subparsers.add_parser("vacuum", help=_("help.cmd.vacuum"))
18
+ p = subparsers.add_parser(
19
+ "vacuum",
20
+ help=_("help.cmd.vacuum"),
21
+ formatter_class=argparse.RawDescriptionHelpFormatter,
22
+ epilog=build_help_epilog("vacuum", _VACUUM_EXAMPLES),
23
+ )
13
24
  p.add_argument("--force", "-f", action="store_true", help="Skip confirmation")
14
25
 
15
26
 
@@ -322,8 +322,8 @@ L: dict[str, dict[str, str]] = {
322
322
  "en": "╔══════════════════════════════════════════════════════════╗",
323
323
  },
324
324
  "help.header_title": {
325
- "ru": "║ opencode-db — справка ║",
326
- "en": "║ opencode-db — help ║",
325
+ "ru": "║ opencode-db — справка ║",
326
+ "en": "║ opencode-db — help ║",
327
327
  },
328
328
  "help.header_box_bottom": {
329
329
  "ru": "╚══════════════════════════════════════════════════════════╝",
@@ -355,6 +355,14 @@ L: dict[str, dict[str, str]] = {
355
355
  },
356
356
  "help.unknown": {"ru": "❌ Неизвестная команда: {cmd}", "en": "❌ Unknown command: {cmd}"},
357
357
  "help.available": {"ru": " Доступные: {cmds}", "en": " Available: {cmds}"},
358
+ "help.usage_header": {
359
+ "ru": "Примеры использования команды {cmd}:",
360
+ "en": "Usage examples for {cmd}:",
361
+ },
362
+ "help.flags_header": {
363
+ "ru": "Все доступные флаги для {cmd}:",
364
+ "en": "Available flags for {cmd}:",
365
+ },
358
366
  # ==================================================================
359
367
  # HELP — команды (краткие описания в справке)
360
368
  # ==================================================================
@@ -372,8 +380,12 @@ L: dict[str, dict[str, str]] = {
372
380
  "help.cmd.vacuum": {"ru": "Оптимизация БД", "en": "Database optimization"},
373
381
  "help.cmd.help": {"ru": "Подробная справка", "en": "Detailed help"},
374
382
  # ==================================================================
375
- # HELP — примеры
383
+ # HELP — примеры (epilog для argparse --help)
376
384
  # ==================================================================
385
+ "help.cmd.list.examples": {
386
+ "ru": "\nПримеры:\n opencode-db list # Сессии за последнее время\n opencode-db list --limit 10 # Показать 10 последних\n opencode-db list --sort cost # Сортировка по стоимости\n opencode-db list --project proj_xxx # Фильтр по проекту\n opencode-db list --json # Вывод в JSON\n",
387
+ "en": "\nExamples:\n opencode-db list # Recent sessions\n opencode-db list --limit 10 # Show last 10\n opencode-db list --sort cost # Sort by cost\n opencode-db list --project proj_xxx # Filter by project\n opencode-db list --json # JSON output\n",
388
+ },
377
389
  "help.list.e0": {"ru": "Сессии за последнее время", "en": "Recent sessions"},
378
390
  "help.list.e1": {"ru": "Показать 10 последних", "en": "Show last 10"},
379
391
  "help.list.e2": {"ru": "Сортировка по стоимости", "en": "Sort by cost"},
@@ -427,6 +439,14 @@ L: dict[str, dict[str, str]] = {
427
439
  "en": "VACUUM + REINDEX + ANALYZE with confirmation",
428
440
  },
429
441
  "help.vacuum.e1": {"ru": "Без подтверждения", "en": "Skip confirmation"},
442
+ "help.help.e0": {
443
+ "ru": "Общая справка по всем командам",
444
+ "en": "General help for all commands",
445
+ },
446
+ "help.help.e1": {
447
+ "ru": "Справка по конкретной команде",
448
+ "en": "Help for a specific command",
449
+ },
430
450
  # ==================================================================
431
451
  # MARKDOWN EXPORT (formatters.py, config.py)
432
452
  # ==================================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opencode-db
3
- Version: 0.5.0
3
+ Version: 0.5.1
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opencode-db"
7
- version = "0.5.0"
7
+ version = "0.5.1"
8
8
  description = "OpenCode database CLI manager — browse, export, analyze, clean up sessions"
9
9
  readme = "README_PYPI.md"
10
10
  requires-python = ">=3.12"
@@ -91,6 +91,27 @@ def confirm(prompt=None, default=False) -> bool:
91
91
  return False
92
92
 
93
93
 
94
+ def build_help_epilog(cmd_name: str, examples: list[tuple[str, str]]) -> str:
95
+ """Формирует epilog для argparse из списка примеров.
96
+
97
+ Args:
98
+ cmd_name: имя команды (для заголовка)
99
+ examples: список (флаги, ключ в i18n с описанием)
100
+
101
+ Returns:
102
+ str — готовый текст для epilog
103
+ """
104
+ header = _("help.usage_header", cmd=cmd_name)
105
+ lines = [f"\n{header}"]
106
+ for flags, desc_key in examples:
107
+ desc = _(desc_key)
108
+ if flags:
109
+ lines.append(f" opencode-db {cmd_name} {flags:33s} # {desc}")
110
+ else:
111
+ lines.append(f" opencode-db {cmd_name:36s} # {desc}")
112
+ return "\n".join(lines)
113
+
114
+
94
115
  def format_cost(cost_value) -> str:
95
116
  """Форматирует стоимость в долларах."""
96
117
  if cost_value is None:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes