@newpeak/barista-cli 0.1.133 → 0.1.158
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.
- package/README.md +1 -1
- package/dist/commands/liberica/actual-production/create.d.ts.map +1 -1
- package/dist/commands/liberica/actual-production/create.js +36 -1
- package/dist/commands/liberica/actual-production/create.js.map +1 -1
- package/dist/commands/liberica/aps/list.d.ts.map +1 -1
- package/dist/commands/liberica/aps/list.js +3 -2
- package/dist/commands/liberica/aps/list.js.map +1 -1
- package/dist/commands/liberica/aps/schedule.d.ts.map +1 -1
- package/dist/commands/liberica/aps/schedule.js +2 -1
- package/dist/commands/liberica/aps/schedule.js.map +1 -1
- package/dist/commands/liberica/bom/copy.js +1 -1
- package/dist/commands/liberica/bom/copy.js.map +1 -1
- package/dist/commands/liberica/bom/delete.js +1 -1
- package/dist/commands/liberica/bom/delete.js.map +1 -1
- package/dist/commands/liberica/bom/disable.d.ts.map +1 -1
- package/dist/commands/liberica/bom/disable.js +3 -4
- package/dist/commands/liberica/bom/disable.js.map +1 -1
- package/dist/commands/liberica/bom/enable.d.ts.map +1 -1
- package/dist/commands/liberica/bom/enable.js +3 -4
- package/dist/commands/liberica/bom/enable.js.map +1 -1
- package/dist/commands/liberica/bom/review.d.ts.map +1 -1
- package/dist/commands/liberica/bom/review.js +3 -4
- package/dist/commands/liberica/bom/review.js.map +1 -1
- package/dist/commands/liberica/bom/unReview.d.ts.map +1 -1
- package/dist/commands/liberica/bom/unReview.js +3 -4
- package/dist/commands/liberica/bom/unReview.js.map +1 -1
- package/dist/commands/liberica/bom/update.js +1 -1
- package/dist/commands/liberica/bom/update.js.map +1 -1
- package/dist/commands/liberica/cutting-material/list.d.ts.map +1 -1
- package/dist/commands/liberica/cutting-material/list.js +9 -3
- package/dist/commands/liberica/cutting-material/list.js.map +1 -1
- package/dist/commands/liberica/finance/invoices/create.d.ts.map +1 -1
- package/dist/commands/liberica/finance/invoices/create.js +13 -0
- package/dist/commands/liberica/finance/invoices/create.js.map +1 -1
- package/dist/commands/liberica/finance/proceeds/create.d.ts.map +1 -1
- package/dist/commands/liberica/finance/proceeds/create.js +13 -1
- package/dist/commands/liberica/finance/proceeds/create.js.map +1 -1
- package/dist/commands/liberica/inventory-shortage/__tests__/create.test.js +45 -8
- package/dist/commands/liberica/inventory-shortage/__tests__/create.test.js.map +1 -1
- package/dist/commands/liberica/inventory-shortage/create.d.ts +7 -0
- package/dist/commands/liberica/inventory-shortage/create.d.ts.map +1 -1
- package/dist/commands/liberica/inventory-shortage/create.js +12 -4
- package/dist/commands/liberica/inventory-shortage/create.js.map +1 -1
- package/dist/commands/liberica/material-issue/create.d.ts.map +1 -1
- package/dist/commands/liberica/material-issue/create.js +28 -3
- package/dist/commands/liberica/material-issue/create.js.map +1 -1
- package/dist/commands/liberica/material-issue/update.d.ts.map +1 -1
- package/dist/commands/liberica/material-issue/update.js +6 -2
- package/dist/commands/liberica/material-issue/update.js.map +1 -1
- package/dist/commands/liberica/material-return/create.d.ts.map +1 -1
- package/dist/commands/liberica/material-return/create.js +13 -1
- package/dist/commands/liberica/material-return/create.js.map +1 -1
- package/dist/commands/liberica/mes-result/list.d.ts.map +1 -1
- package/dist/commands/liberica/mes-result/list.js +9 -3
- package/dist/commands/liberica/mes-result/list.js.map +1 -1
- package/dist/commands/liberica/mould/list.d.ts.map +1 -1
- package/dist/commands/liberica/mould/list.js +3 -2
- package/dist/commands/liberica/mould/list.js.map +1 -1
- package/dist/commands/liberica/mould/register.d.ts.map +1 -1
- package/dist/commands/liberica/mould/register.js +9 -3
- package/dist/commands/liberica/mould/register.js.map +1 -1
- package/dist/commands/liberica/mould/stock-in.d.ts.map +1 -1
- package/dist/commands/liberica/mould/stock-in.js +7 -4
- package/dist/commands/liberica/mould/stock-in.js.map +1 -1
- package/dist/commands/liberica/operations/create.js +1 -1
- package/dist/commands/liberica/operations/create.js.map +1 -1
- package/dist/commands/liberica/outsourcing-orders/get.d.ts +3 -0
- package/dist/commands/liberica/outsourcing-orders/get.d.ts.map +1 -0
- package/dist/commands/liberica/outsourcing-orders/get.js +75 -0
- package/dist/commands/liberica/outsourcing-orders/get.js.map +1 -0
- package/dist/commands/liberica/outsourcing-orders/index.d.ts.map +1 -1
- package/dist/commands/liberica/outsourcing-orders/index.js +2 -0
- package/dist/commands/liberica/outsourcing-orders/index.js.map +1 -1
- package/dist/commands/liberica/physical-inventory/list.d.ts.map +1 -1
- package/dist/commands/liberica/physical-inventory/list.js +3 -2
- package/dist/commands/liberica/physical-inventory/list.js.map +1 -1
- package/dist/commands/liberica/plan-orders/create.d.ts.map +1 -1
- package/dist/commands/liberica/plan-orders/create.js +6 -2
- package/dist/commands/liberica/plan-orders/create.js.map +1 -1
- package/dist/commands/liberica/plan-orders/list.d.ts.map +1 -1
- package/dist/commands/liberica/plan-orders/list.js +8 -2
- package/dist/commands/liberica/plan-orders/list.js.map +1 -1
- package/dist/commands/liberica/plan-orders/update.js +1 -1
- package/dist/commands/liberica/plan-orders/update.js.map +1 -1
- package/dist/commands/liberica/product-stock-in/create.d.ts.map +1 -1
- package/dist/commands/liberica/product-stock-in/create.js +2 -0
- package/dist/commands/liberica/product-stock-in/create.js.map +1 -1
- package/dist/commands/liberica/product-stock-out/create.d.ts.map +1 -1
- package/dist/commands/liberica/product-stock-out/create.js +7 -1
- package/dist/commands/liberica/product-stock-out/create.js.map +1 -1
- package/dist/commands/liberica/product-stock-out/list.d.ts.map +1 -1
- package/dist/commands/liberica/product-stock-out/list.js +9 -3
- package/dist/commands/liberica/product-stock-out/list.js.map +1 -1
- package/dist/commands/liberica/purchase-orders/stock-in-create.d.ts.map +1 -1
- package/dist/commands/liberica/purchase-orders/stock-in-create.js +7 -2
- package/dist/commands/liberica/purchase-orders/stock-in-create.js.map +1 -1
- package/dist/commands/liberica/quotations/create.d.ts.map +1 -1
- package/dist/commands/liberica/quotations/create.js +16 -0
- package/dist/commands/liberica/quotations/create.js.map +1 -1
- package/dist/commands/liberica/routing/compute.js +1 -1
- package/dist/commands/liberica/routing/compute.js.map +1 -1
- package/dist/commands/liberica/routing/copy.js +1 -1
- package/dist/commands/liberica/routing/copy.js.map +1 -1
- package/dist/commands/liberica/routing/delete.js +1 -1
- package/dist/commands/liberica/routing/delete.js.map +1 -1
- package/dist/commands/liberica/routing/disable.js +2 -2
- package/dist/commands/liberica/routing/disable.js.map +1 -1
- package/dist/commands/liberica/routing/enable.js +1 -1
- package/dist/commands/liberica/routing/enable.js.map +1 -1
- package/dist/commands/liberica/routing/review.js +2 -2
- package/dist/commands/liberica/routing/review.js.map +1 -1
- package/dist/commands/liberica/routing/unReview.js +2 -2
- package/dist/commands/liberica/routing/unReview.js.map +1 -1
- package/dist/commands/liberica/routing/update.js +1 -1
- package/dist/commands/liberica/routing/update.js.map +1 -1
- package/dist/commands/liberica/sales-orders/create.d.ts.map +1 -1
- package/dist/commands/liberica/sales-orders/create.js +8 -2
- package/dist/commands/liberica/sales-orders/create.js.map +1 -1
- package/dist/commands/liberica/sales-orders/submit.d.ts.map +1 -1
- package/dist/commands/liberica/sales-orders/submit.js +10 -0
- package/dist/commands/liberica/sales-orders/submit.js.map +1 -1
- package/dist/commands/liberica/sales-orders/update.js +1 -1
- package/dist/commands/liberica/sales-orders/update.js.map +1 -1
- package/dist/commands/liberica/stock-reservation/create.d.ts.map +1 -1
- package/dist/commands/liberica/stock-reservation/create.js +30 -1
- package/dist/commands/liberica/stock-reservation/create.js.map +1 -1
- package/dist/commands/liberica/supplier-price/create.d.ts.map +1 -1
- package/dist/commands/liberica/supplier-price/create.js +13 -1
- package/dist/commands/liberica/supplier-price/create.js.map +1 -1
- package/dist/commands/liberica/supplier-price/list.d.ts.map +1 -1
- package/dist/commands/liberica/supplier-price/list.js +66 -77
- package/dist/commands/liberica/supplier-price/list.js.map +1 -1
- package/dist/commands/liberica/suppliers/update.d.ts.map +1 -1
- package/dist/commands/liberica/suppliers/update.js +10 -4
- package/dist/commands/liberica/suppliers/update.js.map +1 -1
- package/dist/commands/liberica/work-orders/create.js +2 -2
- package/dist/commands/liberica/work-orders/create.js.map +1 -1
- package/dist/core/api/client.d.ts +3 -0
- package/dist/core/api/client.d.ts.map +1 -1
- package/dist/core/api/client.js +59 -0
- package/dist/core/api/client.js.map +1 -1
- package/dist/types/aps.d.ts +2 -1
- package/dist/types/aps.d.ts.map +1 -1
- package/dist/types/bom.d.ts +4 -4
- package/dist/types/material-return.d.ts +1 -0
- package/dist/types/material-return.d.ts.map +1 -1
- package/dist/types/mould-stock-in.d.ts +1 -1
- package/dist/types/outsourcing-order.d.ts +36 -0
- package/dist/types/outsourcing-order.d.ts.map +1 -1
- package/dist/types/outsourcing-order.js +1 -0
- package/dist/types/outsourcing-order.js.map +1 -1
- package/dist/types/plan-order.d.ts +4 -2
- package/dist/types/plan-order.d.ts.map +1 -1
- package/dist/types/quotation.d.ts +1 -0
- package/dist/types/quotation.d.ts.map +1 -1
- package/dist/types/routing.d.ts +4 -4
- package/dist/types/sales-order.d.ts +3 -0
- package/dist/types/sales-order.d.ts.map +1 -1
- package/dist/types/supplier-price.d.ts +3 -3
- package/dist/types/supplier-price.d.ts.map +1 -1
- package/dist/types/supplier.d.ts +7 -1
- package/dist/types/supplier.d.ts.map +1 -1
- package/dist/types/work-order.d.ts +1 -1
- package/dist/types/work-order.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/barista-cli/SKILL.md +193 -193
- package/skills/barista-cli/data/commands.json +7 -2
- package/skills/barista-cli/data/commands.yaml +5 -2
- package/skills/barista-cli/scripts/search.py +194 -194
- package/skills/barista-cli/skill.json +17 -17
|
@@ -1,194 +1,194 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
search.py — Barista CLI 意图搜索
|
|
4
|
-
|
|
5
|
-
AI agent 通过此脚本根据用户意图查询相关命令。
|
|
6
|
-
SKILL.md 指导 AI 在需要查找命令时调用此脚本。
|
|
7
|
-
|
|
8
|
-
用法:
|
|
9
|
-
python3 search.py "<query>" [--domain <domain>] [--format text|json] [--max N]
|
|
10
|
-
|
|
11
|
-
示例:
|
|
12
|
-
python3 search.py "采购订单"
|
|
13
|
-
python3 search.py "创建入库单" --domain liberica
|
|
14
|
-
python3 search.py "subscription" --domain arabica
|
|
15
|
-
python3 search.py "invoice" --domain arabica.invoices
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
import sys
|
|
19
|
-
import json
|
|
20
|
-
import argparse
|
|
21
|
-
from pathlib import Path
|
|
22
|
-
from typing import Any
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def load_data() -> dict[str, Any]:
|
|
26
|
-
"""Load commands data from JSON or YAML file."""
|
|
27
|
-
script_dir = Path(__file__).resolve().parent
|
|
28
|
-
data_dir = script_dir.parent / "data"
|
|
29
|
-
|
|
30
|
-
json_path = data_dir / "commands.json"
|
|
31
|
-
yaml_path = data_dir / "commands.yaml"
|
|
32
|
-
|
|
33
|
-
if json_path.exists():
|
|
34
|
-
with open(json_path, "r", encoding="utf-8") as f:
|
|
35
|
-
return json.load(f)
|
|
36
|
-
|
|
37
|
-
if yaml_path.exists():
|
|
38
|
-
try:
|
|
39
|
-
import yaml as yaml_lib
|
|
40
|
-
with open(yaml_path, "r", encoding="utf-8") as f:
|
|
41
|
-
return yaml_lib.safe_load(f)
|
|
42
|
-
except ImportError:
|
|
43
|
-
# Fallback: parse YAML lines manually (basic)
|
|
44
|
-
return fallback_to_json(yaml_path)
|
|
45
|
-
|
|
46
|
-
sys.stderr.write("❌ No commands data found. Run 'npm run generate-skills-data' first.\n")
|
|
47
|
-
sys.exit(1)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def fallback_to_json(yaml_path: Path) -> dict[str, Any]:
|
|
51
|
-
"""Fallback to JSON when PyYAML is not installed."""
|
|
52
|
-
sys.stderr.write("⚠️ PyYAML not installed. Install with: pip install pyyaml\n")
|
|
53
|
-
sys.stderr.write(" Falling back to JSON format (if available).\n")
|
|
54
|
-
json_path = yaml_path.with_suffix(".json")
|
|
55
|
-
if json_path.exists():
|
|
56
|
-
with open(json_path, "r", encoding="utf-8") as f:
|
|
57
|
-
return json.load(f)
|
|
58
|
-
return {"global": {}, "liberica": {}, "arabica": {}}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def flatten_commands(data: dict[str, Any]) -> list[dict[str, Any]]:
|
|
62
|
-
"""Flatten nested command structure into a searchable list."""
|
|
63
|
-
results = []
|
|
64
|
-
for service in ["global", "liberica", "arabica"]:
|
|
65
|
-
svc_data = data.get(service, {})
|
|
66
|
-
for module_name, module in svc_data.items():
|
|
67
|
-
group = module.get("group", "")
|
|
68
|
-
for cmd_name, cmd in module.get("commands", {}).items():
|
|
69
|
-
desc = cmd.get("description", "")
|
|
70
|
-
options = cmd.get("options", [])
|
|
71
|
-
results.append({
|
|
72
|
-
"service": service,
|
|
73
|
-
"module": module_name,
|
|
74
|
-
"group": group,
|
|
75
|
-
"action": cmd_name,
|
|
76
|
-
"description": desc,
|
|
77
|
-
"options": options,
|
|
78
|
-
# For relevance scoring
|
|
79
|
-
"keywords": f"{module_name} {cmd_name} {group} {desc} {service}".lower(),
|
|
80
|
-
})
|
|
81
|
-
return results
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def search(flat: list[dict[str, Any]], query: str, domain: str = "", max_results: int = 10) -> list[dict[str, Any]]:
|
|
85
|
-
"""Search commands by keyword matching with relevance scoring."""
|
|
86
|
-
query_lower = query.lower()
|
|
87
|
-
query_words = [w for w in query_lower.split() if len(w) > 1]
|
|
88
|
-
|
|
89
|
-
if not query_words:
|
|
90
|
-
return []
|
|
91
|
-
|
|
92
|
-
scored = []
|
|
93
|
-
for cmd in flat:
|
|
94
|
-
# Domain filter
|
|
95
|
-
if domain:
|
|
96
|
-
domain_lower = domain.lower()
|
|
97
|
-
if domain_lower == "liberica" and cmd["service"] != "liberica":
|
|
98
|
-
continue
|
|
99
|
-
if domain_lower == "arabica" and cmd["service"] != "arabica":
|
|
100
|
-
continue
|
|
101
|
-
if domain_lower.startswith("liberica."):
|
|
102
|
-
mod = domain_lower[len("liberica."):]
|
|
103
|
-
if cmd["module"] != mod and not cmd["module"].startswith(mod + "/"):
|
|
104
|
-
continue
|
|
105
|
-
if domain_lower.startswith("arabica."):
|
|
106
|
-
mod = domain_lower[len("arabica."):]
|
|
107
|
-
if cmd["module"] != mod:
|
|
108
|
-
continue
|
|
109
|
-
|
|
110
|
-
# Relevance scoring
|
|
111
|
-
keywords = cmd["keywords"]
|
|
112
|
-
score = 0
|
|
113
|
-
matched_words = []
|
|
114
|
-
|
|
115
|
-
for word in query_words:
|
|
116
|
-
if word in keywords:
|
|
117
|
-
score += 3
|
|
118
|
-
matched_words.append(word)
|
|
119
|
-
# Partial match (substring)
|
|
120
|
-
elif any(word in kw_part for kw_part in keywords.split()):
|
|
121
|
-
score += 1
|
|
122
|
-
matched_words.append(word)
|
|
123
|
-
|
|
124
|
-
# Boost exact module match
|
|
125
|
-
if query_lower == cmd["module"]:
|
|
126
|
-
score += 5
|
|
127
|
-
if query_lower == cmd["action"]:
|
|
128
|
-
score += 3
|
|
129
|
-
# Boost description match priority
|
|
130
|
-
if any(w in cmd["description"].lower() for w in query_words):
|
|
131
|
-
score += 2
|
|
132
|
-
|
|
133
|
-
if score > 0:
|
|
134
|
-
scored.append((score, cmd))
|
|
135
|
-
|
|
136
|
-
# Sort by score descending
|
|
137
|
-
scored.sort(key=lambda x: -x[0])
|
|
138
|
-
return [cmd for _, cmd in scored[:max_results]]
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
def format_text(results: list[dict[str, Any]]) -> str:
|
|
142
|
-
"""Format results as human-readable text."""
|
|
143
|
-
if not results:
|
|
144
|
-
return "No matching commands found."
|
|
145
|
-
|
|
146
|
-
lines = []
|
|
147
|
-
last_service = ""
|
|
148
|
-
last_group = ""
|
|
149
|
-
|
|
150
|
-
for r in results:
|
|
151
|
-
if r["service"] != last_service:
|
|
152
|
-
lines.append(f"[{r['service'].upper()}]")
|
|
153
|
-
last_service = r["service"]
|
|
154
|
-
last_group = ""
|
|
155
|
-
|
|
156
|
-
if r["group"] != last_group:
|
|
157
|
-
lines.append(f" {r['group']}:")
|
|
158
|
-
last_group = r["group"]
|
|
159
|
-
|
|
160
|
-
opts = ""
|
|
161
|
-
if r["options"]:
|
|
162
|
-
opts = " [" + ", ".join(str(o) for o in r["options"]) + "]"
|
|
163
|
-
desc = f" — {r['description']}" if r["description"] else ""
|
|
164
|
-
lines.append(f" barista {r['service']} {r['module']} {r['action']}{opts}{desc}")
|
|
165
|
-
|
|
166
|
-
lines.append("")
|
|
167
|
-
lines.append(f"({len(results)} commands found)")
|
|
168
|
-
return "\n".join(lines)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def main():
|
|
172
|
-
parser = argparse.ArgumentParser(description="Barista CLI command search")
|
|
173
|
-
parser.add_argument("query", help="Search query (user intent)")
|
|
174
|
-
parser.add_argument("--domain", default="",
|
|
175
|
-
help="Filter by domain (liberica, arabica, liberica.purchase-orders, etc.)")
|
|
176
|
-
parser.add_argument("--format", choices=["text", "json"], default="text",
|
|
177
|
-
help="Output format")
|
|
178
|
-
parser.add_argument("--max", type=int, default=10,
|
|
179
|
-
help="Maximum results (default: 10)")
|
|
180
|
-
|
|
181
|
-
args = parser.parse_args()
|
|
182
|
-
|
|
183
|
-
data = load_data()
|
|
184
|
-
flat = flatten_commands(data)
|
|
185
|
-
results = search(flat, args.query, args.domain, args.max)
|
|
186
|
-
|
|
187
|
-
if args.format == "json":
|
|
188
|
-
print(json.dumps({"success": True, "data": {"items": results}}, indent=2, ensure_ascii=False))
|
|
189
|
-
else:
|
|
190
|
-
print(format_text(results))
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if __name__ == "__main__":
|
|
194
|
-
main()
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
search.py — Barista CLI 意图搜索
|
|
4
|
+
|
|
5
|
+
AI agent 通过此脚本根据用户意图查询相关命令。
|
|
6
|
+
SKILL.md 指导 AI 在需要查找命令时调用此脚本。
|
|
7
|
+
|
|
8
|
+
用法:
|
|
9
|
+
python3 search.py "<query>" [--domain <domain>] [--format text|json] [--max N]
|
|
10
|
+
|
|
11
|
+
示例:
|
|
12
|
+
python3 search.py "采购订单"
|
|
13
|
+
python3 search.py "创建入库单" --domain liberica
|
|
14
|
+
python3 search.py "subscription" --domain arabica
|
|
15
|
+
python3 search.py "invoice" --domain arabica.invoices
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
import json
|
|
20
|
+
import argparse
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_data() -> dict[str, Any]:
|
|
26
|
+
"""Load commands data from JSON or YAML file."""
|
|
27
|
+
script_dir = Path(__file__).resolve().parent
|
|
28
|
+
data_dir = script_dir.parent / "data"
|
|
29
|
+
|
|
30
|
+
json_path = data_dir / "commands.json"
|
|
31
|
+
yaml_path = data_dir / "commands.yaml"
|
|
32
|
+
|
|
33
|
+
if json_path.exists():
|
|
34
|
+
with open(json_path, "r", encoding="utf-8") as f:
|
|
35
|
+
return json.load(f)
|
|
36
|
+
|
|
37
|
+
if yaml_path.exists():
|
|
38
|
+
try:
|
|
39
|
+
import yaml as yaml_lib
|
|
40
|
+
with open(yaml_path, "r", encoding="utf-8") as f:
|
|
41
|
+
return yaml_lib.safe_load(f)
|
|
42
|
+
except ImportError:
|
|
43
|
+
# Fallback: parse YAML lines manually (basic)
|
|
44
|
+
return fallback_to_json(yaml_path)
|
|
45
|
+
|
|
46
|
+
sys.stderr.write("❌ No commands data found. Run 'npm run generate-skills-data' first.\n")
|
|
47
|
+
sys.exit(1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def fallback_to_json(yaml_path: Path) -> dict[str, Any]:
|
|
51
|
+
"""Fallback to JSON when PyYAML is not installed."""
|
|
52
|
+
sys.stderr.write("⚠️ PyYAML not installed. Install with: pip install pyyaml\n")
|
|
53
|
+
sys.stderr.write(" Falling back to JSON format (if available).\n")
|
|
54
|
+
json_path = yaml_path.with_suffix(".json")
|
|
55
|
+
if json_path.exists():
|
|
56
|
+
with open(json_path, "r", encoding="utf-8") as f:
|
|
57
|
+
return json.load(f)
|
|
58
|
+
return {"global": {}, "liberica": {}, "arabica": {}}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def flatten_commands(data: dict[str, Any]) -> list[dict[str, Any]]:
|
|
62
|
+
"""Flatten nested command structure into a searchable list."""
|
|
63
|
+
results = []
|
|
64
|
+
for service in ["global", "liberica", "arabica"]:
|
|
65
|
+
svc_data = data.get(service, {})
|
|
66
|
+
for module_name, module in svc_data.items():
|
|
67
|
+
group = module.get("group", "")
|
|
68
|
+
for cmd_name, cmd in module.get("commands", {}).items():
|
|
69
|
+
desc = cmd.get("description", "")
|
|
70
|
+
options = cmd.get("options", [])
|
|
71
|
+
results.append({
|
|
72
|
+
"service": service,
|
|
73
|
+
"module": module_name,
|
|
74
|
+
"group": group,
|
|
75
|
+
"action": cmd_name,
|
|
76
|
+
"description": desc,
|
|
77
|
+
"options": options,
|
|
78
|
+
# For relevance scoring
|
|
79
|
+
"keywords": f"{module_name} {cmd_name} {group} {desc} {service}".lower(),
|
|
80
|
+
})
|
|
81
|
+
return results
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def search(flat: list[dict[str, Any]], query: str, domain: str = "", max_results: int = 10) -> list[dict[str, Any]]:
|
|
85
|
+
"""Search commands by keyword matching with relevance scoring."""
|
|
86
|
+
query_lower = query.lower()
|
|
87
|
+
query_words = [w for w in query_lower.split() if len(w) > 1]
|
|
88
|
+
|
|
89
|
+
if not query_words:
|
|
90
|
+
return []
|
|
91
|
+
|
|
92
|
+
scored = []
|
|
93
|
+
for cmd in flat:
|
|
94
|
+
# Domain filter
|
|
95
|
+
if domain:
|
|
96
|
+
domain_lower = domain.lower()
|
|
97
|
+
if domain_lower == "liberica" and cmd["service"] != "liberica":
|
|
98
|
+
continue
|
|
99
|
+
if domain_lower == "arabica" and cmd["service"] != "arabica":
|
|
100
|
+
continue
|
|
101
|
+
if domain_lower.startswith("liberica."):
|
|
102
|
+
mod = domain_lower[len("liberica."):]
|
|
103
|
+
if cmd["module"] != mod and not cmd["module"].startswith(mod + "/"):
|
|
104
|
+
continue
|
|
105
|
+
if domain_lower.startswith("arabica."):
|
|
106
|
+
mod = domain_lower[len("arabica."):]
|
|
107
|
+
if cmd["module"] != mod:
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
# Relevance scoring
|
|
111
|
+
keywords = cmd["keywords"]
|
|
112
|
+
score = 0
|
|
113
|
+
matched_words = []
|
|
114
|
+
|
|
115
|
+
for word in query_words:
|
|
116
|
+
if word in keywords:
|
|
117
|
+
score += 3
|
|
118
|
+
matched_words.append(word)
|
|
119
|
+
# Partial match (substring)
|
|
120
|
+
elif any(word in kw_part for kw_part in keywords.split()):
|
|
121
|
+
score += 1
|
|
122
|
+
matched_words.append(word)
|
|
123
|
+
|
|
124
|
+
# Boost exact module match
|
|
125
|
+
if query_lower == cmd["module"]:
|
|
126
|
+
score += 5
|
|
127
|
+
if query_lower == cmd["action"]:
|
|
128
|
+
score += 3
|
|
129
|
+
# Boost description match priority
|
|
130
|
+
if any(w in cmd["description"].lower() for w in query_words):
|
|
131
|
+
score += 2
|
|
132
|
+
|
|
133
|
+
if score > 0:
|
|
134
|
+
scored.append((score, cmd))
|
|
135
|
+
|
|
136
|
+
# Sort by score descending
|
|
137
|
+
scored.sort(key=lambda x: -x[0])
|
|
138
|
+
return [cmd for _, cmd in scored[:max_results]]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def format_text(results: list[dict[str, Any]]) -> str:
|
|
142
|
+
"""Format results as human-readable text."""
|
|
143
|
+
if not results:
|
|
144
|
+
return "No matching commands found."
|
|
145
|
+
|
|
146
|
+
lines = []
|
|
147
|
+
last_service = ""
|
|
148
|
+
last_group = ""
|
|
149
|
+
|
|
150
|
+
for r in results:
|
|
151
|
+
if r["service"] != last_service:
|
|
152
|
+
lines.append(f"[{r['service'].upper()}]")
|
|
153
|
+
last_service = r["service"]
|
|
154
|
+
last_group = ""
|
|
155
|
+
|
|
156
|
+
if r["group"] != last_group:
|
|
157
|
+
lines.append(f" {r['group']}:")
|
|
158
|
+
last_group = r["group"]
|
|
159
|
+
|
|
160
|
+
opts = ""
|
|
161
|
+
if r["options"]:
|
|
162
|
+
opts = " [" + ", ".join(str(o) for o in r["options"]) + "]"
|
|
163
|
+
desc = f" — {r['description']}" if r["description"] else ""
|
|
164
|
+
lines.append(f" barista {r['service']} {r['module']} {r['action']}{opts}{desc}")
|
|
165
|
+
|
|
166
|
+
lines.append("")
|
|
167
|
+
lines.append(f"({len(results)} commands found)")
|
|
168
|
+
return "\n".join(lines)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def main():
|
|
172
|
+
parser = argparse.ArgumentParser(description="Barista CLI command search")
|
|
173
|
+
parser.add_argument("query", help="Search query (user intent)")
|
|
174
|
+
parser.add_argument("--domain", default="",
|
|
175
|
+
help="Filter by domain (liberica, arabica, liberica.purchase-orders, etc.)")
|
|
176
|
+
parser.add_argument("--format", choices=["text", "json"], default="text",
|
|
177
|
+
help="Output format")
|
|
178
|
+
parser.add_argument("--max", type=int, default=10,
|
|
179
|
+
help="Maximum results (default: 10)")
|
|
180
|
+
|
|
181
|
+
args = parser.parse_args()
|
|
182
|
+
|
|
183
|
+
data = load_data()
|
|
184
|
+
flat = flatten_commands(data)
|
|
185
|
+
results = search(flat, args.query, args.domain, args.max)
|
|
186
|
+
|
|
187
|
+
if args.format == "json":
|
|
188
|
+
print(json.dumps({"success": True, "data": {"items": results}}, indent=2, ensure_ascii=False))
|
|
189
|
+
else:
|
|
190
|
+
print(format_text(results))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
if __name__ == "__main__":
|
|
194
|
+
main()
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "barista-cli",
|
|
3
|
-
"displayName": "Barista CLI",
|
|
4
|
-
"version": "0.1.0",
|
|
5
|
-
"description": "AI agent skill for operating Barista CLI — bridge AI assistants to Liberica production management SaaS and Arabica subscription platform. Covers 70+ Liberica modules (employees, materials, inventory, production, BOM, quality, finance, HR, teams) and 7 Arabica modules (plans, subscription, orders, invoices, enterprises).",
|
|
6
|
-
"author": "Newpeak Technology",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"homepage": "https://gitlab.newpeaksh.com/coffee/coffee-barista-cli",
|
|
9
|
-
"repository": "https://gitlab.newpeaksh.com/coffee/coffee-barista-cli.git",
|
|
10
|
-
"platforms": ["claude", "cursor", "windsurf", "copilot", "kiro", "roocode", "codex", "qoder", "gemini", "trae", "opencode", "continue", "droid"],
|
|
11
|
-
"install": "npx @newpeak/barista-cli skills install --ai {{platform}}",
|
|
12
|
-
"keywords": ["barista", "cli", "liberica", "arabica", "production-management", "saas", "erp", "enterprise"],
|
|
13
|
-
"metadata": {
|
|
14
|
-
"dataSource": "auto-generated from src/commands/",
|
|
15
|
-
"search": "barista skills query <intent> or python3 scripts/search.py"
|
|
16
|
-
}
|
|
17
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "barista-cli",
|
|
3
|
+
"displayName": "Barista CLI",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "AI agent skill for operating Barista CLI — bridge AI assistants to Liberica production management SaaS and Arabica subscription platform. Covers 70+ Liberica modules (employees, materials, inventory, production, BOM, quality, finance, HR, teams) and 7 Arabica modules (plans, subscription, orders, invoices, enterprises).",
|
|
6
|
+
"author": "Newpeak Technology",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://gitlab.newpeaksh.com/coffee/coffee-barista-cli",
|
|
9
|
+
"repository": "https://gitlab.newpeaksh.com/coffee/coffee-barista-cli.git",
|
|
10
|
+
"platforms": ["claude", "cursor", "windsurf", "copilot", "kiro", "roocode", "codex", "qoder", "gemini", "trae", "opencode", "continue", "droid"],
|
|
11
|
+
"install": "npx @newpeak/barista-cli skills install --ai {{platform}}",
|
|
12
|
+
"keywords": ["barista", "cli", "liberica", "arabica", "production-management", "saas", "erp", "enterprise"],
|
|
13
|
+
"metadata": {
|
|
14
|
+
"dataSource": "auto-generated from src/commands/",
|
|
15
|
+
"search": "barista skills query <intent> or python3 scripts/search.py"
|
|
16
|
+
}
|
|
17
|
+
}
|