Coverage for /home/runner/work/bijux-cli/bijux-cli/src/bijux_cli/commands/memory/delete.py: 100%
26 statements
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-19 23:36 +0000
« prev ^ index » next coverage.py v7.10.4, created at 2025-08-19 23:36 +0000
1# SPDX-License-Identifier: MIT
2# Copyright © 2025 Bijan Mousavi
4"""Implements the `memory delete` subcommand for the Bijux CLI.
6This module contains the logic for removing a specific key and its associated
7value from the transient, in-memory data store. It provides a structured,
8machine-readable confirmation of the deletion.
10Output Contract:
11 * Success: `{"status": "deleted", "key": str}`
12 * Verbose: Adds `{"python": str, "platform": str}` to the payload.
13 * Error: `{"error": str, "code": int}`
15Exit Codes:
16 * `0`: Success.
17 * `1`: The key was not found, or another unexpected error occurred.
18 * `2`: The provided key was invalid.
19"""
21from __future__ import annotations
23from collections.abc import Mapping
24import platform
26import typer
28from bijux_cli.commands.memory.utils import resolve_memory_service
29from bijux_cli.commands.utilities import (
30 ascii_safe,
31 emit_error_and_exit,
32 new_run_command,
33 validate_common_flags,
34)
35from bijux_cli.core.constants import (
36 HELP_DEBUG,
37 HELP_FORMAT,
38 HELP_NO_PRETTY,
39 HELP_QUIET,
40 HELP_VERBOSE,
41)
44def _build_payload(include_runtime: bool, key: str) -> Mapping[str, object]:
45 """Builds the payload for a memory key deletion response.
47 Args:
48 include_runtime (bool): If True, includes Python and platform info.
49 key (str): The memory key that was deleted.
51 Returns:
52 Mapping[str, object]: A dictionary containing the status, the key that
53 was deleted, and optional runtime metadata.
54 """
55 payload: dict[str, object] = {"status": "deleted", "key": key}
56 if include_runtime:
57 payload["python"] = ascii_safe(platform.python_version(), "python_version")
58 payload["platform"] = ascii_safe(platform.platform(), "platform")
59 return payload
62def delete_memory(
63 key: str = typer.Argument(..., help="Key to delete"),
64 quiet: bool = typer.Option(False, "-q", "--quiet", help=HELP_QUIET),
65 verbose: bool = typer.Option(False, "-v", "--verbose", help=HELP_VERBOSE),
66 fmt: str = typer.Option("json", "-f", "--format", help=HELP_FORMAT),
67 pretty: bool = typer.Option(True, "--pretty/--no-pretty", help=HELP_NO_PRETTY),
68 debug: bool = typer.Option(False, "-d", "--debug", help=HELP_DEBUG),
69) -> None:
70 """Deletes a key from the transient in-memory store.
72 This command validates the key's format and then removes the corresponding
73 key-value pair from the memory service.
75 Args:
76 key (str): The memory key to remove. Must be between 1 and 4096
77 printable, non-whitespace characters.
78 quiet (bool): If True, suppresses all output except for errors.
79 verbose (bool): If True, includes Python/platform details in the output.
80 fmt (str): The output format, "json" or "yaml".
81 pretty (bool): If True, pretty-prints the output.
82 debug (bool): If True, enables debug diagnostics.
84 Returns:
85 None:
87 Raises:
88 SystemExit: Always exits with a contract-compliant status code and
89 payload, indicating success or detailing an error.
90 """
91 command = "memory delete"
93 fmt_lower = validate_common_flags(fmt, command, quiet)
95 if not (
96 1 <= len(key) <= 4096 and all(c.isprintable() and not c.isspace() for c in key)
97 ):
98 emit_error_and_exit(
99 "Invalid key: must be 1-4096 printable non-space characters",
100 code=2,
101 failure="invalid_key",
102 command=command,
103 fmt=fmt_lower,
104 quiet=quiet,
105 include_runtime=verbose,
106 debug=debug,
107 )
109 memory_svc = resolve_memory_service(command, fmt_lower, quiet, verbose, debug)
111 try:
112 memory_svc.delete(key)
113 except KeyError:
114 emit_error_and_exit(
115 f"Key not found: {key}",
116 code=1,
117 failure="not_found",
118 command=command,
119 fmt=fmt_lower,
120 quiet=quiet,
121 include_runtime=verbose,
122 debug=debug,
123 )
124 except Exception as exc:
125 emit_error_and_exit(
126 f"Failed to delete memory key: {exc}",
127 code=1,
128 failure="delete_failed",
129 command=command,
130 fmt=fmt_lower,
131 quiet=quiet,
132 include_runtime=verbose,
133 debug=debug,
134 )
136 new_run_command(
137 command_name=command,
138 payload_builder=lambda include: _build_payload(include, key),
139 quiet=quiet,
140 verbose=verbose,
141 fmt=fmt_lower,
142 pretty=pretty,
143 debug=debug,
144 )