Skip to content

Commit b86dd6f

Browse files
authored
feat: Fix bm CLI runtime defects and audit regressions (#596)
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent 8451f2b commit b86dd6f

22 files changed

Lines changed: 593 additions & 91 deletions

src/basic_memory/cli/commands/cloud/api_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ async def get_authenticated_headers(auth: CLIAuth | None = None) -> dict[str, st
5252
auth_obj = auth or CLIAuth(client_id=client_id, authkit_domain=domain)
5353
token = await auth_obj.get_valid_token()
5454
if not token:
55-
console.print("[red]Not authenticated. Please run 'basic-memory cloud login' first.[/red]")
55+
console.print("[red]Not authenticated. Please run 'bm cloud login' first.[/red]")
5656
raise typer.Exit(1)
5757

5858
return {"Authorization": f"Bearer {token}"}

src/basic_memory/cli/commands/cloud/core_commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def setup() -> None:
151151
"""Set up cloud sync by installing rclone and configuring credentials.
152152
153153
After setup, use project commands for syncing:
154-
bm project add <name> <path> --local-path ~/projects/<name>
154+
bm project add <name> --cloud --local-path ~/projects/<name>
155155
bm project bisync --name <name> --resync # First time
156156
bm project bisync --name <name> # Subsequent syncs
157157
"""
@@ -183,7 +183,7 @@ def setup() -> None:
183183
console.print("\n[bold green]Cloud setup completed successfully![/bold green]")
184184
console.print("\n[bold]Next steps:[/bold]")
185185
console.print("1. Add a project with local sync path:")
186-
console.print(" bm project add research --local-path ~/Documents/research")
186+
console.print(" bm project add research --cloud --local-path ~/Documents/research")
187187
console.print("\n Or configure sync for an existing project:")
188188
console.print(" bm project sync-setup research ~/Documents/research")
189189
console.print("\n2. Preview the initial sync (recommended):")

src/basic_memory/cli/commands/cloud/upload_command.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
sync_project,
1414
)
1515
from basic_memory.cli.commands.cloud.upload import upload_path
16+
from basic_memory.mcp.async_client import get_cloud_control_plane_client
1617

1718
console = Console()
1819

@@ -86,7 +87,7 @@ async def _upload():
8687
console.print(
8788
f"[red]Project '{project}' does not exist.[/red]\n"
8889
f"[yellow]Options:[/yellow]\n"
89-
f" 1. Create it first: bm project add {project}\n"
90+
f" 1. Create it first: bm project add {project} --cloud\n"
9091
f" 2. Use --create-project flag to create automatically"
9192
)
9293
raise typer.Exit(1)
@@ -100,7 +101,12 @@ async def _upload():
100101
console.print(f"[blue]Uploading {path} to project '{project}'...[/blue]")
101102

102103
success = await upload_path(
103-
path, project, verbose=verbose, use_gitignore=not no_gitignore, dry_run=dry_run
104+
path,
105+
project,
106+
verbose=verbose,
107+
use_gitignore=not no_gitignore,
108+
dry_run=dry_run,
109+
client_cm_factory=get_cloud_control_plane_client,
104110
)
105111
if not success:
106112
console.print("[red]Upload failed[/red]")

src/basic_memory/cli/commands/command_utils.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,19 @@ async def get_project_info(project: str):
9797
response = await call_get(client, f"/v2/projects/{project_item.external_id}/info")
9898
return ProjectInfoResponse.model_validate(response.json())
9999
except (ToolError, ValueError) as e:
100-
console.print(f"[red]Sync failed: {e}[/red]")
100+
error_text = str(e)
101+
if "internal proxy error" in error_text.lower() and "not found in configuration" in (
102+
error_text.lower()
103+
):
104+
console.print(
105+
"[red]Project info failed: cloud returned an internal configuration error for "
106+
"this project.[/red]"
107+
)
108+
console.print(
109+
"[yellow]This is a cloud backend issue for detailed info lookups. "
110+
"Use `bm project list --cloud` for project metadata until the service is updated."
111+
"[/yellow]"
112+
)
113+
else:
114+
console.print(f"[red]Project info failed: {e}[/red]")
101115
raise typer.Exit(1)

src/basic_memory/cli/commands/format.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,10 @@ def format(
183183
By default, formats all .md, .json, and .canvas files in the current project.
184184
185185
Examples:
186-
basic-memory format # Format all files in current project
187-
basic-memory format --project research # Format files in specific project
188-
basic-memory format notes/meeting.md # Format a specific file
189-
basic-memory format notes/ # Format all files in directory
186+
bm format # Format all files in current project
187+
bm format --project research # Format files in specific project
188+
bm format notes/meeting.md # Format a specific file
189+
bm format notes/ # Format all files in directory
190190
"""
191191
try:
192192
run_with_cleanup(run_format(path, project))

src/basic_memory/cli/commands/import_chatgpt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def import_chatgpt(
4444
2. Convert them to linear markdown conversations
4545
3. Save as clean, readable markdown files
4646
47-
After importing, run 'basic-memory sync' to index the new files.
47+
After importing, run 'bm reindex --search' to index the new files.
4848
"""
4949

5050
try:
@@ -81,7 +81,7 @@ def import_chatgpt(
8181
)
8282
)
8383

84-
console.print("\nRun 'basic-memory sync' to index the new files.")
84+
console.print("\nRun 'bm reindex --search' to index the new files.")
8585

8686
except Exception as e:
8787
logger.error("Import failed")

src/basic_memory/cli/commands/import_claude_conversations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def import_claude(
4444
2. Create markdown files for each conversation
4545
3. Format content in clean, readable markdown
4646
47-
After importing, run 'basic-memory sync' to index the new files.
47+
After importing, run 'bm reindex --search' to index the new files.
4848
"""
4949

5050
config = get_project_config()
@@ -84,7 +84,7 @@ def import_claude(
8484
)
8585
)
8686

87-
console.print("\nRun 'basic-memory sync' to index the new files.")
87+
console.print("\nRun 'bm reindex --search' to index the new files.")
8888

8989
except Exception as e:
9090
logger.error("Import failed")

src/basic_memory/cli/commands/import_claude_projects.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def import_projects(
4444
2. Store docs in a docs/ subdirectory
4545
3. Place prompt template in project root
4646
47-
After importing, run 'basic-memory sync' to index the new files.
47+
After importing, run 'bm reindex --search' to index the new files.
4848
"""
4949
config = get_project_config()
5050
try:
@@ -83,7 +83,7 @@ def import_projects(
8383
)
8484
)
8585

86-
console.print("\nRun 'basic-memory sync' to index the new files.")
86+
console.print("\nRun 'bm reindex --search' to index the new files.")
8787

8888
except Exception as e:
8989
logger.error("Import failed")

src/basic_memory/cli/commands/mcp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def mcp(
3636
This command starts an MCP server using one of three transport options:
3737
3838
- stdio: Standard I/O (good for local usage)
39-
- streamable-http: Recommended for web deployments (default)
39+
- streamable-http: Recommended for web deployments
4040
- sse: Server-Sent Events (for compatibility with existing clients)
4141
4242
Initialization, file sync, and cleanup are handled by the MCP server's lifespan.

src/basic_memory/cli/commands/project.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,8 @@ def display_project_info(
11491149
)
11501150
console.print(f"\nTimestamp: [cyan]{current_time.strftime('%Y-%m-%d %H:%M:%S')}[/cyan]")
11511151

1152+
except typer.Exit:
1153+
raise
11521154
except Exception as e: # pragma: no cover
11531155
typer.echo(f"Error getting project info: {e}", err=True)
11541156
raise typer.Exit(1)

0 commit comments

Comments
 (0)