xumret 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. xumret-0.1.0/.claude/skills/code-deps/SKILL.md +102 -0
  2. xumret-0.1.0/.claude/skills/code-review/SKILL.md +54 -0
  3. xumret-0.1.0/.claude/skills/code-work/SKILL.md +69 -0
  4. xumret-0.1.0/.claude/skills/journal-save/SKILL.md +90 -0
  5. xumret-0.1.0/.claude/skills/journal-search/SKILL.md +62 -0
  6. xumret-0.1.0/.claude/skills/wit/SKILL.md +50 -0
  7. xumret-0.1.0/.github/workflows/check.yaml +26 -0
  8. xumret-0.1.0/.github/workflows/publish-pypi.yaml +30 -0
  9. xumret-0.1.0/.gitignore +26 -0
  10. xumret-0.1.0/.gitmodules +9 -0
  11. xumret-0.1.0/AGENTS.md +44 -0
  12. xumret-0.1.0/CLAUDE.md +1 -0
  13. xumret-0.1.0/LICENSE +201 -0
  14. xumret-0.1.0/Makefile +80 -0
  15. xumret-0.1.0/PKG-INFO +16 -0
  16. xumret-0.1.0/README.md +8 -0
  17. xumret-0.1.0/TASKS.md +204 -0
  18. xumret-0.1.0/doc/architecture.md +127 -0
  19. xumret-0.1.0/doc/dev.md +312 -0
  20. xumret-0.1.0/doc/phone-command-taxonomy.md +220 -0
  21. xumret-0.1.0/doc/termux-schematic.md +104 -0
  22. xumret-0.1.0/doc/ui_api.md +31 -0
  23. xumret-0.1.0/doc/use-cases.md +84 -0
  24. xumret-0.1.0/doc/wits.md +16 -0
  25. xumret-0.1.0/dprint.json +35 -0
  26. xumret-0.1.0/journals/.gitkeep +0 -0
  27. xumret-0.1.0/mise.toml +0 -0
  28. xumret-0.1.0/package-lock.json +2270 -0
  29. xumret-0.1.0/package.json +30 -0
  30. xumret-0.1.0/pyproject.toml +13 -0
  31. xumret-0.1.0/requirements-dev.txt +5 -0
  32. xumret-0.1.0/requirements.txt +24 -0
  33. xumret-0.1.0/src/xumret/__init__.py +3 -0
  34. xumret-0.1.0/src/xumret/__main__.py +48 -0
  35. xumret-0.1.0/src/xumret/executor/AGENTS.md +21 -0
  36. xumret-0.1.0/src/xumret/executor/__init__.py +0 -0
  37. xumret-0.1.0/src/xumret/executor/dummy_executor.py +229 -0
  38. xumret-0.1.0/src/xumret/executor/dummy_executor_test.py +196 -0
  39. xumret-0.1.0/src/xumret/executor/local.py +252 -0
  40. xumret-0.1.0/src/xumret/executor/models.py +81 -0
  41. xumret-0.1.0/src/xumret/protocol/__init__.py +0 -0
  42. xumret-0.1.0/src/xumret/protocol/executor.py +34 -0
  43. xumret-0.1.0/src/xumret/protocol/service.py +25 -0
  44. xumret-0.1.0/src/xumret/server/__init__.py +1 -0
  45. xumret-0.1.0/src/xumret/server/api/AGENTS.md +24 -0
  46. xumret-0.1.0/src/xumret/server/api/__init__.py +11 -0
  47. xumret-0.1.0/src/xumret/server/api/app.py +27 -0
  48. xumret-0.1.0/src/xumret/server/api/events.py +43 -0
  49. xumret-0.1.0/src/xumret/server/api/routes.py +84 -0
  50. xumret-0.1.0/src/xumret/server_bridge/AGENTS.md +17 -0
  51. xumret-0.1.0/src/xumret/server_bridge/__init__.py +0 -0
  52. xumret-0.1.0/src/xumret/server_bridge/models.py +86 -0
  53. xumret-0.1.0/src/xumret/single.py +101 -0
  54. xumret-0.1.0/src/xumret/state/AGENTS.md +24 -0
  55. xumret-0.1.0/src/xumret/state/__init__.py +0 -0
  56. xumret-0.1.0/src/xumret/state/models.py +49 -0
  57. xumret-0.1.0/src/xumret/state/phone.py +124 -0
  58. xumret-0.1.0/tsconfig.json +20 -0
  59. xumret-0.1.0/vite.config.mts +32 -0
  60. xumret-0.1.0/webui-src/App.tsx +19 -0
  61. xumret-0.1.0/webui-src/app.css +4 -0
  62. xumret-0.1.0/webui-src/components/AGENTS.md +57 -0
  63. xumret-0.1.0/webui-src/components/camera/commands.ts +24 -0
  64. xumret-0.1.0/webui-src/components/camera/types.ts +60 -0
  65. xumret-0.1.0/webui-src/index.html +15 -0
  66. xumret-0.1.0/webui-src/main.tsx +15 -0
  67. xumret-0.1.0/webui-src/pages/devices/:deviceId/commands/:commandId/index.tsx +28 -0
  68. xumret-0.1.0/webui-src/pages/devices/:deviceId/commands/index.tsx +50 -0
  69. xumret-0.1.0/webui-src/pages/devices/:deviceId/index.tsx +243 -0
  70. xumret-0.1.0/webui-src/pages/devices/index.tsx +39 -0
  71. xumret-0.1.0/webui-src/util/commands.ts +15 -0
  72. xumret-0.1.0/xumret +3 -0
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: code-deps
3
+ description: "Manage Python/Node dependencies in this project. Use this to install/update deps in the smooth way."
4
+ allowed-tools: [Read, Edit, Bash, Glob, Grep]
5
+ ---
6
+
7
+ # code-deps — Dependency Management
8
+
9
+ Manage Python and Node dependencies for the xumret project. This skill covers adding, removing, upgrading, and troubleshooting packages.
10
+
11
+ ## Critical Rules
12
+
13
+ - **NEVER run `pip install` or `uv pip install` directly.** Always add the package to `requirements.txt` first, then run `make deps`.
14
+ - **NEVER edit `venv/` contents manually.** The venv is managed by uv via the Makefile.
15
+
16
+ ## Python Dependencies
17
+
18
+ ### Layout
19
+
20
+ | Path | Purpose |
21
+ |---|---|
22
+ | `requirements.txt` | All Python deps (pinned and unpinned) |
23
+ | `Makefile` | `deps`, venv creation targets |
24
+ | `venv/` | The uv-managed virtualenv (Python 3.13) |
25
+
26
+ ### Adding a New Python Package
27
+
28
+ 1. **Edit `requirements.txt`**: Add the package. Don't add a version — uv will find the latest compatible version.
29
+ 2. **Install**: Run `make deps`
30
+ 3. **Verify**: The Makefile target uses `uv pip install -r requirements.txt` under the hood. It touches `venv/.deps_installed` as a sentinel file so subsequent `make deps` calls are no-ops unless `requirements.txt` changes.
31
+
32
+ ### Shared library (`ihate_work`)
33
+
34
+ The `local-ihate-work` package is installed from GitHub (not a local editable tree):
35
+
36
+ ```
37
+ local-ihate-work @ git+https://github.com/ihate-work/ihate-library
38
+ ```
39
+
40
+ This provides `ihate_work.o11y`, `ihate_work.util`, etc. To upgrade to the latest commit, run:
41
+
42
+ ```bash
43
+ uv pip install --force-reinstall "local-ihate-work @ git+https://github.com/ihate-work/ihate-library"
44
+ ```
45
+
46
+ Or delete the venv and reinstall: `make clean && make deps`.
47
+
48
+ ### Removing a Python Package
49
+
50
+ 1. Remove the line from `requirements.txt`.
51
+ 2. Run `make deps`. Note: uv may not uninstall the removed package from the existing venv automatically. If a clean state is needed, run `make clean && make deps` to recreate.
52
+
53
+ ### Venv Details
54
+
55
+ - **Location**: `venv/`
56
+ - **Python version**: 3.13 (set by `PYTHON_VER` in Makefile)
57
+ - **Created by**: `uv venv --clear --python=3.13 venv`
58
+ - **Sentinel files**: `venv/.venv_created` (venv exists), `venv/.deps_installed` (deps are current)
59
+ - **Environment variables used during install**: `UV_PYTHON=venv UV_LINK_MODE=symlink`
60
+ - **Interpreter path**: `venv/bin/python`
61
+
62
+ To recreate the venv from scratch: `make clean && make deps`.
63
+
64
+ ### Troubleshooting Python Deps
65
+
66
+ - **`ModuleNotFoundError`**: Check that the package is in `requirements.txt` and run `make deps`. If the sentinel file is up to date but the package is missing, delete `venv/.deps_installed` and re-run.
67
+ - **Stale venv**: Run `make clean && make deps` to get a clean state.
68
+ - **`make deps` is a no-op but packages are missing**: The sentinel `venv/.deps_installed` may be newer than `requirements.txt`. Run `touch requirements.txt && make deps` to force reinstall.
69
+
70
+ ## Node Dependencies (Web UI)
71
+
72
+ ### Layout
73
+
74
+ | Path | Purpose |
75
+ |---|---|
76
+ | `package.json` | JS deps for the web UI |
77
+ | `package-lock.json` | Lockfile (committed) |
78
+
79
+ ### Adding a New Node Package
80
+
81
+ ```bash
82
+ npm install <package-name>
83
+ ```
84
+
85
+ For dev dependencies:
86
+
87
+ ```bash
88
+ npm install -D <package-name>
89
+ ```
90
+
91
+ ### Installing
92
+
93
+ ```bash
94
+ make webui-deps
95
+ ```
96
+
97
+ This runs `npm ci` and touches `node_modules/.webui_deps_installed` as a sentinel.
98
+
99
+ ### Troubleshooting Node Deps
100
+
101
+ - **Module not found**: Run `npm ci` to reinstall from the lockfile.
102
+ - **Lockfile conflicts**: Delete `node_modules/` and `package-lock.json`, then run `npm install` to regenerate. Only do this as a last resort.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: code-review
3
+ description: "Review changed code for correctness, readability, testability, security, and adherence to project conventions. Checks multiple perspectives and flags issues with concrete suggestions."
4
+ allowed-tools: [Read, Glob, Grep, Bash, Agent]
5
+ ---
6
+
7
+ # code-review — Multi-Perspective Code Review
8
+
9
+ Review the specified code (files, diff, or staged changes) from multiple perspectives, flagging issues with concrete suggestions.
10
+
11
+ ## Steps
12
+
13
+ ### 1. Determine what to review
14
+
15
+ - If the user specifies files or a diff range, use that.
16
+ - If nothing is specified, review the current uncommitted changes: run `git diff HEAD` (and `git diff --cached` for staged changes).
17
+ - Read every file that has changes. Do not review code you haven't read.
18
+
19
+ ### 2. Read project conventions
20
+
21
+ Read `doc/dev.md` to load the current review checklist and project conventions. These are authoritative — violations are must-fix, not nits.
22
+
23
+ Also read `CLAUDE.md` for project-specific rules (Web UI rules, o11y conventions, etc.).
24
+
25
+ ### 3. Review from each perspective
26
+
27
+ Evaluate every changed file against all perspectives listed in the "Code Review Checklist" section of `doc/dev.md`, plus the conventions defined earlier in that file (Principles, o11y, pytest, dotenv) and the project-specific rules in `CLAUDE.md`.
28
+
29
+ Only report findings that are actionable — skip a perspective if there's nothing to flag.
30
+
31
+ ### 4. Report findings
32
+
33
+ Present findings grouped by file path. For each finding:
34
+
35
+ 1. **File and line reference** — `path/to/file.py:42`
36
+ 2. **Perspective** — which review lens caught it (e.g. Correctness, Convention)
37
+ 3. **Issue** — one-line description
38
+ 4. **Suggestion** — concrete fix or direction (show code when helpful)
39
+
40
+ Use the severity levels from `doc/dev.md`.
41
+
42
+ ### 5. Summary
43
+
44
+ End with a brief summary:
45
+ - Total findings by severity
46
+ - Overall assessment (ship it / needs changes / needs rethink)
47
+ - If the code is clean, say so — don't invent issues.
48
+
49
+ ## Rules
50
+
51
+ - Do not suggest changes you haven't verified against the actual code.
52
+ - Do not flag things that are already handled correctly.
53
+ - Do not add noise — if the code is good, the review should be short.
54
+ - Convention violations from `doc/dev.md` and `CLAUDE.md` are must-fix, not nits.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: code-work
3
+ description: "Implement a milestone or task from a project plan. Reads the plan, picks up the next task, writes code + tests, runs them, and marks it done."
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, Agent]
5
+ ---
6
+
7
+ # code-work — Implement a Plan Task
8
+
9
+ Pick up a milestone or task from a project's plan doc, implement it with tests, and mark it done.
10
+
11
+ ## Steps
12
+
13
+ ### 1. Load the plan and conventions
14
+
15
+ - Read the plan doc specified by the user.
16
+ - Read `doc/dev.md` for project-wide coding conventions.
17
+ - Read `CLAUDE.md` for project-specific rules.
18
+ - Read the `Makefile` to understand how to run tests and install deps.
19
+
20
+ ### 2. Determine what to work on
21
+
22
+ - If the user specifies a task or milestone, use that.
23
+ - If not, pick the first unchecked `- [ ]` item in the plan.
24
+ - Read all existing code that the task will touch or depend on before writing anything.
25
+
26
+ ### 3. Implement
27
+
28
+ Write code that follows these rules:
29
+
30
+ - **Readable, testable, minimal.** Only implement what the task asks for. Don't refactor surrounding code, add speculative features, or over-abstract.
31
+ - **Match existing patterns.** Read neighboring code and follow the same style, naming, imports, and structure. New code should look like it was written by the same person.
32
+ - **Stable APIs.** Exported functions get a short docstring and a stable signature. Internal helpers do not need docstrings.
33
+ - **Comments are for "why".** Use code for "what" and "how". Only comment when the reason behind a choice isn't obvious.
34
+ - **Follow plan-level notes.** The plan doc may include project-specific conventions or constraints — read and follow them.
35
+
36
+ ### 4. Write tests
37
+
38
+ Every task that adds or changes behavior must include tests.
39
+
40
+ - Test file naming: `TESTEE_test.py`.
41
+ - Tests live **beside** the testee module (same directory), not in a separate `tests/` tree.
42
+ - Test behavior, not implementation. Prefer round-trip tests over mocking internals.
43
+ - Keep tests fast and independent.
44
+
45
+ ### 5. Run tests
46
+
47
+ - Run `make test` to execute the test suite.
48
+ - All tests must pass before the task is considered done. If a test fails, fix the code or the test — don't skip or delete it.
49
+ - Run `make format` before finishing.
50
+
51
+ ### 6. Update the plan
52
+
53
+ In the plan doc, change `- [ ]` to `- [x]` for the completed task. Do not modify other tasks.
54
+
55
+ ### 7. Summarize
56
+
57
+ Tell the user:
58
+ - Which task was completed
59
+ - What files were created or changed
60
+ - Any design decisions you made (and why)
61
+ - Anything you noticed that affects upcoming tasks
62
+
63
+ ## Rules
64
+
65
+ - Do not start coding before reading the existing code that your task touches.
66
+ - Do not change code outside the scope of the current task.
67
+ - Do not mark a task done if tests don't pass.
68
+ - If a task is ambiguous or blocked by an unresolved design decision in the plan, stop and ask the user rather than guessing.
69
+ - One task per invocation. If the user asks for a whole milestone, work through tasks sequentially — finish and verify each one before starting the next.
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: journal-save
3
+ description: "Please create or update journals/YYYYMMDD-{pid}-{topic}.md to document this session's work. Especially the intention, investigations, quirks, experiments, actual changes."
4
+ allowed-tools: [Read, Write, Edit, Glob, Grep, Bash]
5
+ ---
6
+
7
+ # journal-update — Document This Session's Work
8
+
9
+ Create or update a journal entry capturing what happened in this conversation — the intent, investigations, discoveries, quirks, experiments, and actual changes made.
10
+
11
+ ## Steps
12
+
13
+ ### 1. Determine the journal filename
14
+
15
+ The filename format is: `journals/YYYYMMDD-p{PID}-{topic}.md`
16
+
17
+ - Get the Claude Code PID via `echo $PPID` (stable across all bash calls in a session)
18
+ - Infer a 2-3 word kebab-case topic from the session's work (e.g. `ws-protocol`, `webui-layout`, `executor-refactor`). Prefer the verb-object pattern. The topic should always be inferable from the conversation — never use `unknown`.
19
+
20
+ Example: `journals/20260324-p3593122-ws-protocol.md`
21
+
22
+ ### 2. Find or create the journal file
23
+
24
+ One PID may have multiple journals (the user can `/clear` and start a new topic within the same Claude Code process). Search for all journals with this PID:
25
+
26
+ ```
27
+ journals/*-p${PPID}-*.md
28
+ ```
29
+
30
+ If matches exist:
31
+ 1. Read the first ~10 lines of each match (frontmatter + title) to understand its topic
32
+ 2. If the current session's work fits an existing file's topic, update that file (append a new dated section — don't rewrite history)
33
+ 3. If the current work is a clearly different topic from all existing files, create a new file
34
+
35
+ If no matches exist, create a new file.
36
+
37
+ ### 3. Gather context
38
+
39
+ Run `echo $HOST $USER` to find hostname and username to populate the frontmatter with. Then collect the following from the conversation history — do NOT run extra exploratory commands:
40
+
41
+ - **Intent**: What did the user ask for? What was the goal?
42
+ - **Investigations**: What did we read, search, or explore to understand the problem?
43
+ - **Discoveries / Quirks**: Anything surprising, non-obvious, or worth remembering (gotchas, undocumented behavior, edge cases).
44
+ - **Experiments**: Anything we tried that didn't work, and why.
45
+ - **Changes**: What files were actually created, modified, or deleted? Summarize the substance of each change.
46
+ - **Open threads**: Anything unfinished, deferred, or worth revisiting.
47
+
48
+ ### 4. Write the journal entry
49
+
50
+ Use this template:
51
+
52
+ ```markdown
53
+ ---
54
+ date: {YYYY-MM-DD HH:MM}
55
+ branch: {current git branch}
56
+ host: {hostname}
57
+ user: {username}
58
+ tldr: {One-sentence summary of the session's outcome}
59
+ ---
60
+
61
+ # Journal: {brief title}
62
+
63
+ ## Intent
64
+
65
+ {What the user wanted to accomplish.}
66
+
67
+ ## What happened
68
+
69
+ {Narrative of the work — investigations, key decisions, pivots. Keep it concise but useful to future-you skimming old entries. Use subsections if the session covered multiple distinct topics.}
70
+
71
+ ## Discoveries / Quirks
72
+
73
+ {Bullet list of non-obvious things learned. Omit this section if nothing surprising came up.}
74
+
75
+ ## Changes
76
+
77
+ {Bullet list of files changed and what was done to each. Group by topic if the session touched multiple areas.}
78
+
79
+ ## Open threads
80
+
81
+ {Anything left unfinished or worth revisiting. Omit if everything is wrapped up.}
82
+ ```
83
+
84
+ ### 5. Guidelines
85
+
86
+ - Be concise but specific. The journal is for the user to skim later, not a transcript.
87
+ - Focus on *why* and *what was surprising*, not mechanical play-by-play.
88
+ - Use code references (`file:line`) where they help.
89
+ - If updating an existing entry, append a new dated section rather than rewriting history.
90
+ - Don't editorialize or add filler — if a section has nothing useful, omit it.
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: journal-search
3
+ description: "Search past journal entries to answer questions about previous sessions — what was done, what was discovered, what changed, and what's still open."
4
+ allowed-tools: [Read, Glob, Grep, Bash]
5
+ ---
6
+
7
+ # journal-search — Answer Questions from Past Journals
8
+
9
+ Search and synthesize information from journal entries in `journals/` to answer the user's question about previous work sessions.
10
+
11
+ ## Steps
12
+
13
+ ### 1. Understand the question
14
+
15
+ Identify what the user is asking about. Common queries:
16
+
17
+ - **What/when**: "What did we do about X?", "When did we change Y?"
18
+ - **Why**: "Why is Z implemented this way?"
19
+ - **Discoveries**: "What gotchas did we find about X?"
20
+ - **Open threads**: "What's left unfinished?"
21
+ - **Changes**: "What files were touched for feature X?"
22
+
23
+ ### 2. Search journals
24
+
25
+ Journals live in `journals/*.md` and have YAML frontmatter with `pid`, `date`, `branch`, `host`, `user`, `tldr`.
26
+
27
+ #### Strategy
28
+
29
+ 0. Use `git grep` when possible.
30
+
31
+ 1. **Start with grep** — search for keywords from the user's question across all journals:
32
+ ```
33
+ grep -li <keyword> journals/*.md
34
+ ```
35
+ Use multiple keywords in parallel if the question has several concepts.
36
+
37
+ 2. **If grep finds matches**, read the matching files. Start with frontmatter + title (first ~10 lines) to assess relevance, then read the full file for relevant ones.
38
+
39
+ 3. **If grep finds nothing**, broaden: try synonyms, related terms, or list all journals and scan their `tldr` fields:
40
+ ```
41
+ grep "^tldr:" journals/*.md
42
+ ```
43
+
44
+ 4. **For time-based queries** ("last week", "recently"), list journals sorted by date and read the most recent ones:
45
+ ```
46
+ ls -t journals/*.md
47
+ ```
48
+
49
+ ### 3. Synthesize an answer
50
+
51
+ - Answer the user's question directly, citing specific journal entries by filename and section.
52
+ - Use `journals/filename.md` references so the user can find the source.
53
+ - If the answer spans multiple sessions, present it chronologically.
54
+ - If journals contain contradictory information, flag it — the more recent entry is likely more accurate.
55
+ - If no journals are relevant, say so clearly rather than guessing.
56
+
57
+ ### 4. Guidelines
58
+
59
+ - Be concise. The user wants an answer, not a journal dump.
60
+ - Quote specific discoveries/quirks verbatim when they're the answer — these are the high-value bits.
61
+ - If the question is about open threads, check whether later journals resolved them.
62
+ - Don't fabricate information that isn't in the journals. If the journals don't cover the topic, say so.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: wit
3
+ description: "Record a small idea or design thought to doc/wits.md. Use when the user has a loose idea, observation, or future-facing thought they want to capture."
4
+ allowed-tools: [Read, Edit, AskUserQuestion]
5
+ ---
6
+
7
+ # wit — Capture a design thought
8
+
9
+ The user has an idea or observation they want to land in `doc/wits.md`. Your job is to **interview** them until the intent is sharp, then write a concise entry.
10
+
11
+ ## The file
12
+
13
+ Read `doc/wits.md` first to understand the existing format and entries.
14
+
15
+ Entries live under dated `##` sections, sorted date DESC (newest at top, right after the header block). Each entry is a checkbox line followed by indented detail lines.
16
+
17
+ ## Interview
18
+
19
+ The user may provide the idea inline (e.g. `/wit we should cache device state`) or just invoke `/wit` bare.
20
+
21
+ Either way, ask clarifying questions using AskUserQuestion until you can answer ALL of these:
22
+
23
+ 1. **What** — the concrete idea (feature, API shape, behavior, constraint)
24
+ 2. **Why** — the motivation or problem it solves
25
+ 3. **Decisions** — any choices already made or explicitly deferred
26
+
27
+ Keep the interview short. 1-3 questions max. If the user's initial description already covers everything, skip straight to writing. Do NOT over-interview obvious ideas.
28
+
29
+ ## Write the entry
30
+
31
+ Each entry must be **very concise** — this is a scratchpad, not a design doc. But it must not lose intent, rationale, or decisions.
32
+
33
+ Format:
34
+
35
+ ```markdown
36
+ ## YYYY-MM-DD
37
+
38
+ - [ ] one-line summary of the idea
39
+ — detail line: rationale, constraints, decisions. Use em-dash prefix for continuation lines. Multiple detail lines are OK if needed, but keep each short.
40
+ ```
41
+
42
+ If there are already entries under today's `## YYYY-MM-DD` section, append to that section instead of creating a duplicate date header.
43
+
44
+ ### Rules
45
+
46
+ - Use today's date. Get it from context or `date +%Y-%m-%d`.
47
+ - Sort sections date DESC — newest `##` section goes first (right after the file's top-level header block ending at the first `##`).
48
+ - Never modify existing entries.
49
+ - Never mark entries as done (`[x]`).
50
+ - The summary line should be concrete enough that someone reading it months later understands the idea without expanding context.
@@ -0,0 +1,26 @@
1
+ name: Check
2
+
3
+ on:
4
+ workflow_call:
5
+ workflow_dispatch:
6
+ pull_request:
7
+ push:
8
+ branches: [master]
9
+
10
+ jobs:
11
+ check:
12
+ name: Run tests
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.11", "3.12", "3.13"]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - uses: astral-sh/setup-uv@v6
23
+
24
+ - run: PYTHON_VER=${{ matrix.python-version }} make deps
25
+
26
+ - run: make test
@@ -0,0 +1,30 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+ workflow_dispatch:
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ pypi-publish:
12
+ name: Upload release to PyPI
13
+ runs-on: ubuntu-latest
14
+ environment:
15
+ name: pypi
16
+ url: https://pypi.org/p/xumret
17
+ permissions:
18
+ id-token: write # mandatory for trusted publishing
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - uses: actions/setup-python@v5
23
+
24
+ - name: Install pypa/build
25
+ run: python3 -m pip install build --user
26
+
27
+ - name: Build
28
+ run: python3 -m build --wheel --sdist
29
+
30
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,26 @@
1
+ # python
2
+ build
3
+ .venv
4
+ venv
5
+ *.pyc
6
+ __pycache__
7
+ *.egg-info
8
+
9
+ # tools
10
+ .mypy_cache
11
+ .pytest_cache
12
+ .ruff_cache
13
+ htmlcov
14
+ .coverage
15
+
16
+ # env
17
+ .env
18
+ .env.local
19
+
20
+ # project
21
+ /logs
22
+
23
+ # misc
24
+ .DS_Store
25
+ *.log
26
+ node_modules
@@ -0,0 +1,9 @@
1
+ [submodule "vendor/termux-api"]
2
+ path = vendor/termux-api
3
+ url = https://github.com/termux/termux-api
4
+ [submodule "vendor/termux-app"]
5
+ path = vendor/termux-app
6
+ url = https://github.com/termux/termux-app
7
+ [submodule "vendor/termux-api-package"]
8
+ path = vendor/termux-api-package
9
+ url = https://github.com/termux/termux-api-package
xumret-0.1.0/AGENTS.md ADDED
@@ -0,0 +1,44 @@
1
+ This directory contains `xumret`, a remote control solution for termux and termux-api.
2
+
3
+ Please check README.md to grasp the idea of the project.
4
+
5
+ Please check doc/architecture.md to understand the components and roles.
6
+
7
+ ## Code
8
+
9
+ - src/ : python code for server and clients
10
+
11
+ - webui-src/ : React+TypeScript source for the controller UI. Built output goes to webui-assets/.
12
+
13
+ ## Vendor packages
14
+
15
+ The dependency `termux-api` `termux-app` `termux-api-packages` repositories are added as git submodules for reference.
16
+
17
+ Their code schematic is [indexed](doc/termux-schematic.md). Please refer to (and update if needed) the index to save your and human's energy.
18
+
19
+ ## Shared library
20
+
21
+ Depends on `local-ihate-work` from `../ihate_library` (editable install). Provides `ihate_work.o11y` for observability.
22
+
23
+ ## Web UI rules
24
+
25
+ - **PrimeReact is the ONLY component library.** Use PrimeReact components unconditionally for all UI (buttons, inputs, layout, data display, overlays, etc.). Do NOT use Tailwind CSS, custom utility classes, or other component libraries.
26
+ - Theme: `lara-light-cyan` (imported in `main.tsx`). Use PrimeReact's built-in theming/styling — do not override with raw CSS unless absolutely necessary.
27
+ - PrimeIcons for all icons (`primeicons` package).
28
+ - Entry point: `webui-src/main.tsx`. Vite config + tsconfig at repo root.
29
+ - Build: `make webui-dev` (dev server), `npm run build` (production → webui-assets/).
30
+
31
+ ## Wits
32
+
33
+ `doc/wits.md` is a living scratchpad of small design ideas and decisions. When you encounter or make a non-obvious design choice worth preserving, add it there. Keep entries very concise — intent + rationale, one or two lines.
34
+
35
+ ## Coding rules
36
+
37
+ Inherited from vibra conventions:
38
+
39
+ - **o11y**: Use `ihate_work.o11y` exclusively (not stdlib `logging.getLogger()`). structlog uses keyword args, not printf-style. `setup_otel()` / `setup_structlog()` called exactly once at entry point (`__main__.py`).
40
+ - **Data models**: Pydantic `BaseModel` by default for structured records. Keyword args only.
41
+ - **No mutable globals**: Wire deps through constructor args or framework DI.
42
+ - **Tests**: Named `TESTEE_test.py`. Run with `make test`.
43
+ - **dotenv**: Always `load_dotenv(override=False)`.
44
+ - **Formatting**: ruff (line-length 100, select E/F/I/N/W/UP).
xumret-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ AGENTS.md