chore(skills): docs + ruff format for skill-management-console
Tests / Test passed: 855

Documents Skill Management in CLOUD_DEPLOYMENT.md (cloud-skill store,
per-host entitlement, incremental sync, local authoring/override,
inventory report, skills:admin scope) and applies ruff check/format to
all touched modules. All tasks complete; full non-integration suite
green (593 passed) and openspec validate --strict passes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 08:10:20 +08:00
co-authored by Claude Opus 4.6
parent fd0ea3a066
commit f8054cb58c
9 changed files with 83 additions and 53 deletions
+4 -4
View File
@@ -12,6 +12,7 @@ Authoring tools (``create_skill``/``update_skill``/``delete_skill``) dispatch by
origin (design D10): they edit/delete local skills and create/update/remove
local overrides for cloud skills, never writing to the synced store.
"""
from __future__ import annotations
from collections.abc import Callable
@@ -140,9 +141,7 @@ def skill_tool_handlers(
except ValueError as exc:
return _error_response(SkillAuthoringError(str(exc)))
if view.is_local_skill(skill_id):
stored = local.update_local(
_with_id(skill, skill_id)
)
stored = local.update_local(_with_id(skill, skill_id))
return {
"ok": True,
"skill": _skill_to_full_dict(stored),
@@ -308,7 +307,8 @@ def _build_skill(payload: dict[str, Any]) -> KnowledgeSkill | FlowTemplateSkill:
for step in (payload.get("steps") or [])
]
parameters = {
str(name): dict(schema) for name, schema in (payload.get("parameters") or {}).items()
str(name): dict(schema)
for name, schema in (payload.get("parameters") or {}).items()
}
return FlowTemplateSkill(metadata=meta, steps=steps, parameters=parameters)
+4 -11
View File
@@ -9,16 +9,15 @@ Override semantics (design D8/D9/D11): a local override shadows the cloud
skill at read time, wins against sync updates, and is reported with
``origin = "cloud"`` and ``locally_overridden = true`` while it shadows.
"""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Literal
from skills_learning.models import (
FlowTemplateSkill,
KnowledgeSkill,
Skill,
SkillMetadata,
)
from storage.local_skills import LocalSkillStore
@@ -72,9 +71,7 @@ class SkillCatalogView:
if meta.id in override_ids:
override = self._local.get_override(meta.id)
if override is not None:
summaries.append(
SkillSummary(override.metadata, "cloud", True)
)
summaries.append(SkillSummary(override.metadata, "cloud", True))
continue
summaries.append(SkillSummary(meta, "cloud", False))
@@ -96,9 +93,7 @@ class SkillCatalogView:
if meta.id in override_ids:
override = self._local.get_override(meta.id)
if override is not None:
summaries.append(
SkillSummary(override.metadata, "cloud", True)
)
summaries.append(SkillSummary(override.metadata, "cloud", True))
continue
summaries.append(SkillSummary(meta, "cloud", False))
@@ -148,9 +143,7 @@ class SkillCatalogView:
return self._local.has_override(cloud_skill_id)
def _tools_valid(
skill: FlowTemplateSkill, registered_tools: set[str]
) -> bool:
def _tools_valid(skill: FlowTemplateSkill, registered_tools: set[str]) -> bool:
return all(step.tool_name in registered_tools for step in skill.steps)
+3 -6
View File
@@ -7,6 +7,7 @@ truth" contract is enforced by that import boundary.
Push (webhook) is optional; the baseline pull loop is correct standalone.
"""
from __future__ import annotations
import logging
@@ -185,9 +186,7 @@ class CloudApiSkillClient:
response.raise_for_status()
return _parse_cloud_sync_payload(response.json())
def report_inventory(
self, host_id: str, inventory: list[dict[str, Any]]
) -> None:
def report_inventory(self, host_id: str, inventory: list[dict[str, Any]]) -> None:
"""Best-effort local-skill inventory report to the Cloud (design D7)."""
response = self._ensure_client().post(
f"{self.base_url}/internal/v1/hosts/{host_id}/skills/inventory",
@@ -312,9 +311,7 @@ class SkillSyncRunner:
subscription_id, since_version=since_version
)
except Exception as exc:
log.warning(
"skill sync fetch failed for %s: %s", subscription_id, exc
)
log.warning("skill sync fetch failed for %s: %s", subscription_id, exc)
self.store._set_subscription_state(
subscription_id,
last_error=f"{type(exc).__name__}: {exc}",