Repository navigation
Recipes
Each recipe was run against the 0.1.1 release zip, in the order shown, on the set from Getting started: "Render tonight" picked, a note on the music question.
The person's note asked for the composer first; the composer sent two cuts. Write the new question to a file with supersedes naming the old one:
{
"id": "music2",
"kind": "choice",
"title": "Credits music, again",
"supersedes": "music",
"question": "Which of the two piano cuts should play over the credits?",
"why": "The composer sent two lengths; the credits run 40 seconds.",
"options": [
{"id": "short", "label": "The 38-second cut"},
{"id": "long", "label": "The 52-second cut"}
],
"guess": {"option": "short", "why": "It fits without a fade.", "confidence": "high"}
}$ python ask.py add ask/first round2.json
{
"ok": true,
"added": [
"music2"
],
"warnings": []
}
$ echo $?
0music is now superseded and off the page; the running server picks up the new question on the page's next load, with no restart. add also writes an "added" mark, so a set the person had finished reports "done": false again until they press "All done" once more.
The render now takes nine hours instead of six. Replace the question with --replace, which raises its rev:
python ask.py add ask/first render2.json --replaceThe answer the person gave to the six-hour version is now stale. It still counts as answered, so check stale before acting on it:
$ python ask.py status ask/first
{
"ok": true,
"set": "first",
"title": "Try askwright",
"open": 2,
"rev": 2,
"done": false,
"paused": false,
"last_mark": {
"t": "<time>",
"type": "added",
"q": [
"render"
]
},
"server": {
"url": "http://127.0.0.1:<port>/",
"pid": <pid>,
"port": <port>,
"set_dir": "/work/proj/ask/first",
"started": "<time>",
"alive": true
},
"answered": [
"render"
],
"unsure": [],
"note_only": [],
"unanswered": [
"music2"
],
"waiting": [],
"not_applicable": [],
"stale": [
"render"
]
}
$ echo $?
0Change a question in place without --replace (by editing questions.json) only for a typo: the old answer would not be flagged.
python ask.py close ask/first music2 --withdrawn "The credits were cut"A withdrawn question leaves the page; its reason stays in the file. --superseded-by <id> points to the question that replaces it, and no option just closes it.
status --wait-done exits 0 whether the person finished or the wait timed out, so test timed_out. With ask.py's path in ASK:
import json, subprocess, sys
ASK = "skills/askwright/scripts/ask.py"
def ask(*args):
out = subprocess.run([sys.executable, ASK, *args], capture_output=True, text=True).stdout
return json.loads(out)
status = ask("status", "ask/first", "--wait-done", "--timeout", "5", "--interval", "1")
if status["timed_out"]:
print("not done yet; unanswered:", status["unanswered"], "stale:", status["stale"])
for a in ask("read", "ask/first")["answers"]:
print(a["qid"], a["state"], a.get("choice"), a["note"] or "-")Run after the two recipes above (the second round added, then withdrawn), it printed:
not done yet; unanswered: [] stale: ['render']
render answered tonight -
music note_only None Ask the composer first
Nothing is unanswered, but the last mark is the "added" one, so the wait ran out; the render answer is stale; and read still returns the superseded music question's note.
For one to four plain questions, a page may be more than the person wants. ask.py inline turns them into a numbered chat message and an AskUserQuestion mapping, or says why it cannot (Commands). inline records nothing: the chat reply is the answer, and the set's answers.json stays as it was.
Keep the set small and point it at the render folder with media_roots, relative to the set folder:
{"media_roots": ["../../renders"]}lint checks that each root exists and that every src is found inside the set folder or a root. A src such as ../outside.png that climbs out fails as media-outside, and the server refuses such a path with 403 (Server and security).
This wiki describes askwright 0.2.0 and was last updated on 2026-10-25. The skill is MIT licensed. Report problems in the issues. Download: askwright 0.2.0.
Using it
- Getting started
- Commands
- Question set format
- Lint rules and errors
- Server and security
- Study mode
- Figures
- Recipes
- FAQ
The releases
Contributing
Elsewhere