Hook Development for Claude Code Plugins
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
Query flow event logs to answer questions about past sensing events — "Have you seen anybody between 10pm and midnight?", "Is there any motion in the last hour?", "What happened while I was away?".
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-track --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/sensing-track .claude/skills/sensing-track && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .claude/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-trackType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-track --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/sensing-track .agents/skills/sensing-track && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .agents/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-track --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/sensing-track .cursor/skills/sensing-track && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .cursor/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/autonomous-ai/Physical-AI-Operating-System.git --path skills/sensing-track--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-track --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/sensing-track .gemini/skills/sensing-track && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .gemini/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-trackInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/sensing-track .github/skills/sensing-track && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .github/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install autonomous-ai/Physical-AI-Operating-System sensing-track --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/sensing-track .opencode/skills/sensing-track && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "sensing-track" agent skill from https://github.com/autonomous-ai/Physical-AI-Operating-System/tree/main/skills/sensing-track into .opencode/skills/sensing-track/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sensing-track", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
sensing-trackQuery flow event logs to answer questions about past sensing events — "Have you seen anybody between 10pm and midnight?", "Is there any motion in the last hour?", "What happened while I was away?".
Sensing Track is an agent skill from autonomous-ai/Physical-AI-Operating-System. Query flow event logs to answer questions about past sensing events — "Have you seen anybody between 10pm and midnight?", "Is there any motion in the last hour?", "What happened while I was away?". Also holds your OWN sleep history — "how many times have you slept?", "when do you usually go to sleep?".
Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `skill.json`).
It works with Bash. The repository describes itself as: The open-source operating system for physical AI. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 1bbd649. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
jqcurlFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use curl, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Sensing Track loads about 4.3k tokens when it runs. Until then it costs about 79 tokens; SKILL.md has 1,516 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from autonomous-ai/Physical-AI-Operating-System at commit 1bbd649, republished under its Apache-2.0 licence (© autonomous-ai). 1,516 words, ~4,312 tokens.
.claude/skills/sensing-track/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.The primary data source is the flow events JSONL at /root/local/flow_events_YYYY-MM-DD.jsonl. Each file covers one calendar day (7-day retention, no size-rotation mid-day). Use Bash + jq to query it.
Important: Always use the absolute path
/root/local/— thereadtool cannot access files outside the workspace, so useexec(Bash) for all JSONL queries.
Persistent camera snapshots are stored under /var/lib/hal/snapshots/sensing_<prefix>/<ms>.jpg (72h TTL, 50 MB cap) — one subdir per event kind:
| Event type | Folder |
|---|---|
presence.enter, presence.leave | sensing_face/ |
motion.activity | sensing_motion_activity/ |
emotion.detected | sensing_emotion/ |
Reference these when the user asks what happened visually.
Each line is a JSON object:
{"kind":"enter","node":"sensing_input","ts":1712345678.123,"seq":42,"trace_id":"run-abc","data":{"type":"presence.enter","message":"Person detected — new: friend (gray); faces in frame: 1 (gray)\n[snapshot: /var/lib/hal/snapshots/sensing_face/1712345678123.jpg]"},"version":"1.2.3"}
{"kind":"exit","node":"sensing_input","ts":1712345678.456,"seq":43,"trace_id":"run-abc","duration_ms":332,"data":{"path":"agent","run_id":"run-abc"},"version":"1.2.3"}Key fields:
node — filter on "sensing_input" for sensing eventskind — "enter" = event received, "exit" = event processed (with duration_ms)data.type — event type: presence.enter, presence.leave, motion, motion.activity, sound, light.level, voice, voice_command, emotion.detected, speech_emotion.detecteddata.message — natural-language description; may contain [snapshot: /var/lib/hal/snapshots/sensing_<prefix>/<ms>.jpg]data.path — in exit records: "agent" (forwarded), "local" (handled locally), or has "error" key (failed/dropped)ts — Unix timestamp (seconds with fractional ms)trace_id — correlates enter/exit and links to agent turnBash — jq, cat, date arithmetic. No writes.
export TZ=$(cat /etc/timezone)export TZ=$(cat /etc/timezone)
DATE="$(date +%Y-%m-%d)"
FROM_TS=$(date -d "$DATE 22:00:00" +%s)
TO_TS=$(date -d "$DATE 23:59:59" +%s)
jq -c 'select(.node=="sensing_input" and .kind=="enter" and .ts >= '"$FROM_TS"' and .ts <= '"$TO_TS"')' \
"/root/local/flow_events_${DATE}.jsonl"Use "motion" for raw motion, "motion.activity" for activity analysis (HAL-categorised — bucket names drink/break/celebrate and raw Kinetics sedentary labels like using computer, writing, reading). Most queries want both:
For any relative range, select every local calendar day's file intersecting that range, including yesterday when crossing midnight. Run this range setup and the chosen query in the same Bash call; do not assume variables survive between tool calls. GNU date -d is available on the device.
export TZ=$(cat /etc/timezone)
SINCE=$(date -d "1 hour ago" +%s)
UNTIL=$(date +%s)
first_day=$(date -d "@$SINCE" +%F)
last_day=$(date -d "@$UNTIL" +%F)
range_files=()
range_day=$first_day
while [[ "$range_day" < "$last_day" || "$range_day" == "$last_day" ]]; do
range_file="/root/local/flow_events_${range_day}.jsonl"
if [ -r "$range_file" ]; then
range_files+=("$range_file")
else
printf 'History unavailable for %s\n' "$range_day" >&2
fi
range_day=$(date -d "$range_day +1 day" +%F)
done
if [ "${#range_files[@]}" -gt 0 ]; then
jq -c --argjson since "$SINCE" --argjson until "$UNTIL" \
'select(.node=="sensing_input" and .kind=="enter" and .ts >= $since and .ts <= $until and (.data.type=="motion" or .data.type=="motion.activity"))' \
"${range_files[@]}"
fiUse the same range setup above with SINCE=$(date -d "30 minutes ago" +%s) and remove the type predicate from the jq filter. Keep both time bounds and all range_files; even 30 minutes can span two local dates.
Names in messages are lowercase (friend (gray)). Use test() with "i" flag for case-insensitive search:
TODAY=$(date +%Y-%m-%d)
# All presence events
jq -c 'select(.node=="sensing_input" and .kind=="enter" and (.data.type=="presence.enter" or .data.type=="presence.leave"))' \
"/root/local/flow_events_${TODAY}.jsonl"
# Search for a specific person (case-insensitive)
jq -c 'select(.node=="sensing_input" and .kind=="enter" and .data.type=="presence.enter" and (.data.message | test("gray";"i")))' \
"/root/local/flow_events_${TODAY}.jsonl"export TZ=$(cat /etc/timezone)
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
TODAY=$(date +%Y-%m-%d)
cat "/root/local/flow_events_${YESTERDAY}.jsonl" "/root/local/flow_events_${TODAY}.jsonl" \
| jq -c 'select(.node=="sensing_input" and .kind=="enter" and .ts >= '"$FROM_TS"' and .ts <= '"$TO_TS"')'TODAY=$(date +%Y-%m-%d)
jq -c 'select(.node=="sensing_input" and .kind=="exit" and .data.error != null)' \
"/root/local/flow_events_${TODAY}.jsonl"Snapshots are bucketed into sensing_face/ (presence), sensing_motion_activity/, sensing_emotion/. Recurse into subdirs:
# Most-recent snapshots across all categories
find /var/lib/hal/snapshots -type f -name '*.jpg' -printf '%T@ %p\n' | sort -rn | head -20 | cut -d' ' -f2-
# Only a specific category
ls -lt /var/lib/hal/snapshots/sensing_motion_activity/ | head -20Posture snapshots are NOT in /var/lib/hal/snapshots/ — they live in tmp under a per-window bucket layout at /tmp/hal-sensing-snapshots/sensing_pose/buckets/<bucket_id>/. A bucket only exists when a tumbling window closed with bad posture (bad_ratio >= POSE_BAD_RATIO). Kept buckets survive ~2 days (POSE_BUCKET_KEEP_S); windows that didn't fire a nudge are deleted immediately, so the buckets you can see are by definition "bad posture" sessions.
Each kept bucket contains:
<sample_ts>_<score>.jpg — annotated frame per sample (skeleton overlay + RULA score)bucket.json — manifest:bucket_id, window_start_ts, window_end_ts, kept: truesummary — same shape as the [posture_summary:] block on motion.activity (bad_ratio, dominant_region, samples, …)samples[] — {ts, score, risk_level, filename, left, right} (per-side RULA body_scores + angles)worst_snapshots[] — pre-selected worst filenames (the ones the device auto-attaches to /dm on posture nudges)# List recent buckets (newest first)
ls -lt /tmp/hal-sensing-snapshots/sensing_pose/buckets/ | head -10
# Read a specific bucket's manifest
jq . /tmp/hal-sensing-snapshots/sensing_pose/buckets/1779259742/bucket.json
# Buckets that closed in the last 2 hours
find /tmp/hal-sensing-snapshots/sensing_pose/buckets -maxdepth 1 -type d -mmin -120 -name '[0-9]*' | sort
# Worst-frame paths from the latest kept bucket
LATEST=$(ls -t /tmp/hal-sensing-snapshots/sensing_pose/buckets/ | head -1)
jq -r '.worst_snapshots[]' "/tmp/hal-sensing-snapshots/sensing_pose/buckets/${LATEST}/bucket.json" \
| sed "s|^|/tmp/hal-sensing-snapshots/sensing_pose/buckets/${LATEST}/|"
# Today's bad-posture sessions — bucket id == window_start unix-seconds
TODAY_START=$(date -d "today 00:00" +%s)
for b in /tmp/hal-sensing-snapshots/sensing_pose/buckets/*/bucket.json; do
jq --arg start "$TODAY_START" 'select((.window_start_ts | floor) >= ($start | tonumber)) | {bucket_id, dominant: .summary.dominant_region, bad_ratio: .summary.bad_ratio, started: .window_start_ts}' "$b"
doneNote: motion.activity event messages contain [pose_bucket: <id>] and [pose_worst: <fn1>,<fn2>,...] markers — parse these out of data.message when you need to map a sensing_input record to its bucket. Markers are present whenever a posture nudge folded in.
For detailed debugging or when you need Go-side log context (errors, warnings, lifecycle details), fall back to ${OS_LOG:-/var/log/os-server.log}:
LOG="${OS_LOG:-/var/log/os-server.log}"
sed 's/\x1b\[[0-9;]*m//g' "$LOG" | grep "sensing event received"The system log uses lumberjack rotation (1 MB cap, 3 backups) — it may miss data during high traffic. Use it only when JSONL doesn't have enough detail, or when investigating bugs.
A dedicated mood history log tracks user mood per user. Only the user's emotional state is logged — not system events or device emotions. Each user's mood data lives in their own directory.
Read API:
# Current user's mood history (auto-detects who's present)
curl -s "http://127.0.0.1:5000/api/openclaw/mood-history?date=$(date +%Y-%m-%d)&last=100"
# Specific user's mood history
curl -s "http://127.0.0.1:5000/api/openclaw/mood-history?user=gray&date=$(date +%Y-%m-%d)&last=100"Write: Follow the Mood skill to log user mood from camera or conversation.
{"ts":1776138500,"seq":1,"hour":10,"mood":"happy","source":"camera","trigger":"laughing"}
{"ts":1776139200,"seq":2,"hour":10,"mood":"stressed","source":"conversation","trigger":"user said feeling overwhelmed"}Storage: /root/local/users/{name}/mood/YYYY-MM-DD.jsonl (30-day retention).
Your own sleep — when you went to sleep and woke up, not the user's. Use it for "how many times have you slept?", "when do you usually go to sleep?", "did you sleep while I was out?".
Storage: /root/local/device/sleep/YYYY-MM-DD.jsonl (30-day retention). One line per
transition, appended:
{"ts":1758000000.12,"local":"2026-09-16T22:00:00+07:00","tz":"Asia/Ho_Chi_Minh","date":"2026-09-16","hour":22,"event":"sleep","emotion":"sleepy","source":"api"}
{"ts":1758021600.45,"local":"2026-09-17T06:00:00+07:00","tz":"Asia/Ho_Chi_Minh","date":"2026-09-17","hour":6,"event":"wake","emotion":"stretching","source":"button"}local — the device's own wall-clock with its UTC offset. Say times to the user from
this field, never by converting ts yourself.tz — the zone that offset came from. Empty means the device could not resolve its zone
and the time is naive: report it as approximate rather than quoting it exactly.ts — epoch seconds. Use it for ordering and for durations; it is the only field safe to
subtract, because the user can change the zone between two rows.event — sleep or wake. Count sleep rows; a sleepy re-sent to an already
sleeping device writes nothing, so every row is a real transition.source — who caused it: button / touch / MPR121 (someone did it by hand),
api (your own [HW:/emotion:sleepy] marker, or the web UI).emotion — sleepy going in; stretching or greeting coming out.export TZ=$(cat /etc/timezone)
# Times slept today
jq -c 'select(.event=="sleep")' "/root/local/device/sleep/$(date +%Y-%m-%d).jsonl" | wc -l
# Times slept over everything retained
cat /root/local/device/sleep/*.jsonl | jq -c 'select(.event=="sleep")' | wc -l
# Usual bedtime hour
cat /root/local/device/sleep/*.jsonl \
| jq -r 'select(.event=="sleep") | .hour' | sort -n | uniq -c | sort -rn | head -3
# Recent transitions with readable local times
cat /root/local/device/sleep/*.jsonl | jq -c '{local,event,source}' | tail -6
# How long each sleep lasted — pair every sleep with the wake that follows it.
# Durations come from `ts`, the times shown come from `local`.
cat /root/local/device/sleep/*.jsonl | jq -s -r '
def shown: .local // ((.ts | strftime("%Y-%m-%dT%H:%M:%SZ")) + " (UTC)");
sort_by(.ts)
| reduce .[] as $r ({open:null, out:[]};
if $r.event == "sleep" then .open = $r
elif .open then .out += [{from: (.open | shown), to: ($r | shown),
mins: (($r.ts - .open.ts) / 60 | floor)}] | .open = null
else . end)
| .out[] | "\(.from) → \(.to) (\(.mins) min)"'Two gaps to report honestly rather than paper over:
sleep with no wake after it means the device is still asleep, or was
powered off while sleeping. The pairing drops it instead of inventing an end.local existed have no local time. The shown fallback above
prints those in UTC, labelled — do not present a UTC time as the user's local time.Do not confuse this with action:"sleep" in the wellbeing log — that is the user
telling you they are going to bed (see the Habit skill). This file is about your own
body.
This file is the only complete record. Flow events carry hw_emotion rows for
sleeps your own marker fired, but the button never reaches os-server, so counting from
flow_events_*.jsonl silently undercounts and misses exactly the times a person put
you to sleep by hand. Count from here.
Nothing before the journal existed can be recovered — it was never written down anywhere. If the files start mid-window, say how far back you can actually see rather than reporting a total as if it were lifetime.
exit records with data.error for events the agent missed. Mention it: "There was motion at 10:45 PM but I was mid-conversation and missed it."date -d before filtering.cat multiple JSONL files together.new: segment carries friend (gray), friend (chloe), stranger (stranger_1); already present: gray (friend) means gray was in frame when someone else arrived; faces in frame: N (...) is the box count of that snapshot; other events: Large movement detected, etc.[snapshot: ...] path from the message. Path format is /var/lib/hal/snapshots/sensing_<prefix>/<ms>.jpg (category subdir per event kind). Snapshots have 72h TTL — check the file exists before referencing (test -f <path>)./tmp/hal-sensing-snapshots/sensing_pose/buckets/. Only sessions that crossed the bad-ratio threshold survive here, so the bucket list itself answers "when did my posture get bad today?". Read each bucket's bucket.json for summary.dominant_region and summary.bad_ratio, then reference worst_snapshots[] for representative frames.Input: "Have you seen anybody between 10pm and midnight?"
Action: Resolve which evening the user means, then query presence.enter from 22:00 on that date up to (but not including) 00:00 on the following date, selecting the files for the resolved interval. 12pm means noon, not midnight; clarify an ambiguous request rather than silently changing it.
Response: "Yes — I detected a stranger at 10:03 PM and again at 10:07 PM." or "No one came by between 10 PM and midnight."
Input: "Is there any motion in the last hour?"
Action: Query data.type in ["motion", "motion.activity"] with SINCE=$(date -d "1 hour ago" +%s).
Response: "Yes, I detected large movement 3 times — at 9:29, 9:59, and 10:12." or "No motion in the last hour."
Input: "What happened while I was away?"
Action: Ask the user when they left, or find the last presence.leave and query all events after that timestamp.
Response: "After around 3 PM — I saw motion at 4:30 PM and again at 5:15 PM. No one was identified though. I have snapshots from those moments if you want to see."
Input: "How was my posture today?"
Action: List today's pose buckets and aggregate summary.dominant_region + summary.bad_ratio from each bucket.json.
Response: "You had 3 bad-posture sessions today: a neck-flexion one at 10:14 AM (77% bad), another neck stretch at 1:39 PM (100% bad), and one trunk lean at 3:20 PM (62% bad). The worst frames are in the bucket dirs if you want me to pull one up."
© autonomous-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in skills/sensing-track of autonomous-ai/Physical-AI-Operating-System.
Open the folder on GitHubat commit 1bbd649
Sensing Track next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Sensing Track this skillautonomous-ai/Physical-AI-Operating-System | 381 | — | ~4.3k | Automated safety check: Pass | Apache-2.0 | |
| Hook Development for Claude Code Pluginsanthropics/claude-plugins-official | 38k | 10 repos | ~4.1k | Automated safety check: Notes | Apache-2.0 | |
| Plugin Settings Patternanthropics/claude-plugins-official | 38k | 7 repos | ~3k | Automated safety check: Pass | Apache-2.0 | |
| Mole Bug Patternstw93/Mole | 70k | — | ~2k | Automated safety check: Pass | GPL-3.0 | |
| Neat-Freak Knowledge CloseoutKKKKhazix/khazix-skills | 21k | — | ~1.9k | Automated safety check: Pass | MIT | |
| E2Ecallstack/react-native-pager-view | 3.4k | 1 repos | ~2.1k | Automated safety check: Pass | MIT |
anthropics/claude-plugins-official
Explains how to write Claude Code plugin hooks, both prompt-based checks and bash commands, for events such as PreToolUse, Stop and SessionStart.
anthropics/claude-plugins-official
Shows how Claude Code plugins keep per-project settings and state in .claude/plugin-name.local.md files with YAML frontmatter and a markdown body.
tw93/Mole
A catalog of recurring bug shapes in the Mole Mac cleaner, used to review safety-sensitive diffs for deletion safety, unbounded commands, shell traps and weak tests.
KKKKhazix/khazix-skills
Brings project docs, agent rule files, authorized memory and leftover workspace files back in line with what the code and runtime actually do at the end of a work session.
callstack/react-native-pager-view
Agentic end-to-end tests with e2e, the e2e runner. An agent skill from callstack/react-native-pager-view.
automazeio/ccpm
Runs a spec-driven workflow from PRD to epic to GitHub issues to parallel agents, with status, standup and blocked-work reports from bundled scripts.
autonomous-ai/Physical-AI-Operating-System
Legacy Autonomous Buddy control for explicitly requested Buddy coding sessions.
autonomous-ai/Physical-AI-Operating-System
Push Claude Code activity to the user's device (e.g. An agent skill from autonomous-ai/Physical-AI-Operating-System.
autonomous-ai/Physical-AI-Operating-System
Operate apps/websites on the paired Mac via Buddy: Calendar, Notes, forms, screenshots, files.
autonomous-ai/Physical-AI-Operating-System
Discover and use linked third-party services (Gmail, Google Calendar, Google Drive, Notion, Figma, Asana, Linear, GitHub, Ahrefs, Facebook Fan Page and others).
autonomous-ai/Physical-AI-Operating-System
Delegate digital work to agents on the computer paired through Harness; discover Store packages and prepare an agent when needed.
autonomous-ai/Physical-AI-Operating-System
Low-level speaker and microphone hardware control — adjust volume, play test tones, record raw audio.
Works with
Query flow event logs to answer questions about past sensing events — "Have you seen anybody between 10pm and midnight?", "Is there any motion in the last hour?", "What happened while I was away?". Sensing Track is an agent skill from autonomous-ai/Physical-AI-Operating-System.".
Run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a claude-code`. Or copy the skill folder (skills/sensing-track in autonomous-ai/Physical-AI-Operating-System) into .claude/skills/sensing-track in your project. Claude Code loads it when a task matches its description.
Run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a codex`. Or copy the skill folder (skills/sensing-track in autonomous-ai/Physical-AI-Operating-System) into .agents/skills/sensing-track in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill sensing-track -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sensing-track, .gemini/skills/sensing-track, .github/skills/sensing-track and .opencode/skills/sensing-track in your project.
Going by SKILL.md and its folder, Sensing Track needs the command-line tools its instructions call (jq and curl).
SKILL.md contains no URLs. Its commands use curl, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Sensing Track is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.3k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Sensing Track: Hook Development for Claude Code Plugins (anthropics/claude-plugins-official, 38k stars), Plugin Settings Pattern (anthropics/claude-plugins-official, 38k stars), Mole Bug Patterns (tw93/Mole, 70k stars) and Neat-Freak Knowledge Closeout (KKKKhazix/khazix-skills, 21k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
autonomous-ai (a GitHub organization) maintains it in autonomous-ai/Physical-AI-Operating-System, which has 381 GitHub stars. The repository holds 28 skills in this directory. The repository was last updated on October 9, 2026.
Source: autonomous-ai/Physical-AI-Operating-System on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.