Coverage for / home / runner / work / bijux-cli / bijux-cli / src / bijux_cli / cli / commands / memory / set.py: 100%
30 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-26 17:59 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-26 17:59 +0000
1# SPDX-License-Identifier: Apache-2.0
2# Copyright © 2025 Bijan Mousavi
4"""Implements the `memory set` subcommand for the Bijux CLI.
6This module contains the logic for storing a key-value pair in a transient,
7in-memory data store. The data persists only for the lifetime of the
8application's parent process. A structured confirmation is emitted upon success.
10Output Contract:
11 * Success: `{"status": "updated", "key": str, "value": str}`
12 * Error: `{"error": str, "code": int}`
14Exit Codes:
15 * `0`: Success.
16 * `1`: An unexpected error occurred (e.g., service unavailable, set failed).
17 * `2`: The provided key was invalid.
18"""
20from __future__ import annotations
22import platform
24import typer
26from bijux_cli.cli.commands.memory.resolve import resolve_memory_service
27from bijux_cli.cli.core.command import (
28 ascii_safe,
29 new_run_command,
30 raise_exit_intent,
31 validate_common_flags,
32)
33from bijux_cli.cli.core.constants import (
34 OPT_FORMAT,
35 OPT_LOG_LEVEL,
36 OPT_PRETTY,
37 OPT_QUIET,
38)
39from bijux_cli.cli.core.help_text import (
40 HELP_FORMAT,
41 HELP_LOG_LEVEL,
42 HELP_NO_PRETTY,
43 HELP_QUIET,
44)
45from bijux_cli.core.enums import ErrorType
46from bijux_cli.core.precedence import current_execution_policy
49def _build_payload(include_runtime: bool, key: str, value: str) -> dict[str, object]:
50 """Constructs the payload confirming a key-value pair was set.
52 Args:
53 include_runtime (bool): If True, includes Python and platform info.
54 key (str): The key that was updated.
55 value (str): The new value assigned to the key.
57 Returns:
58 Mapping[str, object]: A dictionary containing the status, key, value,
59 and optional runtime metadata.
60 """
61 payload: dict[str, object] = {"status": "updated", "key": key, "value": value}
62 if include_runtime:
63 return {
64 "status": payload["status"],
65 "key": key,
66 "value": value,
67 "python": ascii_safe(platform.python_version(), "python_version"),
68 "platform": ascii_safe(platform.platform(), "platform"),
69 }
70 return payload
73def set_memory(
74 key: str = typer.Argument(..., help="Key to set"),
75 value: str = typer.Argument(..., help="Value to set"),
76 quiet: bool = typer.Option(False, *OPT_QUIET, help=HELP_QUIET),
77 fmt: str = typer.Option("json", *OPT_FORMAT, help=HELP_FORMAT),
78 pretty: bool = typer.Option(True, OPT_PRETTY, help=HELP_NO_PRETTY),
79 log_level: str = typer.Option("info", *OPT_LOG_LEVEL, help=HELP_LOG_LEVEL),
80) -> None:
81 """Sets a key-value pair in the transient in-memory store.
83 This command validates the key's format and then stores the key-value
84 pair using the memory service.
86 Args:
87 key (str): The memory key to set. Must be between 1 and 4096 printable,
88 non-whitespace characters.
89 value (str): The value to associate with the key.
90 quiet (bool): If True, suppresses all output except for errors.
91 fmt (str): The output format, "json" or "yaml".
92 pretty (bool): If True, pretty-prints the output. log_level (str): Logging level for diagnostics.
94 Returns:
95 None:
97 Raises:
98 SystemExit: Always exits with a contract-compliant status code and
99 payload, indicating success or detailing an error.
100 """
101 command = "memory set"
102 policy = current_execution_policy()
103 quiet = policy.quiet
104 include_runtime = policy.include_runtime
105 pretty = policy.pretty
106 log_level_value = policy.log_level
107 fmt_lower = validate_common_flags(
108 fmt,
109 command,
110 quiet,
111 include_runtime=include_runtime,
112 log_level=log_level_value,
113 )
115 if not (
116 1 <= len(key) <= 4096 and all(c.isprintable() and not c.isspace() for c in key)
117 ):
118 raise_exit_intent(
119 "Invalid key: must be 1-4096 printable non-space characters",
120 code=2,
121 failure="invalid_key",
122 error_type=ErrorType.USER_INPUT,
123 command=command,
124 fmt=fmt_lower,
125 quiet=quiet,
126 include_runtime=include_runtime,
127 log_level=log_level_value,
128 )
130 memory_svc = resolve_memory_service(
131 command, fmt_lower, quiet, include_runtime, log_level_value
132 )
134 try:
135 memory_svc.set(key, value)
136 except Exception as exc:
137 raise_exit_intent(
138 f"Failed to set memory: {exc}",
139 code=1,
140 failure="set_failed",
141 error_type=ErrorType.INTERNAL,
142 command=command,
143 fmt=fmt_lower,
144 quiet=quiet,
145 include_runtime=include_runtime,
146 log_level=log_level_value,
147 )
149 new_run_command(
150 command_name=command,
151 payload_builder=lambda include: _build_payload(include, key, value),
152 quiet=quiet,
153 fmt=fmt_lower,
154 pretty=pretty,
155 log_level=log_level,
156 )