advai-cli 1.0.2__tar.gz → 1.0.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.
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.4
2
+ Name: advai-cli
3
+ Version: 1.0.4
4
+ Summary: A cross-platform CLI tool.
5
+ Author: advai
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: click>=8.1
10
+
11
+ # advai-cli
12
+
13
+ A cross-platform CLI tool for skill management and CLI self-management.
14
+
15
+ Install:
16
+ ```bash
17
+ pip install advai-cli
18
+ ```
19
+
20
+ Commands:
21
+ ```bash
22
+ advai --help
23
+ advai info
24
+ advai update
25
+ advai skill list
26
+ advai skill install demo-skill
27
+ advai cli list
28
+ advai cli info demo-cli
29
+ advai cli install demo-cli --yes
30
+ ```
31
+
32
+ Structured command groups:
33
+ ```bash
34
+ advai skill list
35
+ advai skill info demo-skill
36
+ advai skill install demo-skill
37
+ advai skill update demo-skill
38
+ advai skill uninstall demo-skill
39
+ ```
40
+
41
+ advai self-management:
42
+ ```bash
43
+ advai info
44
+ advai update
45
+ ```
46
+
47
+ External CLI management:
48
+ ```bash
49
+ advai cli list
50
+ advai cli info demo-cli
51
+ advai cli install demo-cli --yes
52
+ ```
@@ -0,0 +1,42 @@
1
+ # advai-cli
2
+
3
+ A cross-platform CLI tool for skill management and CLI self-management.
4
+
5
+ Install:
6
+ ```bash
7
+ pip install advai-cli
8
+ ```
9
+
10
+ Commands:
11
+ ```bash
12
+ advai --help
13
+ advai info
14
+ advai update
15
+ advai skill list
16
+ advai skill install demo-skill
17
+ advai cli list
18
+ advai cli info demo-cli
19
+ advai cli install demo-cli --yes
20
+ ```
21
+
22
+ Structured command groups:
23
+ ```bash
24
+ advai skill list
25
+ advai skill info demo-skill
26
+ advai skill install demo-skill
27
+ advai skill update demo-skill
28
+ advai skill uninstall demo-skill
29
+ ```
30
+
31
+ advai self-management:
32
+ ```bash
33
+ advai info
34
+ advai update
35
+ ```
36
+
37
+ External CLI management:
38
+ ```bash
39
+ advai cli list
40
+ advai cli info demo-cli
41
+ advai cli install demo-cli --yes
42
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "1.0.4"
@@ -0,0 +1,260 @@
1
+ import click
2
+ import os
3
+ import sys
4
+
5
+ from advai import __version__
6
+ from advai.cli_manager import (
7
+ cli_info,
8
+ get_available_cli_info,
9
+ list_external_clis,
10
+ get_external_cli_info,
11
+ cli_exists,
12
+ build_cli_exec_command,
13
+ build_external_cli_install_command,
14
+ opencli_available,
15
+ build_update_command,
16
+ run_manager_command,
17
+ run_passthrough_command,
18
+ )
19
+ from advai.skills import install_skill, uninstall_skill, list_skills, update_skill, info_skill
20
+
21
+ SKILLS_DIR = os.path.expanduser("~/.advai/skills")
22
+ CONFIG_DIR = os.path.expanduser("~/.advai")
23
+
24
+
25
+ def _ensure_dirs():
26
+ os.makedirs(SKILLS_DIR, exist_ok=True)
27
+ os.makedirs(CONFIG_DIR, exist_ok=True)
28
+
29
+
30
+ @click.group()
31
+ @click.version_option(version=__version__, prog_name="advai")
32
+ def cli():
33
+ """advai — a cross-platform CLI tool."""
34
+ _ensure_dirs()
35
+
36
+
37
+ class ExternalCLIGroup(click.Group):
38
+ """Static management commands + dynamic OpenCLI proxy."""
39
+
40
+ def get_command(self, ctx, cmd_name):
41
+ command = super().get_command(ctx, cmd_name)
42
+ if command is not None:
43
+ return command
44
+ if not opencli_available():
45
+ return None
46
+ if not cli_exists(cmd_name):
47
+ return None
48
+
49
+ @click.command(
50
+ name=cmd_name,
51
+ context_settings={
52
+ "ignore_unknown_options": True,
53
+ "allow_extra_args": True,
54
+ },
55
+ add_help_option=False,
56
+ )
57
+ @click.argument("args", nargs=-1, type=click.UNPROCESSED)
58
+ def dynamic_cli_cmd(args):
59
+ exit_code = run_passthrough_command(build_cli_exec_command(cmd_name, list(args)))
60
+ raise click.exceptions.Exit(exit_code)
61
+
62
+ return dynamic_cli_cmd
63
+
64
+
65
+ def _skill_install(skill_name, force):
66
+ try:
67
+ install_skill(skill_name, force=force)
68
+ click.echo(f"✅ Skill '{skill_name}' installed successfully")
69
+ except FileExistsError:
70
+ click.echo(f"⚠️ Skill '{skill_name}' already exists, use --force to overwrite")
71
+ except Exception as e:
72
+ click.echo(f"❌ Installation failed: {e}", err=True)
73
+ sys.exit(1)
74
+
75
+
76
+ def _skill_uninstall(skill_name):
77
+ try:
78
+ uninstall_skill(skill_name)
79
+ click.echo(f"🗑️ Skill '{skill_name}' uninstalled")
80
+ except FileNotFoundError:
81
+ click.echo(f"⚠️ Skill '{skill_name}' is not installed")
82
+ except Exception as e:
83
+ click.echo(f"❌ Uninstall failed: {e}", err=True)
84
+ sys.exit(1)
85
+
86
+
87
+ def _skill_list():
88
+ skills = list_skills()
89
+ if not skills:
90
+ click.echo("(no Skills installed)")
91
+ return
92
+ click.echo("📋 Installed Skills:")
93
+ for s in skills:
94
+ click.echo(f" • {s}")
95
+
96
+
97
+ def _skill_update(skill_name):
98
+ try:
99
+ updated = update_skill(skill_name)
100
+ if updated:
101
+ for s in updated:
102
+ click.echo(f"🔄 {s} updated")
103
+ else:
104
+ click.echo("(nothing to update)")
105
+ except Exception as e:
106
+ click.echo(f"❌ Update failed: {e}", err=True)
107
+ sys.exit(1)
108
+
109
+
110
+ def _skill_info(skill_name):
111
+ data = info_skill(skill_name)
112
+ if data is None:
113
+ click.echo(f"⚠️ Skill '{skill_name}' not installed or has no metadata")
114
+ return
115
+ click.echo(f"ℹ️ Skill '{skill_name}':")
116
+ for k, v in data.items():
117
+ click.echo(f" {k}: {v}")
118
+
119
+
120
+ def _self_info():
121
+ data = cli_info()
122
+ click.echo("advai:")
123
+ click.echo(f" name: {data['name']}")
124
+ click.echo(f" version: {data['version']}")
125
+ click.echo(f" install_method: {data['install_method']}")
126
+ click.echo(f" python: {data['python']}")
127
+ click.echo(f" entry: {data['entry']}")
128
+ click.echo(f" module: {data['module']}")
129
+ click.echo(f" skills_dir: {data['skills_dir']}")
130
+ click.echo(" available_managers:")
131
+ for manager, available in data["available_managers"].items():
132
+ click.echo(f" {manager}: {'yes' if available else 'no'}")
133
+
134
+
135
+ @cli.command(name="info")
136
+ def self_info_cmd():
137
+ """Show advai details."""
138
+ _self_info()
139
+
140
+
141
+ @cli.command(name="update")
142
+ def self_update_cmd():
143
+ """Update advai itself."""
144
+ command = build_update_command("pip")
145
+ click.echo(f"Recommended update command: {' '.join(command)}")
146
+
147
+
148
+ @cli.group(name="skill")
149
+ def skill_admin():
150
+ """Manage Skills with a structured command group."""
151
+
152
+
153
+ @skill_admin.command(name="install")
154
+ @click.argument("skill_name")
155
+ @click.option("--force", is_flag=True, help="Force reinstall (overwrite existing)")
156
+ def skill_install_cmd(skill_name, force):
157
+ """Install a Skill."""
158
+ _skill_install(skill_name, force)
159
+
160
+
161
+ @skill_admin.command(name="uninstall")
162
+ @click.argument("skill_name")
163
+ def skill_uninstall_cmd(skill_name):
164
+ """Uninstall a Skill."""
165
+ _skill_uninstall(skill_name)
166
+
167
+
168
+ @skill_admin.command(name="list")
169
+ def skill_list_cmd():
170
+ """List locally installed Skills."""
171
+ _skill_list()
172
+
173
+
174
+ @skill_admin.command(name="update")
175
+ @click.argument("skill_name", required=False)
176
+ def skill_update_cmd(skill_name):
177
+ """Update one or all Skills."""
178
+ _skill_update(skill_name)
179
+
180
+
181
+ @skill_admin.command(name="info")
182
+ @click.argument("skill_name")
183
+ def skill_info_cmd(skill_name):
184
+ """Show Skill details."""
185
+ _skill_info(skill_name)
186
+
187
+
188
+ @cli.group(name="cli", cls=ExternalCLIGroup)
189
+ def cli_admin():
190
+ """Manage or execute external CLIs."""
191
+
192
+
193
+ @cli_admin.command(name="info")
194
+ @click.argument("cli_name")
195
+ def cli_info_cmd(cli_name):
196
+ """Show external CLI details."""
197
+ external = get_external_cli_info(cli_name)
198
+ if external is not None:
199
+ click.echo(f"CLI '{cli_name}':")
200
+ for key in ("name", "package", "binary", "installed", "description", "homepage", "tags"):
201
+ click.echo(f" {key}: {external.get(key)}")
202
+ return
203
+ available = get_available_cli_info(cli_name)
204
+ if available is not None:
205
+ click.echo(f"CLI '{cli_name}':")
206
+ click.echo(" source: opencli")
207
+ click.echo(f" command_count: {available['command_count']}")
208
+ click.echo(f" commands: {', '.join(available['commands'])}")
209
+ if available.get("description"):
210
+ click.echo(f" description: {available['description']}")
211
+ return
212
+ raise click.ClickException(f"CLI '{cli_name}' was not found")
213
+
214
+
215
+ @cli_admin.command(name="list")
216
+ @click.option("--search", default="", help="Filter CLI names")
217
+ def cli_list_cmd(search):
218
+ """List installable external CLIs."""
219
+ if not opencli_available():
220
+ raise click.ClickException("opencli is not installed or not on PATH")
221
+ targets = list_external_clis(search)
222
+ if not targets:
223
+ click.echo("(no external CLIs found)")
224
+ return
225
+ click.echo("External CLIs:")
226
+ for item in targets:
227
+ installed = "installed" if item.get("installed") else "not installed"
228
+ click.echo(f" • {item['name']} ({installed})")
229
+ if item.get("description"):
230
+ click.echo(f" description: {item['description']}")
231
+
232
+
233
+ def _execute_cli_command(command, action):
234
+ result = run_manager_command(command)
235
+ if result["stdout"]:
236
+ click.echo(result["stdout"])
237
+ if result["returncode"] != 0:
238
+ if result["stderr"]:
239
+ click.echo(result["stderr"], err=True)
240
+ raise click.ClickException(f"CLI {action} failed")
241
+ if result["stderr"]:
242
+ click.echo(result["stderr"])
243
+
244
+
245
+ @cli_admin.command(name="install")
246
+ @click.argument("cli_name")
247
+ @click.option("--yes", is_flag=True, help="Skip confirmation prompt")
248
+ def cli_install_cmd(cli_name, yes):
249
+ """Install an external CLI."""
250
+ if not opencli_available():
251
+ raise click.ClickException("opencli is not installed or not on PATH")
252
+ command = build_external_cli_install_command(cli_name)
253
+ if not yes:
254
+ click.confirm(f"Install external CLI '{cli_name}' via: {' '.join(command)} ?", abort=True)
255
+ _execute_cli_command(command, "install")
256
+ click.echo(f"CLI '{cli_name}' install completed")
257
+
258
+
259
+ if __name__ == "__main__":
260
+ cli()
@@ -0,0 +1,253 @@
1
+ import os
2
+ import shutil
3
+ import subprocess
4
+ import sys
5
+ import json
6
+ from functools import lru_cache
7
+
8
+ from advai import __version__
9
+
10
+ PACKAGE_NAME = "advai-cli"
11
+ BREW_FORMULA = "advai-cli"
12
+ SUPPORTED_MANAGERS = ("pip", "npm", "brew")
13
+
14
+
15
+ def _normalize_path(value: str) -> str:
16
+ if not value:
17
+ return ""
18
+ return os.path.realpath(os.path.expanduser(value))
19
+
20
+
21
+ def detect_install_method() -> str:
22
+ argv0 = _normalize_path(sys.argv[0])
23
+ module_path = _normalize_path(__file__)
24
+ combined = f"{argv0} {module_path}".lower()
25
+
26
+ if "cellar" in combined or "homebrew" in combined:
27
+ return "brew"
28
+ if "node_modules" in combined or argv0.endswith(".js"):
29
+ return "npm"
30
+ if "site-packages" in combined or "dist-packages" in combined:
31
+ return "pip"
32
+ return "source"
33
+
34
+
35
+ def available_managers() -> dict:
36
+ return {
37
+ "pip": bool(sys.executable),
38
+ "npm": shutil.which("npm") is not None,
39
+ "brew": shutil.which("brew") is not None,
40
+ }
41
+
42
+
43
+ def cli_info() -> dict:
44
+ return {
45
+ "name": PACKAGE_NAME,
46
+ "version": __version__,
47
+ "install_method": detect_install_method(),
48
+ "python": sys.executable,
49
+ "entry": _normalize_path(sys.argv[0]),
50
+ "module": _normalize_path(__file__),
51
+ "skills_dir": os.path.expanduser("~/.advai/skills"),
52
+ "available_managers": available_managers(),
53
+ }
54
+
55
+
56
+ def list_cli_targets() -> list:
57
+ info = cli_info()
58
+ detected = info["install_method"]
59
+ managers = info["available_managers"]
60
+ items = []
61
+ for name, available in managers.items():
62
+ status = "available" if available else "unavailable"
63
+ if name == detected:
64
+ status = f"{status}, detected"
65
+ items.append({"name": name, "status": status})
66
+ if detected not in managers:
67
+ items.append({"name": detected, "status": "detected"})
68
+ return items
69
+
70
+
71
+ def opencli_available() -> bool:
72
+ return shutil.which("opencli") is not None
73
+
74
+
75
+ @lru_cache(maxsize=1)
76
+ def _opencli_registry() -> list:
77
+ if not opencli_available():
78
+ return []
79
+ result = subprocess.run(
80
+ ["opencli", "list", "-f", "json"],
81
+ capture_output=True,
82
+ text=True,
83
+ )
84
+ if result.returncode != 0:
85
+ raise RuntimeError(result.stderr.strip() or "Failed to query opencli registry")
86
+ try:
87
+ return json.loads(result.stdout)
88
+ except json.JSONDecodeError as exc:
89
+ raise RuntimeError("Failed to parse opencli registry output") from exc
90
+
91
+
92
+ @lru_cache(maxsize=1)
93
+ def _opencli_external_registry() -> list:
94
+ if not opencli_available():
95
+ return []
96
+ result = subprocess.run(
97
+ ["opencli", "external", "list", "-f", "json"],
98
+ capture_output=True,
99
+ text=True,
100
+ )
101
+ if result.returncode != 0:
102
+ raise RuntimeError(result.stderr.strip() or "Failed to query opencli external registry")
103
+ try:
104
+ return json.loads(result.stdout)
105
+ except json.JSONDecodeError as exc:
106
+ raise RuntimeError("Failed to parse opencli external registry output") from exc
107
+
108
+
109
+ def list_available_clis(search: str = "") -> list:
110
+ term = str(search or "").strip().lower()
111
+ grouped = {}
112
+ for item in _opencli_registry():
113
+ site = str(item.get("site") or "").strip()
114
+ if not site:
115
+ continue
116
+ if term and term not in site.lower():
117
+ continue
118
+ info = grouped.setdefault(
119
+ site,
120
+ {
121
+ "name": site,
122
+ "command_count": 0,
123
+ "commands": [],
124
+ "description": "",
125
+ },
126
+ )
127
+ info["command_count"] += 1
128
+ command_name = str(item.get("name") or "").strip()
129
+ if command_name:
130
+ info["commands"].append(command_name)
131
+ if not info["description"]:
132
+ info["description"] = str(item.get("description") or "").strip()
133
+ return [grouped[name] for name in sorted(grouped)]
134
+
135
+
136
+ def get_available_cli_info(cli_name: str) -> dict | None:
137
+ target = str(cli_name or "").strip()
138
+ if not target:
139
+ return None
140
+ for item in list_available_clis():
141
+ if item["name"] == target:
142
+ return item
143
+ return None
144
+
145
+
146
+ def list_external_clis(search: str = "") -> list:
147
+ term = str(search or "").strip().lower()
148
+ items = []
149
+ for item in _opencli_external_registry():
150
+ name = str(item.get("name") or "").strip()
151
+ if not name:
152
+ continue
153
+ if term and term not in name.lower():
154
+ continue
155
+ items.append(item)
156
+ return items
157
+
158
+
159
+ def get_external_cli_info(cli_name: str) -> dict | None:
160
+ target = str(cli_name or "").strip()
161
+ if not target:
162
+ return None
163
+ for item in _opencli_external_registry():
164
+ if str(item.get("name") or "").strip() == target:
165
+ return item
166
+ return None
167
+
168
+
169
+ def cli_exists(cli_name: str) -> bool:
170
+ target = str(cli_name or "").strip()
171
+ if not target:
172
+ return False
173
+ for item in _opencli_registry():
174
+ if str(item.get("site") or "").strip() == target:
175
+ return True
176
+ return False
177
+
178
+
179
+ def build_cli_exec_command(cli_name: str, args: list | None = None) -> list:
180
+ command = ["opencli", cli_name]
181
+ if args:
182
+ command.extend(args)
183
+ return command
184
+
185
+
186
+ def build_external_cli_install_command(cli_name: str) -> list:
187
+ return ["opencli", "external", "install", cli_name]
188
+
189
+
190
+ def run_passthrough_command(command: list) -> int:
191
+ result = subprocess.run(command)
192
+ return result.returncode
193
+
194
+
195
+ def resolve_manager(manager: str = None) -> str:
196
+ if manager:
197
+ return manager
198
+ detected = detect_install_method()
199
+ if detected in SUPPORTED_MANAGERS:
200
+ return detected
201
+ return "pip"
202
+
203
+
204
+ def build_install_command(manager: str, reinstall: bool = False) -> list:
205
+ if manager == "pip":
206
+ cmd = [sys.executable, "-m", "pip", "install", "--upgrade"]
207
+ if reinstall:
208
+ cmd.append("--force-reinstall")
209
+ cmd.append(PACKAGE_NAME)
210
+ return cmd
211
+ if manager == "npm":
212
+ return ["npm", "install", "-g", PACKAGE_NAME]
213
+ if manager == "brew":
214
+ if reinstall:
215
+ return ["brew", "reinstall", BREW_FORMULA]
216
+ return ["brew", "install", BREW_FORMULA]
217
+ raise ValueError(f"Unsupported manager: {manager}")
218
+
219
+
220
+ def build_update_command(manager: str) -> list:
221
+ if manager == "pip":
222
+ return [sys.executable, "-m", "pip", "install", "--upgrade", PACKAGE_NAME]
223
+ if manager == "npm":
224
+ return ["npm", "install", "-g", f"{PACKAGE_NAME}@latest"]
225
+ if manager == "brew":
226
+ return ["brew", "upgrade", BREW_FORMULA]
227
+ raise ValueError(f"Unsupported manager: {manager}")
228
+
229
+
230
+ def build_uninstall_command(manager: str) -> list:
231
+ if manager == "pip":
232
+ return [sys.executable, "-m", "pip", "uninstall", "-y", PACKAGE_NAME]
233
+ if manager == "npm":
234
+ return ["npm", "uninstall", "-g", PACKAGE_NAME]
235
+ if manager == "brew":
236
+ return ["brew", "uninstall", BREW_FORMULA]
237
+ raise ValueError(f"Unsupported manager: {manager}")
238
+
239
+
240
+ def run_manager_command(command: list) -> dict:
241
+ result = subprocess.run(command, capture_output=True, text=True)
242
+ return {
243
+ "command": command,
244
+ "returncode": result.returncode,
245
+ "stdout": result.stdout.strip(),
246
+ "stderr": result.stderr.strip(),
247
+ }
248
+
249
+
250
+ def ensure_manager_available(manager: str) -> None:
251
+ available = available_managers()
252
+ if not available.get(manager):
253
+ raise RuntimeError(f"Package manager '{manager}' is not available on this system")
@@ -0,0 +1,52 @@
1
+ Metadata-Version: 2.4
2
+ Name: advai-cli
3
+ Version: 1.0.4
4
+ Summary: A cross-platform CLI tool.
5
+ Author: advai
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: click>=8.1
10
+
11
+ # advai-cli
12
+
13
+ A cross-platform CLI tool for skill management and CLI self-management.
14
+
15
+ Install:
16
+ ```bash
17
+ pip install advai-cli
18
+ ```
19
+
20
+ Commands:
21
+ ```bash
22
+ advai --help
23
+ advai info
24
+ advai update
25
+ advai skill list
26
+ advai skill install demo-skill
27
+ advai cli list
28
+ advai cli info demo-cli
29
+ advai cli install demo-cli --yes
30
+ ```
31
+
32
+ Structured command groups:
33
+ ```bash
34
+ advai skill list
35
+ advai skill info demo-skill
36
+ advai skill install demo-skill
37
+ advai skill update demo-skill
38
+ advai skill uninstall demo-skill
39
+ ```
40
+
41
+ advai self-management:
42
+ ```bash
43
+ advai info
44
+ advai update
45
+ ```
46
+
47
+ External CLI management:
48
+ ```bash
49
+ advai cli list
50
+ advai cli info demo-cli
51
+ advai cli install demo-cli --yes
52
+ ```
@@ -2,6 +2,7 @@ README.md
2
2
  pyproject.toml
3
3
  advai/__init__.py
4
4
  advai/cli.py
5
+ advai/cli_manager.py
5
6
  advai/skills.py
6
7
  advai_cli.egg-info/PKG-INFO
7
8
  advai_cli.egg-info/SOURCES.txt
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "advai-cli"
7
- version = "1.0.2"
8
- description = "Cross-platform AI Skill manager"
7
+ version = "1.0.4"
8
+ description = "A cross-platform CLI tool."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
11
11
  license = "MIT"
advai_cli-1.0.2/PKG-INFO DELETED
@@ -1,64 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: advai-cli
3
- Version: 1.0.2
4
- Summary: Cross-platform AI Skill manager
5
- Author: advai
6
- License-Expression: MIT
7
- Requires-Python: >=3.8
8
- Description-Content-Type: text/markdown
9
- Requires-Dist: click>=8.1
10
-
11
- # advai-cli — Cross-platform AI Skill Manager
12
-
13
- A Python CLI that lets you install / uninstall AI Skills.
14
-
15
- - **Platforms**: macOS / Linux / Windows
16
- - **Installation**: pip, npm, or one-line script
17
- - **Commands**: install, uninstall, list, update, info
18
-
19
- ---
20
-
21
- ## Quick Start
22
-
23
- ```bash
24
- # pip (recommended)
25
- pip install advai-cli
26
-
27
- # install after installation, the `advai` command is ready to use
28
-
29
- Advai --help
30
- advai --version
31
- advai install <skill-name>
32
- advai uninstall <skill-name>
33
- ```
34
-
35
- ---
36
-
37
- ## Project Structure
38
-
39
- ```
40
- advai/ # core CLI (Python)
41
- __init__.py
42
- cli.py # entry point (click-based)
43
- skills.py # Skill install / uninstall / metadata logic
44
- Formula/advai.rb # Homebrew formula
45
- bin/advai.js # npm entry point bridge
46
- install.sh # one-click installer script
47
- pyproject.toml # PyPI build configuration
48
- package.json # npm package configuration
49
- ```
50
-
51
- ---
52
-
53
- ## Local Development
54
-
55
- ```bash
56
- # run from source
57
- python3 -m advai.cli --help
58
- ```
59
-
60
- ---
61
-
62
- ## License
63
-
64
- MIT
advai_cli-1.0.2/README.md DELETED
@@ -1,54 +0,0 @@
1
- # advai-cli — Cross-platform AI Skill Manager
2
-
3
- A Python CLI that lets you install / uninstall AI Skills.
4
-
5
- - **Platforms**: macOS / Linux / Windows
6
- - **Installation**: pip, npm, or one-line script
7
- - **Commands**: install, uninstall, list, update, info
8
-
9
- ---
10
-
11
- ## Quick Start
12
-
13
- ```bash
14
- # pip (recommended)
15
- pip install advai-cli
16
-
17
- # install after installation, the `advai` command is ready to use
18
-
19
- Advai --help
20
- advai --version
21
- advai install <skill-name>
22
- advai uninstall <skill-name>
23
- ```
24
-
25
- ---
26
-
27
- ## Project Structure
28
-
29
- ```
30
- advai/ # core CLI (Python)
31
- __init__.py
32
- cli.py # entry point (click-based)
33
- skills.py # Skill install / uninstall / metadata logic
34
- Formula/advai.rb # Homebrew formula
35
- bin/advai.js # npm entry point bridge
36
- install.sh # one-click installer script
37
- pyproject.toml # PyPI build configuration
38
- package.json # npm package configuration
39
- ```
40
-
41
- ---
42
-
43
- ## Local Development
44
-
45
- ```bash
46
- # run from source
47
- python3 -m advai.cli --help
48
- ```
49
-
50
- ---
51
-
52
- ## License
53
-
54
- MIT
@@ -1 +0,0 @@
1
- __version__ = "1.0.2"
@@ -1,95 +0,0 @@
1
- import click
2
- import os
3
- import sys
4
-
5
- from advai import __version__
6
- from advai.skills import install_skill, uninstall_skill, list_skills, update_skill, info_skill
7
-
8
- SKILLS_DIR = os.path.expanduser("~/.advai/skills")
9
- CONFIG_DIR = os.path.expanduser("~/.advai")
10
-
11
-
12
- def _ensure_dirs():
13
- os.makedirs(SKILLS_DIR, exist_ok=True)
14
- os.makedirs(CONFIG_DIR, exist_ok=True)
15
-
16
-
17
- @click.group()
18
- @click.version_option(version=__version__, prog_name="advai")
19
- def cli():
20
- """advai — cross-platform AI Skill manager"""
21
- _ensure_dirs()
22
-
23
-
24
- @cli.command()
25
- @click.argument("skill_name")
26
- @click.option("--force", is_flag=True, help="Force reinstall (overwrite existing)")
27
- def install(skill_name, force):
28
- """Install a Skill: advai install <skill-name>"""
29
- try:
30
- install_skill(skill_name, force=force)
31
- click.echo(f"✅ Skill '{skill_name}' installed successfully")
32
- except FileExistsError:
33
- click.echo(f"⚠️ Skill '{skill_name}' already exists, use --force to overwrite")
34
- except Exception as e:
35
- click.echo(f"❌ Installation failed: {e}", err=True)
36
- sys.exit(1)
37
-
38
-
39
- @cli.command()
40
- @click.argument("skill_name")
41
- def uninstall(skill_name):
42
- """Uninstall a Skill: advai uninstall <skill-name>"""
43
- try:
44
- uninstall_skill(skill_name)
45
- click.echo(f"🗑️ Skill '{skill_name}' uninstalled")
46
- except FileNotFoundError:
47
- click.echo(f"⚠️ Skill '{skill_name}' is not installed")
48
- except Exception as e:
49
- click.echo(f"❌ Uninstall failed: {e}", err=True)
50
- sys.exit(1)
51
-
52
-
53
- @cli.command(name="list")
54
- def list_cmd():
55
- """List locally installed Skills"""
56
- skills = list_skills()
57
- if not skills:
58
- click.echo("(no Skills installed)")
59
- return
60
- click.echo("📋 Installed Skills:")
61
- for s in skills:
62
- click.echo(f" • {s}")
63
-
64
-
65
- @cli.command()
66
- @click.argument("skill_name", required=False)
67
- def update(skill_name):
68
- """Update one (or all) Skills: advai update [skill-name]"""
69
- try:
70
- updated = update_skill(skill_name)
71
- if updated:
72
- for s in updated:
73
- click.echo(f"🔄 {s} updated")
74
- else:
75
- click.echo("(nothing to update)")
76
- except Exception as e:
77
- click.echo(f"❌ Update failed: {e}", err=True)
78
- sys.exit(1)
79
-
80
-
81
- @cli.command()
82
- @click.argument("skill_name")
83
- def info(skill_name):
84
- """Show Skill details: advai info <skill-name>"""
85
- data = info_skill(skill_name)
86
- if data is None:
87
- click.echo(f"⚠️ Skill '{skill_name}' not installed or has no metadata")
88
- return
89
- click.echo(f"ℹ️ Skill '{skill_name}':")
90
- for k, v in data.items():
91
- click.echo(f" {k}: {v}")
92
-
93
-
94
- if __name__ == "__main__":
95
- cli()
@@ -1,64 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: advai-cli
3
- Version: 1.0.2
4
- Summary: Cross-platform AI Skill manager
5
- Author: advai
6
- License-Expression: MIT
7
- Requires-Python: >=3.8
8
- Description-Content-Type: text/markdown
9
- Requires-Dist: click>=8.1
10
-
11
- # advai-cli — Cross-platform AI Skill Manager
12
-
13
- A Python CLI that lets you install / uninstall AI Skills.
14
-
15
- - **Platforms**: macOS / Linux / Windows
16
- - **Installation**: pip, npm, or one-line script
17
- - **Commands**: install, uninstall, list, update, info
18
-
19
- ---
20
-
21
- ## Quick Start
22
-
23
- ```bash
24
- # pip (recommended)
25
- pip install advai-cli
26
-
27
- # install after installation, the `advai` command is ready to use
28
-
29
- Advai --help
30
- advai --version
31
- advai install <skill-name>
32
- advai uninstall <skill-name>
33
- ```
34
-
35
- ---
36
-
37
- ## Project Structure
38
-
39
- ```
40
- advai/ # core CLI (Python)
41
- __init__.py
42
- cli.py # entry point (click-based)
43
- skills.py # Skill install / uninstall / metadata logic
44
- Formula/advai.rb # Homebrew formula
45
- bin/advai.js # npm entry point bridge
46
- install.sh # one-click installer script
47
- pyproject.toml # PyPI build configuration
48
- package.json # npm package configuration
49
- ```
50
-
51
- ---
52
-
53
- ## Local Development
54
-
55
- ```bash
56
- # run from source
57
- python3 -m advai.cli --help
58
- ```
59
-
60
- ---
61
-
62
- ## License
63
-
64
- MIT
File without changes
File without changes