branch_health
Quick health check -- test counts and file stats for AIPass branches
Password-lock the machine's screen while every process keeps running, and read whether it is locked
$ npx -y skills add AIOSAI/AIPass --skill screen_lock --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/screen_lockContext preview
The summary Claude sees to decide when to auto-load this skill.
Password-lock the machine's screen while every process keeps running, and read whether it is locked
name: screen_lock description: Password-lock the machine's screen while every process keeps running, and read whether it is locked version: 1.1.0 tags: [system, control, security] when_to_use: - "lock the screen" - "lock the machine" - "walking away from the desk, keep the agents running" - "did I lock the laptop" requires: pip: [] bins: [loginctl] config: [] has_handler: true
Password-locks the graphical session and leaves everything running — agents keep working behind the password wall. Nothing sleeps, nothing is killed, no root is needed (no sudoers grant, no polkit rule).
Two paths, tried in order:
1. `loginctl lock-session <id>` against the **explicitly resolved** graphical session. Callers usually run as a `systemd --user` service with no `XDG_SESSION_ID`, so a bare `lock-session` has no ambient session to resolve and may refuse — naming the session is what makes the verb work from there. 2. `gdbus` → `org.gnome.ScreenSaver.Lock` as the fallback.
If both fail it says so. A screen that never locked is never reported as locked.
> A destructive action never fires from a locked screen. **Lock itself must work > from anywhere — that is its whole point.**
So this verb is never gated: it does not ask whether the screen is already locked, does not require a desktop environment, and does not refuse when no graphical session can be resolved (it still tries the bare call). Callers that gate *other* verbs on screen state must leave this one ungated.
`lock_state()` answers whether the screen **is** locked — the question "did I lock the laptop?" asked from away (FPLAN-0585). It reads through the same pair the lock writes through, in the same order, and changes nothing:
1. `loginctl show-session <id> -p LockedHint` on the resolved graphical session — the logind mechanism `lock-session` sets, so read and write agree. 2. `gdbus` → `org.gnome.ScreenSaver.GetActive` when logind cannot answer. (`org.freedesktop.ScreenSaver.GetActive` is not implemented on GNOME and is never asked.)
It is not gated either — the lock never is, so its read is not — and it never raises. **Unknown is never unlocked:** a read that cannot tell answers `ok: False, locked: None` with a reason code, never `locked: False`.
| `reason` | Meaning | |---------------|------------------------------------------------------------------| | `no_session` | logind lists no active graphical session of ours, and D-Bus did not answer | | `no_reader` | neither `loginctl` nor `gdbus` is installed | | `read_failed` | a reader ran and failed, or answered something other than yes/no |
| Action | Description | |---------|----------------------------------------------------| | `lock` | Lock the screen now; agents keep running | | `state` | Read whether the screen is locked; locks nothing |
drone @skills run screen_lock lock drone @skills run screen_lock state
In-process (what the host API verb lane uses):
from aipass.skills.lib.screen_lock import handler as screen_lock
result = screen_lock.lock_screen()
# {"locked": True, "method": "loginctl", "session": "3", "error": None}
state = screen_lock.lock_state()
# {"ok": True, "locked": False, "method": "loginctl", "session": "3",
# "reason": None, "detail": "The screen is unlocked, per logind session 3."}Use this skill when:
Do NOT use this skill when:
wake, grace-window and reachability story. Lock never suspends.
`run()` returns the standard skill envelope:
{"success": True, "output": "Screen locked via loginctl (session=3)", "error": None}`lock_screen()` returns structured detail for programmatic callers:
{"locked": bool, "method": "loginctl" | "dbus" | None, "session": str | None, "error": str | None}`lock_state()` returns the read, six keys every time:
{
"ok": bool, # True when a reader answered
"locked": bool | None, # None whenever ok is False
"method": "loginctl" | "dbus" | None,
"session": str | None, # the resolved logind session
"reason": "no_session" | "no_reader" | "read_failed" | None,
"detail": str, # the skill's own sentence
}`run("state")` puts `detail` in `output` when the read answered, and fails the envelope with `detail (reason=<code>)` when it cannot tell.
stack, no bot, no network client. A test asserts that in a clean interpreter.
without locking anything.
required for the skill to be usable.
eligible — another user's desktop is never locked.
Persistent Agent Workspace — AI agents that remember, collaborate, and never start from zero.
Quick health check -- test counts and file stats for AIPass branches
Execute drone commands -- the AIPass CLI interface for all module operations
GitHub operations via gh CLI: issues, PRs, CI runs, code review, API queries.
Check system health -- disk usage, memory, running processes, uptime, battery