@smilintux/skcapstone 0.4.4 → 0.4.5
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/package.json
CHANGED
|
@@ -212,7 +212,10 @@ class AgentCard(BaseModel):
|
|
|
212
212
|
content = self.content_hash().encode("utf-8")
|
|
213
213
|
pgp_message = pgpy.PGPMessage.new(content, cleartext=False)
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
if key.is_protected:
|
|
216
|
+
with key.unlock(passphrase):
|
|
217
|
+
sig = key.sign(pgp_message)
|
|
218
|
+
else:
|
|
216
219
|
sig = key.sign(pgp_message)
|
|
217
220
|
|
|
218
221
|
self.signature = str(sig)
|
|
@@ -48,20 +48,34 @@ def register_card_commands(main: click.Group) -> None:
|
|
|
48
48
|
except FileNotFoundError:
|
|
49
49
|
runtime = get_runtime(home_path)
|
|
50
50
|
m = runtime.manifest
|
|
51
|
+
# Try to load public key from capauth
|
|
52
|
+
pub_key = ""
|
|
53
|
+
pub_path = Path(capauth_home).expanduser() / "identity" / "public.asc"
|
|
54
|
+
if pub_path.exists():
|
|
55
|
+
pub_key = pub_path.read_text(encoding="utf-8")
|
|
51
56
|
agent_card = AgentCard.generate(
|
|
52
57
|
name=m.name, fingerprint=m.identity.fingerprint or "unknown",
|
|
53
|
-
public_key=
|
|
58
|
+
public_key=pub_key, entity_type="ai",
|
|
54
59
|
)
|
|
55
60
|
|
|
56
61
|
if motto:
|
|
57
62
|
agent_card.motto = motto
|
|
58
63
|
|
|
59
64
|
if do_sign:
|
|
60
|
-
if not passphrase:
|
|
61
|
-
passphrase = click.prompt("PGP passphrase", hide_input=True)
|
|
62
65
|
capauth_path = Path(capauth_home).expanduser()
|
|
63
66
|
priv_path = capauth_path / "identity" / "private.asc"
|
|
64
67
|
if priv_path.exists():
|
|
68
|
+
# Check if key is passphrase-protected before prompting
|
|
69
|
+
if not passphrase:
|
|
70
|
+
try:
|
|
71
|
+
import pgpy
|
|
72
|
+
key, _ = pgpy.PGPKey.from_file(str(priv_path))
|
|
73
|
+
if key.is_protected:
|
|
74
|
+
passphrase = click.prompt("PGP passphrase", hide_input=True)
|
|
75
|
+
else:
|
|
76
|
+
passphrase = ""
|
|
77
|
+
except Exception:
|
|
78
|
+
passphrase = click.prompt("PGP passphrase", hide_input=True)
|
|
65
79
|
agent_card.sign(priv_path.read_text(encoding="utf-8"), passphrase)
|
|
66
80
|
console.print("[green]Card signed.[/]")
|
|
67
81
|
else:
|
|
@@ -50,19 +50,49 @@ def register_skills_commands(main: click.Group) -> None:
|
|
|
50
50
|
|
|
51
51
|
skcapstone skills list --query identity --json
|
|
52
52
|
"""
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"[bold red]skskills not installed.[/] "
|
|
57
|
-
"Run: pip install skskills"
|
|
58
|
-
)
|
|
59
|
-
sys.exit(1)
|
|
53
|
+
# Try remote registry first, fall back to local catalog
|
|
54
|
+
skill_entries = None
|
|
55
|
+
source = "remote"
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
client = get_registry_client(registry)
|
|
58
|
+
if client is not None:
|
|
59
|
+
try:
|
|
60
|
+
skill_entries = client.search(query) if query else client.list_skills()
|
|
61
|
+
except Exception:
|
|
62
|
+
pass # fall through to local catalog
|
|
63
|
+
|
|
64
|
+
# Fall back to local catalog (bundled with skskills)
|
|
65
|
+
if skill_entries is None:
|
|
66
|
+
try:
|
|
67
|
+
from skskills.catalog import SkillCatalog
|
|
68
|
+
|
|
69
|
+
catalog = SkillCatalog()
|
|
70
|
+
if query:
|
|
71
|
+
entries = catalog.search(query)
|
|
72
|
+
else:
|
|
73
|
+
entries = catalog.list_all()
|
|
74
|
+
skill_entries = [
|
|
75
|
+
{
|
|
76
|
+
"name": e.name,
|
|
77
|
+
"version": "",
|
|
78
|
+
"description": e.description,
|
|
79
|
+
"tags": e.tags,
|
|
80
|
+
"category": e.category,
|
|
81
|
+
"pip": e.pip,
|
|
82
|
+
"git": e.git,
|
|
83
|
+
}
|
|
84
|
+
for e in entries
|
|
85
|
+
]
|
|
86
|
+
source = "catalog"
|
|
87
|
+
except ImportError:
|
|
88
|
+
console.print(
|
|
89
|
+
"[bold red]skskills not installed.[/] "
|
|
90
|
+
"Run: pip install skskills"
|
|
91
|
+
)
|
|
92
|
+
sys.exit(1)
|
|
93
|
+
except Exception as exc:
|
|
94
|
+
console.print(f"[bold red]Catalog error:[/] {exc}")
|
|
95
|
+
sys.exit(1)
|
|
66
96
|
|
|
67
97
|
if json_out:
|
|
68
98
|
click.echo(json.dumps(skill_entries, indent=2))
|
|
@@ -76,17 +106,19 @@ def register_skills_commands(main: click.Group) -> None:
|
|
|
76
106
|
label = f"[bold]{len(skill_entries)}[/] skill(s)"
|
|
77
107
|
if query:
|
|
78
108
|
label += f" matching [cyan]'{query}'[/]"
|
|
109
|
+
if source == "catalog":
|
|
110
|
+
label += " [dim](local catalog)[/]"
|
|
79
111
|
|
|
80
112
|
table = Table(show_header=True, header_style="bold", box=None, padding=(0, 2))
|
|
81
113
|
table.add_column("Name", style="cyan")
|
|
82
|
-
table.add_column("
|
|
114
|
+
table.add_column("Category", style="dim")
|
|
83
115
|
table.add_column("Description")
|
|
84
116
|
table.add_column("Tags", style="dim")
|
|
85
117
|
|
|
86
118
|
for s in skill_entries:
|
|
87
119
|
table.add_row(
|
|
88
120
|
s.get("name", ""),
|
|
89
|
-
s.get("version", ""),
|
|
121
|
+
s.get("category", s.get("version", "")),
|
|
90
122
|
s.get("description", ""),
|
|
91
123
|
", ".join(s.get("tags", [])),
|
|
92
124
|
)
|