ccmd 2.0.8__tar.gz → 2.1.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.
- {ccmd-2.0.8/ccmd.egg-info → ccmd-2.1.0}/PKG-INFO +1 -1
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/__init__.py +1 -1
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/cli.py +126 -34
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/shell_cmds.py +9 -5
- {ccmd-2.0.8 → ccmd-2.1.0/ccmd.egg-info}/PKG-INFO +1 -1
- {ccmd-2.0.8 → ccmd-2.1.0}/pyproject.toml +1 -1
- {ccmd-2.0.8 → ccmd-2.1.0}/LICENSE +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/MANIFEST.in +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/README.md +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/__main__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/config/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/config/paths.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/config/schema.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/aider.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/base.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/chatgpt.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/claude.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/codex.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/cursor.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/goose.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/agents/grok.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/fs.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/launcher.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/migrate.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/profiles.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/projects.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/scan.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/sessions.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/core/ssh.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/mcp/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/mcp/server.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/app.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/ascii.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/agents.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/aliases.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/browser.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/hub.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/project_edit.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/sessions.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/screens/ssh.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/theme.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/widgets/__init__.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd/tui/widgets/spinner.py +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd.egg-info/SOURCES.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd.egg-info/dependency_links.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd.egg-info/entry_points.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd.egg-info/requires.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/ccmd.egg-info/top_level.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/commands.yaml +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/requirements.txt +0 -0
- {ccmd-2.0.8 → ccmd-2.1.0}/setup.cfg +0 -0
|
@@ -20,33 +20,133 @@ from ccmd.core.sessions import SessionStore
|
|
|
20
20
|
from ccmd.core.ssh import SSHStore
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
# Rich colors for agent columns / badges
|
|
24
|
+
_AGENT_STYLE = {
|
|
25
|
+
"claude": "dark_orange3",
|
|
26
|
+
"grok": "bright_white",
|
|
27
|
+
"codex": "green",
|
|
28
|
+
"cursor": "medium_purple",
|
|
29
|
+
"goose": "yellow",
|
|
30
|
+
"aider": "cyan",
|
|
31
|
+
"chatgpt": "sea_green3",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _agent_meta() -> list[dict]:
|
|
36
|
+
"""Logo + name + id for every agent (order matches variants)."""
|
|
37
|
+
from ccmd.core.agents import all_agents
|
|
38
|
+
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
"id": a.id,
|
|
42
|
+
"name": a.display_name,
|
|
43
|
+
"logo": a.ascii_logo,
|
|
44
|
+
"color": a.brand_color,
|
|
45
|
+
"style": _AGENT_STYLE.get(a.id, "white"),
|
|
46
|
+
}
|
|
47
|
+
for a in all_agents()
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
23
51
|
def _print_cmd_rows(rows: list, *, verbose: bool = False) -> None:
|
|
52
|
+
"""Full ccmds view: base cmd + every agent variant with logo & name."""
|
|
53
|
+
try:
|
|
54
|
+
from rich import box
|
|
55
|
+
from rich.console import Console
|
|
56
|
+
from rich.table import Table
|
|
57
|
+
from rich.text import Text
|
|
58
|
+
|
|
59
|
+
console = Console(highlight=False)
|
|
60
|
+
use_rich = True
|
|
61
|
+
except Exception:
|
|
62
|
+
use_rich = False
|
|
63
|
+
|
|
24
64
|
if not rows:
|
|
25
65
|
print("no matching commands")
|
|
26
66
|
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
67
|
+
|
|
68
|
+
agents = _agent_meta()
|
|
69
|
+
|
|
70
|
+
if use_rich:
|
|
71
|
+
console = Console(highlight=False)
|
|
72
|
+
|
|
73
|
+
# legend once
|
|
74
|
+
legend = Text()
|
|
75
|
+
legend.append("agents ", style="dim")
|
|
76
|
+
for a in agents:
|
|
77
|
+
legend.append(f"{a['logo']} ", style=a["style"])
|
|
78
|
+
legend.append(f"{a['name']}", style=a["style"])
|
|
79
|
+
legend.append(" ", style="dim")
|
|
80
|
+
console.print(legend)
|
|
81
|
+
console.print()
|
|
82
|
+
|
|
83
|
+
table = Table(
|
|
84
|
+
show_header=True,
|
|
85
|
+
header_style="bold bright_cyan",
|
|
86
|
+
border_style="bright_black",
|
|
87
|
+
box=box.SIMPLE_HEAVY,
|
|
88
|
+
pad_edge=False,
|
|
89
|
+
expand=False,
|
|
90
|
+
show_lines=False,
|
|
91
|
+
)
|
|
92
|
+
table.add_column("cmd", style="bold bright_cyan", no_wrap=True)
|
|
93
|
+
table.add_column("project", style="white", no_wrap=True)
|
|
94
|
+
table.add_column("default", style="magenta", no_wrap=True)
|
|
95
|
+
for a in agents:
|
|
96
|
+
# header: logo + short id
|
|
97
|
+
hdr = Text()
|
|
98
|
+
hdr.append(f"{a['logo']}\n", style=a["style"])
|
|
99
|
+
hdr.append(a["id"][:6], style=f"dim {a['style']}")
|
|
100
|
+
table.add_column(hdr, justify="center", no_wrap=True)
|
|
101
|
+
if verbose:
|
|
102
|
+
table.add_column("path", style="dim", overflow="ellipsis", max_width=36)
|
|
103
|
+
|
|
104
|
+
for r in rows:
|
|
105
|
+
cells: list = [
|
|
106
|
+
Text(r["short"], style="bold bright_cyan"),
|
|
107
|
+
Text(r["project"], style="white"),
|
|
108
|
+
Text(r["default_agent"], style="magenta"),
|
|
109
|
+
]
|
|
110
|
+
for a in agents:
|
|
111
|
+
fn = r["variants"].get(a["id"], "")
|
|
112
|
+
is_default = r["default_agent"] == a["id"]
|
|
113
|
+
style = a["style"] if is_default else f"dim {a['style']}"
|
|
114
|
+
# mark default with *
|
|
115
|
+
label = f"{fn}*" if is_default and fn else fn
|
|
116
|
+
cells.append(Text(label, style=style))
|
|
117
|
+
if verbose:
|
|
118
|
+
cells.append(Text(r["path"], style="dim"))
|
|
119
|
+
table.add_row(*cells)
|
|
120
|
+
|
|
121
|
+
console.print(table)
|
|
122
|
+
console.print()
|
|
123
|
+
console.print(
|
|
124
|
+
f"[dim]{len(rows)} project(s)[/] "
|
|
125
|
+
f"[dim]·[/] [bright_cyan]cmd[/][dim] = default agent[/] "
|
|
126
|
+
f"[dim]·[/] [bright_cyan]*[/][dim] = project default[/] "
|
|
127
|
+
f"[dim]·[/] [bright_cyan]ccmds ana[/][dim] filter[/] "
|
|
128
|
+
f"[dim]·[/] [bright_cyan]ccmds -v[/][dim] show paths[/]"
|
|
34
129
|
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
# plain fallback — still show all agent cmds
|
|
133
|
+
headers = ["cmd", "project", "default"] + [a["id"][:6] for a in agents]
|
|
134
|
+
print(" ".join(f"{h:<10}" for h in headers))
|
|
135
|
+
print("-" * (12 * len(headers)))
|
|
136
|
+
for r in rows:
|
|
137
|
+
cols = [r["short"], r["project"], r["default_agent"]]
|
|
138
|
+
for a in agents:
|
|
139
|
+
cols.append(r["variants"].get(a["id"], ""))
|
|
140
|
+
print(" ".join(f"{c:<10}" for c in cols))
|
|
141
|
+
if verbose:
|
|
142
|
+
print(f" {r['path']}")
|
|
143
|
+
print(f"\n{len(rows)} project(s) · * default agent on project")
|
|
42
144
|
|
|
43
145
|
|
|
44
146
|
def _cmd_shell(args: argparse.Namespace) -> int:
|
|
45
147
|
from ccmd.core.shell_cmds import (
|
|
46
|
-
format_cmds_block,
|
|
47
148
|
install_shell_hook,
|
|
48
149
|
list_cmd_rows,
|
|
49
|
-
shell_cmds_path,
|
|
50
150
|
write_shell_cmds,
|
|
51
151
|
)
|
|
52
152
|
|
|
@@ -61,40 +161,32 @@ def _cmd_shell(args: argparse.Namespace) -> int:
|
|
|
61
161
|
for rc in rcs:
|
|
62
162
|
print(f"hooked {rc}")
|
|
63
163
|
print("restart shell or: source ~/.ccmd/shell_cmds.sh")
|
|
64
|
-
print("then: ccmds #
|
|
164
|
+
print("then: ccmds # all cmds + agents with logos")
|
|
165
|
+
print(" ccmds ana # filter one project")
|
|
65
166
|
print(" ana / anac / anag …")
|
|
66
167
|
if verbose:
|
|
67
|
-
_print_cmd_rows(list_cmd_rows(), verbose=
|
|
168
|
+
_print_cmd_rows(list_cmd_rows(), verbose=True)
|
|
68
169
|
return 0
|
|
69
170
|
if sub == "regen":
|
|
70
171
|
path, shorts = write_shell_cmds()
|
|
71
172
|
print(f"regenerated {path} ({len(shorts)} projects)")
|
|
72
|
-
|
|
73
|
-
_print_cmd_rows(rows, verbose=verbose)
|
|
74
|
-
return 0
|
|
75
|
-
if sub == "list":
|
|
76
|
-
rows = list_cmd_rows(filter_text=filt)
|
|
77
|
-
_print_cmd_rows(rows, verbose=verbose or bool(filt))
|
|
78
|
-
print(f"file: {shell_cmds_path()}")
|
|
173
|
+
_print_cmd_rows(list_cmd_rows(filter_text=filt), verbose=verbose)
|
|
79
174
|
return 0
|
|
80
|
-
if sub
|
|
81
|
-
|
|
82
|
-
_print_cmd_rows(rows, verbose=True)
|
|
175
|
+
if sub in ("list", "show"):
|
|
176
|
+
_print_cmd_rows(list_cmd_rows(filter_text=filt), verbose=verbose)
|
|
83
177
|
return 0
|
|
84
178
|
print("usage: ccmd shell install|regen|list [--filter NAME] [-v]", file=sys.stderr)
|
|
85
|
-
print(" ccmds #
|
|
179
|
+
print(" ccmds # full table with agent logos", file=sys.stderr)
|
|
86
180
|
return 1
|
|
87
181
|
|
|
88
182
|
|
|
89
183
|
def _cmd_cmds(args: argparse.Namespace) -> int:
|
|
90
|
-
"""Top-level: ccmd cmds [
|
|
91
|
-
from ccmd.core.shell_cmds import list_cmd_rows
|
|
184
|
+
"""Top-level: ccmd cmds [name] [-v] — same as ccmds."""
|
|
185
|
+
from ccmd.core.shell_cmds import list_cmd_rows
|
|
92
186
|
|
|
93
187
|
filt = args.filter or args.name
|
|
94
188
|
rows = list_cmd_rows(filter_text=filt)
|
|
95
|
-
_print_cmd_rows(rows, verbose=bool(
|
|
96
|
-
print(f"file: {shell_cmds_path()}")
|
|
97
|
-
print("tip: ccmds (shell function) after source ~/.ccmd/shell_cmds.sh")
|
|
189
|
+
_print_cmd_rows(rows, verbose=bool(args.verbose))
|
|
98
190
|
return 0
|
|
99
191
|
|
|
100
192
|
|
|
@@ -243,18 +243,22 @@ def render_shell_cmds(projects: list, shorts: dict[str, str]) -> str:
|
|
|
243
243
|
)
|
|
244
244
|
lines.append("")
|
|
245
245
|
|
|
246
|
-
# helper:
|
|
246
|
+
# helper: full table — cmd + every agent logo/name/variant
|
|
247
247
|
lines.extend(
|
|
248
248
|
[
|
|
249
|
-
"# list
|
|
249
|
+
"# list all short commands with agent logos & variants",
|
|
250
250
|
"ccmds() {",
|
|
251
251
|
' if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then',
|
|
252
|
-
' echo "ccmds
|
|
253
|
-
' echo "ccmds
|
|
252
|
+
' echo "ccmds all projects + agent cmds (logos)"',
|
|
253
|
+
' echo "ccmds -v include full paths"',
|
|
254
|
+
' echo "ccmds <name> filter (e.g. ccmds ana)"',
|
|
254
255
|
' echo "ccmds -l|--list same as bare ccmds"',
|
|
255
|
-
' echo "ccmd shell list full CLI list"',
|
|
256
256
|
" return 0",
|
|
257
257
|
" fi",
|
|
258
|
+
' if [ "$1" = "-v" ] || [ "$1" = "--verbose" ]; then',
|
|
259
|
+
' command ccmd shell list -v',
|
|
260
|
+
" return $?",
|
|
261
|
+
" fi",
|
|
258
262
|
' if [ -z "$1" ] || [ "$1" = "-l" ] || [ "$1" = "--list" ]; then',
|
|
259
263
|
' command ccmd shell list',
|
|
260
264
|
" return $?",
|
|
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
|
|
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
|