personal memory agent
1# SPDX-License-Identifier: AGPL-3.0-only
2# Copyright (c) 2026 sol pbc
3
4import argparse
5import sys
6
7from think.callosum import callosum_send
8from think.utils import setup_cli
9
10
11def main() -> None:
12 parser = argparse.ArgumentParser(description="Send a notification via callosum")
13 parser.add_argument("message", nargs="+", help="notification message text")
14 parser.add_argument("--title", help="notification title")
15 parser.add_argument("--icon", help="emoji icon")
16 parser.add_argument("--event", default="show", help="event name (default: show)")
17 parser.add_argument("--action", help="URL path to open on click")
18 parser.add_argument("--facet", help="facet context")
19 parser.add_argument("--app", help="source app name")
20 parser.add_argument("--badge", help="badge text or number")
21 parser.add_argument(
22 "--auto-dismiss",
23 type=int,
24 dest="auto_dismiss",
25 help="auto-dismiss after N milliseconds",
26 )
27 parser.add_argument(
28 "--no-dismiss",
29 action="store_true",
30 dest="no_dismiss",
31 help="make notification non-dismissible",
32 )
33
34 args = setup_cli(parser)
35
36 message = " ".join(args.message)
37 kwargs = {"message": message}
38
39 if args.title is not None:
40 kwargs["title"] = args.title
41 if args.icon is not None:
42 kwargs["icon"] = args.icon
43 if args.action is not None:
44 kwargs["action"] = args.action
45 if args.facet is not None:
46 kwargs["facet"] = args.facet
47 if args.app is not None:
48 kwargs["app"] = args.app
49 if args.badge is not None:
50 kwargs["badge"] = args.badge
51 if args.auto_dismiss is not None:
52 kwargs["autoDismiss"] = args.auto_dismiss
53 if args.no_dismiss:
54 kwargs["dismissible"] = False
55
56 ok = callosum_send("notification", args.event, **kwargs)
57 if ok:
58 print("Notification sent", file=sys.stderr)
59 return
60
61 print("Failed to send notification (is callosum running?)", file=sys.stderr)
62 sys.exit(1)
63
64
65if __name__ == "__main__":
66 main()