shopping-cli 3.2.1__tar.gz → 3.2.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 (110) hide show
  1. {shopping_cli-3.2.1/shopping_cli.egg-info → shopping_cli-3.2.4}/PKG-INFO +15 -1
  2. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/README.md +14 -0
  3. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/pyproject.toml +1 -1
  4. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/__init__.py +1 -1
  5. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli.py +4 -2
  6. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_adapter_commands.py +28 -3
  7. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_common.py +10 -1
  8. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/listings/projection.py +7 -20
  9. {shopping_cli-3.2.1 → shopping_cli-3.2.4/shopping_cli.egg-info}/PKG-INFO +15 -1
  10. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/LICENSE +0 -0
  11. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/MANIFEST.in +0 -0
  12. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/setup.cfg +0 -0
  13. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/__init__.py +0 -0
  14. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/agent_cli.py +0 -0
  15. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/buyer_cli.py +0 -0
  16. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/merchant_agent.py +0 -0
  17. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/merchant_daemon.py +0 -0
  18. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/merchant_state_helpers.py +0 -0
  19. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/agents/tools.py +0 -0
  20. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/__init__.py +0 -0
  21. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/app.py +0 -0
  22. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/auth.py +0 -0
  23. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/error_handlers.py +0 -0
  24. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/error_response.py +0 -0
  25. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/fallback_asgi.py +0 -0
  26. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/fastapi_routes.py +0 -0
  27. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/__init__.py +0 -0
  28. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/agents.py +0 -0
  29. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/audit.py +0 -0
  30. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/buyer.py +0 -0
  31. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/catalog.py +0 -0
  32. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/common.py +0 -0
  33. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/conversations.py +0 -0
  34. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/erp.py +0 -0
  35. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/human_review.py +0 -0
  36. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/listings_projection.py +0 -0
  37. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/handlers/negotiation.py +0 -0
  38. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/idempotency.py +0 -0
  39. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/limits.py +0 -0
  40. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/request_dispatch.py +0 -0
  41. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/request_limits.py +0 -0
  42. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/route_matching.py +0 -0
  43. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/route_registry.py +0 -0
  44. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/route_table.py +0 -0
  45. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/routes_agents.py +0 -0
  46. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/routes_conversations.py +0 -0
  47. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/routes_marketplace.py +0 -0
  48. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/routes_merchants.py +0 -0
  49. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/api/server.py +0 -0
  50. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_agent_commands.py +0 -0
  51. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_buyer_commands.py +0 -0
  52. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_catalog_commands.py +0 -0
  53. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_conversation_commands.py +0 -0
  54. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_erp_commands.py +0 -0
  55. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/cli_listing_commands.py +0 -0
  56. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/commerce/__init__.py +0 -0
  57. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/commerce/adapters.py +0 -0
  58. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/commerce/data_source.py +0 -0
  59. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/config.py +0 -0
  60. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/contracts/kiwi-contracts.lock.json +0 -0
  61. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/contracts/shopping.negotiation/0.1/capabilities.schema.json +0 -0
  62. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/contracts/shopping.negotiation/0.1/decision.schema.json +0 -0
  63. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/contracts/shopping.negotiation/0.1/policy-result.schema.json +0 -0
  64. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/contracts/shopping.negotiation/0.1/snapshot.schema.json +0 -0
  65. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/__init__.py +0 -0
  66. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/catalog.py +0 -0
  67. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/catalog_scoring.py +0 -0
  68. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/catalog_text.py +0 -0
  69. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/catalog_views.py +0 -0
  70. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/channels.py +0 -0
  71. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/conversations.py +0 -0
  72. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/delivery.py +0 -0
  73. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/errors.py +0 -0
  74. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/harness.py +0 -0
  75. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/limits.py +0 -0
  76. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/negotiation.py +0 -0
  77. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/negotiation_contracts.py +0 -0
  78. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/policies.py +0 -0
  79. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/risk.py +0 -0
  80. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/core/tokens.py +0 -0
  81. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/data_sources/__init__.py +0 -0
  82. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/data_sources/adapter.py +0 -0
  83. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/data_sources/csv_excel_source.py +0 -0
  84. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/data_sources/erp_source.py +0 -0
  85. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/db/__init__.py +0 -0
  86. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/db/migrations.py +0 -0
  87. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/db/models.py +0 -0
  88. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/db/provenance.py +0 -0
  89. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/db/session.py +0 -0
  90. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/http_client.py +0 -0
  91. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/listings/__init__.py +0 -0
  92. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/__init__.py +0 -0
  93. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/agents.py +0 -0
  94. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/audit.py +0 -0
  95. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/buyer_bootstrap.py +0 -0
  96. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/conversations.py +0 -0
  97. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/human_review.py +0 -0
  98. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation.py +0 -0
  99. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_gates.py +0 -0
  100. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_message.py +0 -0
  101. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_policy_helpers.py +0 -0
  102. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_policy_result.py +0 -0
  103. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_snapshot.py +0 -0
  104. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/negotiation_snapshot_projection.py +0 -0
  105. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli/services/tokens.py +0 -0
  106. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli.egg-info/SOURCES.txt +0 -0
  107. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli.egg-info/dependency_links.txt +0 -0
  108. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli.egg-info/entry_points.txt +0 -0
  109. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli.egg-info/requires.txt +0 -0
  110. {shopping_cli-3.2.1 → shopping_cli-3.2.4}/shopping_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shopping-cli
3
- Version: 3.2.1
3
+ Version: 3.2.4
4
4
  Summary: Standalone local-commerce AI consultation marketplace runtime
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -310,6 +310,20 @@ printf 'longjing gift delivery today\n/summary\n/quit\n' | \
310
310
 
311
311
  Default database path: `~/.local/share/shopping-cli/shopping-cli.sqlite`.
312
312
 
313
+ For a single-merchant deployment, import commands can read the database and
314
+ merchant identity from the environment instead of repeating tenant flags:
315
+
316
+ ```bash
317
+ export SHOPPING_DB_PATH="$HOME/.local/share/shopping-cli/shopping-cli.sqlite"
318
+ export SHOPPING_MERCHANT_ID="your-merchant-id"
319
+
320
+ shopping-cli import-csv-excel --file products.csv
321
+ ```
322
+
323
+ `KIWI_MERCHANT_ID` is accepted as a compatibility alias for
324
+ `SHOPPING_MERCHANT_ID`. Explicit `--db` and `--merchant` arguments take
325
+ precedence over environment variables.
326
+
313
327
  ## Channel Ingress
314
328
 
315
329
  External channel adapters can ingest buyer messages through a stable local entry point before real WhatsApp, Telegram, Slack, or OpenClaw/Hermes gateway bridges are attached:
@@ -87,6 +87,20 @@ printf 'longjing gift delivery today\n/summary\n/quit\n' | \
87
87
 
88
88
  Default database path: `~/.local/share/shopping-cli/shopping-cli.sqlite`.
89
89
 
90
+ For a single-merchant deployment, import commands can read the database and
91
+ merchant identity from the environment instead of repeating tenant flags:
92
+
93
+ ```bash
94
+ export SHOPPING_DB_PATH="$HOME/.local/share/shopping-cli/shopping-cli.sqlite"
95
+ export SHOPPING_MERCHANT_ID="your-merchant-id"
96
+
97
+ shopping-cli import-csv-excel --file products.csv
98
+ ```
99
+
100
+ `KIWI_MERCHANT_ID` is accepted as a compatibility alias for
101
+ `SHOPPING_MERCHANT_ID`. Explicit `--db` and `--merchant` arguments take
102
+ precedence over environment variables.
103
+
90
104
  ## Channel Ingress
91
105
 
92
106
  External channel adapters can ingest buyer messages through a stable local entry point before real WhatsApp, Telegram, Slack, or OpenClaw/Hermes gateway bridges are attached:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "shopping-cli"
7
- version = "3.2.1"
7
+ version = "3.2.4"
8
8
  description = "Standalone local-commerce AI consultation marketplace runtime"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """Standalone shopping-cli consultation runtime."""
2
2
 
3
- VERSION = "3.2.1"
3
+ VERSION = "3.2.4"
@@ -866,8 +866,10 @@ def build_parser() -> argparse.ArgumentParser:
866
866
  import_csv = subparsers.add_parser(
867
867
  "import-csv-excel", help="Import product facts from CSV / Excel (.xlsx) into the local store"
868
868
  )
869
- import_csv.add_argument("--file", required=True, help="Path to .csv / .tsv / .xlsx file")
870
- import_csv.add_argument("--merchant", default="", dest="merchant", help="Owning merchant id (required, FK guard)")
869
+ import_csv.add_argument("--file", default="", help="Path to .csv / .tsv / .xlsx file (required unless --template)")
870
+ import_csv.add_argument("--template", default="", dest="template", help="写一份 CSV 模板到该路径后退出(不导入)")
871
+ import_csv.add_argument("--merchant", default="", dest="merchant", help="Owning merchant id (or SHOPPING_MERCHANT_ID / KIWI_MERCHANT_ID)")
872
+ import_csv.add_argument("--default-merchant", default="", dest="default_merchant", help=argparse.SUPPRESS)
871
873
  import_csv.add_argument("--allowed-merchant", default="", dest="allowed_merchant", help="Tenant boundary: only rows of this merchant are written")
872
874
  import_csv.add_argument("--format", choices=["text", "json"], default="text")
873
875
  import_csv.set_defaults(func=cmd_import_csv_excel)
@@ -7,17 +7,25 @@
7
7
  from __future__ import annotations
8
8
 
9
9
  import argparse
10
+ import os
10
11
 
11
12
  from shopping_cli.cli_common import db_path_from_args, emit
12
13
  from shopping_cli.data_sources import csv_excel_source # noqa: F401 # 导入即注册适配器
13
14
  from shopping_cli.data_sources.adapter import (
14
- AdapterError,
15
15
  SyncContext,
16
16
  registered_adapters,
17
17
  run,
18
18
  )
19
19
  from shopping_cli.db.session import db_session
20
20
 
21
+ # CSV/Excel 导入模板(与 examples/products-template.csv 一致)。必填列 sku/title/
22
+ # price/stock;可选 currency(缺省 CNY)/ category / description / merchant_id。
23
+ PRODUCTS_TEMPLATE_CSV = (
24
+ "sku,title,price,stock,currency,category,description\n"
25
+ "VQ-001,智能保温杯 500ml,129.00,50,CNY,kitchenware,316 不锈钢内胆真空保温\n"
26
+ "VQ-002,桌面无线充电器 15W,89.00,120,CNY,electronics,兼容 QC3.0\n"
27
+ )
28
+
21
29
 
22
30
  def cmd_adapters_list(args: argparse.Namespace) -> None:
23
31
  """列出已注册适配器(Adapter SDK 注册表)。"""
@@ -28,9 +36,26 @@ def cmd_adapters_list(args: argparse.Namespace) -> None:
28
36
 
29
37
 
30
38
  def cmd_import_csv_excel(args: argparse.Namespace) -> None:
31
- """运行 CSV/Excel 适配器导入本地 products 表。"""
39
+ """运行 CSV/Excel 适配器导入本地 products 表;--template 只生成模板不导入。"""
40
+ template_path = str(getattr(args, "template", "") or "").strip()
41
+ if template_path:
42
+ with open(template_path, "w", encoding="utf-8", newline="") as fh:
43
+ fh.write(PRODUCTS_TEMPLATE_CSV)
44
+ emit(
45
+ {"ok": True, "message": f"CSV 模板已写入 {template_path}(填好 sku/title/price/stock 后再导入)"},
46
+ getattr(args, "format", "text"),
47
+ )
48
+ return
49
+ file_path = str(args.file or "").strip()
50
+ if not file_path:
51
+ raise SystemExit("--file <path> 必填(或先用 --template <path> 生成模板)")
32
52
  db_path = db_path_from_args(args)
33
- merchant_id = str(args.merchant or "").strip() or str(args.default_merchant or "").strip()
53
+ merchant_id = (
54
+ str(args.merchant or "").strip()
55
+ or str(getattr(args, "default_merchant", "")).strip()
56
+ or str(os.environ.get("SHOPPING_MERCHANT_ID") or "").strip()
57
+ or str(os.environ.get("KIWI_MERCHANT_ID") or "").strip()
58
+ )
34
59
  if not merchant_id:
35
60
  raise SystemExit("--merchant is required (FK 归属防护)")
36
61
  with db_session(db_path) as conn:
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import argparse
6
6
  import json
7
7
  import math
8
+ import os
8
9
  from pathlib import Path
9
10
  from typing import Any
10
11
 
@@ -132,4 +133,12 @@ def tcp_port(value: str) -> int:
132
133
 
133
134
 
134
135
  def db_path_from_args(args: argparse.Namespace) -> Path:
135
- return Path(getattr(args, "agent_db", None) or args.db or args.data or DEFAULT_DB_PATH).expanduser()
136
+ configured = (
137
+ getattr(args, "agent_db", None)
138
+ or getattr(args, "db", None)
139
+ or getattr(args, "data", None)
140
+ or os.environ.get("SHOPPING_DB_PATH")
141
+ or os.environ.get("SHOPPING_DB")
142
+ or DEFAULT_DB_PATH
143
+ )
144
+ return Path(configured).expanduser()
@@ -1,12 +1,10 @@
1
1
  """PublicListingProjection(shopping-cli v0.3 §14/§16;DoD #1-#3)。
2
2
 
3
3
  public-only 白名单投影:把 products 行压缩为可公开的 discovery projection。
4
- **绝不输出** cost / floor price / 私密库存 / credentials / 客户特定条款
5
- (v0.3 §16 不得输出清单;DoD #2 有回归测试锁定)。
6
-
7
- availability_hint / price_range_hint 必须携带 provenance 并注明只是
8
- discovery hint(v0.3 §14)——权威值以本地 products 行为准(v3.0 起
9
- 发布面已随 kiwi-catalog 子系统迁移至独立服务)。
4
+ **绝不输出** cost / floor price / 私密库存 / credentials / 客户特定条款 / 价格 /
5
+ 促销 / 底价(v0.3 §16 不得输出清单;DoD #2 有回归测试锁定)。商品 listing 只携带
6
+ 名称 + 分类/标签/区域等发现元数据,价格与供应事实以本地 products 行为准
7
+ (v3.0 起发布面已随 kiwi-catalog 子系统迁移至独立服务)。
10
8
  """
11
9
 
12
10
  from __future__ import annotations
@@ -27,11 +25,6 @@ def _now_iso() -> str:
27
25
  return datetime.now(timezone.utc).isoformat()
28
26
 
29
27
 
30
- def _hint_price_range(price: float, currency: str) -> str:
31
- """price_range_hint:粗粒度公开价格提示(不是报价)。"""
32
- return f"{currency} {price:.0f}"
33
-
34
-
35
28
  def _product_row(conn: sqlite3.Connection, sku: str) -> dict[str, Any]:
36
29
  row = conn.execute(
37
30
  "select * from products where sku = ?", (str(sku).strip(),)
@@ -74,12 +67,6 @@ def project_product_listing(
74
67
  "category": str(row.get("category") or ""),
75
68
  "regions": [],
76
69
  "tags": json.loads(row.get("tags_json") or "[]"),
77
- "commercial_hints": {
78
- "price_range_hint": _hint_price_range(float(row["price"]), str(row.get("currency") or "CNY")),
79
- "availability_hint": "in_stock" if int(row.get("stock", 0)) > 0 else "out_of_stock",
80
- "moq": 1,
81
- "supports_bulk_quote": True,
82
- },
83
70
  }
84
71
  # 每商品成交入口(KTH destination_ref):商家自行维护,publish 时同步进
85
72
  # catalog listing 的 handoff_destination_ref。审查 S-M3:私有字段,缺省
@@ -90,14 +77,14 @@ def project_product_listing(
90
77
  if description:
91
78
  projection["summary"] = description
92
79
 
93
- # provenance 标注:availability/price 是 discovery hint,不是权威事实(v0.3 §14)。
94
- # 只存在于 projection(Merchant Kiwi 可见)(wire commercial_hints 七键白名单,v0.4 §4.1)。
80
+ # provenance 标注:只存在于 projection(Merchant Kiwi 可见),发布前由
81
+ # strip_provenance 剥离;商品不再携带价格/库存 hint(名称-only,v0.3 §16)。
95
82
  projection["_provenance"] = {
96
83
  "authority": authority,
97
84
  "source_revision": projection["source_revision"],
98
85
  "observed_at": str(row.get("observed_at") or now),
99
86
  "fresh_until": str(row.get("fresh_until") or ""),
100
- "note": "discovery hint only; authoritative value in the local product record",
87
+ "note": "name-only discovery projection; authoritative facts in the local product record",
101
88
  }
102
89
  return projection
103
90
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shopping-cli
3
- Version: 3.2.1
3
+ Version: 3.2.4
4
4
  Summary: Standalone local-commerce AI consultation marketplace runtime
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -310,6 +310,20 @@ printf 'longjing gift delivery today\n/summary\n/quit\n' | \
310
310
 
311
311
  Default database path: `~/.local/share/shopping-cli/shopping-cli.sqlite`.
312
312
 
313
+ For a single-merchant deployment, import commands can read the database and
314
+ merchant identity from the environment instead of repeating tenant flags:
315
+
316
+ ```bash
317
+ export SHOPPING_DB_PATH="$HOME/.local/share/shopping-cli/shopping-cli.sqlite"
318
+ export SHOPPING_MERCHANT_ID="your-merchant-id"
319
+
320
+ shopping-cli import-csv-excel --file products.csv
321
+ ```
322
+
323
+ `KIWI_MERCHANT_ID` is accepted as a compatibility alias for
324
+ `SHOPPING_MERCHANT_ID`. Explicit `--db` and `--merchant` arguments take
325
+ precedence over environment variables.
326
+
313
327
  ## Channel Ingress
314
328
 
315
329
  External channel adapters can ingest buyer messages through a stable local entry point before real WhatsApp, Telegram, Slack, or OpenClaw/Hermes gateway bridges are attached:
File without changes
File without changes
File without changes