cortexdb-cli 0.5.4__tar.gz → 0.6.0__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.
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/PKG-INFO +1 -1
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/__init__.py +3 -3
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/__init__.py +1 -1
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/auth.py +38 -5
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/config_cmd.py +50 -50
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/errors.py +96 -96
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/pyproject.toml +56 -56
- cortexdb_cli-0.5.4/.gitignore +0 -109
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/README.md +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/client.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/admin.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/answer.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/audit.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/beliefs.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/claims.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/code.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/compose.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/conflicts.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/entities.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/episodes.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/experience.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/export_cmd.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/facts.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/forget.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/import_cmd.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/init.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/interactive.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/onboard.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/policy.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/recall.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/scopes.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/search.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/understanding.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/commands/wire.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/config.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/harness_packs_data.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/main.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/onboarding.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/output.py +0 -0
- {cortexdb_cli-0.5.4 → cortexdb_cli-0.6.0}/cortexdb_cli/state.py +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""CortexDB CLI - command-line interface for the v1 memory API."""
|
|
2
|
-
|
|
3
|
-
__version__ = "0.
|
|
1
|
+
"""CortexDB CLI - command-line interface for the v1 memory API."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.6.0"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"""CortexDB CLI command modules."""
|
|
1
|
+
"""CortexDB CLI command modules."""
|
|
@@ -83,11 +83,29 @@ def auth_signup(ctx: click.Context, endpoint: str, save_state_flag: bool) -> Non
|
|
|
83
83
|
show_default=True,
|
|
84
84
|
help="Token lifetime in seconds (server enforces a tenant ceiling).",
|
|
85
85
|
)
|
|
86
|
-
@click.option(
|
|
86
|
+
@click.option(
|
|
87
|
+
"--scope",
|
|
88
|
+
"scope",
|
|
89
|
+
default=None,
|
|
90
|
+
help="Scope path where YOUR auth.mint is checked (omit for a deployment-wide "
|
|
91
|
+
"check). Does not confine the minted token - use --confine.",
|
|
92
|
+
)
|
|
93
|
+
@click.option(
|
|
94
|
+
"--confine",
|
|
95
|
+
"confine",
|
|
96
|
+
multiple=True,
|
|
97
|
+
metavar="CAP:PREFIX",
|
|
98
|
+
help="Confine a capability (or capability prefix) to a scope subtree, e.g. "
|
|
99
|
+
"scope.read:org:acme/team:b/* - repeat for multiple. Sent as the `scopes` claim.",
|
|
100
|
+
)
|
|
87
101
|
@click.pass_context
|
|
88
102
|
@handle_errors
|
|
89
103
|
def auth_tokens(
|
|
90
|
-
ctx: click.Context,
|
|
104
|
+
ctx: click.Context,
|
|
105
|
+
subject: str,
|
|
106
|
+
ttl_seconds: int,
|
|
107
|
+
scope: str | None,
|
|
108
|
+
confine: tuple[str, ...],
|
|
91
109
|
) -> None:
|
|
92
110
|
"""POST /v1/auth/tokens - mint a service-account token.
|
|
93
111
|
|
|
@@ -95,12 +113,27 @@ def auth_tokens(
|
|
|
95
113
|
have it - you must hold an IdP-issued token (or a token previously
|
|
96
114
|
minted by an account that does).
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
--scope only says where your auth.mint is evaluated. The token is
|
|
117
|
+
confined only by --confine entries (CAP:PREFIX); the server rejects an
|
|
118
|
+
entry whose capability part names no capability.
|
|
119
|
+
|
|
120
|
+
cortexdb auth tokens --subject agent:b --confine scope.read:org:acme/team:b/*
|
|
99
121
|
"""
|
|
122
|
+
# Before --confine existed, --scope carried `scopes` entries. A value
|
|
123
|
+
# that starts with a capability (dots before the first ':') is one of
|
|
124
|
+
# those, not a scope path; point at the right flag instead of letting
|
|
125
|
+
# the server 422 on the scope grammar.
|
|
126
|
+
if scope is not None and "." in scope.split(":", 1)[0]:
|
|
127
|
+
raise click.UsageError(
|
|
128
|
+
f"--scope {scope!r} looks like a CAP:PREFIX confinement entry; "
|
|
129
|
+
"pass it with --confine"
|
|
130
|
+
)
|
|
100
131
|
cfg = ctx.obj
|
|
101
132
|
body: dict[str, object] = {"subject": subject, "ttl_seconds": ttl_seconds}
|
|
102
|
-
if
|
|
103
|
-
body["
|
|
133
|
+
if scope is not None:
|
|
134
|
+
body["scope"] = scope
|
|
135
|
+
if confine:
|
|
136
|
+
body["scopes"] = list(confine)
|
|
104
137
|
with get_client(cfg) as client:
|
|
105
138
|
if not is_json_mode(cfg):
|
|
106
139
|
with spinner("Minting..."):
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
"""cortexdb config -- View and edit configuration."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import click
|
|
6
|
-
|
|
7
|
-
from cortexdb_cli.config import config_path, load_config, save_config
|
|
8
|
-
from cortexdb_cli.output import console, print_json, is_json_mode
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@click.group("config")
|
|
12
|
-
def config_group() -> None:
|
|
13
|
-
"""View and manage CLI configuration."""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@config_group.command("show")
|
|
17
|
-
@click.pass_context
|
|
18
|
-
def config_show(ctx: click.Context) -> None:
|
|
19
|
-
"""Show current configuration."""
|
|
20
|
-
cfg = load_config()
|
|
21
|
-
if is_json_mode(ctx.obj):
|
|
22
|
-
# Redact API key in JSON output
|
|
23
|
-
safe = dict(cfg)
|
|
24
|
-
if "api_key" in safe:
|
|
25
|
-
key = safe["api_key"]
|
|
26
|
-
safe["api_key"] = key[:8] + "..." + key[-4:] if len(key) > 12 else "***"
|
|
27
|
-
print_json(safe)
|
|
28
|
-
else:
|
|
29
|
-
console.print(f"[dim]Config file: {config_path()}[/dim]\n")
|
|
30
|
-
for k, v in cfg.items():
|
|
31
|
-
if k == "api_key" and v:
|
|
32
|
-
v = v[:8] + "..." + v[-4:] if len(v) > 12 else "***"
|
|
33
|
-
console.print(f" [bold]{k}[/bold] = {v}")
|
|
34
|
-
console.print()
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
@config_group.command("set")
|
|
38
|
-
@click.argument("key")
|
|
39
|
-
@click.argument("value")
|
|
40
|
-
def config_set(key: str, value: str) -> None:
|
|
41
|
-
"""Set a configuration value.
|
|
42
|
-
|
|
43
|
-
cortexdb config set api_key cx_live_...
|
|
44
|
-
|
|
45
|
-
cortexdb config set endpoint https://api-v1.cortexdb.ai
|
|
46
|
-
"""
|
|
47
|
-
cfg = load_config()
|
|
48
|
-
cfg[key] = value
|
|
49
|
-
save_config("default", cfg)
|
|
50
|
-
console.print(f"[success]Set {key}[/success]")
|
|
1
|
+
"""cortexdb config -- View and edit configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from cortexdb_cli.config import config_path, load_config, save_config
|
|
8
|
+
from cortexdb_cli.output import console, print_json, is_json_mode
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group("config")
|
|
12
|
+
def config_group() -> None:
|
|
13
|
+
"""View and manage CLI configuration."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@config_group.command("show")
|
|
17
|
+
@click.pass_context
|
|
18
|
+
def config_show(ctx: click.Context) -> None:
|
|
19
|
+
"""Show current configuration."""
|
|
20
|
+
cfg = load_config()
|
|
21
|
+
if is_json_mode(ctx.obj):
|
|
22
|
+
# Redact API key in JSON output
|
|
23
|
+
safe = dict(cfg)
|
|
24
|
+
if "api_key" in safe:
|
|
25
|
+
key = safe["api_key"]
|
|
26
|
+
safe["api_key"] = key[:8] + "..." + key[-4:] if len(key) > 12 else "***"
|
|
27
|
+
print_json(safe)
|
|
28
|
+
else:
|
|
29
|
+
console.print(f"[dim]Config file: {config_path()}[/dim]\n")
|
|
30
|
+
for k, v in cfg.items():
|
|
31
|
+
if k == "api_key" and v:
|
|
32
|
+
v = v[:8] + "..." + v[-4:] if len(v) > 12 else "***"
|
|
33
|
+
console.print(f" [bold]{k}[/bold] = {v}")
|
|
34
|
+
console.print()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@config_group.command("set")
|
|
38
|
+
@click.argument("key")
|
|
39
|
+
@click.argument("value")
|
|
40
|
+
def config_set(key: str, value: str) -> None:
|
|
41
|
+
"""Set a configuration value.
|
|
42
|
+
|
|
43
|
+
cortexdb config set api_key cx_live_...
|
|
44
|
+
|
|
45
|
+
cortexdb config set endpoint https://api-v1.cortexdb.ai
|
|
46
|
+
"""
|
|
47
|
+
cfg = load_config()
|
|
48
|
+
cfg[key] = value
|
|
49
|
+
save_config("default", cfg)
|
|
50
|
+
console.print(f"[success]Set {key}[/success]")
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
"""Error handling for CortexDB CLI commands."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import functools
|
|
6
|
-
import sys
|
|
7
|
-
from typing import Any, Callable
|
|
8
|
-
|
|
9
|
-
import click
|
|
10
|
-
import httpx
|
|
11
|
-
|
|
12
|
-
from cortexdb_cli.output import err_console
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def escape_safe(s: Any) -> str:
|
|
16
|
-
"""Rich-safe escape used in the error decorator (avoids circular imports)."""
|
|
17
|
-
from rich.markup import escape
|
|
18
|
-
|
|
19
|
-
return escape(str(s))
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def handle_errors(fn: Callable[..., Any]) -> Callable[..., Any]:
|
|
23
|
-
"""Decorator that catches common errors and prints friendly messages."""
|
|
24
|
-
|
|
25
|
-
@functools.wraps(fn)
|
|
26
|
-
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
27
|
-
try:
|
|
28
|
-
return fn(*args, **kwargs)
|
|
29
|
-
except httpx.HTTPStatusError as exc:
|
|
30
|
-
status = exc.response.status_code
|
|
31
|
-
body: dict[str, Any] = {}
|
|
32
|
-
try:
|
|
33
|
-
body = exc.response.json()
|
|
34
|
-
except Exception:
|
|
35
|
-
body = {}
|
|
36
|
-
code = body.get("error_code") or body.get("code") or ""
|
|
37
|
-
msg = body.get("message") or body.get("error") or exc.response.text[:200]
|
|
38
|
-
|
|
39
|
-
if status == 401:
|
|
40
|
-
if code in ("TOKEN_EXPIRED", "INVALID_TOKEN_SIGNATURE", "MISSING_TOKEN"):
|
|
41
|
-
err_console.print(
|
|
42
|
-
f"[error]Token rejected ({code}).[/error] "
|
|
43
|
-
"Run [bold]cortexdb init[/bold] to mint a fresh one."
|
|
44
|
-
)
|
|
45
|
-
elif code == "actor_mismatch":
|
|
46
|
-
err_console.print(
|
|
47
|
-
"[error]Actor mismatch.[/error] The X-Cortex-Actor header "
|
|
48
|
-
"doesn't match the token's subject. Re-run "
|
|
49
|
-
"[bold]cortexdb init[/bold] to re-bind."
|
|
50
|
-
)
|
|
51
|
-
else:
|
|
52
|
-
err_console.print(
|
|
53
|
-
f"[error]Authentication failed:[/error] {msg}\n"
|
|
54
|
-
"Run [bold]cortexdb init[/bold] to set up credentials."
|
|
55
|
-
)
|
|
56
|
-
elif status == 403:
|
|
57
|
-
# The v1 surface always cites the missing capability.
|
|
58
|
-
details = body.get("details") or {}
|
|
59
|
-
cap = details.get("capability") or ""
|
|
60
|
-
tier = details.get("decided_by_tier") or ""
|
|
61
|
-
if cap:
|
|
62
|
-
err_console.print(
|
|
63
|
-
f"[error]Denied by {escape_safe(tier)}:[/error] "
|
|
64
|
-
f"missing capability [bold]{escape_safe(cap)}[/bold]."
|
|
65
|
-
)
|
|
66
|
-
if cap == "diagnostics.read":
|
|
67
|
-
err_console.print(
|
|
68
|
-
"[dim]Hint: pass [bold]--diagnostics none[/bold] (free tier).[/dim]"
|
|
69
|
-
)
|
|
70
|
-
else:
|
|
71
|
-
err_console.print(f"[error]Forbidden:[/error] {msg}")
|
|
72
|
-
elif status == 429:
|
|
73
|
-
retry = exc.response.headers.get("Retry-After", "?")
|
|
74
|
-
err_console.print(f"[error]Rate limited.[/error] Retry after {retry}s.")
|
|
75
|
-
elif status == 402:
|
|
76
|
-
err_console.print(f"[warning]Feature not available on your tier.[/warning] {msg}")
|
|
77
|
-
else:
|
|
78
|
-
err_console.print(f"[error]API error (HTTP {status}, {code}):[/error] {msg}")
|
|
79
|
-
sys.exit(1)
|
|
80
|
-
except httpx.ConnectError:
|
|
81
|
-
err_console.print(
|
|
82
|
-
"[error]Cannot connect to CortexDB.[/error] "
|
|
83
|
-
"Check your endpoint and network."
|
|
84
|
-
)
|
|
85
|
-
sys.exit(2)
|
|
86
|
-
except httpx.TimeoutException:
|
|
87
|
-
err_console.print("[error]Request timed out.[/error]")
|
|
88
|
-
sys.exit(2)
|
|
89
|
-
except click.Abort:
|
|
90
|
-
err_console.print("\n[dim]Aborted.[/dim]")
|
|
91
|
-
sys.exit(130)
|
|
92
|
-
except KeyboardInterrupt:
|
|
93
|
-
err_console.print("\n[dim]Interrupted.[/dim]")
|
|
94
|
-
sys.exit(130)
|
|
95
|
-
|
|
96
|
-
return wrapper
|
|
1
|
+
"""Error handling for CortexDB CLI commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import functools
|
|
6
|
+
import sys
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
import httpx
|
|
11
|
+
|
|
12
|
+
from cortexdb_cli.output import err_console
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def escape_safe(s: Any) -> str:
|
|
16
|
+
"""Rich-safe escape used in the error decorator (avoids circular imports)."""
|
|
17
|
+
from rich.markup import escape
|
|
18
|
+
|
|
19
|
+
return escape(str(s))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def handle_errors(fn: Callable[..., Any]) -> Callable[..., Any]:
|
|
23
|
+
"""Decorator that catches common errors and prints friendly messages."""
|
|
24
|
+
|
|
25
|
+
@functools.wraps(fn)
|
|
26
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
27
|
+
try:
|
|
28
|
+
return fn(*args, **kwargs)
|
|
29
|
+
except httpx.HTTPStatusError as exc:
|
|
30
|
+
status = exc.response.status_code
|
|
31
|
+
body: dict[str, Any] = {}
|
|
32
|
+
try:
|
|
33
|
+
body = exc.response.json()
|
|
34
|
+
except Exception:
|
|
35
|
+
body = {}
|
|
36
|
+
code = body.get("error_code") or body.get("code") or ""
|
|
37
|
+
msg = body.get("message") or body.get("error") or exc.response.text[:200]
|
|
38
|
+
|
|
39
|
+
if status == 401:
|
|
40
|
+
if code in ("TOKEN_EXPIRED", "INVALID_TOKEN_SIGNATURE", "MISSING_TOKEN"):
|
|
41
|
+
err_console.print(
|
|
42
|
+
f"[error]Token rejected ({code}).[/error] "
|
|
43
|
+
"Run [bold]cortexdb init[/bold] to mint a fresh one."
|
|
44
|
+
)
|
|
45
|
+
elif code == "actor_mismatch":
|
|
46
|
+
err_console.print(
|
|
47
|
+
"[error]Actor mismatch.[/error] The X-Cortex-Actor header "
|
|
48
|
+
"doesn't match the token's subject. Re-run "
|
|
49
|
+
"[bold]cortexdb init[/bold] to re-bind."
|
|
50
|
+
)
|
|
51
|
+
else:
|
|
52
|
+
err_console.print(
|
|
53
|
+
f"[error]Authentication failed:[/error] {msg}\n"
|
|
54
|
+
"Run [bold]cortexdb init[/bold] to set up credentials."
|
|
55
|
+
)
|
|
56
|
+
elif status == 403:
|
|
57
|
+
# The v1 surface always cites the missing capability.
|
|
58
|
+
details = body.get("details") or {}
|
|
59
|
+
cap = details.get("capability") or ""
|
|
60
|
+
tier = details.get("decided_by_tier") or ""
|
|
61
|
+
if cap:
|
|
62
|
+
err_console.print(
|
|
63
|
+
f"[error]Denied by {escape_safe(tier)}:[/error] "
|
|
64
|
+
f"missing capability [bold]{escape_safe(cap)}[/bold]."
|
|
65
|
+
)
|
|
66
|
+
if cap == "diagnostics.read":
|
|
67
|
+
err_console.print(
|
|
68
|
+
"[dim]Hint: pass [bold]--diagnostics none[/bold] (free tier).[/dim]"
|
|
69
|
+
)
|
|
70
|
+
else:
|
|
71
|
+
err_console.print(f"[error]Forbidden:[/error] {msg}")
|
|
72
|
+
elif status == 429:
|
|
73
|
+
retry = exc.response.headers.get("Retry-After", "?")
|
|
74
|
+
err_console.print(f"[error]Rate limited.[/error] Retry after {retry}s.")
|
|
75
|
+
elif status == 402:
|
|
76
|
+
err_console.print(f"[warning]Feature not available on your tier.[/warning] {msg}")
|
|
77
|
+
else:
|
|
78
|
+
err_console.print(f"[error]API error (HTTP {status}, {code}):[/error] {msg}")
|
|
79
|
+
sys.exit(1)
|
|
80
|
+
except httpx.ConnectError:
|
|
81
|
+
err_console.print(
|
|
82
|
+
"[error]Cannot connect to CortexDB.[/error] "
|
|
83
|
+
"Check your endpoint and network."
|
|
84
|
+
)
|
|
85
|
+
sys.exit(2)
|
|
86
|
+
except httpx.TimeoutException:
|
|
87
|
+
err_console.print("[error]Request timed out.[/error]")
|
|
88
|
+
sys.exit(2)
|
|
89
|
+
except click.Abort:
|
|
90
|
+
err_console.print("\n[dim]Aborted.[/dim]")
|
|
91
|
+
sys.exit(130)
|
|
92
|
+
except KeyboardInterrupt:
|
|
93
|
+
err_console.print("\n[dim]Interrupted.[/dim]")
|
|
94
|
+
sys.exit(130)
|
|
95
|
+
|
|
96
|
+
return wrapper
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "cortexdb-cli"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Command-line interface for CortexDB — the long-term memory layer for AI."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = "Apache-2.0"
|
|
11
|
-
requires-python = ">=3.10"
|
|
12
|
-
authors = [
|
|
13
|
-
{ name = "CortexDB Team", email = "team@cortexdb.ai" },
|
|
14
|
-
]
|
|
15
|
-
keywords = ["ai", "memory", "cli", "cortexdb", "agents", "llm"]
|
|
16
|
-
classifiers = [
|
|
17
|
-
"Development Status :: 4 - Beta",
|
|
18
|
-
"Environment :: Console",
|
|
19
|
-
"Intended Audience :: Developers",
|
|
20
|
-
"License :: OSI Approved :: Apache Software License",
|
|
21
|
-
"Programming Language :: Python :: 3",
|
|
22
|
-
"Programming Language :: Python :: 3.10",
|
|
23
|
-
"Programming Language :: Python :: 3.11",
|
|
24
|
-
"Programming Language :: Python :: 3.12",
|
|
25
|
-
"Programming Language :: Python :: 3.13",
|
|
26
|
-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
27
|
-
"Topic :: Database",
|
|
28
|
-
]
|
|
29
|
-
dependencies = [
|
|
30
|
-
"click>=8.1",
|
|
31
|
-
"rich>=13.0",
|
|
32
|
-
"rich-click>=1.7",
|
|
33
|
-
"httpx>=0.27",
|
|
34
|
-
"prompt-toolkit>=3.0",
|
|
35
|
-
"tomli>=2.0; python_version < '3.11'",
|
|
36
|
-
"tomli-w>=1.0",
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
[project.scripts]
|
|
40
|
-
cortexdb = "cortexdb_cli.main:cli"
|
|
41
|
-
|
|
42
|
-
[project.urls]
|
|
43
|
-
Homepage = "https://cortexdb.ai"
|
|
44
|
-
Documentation = "https://cortexdb.ai/docs"
|
|
45
|
-
Repository = "https://github.com/cortexdb/cortexdb"
|
|
46
|
-
Issues = "https://github.com/cortexdb/cortexdb/issues"
|
|
47
|
-
|
|
48
|
-
[tool.hatch.build.targets.wheel]
|
|
49
|
-
packages = ["cortexdb_cli"]
|
|
50
|
-
|
|
51
|
-
[tool.hatch.build.targets.sdist]
|
|
52
|
-
include = ["cortexdb_cli", "README.md", "LICENSE"]
|
|
53
|
-
|
|
54
|
-
[tool.ruff]
|
|
55
|
-
target-version = "py310"
|
|
56
|
-
line-length = 100
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cortexdb-cli"
|
|
7
|
+
version = "0.6.0"
|
|
8
|
+
description = "Command-line interface for CortexDB — the long-term memory layer for AI."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "CortexDB Team", email = "team@cortexdb.ai" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["ai", "memory", "cli", "cortexdb", "agents", "llm"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"License :: OSI Approved :: Apache Software License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
27
|
+
"Topic :: Database",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"click>=8.1",
|
|
31
|
+
"rich>=13.0",
|
|
32
|
+
"rich-click>=1.7",
|
|
33
|
+
"httpx>=0.27",
|
|
34
|
+
"prompt-toolkit>=3.0",
|
|
35
|
+
"tomli>=2.0; python_version < '3.11'",
|
|
36
|
+
"tomli-w>=1.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
cortexdb = "cortexdb_cli.main:cli"
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://cortexdb.ai"
|
|
44
|
+
Documentation = "https://cortexdb.ai/docs"
|
|
45
|
+
Repository = "https://github.com/cortexdb/cortexdb"
|
|
46
|
+
Issues = "https://github.com/cortexdb/cortexdb/issues"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["cortexdb_cli"]
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.sdist]
|
|
52
|
+
include = ["cortexdb_cli", "README.md", "LICENSE"]
|
|
53
|
+
|
|
54
|
+
[tool.ruff]
|
|
55
|
+
target-version = "py310"
|
|
56
|
+
line-length = 100
|
cortexdb_cli-0.5.4/.gitignore
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Rust
|
|
2
|
-
/target
|
|
3
|
-
**/*.rs.bk
|
|
4
|
-
|
|
5
|
-
# Environment / secrets
|
|
6
|
-
.env
|
|
7
|
-
.env.local
|
|
8
|
-
.env*.local
|
|
9
|
-
*.pem
|
|
10
|
-
*.key
|
|
11
|
-
.npmrc
|
|
12
|
-
|
|
13
|
-
# SQLite database
|
|
14
|
-
*.sqlite
|
|
15
|
-
*.sqlite-wal
|
|
16
|
-
*.sqlite-shm
|
|
17
|
-
|
|
18
|
-
# OS
|
|
19
|
-
.DS_Store
|
|
20
|
-
Thumbs.db
|
|
21
|
-
desktop.ini
|
|
22
|
-
|
|
23
|
-
# IDE
|
|
24
|
-
.idea/
|
|
25
|
-
.vscode/
|
|
26
|
-
*.swp
|
|
27
|
-
*.swo
|
|
28
|
-
|
|
29
|
-
# Data directories
|
|
30
|
-
cortexdb_data*/
|
|
31
|
-
/data/
|
|
32
|
-
# Per-bench tenant stores (RocksDB + Tantivy + HNSW state; regeneratable per run)
|
|
33
|
-
/data_*/
|
|
34
|
-
# Experimental per-branch stores (not tracked on this branch but left gitignored
|
|
35
|
-
# so checkout from other branches doesn't surface them in git status)
|
|
36
|
-
/event_memory_store/
|
|
37
|
-
/llm_cache/
|
|
38
|
-
|
|
39
|
-
# Benchmark inputs and per-run outputs (kept local, regenerated each run)
|
|
40
|
-
benchmarks/longmemeval/data/
|
|
41
|
-
benchmarks/longmemeval/server_results/
|
|
42
|
-
benchmarks/longmemeval/fast_results/
|
|
43
|
-
benchmarks/longmemeval/micro_results/
|
|
44
|
-
benchmarks/longmemeval/server_logs/
|
|
45
|
-
benchmarks/longmemeval/*.log
|
|
46
|
-
benchmarks/locomo/locomo_results*.json
|
|
47
|
-
benchmarks/locomo/server_results/
|
|
48
|
-
benchmarks/locomo/*.log
|
|
49
|
-
/answer_out.json
|
|
50
|
-
|
|
51
|
-
# Local Claude Code state
|
|
52
|
-
.claude/
|
|
53
|
-
.tmp/
|
|
54
|
-
|
|
55
|
-
# Python
|
|
56
|
-
__pycache__/
|
|
57
|
-
*.pyc
|
|
58
|
-
.venv/
|
|
59
|
-
venv/
|
|
60
|
-
|
|
61
|
-
# Node
|
|
62
|
-
node_modules/
|
|
63
|
-
dist/
|
|
64
|
-
.next/
|
|
65
|
-
|
|
66
|
-
# Egg info
|
|
67
|
-
*.egg-info/
|
|
68
|
-
|
|
69
|
-
# Scratch/debug text files at root
|
|
70
|
-
/*.txt
|
|
71
|
-
/*.log
|
|
72
|
-
|
|
73
|
-
# Local debug / marketing / private content (not for repo)
|
|
74
|
-
harness/.reports/
|
|
75
|
-
harness_data_*/
|
|
76
|
-
blog/
|
|
77
|
-
sales/
|
|
78
|
-
videos/
|
|
79
|
-
local-instance/
|
|
80
|
-
|
|
81
|
-
# doc-claims verifier scratch output
|
|
82
|
-
tools/verifier_out*/
|
|
83
|
-
|
|
84
|
-
# Generated benchmark / runtime data (audit M-10: hundreds of untracked
|
|
85
|
-
# data dirs at the workspace root slow every git status/search and risk
|
|
86
|
-
# being packaged; results JSONs are artifacts, never source)
|
|
87
|
-
benchmarks/data_*/
|
|
88
|
-
benchmarks/**/fast_results/
|
|
89
|
-
data_*/
|
|
90
|
-
*_data/
|
|
91
|
-
*_data_20*/
|
|
92
|
-
cortexdb_data*/
|
|
93
|
-
server_results/
|
|
94
|
-
*.log
|
|
95
|
-
docker_build.log
|
|
96
|
-
|
|
97
|
-
# local gate/bench data stores
|
|
98
|
-
gate*_data_*/
|
|
99
|
-
|
|
100
|
-
# Code-plane benchmark local run outputs (official results are committed deliberately)
|
|
101
|
-
benchmarks/codeplane/runs/
|
|
102
|
-
|
|
103
|
-
# Deliberately untracked, four times over: `git add docs/` keeps sweeping the
|
|
104
|
-
# investor deck sources and the 2.7 MB OpenClaw design PDF back in (7dda2a51,
|
|
105
|
-
# 3a778b5e, then again in the 2026-09-09 checkpoint). They live on disk; they do
|
|
106
|
-
# not belong in the repo. Stage explicit paths, never a directory.
|
|
107
|
-
docs/investor_deck/
|
|
108
|
-
docs/CORTEX_OPENCLAW_AGENT_OS_DESIGN.md
|
|
109
|
-
docs/CORTEX_OPENCLAW_AGENT_OS_DESIGN.pdf
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|