nmem-cli 0.10.3__tar.gz → 0.10.4__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.
Files changed (36) hide show
  1. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/Cargo.lock +15 -13
  2. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/Cargo.toml +1 -1
  3. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/PKG-INFO +1 -1
  4. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/cli.rs +17 -2
  5. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/data_transfer.rs +44 -2
  6. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/memories.rs +9 -0
  7. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/pyproject.toml +1 -1
  8. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/README.md +0 -0
  9. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/Cargo.toml +0 -0
  10. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/README.md +0 -0
  11. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/client.rs +0 -0
  12. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/agents.rs +0 -0
  13. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/communities.rs +0 -0
  14. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/feed.rs +0 -0
  15. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/fs.rs +0 -0
  16. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/graph.rs +0 -0
  17. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/library.rs +0 -0
  18. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/license.rs +0 -0
  19. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/memory_relations.rs +0 -0
  20. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/mod.rs +0 -0
  21. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/models.rs +0 -0
  22. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/plugins.rs +0 -0
  23. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/provider.rs +0 -0
  24. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/rules.rs +0 -0
  25. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/session_import.rs +0 -0
  26. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/skills.rs +0 -0
  27. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/spaces.rs +0 -0
  28. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/stubs.rs +0 -0
  29. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/system.rs +0 -0
  30. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/threads.rs +0 -0
  31. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/wiki.rs +0 -0
  32. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/commands/working_memory.rs +0 -0
  33. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/config.rs +0 -0
  34. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/format.rs +0 -0
  35. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/main.rs +0 -0
  36. {nmem_cli-0.10.3 → nmem_cli-0.10.4}/crates/nmem-cli/src/style.rs +0 -0
@@ -5206,7 +5206,7 @@ dependencies = [
5206
5206
 
5207
5207
  [[package]]
5208
5208
  name = "nmem-cli"
5209
- version = "0.10.3"
5209
+ version = "0.10.4"
5210
5210
  dependencies = [
5211
5211
  "anstyle",
5212
5212
  "anyhow",
@@ -5222,7 +5222,7 @@ dependencies = [
5222
5222
 
5223
5223
  [[package]]
5224
5224
  name = "nmem-content"
5225
- version = "0.10.3"
5225
+ version = "0.10.4"
5226
5226
  dependencies = [
5227
5227
  "anyhow",
5228
5228
  "md5",
@@ -5234,7 +5234,7 @@ dependencies = [
5234
5234
 
5235
5235
  [[package]]
5236
5236
  name = "nmem-core"
5237
- version = "0.10.3"
5237
+ version = "0.10.4"
5238
5238
  dependencies = [
5239
5239
  "serde",
5240
5240
  "serde_json",
@@ -5244,7 +5244,7 @@ dependencies = [
5244
5244
 
5245
5245
  [[package]]
5246
5246
  name = "nmem-docs"
5247
- version = "0.10.3"
5247
+ version = "0.10.4"
5248
5248
  dependencies = [
5249
5249
  "criterion",
5250
5250
  "scraper",
@@ -5254,7 +5254,7 @@ dependencies = [
5254
5254
 
5255
5255
  [[package]]
5256
5256
  name = "nmem-embed"
5257
- version = "0.10.3"
5257
+ version = "0.10.4"
5258
5258
  dependencies = [
5259
5259
  "anyhow",
5260
5260
  "arrow-array",
@@ -5274,7 +5274,7 @@ dependencies = [
5274
5274
 
5275
5275
  [[package]]
5276
5276
  name = "nmem-feed"
5277
- version = "0.10.3"
5277
+ version = "0.10.4"
5278
5278
  dependencies = [
5279
5279
  "anyhow",
5280
5280
  "serde_json",
@@ -5283,7 +5283,7 @@ dependencies = [
5283
5283
 
5284
5284
  [[package]]
5285
5285
  name = "nmem-graph"
5286
- version = "0.10.3"
5286
+ version = "0.10.4"
5287
5287
  dependencies = [
5288
5288
  "anyhow",
5289
5289
  "caseless",
@@ -5302,7 +5302,7 @@ dependencies = [
5302
5302
 
5303
5303
  [[package]]
5304
5304
  name = "nmem-harness"
5305
- version = "0.10.3"
5305
+ version = "0.10.4"
5306
5306
  dependencies = [
5307
5307
  "anyhow",
5308
5308
  "futures",
@@ -5322,7 +5322,7 @@ dependencies = [
5322
5322
 
5323
5323
  [[package]]
5324
5324
  name = "nmem-model"
5325
- version = "0.10.3"
5325
+ version = "0.10.4"
5326
5326
  dependencies = [
5327
5327
  "anyhow",
5328
5328
  "encoding_rs",
@@ -5351,7 +5351,7 @@ dependencies = [
5351
5351
 
5352
5352
  [[package]]
5353
5353
  name = "nmem-search"
5354
- version = "0.10.3"
5354
+ version = "0.10.4"
5355
5355
  dependencies = [
5356
5356
  "anyhow",
5357
5357
  "arrow-array",
@@ -5373,13 +5373,15 @@ dependencies = [
5373
5373
 
5374
5374
  [[package]]
5375
5375
  name = "nmem-server"
5376
- version = "0.10.3"
5376
+ version = "0.10.4"
5377
5377
  dependencies = [
5378
5378
  "aes-gcm",
5379
5379
  "anyhow",
5380
5380
  "async-stream",
5381
5381
  "axum",
5382
5382
  "base64",
5383
+ "chrono",
5384
+ "chrono-tz",
5383
5385
  "csv",
5384
5386
  "dom_smoothie",
5385
5387
  "futures",
@@ -5427,7 +5429,7 @@ dependencies = [
5427
5429
 
5428
5430
  [[package]]
5429
5431
  name = "nmem-tui"
5430
- version = "0.10.3"
5432
+ version = "0.10.4"
5431
5433
  dependencies = [
5432
5434
  "anyhow",
5433
5435
  "arboard",
@@ -5441,7 +5443,7 @@ dependencies = [
5441
5443
 
5442
5444
  [[package]]
5443
5445
  name = "nmem-websearch"
5444
- version = "0.10.3"
5446
+ version = "0.10.4"
5445
5447
  dependencies = [
5446
5448
  "anyhow",
5447
5449
  "dom_smoothie",
@@ -4,7 +4,7 @@ members = ["crates/nmem-cli"]
4
4
 
5
5
  [workspace.package]
6
6
  edition = "2021"
7
- version = "0.10.3"
7
+ version = "0.10.4"
8
8
  license = "UNLICENSED"
9
9
  publish = false
10
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nmem-cli
3
- Version: 0.10.3
3
+ Version: 0.10.4
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -1132,7 +1132,11 @@ pub struct MemSearchArgs {
1132
1132
  #[arg(long, default_value = "normal")]
1133
1133
  pub mode: String,
1134
1134
  /// Minimum importance.
1135
- #[arg(long = "importance-min")]
1135
+ // `alias = "importance"` keeps the old Python-CLI flag name working: the
1136
+ // community plugins (Hermes/Codex/...) were written against `--importance`
1137
+ // for the search min-importance filter; the Rust port renamed it to
1138
+ // `--importance-min`, silently breaking those callers. Accept both.
1139
+ #[arg(long = "importance-min", alias = "importance")]
1136
1140
  pub importance_min: Option<f64>,
1137
1141
  /// Space NAME (Python-parity; passed through as space_id).
1138
1142
  #[arg(long)]
@@ -1162,11 +1166,22 @@ pub struct MemAddArgs {
1162
1166
  #[arg(short = 'l', long = "label")]
1163
1167
  pub label: Vec<String>,
1164
1168
  /// Source tag (default: cli).
1165
- #[arg(long, default_value = "cli")]
1169
+ // `short = 's'` restores the Python-CLI alias (`-s`/`--source`); the Rust
1170
+ // port dropped the short form, which broke community plugins (Hermes) that
1171
+ // called `m add ... -s hermes`.
1172
+ #[arg(short = 's', long, default_value = "cli")]
1166
1173
  pub source: String,
1167
1174
  /// Unit type.
1168
1175
  #[arg(long = "unit-type")]
1169
1176
  pub unit_type: Option<String>,
1177
+ /// When this event occurred (YYYY, YYYY-MM, or YYYY-MM-DD). Python-parity
1178
+ /// (`m add --event-start`); the Rust port dropped it, so the Hermes plugin's
1179
+ /// event_date was silently lost. The backend create payload accepts it.
1180
+ #[arg(long = "event-start")]
1181
+ pub event_start: Option<String>,
1182
+ /// When this event ended, for ranges (YYYY, YYYY-MM, or YYYY-MM-DD).
1183
+ #[arg(long = "event-end")]
1184
+ pub event_end: Option<String>,
1170
1185
  /// Space NAME (Python-parity; passed through as space_id).
1171
1186
  #[arg(long)]
1172
1187
  pub space: Option<String>,
@@ -108,13 +108,55 @@ pub async fn import(client: &ApiClient, args: &ImportArgs, json_mode: bool) -> R
108
108
  payload.insert("include_source_files".into(), Value::Bool(!args.no_source_files));
109
109
 
110
110
  let result = client.post("/data/import", &Value::Object(payload), 600).await?;
111
+ // `/data/import` enqueues a BACKGROUND job ({job_id, status:"processing"}).
112
+ // Poll it to completion so this command doesn't print "Imported" and return
113
+ // while the import is still running. Without this, `nmemctl restore` (which
114
+ // runs `nmem stats` immediately after) races the job, and a concurrent
115
+ // restore 409s confusingly.
116
+ let result = match result.get("job_id").and_then(Value::as_str) {
117
+ Some(job_id) if result.get("status").and_then(Value::as_str) == Some("processing") => {
118
+ let endpoint = format!("/data/import/status/{job_id}");
119
+ let start = std::time::Instant::now();
120
+ loop {
121
+ if start.elapsed().as_secs() > 7200 {
122
+ anyhow::bail!(
123
+ "import did not finish within 2h; check progress with `nmem stats`"
124
+ );
125
+ }
126
+ tokio::time::sleep(std::time::Duration::from_millis(750)).await;
127
+ let st = client.get(&endpoint, &[], 30).await?;
128
+ match st.get("status").and_then(Value::as_str) {
129
+ Some("completed") => break st,
130
+ Some("error") => {
131
+ let msg = st
132
+ .get("error")
133
+ .and_then(Value::as_str)
134
+ .or_else(|| st.get("message").and_then(Value::as_str))
135
+ .unwrap_or("import failed");
136
+ anyhow::bail!("import failed: {msg}");
137
+ }
138
+ // "processing" / unknown / transient null: keep polling.
139
+ _ => continue,
140
+ }
141
+ }
142
+ }
143
+ _ => result,
144
+ };
111
145
  if json_mode {
112
146
  print_json(&result);
113
147
  return Ok(());
114
148
  }
115
149
  println!("Imported: {resolved}");
116
- if let Some(counts) = result.get("counts") {
117
- if !counts.is_null() && counts.as_object().map(|m| !m.is_empty()).unwrap_or(false) {
150
+ // Counts live at the top level on the inline path, but a polled background
151
+ // job nests them under `result.counts` (the completed status envelope is
152
+ // `{status:"completed", result:{counts:{…}}}`), so check both or the summary
153
+ // is dropped after polling.
154
+ let counts = result
155
+ .get("counts")
156
+ .filter(|c| !c.is_null())
157
+ .or_else(|| result.get("result").and_then(|r| r.get("counts")));
158
+ if let Some(counts) = counts {
159
+ if counts.as_object().map(|m| !m.is_empty()).unwrap_or(false) {
118
160
  print_json(counts);
119
161
  }
120
162
  }
@@ -189,6 +189,15 @@ pub async fn add(client: &ApiClient, args: &MemAddArgs, json_mode: bool) -> Resu
189
189
  if let Some(ut) = &args.unit_type {
190
190
  payload.insert("unit_type".into(), Value::String(ut.clone()));
191
191
  }
192
+ // Bi-temporal event window (Python-parity `--event-start`/`--event-end`).
193
+ // The /memories create payload accepts these (rest_write.rs); without
194
+ // forwarding them the Hermes plugin's event_date was silently dropped.
195
+ if let Some(es) = &args.event_start {
196
+ payload.insert("event_start".into(), Value::String(es.clone()));
197
+ }
198
+ if let Some(ee) = &args.event_end {
199
+ payload.insert("event_end".into(), Value::String(ee.clone()));
200
+ }
192
201
  if let Some(sid) = crate::cli::resolve_space(args.space.as_deref(), args.space_id.as_deref()) {
193
202
  payload.insert("space_id".into(), Value::String(sid));
194
203
  }
@@ -13,7 +13,7 @@ build-backend = "maturin"
13
13
 
14
14
  [project]
15
15
  name = "nmem-cli"
16
- version = "0.10.3"
16
+ version = "0.10.4"
17
17
  description = "CLI and TUI for Nowledge Mem - AI memory management"
18
18
  authors = [
19
19
  { name = "Nowledge Labs" },
File without changes