repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
011c851
parent
dcfaddb
author
Antonio Mika
date
2024-10-03 18:30:07 +0000 UTC
Update help command output
6 files changed,  +166, -109
M go.mod
M go.sum
M go.mod
+15, -16
 1@@ -19,12 +19,12 @@ require (
 2 	github.com/alecthomas/chroma/v2 v2.14.0
 3 	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
 4 	github.com/charmbracelet/bubbles v0.18.0
 5-	github.com/charmbracelet/bubbletea v0.27.0
 6+	github.com/charmbracelet/bubbletea v1.1.1
 7 	github.com/charmbracelet/glamour v0.7.0
 8-	github.com/charmbracelet/lipgloss v0.12.1
 9+	github.com/charmbracelet/lipgloss v0.13.0
10 	github.com/charmbracelet/promwish v0.7.0
11 	github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa
12-	github.com/charmbracelet/wish v1.4.2
13+	github.com/charmbracelet/wish v1.4.3
14 	github.com/google/go-cmp v0.6.0
15 	github.com/google/uuid v1.6.0
16 	github.com/gorilla/feeds v1.1.2
17@@ -36,7 +36,7 @@ require (
18 	github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5
19 	github.com/neurosnap/go-exif-remove v0.0.0-20221010134343-50d1e3c35577
20 	github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a
21-	github.com/picosh/pubsub v0.0.0-20241003035535-c319ff16a4ce
22+	github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe
23 	github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc
24 	github.com/picosh/tunkit v0.0.0-20240709033345-8315d4f3cd0e
25 	github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
26@@ -49,7 +49,7 @@ require (
27 	go.abhg.dev/goldmark/anchor v0.1.1
28 	go.abhg.dev/goldmark/hashtag v0.3.1
29 	go.abhg.dev/goldmark/toc v0.10.0
30-	golang.org/x/crypto v0.26.0
31+	golang.org/x/crypto v0.27.0
32 	gopkg.in/yaml.v2 v2.4.0
33 )
34 
35@@ -67,14 +67,13 @@ require (
36 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
37 	github.com/charmbracelet/keygen v0.5.1 // indirect
38 	github.com/charmbracelet/log v0.4.0 // indirect
39-	github.com/charmbracelet/x/ansi v0.1.4 // indirect
40+	github.com/charmbracelet/x/ansi v0.3.2 // indirect
41 	github.com/charmbracelet/x/conpty v0.1.0 // indirect
42-	github.com/charmbracelet/x/errors v0.0.0-20240603171354-f37319acd141 // indirect
43-	github.com/charmbracelet/x/input v0.1.3 // indirect
44-	github.com/charmbracelet/x/term v0.1.1 // indirect
45+	github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a // indirect
46+	github.com/charmbracelet/x/input v0.2.0 // indirect
47+	github.com/charmbracelet/x/term v0.2.0 // indirect
48 	github.com/charmbracelet/x/termios v0.1.0 // indirect
49-	github.com/charmbracelet/x/windows v0.1.2 // indirect
50-	github.com/creack/pty v1.1.21 // indirect
51+	github.com/creack/pty v1.1.23 // indirect
52 	github.com/delthas/go-libnp v0.0.0-20221222161248-0e45ece1f878 // indirect
53 	github.com/delthas/go-localeinfo v0.0.0-20221116001557-686a1e185118 // indirect
54 	github.com/dlclark/regexp2 v1.11.0 // indirect
55@@ -109,7 +108,7 @@ require (
56 	github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect
57 	github.com/mattn/go-isatty v0.0.20 // indirect
58 	github.com/mattn/go-localereader v0.0.1 // indirect
59-	github.com/mattn/go-runewidth v0.0.15 // indirect
60+	github.com/mattn/go-runewidth v0.0.16 // indirect
61 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
62 	github.com/minio/madmin-go/v3 v3.0.54 // indirect
63 	github.com/minio/md5-simd v1.1.2 // indirect
64@@ -144,12 +143,12 @@ require (
65 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
66 	github.com/yuin/goldmark-emoji v1.0.2 // indirect
67 	github.com/yusufpapurcu/wmi v1.2.4 // indirect
68-	golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
69+	golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
70 	golang.org/x/net v0.25.0 // indirect
71 	golang.org/x/sync v0.8.0 // indirect
72-	golang.org/x/sys v0.24.0 // indirect
73-	golang.org/x/term v0.23.0 // indirect
74-	golang.org/x/text v0.17.0 // indirect
75+	golang.org/x/sys v0.25.0 // indirect
76+	golang.org/x/term v0.24.0 // indirect
77+	golang.org/x/text v0.18.0 // indirect
78 	golang.org/x/time v0.6.0 // indirect
79 	google.golang.org/protobuf v1.34.1 // indirect
80 	gopkg.in/ini.v1 v1.67.0 // indirect
M go.sum
+30, -31
  1@@ -33,38 +33,36 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
  2 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
  3 github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
  4 github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
  5-github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZYGgRBCbHvU=
  6-github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y=
  7+github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
  8+github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
  9 github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng=
 10 github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps=
 11 github.com/charmbracelet/keygen v0.5.1 h1:zBkkYPtmKDVTw+cwUyY6ZwGDhRxXkEp0Oxs9sqMLqxI=
 12 github.com/charmbracelet/keygen v0.5.1/go.mod h1:zznJVmK/GWB6dAtjluqn2qsttiCBhA5MZSiwb80fcHw=
 13-github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs=
 14-github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8=
 15+github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
 16+github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
 17 github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
 18 github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
 19 github.com/charmbracelet/promwish v0.7.0 h1:oaMH+ey6W4DDIv1xucS8jL1ik/Q46qxjNXlh6XxEm+s=
 20 github.com/charmbracelet/promwish v0.7.0/go.mod h1:WbRJN9irg8LmsBU8G2rFF8md9O3rSg63qrnqquP/+cs=
 21 github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa h1:6rePgmsJguB6Z7Y55stsEVDlWFJoUpQvOX4mdnBjgx4=
 22 github.com/charmbracelet/ssh v0.0.0-20240725163421-eb71b85b27aa/go.mod h1:LmMZag2g7ILMmWtDmU7dIlctUopwmb73KpPzj0ip1uk=
 23-github.com/charmbracelet/wish v1.4.2 h1:H2BKXewugK9Al75wST9h0hpQ95h981RZ5rtimDpygPQ=
 24-github.com/charmbracelet/wish v1.4.2/go.mod h1:3Bzq7qMU2LTvdaM61KrCnhrzGP92D/Ru7CasrpyZmzY=
 25-github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
 26-github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
 27+github.com/charmbracelet/wish v1.4.3 h1:7FvNLoPGqiT7EdjQP4+XuvM1Hrnx9DyknilbD+Okx1s=
 28+github.com/charmbracelet/wish v1.4.3/go.mod h1:hVgmhwhd52fLmO6m5AkREUMZYqQ0qmIJQDMe3HsNPmU=
 29+github.com/charmbracelet/x/ansi v0.3.2 h1:wsEwgAN+C9U06l9dCVMX0/L3x7ptvY1qmjMwyfE6USY=
 30+github.com/charmbracelet/x/ansi v0.3.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
 31 github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U=
 32 github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ=
 33-github.com/charmbracelet/x/errors v0.0.0-20240603171354-f37319acd141 h1:9S0jGt7wdFksixTHjDn30qWOUu6LPmPidnO42roe+Ek=
 34-github.com/charmbracelet/x/errors v0.0.0-20240603171354-f37319acd141/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
 35-github.com/charmbracelet/x/input v0.1.3 h1:oy4TMhyGQsYs/WWJwu1ELUMFnjiUAXwtDf048fHbCkg=
 36-github.com/charmbracelet/x/input v0.1.3/go.mod h1:1gaCOyw1KI9e2j00j/BBZ4ErzRZqa05w0Ghn83yIhKU=
 37-github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
 38-github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
 39+github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a h1:IlWNrDYRP6lyttqsFHDhmo8NXggMwBuhvvCP+Wmb2a8=
 40+github.com/charmbracelet/x/errors v0.0.0-20240919170804-a4978c8e603a/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
 41+github.com/charmbracelet/x/input v0.2.0 h1:1Sv+y/flcqUfUH2PXNIDKDIdT2G8smOnGOgawqhwy8A=
 42+github.com/charmbracelet/x/input v0.2.0/go.mod h1:KUSFIS6uQymtnr5lHVSOK9j8RvwTD4YHnWnzJUYnd/M=
 43+github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
 44+github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
 45 github.com/charmbracelet/x/termios v0.1.0 h1:y4rjAHeFksBAfGbkRDmVinMg7x7DELIGAFbdNvxg97k=
 46 github.com/charmbracelet/x/termios v0.1.0/go.mod h1:H/EVv/KRnrYjz+fCYa9bsKdqF3S8ouDK0AZEbG7r+/U=
 47-github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg=
 48-github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
 49-github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
 50-github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
 51+github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
 52+github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
 53 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 54 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 55 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 56@@ -180,8 +178,9 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
 57 github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 58 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 59 github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 60-github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
 61 github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 62+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
 63+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 64 github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
 65 github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
 66 github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
 67@@ -223,8 +222,8 @@ github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc h1:bvcsoO
 68 github.com/picosh/go-rsync-receiver v0.0.0-20240709135253-1daf4b12a9fc/go.mod h1:i0iR3W4GSm1PuvVxB9OH32E5jP+CYkVb2NQSe0JCtlo=
 69 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a h1:Cr1xODiyd/SjjBRtYA9VX6Do3D+w+DansQzkb4NGeyA=
 70 github.com/picosh/pobj v0.0.0-20240709135546-27097077b26a/go.mod h1:VIkR1MZBvxSK2OO47jikxikAO/sKb/vTmXX5ZuYTIvo=
 71-github.com/picosh/pubsub v0.0.0-20241003035535-c319ff16a4ce h1:mVcqbixMv4F33Aht4chMfIjyN/YZ80Hv+BHhA2sEb6Q=
 72-github.com/picosh/pubsub v0.0.0-20241003035535-c319ff16a4ce/go.mod h1:iuxAenTRpwThFkOJNw5Sumgv0FewjceHrl/4cHKkMe4=
 73+github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe h1:NQA2eXxqFPjVr/8DX073Vap5kMnJk3/AAAgt/jz8cyc=
 74+github.com/picosh/pubsub v0.0.0-20241003170126-d92d74f10efe/go.mod h1:gWhwrStKWJNzp9i44Bc3YQmnC+pIKvI5dYWm1GRHJac=
 75 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc h1:IIsJuAFG2ju3cygKVKTIsYYZf21q5S3Dr1H4fGbfgJg=
 76 github.com/picosh/send v0.0.0-20240820031602-5d3b1a4494cc/go.mod h1:RAgLDK3LrDK6pNeXtU9tjo28obl5DxShcTUk2nm/KCM=
 77 github.com/picosh/senpai v0.0.0-20240503200611-af89e73973b0 h1:pBRIbiCj7K6rGELijb//dYhyCo8A3fvxW5dijrJVtjs=
 78@@ -320,10 +319,10 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
 79 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 80 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
 81 golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
 82-golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
 83-golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
 84-golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
 85-golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
 86+golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
 87+golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
 88+golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
 89+golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
 90 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 92 golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 93@@ -366,8 +365,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 94 golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 95 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 96 golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 97-golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
 98-golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 99+golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
100+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
101 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
102 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
103 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
104@@ -375,8 +374,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
105 golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
106 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
107 golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
108-golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
109-golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
110+golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
111+golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
112 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
113 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
114 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
115@@ -384,8 +383,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
116 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
117 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
118 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
119-golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
120-golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
121+golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
122+golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
123 golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
124 golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
125 golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
M imgs/ssh.go
+1, -1
1@@ -232,7 +232,7 @@ func createServeMux(handler *CliHandler, pubsub psub.PubSub) func(ctx ssh.Contex
2 
3 				err := pubsub.Pub(ctx, uuid.NewString(), bytes.NewBufferString(furl), []*psub.Channel{
4 					psub.NewChannel(fmt.Sprintf("%s/%s:%s", user.Name, img, tag)),
5-				})
6+				}, false)
7 
8 				if err != nil {
9 					handler.Logger.Error("pub error", "err", err)
M pubsub/cli.go
+117, -61
  1@@ -23,14 +23,20 @@ import (
  2 func flagSet(cmdName string, sesh ssh.Session) *flag.FlagSet {
  3 	cmd := flag.NewFlagSet(cmdName, flag.ContinueOnError)
  4 	cmd.SetOutput(sesh)
  5+	cmd.Usage = func() {
  6+		fmt.Fprintf(cmd.Output(), "Usage: %s <topic> [args...]\nArgs:\n", cmdName)
  7+		cmd.PrintDefaults()
  8+	}
  9 	return cmd
 10 }
 11 
 12 func flagCheck(cmd *flag.FlagSet, posArg string, cmdArgs []string) bool {
 13-	_ = cmd.Parse(cmdArgs)
 14+	err := cmd.Parse(cmdArgs)
 15 
 16-	if posArg == "-h" || posArg == "--help" || posArg == "-help" {
 17-		cmd.Usage()
 18+	if err != nil || posArg == "help" {
 19+		if posArg == "help" {
 20+			cmd.Usage()
 21+		}
 22 		return false
 23 	}
 24 	return true
 25@@ -82,7 +88,8 @@ func clientInfo(clients []*psub.Client, clientType string) string {
 26 	return outputData
 27 }
 28 
 29-var helpStr = `Commands: [pub, sub, ls, pipe]
 30+var helpStr = func(sshCmd string) string {
 31+	return fmt.Sprintf(`Command: ssh %s <help | ls | pub | sub | pipe> <topic> [-h | args...]
 32 
 33 The simplest authenticated pubsub system.  Send messages through
 34 user-defined topics.  Topics are private to the authenticated
 35@@ -99,7 +106,8 @@ data is being sent:
 36 - pub => writes to client
 37 - sub => reads from client
 38 - pipe => read and write between clients
 39-`
 40+`, sshCmd)
 41+}
 42 
 43 type CliHandler struct {
 44 	DBPool db.DB
 45@@ -135,14 +143,16 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 46 			args := sesh.Command()
 47 
 48 			if len(args) == 0 {
 49-				wish.Println(sesh, helpStr)
 50+				wish.Println(sesh, helpStr(toSshCmd(handler.Cfg)))
 51 				next(sesh)
 52 				return
 53 			}
 54 
 55 			cmd := strings.TrimSpace(args[0])
 56 			if cmd == "help" {
 57-				wish.Println(sesh, helpStr)
 58+				wish.Println(sesh, helpStr(toSshCmd(handler.Cfg)))
 59+				next(sesh)
 60+				return
 61 			} else if cmd == "ls" {
 62 				topicFilter := fmt.Sprintf("%s/", user.Name)
 63 				if handler.DBPool.HasFeatureForUser(user.ID, "admin") {
 64@@ -188,14 +198,18 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 65 
 66 					_, _ = sesh.Write([]byte(outputData))
 67 				}
 68+
 69+				next(sesh)
 70+				return
 71 			}
 72 
 73 			topic := ""
 74 			cmdArgs := args[1:]
 75-			if len(args) > 1 {
 76+			if len(args) > 1 && !strings.HasPrefix(args[1], "-") {
 77 				topic = strings.TrimSpace(args[1])
 78 				cmdArgs = args[2:]
 79 			}
 80+
 81 			logger.Info(
 82 				"pubsub middleware detected command",
 83 				"args", args,
 84@@ -208,11 +222,26 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
 85 				pubCmd := flagSet("pub", sesh)
 86 				empty := pubCmd.Bool("e", false, "Send an empty message to subs")
 87 				public := pubCmd.Bool("p", false, "Anyone can sub to this topic")
 88-				timeout := pubCmd.Duration("t", 30*24*time.Hour, "Timeout as a Go duration before cancelling the pub event. Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'. Default is 30 days.")
 89+				block := pubCmd.Bool("b", true, "Block writes until a subscriber is available")
 90+				timeout := pubCmd.Duration("t", 30*24*time.Hour, "Timeout as a Go duration to block for a subscriber to be available. Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'. Default is 30 days.")
 91 				if !flagCheck(pubCmd, topic, cmdArgs) {
 92 					return
 93 				}
 94 
 95+				if pubCmd.NArg() == 1 && topic == "" {
 96+					topic = pubCmd.Arg(0)
 97+				}
 98+
 99+				logger.Info(
100+					"flags parsed",
101+					"cmd", cmd,
102+					"empty", *empty,
103+					"public", *public,
104+					"block", *block,
105+					"timeout", *timeout,
106+					"topic", topic,
107+				)
108+
109 				var rw io.ReadWriter
110 				if *empty {
111 					rw = bytes.NewBuffer(make([]byte, 1))
112@@ -236,65 +265,67 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
113 
114 				wish.Println(sesh, "sending msg ...")
115 
116-				count := 0
117-				for topic, channel := range pubsub.GetChannels() {
118-					if topic == name {
119-						for _, client := range channel.GetClients() {
120-							if client.Direction == psub.ChannelDirectionOutput || client.Direction == psub.ChannelDirectionInputOutput {
121-								count++
122+				var pubCtx context.Context = ctx
123+
124+				if *block {
125+					count := 0
126+					for topic, channel := range pubsub.GetChannels() {
127+						if topic == name {
128+							for _, client := range channel.GetClients() {
129+								if client.Direction == psub.ChannelDirectionOutput || client.Direction == psub.ChannelDirectionInputOutput {
130+									count++
131+								}
132 							}
133+							break
134 						}
135-						break
136 					}
137-				}
138 
139-				var pubCtx context.Context = ctx
140+					tt := *timeout
141+					if count == 0 {
142+						termMsg := "no subs found ... waiting"
143+						if tt > 0 {
144+							termMsg += " " + tt.String()
145+						}
146+						wish.Println(sesh, termMsg)
147 
148-				tt := *timeout
149-				if count == 0 {
150-					termMsg := "no subs found ... waiting"
151-					if tt > 0 {
152-						termMsg += " " + tt.String()
153-					}
154-					wish.Println(sesh, termMsg)
155-
156-					downCtx, cancelFunc := context.WithCancel(ctx)
157-					pubCtx = downCtx
158-
159-					ready := make(chan struct{})
160-
161-					go func() {
162-						for {
163-							select {
164-							case <-ctx.Done():
165-								cancelFunc()
166-								return
167-							default:
168-								count := 0
169-								for topic, channel := range pubsub.GetChannels() {
170-									if topic == name {
171-										for _, client := range channel.GetClients() {
172-											if client.Direction == psub.ChannelDirectionOutput || client.Direction == psub.ChannelDirectionInputOutput {
173-												count++
174+						downCtx, cancelFunc := context.WithCancel(ctx)
175+						pubCtx = downCtx
176+
177+						ready := make(chan struct{})
178+
179+						go func() {
180+							for {
181+								select {
182+								case <-ctx.Done():
183+									cancelFunc()
184+									return
185+								default:
186+									count := 0
187+									for topic, channel := range pubsub.GetChannels() {
188+										if topic == name {
189+											for _, client := range channel.GetClients() {
190+												if client.Direction == psub.ChannelDirectionOutput || client.Direction == psub.ChannelDirectionInputOutput {
191+													count++
192+												}
193 											}
194+											break
195 										}
196-										break
197 									}
198-								}
199 
200-								if count > 0 {
201-									close(ready)
202-									return
203+									if count > 0 {
204+										close(ready)
205+										return
206+									}
207 								}
208 							}
209-						}
210-					}()
211+						}()
212 
213-					select {
214-					case <-ready:
215-					case <-time.After(tt):
216-						cancelFunc()
217-						wish.Fatalln(sesh, "timeout reached, exiting ...")
218+						select {
219+						case <-ready:
220+						case <-time.After(tt):
221+							cancelFunc()
222+							wish.Fatalln(sesh, "timeout reached, exiting ...")
223+						}
224 					}
225 				}
226 
227@@ -305,6 +336,7 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
228 					[]*psub.Channel{
229 						psub.NewChannel(name),
230 					},
231+					*block,
232 				)
233 
234 				wish.Println(sesh, "msg sent!")
235@@ -312,13 +344,24 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
236 					wish.Errorln(sesh, err)
237 				}
238 			} else if cmd == "sub" {
239-				pubCmd := flagSet("pub", sesh)
240-				public := pubCmd.Bool("p", false, "Subscribe to a public topic")
241-				keepAlive := pubCmd.Bool("k", false, "Keep the sub alive even after the pub as died")
242-				if !flagCheck(pubCmd, topic, cmdArgs) {
243+				subCmd := flagSet("sub", sesh)
244+				public := subCmd.Bool("p", false, "Subscribe to a public topic")
245+				keepAlive := subCmd.Bool("k", false, "Keep the subscription alive even after the publisher as died")
246+				if !flagCheck(subCmd, topic, cmdArgs) {
247 					return
248 				}
249-				topic := topic
250+
251+				if subCmd.NArg() == 1 && topic == "" {
252+					topic = subCmd.Arg(0)
253+				}
254+
255+				logger.Info(
256+					"flags parsed",
257+					"cmd", cmd,
258+					"public", *public,
259+					"keepAlive", *keepAlive,
260+					"topic", topic,
261+				)
262 
263 				name := toTopic(user.Name, topic)
264 				if *public {
265@@ -345,6 +388,19 @@ func WishMiddleware(handler *CliHandler) wish.Middleware {
266 				if !flagCheck(pipeCmd, topic, cmdArgs) {
267 					return
268 				}
269+
270+				if pipeCmd.NArg() == 1 && topic == "" {
271+					topic = pipeCmd.Arg(0)
272+				}
273+
274+				logger.Info(
275+					"flags parsed",
276+					"cmd", cmd,
277+					"public", *public,
278+					"replay", *replay,
279+					"topic", topic,
280+				)
281+
282 				isCreator := topic == ""
283 				if isCreator {
284 					topic = uuid.NewString()
M pubsub/ssh.go
+2, -0
 1@@ -20,6 +20,7 @@ import (
 2 func StartSshServer() {
 3 	host := shared.GetEnv("PUBSUB_HOST", "0.0.0.0")
 4 	port := shared.GetEnv("PUBSUB_SSH_PORT", "2222")
 5+	portOverride := shared.GetEnv("PUBSUB_SSH_PORT_OVERRIDE", port)
 6 	promPort := shared.GetEnv("PUBSUB_PROM_PORT", "9222")
 7 	cfg := NewConfigSite()
 8 	logger := cfg.Logger
 9@@ -27,6 +28,7 @@ func StartSshServer() {
10 	defer dbh.Close()
11 
12 	cfg.Port = port
13+	cfg.PortOverride = portOverride
14 
15 	pubsub := psub.NewMulticast(logger)
16 	handler := &CliHandler{
M shared/config.go
+1, -0
1@@ -30,6 +30,7 @@ type ConfigSite struct {
2 	Secret       string
3 	Domain       string
4 	Port         string
5+	PortOverride string
6 	Protocol     string
7 	DbURL        string
8 	StorageDir   string