@0dai-dev/cli 4.3.5 → 4.3.7
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 +12 -11
- package/bin/0dai.js +214 -40
- package/lib/ai/manifest/mcp-exposure-contract.json +121 -0
- package/lib/ai/meta/manifest/mcp-tool-tiers.json +435 -0
- package/lib/ai/registry/mcp-catalog.json +98 -0
- package/lib/commands/auth.js +55 -1
- package/lib/commands/compliance.js +1 -1
- package/lib/commands/detect.js +10 -4
- package/lib/commands/doctor.js +545 -26
- package/lib/commands/experience.js +40 -5
- package/lib/commands/export.js +73 -0
- package/lib/commands/feedback.js +157 -15
- package/lib/commands/gh.js +26 -0
- package/lib/commands/graph.js +9 -4
- package/lib/commands/heatmap.js +1 -1
- package/lib/commands/init.js +222 -30
- package/lib/commands/mcp.js +129 -21
- package/lib/commands/models.js +138 -41
- package/lib/commands/provider.js +30 -59
- package/lib/commands/quota.js +1 -1
- package/lib/commands/receipt.js +1 -1
- package/lib/commands/run.js +18 -7
- package/lib/commands/runner.js +31 -1
- package/lib/commands/status.js +44 -11
- package/lib/commands/swarm.js +130 -12
- package/lib/commands/trust.js +286 -0
- package/lib/commands/update.js +184 -38
- package/lib/commands/usage.js +1 -1
- package/lib/commands/validate.js +32 -3
- package/lib/commands/vault.js +46 -9
- package/lib/python/__init__.py +0 -0
- package/lib/python/agent_quotas.py +525 -0
- package/lib/python/anomaly_alert.py +397 -0
- package/lib/python/anti_pattern_detector.py +799 -0
- package/lib/python/auth.py +443 -0
- package/lib/python/capi_profile_guard.py +477 -0
- package/lib/python/compliance_report.py +581 -0
- package/lib/python/drift_detector.py +388 -0
- package/lib/python/experience_pipeline.py +1130 -0
- package/lib/python/graph.py +19 -0
- package/lib/python/graph_core.py +293 -0
- package/lib/python/graph_io.py +179 -0
- package/lib/python/graph_legacy.py +2052 -0
- package/lib/python/graph_legacy_helpers.py +221 -0
- package/lib/python/graph_outcomes_core.py +85 -0
- package/lib/python/graph_queries.py +171 -0
- package/lib/python/graph_slice.py +198 -0
- package/lib/python/graph_slicer.py +576 -0
- package/lib/python/graph_slicer_cli.py +60 -0
- package/lib/python/graph_validation.py +64 -0
- package/lib/python/heatmap.py +934 -0
- package/lib/python/json_utils.py +193 -0
- package/lib/python/mcp_exposure_check.py +247 -0
- package/lib/python/model_router.py +1434 -0
- package/lib/python/project_manager.py +621 -0
- package/lib/python/provider_profiles.py +1618 -0
- package/lib/python/provider_registry.py +1211 -0
- package/lib/python/provider_registry_cli.py +125 -0
- package/lib/python/receipt_png.py +727 -0
- package/lib/python/structural_memory.py +325 -0
- package/lib/python/swarm_cost.py +177 -0
- package/lib/python/usage_ledger.py +569 -0
- package/lib/scripts/mcp_tier_config.py +240 -0
- package/lib/shared.js +97 -14
- package/lib/tui/index.mjs +35174 -0
- package/lib/utils/activation_telemetry.js +230 -11
- package/lib/utils/constants.js +7 -1
- package/lib/utils/export-bundler.js +285 -0
- package/lib/utils/identity.js +198 -1
- package/lib/utils/mcp-auth.js +81 -15
- package/lib/utils/plan.js +1 -1
- package/lib/vault/index.js +19 -3
- package/lib/vault/storage.js +21 -2
- package/lib/wizard.js +5 -2
- package/package.json +9 -3
- package/scripts/build-python-bundle.js +106 -0
- package/scripts/build-tui.js +14 -1
- package/scripts/harvest_experience.py +523 -0
- package/scripts/postinstall.js +15 -9
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""CLI wrapper for local BYOK provider registry list/switch/clear commands."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import pathlib
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import provider_registry as pr
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _provider_row(row: dict[str, Any]) -> dict[str, Any]:
|
|
15
|
+
"""Return only non-secret provider metadata for CLI output."""
|
|
16
|
+
return {
|
|
17
|
+
"name": str(row.get("name") or ""),
|
|
18
|
+
"endpoint_kind": str(row.get("endpoint_kind") or ""),
|
|
19
|
+
"base_url": str(row.get("base_url") or ""),
|
|
20
|
+
"has_credentials": bool(row.get("has_credentials")),
|
|
21
|
+
"source": str(row.get("source") or ""),
|
|
22
|
+
"active": bool(row.get("active")),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _profile_payload(profile: dict[str, Any]) -> dict[str, Any]:
|
|
27
|
+
"""Return a switch result without raw provider secret material."""
|
|
28
|
+
return {
|
|
29
|
+
"provider_name": str(profile.get("provider_name") or ""),
|
|
30
|
+
"base_url": str(profile.get("base_url") or ""),
|
|
31
|
+
"api_key_ref": str(profile.get("api_key_ref") or ""),
|
|
32
|
+
"model": str(profile.get("model") or ""),
|
|
33
|
+
"updated_at": str(profile.get("updated_at") or ""),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _print_json(payload: dict[str, Any]) -> None:
|
|
38
|
+
print(json.dumps(payload, sort_keys=True))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _cmd_list(args: argparse.Namespace) -> int:
|
|
42
|
+
target = pathlib.Path(args.target).resolve()
|
|
43
|
+
providers = [_provider_row(row) for row in pr.list_providers_for_repo(target)]
|
|
44
|
+
if args.json:
|
|
45
|
+
_print_json({"target": str(target), "providers": providers})
|
|
46
|
+
return 0
|
|
47
|
+
|
|
48
|
+
print(f"Provider Status for {target.name}")
|
|
49
|
+
print("=" * 60)
|
|
50
|
+
for row in providers:
|
|
51
|
+
active = "->" if row["active"] else " "
|
|
52
|
+
source = f"[{row['source']}]" if row["source"] else ""
|
|
53
|
+
creds = "yes" if row["has_credentials"] else "no"
|
|
54
|
+
print(f" {active} {row['name']:<12} creds={creds:<3} {source:<10} {row['base_url']}")
|
|
55
|
+
print("")
|
|
56
|
+
return 0
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _cmd_switch(args: argparse.Namespace) -> int:
|
|
60
|
+
target = pathlib.Path(args.target).resolve()
|
|
61
|
+
profile = _profile_payload(pr.switch_provider(target, args.provider))
|
|
62
|
+
if args.json:
|
|
63
|
+
_print_json({"target": str(target), "switched": True, "profile": profile})
|
|
64
|
+
return 0
|
|
65
|
+
|
|
66
|
+
print(f"Switched {target.name} to provider: {profile['provider_name']}")
|
|
67
|
+
print(f" base_url: {profile['base_url']}")
|
|
68
|
+
print(" audit log: ~/.0dai/audit/provider-changes.jsonl")
|
|
69
|
+
return 0
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _cmd_clear(args: argparse.Namespace) -> int:
|
|
73
|
+
target = pathlib.Path(args.target).resolve()
|
|
74
|
+
cleared = pr.clear_repo_profile(target)
|
|
75
|
+
if args.json:
|
|
76
|
+
_print_json({"target": str(target), "cleared": bool(cleared)})
|
|
77
|
+
return 0
|
|
78
|
+
|
|
79
|
+
if cleared:
|
|
80
|
+
print(f"Cleared per-repo profile for {target.name}")
|
|
81
|
+
print("Will fall back to global default or env vars")
|
|
82
|
+
else:
|
|
83
|
+
print(f"No per-repo profile to clear for {target.name}")
|
|
84
|
+
return 0
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
88
|
+
common = argparse.ArgumentParser(add_help=False)
|
|
89
|
+
common.add_argument("--target", default=".", help="project directory")
|
|
90
|
+
common.add_argument("--json", action="store_true", help="emit JSON")
|
|
91
|
+
|
|
92
|
+
parser = argparse.ArgumentParser(
|
|
93
|
+
description="Manage local provider registry profiles",
|
|
94
|
+
parents=[common],
|
|
95
|
+
)
|
|
96
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
97
|
+
|
|
98
|
+
list_cmd = sub.add_parser("list", parents=[common], help="list configured provider availability")
|
|
99
|
+
list_cmd.set_defaults(func=_cmd_list)
|
|
100
|
+
|
|
101
|
+
switch_cmd = sub.add_parser("switch", parents=[common], help="switch this project to a provider")
|
|
102
|
+
switch_cmd.add_argument("--provider", required=True, help="provider name")
|
|
103
|
+
switch_cmd.set_defaults(func=_cmd_switch)
|
|
104
|
+
|
|
105
|
+
clear_cmd = sub.add_parser("clear", parents=[common], help="clear this project's provider override")
|
|
106
|
+
clear_cmd.set_defaults(func=_cmd_clear)
|
|
107
|
+
|
|
108
|
+
return parser
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def main(argv: list[str] | None = None) -> int:
|
|
112
|
+
parser = build_parser()
|
|
113
|
+
args = parser.parse_args(argv)
|
|
114
|
+
try:
|
|
115
|
+
return int(args.func(args) or 0)
|
|
116
|
+
except pr.ProviderRegistryError as exc:
|
|
117
|
+
if getattr(args, "json", False):
|
|
118
|
+
_print_json({"error": str(exc)})
|
|
119
|
+
else:
|
|
120
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
121
|
+
return 1
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
raise SystemExit(main())
|