usecli 0.1.47__tar.gz → 0.1.48__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.
- {usecli-0.1.47 → usecli-0.1.48}/PKG-INFO +1 -2
- {usecli-0.1.47 → usecli-0.1.48}/pyproject.toml +1 -2
- usecli-0.1.47/src/usecli/cli/core/skill_generator.py +0 -153
- {usecli-0.1.47 → usecli-0.1.48}/LICENSE +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/README.md +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/README.md +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/custom/README.md +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/custom/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/about_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/help_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/inspire_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/internal/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/core/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/core/utils.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/make/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/make/make_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/make/make_theme_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/init_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/config/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/config/colors.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/base_command.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/error/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/error/handler.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/error/utils.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/exceptions/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/exceptions/base.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/exceptions/config.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/exceptions/usage.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/exceptions/validation.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/ui/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/ui/list.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/ui/title.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/ui/title.txt +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/validators/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/validators/network.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/validators/numeric.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/validators/path.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/core/validators/string.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/services/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/services/command_service.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/templates/command.py.j2 +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/templates/theme.toml.j2 +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/templates/usecli.config.toml.j2 +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/ayu_dark.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/catppuccin_frappe.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/catppuccin_latte.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/catppuccin_macchiato.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/catppuccin_mocha.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/default.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/dracula.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/gruvbox_dark.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/nord.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/themes/tokyo_night.toml +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/utils/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/utils/interactive/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/utils/interactive/terminal_menu.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/menu.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/params.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/shared/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/shared/config/__init__.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/shared/config/globals.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/shared/config/manager.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/ui.py +0 -0
- {usecli-0.1.47 → usecli-0.1.48}/src/usecli/usecli.config.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: usecli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.48
|
|
4
4
|
Summary: A powerful Python CLI framework for building beautiful, developer-friendly command-line tools.
|
|
5
5
|
Author: Edward Boswell
|
|
6
6
|
Author-email: Edward Boswell <thememium@gmail.com>
|
|
@@ -14,7 +14,6 @@ Requires-Dist: click>=8.3.1
|
|
|
14
14
|
Requires-Dist: fzf-bin>=0.67.0
|
|
15
15
|
Requires-Dist: jinja2>=3.1.6
|
|
16
16
|
Requires-Dist: pyfiglet>=1.0.4
|
|
17
|
-
Requires-Dist: pyyaml>=6.0.2
|
|
18
17
|
Requires-Dist: rich>=14.3.1
|
|
19
18
|
Requires-Dist: simple-term-menu>=1.6.6
|
|
20
19
|
Requires-Dist: tomli>=2.4.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "usecli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.48"
|
|
4
4
|
description = "A powerful Python CLI framework for building beautiful, developer-friendly command-line tools."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Edward Boswell", email = "thememium@gmail.com" }]
|
|
@@ -16,7 +16,6 @@ dependencies = [
|
|
|
16
16
|
"fzf-bin>=0.67.0",
|
|
17
17
|
"jinja2>=3.1.6",
|
|
18
18
|
"pyfiglet>=1.0.4",
|
|
19
|
-
"pyyaml>=6.0.2",
|
|
20
19
|
"rich>=14.3.1",
|
|
21
20
|
"simple-term-menu>=1.6.6",
|
|
22
21
|
"tomli>=2.4.0",
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
"""Skill generator for OpenCode and Claude Code compatibility."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
7
|
-
|
|
8
|
-
import yaml
|
|
9
|
-
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
|
10
|
-
|
|
11
|
-
if TYPE_CHECKING:
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class SkillGenerator:
|
|
16
|
-
"""Generates AI assistant skills for OpenCode and Claude Code."""
|
|
17
|
-
|
|
18
|
-
SKILLS = [
|
|
19
|
-
"usecli-new",
|
|
20
|
-
"usecli-plan",
|
|
21
|
-
"usecli-apply",
|
|
22
|
-
"usecli-sync",
|
|
23
|
-
"usecli-verify",
|
|
24
|
-
"usecli-archive",
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
def __init__(self, templates_dir: Path | None = None) -> None:
|
|
28
|
-
"""Initialize the skill generator.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
templates_dir: Directory containing Jinja2 templates.
|
|
32
|
-
Defaults to built-in templates.
|
|
33
|
-
"""
|
|
34
|
-
if templates_dir is None:
|
|
35
|
-
templates_dir = Path(__file__).parent.parent / "templates" / "skills"
|
|
36
|
-
|
|
37
|
-
self.templates_dir = templates_dir
|
|
38
|
-
self.env = Environment(
|
|
39
|
-
loader=FileSystemLoader(str(templates_dir)),
|
|
40
|
-
autoescape=select_autoescape(),
|
|
41
|
-
)
|
|
42
|
-
self.env.filters["escape_yaml"] = self._escape_yaml
|
|
43
|
-
self.env.filters["to_yaml"] = self._to_yaml
|
|
44
|
-
|
|
45
|
-
def _escape_yaml(self, text: str) -> str:
|
|
46
|
-
"""Escape special YAML characters in text.
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
text: The text to escape.
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
YAML-escaped text.
|
|
53
|
-
"""
|
|
54
|
-
# Handle multi-line strings, quotes, special chars
|
|
55
|
-
if "\n" in text or '"' in text or "'" in text or ":" in text:
|
|
56
|
-
# Use literal block scalar for multi-line strings
|
|
57
|
-
if "\n" in text:
|
|
58
|
-
escaped = text.replace("\\", "\\\\")
|
|
59
|
-
return f'"{escaped.replace(chr(34), chr(92) + chr(34))}"'
|
|
60
|
-
# Escape quotes for single-line strings
|
|
61
|
-
return f'"{text.replace(chr(34), chr(92) + chr(34))}"'
|
|
62
|
-
return text
|
|
63
|
-
|
|
64
|
-
def _to_yaml(self, obj: list[Any] | dict[str, Any]) -> str:
|
|
65
|
-
"""Convert object to YAML string.
|
|
66
|
-
|
|
67
|
-
Args:
|
|
68
|
-
obj: List or dictionary to convert.
|
|
69
|
-
|
|
70
|
-
Returns:
|
|
71
|
-
YAML-formatted string.
|
|
72
|
-
"""
|
|
73
|
-
return yaml.dump(obj, default_flow_style=False).strip()
|
|
74
|
-
|
|
75
|
-
def generate_skill(
|
|
76
|
-
self,
|
|
77
|
-
skill_name: str,
|
|
78
|
-
target: str,
|
|
79
|
-
context: dict[str, Any],
|
|
80
|
-
) -> str:
|
|
81
|
-
"""Generate a skill file for the specified target.
|
|
82
|
-
|
|
83
|
-
Args:
|
|
84
|
-
skill_name: Name of the skill (e.g., 'usecli-explore')
|
|
85
|
-
target: Target platform ('opencode' or 'claude')
|
|
86
|
-
context: Template variables
|
|
87
|
-
|
|
88
|
-
Returns:
|
|
89
|
-
Generated skill content as string
|
|
90
|
-
|
|
91
|
-
Raises:
|
|
92
|
-
ValueError: If target is not 'opencode' or 'claude'
|
|
93
|
-
TemplateNotFound: If the skill template doesn't exist
|
|
94
|
-
"""
|
|
95
|
-
if target not in ("opencode", "claude"):
|
|
96
|
-
msg = f"Invalid target: {target}. Must be 'opencode' or 'claude'"
|
|
97
|
-
raise ValueError(msg)
|
|
98
|
-
|
|
99
|
-
template = self.env.get_template(f"{skill_name}/SKILL.md.j2")
|
|
100
|
-
return template.render(target=target, **context)
|
|
101
|
-
|
|
102
|
-
def generate_all_skills(
|
|
103
|
-
self,
|
|
104
|
-
target: str,
|
|
105
|
-
output_dir: Path,
|
|
106
|
-
version: str = "1.0.0",
|
|
107
|
-
generated_by: str = "useCli",
|
|
108
|
-
) -> list[Path]:
|
|
109
|
-
"""Generate all skills for a target platform.
|
|
110
|
-
|
|
111
|
-
Args:
|
|
112
|
-
target: 'opencode' or 'claude'
|
|
113
|
-
output_dir: Directory to write generated files
|
|
114
|
-
version: Version string for metadata
|
|
115
|
-
generated_by: Generator attribution string
|
|
116
|
-
|
|
117
|
-
Returns:
|
|
118
|
-
List of generated file paths
|
|
119
|
-
|
|
120
|
-
Raises:
|
|
121
|
-
ValueError: If target is not 'opencode' or 'claude'
|
|
122
|
-
"""
|
|
123
|
-
if target not in ("opencode", "claude"):
|
|
124
|
-
msg = f"Invalid target: {target}. Must be 'opencode' or 'claude'"
|
|
125
|
-
raise ValueError(msg)
|
|
126
|
-
|
|
127
|
-
generated = []
|
|
128
|
-
context = {
|
|
129
|
-
"version": version,
|
|
130
|
-
"generated_by": generated_by,
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
for skill_name in self.SKILLS:
|
|
134
|
-
content = self.generate_skill(
|
|
135
|
-
skill_name=skill_name,
|
|
136
|
-
target=target,
|
|
137
|
-
context=context,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
if target == "opencode":
|
|
141
|
-
output_path = (
|
|
142
|
-
output_dir / ".opencode" / "skills" / skill_name / "SKILL.md"
|
|
143
|
-
)
|
|
144
|
-
else: # claude
|
|
145
|
-
output_path = (
|
|
146
|
-
output_dir / ".claude" / "skills" / skill_name / "SKILL.md"
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
150
|
-
output_path.write_text(content)
|
|
151
|
-
generated.append(output_path)
|
|
152
|
-
|
|
153
|
-
return generated
|
|
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
|
{usecli-0.1.47 → usecli-0.1.48}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|