| 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
|