Skip to content

Instantly share code, notes, and snippets.

View sjmf's full-sized avatar
🐝

Samantha Finnigan sjmf

🐝
View GitHub Profile
@sjmf
sjmf / SKILL.md
Created September 11, 2026 14:43
capx-api: a Claude Code skill for querying and automating CapX (UoMResearchIT/CapX) through its REST API with an API key
name capx-api
description Query and automate a CapX deployment (UoMResearchIT/CapX) through its REST API with an API key. Look up projects, people, tasks, resourcing, timesheets, notes, skills and workload models; as a Superuser, change a project's status or dates, add tasks and assign people, change, move or retract assignments, add people, import timesheets and workload models, and audit for overdue projects or unmet demand. Use when asked to query, update, import into, bulk-edit or audit CapX, or to find a CapX endpoint's parameters.

CapX API

CapX serves a REST API under /api, authenticated by an x-api-key header on every call. capx.py in this directory wraps it: Python 3 standard library only, JSON on stdout, explanations on stderr, and every write is a dry run that prints its payload until you add --apply. reference.md lists every endpoint, who may call it, and the enum values.

Setup

@sjmf
sjmf / mkusb.sh
Created August 25, 2026 20:48
Make a Windows USB from Ubuntu
#!/usr/bin/env bash
set -euo pipefail
ISO_PATH="/mnt/_Software/OS ISOs/Windows/Win10_22H2_EnglishInternational_x64v1.iso"
# Read target device from first argument, default to /dev/sdb if empty
TARGET_DEV="${1:-/dev/sdb}"
PARTITION="${TARGET_DEV}1"
@sjmf
sjmf / anylist_to_pantry.py
Last active August 12, 2026 08:26
Anylist email to Markdown for import to Nextcloud Pantry
"""
anylist_to_pantry.py
Convert AnyList "Share, Email & Print" .eml exports into Pantry-compatible
Markdown checklists.
AnyList's export HTML uses these classes per item block:
p.list-name -> list title
p.category-name -> category heading
p.item-name -> item WITH a details paragraph following
@sjmf
sjmf / pantry-userscript.js
Last active August 11, 2026 23:36
ViolentMonkey Userscript for Pantry on Nextcloud to set the custom sort order to order by oldest first (instead of alphabetical)
// ==UserScript==
// @name Pantry Custom Sort by Item ID
// @namespace pantry-tools
// @author @sjmf (Samantha Finnigan)
// @version 1.0
// @description Adds a button to apply identity-based (item ID) ordering to the "Custom" sort order for the currently viewed Pantry list
// @match https://<replace with your Nextcloud instance domain>/apps/pantry/houses/*/lists/*
// @grant none
// ==/UserScript==
@sjmf
sjmf / anylist_to_pantry.py
Created July 27, 2026 21:23
AnyList email exporter to Markdown parser
"""
anylist_to_pantry.py
Convert AnyList "Share, Email & Print" .eml exports into Pantry-compatible
Markdown checklists.
AnyList's export HTML uses these classes per item block:
p.list-name -> list title
p.category-name -> category heading
p.item-name -> item WITH a details paragraph following
@sjmf
sjmf / ch9329_descriptor.py
Created May 5, 2026 23:21
CH9329 USB HID Descriptor
# Combined composite descriptor read from CH9329 (359 bytes, verified
# from 0x81 capture). As CH9329 is a composite device, it presents a
# convenient HID descriptor to emulate.
#
# Contains Report IDs: 1=keyboard, 2=system-ctrl, 3=consumer-ctrl,
# 4=relative-mouse (RID 0x04, range -127..127), 5=absolute-mouse (RID 0x05,
# range 0..4095 for both X and Y), 6=vendor-HID.
# Wire capture confirms the real LC announces the CH9329 composite descriptor
# on PORT=0x01 (HP/HM, P2 in the UC 0x12 keepalive).
# Use as: CH9350Comm(port, state=STATE_0, kbd_desc=CH9329_DESC,
@sjmf
sjmf / s3_lc.txt
Created May 3, 2026 21:30
CH9350L state-3/4 mode bidirectional captures (issue #13) — abs-mouse via dipswitch S1=LOW
[sniff LC] Opening /dev/cu.usbserial-0001 @ 115200 8N1 log=tmp/s3_lc.txt
22:19:54.408787 [LC] [sync: skipped 1B: 00]
22:19:54.411561 [LC] 57 ab 86 | DEVICE_NOTIFY []
22:19:54.675123 [LC] 57 ab 80 ff | LED_STATUS [0xFF unknown]
22:19:54.675596 [LC] 57 ab 89 | STATUS_ANNOUNCE []
22:19:54.889148 [LC] 57 ab 80 ff | LED_STATUS [0xFF unknown]
22:19:59.509114 [LC] 57 ab 04 01 00 02 00 03 00 00 | MOUSE_ABS btn=0x00 x=2 y=3 wheel=0
22:19:59.510436 [LC] 57 ab 04 01 00 04 00 05 00 00 | MOUSE_ABS btn=0x00 x=4 y=5 wheel=0
22:19:59.562138 [LC] 57 ab 04 01 00 05 00 06 00 00 | MOUSE_ABS btn=0x00 x=5 y=6 wheel=0
@sjmf
sjmf / absmouse_uc.txt
Last active May 3, 2026 21:03
CH9350L state-2 mode bidirectional capture (issue #13)
[sniff UC] Opening /dev/cu.usbserial-2130 @ 115200 8N1 log=tmp/absmouse_uc.txt
22:01:55.610957 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:55.663372 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:59.528460 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:59.629656 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:59.681114 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:59.736437 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] status=0x07[p0enum,p1enum,uart] ver=ac20
22:01:59.790835 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 le
@sjmf
sjmf / sniff_emu.txt
Last active May 3, 2026 10:25
CH9350L UART bus sniff — bidirectional capture (LC + UC), real keyboard + mouse source, with 0x81 Device Connection Frames decoded
[sniff UC] Opening /dev/cu.usbserial-110 @ 115200 8N1 log=sniff_emu.txt
11:20:15.089867 [UC] [sync: skipped 1B: 00]
11:20:15.090985 [UC] 57 ab 12 00 00 00 00 00 07 ac 20 | UC_KEEPALIVE p1=0000 p2=0000 led=0x00[-] tail=07ac20
11:20:16.229085 [UC] 57 ab 12 40 00 03 15 00 04 ac 0b | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=04ac0b
11:20:21.431744 [UC] 57 ab 12 40 00 03 15 00 07 ac 20 | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=07ac20
11:20:42.524922 [UC] 57 ab 12 40 00 03 15 00 07 ac 20 | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=07ac20
11:21:15.102974 [UC] 57 ab 12 40 00 03 15 00 07 ac 20 | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=07ac20
11:21:18.694012 [UC] 57 ab 12 40 00 03 15 00 07 ac 20 | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=07ac20
11:21:22.332487 [UC] 57 ab 12 40 00 03 15 00 07 ac 20 | UC_KEEPALIVE p1=4000 p2=0315 led=0x00[-] tail=07ac20
@sjmf
sjmf / sniff_com4_3.txt
Created May 2, 2026 22:11
CH9350L UART bus sniff — real keyboard + mouse source (HID boot protocol, verified decoder output)
[sniff] Opening COM4 @ 115200 8N1 log=sniff_com4_3.txt
22:44:04.451 57 ab 86 | STARTUP_0x86 []
22:44:04.704 57 ab 80 ff | STARTUP_0x80 [0xFF]
22:44:04.934 57 ab 80 ff | STARTUP_0x80 [0xFF]
22:44:04.935 57 ab 82 a3 | HEARTBEAT io=3
22:44:04.935 57 ab 82 a3 | HEARTBEAT io=3
22:44:04.991 57 ab 82 a3 | HEARTBEAT io=3
22:44:04.992 57 ab 82 a3 | HEARTBEAT io=3
22:44:05.044 57 ab 82 a3 | HEARTBEAT io=3