claude fixoval /remind skill
This commit is contained in:
@@ -288,17 +288,11 @@
|
|||||||
"sessionKey": null
|
"sessionKey": null
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"nextRunAtMs": 1781069612302,
|
"nextRunAtMs": 1781071412303,
|
||||||
"lastRunAtMs": 1781067812302,
|
"lastRunAtMs": 1781069612303,
|
||||||
"lastStatus": "ok",
|
"lastStatus": "ok",
|
||||||
"lastError": null,
|
"lastError": null,
|
||||||
"runHistory": [
|
"runHistory": [
|
||||||
{
|
|
||||||
"runAtMs": 1781033115995,
|
|
||||||
"status": "ok",
|
|
||||||
"durationMs": 0,
|
|
||||||
"error": null
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"runAtMs": 1781034915997,
|
"runAtMs": 1781034915997,
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@@ -412,11 +406,17 @@
|
|||||||
"status": "ok",
|
"status": "ok",
|
||||||
"durationMs": 0,
|
"durationMs": 0,
|
||||||
"error": null
|
"error": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"runAtMs": 1781069612303,
|
||||||
|
"status": "ok",
|
||||||
|
"durationMs": 0,
|
||||||
|
"error": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"createdAtMs": 1780892715832,
|
"createdAtMs": 1780892715832,
|
||||||
"updatedAtMs": 1781067812302,
|
"updatedAtMs": 1781069612303,
|
||||||
"deleteAfterRun": false
|
"deleteAfterRun": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -143,28 +143,41 @@ def cmd_list(_args: argparse.Namespace) -> int:
|
|||||||
rows = conn.execute(
|
rows = conn.execute(
|
||||||
"SELECT id, text, enabled, timezone, created_at, updated_at, deleted_at FROM reminders WHERE deleted_at IS NULL ORDER BY id"
|
"SELECT id, text, enabled, timezone, created_at, updated_at, deleted_at FROM reminders WHERE deleted_at IS NULL ORDER BY id"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
reminders = []
|
if not rows:
|
||||||
for row in rows:
|
return 0
|
||||||
|
|
||||||
|
for idx, row in enumerate(rows, start=1):
|
||||||
reminder = dict(row)
|
reminder = dict(row)
|
||||||
rid = reminder["id"]
|
rid = reminder["id"]
|
||||||
reminder["at"] = [
|
status = "enabled" if reminder["enabled"] else "disabled"
|
||||||
dict(r) for r in conn.execute(
|
print(f"{idx}. {reminder['text']} ({status})")
|
||||||
"SELECT id, at_datetime FROM schedule_at WHERE reminder_id = ?", (rid,)
|
|
||||||
).fetchall()
|
at_rows = conn.execute(
|
||||||
]
|
"SELECT at_datetime FROM schedule_at WHERE reminder_id = ?", (rid,)
|
||||||
reminder["cron"] = [
|
).fetchall()
|
||||||
dict(r) for r in conn.execute(
|
for r in at_rows:
|
||||||
"SELECT id, cron_expr FROM schedule_cron WHERE reminder_id = ?", (rid,)
|
print(f" - at: {r['at_datetime']}")
|
||||||
).fetchall()
|
|
||||||
]
|
cron_rows = conn.execute(
|
||||||
reminder["random"] = [
|
"SELECT cron_expr FROM schedule_cron WHERE reminder_id = ?", (rid,)
|
||||||
dict(r) for r in conn.execute(
|
).fetchall()
|
||||||
"SELECT id, times_per_day, window_start, window_end, days_filter, from_date, until_date FROM schedule_random WHERE reminder_id = ?",
|
for r in cron_rows:
|
||||||
(rid,),
|
print(f" - cron: {r['cron_expr']}")
|
||||||
).fetchall()
|
|
||||||
]
|
random_rows = conn.execute(
|
||||||
reminders.append(reminder)
|
"SELECT times_per_day, window_start, window_end, days_filter, from_date, until_date FROM schedule_random WHERE reminder_id = ?",
|
||||||
print(json.dumps({"reminders": reminders}, ensure_ascii=False))
|
(rid,),
|
||||||
|
).fetchall()
|
||||||
|
for r in random_rows:
|
||||||
|
parts = [f"random: {r['times_per_day']}× daily {r['window_start']}–{r['window_end']}"]
|
||||||
|
if r["days_filter"]:
|
||||||
|
parts.append(f"({r['days_filter']})")
|
||||||
|
if r["from_date"]:
|
||||||
|
parts.append(f"from {r['from_date']}")
|
||||||
|
if r["until_date"]:
|
||||||
|
parts.append(f"until {r['until_date']}")
|
||||||
|
print(f" - {' '.join(parts)}")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|||||||
@@ -39,9 +39,8 @@ def test_add_list(tmp_path, capsys):
|
|||||||
ret = _run(db_path, ["list"])
|
ret = _run(db_path, ["list"])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
data = json.loads(captured.out)
|
assert "drink water" in captured.out
|
||||||
assert len(data["reminders"]) == 1
|
assert "cron: 0 9 * * *" in captured.out
|
||||||
assert data["reminders"][0]["text"] == "drink water"
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_at_validation(tmp_path, capsys):
|
def test_add_at_validation(tmp_path, capsys):
|
||||||
@@ -78,8 +77,7 @@ def test_remove(tmp_path, capsys):
|
|||||||
|
|
||||||
ret = _run(db_path, ["list"])
|
ret = _run(db_path, ["list"])
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
data = json.loads(captured.out)
|
assert captured.out.strip() == ""
|
||||||
assert len(data["reminders"]) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_remove_no_match(tmp_path, capsys):
|
def test_remove_no_match(tmp_path, capsys):
|
||||||
|
|||||||
Reference in New Issue
Block a user