aiosai/aipass/screen-lock

Claude Code and agent skill by aiosai/aipass

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Password-lock the machine's screen while every process keeps running, and read whether it is locked

Install

npx vskill@latest install aiosai/aipass/screen-lock

SKILL.md

Screen Lock

What This Does

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.

  1. gdbus → org.gnome.ScreenSaver.Lock as the fallback.

If both fail it says so. A screen that never locked is never reported as locked.

Doctrine — lock is the exception

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.

The read beside the lock

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.

  1. 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.

reasonMeaning
no_sessionlogind lists no active graphical session of ours, and D-Bus did not answer
no_readerneither loginctl nor gdbus is installed
read_faileda reader ran and failed, or answered something other than yes/no

Available Actions

ActionDescription
lockLock the screen now; agents keep running
stateRead whether the screen is locked; locks nothing

Usage

bash
drone @skills run screen_lock lock
drone @skills run screen_lock state

In-process (what the host API verb lane uses):

python
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."}

When to Use

Use this skill when:

  • You are leaving the machine and want the screen locked with work continuing
  • A remote surface (phone, host API, chat bot) needs to secure the desk

Do NOT use this skill when:

  • You want the machine to sleep — that is /suspend, a different verb with a

wake, grace-window and reachability story. Lock never suspends.

  • You want to end sessions — nothing is stopped or killed here.

Output Format

run() returns the standard skill envelope:

python
{"success": True, "output": "Screen locked via loginctl (session=3)", "error": None}

lock_screen() returns structured detail for programmatic callers:

python
{"locked": bool, "method": "loginctl" | "dbus" | None, "session": str | None, "error": str | None}

lock_state() returns the read, six keys every time:

python
{
"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.

Notes

  • Stdlib + the Prax logger only — importing this skill pulls in no Telegram

stack, no bot, no network client. A test asserts that in a clean interpreter.

  • resolve_graphical_session() is public: callers can ask which session is ours

without locking anything.

  • loginctl is the declared requirement; gdbus is the fallback and is not

required for the skill to be usable.

  • Only sessions of type wayland/x11, state active, owned by our own uid are

eligible — another user's desktop is never locked.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
305
Repository forks
45
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/aiosai/aipass/screen-lock/badge)](https://verified-skill.com/skills/aiosai/aipass/screen-lock)

Something wrong with this skill or its page? Tell us.