nmem-cli 0.9.9__tar.gz → 0.9.12__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.
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/PKG-INFO +1 -1
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/pyproject.toml +1 -1
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/__init__.py +1 -1
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/cli.py +64 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/session_import.py +8 -2
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/.gitignore +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/README.md +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/agent_profiles.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/claude_paths.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/data_transfer_paths.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/guidance_rules.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/kfs_cli.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/license_payload.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/memories_reclassify.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/memory_relations_cli.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/py.typed +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/__init__.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/__main__.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/api_client.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/app.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/__init__.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/dashboard.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/graph.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/help.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/memories.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/memory_detail.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/settings.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/thread_detail.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/screens/threads.py +0 -0
- {nmem_cli-0.9.9 → nmem_cli-0.9.12}/src/nmem_cli/tui/widgets/__init__.py +0 -0
|
@@ -1515,6 +1515,17 @@ def _format_cli_upgrade_hint(*, context: _CliInstallContext, server_newer: bool)
|
|
|
1515
1515
|
)
|
|
1516
1516
|
|
|
1517
1517
|
|
|
1518
|
+
def _api_release_base(version: str) -> str:
|
|
1519
|
+
"""Return the numeric X.Y.Z base for API compatibility checks.
|
|
1520
|
+
|
|
1521
|
+
Post/dev/pre releases (e.g. ``0.9.11.post1``) stay compatible with the
|
|
1522
|
+
matching server release (``0.9.11``).
|
|
1523
|
+
"""
|
|
1524
|
+
normalized = str(version or "").strip().lstrip("v")
|
|
1525
|
+
match = re.match(r"^(\d+\.\d+\.\d+)", normalized)
|
|
1526
|
+
return match.group(1) if match else normalized
|
|
1527
|
+
|
|
1528
|
+
|
|
1518
1529
|
def _status_version_warning(
|
|
1519
1530
|
*,
|
|
1520
1531
|
cli_version: str,
|
|
@@ -1525,6 +1536,8 @@ def _status_version_warning(
|
|
|
1525
1536
|
normalized_cli = str(cli_version or "").strip()
|
|
1526
1537
|
if not normalized_server or normalized_server == normalized_cli:
|
|
1527
1538
|
return None
|
|
1539
|
+
if _api_release_base(normalized_cli) == _api_release_base(normalized_server):
|
|
1540
|
+
return None
|
|
1528
1541
|
|
|
1529
1542
|
message = "CLI is v{}, but the server at {} reports v{}.".format(
|
|
1530
1543
|
normalized_cli,
|
|
@@ -3039,6 +3052,7 @@ def cmd_memories_search(
|
|
|
3039
3052
|
include_history: bool = False,
|
|
3040
3053
|
space_id: str | None = None,
|
|
3041
3054
|
unit_type: str | None = None,
|
|
3055
|
+
metadata_filters: list[str] | None = None,
|
|
3042
3056
|
) -> None:
|
|
3043
3057
|
params: dict[str, Any] = {"q": query, "limit": limit}
|
|
3044
3058
|
if space_id:
|
|
@@ -3064,6 +3078,8 @@ def cmd_memories_search(
|
|
|
3064
3078
|
params["include_history"] = "true"
|
|
3065
3079
|
if unit_type:
|
|
3066
3080
|
params["unit_type"] = unit_type
|
|
3081
|
+
if metadata_filters:
|
|
3082
|
+
params["metadata"] = metadata_filters
|
|
3067
3083
|
# Map CLI mode to API mode: "normal" -> "fast", "deep" -> "deep"
|
|
3068
3084
|
api_mode = "fast" if mode == "normal" else "deep"
|
|
3069
3085
|
params["mode"] = api_mode
|
|
@@ -3133,6 +3149,8 @@ def cmd_memories_search(
|
|
|
3133
3149
|
filter_info.append(f"importance>={importance_min}")
|
|
3134
3150
|
if unit_type:
|
|
3135
3151
|
filter_info.append(f"type={unit_type}")
|
|
3152
|
+
if metadata_filters:
|
|
3153
|
+
filter_info.append(f"metadata={','.join(metadata_filters)}")
|
|
3136
3154
|
if filter_info:
|
|
3137
3155
|
console.print(
|
|
3138
3156
|
f"[dim]No results for '{query}' with filters: {' '.join(filter_info)}[/dim]"
|
|
@@ -3157,6 +3175,8 @@ def cmd_memories_search(
|
|
|
3157
3175
|
filter_parts.append(f"[green]imp>={importance_min}[/green]")
|
|
3158
3176
|
if unit_type:
|
|
3159
3177
|
filter_parts.append(f"[blue]type:{unit_type}[/blue]")
|
|
3178
|
+
if metadata_filters:
|
|
3179
|
+
filter_parts.append(f"[cyan]metadata:{','.join(metadata_filters)}[/cyan]")
|
|
3160
3180
|
|
|
3161
3181
|
if filter_parts:
|
|
3162
3182
|
console.print(
|
|
@@ -6030,6 +6050,8 @@ def cmd_sources_list(
|
|
|
6030
6050
|
source_type: str | None = None,
|
|
6031
6051
|
lifecycle_state: str | None = None,
|
|
6032
6052
|
space_id: str | None = None,
|
|
6053
|
+
labels: list[str] | None = None,
|
|
6054
|
+
metadata_filters: list[str] | None = None,
|
|
6033
6055
|
) -> None:
|
|
6034
6056
|
params: dict[str, Any] = {"limit": limit, "offset": 0}
|
|
6035
6057
|
if source_type:
|
|
@@ -6038,6 +6060,11 @@ def cmd_sources_list(
|
|
|
6038
6060
|
params["lifecycle_state"] = lifecycle_state
|
|
6039
6061
|
if space_id:
|
|
6040
6062
|
params["space_id"] = space_id
|
|
6063
|
+
normalized_labels = _normalize_labels(labels)
|
|
6064
|
+
if normalized_labels:
|
|
6065
|
+
params["labels"] = normalized_labels
|
|
6066
|
+
if metadata_filters:
|
|
6067
|
+
params["metadata"] = metadata_filters
|
|
6041
6068
|
|
|
6042
6069
|
if not is_json_mode():
|
|
6043
6070
|
with Progress(
|
|
@@ -6263,11 +6290,18 @@ def cmd_sources_search(
|
|
|
6263
6290
|
query: str,
|
|
6264
6291
|
limit: int = 20,
|
|
6265
6292
|
space_id: str | None = None,
|
|
6293
|
+
labels: list[str] | None = None,
|
|
6294
|
+
metadata_filters: list[str] | None = None,
|
|
6266
6295
|
) -> None:
|
|
6267
6296
|
"""Search across Library artifact names and summaries (FTS)."""
|
|
6268
6297
|
params: dict[str, Any] = {"q": query, "limit": limit}
|
|
6269
6298
|
if space_id:
|
|
6270
6299
|
params["space_id"] = space_id
|
|
6300
|
+
normalized_labels = _normalize_labels(labels)
|
|
6301
|
+
if normalized_labels:
|
|
6302
|
+
params["labels"] = normalized_labels
|
|
6303
|
+
if metadata_filters:
|
|
6304
|
+
params["metadata"] = metadata_filters
|
|
6271
6305
|
|
|
6272
6306
|
if not is_json_mode():
|
|
6273
6307
|
with Progress(
|
|
@@ -10059,6 +10093,13 @@ PRIORITY
|
|
|
10059
10093
|
choices=["fact", "preference", "decision", "plan", "procedure", "learning", "context", "event"],
|
|
10060
10094
|
help="Filter by memory unit type",
|
|
10061
10095
|
)
|
|
10096
|
+
s.add_argument(
|
|
10097
|
+
"--metadata",
|
|
10098
|
+
"--meta",
|
|
10099
|
+
dest="metadata_filters",
|
|
10100
|
+
action="append",
|
|
10101
|
+
help="Filter by memory metadata key=value. Repeat for AND filters.",
|
|
10102
|
+
)
|
|
10062
10103
|
s.add_argument(
|
|
10063
10104
|
"--mode",
|
|
10064
10105
|
choices=["normal", "deep"],
|
|
@@ -11120,6 +11161,15 @@ PRIORITY
|
|
|
11120
11161
|
"--state", dest="lifecycle_state",
|
|
11121
11162
|
help="Filter by state: ingested, parsed, chunked, indexed, error",
|
|
11122
11163
|
)
|
|
11164
|
+
ls.add_argument(
|
|
11165
|
+
"-l", "--label", dest="labels", action="append",
|
|
11166
|
+
help="Filter by source label (repeatable)",
|
|
11167
|
+
)
|
|
11168
|
+
ls.add_argument(
|
|
11169
|
+
"--metadata", "--meta", dest="metadata_filters", action="append",
|
|
11170
|
+
metavar="KEY=VALUE",
|
|
11171
|
+
help="Filter by source metadata (repeatable, e.g. customer=acme)",
|
|
11172
|
+
)
|
|
11123
11173
|
|
|
11124
11174
|
add = src_subs.add_parser(
|
|
11125
11175
|
"add",
|
|
@@ -11185,6 +11235,15 @@ PRIORITY
|
|
|
11185
11235
|
srch.add_argument(
|
|
11186
11236
|
"-n", "--limit", type=int, default=20, help="Max results (default 20)"
|
|
11187
11237
|
)
|
|
11238
|
+
srch.add_argument(
|
|
11239
|
+
"-l", "--label", dest="labels", action="append",
|
|
11240
|
+
help="Filter by source label (repeatable)",
|
|
11241
|
+
)
|
|
11242
|
+
srch.add_argument(
|
|
11243
|
+
"--metadata", "--meta", dest="metadata_filters", action="append",
|
|
11244
|
+
metavar="KEY=VALUE",
|
|
11245
|
+
help="Filter by source metadata (repeatable, e.g. customer=acme)",
|
|
11246
|
+
)
|
|
11188
11247
|
|
|
11189
11248
|
rd = src_subs.add_parser(
|
|
11190
11249
|
"read",
|
|
@@ -11626,6 +11685,7 @@ def main() -> int:
|
|
|
11626
11685
|
getattr(args, "include_history", False),
|
|
11627
11686
|
getattr(args, "space", None),
|
|
11628
11687
|
getattr(args, "unit_type", None),
|
|
11688
|
+
getattr(args, "metadata_filters", None),
|
|
11629
11689
|
)
|
|
11630
11690
|
elif action == "reclassify-types":
|
|
11631
11691
|
run_memories_reclassify_types_command(
|
|
@@ -12048,6 +12108,8 @@ def main() -> int:
|
|
|
12048
12108
|
query=args.query,
|
|
12049
12109
|
limit=getattr(args, "limit", 20),
|
|
12050
12110
|
space_id=getattr(args, "space", None),
|
|
12111
|
+
labels=getattr(args, "labels", None),
|
|
12112
|
+
metadata_filters=getattr(args, "metadata_filters", None),
|
|
12051
12113
|
)
|
|
12052
12114
|
elif action == "read":
|
|
12053
12115
|
cmd_sources_read(
|
|
@@ -12076,6 +12138,8 @@ def main() -> int:
|
|
|
12076
12138
|
source_type=getattr(args, "source_type", None),
|
|
12077
12139
|
lifecycle_state=getattr(args, "lifecycle_state", None),
|
|
12078
12140
|
space_id=getattr(args, "space", None),
|
|
12141
|
+
labels=getattr(args, "labels", None),
|
|
12142
|
+
metadata_filters=getattr(args, "metadata_filters", None),
|
|
12079
12143
|
)
|
|
12080
12144
|
elif cmd == "license":
|
|
12081
12145
|
action = args.action
|
|
@@ -2541,7 +2541,11 @@ def _decode_project_path_enhanced(encoded: str) -> Optional[str]:
|
|
|
2541
2541
|
|
|
2542
2542
|
|
|
2543
2543
|
def _decode_project_path_windows(encoded: str) -> Optional[str]:
|
|
2544
|
-
drive_match = re.match(r"^([A-Za-z])
|
|
2544
|
+
drive_match = re.match(r"^([A-Za-z])--(.*)$", encoded)
|
|
2545
|
+
if not drive_match:
|
|
2546
|
+
# Compatibility with older nmem-created expectations before we matched
|
|
2547
|
+
# Claude Code's drive-colon encoding on Windows.
|
|
2548
|
+
drive_match = re.match(r"^([A-Za-z])-(.*)$", encoded)
|
|
2545
2549
|
if not drive_match:
|
|
2546
2550
|
return None
|
|
2547
2551
|
|
|
@@ -2576,7 +2580,9 @@ def _encode_claude_project_path_variant(
|
|
|
2576
2580
|
for segment in re.split(r"[\\/]+", rest)
|
|
2577
2581
|
if segment
|
|
2578
2582
|
]
|
|
2579
|
-
|
|
2583
|
+
if not segments:
|
|
2584
|
+
return f"{drive_letter}--"
|
|
2585
|
+
return f"{drive_letter}--{'-'.join(segments)}"
|
|
2580
2586
|
|
|
2581
2587
|
segments = [
|
|
2582
2588
|
_encode_claude_path_segment(segment, dot_mode=dot_mode)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|