basic-memory 0.10.0__py3-none-any.whl → 0.11.0__py3-none-any.whl

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.

Potentially problematic release.


This version of basic-memory might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
5
5
  Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
6
6
  Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
@@ -37,6 +37,8 @@ Description-Content-Type: text/markdown
37
37
  [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
38
38
  [![Tests](https://github.com/basicmachines-co/basic-memory/workflows/Tests/badge.svg)](https://github.com/basicmachines-co/basic-memory/actions)
39
39
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
40
+ ![](https://badge.mcpx.dev?type=server 'MCP Server')
41
+ ![](https://badge.mcpx.dev?type=dev 'MCP Dev')
40
42
  [![smithery badge](https://smithery.ai/badge/@basicmachines-co/basic-memory)](https://smithery.ai/server/@basicmachines-co/basic-memory)
41
43
 
42
44
  # Basic Memory
@@ -317,7 +319,8 @@ for OS X):
317
319
  }
318
320
  ```
319
321
 
320
- If you want to use a specific project (see [Multiple Projects](#multiple-projects) below), update your Claude Desktop
322
+ If you want to use a specific project (see [Multiple Projects](docs/User%20Guide.md#multiple-projects)), update your
323
+ Claude Desktop
321
324
  config:
322
325
 
323
326
  ```json
@@ -352,7 +355,7 @@ basic-memory sync --watch
352
355
  write_note(title, content, folder, tags) - Create or update notes
353
356
  read_note(identifier, page, page_size) - Read notes by title or permalink
354
357
  build_context(url, depth, timeframe) - Navigate knowledge graph via memory:// URLs
355
- search(query, page, page_size) - Search across your knowledge base
358
+ search_notes(query, page, page_size) - Search across your knowledge base
356
359
  recent_activity(type, depth, timeframe) - Find recently updated information
357
360
  canvas(nodes, edges, title, folder) - Generate knowledge visualizations
358
361
  ```
@@ -383,4 +386,14 @@ AGPL-3.0
383
386
  Contributions are welcome. See the [Contributing](CONTRIBUTING.md) guide for info about setting up the project locally
384
387
  and submitting PRs.
385
388
 
386
- Built with ♥️ by Basic Machines
389
+ ## Star History
390
+
391
+ <a href="https://www.star-history.com/#basicmachines-co/basic-memory&Date">
392
+ <picture>
393
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=basicmachines-co/basic-memory&type=Date&theme=dark" />
394
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=basicmachines-co/basic-memory&type=Date" />
395
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=basicmachines-co/basic-memory&type=Date" />
396
+ </picture>
397
+ </a>
398
+
399
+ Built with ♥️ by Basic Machines
@@ -1,9 +1,9 @@
1
- basic_memory/__init__.py,sha256=YT8crmOfNy-XKuzs53zmYlk7WGRbsDxeU_X1c_UEqAE,123
2
- basic_memory/config.py,sha256=PHUrzwjJSHab691mzShz5uZ-uuJyXcznnXA8kjD-wJU,7659
1
+ basic_memory/__init__.py,sha256=06l2-O3MzDid6DzYEdAOjAn3OLuVGdUYBo17g6ZALWQ,123
2
+ basic_memory/config.py,sha256=3lwRFYA1e2dk5JIRNvnuVVIAGT3UXI4FUjN-CEHpJy8,8432
3
3
  basic_memory/db.py,sha256=UDWBr52u7oBT4aXputhAG_Prmsv5og00sYVzPmaylhk,6026
4
4
  basic_memory/deps.py,sha256=yI6RL_5-8LXw7ywSJ_84BXAczDtv2h9GFLw-E9XDJFg,5770
5
5
  basic_memory/file_utils.py,sha256=csvij8o_j14A-rr8NTDeH6pUaI4DdBqNAWJIVc5r4A0,6658
6
- basic_memory/utils.py,sha256=EPumxT4HkprZG9BzWZnym3teOjn24Vm3lgncQADN5ew,3764
6
+ basic_memory/utils.py,sha256=0EfSx_PiTtFkWIDN2wic9nTPIH35B4fddT-GWi8aVsk,4553
7
7
  basic_memory/alembic/alembic.ini,sha256=IEZsnF8CbbZnkwBr67LzKKNobHuzTaQNUvM8Psop5xc,3733
8
8
  basic_memory/alembic/env.py,sha256=GyQpEpQu84flqAdelxR0-H9nbkHrVoCboYGfmltBDoA,2737
9
9
  basic_memory/alembic/migrations.py,sha256=lriHPXDdBLSNXEW3QTpU0SJKuVd1V-8NrVkpN3qfsUQ,718
@@ -23,45 +23,45 @@ basic_memory/api/routers/search_router.py,sha256=R_a5OF5_8rCjmoOMhmw3M4VLCy6I1KL
23
23
  basic_memory/cli/__init__.py,sha256=arcKLAWRDhPD7x5t80MlviZeYzwHZ0GZigyy3NKVoGk,33
24
24
  basic_memory/cli/app.py,sha256=J4mkWnxbevOYmJwwRMx344olGOxoXq0o4RNG6DMQLKE,1804
25
25
  basic_memory/cli/main.py,sha256=9uwxOUc4mDeTeZCEWyJh7X5PzPXG1fva2veV2OPbFtg,1442
26
- basic_memory/cli/commands/__init__.py,sha256=aBihwtUFs0MpsxCed74A5fYoxFmJA4NOVXPRrVY4lnw,427
27
- basic_memory/cli/commands/db.py,sha256=UL3JXGJrLzKZ-uRwgk6p0kbRznBy5x7keirvweVGNvY,754
26
+ basic_memory/cli/commands/__init__.py,sha256=3oojcC-Y-4RPqff9vtwWziT_T4uvBVicL0pSHNilVkU,393
27
+ basic_memory/cli/commands/db.py,sha256=-jgVH2fs_s1vvBNJx_FWspQVHv0F6Qd7V5ZPxtYn_jQ,1125
28
28
  basic_memory/cli/commands/import_chatgpt.py,sha256=M4_oUN9o_BaW5jpKQu2pTEybivB5ccVolhdZzmhLOsI,8162
29
29
  basic_memory/cli/commands/import_claude_conversations.py,sha256=D_4-0xFKkZka7xFvvW8OkgjLv3TFqsC_VuB2Z-Y3avU,6827
30
30
  basic_memory/cli/commands/import_claude_projects.py,sha256=KzUuf3wrlvJlqTWCzoLRrNxD3OYNteRXaTFj5IB1FA8,6649
31
31
  basic_memory/cli/commands/import_memory_json.py,sha256=zqpU4eCzQXx04aRsigddJAyhvklmTgSAzeRTuEdNw0c,5194
32
32
  basic_memory/cli/commands/mcp.py,sha256=ue_zDA8w0zZZToHLvu56s8hWkalgZsC64CfTyXX6z2I,715
33
- basic_memory/cli/commands/project.py,sha256=vEPv34Grn8DGwP8Ig9xcFWeVW0cro_Qyfq2TU22pcQQ,4103
34
- basic_memory/cli/commands/project_info.py,sha256=2XFe0eONsJ-FOmiOO6faYAS9AgX7Dmj4HNeTTrUr0ZE,7099
33
+ basic_memory/cli/commands/project.py,sha256=BSjdz07xDM3R4CUXggv1qhrWLJsEgvGFir6aOUzdr2Q,11330
35
34
  basic_memory/cli/commands/status.py,sha256=nbs3myxaNtehEEJ4BBngPuKs-vqZTHNCCb0bTgDsE-s,5277
36
35
  basic_memory/cli/commands/sync.py,sha256=JxGJA6b7Qksz0ZKonHfB3s--7qzY7eWeLogPX8tR1pY,8351
37
- basic_memory/cli/commands/tool.py,sha256=DjoB4slhmzfCjIgom1-xBP6sRl_gy7PrhGtQk3rNAqM,8855
36
+ basic_memory/cli/commands/tool.py,sha256=0YFWEmaKZ--1SsNjs_Q3hBsg94CMiyqVc3S8gUmxJNo,9101
38
37
  basic_memory/markdown/__init__.py,sha256=DdzioCWtDnKaq05BHYLgL_78FawEHLpLXnp-kPSVfIc,501
39
- basic_memory/markdown/entity_parser.py,sha256=LnjG_wg38LVN8JndsZJV2UVGPIaoIV5sGs94iQ9PL6k,3781
38
+ basic_memory/markdown/entity_parser.py,sha256=Pc6hTm9TB5SRW_ghf7WD-UMjEgOPyc8j8tgCtxEWfLQ,3893
40
39
  basic_memory/markdown/markdown_processor.py,sha256=S5ny69zu2dlqO7tWJoLrpLSzg8emQIDq7Du7olpJUsk,4968
41
40
  basic_memory/markdown/plugins.py,sha256=gtIzKRjoZsyvBqLpVNnrmzl_cbTZ5ZGn8kcuXxQjRko,6639
42
- basic_memory/markdown/schemas.py,sha256=mzVEDUhH98kwETMknjkKw5H697vg_zUapsJkJVi17ho,1894
41
+ basic_memory/markdown/schemas.py,sha256=eyxYCr1hVyWmImcle0asE5It_DD6ARkqaBZYu1KK5n4,1896
43
42
  basic_memory/markdown/utils.py,sha256=zlHlUtrnXaUCnsaPNJzR0wlhg2kB1YbXx0DMvs-snJM,2973
44
43
  basic_memory/mcp/__init__.py,sha256=dsDOhKqjYeIbCULbHIxfcItTbqudEuEg1Np86eq0GEQ,35
45
44
  basic_memory/mcp/async_client.py,sha256=Eo345wANiBRSM4u3j_Vd6Ax4YtMg7qbWd9PIoFfj61I,236
46
45
  basic_memory/mcp/main.py,sha256=0kbcyf1PxRC1bLnHv2zzParfJ6cOq7Am9ScF9UoI50U,703
47
46
  basic_memory/mcp/server.py,sha256=VGv0uWma6JGkT6Y_GESYGhGMYfPavkhEKlCNza8bvtY,287
48
47
  basic_memory/mcp/prompts/__init__.py,sha256=-Bl9Dgj2TD9PULjzggPqXuvPEjWCRy7S9Yg03h2-U7A,615
49
- basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=rfp3xPmTsbSMlv_NI91BwGhYXtkn6T9ISvtEWru5kM8,855
50
- basic_memory/mcp/prompts/continue_conversation.py,sha256=zb_3cOaO7NMFuStBkJDlMstQZqz1RCOYl6txwaHYM_Q,4424
48
+ basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=8TI5xObiRVcwv6w9by1xQHlX0whvyE7-LGsiqDMRTFg,821
49
+ basic_memory/mcp/prompts/continue_conversation.py,sha256=0AN44p8eF9l3VbtFX8RToSuHwnGYAkKYTZCgWpbbHX0,4442
51
50
  basic_memory/mcp/prompts/recent_activity.py,sha256=7607MWiGJWY0vPurhVII17LxLZlXY_zmH3xH9LfT6SY,2793
52
- basic_memory/mcp/prompts/search.py,sha256=nCz5wPxTszJLNQJ1CE7CIhnamy08EpGLQjoBMlXRRNc,6283
51
+ basic_memory/mcp/prompts/search.py,sha256=wokpuP4uN-N2YVN3VTyIjBG8Uu_HkjYSaln7i4dvfDw,6307
53
52
  basic_memory/mcp/prompts/utils.py,sha256=u_bG8DMtMMERvGPJfA3gbl5VAs0xmkuK8ZJBkY8xyV8,5371
54
- basic_memory/mcp/tools/__init__.py,sha256=mp8BiY-2YY5zzGBAIbf9hMCQM6uhDtst3eq1ApR2p2s,870
53
+ basic_memory/mcp/resources/ai_assistant_guide.md,sha256=qnYWDkYlb-JmKuOoZ5llmRas_t4dWDXB_i8LE277Lgs,14777
54
+ basic_memory/mcp/tools/__init__.py,sha256=prvB6M150ba8WT-v-tmo4Yfu4JG-0yCi6nfK4SsL7XI,882
55
55
  basic_memory/mcp/tools/build_context.py,sha256=8xYRPpeYCEU8F9Dv_ctvbunZ8ciKwmFu9i8Pdv5vYfI,2891
56
56
  basic_memory/mcp/tools/canvas.py,sha256=fHC90eshnSSmROTBV-tBB-FSuXSpYVj_BcDrc96pWi0,2993
57
57
  basic_memory/mcp/tools/delete_note.py,sha256=mnrgOv-D7f6nsgZIAK0Wvyn0dbkwCg8adW_xJd7jwc0,829
58
58
  basic_memory/mcp/tools/project_info.py,sha256=pyoHpOMhjMIvZFku2iEIpXc2XDtbnNeb-OMrJlYR9LU,1710
59
59
  basic_memory/mcp/tools/read_content.py,sha256=PKnvLzNmHfzoIxRKXNaYW5P5q0d1azVwG9juPXPYeQo,8148
60
- basic_memory/mcp/tools/read_note.py,sha256=pM6FUxMdDxxCNxhnDrkrVqIJouIRPbUqSHsL3BVgiy8,6469
60
+ basic_memory/mcp/tools/read_note.py,sha256=1i1iaCBpGEhkHwOCn83zkil72tdKSCN_Ndt_HVcnTAw,6487
61
61
  basic_memory/mcp/tools/recent_activity.py,sha256=S0LgIk9RaeYzIsi2FIHs0KK7R1K-LJy3QaSokGlY9ew,3501
62
- basic_memory/mcp/tools/search.py,sha256=0PcLCpXe73X72jSudVLVMO8TQwEjnB6F1V9jCtjf2ZE,2999
62
+ basic_memory/mcp/tools/search.py,sha256=96mc8KTo23Olz918S9C2u4UOWD5QAo-koGfuWBqDVjQ,3032
63
63
  basic_memory/mcp/tools/utils.py,sha256=tOWklfSlDcoAJCRBmxkCVwkTY_TDBa5vOGxzU8J5eiQ,13636
64
- basic_memory/mcp/tools/write_note.py,sha256=CdUdFitmuDQl8z36IqrbSB0hSEdw20k_ZIXnpV_KDSc,4374
64
+ basic_memory/mcp/tools/write_note.py,sha256=Z2z92pHb74-uLzahY2Cz5Kj8kGikS4VSWPZ1I1rGy1U,4942
65
65
  basic_memory/models/__init__.py,sha256=Bf0xXV_ryndogvZDiVM_Wb6iV2fHUxYNGMZNWNcZi0s,307
66
66
  basic_memory/models/base.py,sha256=4hAXJ8CE1RnjKhb23lPd-QM7G_FXIdTowMJ9bRixspU,225
67
67
  basic_memory/models/knowledge.py,sha256=lbKd8VOOVPqXtIhNMY30bIokoQutFjLpHwLD5At90MY,6644
@@ -83,7 +83,7 @@ basic_memory/schemas/response.py,sha256=lVYR31DTtSeFRddGWX_wQWnQgyiwX0LEpNJ4f4lK
83
83
  basic_memory/schemas/search.py,sha256=mfPHo8lzZ8BMLzmID-0g_0pWHhBIBNIvy4c8KYHFuvQ,3655
84
84
  basic_memory/services/__init__.py,sha256=oop6SKmzV4_NAYt9otGnupLGVCCKIVgxEcdRQWwh25I,197
85
85
  basic_memory/services/context_service.py,sha256=fhJNHQoTEeIC9ZmZ49CXcNF2aVBghVnmo6LtdSDcAas,9708
86
- basic_memory/services/entity_service.py,sha256=p4yP-VngdtfCqbvygQ968tGQVOJ1nFzN3XRyXenEcRM,12432
86
+ basic_memory/services/entity_service.py,sha256=MlJLpZbr67KpSEZXi1yBJSkA_a7_9Ysa-aZnyEi6b7I,12896
87
87
  basic_memory/services/exceptions.py,sha256=VGlCLd4UD2w5NWKqC7QpG4jOM_hA7jKRRM-MqvEVMNk,288
88
88
  basic_memory/services/file_service.py,sha256=7uLVkcFMFj20srdch8c6u9T6nO5X4wHgcXdL81pGV88,9935
89
89
  basic_memory/services/link_resolver.py,sha256=yWqqKqJtGU_93xy25y6Us4xRTNijrBLz76Nvm_zFEOI,3326
@@ -91,9 +91,9 @@ basic_memory/services/search_service.py,sha256=t3d5jhABs5bXwtOu7_AvRCpVd8RRd2j6G
91
91
  basic_memory/services/service.py,sha256=V-d_8gOV07zGIQDpL-Ksqs3ZN9l3qf3HZOK1f_YNTag,336
92
92
  basic_memory/sync/__init__.py,sha256=CVHguYH457h2u2xoM8KvOilJC71XJlZ-qUh8lHcjYj4,156
93
93
  basic_memory/sync/sync_service.py,sha256=YirSOgk0PyqPJoHXVUzAxhNKdd2pebP8sFeXeAYmGjM,21957
94
- basic_memory/sync/watch_service.py,sha256=ZcpMfbNpMsKVjKJQ8BaF3CXKpTycOF9HddTsRlefVEQ,13467
95
- basic_memory-0.10.0.dist-info/METADATA,sha256=g4VfqLtcp4NiydgNNfZYwQyJ4kL96jWv8_0GfHbjmEs,12850
96
- basic_memory-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
97
- basic_memory-0.10.0.dist-info/entry_points.txt,sha256=IDQa_VmVTzmvMrpnjhEfM0S3F--XsVGEj3MpdJfuo-Q,59
98
- basic_memory-0.10.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
99
- basic_memory-0.10.0.dist-info/RECORD,,
94
+ basic_memory/sync/watch_service.py,sha256=IliisNN8HMKLnBaF95wGHpA5WqRWujprWJVxOnAQ2yc,13468
95
+ basic_memory-0.11.0.dist-info/METADATA,sha256=G3NFwoGFvifzfrnPYnBemgmGYmz7jUF8qlaN3LpFe_8,13504
96
+ basic_memory-0.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
97
+ basic_memory-0.11.0.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
98
+ basic_memory-0.11.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
99
+ basic_memory-0.11.0.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  basic-memory = basic_memory.cli.main:app
3
+ bm = basic_memory.cli.main:app
@@ -1,167 +0,0 @@
1
- """CLI command for project info status."""
2
-
3
- import asyncio
4
- import json
5
- from datetime import datetime
6
-
7
- import typer
8
- from rich.console import Console
9
- from rich.table import Table
10
- from rich.panel import Panel
11
- from rich.tree import Tree
12
-
13
- from basic_memory.cli.app import app
14
- from basic_memory.mcp.tools.project_info import project_info
15
-
16
-
17
- info_app = typer.Typer()
18
- app.add_typer(info_app, name="info", help="Get information about your Basic Memory project")
19
-
20
-
21
- @info_app.command("stats")
22
- def display_project_info(
23
- json_output: bool = typer.Option(False, "--json", help="Output in JSON format"),
24
- ):
25
- """Display detailed information and statistics about the current project."""
26
- try:
27
- # Get project info
28
- info = asyncio.run(project_info())
29
-
30
- if json_output:
31
- # Convert to JSON and print
32
- print(json.dumps(info.model_dump(), indent=2, default=str))
33
- else:
34
- # Create rich display
35
- console = Console()
36
-
37
- # Project configuration section
38
- console.print(
39
- Panel(
40
- f"[bold]Project:[/bold] {info.project_name}\n"
41
- f"[bold]Path:[/bold] {info.project_path}\n"
42
- f"[bold]Default Project:[/bold] {info.default_project}\n",
43
- title="📊 Basic Memory Project Info",
44
- expand=False,
45
- )
46
- )
47
-
48
- # Statistics section
49
- stats_table = Table(title="📈 Statistics")
50
- stats_table.add_column("Metric", style="cyan")
51
- stats_table.add_column("Count", style="green")
52
-
53
- stats_table.add_row("Entities", str(info.statistics.total_entities))
54
- stats_table.add_row("Observations", str(info.statistics.total_observations))
55
- stats_table.add_row("Relations", str(info.statistics.total_relations))
56
- stats_table.add_row(
57
- "Unresolved Relations", str(info.statistics.total_unresolved_relations)
58
- )
59
- stats_table.add_row("Isolated Entities", str(info.statistics.isolated_entities))
60
-
61
- console.print(stats_table)
62
-
63
- # Entity types
64
- if info.statistics.entity_types:
65
- entity_types_table = Table(title="📑 Entity Types")
66
- entity_types_table.add_column("Type", style="blue")
67
- entity_types_table.add_column("Count", style="green")
68
-
69
- for entity_type, count in info.statistics.entity_types.items():
70
- entity_types_table.add_row(entity_type, str(count))
71
-
72
- console.print(entity_types_table)
73
-
74
- # Most connected entities
75
- if info.statistics.most_connected_entities:
76
- connected_table = Table(title="🔗 Most Connected Entities")
77
- connected_table.add_column("Title", style="blue")
78
- connected_table.add_column("Permalink", style="cyan")
79
- connected_table.add_column("Relations", style="green")
80
-
81
- for entity in info.statistics.most_connected_entities:
82
- connected_table.add_row(
83
- entity["title"], entity["permalink"], str(entity["relation_count"])
84
- )
85
-
86
- console.print(connected_table)
87
-
88
- # Recent activity
89
- if info.activity.recently_updated:
90
- recent_table = Table(title="🕒 Recent Activity")
91
- recent_table.add_column("Title", style="blue")
92
- recent_table.add_column("Type", style="cyan")
93
- recent_table.add_column("Last Updated", style="green")
94
-
95
- for entity in info.activity.recently_updated[:5]: # Show top 5
96
- updated_at = (
97
- datetime.fromisoformat(entity["updated_at"])
98
- if isinstance(entity["updated_at"], str)
99
- else entity["updated_at"]
100
- )
101
- recent_table.add_row(
102
- entity["title"],
103
- entity["entity_type"],
104
- updated_at.strftime("%Y-%m-%d %H:%M"),
105
- )
106
-
107
- console.print(recent_table)
108
-
109
- # System status
110
- system_tree = Tree("🖥️ System Status")
111
- system_tree.add(f"Basic Memory version: [bold green]{info.system.version}[/bold green]")
112
- system_tree.add(
113
- f"Database: [cyan]{info.system.database_path}[/cyan] ([green]{info.system.database_size}[/green])"
114
- )
115
-
116
- # Watch status
117
- if info.system.watch_status: # pragma: no cover
118
- watch_branch = system_tree.add("Watch Service")
119
- running = info.system.watch_status.get("running", False)
120
- status_color = "green" if running else "red"
121
- watch_branch.add(
122
- f"Status: [bold {status_color}]{'Running' if running else 'Stopped'}[/bold {status_color}]"
123
- )
124
-
125
- if running:
126
- start_time = (
127
- datetime.fromisoformat(info.system.watch_status.get("start_time", ""))
128
- if isinstance(info.system.watch_status.get("start_time"), str)
129
- else info.system.watch_status.get("start_time")
130
- )
131
- watch_branch.add(
132
- f"Running since: [cyan]{start_time.strftime('%Y-%m-%d %H:%M')}[/cyan]"
133
- )
134
- watch_branch.add(
135
- f"Files synced: [green]{info.system.watch_status.get('synced_files', 0)}[/green]"
136
- )
137
- watch_branch.add(
138
- f"Errors: [{'red' if info.system.watch_status.get('error_count', 0) > 0 else 'green'}]{info.system.watch_status.get('error_count', 0)}[/{'red' if info.system.watch_status.get('error_count', 0) > 0 else 'green'}]"
139
- )
140
- else:
141
- system_tree.add("[yellow]Watch service not running[/yellow]")
142
-
143
- console.print(system_tree)
144
-
145
- # Available projects
146
- projects_table = Table(title="📁 Available Projects")
147
- projects_table.add_column("Name", style="blue")
148
- projects_table.add_column("Path", style="cyan")
149
- projects_table.add_column("Default", style="green")
150
-
151
- for name, path in info.available_projects.items():
152
- is_default = name == info.default_project
153
- projects_table.add_row(name, path, "✓" if is_default else "")
154
-
155
- console.print(projects_table)
156
-
157
- # Timestamp
158
- current_time = (
159
- datetime.fromisoformat(str(info.system.timestamp))
160
- if isinstance(info.system.timestamp, str)
161
- else info.system.timestamp
162
- )
163
- console.print(f"\nTimestamp: [cyan]{current_time.strftime('%Y-%m-%d %H:%M:%S')}[/cyan]")
164
-
165
- except Exception as e: # pragma: no cover
166
- typer.echo(f"Error getting project info: {e}", err=True)
167
- raise typer.Exit(1)