OILS / demo / rich-history.ysh View on Github | oils.pub

145 lines, 41 significant
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: '''
10Interface:
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
35Logic:
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
57source $LIB_OSH/task-five.sh
58
59proc 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
108proc my-curl {
109 ... curl
110 --silent
111 --show-error
112 @ARGV
113 ;
114}
115
116proc 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
134proc test-foo {
135 echo hi
136}
137
138# task-five needs a YSH version
139#foo() { echo hi; }
140#task-five @ARGV
141
142byo-maybe-run
143
144#set -x
145@ARGV