1 | # Demo of rich history feature
|
2 | #
|
3 | # Command + Output > Zulip
|
4 | # or Github gist
|
5 | # or Sourcehut pages
|
6 | # or Custom server
|
7 | # or Markdown file / notebook
|
8 |
|
9 | : '''
|
10 | Interface:
|
11 |
|
12 | rh config {
|
13 | module = 'rich-history'
|
14 |
|
15 | # register a service
|
16 | service zulip {
|
17 | }
|
18 | service github {
|
19 | }
|
20 | }
|
21 | rh config # show configuration
|
22 |
|
23 | rh config read < config.json
|
24 |
|
25 |
|
26 | rh start # start recording history
|
27 |
|
28 | rh post # make an HTTP post of the last one
|
29 | rh post -n 2 # the last 2
|
30 |
|
31 | rh post-all # continually POST until we stop
|
32 |
|
33 | rh stop # don't record
|
34 |
|
35 | Logic:
|
36 |
|
37 | rh start
|
38 | create Unix socket, store the descriptor in _rich_history_fd or something
|
39 |
|
40 | main_loop.Interactive
|
41 | create netstring with command
|
42 | create PTY file descriptor
|
43 | bundle these in a FANOS message and send it across the _rich_history_fd
|
44 |
|
45 | Problem:
|
46 | # fork { sleep 5 } | wc -l blocks the whole thing - because we wait on the
|
47 | # It's like { sleep 5 & } | wc -l. Bash has the same behavior though
|
48 | # I guess you can create a special case
|
49 |
|
50 | # This
|
51 | then start configured command
|
52 | rich-history.ysh --max-lines 1000 --buf-size 3 --service zulip
|
53 |
|
54 | '''
|
55 |
|
56 | # make this file a test server
|
57 | source $LIB_OSH/task-five.sh
|
58 |
|
59 | proc server {
|
60 | ### Accept FANOS messages
|
61 |
|
62 | while true {
|
63 |
|
64 | # pass file descriptor 0, and read result
|
65 | # This can raise exceptions too, on malformed FANOS messages?
|
66 | fanos read (0, &result)
|
67 |
|
68 | # result has 2 keys
|
69 | # result = {
|
70 | # # the blob can be CMD {} JSON too
|
71 | # blob: 'CMD ls /tmp; sleep 5'
|
72 | # fd_list: [4], # there should only be one fanos FD
|
73 | # }
|
74 |
|
75 | var fd = fd_list[0]
|
76 | redir < $fd {
|
77 | # discard more than --max-lines?
|
78 | for line in (io.stdin) {
|
79 | :
|
80 | }
|
81 | }
|
82 |
|
83 | # TODO: Construct Markdown for Zulip
|
84 | #
|
85 | # ```shell-sesesion
|
86 | # $ ls /tmp; sleep 5
|
87 | # ```
|
88 |
|
89 | # Output
|
90 | # ```
|
91 | # foo
|
92 | # bar
|
93 | # ```
|
94 | #
|
95 | # must handle:
|
96 | # - triple backticks
|
97 | # - terminal escapes
|
98 | # - if it's a pty()
|
99 | # - other bad UTF-8: surrogates, unprintable characters
|
100 | # - we might want a cleanText() function for this
|
101 | # - Claude AI says Go has bytes.ToValidUTF8, Rust has String::from_utf8_lossy
|
102 | #
|
103 | # Now construct curl command for Zulip
|
104 | }
|
105 | }
|
106 |
|
107 | # Copied from devtools/services/zulip.sh
|
108 | proc my-curl {
|
109 | ... curl
|
110 | --silent
|
111 | --show-error
|
112 | @ARGV
|
113 | ;
|
114 | }
|
115 |
|
116 | proc post-message (bot_email, bot_api_key; stream='misc', subject='Test Zulip API',
|
117 | content=u'```shell-session\n$ ls /tmp\n```\n') {
|
118 |
|
119 | # copied from example at https://zulip.com/api/get-messages
|
120 | ... my-curl
|
121 | -u "$bot_email:$bot_api_key"
|
122 | -d 'type=stream'
|
123 | -d "to=$stream"
|
124 | -d "subject=$subject"
|
125 | -d "content=$content$[ \n ]$(date)"
|
126 | -X POST
|
127 | https://oilshell.zulipchat.com/api/v1/messages
|
128 | ;
|
129 |
|
130 | # doesn't work
|
131 | # --data-urlencode narrow='[{"operand": "0.8.4 Release Notes", "operator": "topic"}]' \
|
132 | }
|
133 |
|
134 | proc test-foo {
|
135 | echo hi
|
136 | }
|
137 |
|
138 | # task-five needs a YSH version
|
139 | #foo() { echo hi; }
|
140 | #task-five @ARGV
|
141 |
|
142 | byo-maybe-run
|
143 |
|
144 | #set -x
|
145 | @ARGV
|