Names collide across resource types (a program and a service can share a name),
so the CLI no longer resolves bare names. Operations live under the resource
they act on; platform lifecycle and the cross-resource overview stay top-level.
castle program list|info|create|add|clone|delete|run|install|uninstall|
build|test|lint|format|type-check|check
castle service list|info|create|delete|deploy|enable|disable|start|stop|restart|logs
castle job <same verbs> (create takes --schedule)
castle gateway start|stop|reload|status
castle list | status | deploy [name] # cross-cutting
castle start | stop | restart # whole platform (systemd verbs)
Key changes:
- info/delete/list/run are resource-scoped (no more cross-section name match).
- delete only removes the named resource's entry; program delete still blocks
when a deployment references it.
- per-resource start/stop/restart (systemctl on the unit/timer); top-level
start/stop/restart act on the whole platform.
- expose → 'service create' (more general: --program ref, --runner); gained
'job create' (the CLI never had one).
- dropped up/down — bringing things online is the honest 'deploy && start'.
Docs (CLAUDE.md, registry.md, stack guides) and user-facing messages updated.
core 94 / cli 24 / api 52 green; ruff clean. Verified live: program/service/job
list+info scope correctly, service create+scoped-delete round-trips.
22 lines
575 B
Python
22 lines
575 B
Python
"""castle deploy — thin CLI wrapper around castle_core.deploy."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
|
|
from castle_core.deploy import deploy
|
|
|
|
|
|
def run_deploy(args: argparse.Namespace) -> int:
|
|
"""Deploy from castle.yaml to ~/.castle/."""
|
|
target_name = getattr(args, "name", None)
|
|
result = deploy(target_name=target_name)
|
|
|
|
for msg in result.messages:
|
|
print(f" {msg}")
|
|
|
|
print(f"\nDeployed {result.deployed_count} item(s).")
|
|
if result.deployed_count > 0:
|
|
print("Run 'castle start' to start all services.")
|
|
return 0
|