├── tanote
├── sys.kelvin
├── desk.ship
├── mar
│ ├── path.hoon
│ ├── thread-done.hoon
│ ├── thread-fail.hoon
│ ├── tape.hoon
│ ├── woff2.hoon
│ ├── png.hoon
│ ├── svg.hoon
│ ├── urbit.hoon
│ ├── language-server
│ │ └── rpc
│ │ │ ├── response.hoon
│ │ │ ├── request.hoon
│ │ │ └── notification.hoon
│ ├── story-diff.hoon
│ ├── txt-diff.hoon
│ ├── atom.hoon
│ ├── purl.hoon
│ ├── noun.hoon
│ ├── htm.hoon
│ ├── ship.hoon
│ ├── kelvin.hoon
│ ├── docket-0.hoon
│ ├── hymn.hoon
│ ├── belt.hoon
│ ├── js.hoon
│ ├── urb.hoon
│ ├── udon.hoon
│ ├── httr.hoon
│ ├── umd.hoon
│ ├── mime.hoon
│ ├── json.hoon
│ ├── xml.hoon
│ ├── tang.hoon
│ ├── html.hoon
│ ├── bill.hoon
│ ├── json
│ │ └── rpc
│ │ │ └── response.hoon
│ ├── sole
│ │ ├── action.hoon
│ │ └── effect.hoon
│ ├── blit.hoon
│ ├── hoon.hoon
│ └── story.hoon
├── sur
│ ├── verb.hoon
│ ├── story.hoon
│ ├── spider.hoon
│ ├── keygen.hoon
│ ├── json
│ │ └── rpc.hoon
│ ├── settings.hoon
│ ├── ring.hoon
│ ├── docket.hoon
│ ├── bitcoin.hoon
│ ├── aquarium.hoon
│ ├── language-server.hoon
│ ├── asn1.hoon
│ ├── hark-store.hoon
│ └── sole.hoon
├── desk.docket-0
├── lib
│ ├── skeleton.hoon
│ ├── bip39.hoon
│ ├── language-server
│ │ ├── build.hoon
│ │ └── parser.hoon
│ ├── mip.hoon
│ ├── test.hoon
│ ├── default-agent.hoon
│ ├── cram.hoon
│ ├── primitive-rsa.hoon
│ ├── ph
│ │ └── util.hoon
│ ├── agentio.hoon
│ ├── keygen.hoon
│ ├── story.hoon
│ ├── verb.hoon
│ ├── pill.hoon
│ ├── bitcoin-utils.hoon
│ ├── sole.hoon
│ ├── bip
│ │ ├── b174.hoon
│ │ └── b173.hoon
│ ├── dbug.hoon
│ ├── server.hoon
│ ├── azimuthio.hoon
│ ├── tanote.hoon
│ ├── strand.hoon
│ ├── hark-store.hoon
│ ├── docket.hoon
│ └── jose.hoon
└── gen
│ ├── help.hoon
│ └── testlib.hoon
├── urbit.aide
├── tanote.md
├── tanote-glob
├── img
│ ├── tanote.png
│ ├── crop_tanote.png
│ ├── tanote_landscape.png
│ └── tanote.svg
└── index.html
├── screen layout.md
├── ~modnyd-salser 2022-04.md
├── urbsidian.md
├── README.md
├── session init.md
├── icon.md
├── proposal project.md
├── ~hanfel-dovned 2021.md
├── Aide
├── LICENSE
├── %pony.md
├── create desk files.md
├── Funes the memorious.md
├── proposal meta.md
├── tah-noh-tay members.md
├── ~pocwet journal.md
├── publish.md
├── session Gettysburg.md
├── tangents.md
├── create and upload glob.md
├── create desk.md
├── glossary.md
├── announce.md
├── Yarvin 2007.md
├── data structures.md
├── proposal tech.md
├── ~tonned-fampet 2022-06-23.md
├── brainstorm.md
├── session Nocturna.md
└── interfaces.md
/tanote/sys.kelvin:
--------------------------------------------------------------------------------
1 | [%zuse 418]
2 |
--------------------------------------------------------------------------------
/tanote/desk.ship:
--------------------------------------------------------------------------------
1 | ~ponhec-picwen
2 |
--------------------------------------------------------------------------------
/urbit.aide:
--------------------------------------------------------------------------------
1 | /n/local/home/jdc/urbit/bus
2 | /n/local/home/jdc/urbit/zod
3 |
--------------------------------------------------------------------------------
/tanote.md:
--------------------------------------------------------------------------------
1 | https://github.com/catenate/tanote
2 |
3 | https://i.imgur.com/zTLTq0U.png
4 |
5 |
--------------------------------------------------------------------------------
/tanote-glob/img/tanote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/catenate/tanote/HEAD/tanote-glob/img/tanote.png
--------------------------------------------------------------------------------
/tanote-glob/img/crop_tanote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/catenate/tanote/HEAD/tanote-glob/img/crop_tanote.png
--------------------------------------------------------------------------------
/tanote-glob/img/tanote_landscape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/catenate/tanote/HEAD/tanote-glob/img/tanote_landscape.png
--------------------------------------------------------------------------------
/tanote/mar/path.hoon:
--------------------------------------------------------------------------------
1 | |_ pax=path
2 | ++ grad %noun
3 | ++ grow
4 | |%
5 | ++ noun pax
6 | --
7 | ++ grab
8 | |%
9 | ++ noun path
10 | --
11 | --
12 |
--------------------------------------------------------------------------------
/tanote/mar/thread-done.hoon:
--------------------------------------------------------------------------------
1 | |_ res=*
2 | ++ grab
3 | |%
4 | ++ noun *
5 | --
6 | ++ grow
7 | |%
8 | ++ noun res
9 | --
10 | ++ grad %noun
11 | --
12 |
--------------------------------------------------------------------------------
/tanote/mar/thread-fail.hoon:
--------------------------------------------------------------------------------
1 | |_ err=*
2 | ++ grab
3 | |%
4 | ++ noun (pair term tang)
5 | --
6 | ++ grow
7 | |%
8 | ++ noun err
9 | --
10 | ++ grad %noun
11 | --
12 |
--------------------------------------------------------------------------------
/tanote/mar/tape.hoon:
--------------------------------------------------------------------------------
1 | |_ tap=tape
2 | ++ grad %noun
3 | ++ grow
4 | |%
5 | ++ noun tap
6 | ++ json s+(crip tap)
7 | --
8 | ++ grab
9 | |%
10 | ++ noun tape
11 | --
12 | --
13 |
--------------------------------------------------------------------------------
/tanote/mar/woff2.hoon:
--------------------------------------------------------------------------------
1 | |_ dat=octs
2 | ++ grow
3 | |%
4 | ++ mime [/font/woff2 dat]
5 | --
6 | ++ grab
7 | |%
8 | ++ mime |=([=mite =octs] octs)
9 | ++ noun octs
10 | --
11 | ++ grad %mime
12 | --
13 |
--------------------------------------------------------------------------------
/tanote/mar/png.hoon:
--------------------------------------------------------------------------------
1 | |_ dat=@
2 | ++ grow
3 | |%
4 | ++ mime [/image/png (as-octs:mimes:html dat)]
5 | --
6 | ++ grab
7 | |%
8 | ++ mime |=([p=mite q=octs] q.q)
9 | ++ noun @
10 | --
11 | ++ grad %mime
12 | --
13 |
--------------------------------------------------------------------------------
/tanote/mar/svg.hoon:
--------------------------------------------------------------------------------
1 | |_ dat=@
2 | ++ grow
3 | |%
4 | ++ mime [/image/'svg+xml' (as-octs:mimes:html dat)]
5 | --
6 | ++ grab
7 | |%
8 | ++ mime |=([p=mite q=octs] q.q)
9 | ++ noun @
10 | --
11 | ++ grad %mime
12 | --
13 |
--------------------------------------------------------------------------------
/screen layout.md:
--------------------------------------------------------------------------------
1 | [[tanote/tanote]]
2 |
3 | General outline of the format of the screen.
4 |
5 | > tags and @ps
6 | >
7 | > names of notes. separated by periods. like sentence fragments.
8 | >
9 | > headers of the text
10 | >
11 | > body of the text
12 |
13 |
--------------------------------------------------------------------------------
/tanote/mar/urbit.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/urbit/mar
3 | ::
4 | /? 310
5 | :::: A minimal urbit mark
6 | ::
7 | |_ her=@p
8 | ++ grab
9 | |%
10 | ++ noun @p
11 | --
12 | ++ grow
13 | |%
14 | ++ noun her
15 | --
16 | ++ grad %noun
17 | --
18 |
--------------------------------------------------------------------------------
/tanote/sur/verb.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | +$ event
3 | $% [%on-init ~]
4 | [%on-load ~]
5 | [%on-poke =mark]
6 | [%on-watch =path]
7 | [%on-leave =path]
8 | [%on-agent =wire sign=term]
9 | [%on-arvo =wire vane=term sign=term]
10 | [%on-fail =term]
11 | ==
12 | --
--------------------------------------------------------------------------------
/~modnyd-salser 2022-04.md:
--------------------------------------------------------------------------------
1 | [[edit text]]
2 |
3 | [[~modnyd-salser]]. [[2022-04]]. The estuary: Non-linear decentralized text editing environment. [[Hackmd]]. https://hackmd.io/@yaHLeQfXQMO1b9SlGU4KOw/rJLoBnVmq
4 |
5 | Also published in [[Urbit]], in the group [[Other life]]: Open group blog.
6 |
7 |
--------------------------------------------------------------------------------
/tanote/desk.docket-0:
--------------------------------------------------------------------------------
1 | :~ title+'Tanote'
2 | info+'factious note store'
3 | color+0x4c.f9ff
4 | version+[0 0 2]
5 | website+'https://github.com/catenate/tanote'
6 | license+'MIT'
7 | base+'tanote'
8 | glob-ames+[~zod 0v0]
9 | image+'https://i.imgur.com/llOoZD3.png'
10 | ==
11 |
--------------------------------------------------------------------------------
/tanote/mar/language-server/rpc/response.hoon:
--------------------------------------------------------------------------------
1 | /- *language-server
2 | /+ lsp=language-server-json
3 | |_ res=all:response
4 | ::
5 | ++ grad %noun
6 | ++ grow
7 | |%
8 | ++ noun res
9 | ++ json (response:enjs:lsp res)
10 | --
11 | ::
12 | ++ grab
13 | |%
14 | ++ noun all:response
15 | --
16 | ::
17 | --
18 |
--------------------------------------------------------------------------------
/tanote/mar/language-server/rpc/request.hoon:
--------------------------------------------------------------------------------
1 | /- *language-server
2 | /+ lsp-json=language-server-json
3 | |_ req=all:request
4 | ++ grad %noun
5 | ++ grow
6 | |%
7 | ++ noun req
8 | --
9 | ++ grab
10 | |%
11 | ++ noun all:request
12 | ++ json
13 | |= jon=^json
14 | (request:dejs:lsp-json jon)
15 | --
16 | --
17 |
--------------------------------------------------------------------------------
/tanote/mar/story-diff.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | ::::
3 | ::
4 | /- *story
5 | |_ =story-diff
6 | ::
7 | ++ grad %noun
8 | ++ grow
9 | |%
10 | ++ noun story-diff
11 | --
12 | ++ grab :: convert from
13 | |%
14 | ++ noun ^story-diff :: make from %noun
15 | --
16 | --
17 |
--------------------------------------------------------------------------------
/tanote/mar/txt-diff.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/txt-diff/mar
3 | ::
4 | /? 310
5 | |_ txt-diff=(urge:clay cord)
6 | ::
7 | ++ grad %noun
8 | ++ grow
9 | |%
10 | ++ noun txt-diff
11 | --
12 | ++ grab :: convert from
13 | |%
14 | ++ noun (urge:clay cord) :: make from %noun
15 | --
16 | --
17 |
--------------------------------------------------------------------------------
/tanote/mar/atom.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/atom/mar
3 | ::
4 | /? 310
5 | ::
6 | :::: A minimal atom mark
7 | ::
8 | =, mimes:html
9 | |_ ato=@
10 | ++ grab |%
11 | ++ noun @
12 | ++ mime |=([* p=octs] q.p)
13 | --
14 | ++ grow |%
15 | ++ mime [/application/x-urb-unknown (as-octs ato)]
16 | --
17 | ++ grad %mime
18 | --
19 |
--------------------------------------------------------------------------------
/tanote-glob/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tanote
5 |
10 |
11 |
12 | factious note store
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tanote/mar/purl.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/purl/mar
3 | ::
4 | /? 310
5 | =, eyre
6 | |_ url=purl
7 | ++ grad %noun
8 | ::
9 | ++ grow
10 | |%
11 | ++ noun url
12 | ++ hiss [url %get ~ ~]
13 | --
14 | ++ grab :: convert from
15 | |%
16 | ++ noun purl :: clam from %noun
17 | --
18 | --
19 |
--------------------------------------------------------------------------------
/tanote/mar/noun.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/noun/mar
3 | ::
4 | /? 310
5 | !:
6 | :::: A minimal noun mark
7 | |_ non=*
8 | ++ grab |%
9 | ++ noun *
10 | --
11 | ++ grad
12 | |%
13 | ++ form %noun
14 | ++ diff |=(* +<)
15 | ++ pact |=(* +<)
16 | ++ join |=([* *] *(unit *))
17 | ++ mash |=([[ship desk *] [ship desk *]] `*`~|(%noun-mash !!))
18 | --
19 | --
20 |
--------------------------------------------------------------------------------
/tanote/mar/language-server/rpc/notification.hoon:
--------------------------------------------------------------------------------
1 | /- *language-server
2 | /+ lsp-json=language-server-json
3 | |_ not=all:notification
4 | ++ grad %noun
5 | ++ grab
6 | |%
7 | ++ noun all:notification
8 | ++ json
9 | |= jon=^json
10 | (notification:dejs:lsp-json jon)
11 | --
12 | ++ grow
13 | |%
14 | ++ noun not
15 | ++ json
16 | (notification:enjs:lsp-json not)
17 | --
18 | --
19 |
--------------------------------------------------------------------------------
/tanote/mar/htm.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/htm/mar
3 | ::
4 | /? 310
5 | |_ own=manx
6 | ::
7 | ++ grad %noun
8 | ++ grow :: convert to
9 | |%
10 | ++ noun own
11 | ++ hymn own
12 | --
13 | ++ grab |% :: convert from
14 | ++ noun manx :: clam from %noun
15 | -- --
16 |
--------------------------------------------------------------------------------
/tanote/mar/ship.hoon:
--------------------------------------------------------------------------------
1 | |_ s=ship
2 | ++ grad %noun
3 | ++ grow
4 | |%
5 | ++ noun s
6 | ++ json s+(scot %p s)
7 | ++ mime
8 | ^- ^mime
9 | [/text/x-ship (as-octt:mimes:html (scow %p s))]
10 |
11 | --
12 | ++ grab
13 | |%
14 | ++ noun ship
15 | ++ json (su:dejs:format ;~(pfix sig fed:ag))
16 | ++ mime
17 | |= [=mite len=@ tex=@]
18 | (slav %p (snag 0 (to-wain:format tex)))
19 | --
20 | --
21 |
--------------------------------------------------------------------------------
/tanote/sur/story.hoon:
--------------------------------------------------------------------------------
1 | ^?
2 | |%
3 | +$ prose [title=@t body=@t]
4 | +$ proses (set prose)
5 | +$ story (jug tako:clay prose) :: set len > 1 means conflicting messages have been assigned
6 | +$ chapter [tako:clay proses] :: prose entry type
7 | +$ cash $%([%tako p=tako:clay] case) :: used in generators to accept a tako directly as well
8 | +$ story-diff [additions=story deletions=story]
9 | --
--------------------------------------------------------------------------------
/tanote/mar/kelvin.hoon:
--------------------------------------------------------------------------------
1 | =/ weft ,[lal=@tas num=@ud] :: TODO remove after merge
2 | |_ kel=weft
3 | ++ grow
4 | |%
5 | ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)]
6 | ++ noun kel
7 | ++ hoon (crip "{<[lal num]:kel>}\0a")
8 | ++ txt (to-wain:format hoon)
9 | --
10 | ++ grab
11 | |%
12 | ++ noun weft
13 | ++ mime
14 | |= [=mite len=@ud tex=@]
15 | !<(weft (slap !>(~) (ream tex)))
16 | --
17 | ++ grad %noun
18 | --
19 |
--------------------------------------------------------------------------------
/tanote/sur/spider.hoon:
--------------------------------------------------------------------------------
1 | /+ libstrand=strand
2 | =, strand=strand:libstrand
3 | |%
4 | +$ thread $-(vase _*form:(strand ,vase))
5 | +$ input [=tid =cage]
6 | +$ tid tid:strand
7 | +$ bowl bowl:strand
8 | +$ http-error
9 | $? %bad-request :: 400
10 | %forbidden :: 403
11 | %nonexistent :: 404
12 | %offline :: 504
13 | ==
14 | +$ start-args
15 | $: parent=(unit tid)
16 | use=(unit tid)
17 | =beak
18 | file=term
19 | =vase
20 | ==
21 | --
22 |
--------------------------------------------------------------------------------
/urbsidian.md:
--------------------------------------------------------------------------------
1 | [[~sogrum-savluc]]: We could get a decent way towards a minimally-useful version with just some additional UI on linking [[Groups Notebook]] posts. Imagine when you typed a `[[` in a Notebook post you got a dropdown fuzzy-finder for other posts whereby clicking on one filled in the appropriate markdown link to that post. That seems small and easy, yet wildly powerful. I guess we'd need backlinks, too. Trying to shoehorn this all into Notebooks isn't the ideal long-term product, but with a few tweaks it could get really close in the near term.
2 |
3 |
--------------------------------------------------------------------------------
/tanote/mar/docket-0.hoon:
--------------------------------------------------------------------------------
1 | /+ dock=docket
2 | |_ =docket:dock
3 | ++ grow
4 | |%
5 | ++ mime
6 | ^- ^mime
7 | [/text/x-docket (as-octt:mimes:html (spit-docket:mime:dock docket))]
8 | ++ noun docket
9 | ++ json (docket:enjs:dock docket)
10 | --
11 | ++ grab
12 | |%
13 | ::
14 | ++ mime
15 | |= [=mite len=@ud tex=@]
16 | ^- docket:dock
17 | %- need
18 | %- from-clauses:mime:dock
19 | !<((list clause:dock) (slap !>(~) (ream tex)))
20 |
21 | ::
22 | ++ noun docket:dock
23 | --
24 | ++ grad %noun
25 | --
26 |
--------------------------------------------------------------------------------
/tanote/sur/keygen.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | +$ revision @ud
3 | +$ nodetype tape
4 | +$ mnemonic tape
5 | ::
6 | +$ vault
7 | $: ownership=node
8 | voting=node
9 | management=node
10 | transfer=node
11 | spawn=node
12 | network=uode
13 | ==
14 | ::
15 | +$ node [type=nodetype seed=mnemonic keys=wallet]
16 | +$ uode [revi=revision seed=@ux keys=edkeys]
17 | ::
18 | +$ wallet [keys=[public=@ux private=@ux] addr=@ux chain=@ux]
19 | ::
20 | +$ edkeys [auth=keypair crypt=keypair]
21 | ::
22 | +$ keypair [public=@ux secret=@ux]
23 | --
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tanote
2 |
3 | Tanote (tah-noh-tay) is a [factious](https://www.unqualified-reservations.org/2007/08/uberfact-ultimate-social-verifier/) note store for [Urbit](https://urbit.org/docs/development/develop), which uses tags to present subsets of notes, and sends versions of notes to others.
4 |
5 | I'm currently working through [Hoon School](https://urbit.org/docs/hoon/hoon-school), so this project will be in development for a while, as I figure out how to write it.
6 |
7 | The markdown files in this repository are best viewed in [Obsidian](https://obsidian.md/).
8 |
9 |
--------------------------------------------------------------------------------
/tanote/mar/hymn.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/hymn/mar
3 | ::
4 | /? 310
5 | =, mimes:html
6 | =, html
7 | |_ own=manx
8 | ::
9 | ++ grad %noun
10 | ++ grow :: convert to
11 | |%
12 | ++ html (crip (en-xml own)) :: convert to %html
13 | ++ mime [/text/html (as-octs html)] :: convert to %mime
14 | --
15 | ++ grab |% :: convert from
16 | ++ noun manx :: clam from %noun
17 | -- --
18 |
--------------------------------------------------------------------------------
/tanote/mar/belt.hoon:
--------------------------------------------------------------------------------
1 | :: belt: runtime belt structure
2 | ::
3 | |_ =belt:dill
4 | ++ grad %noun
5 | :: +grab: convert from
6 | ::
7 | ++ grab
8 | |%
9 | ++ noun belt:dill
10 | ++ json
11 | ^- $-(^json belt:dill)
12 | =, dejs:format
13 | %- of
14 | :~ aro+(su (perk %d %l %r %u ~))
15 | bac+ul
16 | ctl+(cu taft so)
17 | del+ul
18 | met+(cu taft so)
19 | ret+ul
20 | txt+(ar (cu taft so))
21 | ==
22 | --
23 | :: +grow: convert to
24 | ::
25 | ++ grow
26 | |%
27 | ++ noun belt
28 | --
29 | --
30 |
--------------------------------------------------------------------------------
/tanote/mar/js.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/js/mar
3 | ::
4 | /? 310
5 | ::
6 | =, eyre
7 | |_ mud=@
8 | ++ grow
9 | |%
10 | ++ mime [/application/javascript (as-octs:mimes:html (@t mud))]
11 | ++ elem ;script
12 | ;- (trip (@t mud))
13 | ==
14 | ++ hymn ;html:(head:"+{elem}" body)
15 | --
16 | ++ grab
17 | |% :: convert from
18 | ++ mime |=([p=mite q=octs] (@t q.q))
19 | ++ noun cord :: clam from %noun
20 | --
21 | ++ grad %mime
22 | --
23 |
--------------------------------------------------------------------------------
/session init.md:
--------------------------------------------------------------------------------
1 | [[tanote/tanote]]
2 | [[screen layout]]
3 |
4 | The starting screen, before adding any version. The list of @ps comes from %pals. `|` represents the cursor at the start of a text entry field. Struck-out text is changeable. Highlighted text is clickable. Your own id is italic because it’s in the text of the note. The star should be bold, since it is selected by default, and highlighted, since it is clickable.
5 |
6 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==_~ponhec-picwen_==
7 | >
8 | >
9 | >
10 | > by ~ponhec-picwen
11 | > ==to== |
12 | > re |
13 | > ==no== ~~1~~ of 1
14 | >
15 | > |
16 |
17 |
--------------------------------------------------------------------------------
/tanote/sur/json/rpc.hoon:
--------------------------------------------------------------------------------
1 | :: json-rpc: protocol types
2 | ::
3 | |%
4 | +$ batch-request
5 | $% [%a p=(list request)]
6 | [%o p=request]
7 | ==
8 | ::
9 | +$ request
10 | $: id=@t
11 | jsonrpc=@t
12 | method=@t
13 | params=request-params
14 | ==
15 | ::
16 | +$ request-params
17 | $% [%list (list json)]
18 | [%map (map @t json)]
19 | [%object (list (pair @t json))]
20 | ==
21 | +$ response
22 | $~ [%fail *httr:eyre]
23 | $% [%result id=@t res=json]
24 | [%error id=@t code=@t message=@t] ::TODO data?
25 | [%fail hit=httr:eyre]
26 | [%batch bas=(list response)]
27 | ==
28 | --
29 |
--------------------------------------------------------------------------------
/tanote/mar/urb.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/elem/urb/mar
3 | ::
4 | /? 310
5 | =, mimes:html
6 | =, html
7 | |_ own=manx
8 | ::
9 | ++ grad %noun
10 | ++ grow :: convert to
11 | |%
12 | ++ hymn ;html:(head body:"+{own}") :: convert to %hymn
13 | ++ html (crip (en-xml hymn)) :: convert to %html
14 | ++ mime [/text/html (as-octs html)] :: convert to %mime
15 | --
16 | ++ grab |% :: convert from
17 | ++ noun manx :: clam from %noun
18 | -- --
19 |
--------------------------------------------------------------------------------
/tanote/mar/udon.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/udon/mar
3 | ::
4 | /+ cram
5 | ::
6 | |_ mud=@t
7 | ++ grow
8 | |%
9 | ++ mime [/text/x-unmark (as-octs:mimes:html mud)]
10 | ++ txt
11 | (to-wain:format mud)
12 | ++ elem
13 | ^- manx
14 | =, cram
15 | elm:(static (ream mud))
16 | ++ front :: XX performance, types
17 | ^- (map term knot)
18 | %- ~(run by inf:(static:cram (ream mud)))
19 | |= a=dime ^- cord
20 | ?+ (end 3 p.a) (scot a)
21 | %t q.a
22 | ==
23 | --
24 | ++ grab
25 | |%
26 | ++ mime |=((pair mite octs) q.q)
27 | ++ noun @t
28 | ++ txt of-wain:format
29 | --
30 | ++ grad %txt
31 | --
32 |
--------------------------------------------------------------------------------
/tanote/mar/httr.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/httr/mar
3 | ::
4 | /? 310
5 | ::
6 | =, eyre
7 | =, format
8 | =, html
9 | |_ hit=httr
10 | ++ grad %noun
11 | ++ grow |% ++ wall (turn wain trip)
12 | ++ wain (to-wain cord)
13 | ++ json (need (de-json cord))
14 | ++ cord q:octs
15 | ++ noun hit
16 | ++ octs
17 | ~| hit
18 | ?> =(2 (div p.hit 100))
19 | (need r.hit)
20 | --
21 | ++ grab :: convert from
22 | |%
23 | ++ noun httr :: clam from %noun
24 | --
25 | --
26 |
--------------------------------------------------------------------------------
/tanote/mar/umd.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/umd/mar
3 | ::
4 | /+ cram
5 | ::
6 | |_ mud=@t
7 | ++ grow
8 | |%
9 | ++ mime [/text/x-unmark (as-octs:mimes:html mud)]
10 | ++ txt
11 | (to-wain:format mud)
12 | ++ elem
13 | ^- manx
14 | =, cram
15 | elm:(static (ream mud))
16 | ++ front :: XX performance, types
17 | ^- (map term knot)
18 | %- ~(run by inf:(static:cram (ream mud)))
19 | |= a=dime ^- cord
20 | ?+ (end 3 p.a) (scot a)
21 | %t q.a
22 | ==
23 | --
24 | ++ grab
25 | |%
26 | ++ mime |=((pair mite octs) q.q)
27 | ++ noun @t
28 | ++ txt of-wain:format
29 | --
30 | ++ grad %txt
31 | ++ garb /down
32 | --
33 |
--------------------------------------------------------------------------------
/tanote/mar/mime.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/mime/mar
3 | ::
4 | /? 310
5 | ::
6 | |_ own=mime
7 | ++ grow
8 | ^?
9 | |%
10 | ++ jam `@`q.q.own
11 | --
12 | ::
13 | ++ grab :: convert from
14 | ^?
15 | |%
16 | ++ noun mime :: clam from %noun
17 | ++ tape
18 | |=(a=_"" [/application/x-urb-unknown (as-octt:mimes:html a)])
19 | --
20 | ++ grad
21 | ^?
22 | |%
23 | ++ form %mime
24 | ++ diff |=(mime +<)
25 | ++ pact |=(mime +<)
26 | ++ join |=([mime mime] `(unit mime)`~)
27 | ++ mash
28 | |= [[ship desk mime] [ship desk mime]]
29 | ^- mime
30 | ~|(%mime-mash !!)
31 | --
32 | --
33 |
--------------------------------------------------------------------------------
/icon.md:
--------------------------------------------------------------------------------
1 | ![[crop_tanote.png]]
2 |
3 | Small PNG from drawshield. Three stacked horizontal sections. Top: vert, hash sable. Middle: or, bar sable. Bottom: celestial azure, v sable. Alternately, arrow fletched facing downward sable.
4 |
5 | Crop to remove bottom section.
6 |
7 | Color picker says the code for the bottom section is 4cf9ff. This apparently doesn't quite match, or landscape does something to the bubble around the name to make it slightly lighter.
8 |
9 | ## blazon
10 |
11 | Tierced-in-fess vert and or and celestial azure, in chief a letter "#" sable shown slightly lower, in fess point a letter "|" sable shown very much smaller, in base point the letter "v" sable shown much lower, drawn in a square shape
12 |
13 |
--------------------------------------------------------------------------------
/tanote/mar/json.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/json/mar
3 | ::
4 | /? 310
5 | ::
6 | :::: compute
7 | ::
8 | =, eyre
9 | =, format
10 | =, html
11 | |_ jon=json
12 | ::
13 | ++ grow :: convert to
14 | |%
15 | ++ mime [/application/json (as-octs:mimes -:txt)] :: convert to %mime
16 | ++ txt [(crip (en-json jon))]~
17 | --
18 | ++ grab
19 | |% :: convert from
20 | ++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json))
21 | ++ noun json :: clam from %noun
22 | ++ numb numb:enjs
23 | ++ time time:enjs
24 | --
25 | ++ grad %mime
26 | --
27 |
--------------------------------------------------------------------------------
/tanote/mar/xml.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/xml/mar
3 | ::
4 | /? 310
5 | ::
6 | :::: compute
7 | ::
8 | =, mimes:html
9 | =, html
10 | |_ xml=@t
11 | ::
12 | ++ grad %mime
13 | ++ grow :: convert to
14 | |% ::
15 | ++ mime [/application/xml (as-octs xml)] :: to %mime
16 | ++ hymn (need (de-xml xml)) :: to %hymn
17 | -- ::
18 | ++ grab |% :: convert from
19 | ++ noun @t :: clam from %noun
20 | ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime
21 | -- --
22 |
--------------------------------------------------------------------------------
/tanote/mar/tang.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/tang/mar
3 | ::
4 | /? 310
5 | ::
6 | =, format
7 | |_ tan=(list tank)
8 | ++ grad %noun
9 | ++ grow
10 | |%
11 | ++ noun tan
12 | ++ json
13 | =/ result=(each (list ^json) tang)
14 | (mule |.((turn tan tank:enjs:format)))
15 | ?- -.result
16 | %& a+p.result
17 | %| a+[a+[%s '[[output rendering error]]']~]~
18 | ==
19 | ::
20 | ++ elem
21 | =- ;pre:code:"{(of-wall -)}"
22 | ^- wall %- zing ^- (list wall)
23 | (turn (flop tan) |=(a=tank (wash 0^160 a)))
24 | --
25 | ++ grab :: convert from
26 | |%
27 | ++ noun (list ^tank) :: clam from %noun
28 | ++ tank |=(a=^tank [a]~)
29 | --
30 | --
31 |
--------------------------------------------------------------------------------
/tanote/mar/html.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/html/mar
3 | ::
4 | /? 310
5 | ::
6 | :::: compute
7 | ::
8 | =, html
9 | |_ htm=@t
10 | ++ grow :: convert to
11 | ^?
12 | |% ::
13 | ++ mime [/text/html (met 3 htm) htm] :: to %mime
14 | ++ hymn (need (de-xml htm)) :: to %hymn
15 | -- ::
16 | ++ grab ^?
17 | |% :: convert from
18 | ++ noun @t :: clam from %noun
19 | ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime
20 | --
21 | ++ grad %mime
22 | --
23 |
--------------------------------------------------------------------------------
/proposal project.md:
--------------------------------------------------------------------------------
1 | # Tanote proposal
2 |
3 | ## Project summary
4 |
5 | ### Qualifications
6 |
7 | I recently had a brainstorm that defined this project, and have been inspired to make something that strikes me as Martian. I'm doing this on my own, but I have a Computer Engineering degree and 40 years experience writing software (taught myself BASIC on a TI-99/4A and Logo on a Commodore 64), so I should be able to figure it out. Professionally, I’ve been a software build engineer since 1994, in telecoms, build-tool, financial, and electrical-distribution industries, and I use Inferno over top of whichever laptop OS they give me.
8 |
9 | ### Funding
10 |
11 | I’ll let the Foundation decide how much this project is worth. I hope at least one star, which I would use to get more people into Urbit.
12 |
13 |
--------------------------------------------------------------------------------
/tanote/mar/bill.hoon:
--------------------------------------------------------------------------------
1 | |_ bil=(list dude:gall)
2 | ++ grow
3 | |%
4 | ++ mime `^mime`[/text/x-bill (as-octs:mimes:html hoon)]
5 | ++ noun bil
6 | ++ hoon
7 | ^- @t
8 | |^ (crip (of-wall:format (wrap-lines (spit-duz bil))))
9 | ::
10 | ++ wrap-lines
11 | |= taz=wall
12 | ^- wall
13 | ?~ taz ["~"]~
14 | :- (weld ":~ " i.taz)
15 | %- snoc :_ "=="
16 | (turn t.taz |=(t=tape (weld " " t)))
17 | ::
18 | ++ spit-duz
19 | |= duz=(list dude:gall)
20 | ^- wall
21 | (turn duz |=(=dude:gall ['%' (trip dude)]))
22 | --
23 | ++ txt (to-wain:format hoon)
24 | --
25 | ++ grab
26 | |%
27 | ++ noun (list dude:gall)
28 | ++ mime
29 | |= [=mite len=@ud tex=@]
30 | ~_ tex
31 | !<((list dude:gall) (slap !>(~) (ream tex)))
32 | --
33 | ++ grad %noun
34 | --
35 |
--------------------------------------------------------------------------------
/tanote/sur/settings.hoon:
--------------------------------------------------------------------------------
1 | /+ *mip
2 | |%
3 | ::
4 | ++ settings-0
5 | =< settings
6 | |%
7 | +$ settings (map key bucket)
8 | +$ bucket (map key val)
9 | +$ val
10 | $% [%s p=@t]
11 | [%b p=?]
12 | [%n p=@]
13 | ==
14 | --
15 | ::
16 | ++ settings-1
17 | =< settings
18 | |%
19 | +$ settings (map key bucket)
20 | --
21 | +$ bucket (map key val)
22 | +$ key term
23 | +$ val
24 | $~ [%n 0]
25 | $% [%s p=@t]
26 | [%b p=?]
27 | [%n p=@]
28 | [%a p=(list val)]
29 | ==
30 | ::
31 | +$ settings (mip desk key bucket)
32 | +$ event
33 | $% [%put-bucket =desk =key =bucket]
34 | [%del-bucket =desk =key]
35 | [%put-entry =desk buc=key =key =val]
36 | [%del-entry =desk buc=key =key]
37 | ==
38 | +$ data
39 | $% [%all =settings]
40 | [%bucket =bucket]
41 | [%desk desk=(map key bucket)]
42 | [%entry =val]
43 | ==
44 | --
45 |
--------------------------------------------------------------------------------
/~hanfel-dovned 2021.md:
--------------------------------------------------------------------------------
1 | [[~hanfel-dovned]]. [[2021-05-26]]. Userspace apprenticeship: Collaborative text editor and annotator. Urbit: Grants. https://urbit.org/grants/ua-collaborative-text-editor
2 |
3 | [[apprenticeship]] [[urbit app]] [[arvo]] [[~timluc-miptev]]
4 |
5 | ## Summary
6 |
7 | A line-based editor for looking at text and code. Can be organized by projects. Allows multiple people to edit, but can use locking for now.
8 |
9 | Could store edits as diffs. Graph-store is probably fine for this, but a native storage format could work as well and would be good to think through tradeoffs. Interesting extensions would be things like line annotations.
10 |
11 | This project is a good introduction to social apps in Urbit, and could become the framework for a larger product if the apprenticeship prototype works.
12 |
13 | ## User stories
14 |
15 | As a user I can:
16 |
17 | - create projects
18 | - create text files within those projects
19 | - invite other users to my project, with varying permissions
--------------------------------------------------------------------------------
/tanote/lib/skeleton.hoon:
--------------------------------------------------------------------------------
1 | :: Similar to default-agent except crashes everywhere
2 | ^- agent:gall
3 | |_ bowl:gall
4 | ++ on-init
5 | ^- (quip card:agent:gall agent:gall)
6 | !!
7 | ::
8 | ++ on-save
9 | ^- vase
10 | !!
11 | ::
12 | ++ on-load
13 | |~ old-state=vase
14 | ^- (quip card:agent:gall agent:gall)
15 | !!
16 | ::
17 | ++ on-poke
18 | |~ in-poke-data=cage
19 | ^- (quip card:agent:gall agent:gall)
20 | !!
21 | ::
22 | ++ on-watch
23 | |~ path
24 | ^- (quip card:agent:gall agent:gall)
25 | !!
26 | ::
27 | ++ on-leave
28 | |~ path
29 | ^- (quip card:agent:gall agent:gall)
30 | !!
31 | ::
32 | ++ on-peek
33 | |~ path
34 | ^- (unit (unit cage))
35 | !!
36 | ::
37 | ++ on-agent
38 | |~ [wire sign:agent:gall]
39 | ^- (quip card:agent:gall agent:gall)
40 | !!
41 | ::
42 | ++ on-arvo
43 | |~ [wire =sign-arvo]
44 | ^- (quip card:agent:gall agent:gall)
45 | !!
46 | ::
47 | ++ on-fail
48 | |~ [term tang]
49 | ^- (quip card:agent:gall agent:gall)
50 | !!
51 | --
52 |
--------------------------------------------------------------------------------
/Aide:
--------------------------------------------------------------------------------
1 | .
2 | .git/info/exclude
3 | Edit ,|sort|uniq
4 | New urbit.aide
5 | cp -rx /n/local/home/jdc/urbit/zod/tanote tanote
6 | cp -rx tanote/* /n/local/home/jdc/urbit/zod/tanote
7 | cp /n/local/home/jdc/urbit/zod/tanote/desk.docket-0 .
8 | cp tanote/desk.docket-0 /n/local/home/jdc/urbit/zod/tanote
9 | cp tanote/desk.ship /n/local/home/jdc/urbit/zod/tanote
10 | cp tanote/sys.kelvin /n/local/home/jdc/urbit/zod/tanote
11 | git add --all .
12 | git checkout 'create tanote desk files.md'
13 | git commit -a -m 'Add icon designed in Drawshield. Split progress into back-end and front-end. Update members of tah-noh-tay. Add front struct, to store filters and a filtered store. List regards in a store. Filter store front by regards or user tags. Filter a store by tags.'
14 | git diff --staged >commit.diff
15 | git diff >commit.diff
16 | git grep -n '^++ '
17 | git grep -n wut
18 | git push origin main
19 | git status --branch --short
20 | host which urbit
21 | mv ../tanote*.md .
22 | rm -rf /n/local/home/jdc/urbit/zod/tanote/*
23 | https://i.imgur.com/S7PHgtX.png
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Jason Catena
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tanote/lib/bip39.hoon:
--------------------------------------------------------------------------------
1 | :: bip39 implementation in hoon
2 | ::
3 | /+ bip39-english
4 | ::
5 | |%
6 | ++ from-entropy
7 | |= byts
8 | ^- tape
9 | =. wid (mul wid 8)
10 | ~| [%unsupported-entropy-bit-length wid]
11 | ?> &((gte wid 128) (lte wid 256))
12 | ::
13 | =+ cs=(div wid 32)
14 | =/ check=@
15 | %+ rsh [0 (sub 256 cs)]
16 | (sha-256l:sha (div wid 8) dat)
17 | =/ bits=byts
18 | :- (add wid cs)
19 | %+ can 0
20 | :~ cs^check
21 | wid^dat
22 | ==
23 | ::
24 | =/ pieces
25 | |- ^- (list @)
26 | :- (end [0 11] dat.bits)
27 | ?: (lte wid.bits 11) ~
28 | $(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)])
29 | ::
30 | =/ words=(list tape)
31 | %+ turn pieces
32 | |= ind=@ud
33 | (snag ind `(list tape)`bip39-english)
34 | ::
35 | %+ roll (flop words)
36 | |= [nex=tape all=tape]
37 | ?~ all nex
38 | :(weld all " " nex)
39 | ::
40 | ::NOTE always produces a 512-bit result
41 | ++ to-seed
42 | |= [mnem=tape pass=tape]
43 | ^- @
44 | %- hmac-sha512t:pbkdf:crypto
45 | [(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64]
46 | --
47 |
--------------------------------------------------------------------------------
/tanote/mar/json/rpc/response.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | /- *json-rpc
3 | ::
4 | |_ res=response
5 | ::
6 | ++ grad %noun
7 | ++ grow
8 | |%
9 | ++ noun res
10 | --
11 | ++ grab :: convert from
12 | |%
13 | ++ noun response :: from noun
14 | ++ httr :: from httr
15 | |= hit=httr:eyre
16 | ^- response
17 | ~| hit
18 | ?: ?=(%2 (div p.hit 100))
19 | =, html
20 | %- json
21 | ?~ r.hit
22 | a+~
23 | (need (de-json q:u.r.hit))
24 | fail+hit
25 | ++ json :: from json
26 | =, dejs-soft:format
27 | |= a=json
28 | ^- response
29 | =; dere
30 | =+ res=((ar dere) a)
31 | ?~ res (need (dere a))
32 | [%batch u.res]
33 | |= a=json
34 | ^- (unit response)
35 | =/ res=(unit [@t json])
36 | ::TODO breaks when no id present
37 | ((ot id+so result+some ~) a)
38 | ?^ res `[%result u.res]
39 | ~| a
40 | :+ ~ %error %- need
41 | ((ot id+so error+(ot code+no message+so ~) ~) a)
42 | --
43 | --
44 |
--------------------------------------------------------------------------------
/%pony.md:
--------------------------------------------------------------------------------
1 | [[~normul-postem]]: [[~sarlev-sarsen]], I'm still happy to work on [[%pony]]! But I still need a more experienced [[Hoon]] dev.
2 |
3 | [[~hatryx-lastud]]: [[%pony]] sounds possibly cool though my feedback would be that email is arguably the least broken and crappy thing in all of normie computing today, so I wonder about the utility of an [[urbit app]] that competes with [[email]].
4 |
5 | [[~ponhec-picwen]]: [[~hatryx-lastud]], but email is centralised, and no-one routes email from host to host with [[sendmail]] anymore in a [[distributed network]], because it takes the resources of a [[Google]] to catch [[spam]], because [[identity]] is free on the [[internet]].
6 |
7 | [[~sarlev-sarsen]]: I’d make the case (as the one pushing this as something we need on Urbit) that the unbroken nature of e-mail as being on of the things most needed to be cloned over to Urbit. Threaded conversations which can add and remove participants during any part of the conversation by any participant and the ability to manage multiple conversations with the same person or set of people is tremendously useful.
8 |
9 | [[~ponhec-picwen]]: I plan something like this in %tanote: every time each note changes it creates a new version, which may be sent to a different group of people.
10 |
11 |
--------------------------------------------------------------------------------
/tanote/mar/sole/action.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/action/sole/mar
3 | ::
4 | /? 310
5 | /- sole
6 | ::
7 | ::::
8 | ::
9 | =, sole
10 | |_ sole-action
11 | ::
12 | ++ grad %noun
13 | ++ grow
14 | |%
15 | ++ noun +<.grad
16 | --
17 | ++ grab :: convert from
18 | |%
19 | ++ json
20 | |= jon=^json ^- sole-action
21 | %- need %. jon
22 | => [dejs-soft:format ..sole-action]
23 | |^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~)
24 | ++ fo
25 | |* [a=term b=fist]
26 | |=(c=json ?.(=([%s a] c) (b c) (some [a ~])))
27 | ::
28 | ++ ra
29 | |* [a=[term fist] b=fist]
30 | |= c=json %. c
31 | ?.(=(%a -.c) b (pe -.a (ar +.a)))
32 | ::
33 | ++ ke :: callbacks
34 | |* [gar=* sef=(trap fist)]
35 | |= jon=json ^- (unit _gar)
36 | =- ~! gar ~! (need -) -
37 | ((sef) jon)
38 | ::
39 | ++ change (ot ler+(at ni ni ~) ted+(pe 0v0 edit) ~)
40 | ++ char (cu taft so)
41 | ++ edit
42 | %+ ke *sole-edit |. ~+
43 | %+ fo %nop
44 | %+ ra mor+edit
45 | (of del+ni set+(cu tuba sa) ins+(ot at+ni cha+char ~) ~)
46 | --
47 | ::
48 | ++ noun sole-action :: clam from %noun
49 | --
50 | --
51 |
--------------------------------------------------------------------------------
/tanote/lib/language-server/build.hoon:
--------------------------------------------------------------------------------
1 | /- *language-server
2 | ::
3 | |%
4 | ++ parse-error
5 | |= =tape
6 | ^- (unit [=path =range])
7 | =/ parse-pair
8 | %+ cook
9 | |=([row=@ud col=@ud] [(dec row) col])
10 | (ifix [sel ser] ;~((glue ace) dem dem))
11 | =/ parse-path
12 | %+ cook
13 | |=(p=path (slag 3 p))
14 | (ifix [fas (jest '::')] (more fas urs:ab))
15 | =/ parse-full
16 | ;~(plug parse-path ;~(sfix ;~((glue dot) parse-pair parse-pair) gar))
17 | (rust tape parse-full)
18 | ::
19 | ++ get-errors-from-tang
20 | |= [uri=@t =tang]
21 | ^- (list range)
22 | =/ =path
23 | (uri-to-path uri)
24 | %+ murn tang
25 | |= =tank
26 | ^- (unit range)
27 | ?. ?=([%leaf *] tank)
28 | ~
29 | =/ error
30 | (parse-error p.tank)
31 | ?~ error
32 | ~
33 | ?: =(path path.u.error)
34 | `range.u.error
35 | ~
36 | ::
37 | ++ uri-to-path
38 | |= uri=@t
39 | ^- path
40 | =/ pier-root=(set cord)
41 | %- sy
42 | ['app' 'gen' 'lib' 'mar' 'ren' 'sur' 'sys' 'test' ~]
43 | =/ path=(list cord)
44 | (parse-uri uri)
45 | |-
46 | ?< ?=(~ path)
47 | ?: (~(has in pier-root) i.path)
48 | `^path`path
49 | $(path t.path)
50 | ::
51 | ++ parse-uri
52 | |= uri=@t
53 | =- (fall - /fail)
54 | %+ rush uri
55 | %+ more
56 | ;~(pose (plus fas) dot)
57 | %+ cook
58 | crip
59 | (star ;~(pose col hep alf))
60 | ::
61 | --
62 |
--------------------------------------------------------------------------------
/tanote/lib/mip.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | ++ mip :: map of maps
3 | |$ [kex key value]
4 | (map kex (map key value))
5 | ::
6 | ++ bi :: mip engine
7 | =| a=(map * (map))
8 | |@
9 | ++ del
10 | |* [b=* c=*]
11 | =+ d=(~(gut by a) b ~)
12 | =+ e=(~(del by d) c)
13 | ?~ e
14 | (~(del by a) b)
15 | (~(put by a) b e)
16 | ::
17 | ++ get
18 | |* [b=* c=*]
19 | => .(b `_?>(?=(^ a) p.n.a)`b, c `_?>(?=(^ a) ?>(?=(^ q.n.a) p.n.q.n.a))`c)
20 | ^- (unit _?>(?=(^ a) ?>(?=(^ q.n.a) q.n.q.n.a)))
21 | (~(get by (~(gut by a) b ~)) c)
22 | ::
23 | ++ got
24 | |* [b=* c=*]
25 | (need (get b c))
26 | ::
27 | ++ gut
28 | |* [b=* c=* d=*]
29 | (~(gut by (~(gut by a) b ~)) c d)
30 | ::
31 | ++ has
32 | |* [b=* c=*]
33 | !=(~ (get b c))
34 | ::
35 | ++ key
36 | |* b=*
37 | ~(key by (~(gut by a) b ~))
38 | ::
39 | ++ put
40 | |* [b=* c=* d=*]
41 | %+ ~(put by a) b
42 | %. [c d]
43 | %~ put by
44 | (~(gut by a) b ~)
45 | ::
46 | ++ tap
47 | ::NOTE naive turn-based implementation find-errors ):
48 | =< $
49 | =+ b=`_?>(?=(^ a) *(list [x=_p.n.a _?>(?=(^ q.n.a) [y=p v=q]:n.q.n.a)]))`~
50 | |. ^+ b
51 | ?~ a
52 | b
53 | $(a r.a, b (welp (turn ~(tap by q.n.a) (lead p.n.a)) $(a l.a)))
54 | --
55 | --
56 |
--------------------------------------------------------------------------------
/create desk files.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] [[tanote/tanote]]
2 |
3 | https://dev.tlon.io/
4 |
5 | ## create desk files
6 |
7 | The optional `desk.ship` file specifies the original publisher of this desk. Since we merged this from `%garden` it's currently set to `~mister-dister-dozzod-dozzod`. Let's change this to our fake ship `~zod`. In practice you'll set this to the ID you want to be seen as the publisher (likely your own Urbit ID). Currently there is no verification that makes sure publishers are honest about this, but eventually there will be.
8 |
9 | ```bash
10 | echo "~ponhec-picwen" > tanote/desk.ship
11 | ```
12 |
13 | The final file we need to edit is `desk.docket-0`. #now
14 |
15 | ```hoon
16 | :~ title+'Tanote'
17 | info+'factional note manager'
18 | color+0x81.88c9
19 | version+[0 0 1]
20 | website+'https://github.com/catenate/tanote'
21 | license+'MIT'
22 | base+'tanote'
23 | glob-ames+[~zod 0v0]
24 | image+'https://media.urbit.org/docs/userspace/dist/wut.svg'
25 | ==
26 | ```
27 |
28 | Commit and install our changes.
29 |
30 | ```bash
31 | |commit %tanote
32 | |install our %tanote
33 | ```
34 |
35 | Open a browser and navigate to [localhost:80](http://localhost:80) . To get the login code ([[access key]]), enter `+code` into the [[dojo]] prompt for your ship. For [[fake ~zod]]s, the code is always `lidlut-tabwed-pillex-ridrup`. You'll see our tile, but it says installing with a spinner due to the missing glob.
36 |
37 |
--------------------------------------------------------------------------------
/Funes the memorious.md:
--------------------------------------------------------------------------------
1 | _ut nihil non iisdem verbis redderetur auditurn_: that nothing should be rendered without the same words (Google translate)
2 |
3 | "I have more memories in myself alone than all men have had since the world was a world."
4 |
5 | "My dreams are like your vigils."
6 |
7 | "My memory, sir, is like a garbage disposal."
8 |
9 | The truth is that we all live by leaving behind; no doubt we all profoundly know that we are immortal and that sooner or later every man will do all things and know everything.
10 |
11 | He had not written it down, for what he once meditated would not be erased.
12 |
13 | The two projects I have indicated (an infinite vocabulary for the natural series of numbers, and a usable mental catalogue of all the images of memory) are lacking in sense, but they reveal a certain stammering greatness. They allow us to make out dimly, or to infer, the dizzying world of Funes. He was, let us not forget, almost incapable of general, platonic ideas.
14 |
15 | Funes could continuously make out the tranquil advances of corruption, of caries, of fatigue. He noted the progress of death, of moisture. He was the solitary and lucid spectator of a multiform world which was instantaneously and almost intolerably exact.
16 |
17 | I suspect, nevertheless, that he was not very capable of thought. To think is to forget a difference, to generalize, to abstract. In the overly replete world of Funes there were nothing but details, almost contiguous details.
18 |
19 |
--------------------------------------------------------------------------------
/tanote/lib/test.hoon:
--------------------------------------------------------------------------------
1 | :: testing utilities meant to be directly used from files in %/tests
2 | ::
3 | |%
4 | :: +expect-eq: compares :expected and :actual and pretty-prints the result
5 | ::
6 | ++ expect-eq
7 | |= [expected=vase actual=vase]
8 | ^- tang
9 | ::
10 | =| result=tang
11 | ::
12 | =? result !=(q.expected q.actual)
13 | %+ weld result
14 | ^- tang
15 | :~ [%palm [": " ~ ~ ~] [leaf+"expected" (sell expected) ~]]
16 | [%palm [": " ~ ~ ~] [leaf+"actual " (sell actual) ~]]
17 | ==
18 | ::
19 | =? result !(~(nest ut p.actual) | p.expected)
20 | %+ weld result
21 | ^- tang
22 | :~ :+ %palm [": " ~ ~ ~]
23 | :~ [%leaf "failed to nest"]
24 | (~(dunk ut p.actual) %actual)
25 | (~(dunk ut p.expected) %expected)
26 | == ==
27 | result
28 | :: +expect: compares :actual to %.y and pretty-prints anything else
29 | ::
30 | ++ expect
31 | |= actual=vase
32 | (expect-eq !>(%.y) actual)
33 | :: +expect-fail: kicks a trap, expecting crash. pretty-prints if succeeds
34 | ::
35 | ++ expect-fail
36 | |= a=(trap)
37 | ^- tang
38 | =/ b (mule a)
39 | ?- -.b
40 | %| ~
41 | %& [leaf+"expected failure - succeeded" ~]
42 | ==
43 | :: +category: prepends a name to an error result; passes successes unchanged
44 | ::
45 | ++ category
46 | |= [a=tape b=tang] ^- tang
47 | ?: =(~ b) ~ :: test OK
48 | :- leaf+"in: '{a}'"
49 | (turn b |=(c=tank rose+[~ " " ~]^~[c]))
50 | --
51 |
--------------------------------------------------------------------------------
/proposal meta.md:
--------------------------------------------------------------------------------
1 | [[~sarlev-sarsen]]: Some reason I can’t join this group, but if you are interested in making this a serious project, submit it at [https://Urbit.org/grants/proposals](https://urbit.org/grants/proposals) and we can see about getting some address space into your hands if you succeed in building something useful.
2 |
3 | [[Jason Catena]]
4 | [[~ponhec-picwen]]
5 | [catenaten@gmail.com](mailto:catenaten@gmail.com)
6 |
7 | Tanote, a factious note store
8 | web+urbitgraph://group/~ponhec-picwen/tah-noh-tay
9 | just me :)
10 |
11 | ---
12 |
13 | Good proposals all include the following:
14 |
15 | - A **detailed and clear description of the proposal**. If you're proposing something technical, user stories are a good idea.
16 | - An overview of **why you are the right person for the job**. A description of your background, familiarity with the project, and professional/education experience are all good starts.
17 | - Your estimate for **date of completion**.
18 | - The **amount of funding** you'd like for the project, denominated in stars.
19 | - What **specific deliverables** will look like.
20 |
21 | It's recommended to break your project into _milestones_, each of which must have its own completion dates, funding amounts and deliverables. In general, proposals should target a first deliverable within two months of the start of the project. Proposals should have a maximum of five milestones as scoping a project beyond that is impractical, and each milestone should constitute significant enough work to warrant the reward of a full star.
--------------------------------------------------------------------------------
/tanote/mar/blit.hoon:
--------------------------------------------------------------------------------
1 | :: blit: runtime blit structure
2 | ::
3 | |_ =blit:dill
4 | ++ grad %noun
5 | :: +grab: convert from
6 | ::
7 | ++ grab
8 | |%
9 | ++ noun blit:dill
10 | --
11 | :: +grow: convert to
12 | ::
13 | ++ grow
14 | |%
15 | ++ noun blit
16 | ++ json
17 | ^- ^json
18 | =, enjs:format
19 | %+ frond -.blit
20 | ?- -.blit
21 | %bel b+&
22 | %clr b+&
23 | %hop (numb p.blit)
24 | %lin a+(turn p.blit |=(c=@c s+(tuft c)))
25 | %mor b+&
26 | %url s+p.blit
27 | ::
28 | %sag
29 | %- pairs
30 | :~ 'path'^(path p.blit)
31 | 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit)))
32 | ==
33 | ::
34 | %sav
35 | %- pairs
36 | :~ 'path'^(path p.blit)
37 | 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit))
38 | ==
39 | ::
40 | %klr
41 | :- %a
42 | %+ turn p.blit
43 | |= [=stye text=(list @c)]
44 | %- pairs
45 | :~ 'text'^a+(turn text |=(c=@c s+(tuft c)))
46 | ::
47 | :- 'stye'
48 | %- pairs
49 | |^ :~ 'back'^(color p.q.stye)
50 | 'fore'^(color q.q.stye)
51 | 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d)))
52 | ==
53 | ++ color
54 | |= =tint
55 | ?@ tint ?~(tint ~ s+tint)
56 | s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint)))
57 | --
58 | ==
59 | ==
60 | --
61 | --
62 |
--------------------------------------------------------------------------------
/tanote/lib/default-agent.hoon:
--------------------------------------------------------------------------------
1 | /+ skeleton
2 | |* [agent=* help=*]
3 | ?: ?=(%& help)
4 | ~| %default-agent-helpfully-crashing
5 | skeleton
6 | |_ =bowl:gall
7 | ++ on-init
8 | `agent
9 | ::
10 | ++ on-save
11 | !>(~)
12 | ::
13 | ++ on-load
14 | |= old-state=vase
15 | `agent
16 | ::
17 | ++ on-poke
18 | |= =cage
19 | ~| "unexpected poke to {} with mark {}"
20 | !!
21 | ::
22 | ++ on-watch
23 | |= =path
24 | ~| "unexpected subscription to {} on path {}"
25 | !!
26 | ::
27 | ++ on-leave
28 | |= path
29 | `agent
30 | ::
31 | ++ on-peek
32 | |= =path
33 | ~| "unexpected scry into {} on path {}"
34 | !!
35 | ::
36 | ++ on-agent
37 | |= [=wire =sign:agent:gall]
38 | ^- (quip card:agent:gall _agent)
39 | ?- -.sign
40 | %poke-ack
41 | ?~ p.sign
42 | `agent
43 | %- (slog leaf+"poke failed from {} on wire {}" u.p.sign)
44 | `agent
45 | ::
46 | %watch-ack
47 | ?~ p.sign
48 | `agent
49 | =/ =tank leaf+"subscribe failed from {} on wire {}"
50 | %- (slog tank u.p.sign)
51 | `agent
52 | ::
53 | %kick `agent
54 | %fact
55 | ~| "unexpected subscription update to {} on wire {}"
56 | ~| "with mark {}"
57 | !!
58 | ==
59 | ::
60 | ++ on-arvo
61 | |= [=wire =sign-arvo]
62 | ~| "unexpected system response {<-.sign-arvo>} to {} on wire {}"
63 | !!
64 | ::
65 | ++ on-fail
66 | |= [=term =tang]
67 | %- (slog leaf+"error in {}" >term< tang)
68 | `agent
69 | --
70 |
--------------------------------------------------------------------------------
/tah-noh-tay members.md:
--------------------------------------------------------------------------------
1 | ~libbyl-lonsyd
2 | Role
3 | Member
4 |
5 | calibri
6 | ~normul-postem
7 | Role
8 | Member
9 | ~nocsyx-lassul ⚗️
10 | ~nocsyx-lassul
11 | Role
12 | Member
13 | ~silnem
14 | Role
15 | Member
16 |
17 | a tonned fampet
18 | ~tonned-fampet
19 | Role
20 | Member
21 |
22 | ~niblyx-the-zaptist
23 | ~niblyx-malnus
24 | Role
25 | Member
26 | ~ponhec-picwen
27 | Role
28 | Admin
29 | Kate Bush Experimenting with Orgone Rabsef
30 | ~rabsef-bicrym
31 | Role
32 | Member
33 |
34 | ~am
35 | ~haddef-sigwen
36 | Role
37 | Member
38 | ~bilnut-holdem
39 | ~bilnut-holdem
40 | Role
41 | Member
42 | ~hodreb-racdem
43 | Role
44 | Member
45 | ~sogrum-savluc, webmaster
46 | ~sogrum-savluc
47 | Role
48 | Member
49 | ~lorfeb-taglut
50 | Role
51 | Member
52 | ~hosted-fornet
53 | Role
54 | Member
55 |
56 | ~sarlev-sarsen
57 | Role
58 | Member
59 | ~lomseg-laclut 🍝
60 | ~lomseg-laclut
61 | Role
62 | Member
63 | Vitalii Bulychov
64 | ~hardem
65 | Role
66 | Member
67 |
68 | ~norsyr-torryn
69 | Role
70 | Member
71 | ~midden-fabler
72 | Role
73 | Member
74 | ~siplyn-difmev
75 | Role
76 | Member
77 |
78 | ~wicrum-wicrun
79 | Role
80 | Member
81 | ixv
82 | ~novlud-padtyv
83 | Role
84 | Member
85 | ~taller-ravnut�
86 | ~lomseg-laclut
87 | Role
88 | Member
89 | Vitalii Bulychov
90 | ~hardem
91 | Role
92 | Member
93 |
94 | ~norsyr-torryn
95 | Role
96 | Member
97 | ~midden-fabler
98 | Role
99 | Member
100 | ~siplyn-difmev
101 | Role
102 | Member
103 |
104 | ~wicrum-wicrun
105 | Role
106 | Member
107 | ixv
108 | ~novlud-padtyv
109 | Role
110 | Member
111 | ~taller-ravnut
112 |
--------------------------------------------------------------------------------
/~pocwet journal.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] [[~pocwet]] [[journal]]
2 |
3 | ---
4 |
5 | https://urbit.org/docs/hoon/hoon-school/intro
6 |
7 | This series is designed to teach you Hoon without assuming you have an extensive programming background. In fact, you should be able to follow much of it even if you have no programming experience at all, though of course experience helps. We strongly encourage you to try out all the examples of each lesson. These lessons are meant for the beginner, but they aren't meant to be skimmed. Each lesson falls into one of two categories: **readings**, which are prose-heavy explanations of Hoon fundamentals, and **walkthroughs**, which are line-by-line explanations of example programs. Walkthroughs are found between readings, offering a practical implementation of the concepts taught in the reading before.
8 |
9 | ---
10 |
11 | https://urbit.org/docs/userspace/gall-guide/intro
12 |
13 | This guide will walk through everything you need to know to write your own Gall agents. The Gall Guide is suitable for anyone with an intermediate knowledge of Hoon. If you've worked through [Hoon School](https://urbit.org/docs/hoon/hoon-school/intro) or something equivalent, you should be fine.
14 |
15 | ---
16 |
17 | https://urbit.org/docs/userspace/full-stack/1-intro
18 |
19 | This series walks through the writing of a full Gall agent, and then the process of integrating it with a React front-end. This series follows on from the previous [Gall Guide](https://urbit.org/docs/userspace/gall-guide/intro). If you haven't completed that, or otherwise aren't familiar with the basics of writing Gall agents, it's strongly recommended to work through that guide first.
20 |
21 |
--------------------------------------------------------------------------------
/publish.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] [[tanote/tanote]]
2 |
3 | https://dev.tlon.io/
4 |
5 | ## Publish
6 |
7 | The final step is publishing our desk with the `%treaty` agent so others can install it. To do this, there's a simple command in the dojo.
8 |
9 | ```bash
10 | :treaty|publish %tanote
11 | ```
12 |
13 | > **Note**: For desks without a docket file (and therefore without a tile and glob), treaty can't be used. Instead you can make the desk public with `|public %desk-name`.
14 |
15 | > **Note**: Desks aren't publicly readable by default, `:treaty|publish` publishes the metadata and also makes the desk publicly readable, like `|public`.
16 |
17 | ## Remote install
18 |
19 | Let's spin up another fake ship so we can try to install our newly published app.
20 |
21 | ```bash
22 | cd ~/urbit
23 | ./urbit bus
24 | ```
25 |
26 | > **Note**: For desks without a docket file (and therefore without a tile and glob), users cannot install them through the web interface. Instead remote users can install it from the dojo with `|install ~our-ship %desk-name`.
27 |
28 | In the browser, navigate to [http://localhost:8081](http://localhost:8081/) and login with [[fake ~bus]]'s code which can be found by running `+code` in the dojo for `bus`. In this case, the default is `riddec-bicrym-ridlev-pocsef`. Next, type `~zod/` in the search bar, and it should pop up a list of `~zod`'s published apps, which in this case is our `Tanote` app.
29 |
30 | When we click on the app, it'll show some of the information from the clauses in the docket file. Click `Get App`. It'll ask as if we want to install it. Finally, click `Get "Tanote"`. It'll be installed as a tile on `~bus` which can then be opened.
31 |
32 |
--------------------------------------------------------------------------------
/tanote/lib/language-server/parser.hoon:
--------------------------------------------------------------------------------
1 | :: lifted directly from ford, should probably be in zuse
2 | =, clay
3 | =< pile-rule
4 | |%
5 | ++ pile-rule
6 | |= pax=path
7 | %- full
8 | %+ ifix
9 | :_ gay
10 | :: parse optional /? and ignore
11 | ::
12 | ;~(plug gay (punt ;~(plug fas wut gap dem gap)))
13 | |^
14 | ;~ plug
15 | %+ cook (bake zing (list (list taut)))
16 | %+ rune hep
17 | (most ;~(plug com gaw) taut-rule)
18 | ::
19 | %+ cook (bake zing (list (list taut)))
20 | %+ rune lus
21 | (most ;~(plug com gaw) taut-rule)
22 | ::
23 | %+ rune tis
24 | ;~(plug sym ;~(pfix gap stap))
25 | ::
26 | %+ rune sig
27 | ;~((glue gap) sym wyde:vast stap)
28 | ::
29 | %+ rune cen
30 | ;~(plug sym ;~(pfix gap ;~(pfix cen sym)))
31 | ::
32 | %+ rune buc
33 | ;~ (glue gap)
34 | sym
35 | ;~(pfix cen sym)
36 | ;~(pfix cen sym)
37 | ==
38 | ::
39 | %+ rune tar
40 | ;~ (glue gap)
41 | sym
42 | ;~(pfix cen sym)
43 | stap
44 | ==
45 | ::
46 | %+ stag %tssg
47 | (most gap tall:(vang & pax))
48 | ==
49 | ::
50 | ++ pant
51 | |* fel=^rule
52 | ;~(pose fel (easy ~))
53 | ::
54 | ++ mast
55 | |* [bus=^rule fel=^rule]
56 | ;~(sfix (more bus fel) bus)
57 | ::
58 | ++ rune
59 | |* [bus=^rule fel=^rule]
60 | %- pant
61 | %+ mast gap
62 | ;~(pfix fas bus gap fel)
63 | --
64 | ::
65 | ++ taut-rule
66 | %+ cook |=(taut +<)
67 | ;~ pose
68 | (stag ~ ;~(pfix tar sym))
69 | ;~(plug (stag ~ sym) ;~(pfix tis sym))
70 | (cook |=(a=term [`a a]) sym)
71 | ==
72 | --
73 |
--------------------------------------------------------------------------------
/tanote/sur/ring.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | :: +raw-ring-signature: low level ring signature type
3 | ::
4 | :: The :s field of a ring signature grows O(n) with the number of
5 | :: participants in the ring.
6 | ::
7 | ++ raw-ring-signature
8 | $: ch0=@
9 | ::
10 | s=(list @)
11 | :: linked ring signature tag
12 | ::
13 | :: Two linked ring signatures with the same link scope can be shown to
14 | :: have been made by the same private key, leading to Sybil
15 | :: resistance...but if your private keys are compromised, your
16 | :: adversary can determine which signatures you made.
17 | ::
18 | y=(unit @udpoint)
19 | ==
20 | :: +ring-signature: higher level ring signature type
21 | ::
22 | :: This contains all the identifying information to verify a ring signature
23 | :: in an urbit context.
24 | ::
25 | ++ ring-signature
26 | $: :: a ring signature is computed over a set of public keys. the
27 | :: participants set is not those keys, but static references to them.
28 | ::
29 | participants=(set [ship=@p =life])
30 | :: the linkage scope this signature was made on
31 | ::
32 | link-scope=(unit *)
33 | :: the rest of the low level ring signature is appended
34 | ::
35 | raw=raw-ring-signature
36 | ==
37 | ::
38 | +$ ring-group
39 | $: :: a ring signature is computed over a set of public keys. the
40 | :: participants set is not those keys, but static references to them.
41 | ::
42 | participants=(set [ship=@p =life])
43 | :: the linkage scope this signature was made on
44 | ::
45 | link-scope=(unit *)
46 | ==
47 | --
48 |
--------------------------------------------------------------------------------
/session Gettysburg.md:
--------------------------------------------------------------------------------
1 | [[tanote/tanote]]
2 | [[session init]]
3 |
4 | ---
5 |
6 | Receive a version of this text, with regards to a new note name.
7 |
8 | > by ~abeham-lincon as president
9 | > to ~ponhec-picwen
10 | > re draft from train
11 | >
12 | > #Gettysburg address
13 | >
14 | > Four score and seven years ago…
15 |
16 | Automatically update tags, @ps, and regards.
17 |
18 | > ==`*`== ==~abeham-lincon== ==~hatryx-lastud== ==~paldev== ==_~ponhec-picwen_== ==Gettysburg==
19 | >
20 | > ==draft from train==.
21 | >
22 | > by ~ponhec-picwen as |
23 | > ==to== |
24 | > re |
25 | > ==no== ~~1~~ of 1
26 | >
27 | > |
28 |
29 | Select it via its tag. This filters out other notes without the tag, and displays the set of matching notes. This blanks the text because we haven't yet selected a specific node
30 |
31 | > ==`*`== ==~abeham-lincon== ==~hatryx-lastud== ==~paldev== ==~ponhec-picwen== ==**Gettysburg**==
32 | >
33 | > ==draft from train==.
34 | >
35 | >
36 |
37 | Selecting a notes' regards displays it.
38 |
39 | > ==`*`== ==_~abeham-lincon_== ==~hatryx-lastud== ==~paldev== ==_~ponhec-picwen_== ==**Gettysburg**==
40 | >
41 | > ==**draft from train**==.
42 | >
43 | > by ~abeham-lincon as ~~president~~
44 | > ==to== ~~~ponhec-picwen~~
45 | > re ~~draft from train~~
46 | > ==no== ~~1~~ of 1
47 | >
48 | > ~~#Gettysburg address
49 | >
50 | > Four score and seven years ago…~~
51 |
52 | The list of recipients, the regards, the version, and the text are editable, but this changed version is only buffered and may be lost, until the user clicks ==to== (add version, and send to recipients) or ==no== (add version), at which point a new version (of possibly a different note, if the regards changed) is added.
53 |
54 |
--------------------------------------------------------------------------------
/tangents.md:
--------------------------------------------------------------------------------
1 | [[~fabled-faster]]. month _circa_ [[2021-10]]. Mass proliferation of writing/[[Roam]]-like apps. [[urbit group]]s: [[Foundation grant]] ideas. web+urbitgraph://group/~wolref-podlex/foundation/graph/~wolref-podlex/grant-ideas/170141184505228879328373638614380183552
2 |
3 | [[Roam]] and [[Notion]] are onto something. It’s important to be able to go beyond writing and into the realm of creating interconnected graphs of nodes that you can share with others across the network. There could be great overlap between writing, ‘groups’ (new landscape) and a knowledge graph or roamlike.
4 |
5 | ...
6 |
7 | ~wicrum-wicrun: Could I later edit the node in the knowledge graph (_eg_ add links to other nodes, or just rephrase it)? Without affecting the original chat message? While still keeping the "forked from"-link to the original chat message (and vice versa)?
8 |
9 | ---
10 |
11 | [[~datryn-ribdun]]: Would be cool to make an easily deployable [[gora]] for new app users. Like "I just made %dongers, and some people have installed it. I want to send all of them gorae to thank them". Easy to do if you have a list, but not sure how you'd get the list automatically. somewhere software distribution must store the [[@p]]s that have installed from the developer's desk, you just have to extract it.
12 |
13 | ---
14 |
15 | [[~noddep-hanwep]]: Is there some nice way of having long discussions on very specific topics on Urbit?
16 |
17 | [[~ravmel-ropdyl]]: We use notebooks for this from time to time, but it's not ideal.
18 |
19 | [[~noddep-hanwep]]: I mean the kind of stuff that belongs in a forum thread rather than a chat
20 |
21 | [[~ravmel-ropdyl]]: Yeah, notebooks are the stand in for this.
22 |
23 | ---
24 |
25 |
--------------------------------------------------------------------------------
/tanote/mar/hoon.hoon:
--------------------------------------------------------------------------------
1 | :::: /hoon/hoon/mar
2 | ::
3 | /? 310
4 | ::
5 | =, eyre
6 | |_ own=@t
7 | ::
8 | ++ grow :: convert to
9 | |%
10 | ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime
11 | ++ elem :: convert to %html
12 | ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}"
13 | :: =+ gen-id="src-{<`@ui`(mug own)>}"
14 | :: ;div
15 | :: ;textarea(id "{gen-id}"):"{(trip own)}"
16 | :: ;script:"""
17 | :: CodeMirror.fromTextArea(
18 | :: window[{}],
19 | :: \{lineNumbers:true, readOnly:true}
20 | :: )
21 | :: """
22 | :: ==
23 | ++ hymn
24 | :: ;html:(head:title:"Source" "+{elem}")
25 | ;html
26 | ;head
27 | ;title:"Source"
28 | ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js";
29 | ;script@"/lib/syntax/hoon.js";
30 | ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/".
31 | "codemirror/4.3.0/codemirror.min.css");
32 | ;link/"/lib/syntax/codemirror.css"(rel "stylesheet");
33 | ==
34 | ;body
35 | ;textarea#src:"{(trip own)}"
36 | ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})'
37 | ==
38 | ==
39 | ++ txt
40 | (to-wain:format own)
41 | --
42 | ++ grab
43 | |% :: convert from
44 | ++ mime |=([p=mite q=octs] q.q)
45 | ++ noun @t :: clam from %noun
46 | ++ txt of-wain:format
47 | --
48 | ++ grad %txt
49 | --
50 |
--------------------------------------------------------------------------------
/tanote/sur/docket.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | ::
3 | +$ version
4 | [major=@ud minor=@ud patch=@ud]
5 | ::
6 | +$ glob (map path mime)
7 | ::
8 | +$ url cord
9 | :: $glob-location: How to retrieve a glob
10 | ::
11 | +$ glob-reference
12 | [hash=@uvH location=glob-location]
13 | ::
14 | +$ glob-location
15 | $% [%http =url]
16 | [%ames =ship]
17 | ==
18 | :: $href: Where a tile links to
19 | ::
20 | +$ href
21 | $% [%glob base=term =glob-reference]
22 | [%site =path]
23 | ==
24 | :: $chad: State of a docket
25 | ::
26 | +$ chad
27 | $~ [%install ~]
28 | $% :: Done
29 | [%glob =glob]
30 | [%site ~]
31 | :: Waiting
32 | [%install ~]
33 | [%suspend glob=(unit glob)]
34 | :: Error
35 | [%hung err=cord]
36 | ==
37 | ::
38 | :: $charge: A realized $docket
39 | ::
40 | +$ charge
41 | $: =docket
42 | =chad
43 | ==
44 | ::
45 | :: $clause: A key and value, as part of a docket
46 | ::
47 | :: Only used to parse $docket
48 | ::
49 | +$ clause
50 | $% [%title title=@t]
51 | [%info info=@t]
52 | [%color color=@ux]
53 | [%glob-http url=cord hash=@uvH]
54 | [%glob-ames =ship hash=@uvH]
55 | [%image =url]
56 | [%site =path]
57 | [%base base=term]
58 | [%version =version]
59 | [%website website=url]
60 | [%license license=cord]
61 | ==
62 | ::
63 | :: $docket: A description of JS bundles for a desk
64 | ::
65 | +$ docket
66 | $: %1
67 | title=@t
68 | info=@t
69 | color=@ux
70 | =href
71 | image=(unit url)
72 | =version
73 | website=url
74 | license=cord
75 | ==
76 | ::
77 | +$ charge-update
78 | $% [%initial initial=(map desk charge)]
79 | [%add-charge =desk =charge]
80 | [%del-charge =desk]
81 | ==
82 | --
83 |
--------------------------------------------------------------------------------
/create and upload glob.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] [[tanote/tanote]]
2 |
3 | ## create files for glob
4 |
5 | We'll now create the files for the glob. We'll use a very simple static HTML page that just displays "Hello World!" and an image. Typically we'd have a more complex JS web app that talked to apps on our ship through the server API, but for the sake of simplicity we'll forgo that. Let's hop back in the Unix terminal.
6 |
7 | ```bash
8 | cd git/tanote
9 | mkdir tanote-glob
10 | cd tanote-glob
11 | mkdir img
12 | curl https://media.urbit.org/docs/userspace/dist/pot.svg --output img/pot.svg
13 | ```
14 |
15 | We've grabbed an image to use in our "Hello world!" page. The next thing we need to add is an `index.html` file in the root of the folder. The `index.html` file is mandatory; it's what will be loaded when the app's tile is clicked.
16 |
17 | ```html
18 |
19 |
20 |
21 | tanote
22 |
27 |
28 |
29 | a community knowledge manager
30 |
31 |
32 |
33 | ```
34 |
35 | ## upload to glob
36 |
37 | We can now create a glob from the directory. To do so, navigate to [docket/upload](http://localhost:80/docket/upload) in the browser. This will bring up the `%docket` app's Globulator tool.
38 |
39 | 1. Simply select the `tanote` desk from the drop-down, click `Choose file` and select the `tanote-glob` folder in the file browser, then hit `glob!`.
40 | 2. Now if we return to our ship's homescreen, we should see the tile looks as we specified in the docket file: `http://localhost:80`
41 | 3. And if we click on the tile, it'll load the `index.html` in our glob.
42 | 4. Our app is working!
43 |
44 |
--------------------------------------------------------------------------------
/tanote/sur/bitcoin.hoon:
--------------------------------------------------------------------------------
1 | :: sur/btc.hoon
2 | :: Utilities for working with BTC data types and transactions
3 | ::
4 | :: chyg: whether account is (non-)change. 0 or 1
5 | :: bytc: "btc-byts" with dat cast to @ux
6 | |%
7 | +$ network ?(%main %testnet)
8 | +$ hexb [wid=@ dat=@ux] :: hex byts
9 | +$ bits [wid=@ dat=@ub]
10 | +$ xpub @ta
11 | +$ address
12 | $% [%base58 @uc]
13 | [%bech32 cord]
14 | ==
15 | +$ fprint hexb
16 | +$ bipt $?(%44 %49 %84)
17 | +$ chyg $?(%0 %1)
18 | +$ idx @ud
19 | +$ hdkey [=fprint pubkey=hexb =network =bipt =chyg =idx]
20 | +$ sats @ud
21 | +$ vbytes @ud
22 | +$ txid hexb
23 | +$ utxo [pos=@ =txid height=@ value=sats recvd=(unit @da)]
24 | ++ address-info
25 | $: =address
26 | confirmed-value=sats
27 | unconfirmed-value=sats
28 | utxos=(set utxo)
29 | ==
30 | ++ tx
31 | |%
32 | +$ data
33 | $: is=(list input)
34 | os=(list output)
35 | locktime=@ud
36 | nversion=@ud
37 | segwit=(unit @ud)
38 | ==
39 | +$ val
40 | $: =txid
41 | pos=@ud
42 | =address
43 | value=sats
44 | ==
45 | :: included: whether tx is in the mempool or blockchain
46 | ::
47 | +$ info
48 | $: included=?
49 | =txid
50 | confs=@ud
51 | recvd=(unit @da)
52 | inputs=(list val)
53 | outputs=(list val)
54 | ==
55 | +$ input
56 | $: =txid
57 | pos=@ud
58 | sequence=hexb
59 | script-sig=(unit hexb)
60 | pubkey=(unit hexb)
61 | value=sats
62 | ==
63 | +$ output
64 | $: script-pubkey=hexb
65 | value=sats
66 | ==
67 | --
68 | ++ psbt
69 | |%
70 | +$ base64 cord
71 | +$ in [=utxo rawtx=hexb =hdkey]
72 | +$ out [=address hk=(unit hdkey)]
73 | +$ target $?(%input %output)
74 | +$ keyval [key=hexb val=hexb]
75 | +$ map (list keyval)
76 | --
77 | ++ ops
78 | |%
79 | ++ op-dup 118
80 | ++ op-equalverify 136
81 | ++ op-hash160 169
82 | ++ op-checksig 172
83 | --
84 | --
85 |
--------------------------------------------------------------------------------
/create desk.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] [[tanote/tanote]]
2 |
3 | https://urbit.org/docs/development/environment
4 |
5 | ### Create a new desk
6 |
7 | To create a new desk, you'll need to merge from an existing one, typically `%base`. In the dojo, run the following (you can change `%mydesk` to your preferred name):
8 |
9 | ```hoon
10 | |merge %tanote our %base
11 | |mount %tanote
12 | ```
13 |
14 | If you now mount it, you'll have `/mydesk` directory in your pier with all the files of the `%base` desk inside. You can then delete the contents, copy in your own files and `|commit` it.
15 |
16 | Desks must contain all the `mark` files, libraries, etc, that they need. A `sys.kelvin` file is mandatory, and there are a few `mark` files necessary as well. In the next couple of sections we'll look at different ways to populate a new desk with the necessary files.
17 |
18 | The desks in [[urbit/pkg]] ending in `-dev`, like `base-dev` and `garden-dev`, contain files for interfacing with those respective desks. If you're creating a new desk that has a tile and front-end, for example, you might like to use `base-dev` and `garden-dev` as a base. To create such a base, there's a `symbolic-merge.sh` script included in the directory. You can use it like so:
19 |
20 | ```shell
21 | ./symbolic-merge.sh base-dev tanote
22 | ./symbolic-merge.sh garden-dev tanote
23 | ```
24 |
25 | Then, you can go into your pier:
26 |
27 | ```shell
28 | cd /home/jdc/urbit/zod
29 | ```
30 |
31 | Delete the contents of `tanote`:
32 |
33 | ```shell
34 | rm -r tanote/*
35 | ```
36 |
37 | And then copy in the contents of the desk you created:
38 |
39 | ```shell
40 | cp -rL ~/obsidian/flake/urbit/pkg/tanote/* tanote
41 | ```
42 |
43 | Note you have to use `cp -rL` rather than just `cp -r` because the `symbolic-merge.sh` script creates symlinks, so the `L` flag is to resolve them and copy the actual files.
44 |
45 | Now you can just add a `sys.kelvin` file:
46 |
47 | ```shell
48 | echo '[%zuse 418]' > tanote/sys.kelvin
49 | ```
50 |
51 | And you'll be able to mount the desk with
52 |
53 | ```hoon
54 | |commit %tanote
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/tanote/lib/cram.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | ++ static :: freeze .mdh hoon subset
3 | |= gen=hoon ^- [inf=(map term dime) elm=manx]
4 | ?+ -.gen
5 | =/ gen ~(open ap gen)
6 | ?: =(gen ^gen) ~|([%cram-dynamic -.gen] !!)
7 | $(gen gen)
8 | ::
9 | %xray [~ (single (shut gen))]
10 | ^ [(malt (frontmatter p.gen)) (single (shut q.gen))]
11 | ==
12 | ::
13 | ++ single :: unwrap one-elem marl
14 | |= xml=marl ^- manx
15 | ?: ?=([* ~] xml) i.xml
16 | ~|(%many-elems !!)
17 | ::
18 | ++ shut-mart :: xml attrs
19 | |=([n=mane v=(list beer:hoot)] [n (turn v |=(a=beer:hoot ?^(a !! a)))])
20 | ::
21 | ++ shut :: as xml constant
22 | |= gen=hoon ^- marl
23 | ?+ -.gen ~|([%bad-xml -.gen] !!)
24 | %dbug $(gen q.gen)
25 | ::
26 | %xray
27 | [[n.g.p.gen (turn a.g.p.gen shut-mart)] $(gen [%mcts c.p.gen])]~
28 | ::
29 | %mcts
30 | ?~ p.gen ~
31 | =- (weld - $(p.gen t.p.gen))
32 | ?^ -.i.p.gen $(gen [%xray i.p.gen])
33 | ~| [%shut-tuna -.i.p.gen]
34 | ?+ -.i.p.gen !!
35 | %manx ?>(?=(%xray -.p.i.p.gen) $(gen p.i.p.gen))
36 | %marl ?>(?=(%mcts -.p.i.p.gen) $(gen p.i.p.gen))
37 | ==
38 | ==
39 | ::
40 | ::
41 | ++ frontmatter :: parse ~[[%foo 1] [%bar ~s2]]
42 | |= gen=hoon ^- (list [term dime])
43 | ?: ?=([%bust %null] gen) ~
44 | ?: ?=(%dbug -.gen) $(gen q.gen)
45 | ?. ?=(%clsg -.gen) ~|([%bad-frontmatter -.gen] !!)
46 | %+ turn p.gen
47 | |= gen=hoon
48 | ?. ?=(^ -.gen)
49 | =/ gen ~(open ap gen)
50 | ?: =(gen ^gen) ~|([%bad-frontmatter-elem -.gen] !!)
51 | $(gen gen)
52 | =/ hed (as-dime p.gen)
53 | ?. =(%tas p.hed) ~|([%bad-frontmatter-key-type p.hed] !!)
54 | [q.hed (as-dime q.gen)]
55 | ::
56 | ++ as-dime :: %foo ~.foo 0vbar etc
57 | |= gen=hoon ^- dime
58 | ?: ?=(%dbug -.gen) $(gen q.gen)
59 | ?. ?=([?(%rock %sand) @ @] gen) ~|([%bad-literal gen] !!)
60 | +.gen
61 | --
62 |
--------------------------------------------------------------------------------
/tanote/mar/sole/effect.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/effect/sole/mar
3 | ::
4 | /? 310
5 | /- sole
6 | !:
7 | ::
8 | ::::
9 | ::
10 | =, sole
11 | =, format
12 | |%
13 | ++ mar-sole-change :: XX dependency
14 | |_ cha=sole-change
15 | ++ grow
16 | |% ++ json
17 | ^- ^json
18 | =, enjs
19 | =; edi
20 | =,(cha (pairs ted+(edi ted) ler+a+~[(numb own.ler) (numb his.ler)] ~))
21 | |= det=sole-edit
22 | ?- -.det
23 | %nop [%s 'nop']
24 | %mor [%a (turn p.det ..$)]
25 | %del (frond %del (numb p.det))
26 | %set (frond %set (tape (tufa p.det)))
27 | %ins (frond %ins (pairs at+(numb p.det) cha+s+(tuft q.det) ~))
28 | ==
29 | --
30 | --
31 | ++ wush
32 | |= [wid=@u tan=tang]
33 | ^- tape
34 | (of-wall (turn (flop tan) |=(a=tank (of-wall (wash 0^wid a)))))
35 | ::
36 | ++ purge :: discard ++styx style
37 | |= a=styx ^- tape
38 | %- zing %+ turn a
39 | |= a=_?>(?=(^ a) i.a)
40 | ?@(a (trip a) ^$(a q.a))
41 | --
42 | ::
43 | |_ sef=sole-effect
44 | ::
45 | ++ grad %noun
46 | ++ grab :: convert from
47 | |%
48 | ++ noun sole-effect :: clam from %noun
49 | --
50 | ++ grow
51 | =, enjs
52 | |%
53 | ++ noun sef
54 | ++ json
55 | ^- ^json
56 | ?+ -.sef
57 | ~|(unsupported-effect+-.sef !!)
58 | %mor [%a (turn p.sef |=(a=sole-effect json(sef a)))]
59 | %err (frond %hop (numb p.sef))
60 | %txt (frond %txt (tape p.sef))
61 | %tan (frond %tan (tape (wush 160 p.sef)))
62 | %det (frond %det json:~(grow mar-sole-change +.sef))
63 | ::
64 | %pro
65 | %+ frond %pro
66 | (pairs vis+b+vis.sef tag+s+tag.sef cad+(tape (purge cad.sef)) ~)
67 | ::
68 | %tab
69 | :- %a
70 | %+ turn p.sef
71 | |= [=cord =^tank]
72 | %+ frond %tab
73 | %- pairs
74 | :~ match+s+cord
75 | info+(tape ~(ram re tank))
76 | ==
77 | ::
78 | ?(%bel %clr %nex %bye)
79 | (frond %act %s -.sef)
80 | ==
81 | --
82 | --
83 |
--------------------------------------------------------------------------------
/tanote/lib/primitive-rsa.hoon:
--------------------------------------------------------------------------------
1 | :: |rsa: primitive, textbook RSA
2 | ::
3 | :: Unpadded, unsafe, unsuitable for encryption!
4 | ::
5 | |%
6 | :: +key:rsa: rsa public or private key
7 | ::
8 | +$ key
9 | $: :: pub: public parameters (n=modulus, e=pub-exponent)
10 | ::
11 | pub=[n=@ux e=@ux]
12 | :: sek: secret parameters (d=private-exponent, p/q=primes)
13 | ::
14 | sek=(unit [d=@ux p=@ux q=@ux])
15 | ==
16 | :: +ramp: make rabin-miller probabilistic prime
17 | ::
18 | :: XX replace +ramp:number?
19 | :: a: bitwidth
20 | :: b: snags (XX small primes to check divisibility?)
21 | :: c: entropy
22 | ::
23 | ++ ramp
24 | |= [a=@ b=(list @) c=@]
25 | =. c (shas %ramp c)
26 | :: XX what is this value?
27 | ::
28 | =| d=@
29 | |- ^- @ux
30 | :: XX what is this condition?
31 | ::
32 | ?: =((mul 100 a) d)
33 | ~|(%ar-ramp !!)
34 | :: e: prime candidate
35 | ::
36 | :: Sets low bit, as prime must be odd.
37 | :: Sets high bit, as +raw:og only gives up to :a bits.
38 | ::
39 | =/ e :(con 1 (lsh [0 (dec a)] 1) (~(raw og c) a))
40 | :: XX what algorithm is this modular remainder check?
41 | ::
42 | ?: ?& (levy b |=(f=@ !=(1 (mod e f))))
43 | (pram:number e)
44 | ==
45 | e
46 | $(c +(c), d (shax d))
47 | :: +elcm:rsa: carmichael totient
48 | ::
49 | ++ elcm
50 | |= [a=@ b=@]
51 | (div (mul a b) d:(egcd a b))
52 | :: +new-key:rsa: write somethingXXX
53 | ::
54 | ++ new-key
55 | =/ e `@ux`65.537
56 | |= [wid=@ eny=@]
57 | ^- key
58 | =/ diw (rsh 0 wid)
59 | =/ p=@ux (ramp diw [3 5 ~] eny)
60 | =/ q=@ux (ramp diw [3 5 ~] +(eny))
61 | =/ n=@ux (mul p q)
62 | =/ d=@ux (~(inv fo (elcm (dec p) (dec q))) e)
63 | [[n e] `[d p q]]
64 | :: +en:rsa: primitive RSA encryption
65 | ::
66 | :: ciphertext = message^e (mod n)
67 | ::
68 | ++ en
69 | |= [m=@ k=key]
70 | ~| %rsa-len
71 | ?> (lte (met 0 m) (met 0 n.pub.k))
72 | (~(exp fo n.pub.k) e.pub.k m)
73 | :: +de:rsa: primitive RSA decryption
74 | ::
75 | :: message = ciphertext^d (mod e)
76 | ::
77 | ++ de
78 | |= [m=@ k=key]
79 | :: XX assert rsa-len here too?
80 | ~| %rsa-need-ring
81 | ?> ?=(^ sek.k)
82 | =/ fu (fu:number p.u.sek.k q.u.sek.k)
83 | (out.fu (exp.fu d.u.sek.k (sit.fu m)))
84 | --
85 |
--------------------------------------------------------------------------------
/tanote/mar/story.hoon:
--------------------------------------------------------------------------------
1 | /- *story
2 | /+ *story
3 | |_ tale=story
4 | ++ grad
5 | |%
6 | ++ form %story-diff
7 | ++ diff
8 | |= tory=story
9 | ^- story-diff
10 | :: Given new story (tory), old story (tale), compute the diff
11 | :: additions = new - old
12 | :: deletions = old - new
13 | [(dif-ju tory tale) (dif-ju tale tory)]
14 | ++ pact
15 | |= dif=story-diff
16 | :: Compute the new story after applying dif to tale.
17 | ::
18 | ^- story
19 | =. tale (uni-ju tale additions.dif)
20 | =. tale (dif-ju tale deletions.dif)
21 | tale
22 | ++ join
23 | |= [ali=story-diff bob=story-diff]
24 | ^- (unit story-diff)
25 | =/ joined-additions (uni-ju additions.ali additions.bob)
26 | =/ joined-deletions (uni-ju deletions.ali deletions.bob)
27 | ::
28 | :: In a true join, we'd do a set intersection on the keys.
29 | :: If they're not equal, we have a conflict.
30 | :: In this case, we'd produce null and kick the flow to +mash
31 | ::
32 | %- some
33 | [joined-additions joined-deletions]
34 | ++ mash
35 | :: called by meld, force merge, annotating conflicts
36 | |= $: [als=ship ald=desk ali=story-diff]
37 | [bos=ship bod=desk bob=story-diff]
38 | ==
39 | ^- story-diff
40 | (need (join ali bob)) :: XX temporary, only because join doesn't fail
41 | --
42 | ::
43 | ++ grow :: convert to
44 | |% ::
45 | ++ mime :: to %mime
46 | [/text/x-urb-story (as-octs:mimes:html (of-wain:format txt))]
47 | ++ txt
48 | ^- wain
49 | %- snoc :_ '' :: ensures terminating newline is present
50 | %+ murn ~(tap by tale)
51 | |= [[=tako:clay =proses]]
52 | ^- (unit cord)
53 | ?~ proses ~
54 | %- some
55 | %- crip
56 | ;: welp
57 | (tako-to-text tako)
58 | (proses-to-text proses)
59 | "---"
60 | ==
61 | --
62 | ++ grab
63 | |% :: convert from
64 | ++ noun story :: clam from %noun
65 | ++ mime :: retrieve from %mime
66 | |= [p=mite q=octs]
67 | =/ story-text `@t`q.q
68 | `story`(rash story-text parse-story)
69 | --
70 | --
71 |
--------------------------------------------------------------------------------
/tanote/sur/aquarium.hoon:
--------------------------------------------------------------------------------
1 | :: Traditionally, ovo refers to an ovum -- (pair wire card) -- and ova
2 | :: refers to a list of them. We have several versions of each of these
3 | :: depending on context, so we do away with that naming scheme and use
4 | :: the following naming scheme.
5 | ::
6 | :: Every card is either an `event` or an `effect`. Prepended to this
7 | :: is `unix` if it has no ship associated with it, or `aqua` if it
8 | :: does. `timed` is added if it includes the time of the event.
9 | ::
10 | :: Short names are simply the first letter of each word plus `s` if
11 | :: it's a list.
12 | ::
13 | /+ pill
14 | =, pill-lib=pill
15 | |%
16 | +$ az-log [topics=(lest @) data=@t]
17 | +$ az-state
18 | $: logs=(list az-log)
19 | lives=(map ship [lyfe=life rut=rift])
20 | tym=@da
21 | ==
22 | ++ ph-event
23 | $% [%test-done p=?]
24 | aqua-event
25 | ==
26 | ::
27 | +$ unix-event ::NOTE like unix-event:pill-lib but for all tasks
28 | %+ pair wire
29 | $% [%wack p=@]
30 | [%what p=(list (pair path (cask)))]
31 | [%whom p=ship]
32 | [%boot ? $%($>(%fake task:jael) $>(%dawn task:jael))]
33 | [%wyrd p=vere]
34 | [%verb p=(unit ?)]
35 | task-arvo
36 | ==
37 | +$ pill pill:pill-lib
38 | ::
39 | +$ aqua-event
40 | $% [%init-ship who=ship fake=?]
41 | [%pause-events who=ship]
42 | [%snap-ships lab=term hers=(list ship)]
43 | [%restore-snap lab=term]
44 | [%event who=ship ue=unix-event]
45 | ==
46 | ::
47 | +$ azimuth-action
48 | $% [%init-azimuth ~]
49 | [%spawn who=ship]
50 | [%breach who=ship]
51 | ==
52 | ::
53 | +$ aqua-effects
54 | [who=ship ufs=(list unix-effect)]
55 | ::
56 | +$ aqua-effect
57 | [who=ship ufs=unix-effect]
58 | ::
59 | +$ aqua-events
60 | [who=ship utes=(list unix-timed-event)]
61 | ::
62 | +$ aqua-boths
63 | [who=ship ub=(list unix-both)]
64 | ::
65 | +$ unix-both
66 | $% [%event unix-timed-event]
67 | [%effect unix-effect]
68 | ==
69 | ::
70 | +$ unix-timed-event [tym=@da ue=unix-event]
71 | ::
72 | +$ unix-effect
73 | %+ pair wire
74 | $% [%blit p=(list blit:dill)]
75 | [%send p=lane:ames q=@]
76 | [%doze p=(unit @da)]
77 | [%thus p=@ud q=(unit hiss:eyre)]
78 | [%ergo p=@tas q=mode:clay]
79 | [%sleep ~]
80 | [%restore ~]
81 | [%kill ~]
82 | [%init ~]
83 | [%request id=@ud request=request:http]
84 | ==
85 | --
86 |
--------------------------------------------------------------------------------
/tanote/sur/language-server.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | ::
3 | +$ versioned-doc-id
4 | [uri=@t version=(unit @)]
5 | ::
6 | ++ request
7 | |%
8 | +$ all
9 | $%
10 | text-document--hover
11 | text-document--completion
12 | unknown
13 | ==
14 | +$ text-document--hover
15 | [%text-document--hover id=cord position versioned-doc-id]
16 | +$ text-document--completion
17 | [%text-document--completion id=cord position versioned-doc-id]
18 | +$ unknown
19 | [%unknown json]
20 | --
21 | ++ response
22 | |%
23 | +$ all
24 | $%
25 | text-document--hover
26 | text-document--completion
27 | ==
28 | +$ text-document--hover
29 | [%text-document--hover id=cord contents=(unit @t)]
30 | +$ text-document--completion
31 | [%text-document--completion id=cord completion=(list completion-item)]
32 | --
33 | ::
34 | +$ completion-item
35 | $:
36 | label=cord
37 | kind=@ud
38 | detail=cord
39 | doc=cord
40 | insert-text=cord
41 | insert-text-format=@ud
42 | ==
43 |
44 |
45 |
46 | ::
47 | +$ diagnostic
48 | [=range severity=@ud message=@t]
49 | ::
50 | +$ position
51 | [row=@ud col=@ud]
52 | ::
53 | +$ text-document-item
54 | [uri=@t version=(unit @) text=@t]
55 | ::
56 | ++ notification
57 | |%
58 | ::
59 | +$ in
60 | $%
61 | text-document--did-change
62 | text-document--did-open
63 | text-document--did-save
64 | text-document--did-close
65 | exit
66 | unknown
67 | ==
68 | ::
69 | +$ out
70 | $%
71 | text-document--publish-diagnostics
72 | ==
73 | ::
74 | +$ all
75 | $%
76 | out
77 | in
78 | ==
79 | ::
80 | +$ text-document--did-change
81 | [%text-document--did-change versioned-doc-id changes=(list change)]
82 | ::
83 | +$ text-document--did-open
84 | [%text-document--did-open text-document-item]
85 | ::
86 | +$ text-document--did-save
87 | [%text-document--did-save versioned-doc-id]
88 | ::
89 | +$ text-document--did-close
90 | [%text-document--did-close versioned-doc-id]
91 | ::
92 | +$ exit
93 | [%exit ~]
94 | ::
95 | +$ unknown
96 | [%unknown =json]
97 | ::
98 | +$ text-document--publish-diagnostics
99 | [%text-document--publish-diagnostics uri=@t diagnostics=(list diagnostic)]
100 | ::
101 | --
102 | ::
103 | +$ change
104 | $: range=(unit range)
105 | range-length=(unit @ud)
106 | text=@t
107 | ==
108 | ::
109 | +$ range
110 | $: start=position
111 | end=position
112 | ==
113 | ::
114 | --
115 |
--------------------------------------------------------------------------------
/glossary.md:
--------------------------------------------------------------------------------
1 | # Tanote glossary
2 |
3 | ## as
4 |
5 | > You’re going to find that many of the truths we cling to depend greatly on our own point of view.—George Lucas as Obi-Wan Kenobi
6 |
7 | A tag which identifies the faction (_confer_ [[Yarvin 2007]]) of the author with respect to a version of a note.
8 |
9 | Metadata carried with a note. Considered a tag of the note.
10 |
11 | ## backlink
12 |
13 | > Practically, the link context is an explanation on why you should follow a link. A good link context explains what you can expect if you follow the link. But it can also explain the nature of the relationship between both notes.—Sascha Fast
14 |
15 | References to other notes. A tape between `[[` and `]]`. Backlinks are carried in the text of the note.
16 |
17 | ## by
18 |
19 | > A reader should be able to identify a column without its byline or funny little picture on top purely by look or feel, or its turgidity ratio.—William Safire
20 |
21 | The single @p of the author of a version of a note. This field is read-only for the user, and is maintained by the code. For a new note, this is automatically set to our @p. When a note is changed, the author is automatically updated to our @p.
22 |
23 | Metadata carried with a note. Considered a tag of the note.
24 |
25 | ## if
26 |
27 | > Trifles they may be; but it is by such that character and disposition are oftenest revealed.—Washington Irving
28 |
29 | The gora which must be present on a ship for a version of a note to be received.
30 |
31 | ## regards
32 |
33 | > No one regards what is before his feet; we all gaze at the stars.—Quintus Ennius
34 |
35 | With regards: the subject and title of the note. Every note with the same title is considered to be a version of the same note.
36 |
37 | Metadata carried with a note, or the first tape of the data structure of a note, where the remaining cells in the list are versions of the same note.
38 |
39 | ## tag
40 |
41 | > Seeing, hearing, feeling, are miracles, and each part and tag of me is a miracle.—Walt Whitman
42 |
43 | An alphanumeric keyword by which the note is classified, following an octothorpe (`#`); or, a `@p` in the text (_eg_ `~ponhec-picwen`). Tags are carried in the text of the note.
44 |
45 | ## text
46 |
47 | > The absence of a message sometimes is a presence of one.—Hasse Jerner
48 |
49 | The text, the body of a note, excluding metadata. The tape which is the text contains tags and backlinks.
50 |
51 | ## to
52 |
53 | > Whatever is received is received according to the nature of the recipient.—Thomas Aquinas
54 |
55 | The set of @p of recipients of the note.
56 |
57 | Metadata carried with a note, and used to route the note to other users. Considered tags of the note?
58 |
59 |
--------------------------------------------------------------------------------
/tanote-glob/img/tanote.svg:
--------------------------------------------------------------------------------
1 |
2 |
33 |
--------------------------------------------------------------------------------
/announce.md:
--------------------------------------------------------------------------------
1 | [[~ponhec-picwen]]. [[2022-06-04]]. Urbit community: General. Urbit groups. web+urbitgraph://group/~bitbet-bolbel/urbit-community/graph/~darrux-landes/general/170141184505669025390660775828512957267
2 |
3 | [[~nocsyx-lassul]]: we keep hoping someone will build one
4 |
5 | [[~ponhec-picwen]]: [[~nocsyx-lassul]], I recently had a brainstorm, and have been inspired to make something that strikes me as Martian. I just started Hoon school (I'm up to recursion), and then comes Gall school and working through the journal example. I'm doing this on my own, but I have a Computer Engineering degree and 40 years experience writing software (taught myself BASIC on a TI-99/4A and Logo on a Commodore 64), so I should be able to figure it out. Here's my work on it so far, which is mostly just notes and a static page.
6 |
7 | https://github.com/catenate/tanote
8 |
9 | Speaking of early days of home computers, Urbit most reminds me of the shareware and freeware produced by communities of hobbyists and spread by word-of-mouth, swap meets, BBSes, small-group zines, and ads in the back pages of magazines from which you typed in program listings. It's nice to get back to that spirit and enthusiasm, in which random people use what they know to make software they love.
10 |
11 | [[~pinsyt-nossub]]: [[~ponhec-picwen]], I assume you know about this grant, but I'd rather be redundant for you not to miss it:
12 | https://urbit.org/grants/app-engram
13 |
14 | [[~ponhec-picwen]]: [[~pinsyt-nossub]], I read that, but what I'd like to build is not that. It's not a mediated common view that tries to reconcile multiple simultaneous edits. It's more like email, in that you send asynchronously a particular version of a titled document, but the new (ur-)bit is that it stores and presents together, as versions in a series, all the notes with the same title, since it considers these drafts of the same document, working towards a definition of that title. Which document titles you may select from, to view, is determined by the active selected hash tags, and the list of hash tags to select from is composed from the list of hash tags in the latest versions of all the documents (plus a * to see every note, plus the note's faction, plus the @p of the note's author, plus the @p of each recipient). Each version of each note has a list of people (by @p) to whom it is sent, and once sent it appears in that person's set of notes (I'm not really yet planning on delete, but you can always make a new blank version of a note with any title to remove it from the hashtag index). I'm also planning on signalling which other visible notes have back links to the current note (though Urbsidian is also not quite what I want to write), and allowing the writer of the note to provide with each note a tag stating the note's single factional point of view (cf Uberfact), to keep the notes small and focused and coherent and findable.
15 |
16 |
--------------------------------------------------------------------------------
/tanote/lib/ph/util.hoon:
--------------------------------------------------------------------------------
1 | :: Utility functions for constructing tests
2 | ::
3 | /- aquarium
4 | =, aquarium
5 | |%
6 | ::
7 | :: Turn [ship (list unix-event)] into (list ph-event)
8 | ::
9 | ++ send-events-to
10 | |= [who=ship what=(list unix-event)]
11 | ^- (list aqua-event)
12 | %+ turn what
13 | |= ue=unix-event
14 | [%event who ue]
15 | ::
16 | :: Start a ship (low-level; prefer +raw-ship)
17 | ::
18 | ++ init
19 | |= [who=ship fake=?]
20 | ^- (list aqua-event)
21 | [%init-ship who fake]~
22 | ::
23 | :: Send dojo command
24 | ::
25 | ++ dojo
26 | |= [who=ship what=tape]
27 | ^- (list aqua-event)
28 | %+ send-events-to who
29 | ^- (list unix-event)
30 | :~
31 | [/d/term/1 %belt %ctl `@c`%e]
32 | [/d/term/1 %belt %ctl `@c`%u]
33 | [/d/term/1 %belt %txt ((list @c) what)]
34 | [/d/term/1 %belt %ret ~]
35 | ==
36 | ::
37 | :: Control character
38 | ::
39 | ++ ctrl
40 | |= [who=ship what=term]
41 | ^- (list ph-event)
42 | %+ send-events-to who
43 | :~ [/d/term/1 %belt %ctl (,@c what)]
44 | ==
45 | ::
46 | :: Inject a file into a ship
47 | ::
48 | ++ insert-files
49 | |= [who=ship des=desk files=(list [=path txt=@t])]
50 | ^- (list aqua-event)
51 | =/ input
52 | %+ turn files
53 | |= [=path txt=@t]
54 | [path ~ /text/plain (as-octs:mimes:html txt)]
55 | %+ send-events-to who
56 | :~
57 | [/c/sync/0v1n.2m9vh %into des | input]
58 | ==
59 | ::
60 | :: Checks whether the given event is a dojo output blit containing the
61 | :: given tape
62 | ::TODO should be rename -dill-output
63 | ++ is-dojo-output
64 | |= [who=ship her=ship uf=unix-effect what=tape]
65 | ?& =(who her)
66 | ?=(%blit -.q.uf)
67 | ::
68 | %+ lien p.q.uf
69 | |= =blit:dill
70 | ?. ?=(%lin -.blit)
71 | |
72 | !=(~ (find what p.blit))
73 | ==
74 | ::
75 | :: Test is successful if +is-dojo-output
76 | ::
77 | ++ expect-dojo-output
78 | |= [who=ship her=ship uf=unix-effect what=tape]
79 | ^- (list ph-event)
80 | ?. (is-dojo-output who her uf what)
81 | ~
82 | [%test-done &]~
83 | ::
84 | :: Check whether the given event is an ergo
85 | ::
86 | ++ is-ergo
87 | |= [who=ship her=ship uf=unix-effect]
88 | ?& =(who her)
89 | ?=(%ergo -.q.uf)
90 | ==
91 | ::
92 | :: Check if given effect is an http request; extract
93 | ::
94 | ++ extract-request
95 | |= [uf=unix-effect dest=@t]
96 | ^- (unit [num=@ud =request:http])
97 | ?. ?=(%request -.q.uf) ~
98 | ?. =(dest url.request.q.uf) ~
99 | `[id.q.uf request.q.uf]
100 | ::
101 | :: Scry into a running aqua ship
102 | ::
103 | ++ scry-aqua
104 | |* [a=mold our=@p now=@da pax=path]
105 | .^ a
106 | %gx
107 | (scot %p our)
108 | %aqua
109 | (scot %da now)
110 | pax
111 | ==
112 | --
113 |
--------------------------------------------------------------------------------
/tanote/sur/asn1.hoon:
--------------------------------------------------------------------------------
1 | :: |asn1: small selection of types and constants for ASN.1
2 | ::
3 | :: A minimal representation of some basic ASN.1 types,
4 | :: created to support PKCS keys, digests, and cert requests.
5 | ::
6 | ^?
7 | |%
8 | :: +bespoke:asn1: context-specific, generic ASN.1 tag type
9 | ::
10 | :: Note that *explicit* implies *constructed* (ie, bit 5 is set in DER).
11 | ::
12 | +$ bespoke
13 | :: imp: & is implicit, | is explicit
14 | :: tag: 5 bits for the custom tag number
15 | ::
16 | [imp=? tag=@ud]
17 | :: +spec:asn1: minimal representations of basic ASN.1 types
18 | ::
19 | +$ spec
20 | $% :: %int: arbitrary-sized, unsigned integers
21 | ::
22 | :: Unsigned integers, represented as having a positive sign.
23 | :: Negative integers would be two's complement in DER,
24 | :: but we don't need them.
25 | ::
26 | [%int int=@u]
27 | :: %bit: very minimal support for bit strings
28 | ::
29 | :: Specifically, values must already be padded and byte-aligned.
30 | :: len: bitwidth
31 | :: bit: data
32 | ::
33 | [%bit len=@ud bit=@ux]
34 | :: %oct: octets in little-endian byte order
35 | ::
36 | :: len: bytewidth
37 | :: bit: data
38 | ::
39 | [%oct len=@ud oct=@ux]
40 | :: %nul: fully supported!
41 | ::
42 | [%nul ~]
43 | :: %obj: object identifiers, pre-packed
44 | ::
45 | :: Object identifiers are technically a sequence of integers,
46 | :: represented here in their already-encoded form.
47 | ::
48 | [%obj obj=@ux]
49 | :: %seq: a list of specs
50 | ::
51 | [%seq seq=(list spec)]
52 | :: %set: a logical set of specs
53 | ::
54 | :: Implemented here as a list for the sake of simplicity.
55 | :: must be already deduplicated and sorted!
56 | ::
57 | [%set set=(list spec)]
58 | :: %con: context-specific
59 | ::
60 | :: General support for context-specific tags.
61 | :: bes: custom tag number, implicit or explicit
62 | :: con: already-encoded bytes
63 | ::
64 | [%con bes=bespoke con=(list @D)]
65 | ==
66 | :: |obj:asn1: constant object ids, pre-encoded
67 | ::
68 | ++ obj
69 | ^?
70 | |% :: rfc4055
71 | ++ sha-256 0x1.0204.0365.0148.8660 :: 2.16.840.1.101.3.4.2.1
72 | ++ rsa 0x1.0101.0df7.8648.862a :: 1.2.840.113549.1.1.1
73 | ++ rsa-sha-256 0xb.0101.0df7.8648.862a :: 1.2.840.113549.1.1.11
74 | :: rfc2985
75 | ++ csr-ext 0xe.0901.0df7.8648.862a :: 1.2.840.113549.1.9.14
76 | :: rfc3280
77 | ++ sub-alt 0x11.1d55 :: 2.5.29.17
78 | --
79 | --
80 |
81 |
--------------------------------------------------------------------------------
/Yarvin 2007.md:
--------------------------------------------------------------------------------
1 | [[Curtis Yarvin]] as [[Mencius Moldbug]]. [[2007-08-22]]. [[Uberfact]]: The ultimate social verifier. [[Unqualified reservations]]. https://www.unqualified-reservations.org/2007/08/uberfact-ultimate-social-verifier/
2 |
3 | …
4 |
5 | Notice these group labels. In Uberfact, these are called _factions_. Factions are groups of people who see the world in the same way. Factions may form on any issue and for any reason—progressive _versus_ conservative, Ford _versus_ Chevy, [emacs _versus_ vi](https://en.wikipedia.org/wiki/Editor_war).
6 |
7 | Any user can have a reputation in as many factions as he likes. But reputation in one faction has no meaning to another faction. To a Ford-lover, it means nothing that you’re a highly rated libertarian. What do you know about limited-slip differentials? Jack. Until you prove otherwise.
8 |
9 | Every contribution to Uberfact must be associated with a faction, and it is judged by that faction and that faction only. If the contribution is good, it improves your local reputation within that faction. If I have something to share about Ezra Pound, I have to decide whether I’m saying it as a modernist, a postmodernist, a New Critic, _et cetera_, _et cetera_.
10 |
11 | Factions are self-constituting—they are responsible for their own reputation algorithms. Anyone can start a new faction for any reason, but generally they form by the usual process of human group formation—one group gets too large and quarrelsome, and splits into parts. The faction’s founders constitute and manage its reputation system.
12 |
13 | For example, early in Uberfact’s development, there would probably be a libertarian faction. This would then fragment into Rothbardian, Randian, and Kochian libertarians—at least. Various strongly-flavored personalities might spin off their own little factions, and so on.
14 |
15 | As a user of Uberfact, you have access to all content produced by all factions. Your process for answering a question, such as “is George W Bush a tyrant,” is in two steps. One, figure out what faction is both (a) interested in this question, and (b) reasonably aligned with your own perspective in the area. Two, find out what that faction says about George W Bush.
16 |
17 | For example, it’s easy to imagine upgrading Wikipedia to be uberfactious. Instead of one page for George W Bush, you could read the story of George W Bush according to libertarians, according to progressives, according to jihadis, racists, Ford lovers, emacs bigots, and so on—anyone who cares enough to have an opinion about George W Bush.
18 |
19 | One might quickly notice that these pages matched in certain details. For example, jihadis, racists, and progressives probably all agree that George W Bush was born on July 6, 1946. So all of these groups might contribute to a consensus page, signed by a large number of factions, which might even be similar to today’s “objective” page. And since this would probably be the most commonly requested George W. Bush page, it would come up first. An uberfactious Wikipedia doesn’t need to be any harder to use than today’s neutralist Wikipedia.
20 |
21 |
--------------------------------------------------------------------------------
/data structures.md:
--------------------------------------------------------------------------------
1 | # alternative arrangements to store notes
2 |
3 | ## metadata and text
4 |
5 | Store each note independently in a larger list.
6 |
7 | ```hoon
8 | [[by=@p as=@t] to=(list @p) re=@t te=@t]
9 | ```
10 |
11 | slot | accessor | noun
12 | --- | --- | ---
13 | +1:c | c | `[by=@p to=(list @p) re=@t te=@t]`
14 | +2:c | | `[by=@p as=@t]`
15 | +3:c | | `[to=(list @p) re=@t te=@t]`
16 | +4:c | (by c) | `by=@p`
17 | +5:c | (as c) | `as=@t`
18 | +6:c | (to c) | `to=(list @p)`
19 | +7:c | | `[re=@t te=@t]`
20 | | |
21 | +14:c | (re c) | `re=@t`
22 | +15:c | (te c) | `te=@t`
23 |
24 | `(ta c)` returns a `(list @t)` of tags (`#[^ ]+`) in `(te c)`.
25 |
26 | ## grouped by regards
27 |
28 | Store all versions by their common regards, within a larger list of all regards.
29 |
30 | ```hoon
31 | [re [[by as] to te] [[by as] to te]]
32 | ```
33 |
34 | slot | subexpression | content
35 | --- | --- | ---
36 | +1:c | `[re [[by as] to te] [[by as] to te]]` | list of all notes with the same regards
37 | +2:c | `re` | @t of regards (title) common to all following notes
38 | +3:c | `[[by as] to te] [[by as] to te]` | all the versions of the notes, decreasing to 1
39 | | |
40 | +6:c | `[[by as] to te]` | version 2 of the note
41 | +7:c | `[[by as] to te]` | version 1 of the note
42 | | |
43 | +12:c | `[by as]` | author and faction of version 2 of the note
44 | +13:c | `[to te]` | recipients and text of version 2 of the note
45 | +14:c | `[by as]` | author and faction of version 1 of the note
46 | +15:c | `[to te]` | recipients and text of version 1 of the note
47 | | |
48 | +24:c | `(by +6:c)` (by gets +4) | @p of author of version 2 of the note
49 | +25:c | `(as +6:c)` (as gets +5) | @t of faction of version 2 of the note
50 | +26:c | `(to +6:c)` (to gets +6) | `(list @p)` of recipients of version 2 of the note
51 | +27:c | `(te +6:c)` (te gets +7) | @t of text of version 2 of the note
52 | +28:c | `(by +7:c)` | @p of author of version 1 of the note
53 | +29:c | `(as +7:c)` | @t of faction of version 1 of the note
54 | +30:c | `(to +7:c)` | `(list @p)` of recipients of version 1 of the note
55 | +31:c | `(te +7:c)` | @t of text of version 1 of the note
56 |
57 | Construct the list of all regards simply by grabbing +2 from all of the regards in the overall structure. We don’t have to keep a separate list of regards. How do we identify backlinks? We want to know, for the latest version of each note, whether the text of the note contains the regards of the uniquely **selected note** within `[[ ]]`. If so, present the regards of the _referring note_ in italics, if the note is filtered in by the multiple **selected tags**.
58 |
59 | Construct the list of all tags by extracting the list of tags in the text (always `(te +7:c)`) in the latest version (+6) of each regards. This means that the tags are always up-to-date, but that the history of tags is not presented. On the plus side, we don’t have to keep a separate list of tags.
60 |
61 | Tags include `by` (the `@p` of the author), `as` (the faction of the author with respect to this note), each `to` (`(list @p)` of recipients), and all tags (`#[^ ]+`) in the text.
62 |
63 |
--------------------------------------------------------------------------------
/tanote/lib/agentio.hoon:
--------------------------------------------------------------------------------
1 | =>
2 | |%
3 | ++ card card:agent:gall
4 | --
5 | ::
6 | |_ =bowl:gall
7 | ++ scry
8 | |= [desk=@tas =path]
9 | %+ weld
10 | /(scot %p our.bowl)/[desk]/(scot %da now.bowl)
11 | path
12 | ::
13 | ++ pass
14 | |_ =wire
15 | ++ poke
16 | |= [=dock =cage]
17 | [%pass wire %agent dock %poke cage]
18 | ::
19 | ++ poke-our
20 | |= [app=term =cage]
21 | ^- card
22 | (poke [our.bowl app] cage)
23 | ::
24 | ++ poke-self
25 | |= =cage
26 | ^- card
27 | (poke-our dap.bowl cage)
28 | ::
29 | ++ arvo
30 | |= =note-arvo
31 | ^- card
32 | [%pass wire %arvo note-arvo]
33 | ::
34 | ++ watch
35 | |= [=dock =path]
36 | [%pass (watch-wire path) %agent dock %watch path]
37 | ::
38 | ++ watch-our
39 | |= [app=term =path]
40 | (watch [our.bowl app] path)
41 | ::
42 | ++ watch-wire
43 | |= =path
44 | ^+ wire
45 | ?. ?=(~ wire)
46 | wire
47 | agentio-watch+path
48 | ::
49 | ++ leave
50 | |= =dock
51 | [%pass wire %agent dock %leave ~]
52 | ::
53 | ++ leave-our
54 | |= app=term
55 | (leave our.bowl app)
56 | ::
57 | ++ leave-path
58 | |= [=dock =path]
59 | =. wire
60 | (watch-wire path)
61 | (leave dock)
62 | ::
63 | ++ wait
64 | |= p=@da
65 | (arvo %b %wait p)
66 | ::
67 | ++ rest
68 | |= p=@da
69 | (arvo %b %wait p)
70 | ::
71 | ++ warp
72 | |= [wer=ship =riff:clay]
73 | (arvo %c %warp wer riff)
74 | ::
75 | ++ warp-our
76 | |= =riff:clay
77 | (warp our.bowl riff)
78 | ::
79 | :: right here, right now
80 | ++ warp-slim
81 | |= [genre=?(%sing %next) =care:clay =path]
82 | =/ =mood:clay
83 | [care r.byk.bowl path]
84 | =/ =rave:clay
85 | ?:(?=(%sing genre) [genre mood] [genre mood])
86 | (warp-our q.byk.bowl `rave)
87 | ::
88 | ++ connect
89 | |= [=binding:eyre app=term]
90 | (arvo %e %connect binding app)
91 | --
92 | ::
93 | ++ fact-curry
94 | |* [=mark =mold]
95 | |= [paths=(list path) fac=mold]
96 | (fact mark^!>(fac) paths)
97 | ::
98 | ++ fact-kick
99 | |= [=path =cage]
100 | ^- (list card)
101 | :~ (fact cage ~[path])
102 | (kick ~[path])
103 | ==
104 | ::
105 | ++ fact-init
106 | |= =cage
107 | ^- card
108 | [%give %fact ~ cage]
109 | ::
110 | ++ fact-init-kick
111 | |= =cage
112 | ^- (list card)
113 | :~ (fact cage ~)
114 | (kick ~)
115 | ==
116 | ::
117 | ++ fact
118 | |= [=cage paths=(list path)]
119 | ^- card
120 | [%give %fact paths cage]
121 | ::
122 | ++ fact-all
123 | |= =cage
124 | ^- (unit card)
125 | =/ paths=(set path)
126 | %- ~(gas in *(set path))
127 | %+ turn ~(tap by sup.bowl)
128 | |=([duct ship =path] path)
129 | ?: =(~ paths) ~
130 | `(fact cage ~(tap in paths))
131 | ::
132 | ++ kick
133 | |= paths=(list path)
134 | [%give %kick paths ~]
135 | ::
136 | ++ kick-only
137 | |= [=ship paths=(list path)]
138 | [%give %kick paths `ship]
139 | --
140 |
--------------------------------------------------------------------------------
/tanote/lib/keygen.hoon:
--------------------------------------------------------------------------------
1 | :: urbit-style key generation and derivation functions
2 | ::
3 | /- keygen
4 | ::
5 | /+ ethereum, bip32, bip39
6 | ::
7 | =, keygen
8 | ::
9 | |%
10 | ++ argon2u
11 | |= [who=ship tic=byts]
12 | ^- @
13 | ~| [%who who (met 3 who)]
14 | :: ?> (lte (met 3 who) 4)
15 | %- (argon2-urbit:argon2:crypto 32)
16 | :- tic
17 | =- [(met 3 -) (swp 3 -)]
18 | %- crip
19 | (weld "urbitkeygen" (a-co:co who))
20 | ::
21 | ++ child-node-from-seed
22 | |= [seed=@ typ=tape pass=(unit @t)]
23 | ^- node
24 | =+ sed=(seed:ds 32^seed typ)
25 | =+ nom=(from-entropy:bip39 32^sed)
26 | :+ typ nom
27 | %- wallet:ds
28 | %+ to-seed:bip39 nom
29 | (trip (fall pass ''))
30 | ::
31 | ++ derive-network-seed
32 | |= [mngs=@ rev=@ud]
33 | ^- @ux
34 | =+ (seed:ds 64^mngs (weld "network" (a-co:co rev)))
35 | ?: =(0 rev) -
36 | :: hash again to prevent length extension attacks
37 | (sha-256l:sha 32 -)
38 | ::
39 | ++ ownership-wallet-from-ticket
40 | |= [who=ship ticket=byts pass=(unit @t)]
41 | ^- node
42 | =+ master-seed=(argon2u who ticket)
43 | (child-node-from-seed master-seed "ownership" pass)
44 | ::
45 | ++ full-wallet-from-ticket
46 | :: who: username
47 | :: ticket: password
48 | :: rev: network key revision
49 | :: pass: optional passphrase
50 | ::
51 | |= [who=ship ticket=byts rev=@ud pass=(unit @t)]
52 | ^- vault
53 | =+ master-seed=(argon2u who ticket)
54 | =/ cn :: child node
55 | |= typ=nodetype
56 | (child-node-from-seed master-seed typ pass)
57 | ::
58 | :- ^= ownership ^- node
59 | (cn "ownership")
60 | ::
61 | :- ^= voting ^- node
62 | (cn "voting")
63 | ::
64 | =/ management=node
65 | (cn "management")
66 | :- management=management
67 | ::
68 | :- ^= transfer ^- node
69 | (cn "transfer")
70 | ::
71 | :- ^= spawn ^- node
72 | (cn "spawn")
73 | ::
74 | ^= network ^- uode
75 | =/ mad :: management seed
76 | %+ to-seed:bip39
77 | seed:management
78 | (trip (fall pass ''))
79 | =+ sed=(derive-network-seed mad rev)
80 | [rev sed (urbit:ds sed)]
81 | ::
82 | ++ ds :: derive from raw seed
83 | |%
84 | ++ wallet
85 | |= seed=@
86 | ^- ^wallet
87 | =+ => (from-seed:bip32 64^seed)
88 | (derive-path "m/44'/60'/0'/0/0")
89 | :+ [public-key private-key]
90 | (address-from-prv:key:ethereum private-key)
91 | chain-code
92 | ::
93 | ++ urbit
94 | |= seed=@
95 | ^- edkeys
96 | =+ =< [pub=pub:ex sec=sec:ex]
97 | (pit:nu:crub:crypto 256 seed)
98 | :- ^= auth
99 | :- (rsh 3 (end [3 33] pub))
100 | (rsh 3 (end [3 33] sec))
101 | ^= crypt
102 | :- (rsh [3 33] pub)
103 | (rsh [3 33] sec)
104 | ::
105 | ++ seed
106 | |= [seed=byts salt=tape]
107 | ^- @ux
108 | %- sha-256l:sha
109 | :- (add wid.seed (lent salt))
110 | (cat 3 (crip (flop salt)) dat.seed)
111 | --
112 | --
113 |
--------------------------------------------------------------------------------
/proposal tech.md:
--------------------------------------------------------------------------------
1 | # Tanote proposal
2 |
3 | ## Technical summary
4 |
5 | ### Screen layout
6 |
7 | In a graphical interface of mostly text (eg, Groups, Escape, Journal), Tanote captures titled, textual notes (a UTF-8 string) with a set of metadata (author, faction, recipients, tags in the text, and backlinks in the text). It presents three areas of text on the screen: (1) set of all tags in the most recent versions of notes stored locally (authored by the ship owner, or received from others), where each tag is clickable to select it; (2) set of titles of notes, for either all notes, or only notes which contain all the selected tags; one note title may be clicked on at a time, to select it; (3) and the text and metadata of the selected note, or the list of versions of the selected note.
8 |
9 | ### Additional user interface
10 |
11 | Notes which are selected by tags, but which are not the selected note, which contain a backlink to the selected note, are indicated by presenting the note title in italics. The user can edit the recipients (and text and other metadata; except author, which is set to the ship’s @p) of a note, to send (ie, forward) it to a new set of recipients, which stores it as a new version of the note.
12 |
13 | ### Storage
14 |
15 | All notes with the same title are considered versions of the same note. A note is stored as a title, and then a list of its versions. Each note becomes a new immutable version once it has been stored locally (via an add UI element), or once it has been sent to its recipients (which also stores it locally as a new version). A received note is automatically added to the store, its tags (including metadata), are added to set of tags shown in the tags section (always all known tags in the latest versions of notes), and the title (if new) is added to the set of notes shown in the titles section (if it should be shown by the selected tags). To make a note disappear again from the index of tags (and also from the set of shown notes, unless we are displaying all notes), the recipient may add a new version with no text.
16 |
17 | ### Interoperability
18 |
19 | I’d like to store these notes in a way that other applications can get to them, which might be %graph-store (I don’t know enough about this yet). This may mean that the application is architected as a layer that is called by the (minimal) GUI to talk to primitives that actually work with the data, so other programs may use these primitives. (It’s early days in my understanding of Urbit app architecture.)
20 |
21 | ### Economy
22 |
23 | We could possibly monetize notes, either automatically by gating the sending of the note on a blockchain transaction or the presence of a subscriber gora, or manually by the author not sending the note until the transaction is performed elsewhere. This was not one of my primary goals in writing this, but it could help people create an economy within Urbit around the text of notes. (It’s up to the authors to make them worth paying for.;) There’s a tension between allowing other apps access to notes, and monetizing them, in that the other apps accessing paid notes should not themselves send the note elsewhere, to get around the payment mechanism.
24 |
25 |
--------------------------------------------------------------------------------
/tanote/lib/story.hoon:
--------------------------------------------------------------------------------
1 | /- *story
2 | !:
3 | ^?
4 | |%
5 | :: XX generalize move to hoon.hoon
6 | ++ dif-ju
7 | |= [a=story b=story]
8 | ^- story
9 | :: if 0 is the empty set,
10 | :: a \ 0 = a
11 | :: 0 \ b = 0 :: anything in 0 but not in b is by definition 0
12 | ::
13 | ?: =(~ a) ~
14 | :: uno := (a-b) + (merged items in both a and b) + (b-a)
15 | :: ret := (a-b) + (merged items in both a and b)
16 | :: ret = (~(int by a) uno) :: preserve only the entries whose keys are in a
17 | =/ uno=story
18 | %- (~(uno by a) b)
19 | |= [k=tako:clay proses-a=proses proses-b=proses]
20 | ^- proses
21 | (~(dif in proses-a) proses-b)
22 | ::
23 | =/ ret=story (~(int by a) uno)
24 | :: normalizing step, remove any keys with null sets,
25 | :: which can occur if proses-a == proses-b above
26 | %- ~(gas by *story)
27 | (skip ~(tap by ret) |=([k=* v=proses] ?=(~ v)))
28 | ::
29 | ++ uni-ju
30 | |= [a=story b=story]
31 | ^- story
32 | :: 0 + b = b
33 | ?: =(~ a) b
34 | %- (~(uno by a) b)
35 | |= [k=tako:clay proses-a=proses proses-b=proses]
36 | ^- proses
37 | (~(uni in proses-a) proses-b)
38 | ::
39 | :: Canonical textual representation
40 | ::
41 | ++ tako-to-text
42 | |= [=tako:clay]
43 | ^- tape
44 | "commit: {<`@uv`tako>}\0a"
45 | ::
46 | ++ proses-to-text
47 | |= [=proses]
48 | ^- tape
49 | =/ proses-list=(list prose) ~(tap in proses)
50 | ?: ?=(~ proses-list) ""
51 | ?: ?=([prose ~] proses-list)
52 | (prose-to-text i.proses-list)
53 | %- tail
54 | %^ spin `(list prose)`t.proses-list
55 | (prose-to-text i.proses-list)
56 | |= [prz=prose state=tape]
57 | ^- [prose tape]
58 | :- prz
59 | ;: welp
60 | state
61 | "|||"
62 | "\0a"
63 | (prose-to-text prz)
64 | ==
65 | ::
66 | ++ prose-to-text
67 | |= prz=prose
68 | =/ [title=@t body=@t] prz
69 | ^- tape
70 | ;: welp
71 | "{(trip title)}"
72 | "\0a\0a"
73 | "{(trip body)}"
74 | "\0a"
75 | ==
76 | ::
77 | :: Parsers
78 | ::
79 | ++ parse-commit-hash
80 | ;~ sfix
81 | ;~ pfix (jest 'commit: ')
82 | (cook @uv ;~(pfix (jest '0v') viz:ag))
83 | ==
84 | ::
85 | (just '\0a')
86 | ==
87 | ::
88 | ++ parse-title
89 | ;~ sfix
90 | (cook crip (star prn))
91 | (jest '\0a\0a')
92 | ==
93 | ::
94 | ++ parse-body
95 | %+ cook of-wain:format
96 | %- star
97 | ;~ less
98 | ;~(pose (jest '|||\0a') (jest '---\0a'))
99 | (cook crip ;~(sfix (star prn) (just '\0a')))
100 | ==
101 | ::
102 | ++ parse-prose ;~(plug parse-title parse-body)
103 | ++ parse-rest-proses (star ;~(pfix (jest '|||\0a') parse-prose))
104 | ++ parse-proses (cook silt ;~(plug parse-prose parse-rest-proses))
105 | ++ parse-chapter ;~(plug parse-commit-hash parse-proses)
106 | ++ parse-story
107 | (cook ~(gas by *story) (star ;~(sfix parse-chapter (jest '---\0a'))))
108 | ::
109 | :: N.B: If conflicting messages are written individually,
110 | :: instead of under the same commit, we will overwrite previous entries
111 | :: with later ones due to the nature of gas:by.
112 | --
113 |
--------------------------------------------------------------------------------
/~tonned-fampet 2022-06-23.md:
--------------------------------------------------------------------------------
1 | [[~monsut-bidnym]]: [[~tonned-fampet]], I think [[knowledge management]] on [[Urbit]] is a big project, but could encompass all of these things. [[Holium]] is making a bid at this with [[Engram]].
2 |
3 | [[~tonned-fampet]]: [[~monsut-bidnym]], this has probably been said before, but a feature that would be really nice for [[Engram]] is [[bi-directional linking]], similar to [[Roam Research]] and [[Obsidian]]. My wife is a heavy user of Roam; although she has an [[Urbit planet]] that I gave her but rarely uses it. She has said that if there were a Roam competitor on Urbit she would actually use the platform.
4 |
5 | If her view is any indication, a Roam competitor on Urbit could be a killer app that could drive more mainstream adoption of Urbit, much more so than a reproduction of [[Google Docs]] or whatever. Google Docs is free, and so it will only be true Urbit believers already on the platform that would be interested in using an Urbit-based competitor to a Google product. But Roam Research costs about $15 a month, and so Roam users would have a strong financial incentive to take the time to set up a personal server to run an Urbit-based Roam competitor if it means eliminating lock-in to an expensive [[SaaS]] offering. An Urbit-based Roam competitor would also hit the right sweet spot of decentralization. If you don't want to pay for Roam Research, your best option is to use Obsidian, in which case you are stuck using a knowledge graph tied to your PC.
6 |
7 | [[~ponhec-picwen]]: I use Obsidian synced between my laptop and phone, so if one crashes the other can resync the replacement. I plan to have [[bi-directional linking]] in %[[tanote/tanote]], but I'm still working on internals, like structuring notes into histories and histories into stores, and extracting tags and back links from stores, to have the right displays on the front end. Also, I have no real plans to make an "[[Urbsidian]]": if we liken [[Emacs]] to [[Obsidian]], then what I want to create with %[[tanote]] is more like [[vi]] (or [[vim]]).
8 |
9 | I should also mention that I feel %[[tanote]] will be better at sharing than any of the mentioned tools, since it will be able to share (and record the fact of that sharing) specific versions of specific notes individually. Also, if it works out, my plan is to let you optionally gate the sharing on whether the recipient(s) have a specific [[gora]] that you can set per version of a note.
10 |
11 | [[~sarlev-sarsen]]: Build It. <<< My general statement for all things urbit notetaking/pkm related. There is lots of pontificating on this topic and the best way to figure out what works best is most certainly to start doing it. [[~ponhec-picwen]] is working on a proposal for this which is rad, and [[Engram]] is still an open bounty as of now, but would be good to see a few more options out there as well. [[~ribben-donnyl]] is working on an [[iOS]] mobile notes app that stores in your urbit, as well.
12 |
13 | [[~tonned-fampet]]: [[~ponhec-picwen]], sounds great—is there a group where I can follow the development progress?
14 |
15 | [[~ponhec-picwen]]: [[~tonned-fampet]]: I update (at least weekly) the proposal notebook in my tah-noh-tay group with the latest progress, and you can watch my [[GitHub]] repo catenate/[[tanote/tanote]] for commits.
16 |
--------------------------------------------------------------------------------
/tanote/lib/verb.hoon:
--------------------------------------------------------------------------------
1 | :: Print what your agent is doing.
2 | ::
3 | /- verb
4 | ::
5 | |= [loud=? =agent:gall]
6 | =| bowl-print=_|
7 | ^- agent:gall
8 | |^ !.
9 | |_ =bowl:gall
10 | +* this .
11 | ag ~(. agent bowl)
12 | ::
13 | ++ on-init
14 | ^- (quip card:agent:gall agent:gall)
15 | %- (print bowl |.("{}: on-init"))
16 | =^ cards agent on-init:ag
17 | [[(emit-event %on-init ~) cards] this]
18 | ::
19 | ++ on-save
20 | ^- vase
21 | %- (print bowl |.("{}: on-save"))
22 | on-save:ag
23 | ::
24 | ++ on-load
25 | |= old-state=vase
26 | ^- (quip card:agent:gall agent:gall)
27 | %- (print bowl |.("{}: on-load"))
28 | =^ cards agent (on-load:ag old-state)
29 | [[(emit-event %on-load ~) cards] this]
30 | ::
31 | ++ on-poke
32 | |= [=mark =vase]
33 | ^- (quip card:agent:gall agent:gall)
34 | %- (print bowl |.("{}: on-poke with mark {}"))
35 | ?: ?=(%verb mark)
36 | ?- !<(?(%loud %bowl) vase)
37 | %loud `this(loud !loud)
38 | %bowl `this(bowl-print !bowl-print)
39 | ==
40 | =^ cards agent (on-poke:ag mark vase)
41 | [[(emit-event %on-poke mark) cards] this]
42 | ::
43 | ++ on-watch
44 | |= =path
45 | ^- (quip card:agent:gall agent:gall)
46 | %- (print bowl |.("{}: on-watch on path {}"))
47 | =^ cards agent
48 | ?: ?=([%verb %events ~] path)
49 | [~ agent]
50 | (on-watch:ag path)
51 | [[(emit-event %on-watch path) cards] this]
52 | ::
53 | ++ on-leave
54 | |= =path
55 | ^- (quip card:agent:gall agent:gall)
56 | %- (print bowl |.("{}: on-leave on path {}"))
57 | ?: ?=([%verb %event ~] path)
58 | [~ this]
59 | =^ cards agent (on-leave:ag path)
60 | [[(emit-event %on-leave path) cards] this]
61 | ::
62 | ++ on-peek
63 | |= =path
64 | ^- (unit (unit cage))
65 | %- (print bowl |.("{}: on-peek on path {}"))
66 | (on-peek:ag path)
67 | ::
68 | ++ on-agent
69 | |= [=wire =sign:agent:gall]
70 | ^- (quip card:agent:gall agent:gall)
71 | %- (print bowl |.("{}: on-agent on wire {}, {<-.sign>}"))
72 | =^ cards agent (on-agent:ag wire sign)
73 | [[(emit-event %on-agent wire -.sign) cards] this]
74 | ::
75 | ++ on-arvo
76 | |= [=wire =sign-arvo]
77 | ^- (quip card:agent:gall agent:gall)
78 | %- %+ print bowl |.
79 | "{}: on-arvo on wire {}, {<[- +<]:sign-arvo>}"
80 | =^ cards agent (on-arvo:ag wire sign-arvo)
81 | [[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this]
82 | ::
83 | ++ on-fail
84 | |= [=term =tang]
85 | ^- (quip card:agent:gall agent:gall)
86 | %- (print bowl |.("{}: on-fail with term {}"))
87 | =^ cards agent (on-fail:ag term tang)
88 | [[(emit-event %on-fail term) cards] this]
89 | --
90 | ::
91 | ++ print
92 | |= [=bowl:gall render=(trap tape)]
93 | ^+ same
94 | =? . bowl-print
95 | %- (slog >bowl< ~)
96 | .
97 | ?. loud same
98 | %- (slog [%leaf $:render] ~)
99 | same
100 | ::
101 | ++ emit-event
102 | |= =event:verb
103 | ^- card:agent:gall
104 | [%give %fact ~[/verb/events] %verb-event !>(event)]
105 | --
106 |
--------------------------------------------------------------------------------
/brainstorm.md:
--------------------------------------------------------------------------------
1 | [[urbit app]] idea: tags-notes-text
2 | pronounced tah-noh-teh
3 | [[tanote/tanote]]
4 |
5 | community knowledge manager
6 | Teaching Assistant
7 | note-taker
8 |
9 | Tags at top: set of tags. bold if selected for display filter (clicked). italic if tagged by currently selected note (in text of note after `#`). list of @p are pulled from %pals, or ride with notes shared by others to you (*id est*, you are named as a reader). bold @p for author of current version of note. italic @p for readers of current version of note. `*` displays all notes. `/` displays all notes with backlinks to the currently selected note. update when a version is added: when a local version is saved, when a note is shared (which also saves it), or when a version of a note is received. ~~each tag needs to store a list of notes which referred to it in any version.~~
10 |
11 | > * / *later* other **~ponhec-picwen** __*tanote*__ that
12 |
13 | ---
14 |
15 | Notes in middle: set of notes which match the tags selected for display filter. selected note (clicked) is bold. click on a note to switch to it. italic notes are those which still refer to the current note with a `[[]]` reference (backlink). updated when a version is added. ~~each note needs to maintain a list of other notes which referred to it in any version, and check whether the latest version still does.~~
16 |
17 | > **tanote idea**. *tanote literate program*. tanote overview. tanote use cases.
18 |
19 | ---
20 |
21 | Text versions at bottom: current note text, sharing tools. title is first line. list of authors that changed the text in second line. text in `[[]]` is taken to be other notes. text from `#` to space is taken to be a tag.
22 |
23 | *by* (read-only) is the writer of this version of the note. Change to self when the note is edited.
24 |
25 | _as_ is the name of the faction (_confer_ [[Yarvin 2007]]) of the point of view of the note.
26 |
27 | *to* is the set of readers (exclude writers) to which this is shared. Share the current note when someone is named as a reader, and the author clicks *to* (or moves to a different line).
28 |
29 | *re* is the title of the note. update title in list of notes when this is clicked (or when the author moves to a different line), which locally saves a version.
30 |
31 | *no* is a serial count of the version saved when this is clicked, and *of* is the highest version known. when a new version is received, increment *of* (read-only). if an existing version is entered and this is clicked, present that version. if a version that does not yet exist is entered and this is clicked, save the text as that version. when a note is selected, display the highest version known. not everyone's correspondences between version number and text will be the same, since they may edit without sharing, may be added later, and may receive versions in different orders.
32 |
33 | > by ~ponhec-picwen as creator
34 | > to
35 | > re tanote idea
36 | > no 1 of 1
37 | >
38 | > Would be really nice to #later write a [[tanote literate program]] (which refers back to this note) to implement the #tanote idea.
39 |
40 | ---
41 |
42 | tanote (group)
43 | - code
44 | - user
45 | - risk
46 | - test
47 |
48 | start with just chat, notebook, and links
49 |
50 | for each of curt: chat, notebook, and links
51 |
52 |
--------------------------------------------------------------------------------
/session Nocturna.md:
--------------------------------------------------------------------------------
1 | [[tanote/tanote]] [[session init]]
2 |
3 | General outline of the format of the screen.
4 |
5 | > tags and @ps
6 | >
7 | > names of notes. separated by periods. like sentences.
8 | >
9 | > headers of the text
10 | > body of the text
11 |
12 | The starting screen, before adding any version. The list of @ps comes from %pals. `|` represents the cursor at the start of a text entry field. Struck-out text is changeable. Highlighted text is clickable. Your own id is italic because it’s in the text of the note. The star should be bold, since it is selected by default, and highlighted, since it is clickable.
13 |
14 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==_~ponhec-picwen_==
15 | >
16 | >
17 | >
18 | > by ~ponhec-picwen as |
19 | > ==to== |
20 | > re |
21 | > ==no== ~~1~~ of 1
22 | >
23 | > |
24 |
25 | Name the note, add some text, set a recipient.
26 |
27 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==_~ponhec-picwen_==
28 | >
29 | >
30 | >
31 | > by ~ponhec-picwen as ~~muse~~
32 | > ==to== ~~`~`petlod-byrons~~
33 | > re ~~Nocturna~~
34 | > ==no== ~~1~~ of 1
35 | >
36 | > ~~She walks in beauty, like the night…~~
37 |
38 | ==no== saves the note, adding a version, if the version number is not already stored.
39 |
40 | Add tags and @ps automatically when a version is added, if not already known.
41 |
42 | Add note regards automatically when a version is added, if not already known. Bold the name of the current note.
43 |
44 | The text of the note is no longer editable.
45 |
46 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==~petlod-byrons== ==_~ponhec-picwen_== ==beauty== ==night==
47 | >
48 | > ==**Nocturna**==.
49 | >
50 | > by ~ponhec-picwen as muse
51 | > ==to== ~petlod-byrons
52 | > re Nocturna
53 | > ==no== 1 of 1
54 | >
55 | > She walks in #beauty, like the #night…
56 |
57 | Edit and resave to add another version and its tags and @ps.
58 |
59 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==_~petlod-byrons_== ==_~ponhec-picwen_== ==_beauty_== ==_bright_== ==_dark_== ==_day_== ==_Heaven_== ==_light_== ==_night_==
60 | >
61 | > ==**Nocturna**==.
62 | >
63 | > by ~ponhec-picwen as ~~poet~~
64 | > ==to== ~~`~`petlod-byrons~~
65 | > re ~~Nocturna~~
66 | > ==no== ~~2~~ of 2
67 | >
68 | > ~~She walks in #beauty, like the #night
69 | > of cloudless climes and starry skies
70 | > and all that’s best of #dark and #bright
71 | > meet in her aspect and her eyes
72 | > this mellow’d to that tender #light
73 | > which #Heaven to gaudy #day denies.~~
74 |
75 | Set the version field and click ==no== to switch back to the previous version.
76 |
77 | > ==`*`== ==~hatryx-lastud== ==~paldev== ==_~petlod-byrons_== ==_~ponhec-picwen_== ==_beauty_== ==bright== ==dark== ==day== ==Heaven== ==light== ==_night_==
78 | >
79 | > ==**Nocturna**==.
80 | >
81 | > by ~ponhec-picwen as muse
82 | > ==to== ~petlod-byrons
83 | > re Nocturna
84 | > ==no== 1 ==of== 2
85 | >
86 | > She walks in #beauty, like the #night…
87 |
88 | ==To== adds a version (if not already added), and sends the text to any named recipients. Re-sending an existing version adds a new version for the recipient.
89 |
90 | ==Of== lists, in the text section, the versions of the node available, each with the first line, or the (beginning of the) diff from the previous version.
91 |
92 | > 1 muse: She walks in #beauty, like the #night…
93 | > 2 poet: She walks in #beauty, like the #night~~...~~**of cloudless climes and starry skies**
94 |
95 |
--------------------------------------------------------------------------------
/tanote/lib/pill.hoon:
--------------------------------------------------------------------------------
1 | :: |pill: helper functions for making pills
2 | ::
3 | /- dice
4 | ^?
5 | |%
6 | ::
7 | +$ pill
8 | $% [%ivory p=(list)]
9 | $: %pill
10 | nam=term
11 | boot-ova=(list)
12 | kernel-ova=(list unix-event)
13 | userspace-ova=(list unix-event)
14 | == ==
15 | ::
16 | +$ unix-event
17 | %+ pair wire
18 | $% [%wack p=@]
19 | [%what p=(list (pair path (cask)))]
20 | [%whom p=ship]
21 | [%boot ? $%($>(%fake task:jael) $>(%dawn task:jael))]
22 | [%wyrd p=vere]
23 | [%verb p=(unit ?)]
24 | unix-task
25 | ==
26 | :: +boot-ovum: boostrap kernel filesystem load
27 | ::
28 | ++ boot-ovum
29 | |= [hoon=cord arvo=cord]
30 | :~ //arvo
31 | %what
32 | [/sys/hoon hoon/hoon]
33 | [/sys/arvo hoon/arvo]
34 | ==
35 | :: +file-ovum: userspace filesystem load
36 | ::
37 | :: bas: full path to / directory
38 | ::
39 | ++ file-ovum
40 | =/ directories=(list path)
41 | :~ /app :: %gall applications
42 | /gen :: :dojo generators
43 | /lib :: libraries
44 | /mar :: mark definitions
45 | /sur :: structures
46 | /sys :: system files
47 | /ted :: :spider strands
48 | /web :: %eyre web content
49 | /desk :: desk manifest
50 | ==
51 | |= [des=desk bas=path]
52 | ^- unix-event
53 | %. directories
54 | |= :: sal: all spurs to load from
55 | ::
56 | sal=(list spur)
57 | ^- unix-event
58 | ::
59 | :: hav: all user files
60 | ::
61 | =; hav ~& user-files+(lent hav)
62 | =/ =yuki:clay
63 | :- *(list tako:clay)
64 | %- ~(gas by *(map path (each page lobe:clay)))
65 | (turn hav |=([=path =page] [path &+page]))
66 | [/c/sync [%park des &+yuki *rang:clay]]
67 | =| hav=(list [path page])
68 | |- ^+ hav
69 | ?~ sal ~
70 | =. hav $(sal t.sal)
71 | ::
72 | :: tyl: spur
73 | ::
74 | =/ tyl i.sal
75 | |- ^+ hav
76 | ::
77 | :: pax: full path at `tyl`
78 | :: lon: directory at `tyl`
79 | ::
80 | =/ lyt (flop tyl)
81 | =/ pax (weld bas lyt)
82 | =/ lon .^(arch %cy pax)
83 | =? hav ?=(^ fil.lon)
84 | :_ hav
85 | :- lyt
86 | ?. ?=([%azimuth-snapshot *] tyl)
87 | [mark=;;(@tas (head tyl)) noun=.^(* %cx pax)]
88 | =; convert
89 | mime/(convert .^(snap-state:dice %cx pax))
90 | .^($-(snap-state:dice mime) %cf (weld bas /azimuth-snapshot/mime))
91 | =/ all ~(tap by dir.lon)
92 | |- ^+ hav
93 | ?~ all hav
94 | $(all t.all, hav ^$(tyl [p.i.all tyl]))
95 | ::
96 | :: +file-ovum2: electric boogaloo
97 | ::
98 | ++ file-ovum2 |=(p=path `unix-event`[//arvo what/(user-files p)])
99 | ::
100 | :: +user-files: all userspace hoon files
101 | ::
102 | ++ user-files
103 | |= bas=path
104 | %. directories:file-ovum
105 | |= sal=(list spur)
106 | ^- (list (pair path (cask)))
107 | ::
108 | :: hav: all user files
109 | ::
110 | =| hav=(list (pair path (cask)))
111 | |- ^+ hav
112 | ?~ sal ~
113 | =. hav $(sal t.sal)
114 | ::
115 | :: tyl: spur
116 | ::
117 | =/ tyl i.sal
118 | |- ^+ hav
119 | ::
120 | :: pax: full path at `tyl`
121 | :: lon: directory at `tyl`
122 | ::
123 | =/ pax (weld bas (flop tyl))
124 | =/ lon .^(arch %cy pax)
125 | =? hav ?=(^ fil.lon)
126 | ::
127 | :: install only hoon files for now
128 | ::
129 | ?. ?=([%hoon *] tyl)
130 | hav
131 | :_ hav
132 | [(flop `path`t.tyl) hoon/.^(@t %cx pax)]
133 | ::
134 | =/ all ~(tap by dir.lon)
135 | |- ^+ hav
136 | ?~ all hav
137 | $(all t.all, hav ^$(tyl [p.i.all tyl]))
138 | --
139 |
--------------------------------------------------------------------------------
/tanote/gen/help.hoon:
--------------------------------------------------------------------------------
1 | /+ tanote
2 | :- %say
3 | |= *
4 | :- %noun
5 | =/ note0=note:tanote [~ponhec-picwen "reviewer" [0x0 ~ponhec-picwen] ~ "note" "A note is composed of several #field: by, as, if, to, re, and text."]
6 | =/ note-history=history:tanote (add-note-history:tanote note0 ["note" ~])
7 | =/ history0=note:tanote [~ponhec-picwen "reviewer" [0x0 ~ponhec-picwen] ~ "history" "A history is a list of notes, with the latest note first; and a regards, which is the same as the re #field of each note."]
8 | =/ history-history=history:tanote (add-note-history:tanote history0 ["history" ~])
9 | =/ history1=note:tanote [~ponhec-picwen "reviewer" [0x0 ~ponhec-picwen] ~ "history" "A [[history]] is a #list of notes, with the latest [[note]] first; and a [[regards]], which a #tape (text string) that is the same as the [[re]] field of each [[note]]."]
10 | =/ updated-history-history=history:tanote (add-note-history:tanote history1 history-history)
11 | =/ store0=note:tanote [~ponhec-picwen "reviewer" [0x0 ~ponhec-picwen] ~ "store" "A store is a list of histories."]
12 | =/ store-history=history:tanote (add-note-history:tanote store0 ["store" ~])
13 | =/ help0=store:tanote (add-note-store:tanote note0 (add-note-store:tanote history0 (add-note-store:tanote store0 ~)))
14 | =/ help1=store:tanote (add-note-store:tanote history1 help0)
15 | =/ all0=front:tanote [tab="default" tags=~ tugs=~ regards=~ histories=help0]
16 | =/ all1=front:tanote [tab="default" tags=~ tugs=~ regards=~ histories=help1]
17 | =/ filter-regards0=front:tanote (filter-front-regards:tanote [tab="histories" tags=~ tugs=~ regards="history" histories=help0])
18 | =/ filter-field1=front:tanote (filter-front-tugs:tanote [tab="field" tags=~ tugs=(sy ~["#field"]) regards=~ histories=help1])
19 | :- =(note-history ["note" ~[note0]])
20 | :- =(history-history ["history" ~[history0]])
21 | :- =(store-history ["store" ~[store0]])
22 | :- help0
23 | :- .= help0
24 | ~[note-history history-history store-history]
25 | :- .= (extract-tags-store:tanote help0)
26 | (sy ~["#field"])
27 | :- .= (extract-backlinks-store:tanote help0)
28 | (sy ~["reviewer"])
29 | :- (filter-store-tag:tanote help0 "#field")
30 | :- .= (filter-store-tag:tanote help0 "#field")
31 | ~[history-history note-history]
32 | :- (find-store-regards:tanote help0 "history")
33 | :- .= (find-store-regards:tanote help0 "history")
34 | history-history
35 | :- =(updated-history-history ["history" ~[history1 history0]])
36 | :- help1
37 | :- .= help1
38 | ~[store-history updated-history-history note-history]
39 | :- .= (extract-tags-store:tanote help1)
40 | (sy ~["#field" "#list" "#tape"])
41 | :- .= (extract-backlinks-store:tanote help1)
42 | (sy ~["reviewer" "history" "note" "regards" "re" "note"])
43 | :- (filter-store-tag:tanote help1 "#field")
44 | :- .= (filter-store-tag:tanote help1 "#field")
45 | ~[note-history]
46 | :- (find-store-regards:tanote help1 "history")
47 | :- .= (find-store-regards:tanote help1 "history")
48 | updated-history-history
49 | :- (display-tags:tanote help0)
50 | :- .= (display-tags:tanote help0)
51 | (sy ~["*" "/" "#field"])
52 | :- (display-tags:tanote help1)
53 | :- .= (display-tags:tanote help1)
54 | (sy ~["*" "/" "#field" "#list" "#tape"])
55 | :- (display-backlinks:tanote help0)
56 | :- .= (display-backlinks:tanote help0)
57 | (sy ~["reviewer"])
58 | :- (display-backlinks:tanote help1)
59 | :- .= (display-backlinks:tanote help1)
60 | (sy ~["reviewer" "history" "note" "regards" "re" "note"])
61 | :- (list-regards-store:tanote help0)
62 | :- .= (list-regards-store:tanote help0)
63 | ~["store" "history" "note"]
64 | :- all0
65 | :- .= histories.all0
66 | help0
67 | :- .= (list-regards-store:tanote histories.all0)
68 | ~["store" "history" "note"]
69 | :- all1
70 | :- .= histories.all1
71 | help1
72 | :- .= (list-regards-store:tanote histories.all1)
73 | ~["note" "history" "store"]
74 | :- filter-regards0
75 | :- .= filter-regards0
76 | [tab="histories" tags=~ tugs=~ regards="history" histories=~[history-history]]
77 | :- filter-field1
78 | ~
79 | :: DO NOT EDIT THIS FILE. Auto-generated from verbose help.md by lit.
80 |
--------------------------------------------------------------------------------
/interfaces.md:
--------------------------------------------------------------------------------
1 | # Tanote interfaces
2 |
3 | ## graph store
4 |
5 | ### note version structure
6 |
7 | An @p called `by`, which is the identity of the author of this version of the note. This field is considered a tag of this version of the note.
8 |
9 | A tape called `as`, which is the faction (_confer_ [[Yarvin 2007]]), or the point of view, of this version of the note. This field is considered a tag of this version of the note.
10 |
11 | A cell called `if`, with a @ux and an @p, which store the number and ship of the source of a gora. If the @ux is not 0, then this gora is checked before a note version is received (naïve approach) or sent (jaded approach). Both the @ux and @p are considered tags of this version of the note.
12 |
13 | A list of @p called `to`, which is the list of recipients of this version of the note.
14 |
15 | A tape called `re`, which is the regards, or subject, or title of the note.
16 |
17 | A tape called `text`, which is the body of this version of the note. Tags (`#tag`) in the text are considered tags of this version of the note. Backlinks ([[back link]]) in the text are references to the `regards` of other histories.
18 |
19 | See also the [[tanote/glossary]].
20 |
21 | ### history structure
22 |
23 | A tape called `regards`, which is the `re` field of each note. All the note versions wich the same `re` are stored together in one history, with a single `regards`.
24 |
25 | A list of notes, called `versions`. The most recent note is first, and the remainder of the notes are in reverse-chronological order, as seen on this ship.
26 |
27 | ### store structure
28 |
29 | A list of histories, each with a different `regards`.
30 |
31 | ## libraries
32 |
33 | ### tanote
34 |
35 | [[tanote/tanote/lib/tanote]] contains the data structure of a note version, history, and store, and the arms which work with them.
36 |
37 | ### tanote-ames
38 |
39 | Send a note version to another ship.
40 |
41 | Receive a note version from another ship.
42 |
43 | ### tanote-gall
44 |
45 | Tanote as an application or agent.
46 |
47 | ### tanote-gora
48 |
49 | Check for the existence of a gora.
50 |
51 | ### tanote-graphstore
52 |
53 | Preserve the contents of a store.
54 |
55 | Load a preserved store to a running store.
56 |
57 | ## generators
58 |
59 | ### help
60 |
61 | [[help]] generates notes which describe usage and internals of the %tanote desk.
62 |
63 | ### testlib
64 |
65 | [[testlib]] generates the results of tests of arms of the [[tanote/tanote/lib/tanote]] library.
66 |
67 | ## front end
68 |
69 | Front end in three parts, split into three horizontal sections, one atop another.
70 |
71 | ### top section: tags
72 |
73 | First, all the tags, listed one after another as a paragraph.
74 |
75 | Each tag may separately be selected, which determines which notes are displayed in the second section. Selected tags are set in bold.
76 |
77 | Default tags are `*` (display all notes), `/` (display all notes with backlinks to the selected note), and the @p of our ship.
78 |
79 | ### middle section: note regards
80 |
81 | Second, a paragraph which displays a list of regards, of notes which have the selected tags in the text of the latest version.
82 |
83 | One note may be selected, which determines which note or history is displayed in the third section.
84 |
85 | Displayed notes which have backlinks to the selected note are set in italics.
86 |
87 | ### bottom section: note version(s)
88 |
89 | Third, a version of the selected note (a paragraph of metadata, and the text as it is formatted by the user), or a list of all the versions of the selected note.
90 |
91 | The metadata contains the generated phrase “==no== # ==of== #“. The first number is the count (the earliest version is 1) of this version in the `versions` list of the note’s history. The second version is the number of versions in the note’s history.
92 |
93 | Some fields in this section are editable, which buffers another version of the note and increments the note version. The buffered changes are saved as a new version when the button ==no== is clicked. Clicking on the button-word ==no== adds the buffered version to the beginning of the note’s history, which becomes the most recent version of the note.
94 |
95 | Clicking on the button-word ==of== displays the list of versions of this note. One of these may be selected to display that version of the note.
96 |
97 |
--------------------------------------------------------------------------------
/tanote/lib/bitcoin-utils.hoon:
--------------------------------------------------------------------------------
1 | :: lib/bitcoin-utils.hoon
2 | :: Utilities for working with BTC data types and transactions
3 | ::
4 | /- *bitcoin
5 | ~% %bitcoin-utils-lib ..part ~
6 | |%
7 | ::
8 | :: TODO: move this bit/byt stuff to zuse
9 | :: bit/byte utilities
10 | ::
11 | ::
12 | :: +blop: munge bit and byt sequences (cat, flip, take, drop)
13 | ::
14 | ++ blop
15 | ~/ %blop
16 | |_ =bloq
17 | +$ biyts [wid=@ud dat=@]
18 | ++ cat
19 | |= bs=(list biyts)
20 | ^- biyts
21 | :- (roll (turn bs |=(b=biyts -.b)) add)
22 | (can bloq (flop bs))
23 | :: +flip: flip endianness while preserving lead/trail zeroes
24 | ::
25 | ++ flip
26 | |= b=biyts
27 | ^- biyts
28 | [wid.b (rev bloq b)]
29 | :: +take: take n bloqs from front
30 | :: pads front with extra zeroes if n is longer than input
31 | ::
32 | ++ take
33 | |= [n=@ b=biyts]
34 | ^- biyts
35 | ?: (gth n wid.b)
36 | [n dat.b]
37 | [n (rsh [bloq (sub wid.b n)] dat.b)]
38 | :: +drop: drop n bloqs from front
39 | :: returns 0^0 if n >= width
40 | ::
41 | ++ drop
42 | |= [n=@ b=biyts]
43 | ^- biyts
44 | ?: (gte n wid.b)
45 | 0^0x0
46 | =+ n-take=(sub wid.b n)
47 | [n-take (end [bloq n-take] dat.b)]
48 | --
49 | ++ byt ~(. blop 3)
50 | ::
51 | ++ bit
52 | ~/ %bit
53 | =/ bl ~(. blop 0)
54 | |%
55 | ++ cat cat:bl:bit
56 | ++ flip flip:bl:bit
57 | ++ take take:bl:bit
58 | ++ drop drop:bl:bit
59 | ++ from-atoms
60 | |= [bitwidth=@ digits=(list @)]
61 | ^- bits
62 | %- cat:bit
63 | %+ turn digits
64 | |= a=@
65 | ?> (lte (met 0 a) bitwidth)
66 | [bitwidth `@ub`a]
67 | :: +to-atoms: convert bits to atoms of bitwidth
68 | ::
69 | ++ to-atoms
70 | |= [bitwidth=@ bs=bits]
71 | ^- (list @)
72 | =| res=(list @)
73 | ?> =(0 (mod wid.bs bitwidth))
74 | |-
75 | ?: =(0 wid.bs) res
76 | %= $
77 | res (snoc res dat:(take:bit bitwidth bs))
78 | bs (drop:bit bitwidth bs)
79 | ==
80 | --
81 | :: big endian sha256: input and output are both MSB first (big endian)
82 | ::
83 | ++ sha256
84 | ~/ %sha256
85 | |= =byts
86 | ^- hexb
87 | %- flip:byt
88 | [32 (shay (flip:byt byts))]
89 | ::
90 | ++ dsha256
91 | ~/ %dsha256
92 | |= =byts
93 | (sha256 (sha256 byts))
94 | ::
95 | ++ hash-160
96 | ~/ %hash-160
97 | |= val=byts
98 | ^- hexb
99 | =, ripemd:crypto
100 | :- 20
101 | %- ripemd-160
102 | (sha256 val)
103 |
104 | ::
105 | :: hxb: hex parsing utilities
106 | ::
107 | ++ hxb
108 | ~% %hxb ..blop ~
109 | |%
110 | ++ from-cord
111 | ~/ %from-cord
112 | |= h=@t
113 | ^- hexb
114 | ?: =('' h) 1^0x0
115 | :: Add leading 00
116 | ::
117 | =+ (lsh [3 2] h)
118 | :: Group by 4-size block
119 | ::
120 | =+ (rsh [3 2] -)
121 | :: Parse hex to atom
122 | ::
123 | =/ a (need (de:base16:mimes:html -))
124 | [-.a `@ux`+.a]
125 | ::
126 | ++ to-cord
127 | ~/ %to-cord
128 | |= =hexb
129 | ^- cord
130 | (en:base16:mimes:html hexb)
131 | --
132 | ::
133 | :: +csiz: CompactSize integers (a Bitcoin-specific datatype)
134 | :: https://btcinformation.org/en/developer-reference#compactsize-unsigned-integers
135 | :: - encode: big endian to little endian
136 | :: - decode: little endian to big endian
137 | ::
138 | ++ csiz
139 | ~% %csiz ..blop ~
140 | |%
141 | ++ en
142 | ~/ %en
143 | |= a=@
144 | ^- hexb
145 | =/ l=@ (met 3 a)
146 | ?: =(l 1) 1^a
147 | ?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)])
148 | ?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)])
149 | ?: (lte l 8) (cat:byt ~[1^0xff (flip:byt 8^a)])
150 | ~|("Cannot encode CompactSize longer than 8 bytes" !!)
151 | ::
152 | ++ de
153 | ~/ %de
154 | |= h=hexb
155 | ^- [n=hexb rest=hexb]
156 | =/ s=@ux dat:(take:byt 1 h)
157 | ?: (lth s 0xfd) [1^s (drop:byt 1 h)]
158 | ~| "Invalid compact-size at start of {}"
159 | =/ len=bloq
160 | ?+ s !!
161 | %0xfd 1
162 | %0xfe 2
163 | %0xff 3
164 | ==
165 | :_ (drop:byt (add 1 len) h)
166 | %- flip:byt
167 | (take:byt (bex len) (drop:byt 1 h))
168 | :: +dea: atom instead of hexb for parsed CompactSize
169 | ::
170 | ++ dea
171 | |= h=hexb
172 | ^- [a=@ rest=hexb]
173 | => (de h)
174 | [dat.n rest]
175 | --
176 | --
177 |
--------------------------------------------------------------------------------
/tanote/lib/sole.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/sole/lib
3 | ::
4 | /? 310
5 | /- *sole
6 | ::::
7 | ::
8 | |_ sole-share :: shared-state engine
9 | ++ abet +<
10 | ++ apply
11 | |= ted=sole-edit
12 | ^+ +>
13 | ?- -.ted
14 | %del +>.$(buf (weld (scag p.ted buf) (slag +(p.ted) buf)))
15 | %ins +>.$(buf (weld (scag p.ted buf) `_buf`[q.ted (slag p.ted buf)]))
16 | %mor |- ^+ +>.^$
17 | ?~ p.ted
18 | +>.^$
19 | $(p.ted t.p.ted, +>.^$ ^$(ted i.p.ted))
20 | %nop +>.$
21 | %set +>.$(buf p.ted)
22 | ==
23 | ::
24 | ::::
25 | :: ++transmute: symmetric operational transformation.
26 | ::
27 | :: for any sole state +>, obeys
28 | ::
29 | :: =+ [x=(transmute a b) y=(transmute b a)]
30 | :: .= (apply:(apply a) x)
31 | :: (apply:(apply b) y)
32 | ::
33 | ++ transmute :: dex as after sin
34 | |= [sin=sole-edit dex=sole-edit]
35 | ~| [%transmute sin dex]
36 | ^- sole-edit
37 | ?: ?=(%mor -.sin)
38 | |- ^- sole-edit
39 | ?~ p.sin dex
40 | $(p.sin t.p.sin, dex ^$(sin i.p.sin))
41 | ::
42 | ?: ?=(%mor -.dex)
43 | :- %mor
44 | |- ^- (list sole-edit)
45 | ?~ p.dex ~
46 | [^$(dex i.p.dex) $(p.dex t.p.dex)]
47 | ::
48 | ?: |(?=(%nop -.sin) ?=(%nop -.dex)) dex
49 | ?: ?=(%set -.sin) [%nop ~]
50 | ?: ?=(%set -.dex) dex
51 | ::
52 | ?- -.sin
53 | %del
54 | ?- -.dex
55 | %del ?: =(p.sin p.dex) [%nop ~]
56 | ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex)
57 | %ins ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex)
58 | ==
59 | ::
60 | %ins
61 | ?- -.dex
62 | %del ?:((lte p.sin p.dex) dex(p +(p.dex)) dex)
63 | %ins ?: =(p.sin p.dex)
64 | ?:((lth q.sin q.dex) dex dex(p +(p.dex)))
65 | ?:((lte p.sin p.dex) dex(p +(p.dex)) dex)
66 | ==
67 | ==
68 | ::
69 | ++ commit :: local change
70 | |= ted=sole-edit
71 | ^- sole-share
72 | abet:(apply(own.ven +(own.ven), leg [ted leg]) ted)
73 | ::
74 | ::::
75 | :: ++inverse: inverse of change in context.
76 | ::
77 | :: for any sole state +>, obeys
78 | ::
79 | :: =(+> (apply:(apply a) (inverse a)))
80 | ::
81 | ++ inverse :: relative inverse
82 | |= ted=sole-edit
83 | ^- sole-edit
84 | =. ted ?.(?=([%mor * ~] ted) ted i.p.ted)
85 | ?- -.ted
86 | %del [%ins p.ted (snag p.ted buf)]
87 | %ins [%del p.ted]
88 | %mor :- %mor
89 | %- flop
90 | |- ^- (list sole-edit)
91 | ?~ p.ted ~
92 | :- ^$(ted i.p.ted)
93 | $(p.ted t.p.ted, +>.^$ (apply i.p.ted))
94 | %nop [%nop ~]
95 | %set [%set buf]
96 | ==
97 | ::
98 | ++ receive :: naturalize event
99 | |= sole-change
100 | ^- [sole-edit sole-share]
101 | ?. &(=(his.ler his.ven) (lte own.ler own.ven))
102 | ~| [%receive-sync his+[his.ler his.ven] own+[own.ler own.ven]]
103 | !!
104 | ?> &(=(his.ler his.ven) (lte own.ler own.ven))
105 | ?> |(!=(own.ler own.ven) =(`@`0 haw) =(haw (sham buf)))
106 | =. leg (scag (sub own.ven own.ler) leg)
107 | :: ~? !=(own.ler own.ven) [%miss-leg leg]
108 | =+ dat=(transmute [%mor leg] ted)
109 | :: ~? !=(~ leg) [%transmute from+ted to+dat ~]
110 | [dat abet:(apply(his.ven +(his.ven)) dat)]
111 | ::
112 | ++ remit :: conditional accept
113 | |= [cal=sole-change ask=$-((list @c) ?)]
114 | ^- [(unit sole-change) sole-share]
115 | =+ old=buf
116 | =^ dat +>+<.$ (receive cal)
117 | ?: (ask buf)
118 | [~ +>+<.$]
119 | =^ lic +>+<.$ (transmit (inverse(buf old) dat))
120 | [`lic +>+<.$]
121 | ::
122 | ++ transmit :: outgoing change
123 | |= ted=sole-edit
124 | ^- [sole-change sole-share]
125 | [[[his.ven own.ven] (sham buf) ted] (commit ted)]
126 | ::
127 | ++ transceive :: receive and invert
128 | |= sole-change
129 | ^- [sole-edit sole-share]
130 | =+ old=buf
131 | =^ dat +>+<.$ (receive +<.$)
132 | [(inverse(buf old) dat) +>+<.$]
133 | ::
134 | ++ transpose :: adjust position
135 | |= pos=@ud
136 | =+ dat=(transmute [%mor leg] [%ins pos `@c`0])
137 | ?> ?=(%ins -.dat)
138 | p.dat
139 | --
140 |
--------------------------------------------------------------------------------
/tanote/lib/bip/b174.hoon:
--------------------------------------------------------------------------------
1 | :: BIP174: PSBTs
2 | :: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
3 | ::
4 | /- sur=bitcoin
5 | /+ bcu=bitcoin-utils
6 | =, sur
7 | =, bcu
8 | |%
9 | ++ en
10 | |%
11 | ++ globals
12 | |= rawtx=hexb
13 | ^- map:psbt
14 | :~ [[1 0x0] rawtx]
15 | ==
16 | ::
17 | ++ input
18 | |= [only-witness=? i=in:psbt]
19 | ^- map:psbt
20 | %+ weld
21 | ?: only-witness ~
22 | ~[[1^0x0 rawtx.i]]
23 | :~ (witness-tx i)
24 | (hdkey %input hdkey.i)
25 | ==
26 | ::
27 | ++ output
28 | |= =out:psbt
29 | ^- map:psbt
30 | ?~ hk.out ~
31 | :~ (hdkey %output u.hk.out)
32 | ==
33 | ::
34 | ++ witness-tx
35 | |= i=in:psbt
36 | ^- keyval:psbt
37 | :- [1 0x1]
38 | %- cat:byt
39 | :~ (flip:byt 8^value.utxo.i)
40 | 1^0x16
41 | 2^0x14
42 | (hash-160 pubkey.hdkey.i)
43 | ==
44 | ::
45 | ++ hdkey
46 | |= [=target:psbt h=^hdkey]
47 | ^- keyval:psbt
48 | =/ typ=@ux
49 | ?- target
50 | %input 0x6
51 | %output 0x2
52 | ==
53 | =/ coin-type=hexb
54 | ?- network.h
55 | %main
56 | 1^0x0
57 | %testnet
58 | 1^0x1
59 | ==
60 | :- (cat:byt ~[1^typ pubkey.h])
61 | %- cat:byt
62 | :~ fprint.h
63 | 1^`@ux`bipt.h 3^0x80
64 | coin-type 3^0x80
65 | 4^0x80
66 | 1^`@ux`chyg.h 3^0x0
67 | (flip:byt 4^idx.h)
68 | ==
69 | ::
70 | ++ keyval-byts
71 | |= kv=keyval:psbt
72 | ^- hexb
73 | %- cat:byt
74 | :~ 1^wid.key.kv
75 | key.kv
76 | 1^wid.val.kv
77 | val.kv
78 | ==
79 | ::
80 | ++ map-byts
81 | |= m=map:psbt
82 | ^- (unit hexb)
83 | ?~ m ~
84 | :- ~
85 | %- cat:byt
86 | (turn m keyval-byts)
87 | --
88 | ++ base64
89 | |= b=hexb
90 | ^- base64:psbt
91 | %- en:base64:mimes:html
92 | (flip:byt b)
93 | :: +encode: make base64 cord of PSBT
94 | :: - only-witness: don't include non-witness UTXO
95 | ::
96 | ++ encode
97 | |= $: only-witness=?
98 | rawtx=hexb
99 | txid=hexb
100 | inputs=(list in:psbt)
101 | outputs=(list out:psbt)
102 | ==
103 | ^- base64:psbt
104 | =/ sep=(unit hexb) `1^0x0
105 | =/ final=(list (unit hexb))
106 | %+ join sep
107 | %+ turn
108 | %- zing
109 | :~ ~[(globals:en rawtx)]
110 | (turn inputs (cury input:en only-witness))
111 | (turn outputs output:en)
112 | ==
113 | map-byts:en
114 | %- base64:en
115 | ^- byts
116 | %- cat:byt
117 | %+ weld ~[[5 0x70.7362.74ff]]
118 | (murn (snoc final sep) same)
119 | ::
120 | ++ parse
121 | |= psbt-base64=cord
122 | ^- (list map:psbt)
123 | =/ todo=hexb
124 | (drop:byt 5 (to-byts psbt-base64))
125 | =| acc=(list map:psbt)
126 | =| m=map:psbt
127 | |-
128 | ?: =(wid.todo 0)
129 | (snoc acc m)
130 | :: 0x0: map separator
131 | ::
132 | ?: =(1^0x0 (take:byt 1 todo))
133 | $(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo))
134 | =^ kv todo (next-keyval todo)
135 | $(m (snoc m kv))
136 | :: +get-txid: extract txid from a valid PSBT
137 | ::
138 | ++ get-txid
139 | |= psbt-base64=cord
140 | ^- hexb
141 | =/ tx=hexb
142 | %- raw-tx
143 | %+ drop:byt 5
144 | (to-byts psbt-base64)
145 | %- flip:byt
146 | (dsha256 tx)
147 | :: +raw-tx: extract hex transaction
148 | :: looks for key 0x0 in global map
149 | :: crashes if tx not in hex
150 | ::
151 | ++ raw-tx
152 | |= b=hexb
153 | ^- hexb
154 | |-
155 | ?: =(wid.b 0) !!
156 | ?: =(1^0x0 (take:byt 1 b)) !!
157 | =/ nk (next-keyval b)
158 | ?: =(0x0 dat.key.kv.nk)
159 | val.kv.nk
160 | $(b rest.nk)
161 | :: +next-keyval: returns next key-val in a PSBT map
162 | :: input first byte must be a map key length
163 | ::
164 | ++ next-keyval
165 | |= b=hexb
166 | ^- [kv=keyval:psbt rest=hexb]
167 | =/ klen dat:(take:byt 1 b)
168 | =/ k (take:byt klen (drop:byt 1 b))
169 | =/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b))
170 | =/ v (take:byt vlen (drop:byt (add 2 klen) b))
171 | ?> ?&((gth wid.k 0) (gth wid.v 0))
172 | :- [k v]
173 | (drop:byt ;:(add 2 klen vlen) b)
174 | ::
175 | ++ to-byts
176 | |= psbt-base64=cord
177 | ^- hexb
178 | ~| "Invalid PSBT"
179 | =+ p=(de:base64:mimes:html psbt-base64)
180 | ?~ p !!
181 | (flip:byt u.p)
182 | --
183 |
--------------------------------------------------------------------------------
/tanote/lib/dbug.hoon:
--------------------------------------------------------------------------------
1 | :: dbug: agent wrapper for generic debugging tools
2 | ::
3 | :: usage: %-(agent:dbug your-agent)
4 | ::
5 | |%
6 | +$ poke
7 | $% [%bowl ~]
8 | [%state grab=cord]
9 | [%incoming =about]
10 | [%outgoing =about]
11 | ==
12 | ::
13 | +$ about
14 | $@ ~
15 | $% [%ship =ship]
16 | [%path =path]
17 | [%wire =wire]
18 | [%term =term]
19 | ==
20 | ::
21 | ++ agent
22 | |= =agent:gall
23 | ^- agent:gall
24 | !.
25 | |_ =bowl:gall
26 | +* this .
27 | ag ~(. agent bowl)
28 | ::
29 | ++ on-poke
30 | |= [=mark =vase]
31 | ^- (quip card:agent:gall agent:gall)
32 | ?. ?=(%dbug mark)
33 | =^ cards agent (on-poke:ag mark vase)
34 | [cards this]
35 | =/ dbug
36 | !<(poke vase)
37 | =; =tang
38 | ((%*(. slog pri 1) tang) [~ this])
39 | ?- -.dbug
40 | %bowl [(sell !>(bowl))]~
41 | ::
42 | %state
43 | =? grab.dbug =('' grab.dbug) '-'
44 | =; product=^vase
45 | [(sell product)]~
46 | =/ state=^vase
47 | :: if the underlying app has implemented a /dbug/state scry endpoint,
48 | :: use that vase in place of +on-save's.
49 | ::
50 | =/ result=(each ^vase tang)
51 | (mule |.(q:(need (need (on-peek:ag /x/dbug/state)))))
52 | ?:(?=(%& -.result) p.result on-save:ag)
53 | %+ slap
54 | (slop state !>([bowl=bowl ..zuse]))
55 | (ream grab.dbug)
56 | ::
57 | %incoming
58 | =; =tang
59 | ?^ tang tang
60 | [%leaf "no matching subscriptions"]~
61 | %+ murn
62 | %+ sort ~(tap by sup.bowl)
63 | |= [[* a=[=ship =path]] [* b=[=ship =path]]]
64 | (aor [path ship]:a [path ship]:b)
65 | |= [=duct [=ship =path]]
66 | ^- (unit tank)
67 | =; relevant=?
68 | ?. relevant ~
69 | `>[path=path from=ship duct=duct]<
70 | ?: ?=(~ about.dbug) &
71 | ?- -.about.dbug
72 | %ship =(ship ship.about.dbug)
73 | %path ?=(^ (find path.about.dbug path))
74 | %wire %+ lien duct
75 | |=(=wire ?=(^ (find wire.about.dbug wire)))
76 | %term !!
77 | ==
78 | ::
79 | %outgoing
80 | =; =tang
81 | ?^ tang tang
82 | [%leaf "no matching subscriptions"]~
83 | %+ murn
84 | %+ sort ~(tap by wex.bowl)
85 | |= [[[a=wire *] *] [[b=wire *] *]]
86 | (aor a b)
87 | |= [[=wire =ship =term] [acked=? =path]]
88 | ^- (unit tank)
89 | =; relevant=?
90 | ?. relevant ~
91 | `>[wire=wire agnt=[ship term] path=path ackd=acked]<
92 | ?: ?=(~ about.dbug) &
93 | ?- -.about.dbug
94 | %ship =(ship ship.about.dbug)
95 | %path ?=(^ (find path.about.dbug path))
96 | %wire ?=(^ (find wire.about.dbug wire))
97 | %term =(term term.about.dbug)
98 | ==
99 | ==
100 | ::
101 | ++ on-peek
102 | |= =path
103 | ^- (unit (unit cage))
104 | ?. ?=([@ %dbug *] path)
105 | (on-peek:ag path)
106 | ?+ path [~ ~]
107 | [%u %dbug ~] ``noun+!>(&)
108 | [%x %dbug %state ~] ``noun+!>(on-save:ag)
109 | [%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl)
110 | ==
111 | ::
112 | ++ on-init
113 | ^- (quip card:agent:gall agent:gall)
114 | =^ cards agent on-init:ag
115 | [cards this]
116 | ::
117 | ++ on-save on-save:ag
118 | ::
119 | ++ on-load
120 | |= old-state=vase
121 | ^- (quip card:agent:gall agent:gall)
122 | =^ cards agent (on-load:ag old-state)
123 | [cards this]
124 | ::
125 | ++ on-watch
126 | |= =path
127 | ^- (quip card:agent:gall agent:gall)
128 | =^ cards agent (on-watch:ag path)
129 | [cards this]
130 | ::
131 | ++ on-leave
132 | |= =path
133 | ^- (quip card:agent:gall agent:gall)
134 | =^ cards agent (on-leave:ag path)
135 | [cards this]
136 | ::
137 | ++ on-agent
138 | |= [=wire =sign:agent:gall]
139 | ^- (quip card:agent:gall agent:gall)
140 | =^ cards agent (on-agent:ag wire sign)
141 | [cards this]
142 | ::
143 | ++ on-arvo
144 | |= [=wire =sign-arvo]
145 | ^- (quip card:agent:gall agent:gall)
146 | =^ cards agent (on-arvo:ag wire sign-arvo)
147 | [cards this]
148 | ::
149 | ++ on-fail
150 | |= [=term =tang]
151 | ^- (quip card:agent:gall agent:gall)
152 | =^ cards agent (on-fail:ag term tang)
153 | [cards this]
154 | --
155 | --
156 |
--------------------------------------------------------------------------------
/tanote/lib/server.hoon:
--------------------------------------------------------------------------------
1 | =, eyre
2 | |%
3 | +$ request-line
4 | $: [ext=(unit @ta) site=(list @t)]
5 | args=(list [key=@t value=@t])
6 | ==
7 | :: +parse-request-line: take a cord and parse out a url
8 | ::
9 | ++ parse-request-line
10 | |= url=@t
11 | ^- request-line
12 | (fall (rush url ;~(plug apat:de-purl:html yque:de-purl:html)) [[~ ~] ~])
13 | ::
14 | ++ manx-to-octs
15 | |= man=manx
16 | ^- octs
17 | (as-octt:mimes:html (en-xml:html man))
18 | ::
19 | ++ json-to-octs
20 | |= jon=json
21 | ^- octs
22 | (as-octt:mimes:html (en-json:html jon))
23 | ::
24 | ++ app
25 | |%
26 | ::
27 | :: +require-authorization:
28 | :: redirect to the login page when unauthenticated
29 | :: otherwise call handler on inbound request
30 | ::
31 | ++ require-authorization
32 | |= $: =inbound-request:eyre
33 | handler=$-(inbound-request:eyre simple-payload:http)
34 | ==
35 | ^- simple-payload:http
36 | ::
37 | ?: authenticated.inbound-request
38 | ~! this
39 | ~! +:*handler
40 | (handler inbound-request)
41 | ::
42 | =- [[307 ['location' -]~] ~]
43 | %^ cat 3
44 | '/~/login?redirect='
45 | url.request.inbound-request
46 | ::
47 | :: +require-authorization-simple:
48 | :: redirect to the login page when unauthenticated
49 | :: otherwise pass through simple-paylod
50 | ::
51 | ++ require-authorization-simple
52 | |= [=inbound-request:eyre =simple-payload:http]
53 | ^- simple-payload:http
54 | ::
55 | ?: authenticated.inbound-request
56 | ~! this
57 | simple-payload
58 | ::
59 | =- [[307 ['location' -]~] ~]
60 | %^ cat 3
61 | '/~/login?redirect='
62 | url.request.inbound-request
63 | ::
64 | ++ give-simple-payload
65 | |= [eyre-id=@ta =simple-payload:http]
66 | ^- (list card:agent:gall)
67 | =/ header-cage
68 | [%http-response-header !>(response-header.simple-payload)]
69 | =/ data-cage
70 | [%http-response-data !>(data.simple-payload)]
71 | :~ [%give %fact ~[/http-response/[eyre-id]] header-cage]
72 | [%give %fact ~[/http-response/[eyre-id]] data-cage]
73 | [%give %kick ~[/http-response/[eyre-id]] ~]
74 | ==
75 | --
76 | ++ gen
77 | |%
78 | ::
79 | ++ max-1-da ['cache-control' 'max-age=86400']
80 | ++ max-1-wk ['cache-control' 'max-age=604800']
81 | ::
82 | ++ html-response
83 | =| cache=?
84 | |= =octs
85 | ^- simple-payload:http
86 | :_ `octs
87 | [200 [['content-type' 'text/html'] ?:(cache [max-1-wk ~] ~)]]
88 | ::
89 | ++ css-response
90 | =| cache=?
91 | |= =octs
92 | ^- simple-payload:http
93 | :_ `octs
94 | [200 [['content-type' 'text/css'] ?:(cache [max-1-wk ~] ~)]]
95 | ::
96 | ++ js-response
97 | =| cache=?
98 | |= =octs
99 | ^- simple-payload:http
100 | :_ `octs
101 | [200 [['content-type' 'text/javascript'] ?:(cache [max-1-wk ~] ~)]]
102 | ::
103 | ++ png-response
104 | =| cache=?
105 | |= =octs
106 | ^- simple-payload:http
107 | :_ `octs
108 | [200 [['content-type' 'image/png'] ?:(cache [max-1-wk ~] ~)]]
109 | ::
110 | ++ svg-response
111 | =| cache=?
112 | |= =octs
113 | ^- simple-payload:http
114 | :_ `octs
115 | [200 [['content-type' 'image/svg+xml'] ?:(cache [max-1-wk ~] ~)]]
116 | ::
117 | ++ ico-response
118 | |= =octs
119 | ^- simple-payload:http
120 | [[200 [['content-type' 'image/x-icon'] max-1-wk ~]] `octs]
121 | ::
122 | ++ woff2-response
123 | =| cache=?
124 | |= =octs
125 | ^- simple-payload:http
126 | [[200 [['content-type' 'font/woff2'] max-1-wk ~]] `octs]
127 | ::
128 | ++ json-response
129 | =| cache=_|
130 | |= =json
131 | ^- simple-payload:http
132 | :_ `(json-to-octs json)
133 | [200 [['content-type' 'application/json'] ?:(cache [max-1-da ~] ~)]]
134 | ::
135 | ++ manx-response
136 | =| cache=_|
137 | |= man=manx
138 | ^- simple-payload:http
139 | :_ `(manx-to-octs man)
140 | [200 [['content-type' 'text/html'] ?:(cache [max-1-da ~] ~)]]
141 | ::
142 | ++ not-found
143 | ^- simple-payload:http
144 | [[404 ~] ~]
145 | ::
146 | ++ login-redirect
147 | |= =request:http
148 | ^- simple-payload:http
149 | =- [[307 ['location' -]~] ~]
150 | %^ cat 3
151 | '/~/login?redirect='
152 | url.request
153 | ::
154 | ++ redirect
155 | |= redirect=cord
156 | ^- simple-payload:http
157 | [[307 ['location' redirect]~] ~]
158 | --
159 | --
160 |
--------------------------------------------------------------------------------
/tanote/lib/bip/b173.hoon:
--------------------------------------------------------------------------------
1 | :: BIP173: Bech32 Addresses
2 | :: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
3 | ::
4 | :: Heavily copies:
5 | :: https://github.com/bitcoinjs/bech32/blob/master/index.js
6 | ::
7 | /- sur=bitcoin
8 | /+ bcu=bitcoin-utils
9 | =, sur
10 | =, bcu
11 | |%
12 | ++ prefixes
13 | ^- (map network tape)
14 | (my [[%main "bc"] [%testnet "tb"] ~])
15 | ++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
16 | +$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
17 | :: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js
18 | ::
19 | ++ polymod
20 | |= values=(list @)
21 | |^ ^- @
22 | =/ gen=(list @ux)
23 | ~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3]
24 | =/ chk=@ 1
25 | |- ?~ values chk
26 | =/ top (rsh [0 25] chk)
27 | =. chk
28 | (mix i.values (lsh [0 5] (dis chk 0x1ff.ffff)))
29 | $(values t.values, chk (update-chk chk top gen))
30 | ::
31 | ++ update-chk
32 | |= [chk=@ top=@ gen=(list @ux)]
33 | =/ is (gulf 0 4)
34 | |- ?~ is chk
35 | ?: =(1 (dis 1 (rsh [0 i.is] top)))
36 | $(is t.is, chk (mix chk (snag i.is gen)))
37 | $(is t.is)
38 | --
39 | ::
40 | ++ expand-hrp
41 | |= hrp=tape
42 | ^- (list @)
43 | =/ front (turn hrp |=(p=@tD (rsh [0 5] p)))
44 | =/ back (turn hrp |=(p=@tD (dis 31 p)))
45 | (zing ~[front ~[0] back])
46 | ::
47 | ++ verify-checksum
48 | |= [hrp=tape data-and-checksum=(list @)]
49 | ^- ?
50 | %- |=(a=@ =(1 a))
51 | %- polymod
52 | (weld (expand-hrp hrp) data-and-checksum)
53 | ::
54 | ++ checksum
55 | |= [hrp=tape data=(list @)]
56 | ^- (list @)
57 | :: xor 1 with the polymod
58 | ::
59 | =/ pmod=@
60 | %+ mix 1
61 | %- polymod
62 | (zing ~[(expand-hrp hrp) data (reap 6 0)])
63 | %+ turn (gulf 0 5)
64 | |=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod)))
65 | ::
66 | ++ charset-to-value
67 | |= c=@tD
68 | ^- (unit @)
69 | (find ~[c] charset)
70 | ++ value-to-charset
71 | |= value=@
72 | ^- (unit @tD)
73 | ?: (gth value 31) ~
74 | `(snag value charset)
75 | ::
76 | ++ is-valid
77 | |= [bech=tape last-1-pos=@] ^- ?
78 | ?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech
79 | (gte last-1-pos 1)
80 | (lte (add last-1-pos 7) (lent bech))
81 | (lte (lent bech) 90)
82 | (levy bech |=(c=@tD (gte c 33)))
83 | (levy bech |=(c=@tD (lte c 126)))
84 | ==
85 | :: data should be 5bit words
86 | ::
87 | ++ encode-raw
88 | |= [hrp=tape data=(list @)]
89 | ^- cord
90 | =/ combined=(list @)
91 | (weld data (checksum hrp data))
92 | %- crip
93 | (zing ~[hrp "1" (tape (murn combined value-to-charset))])
94 | ++ decode-raw
95 | |= body=cord
96 | ^- (unit raw-decoded)
97 | =/ bech (cass (trip body)) :: to lowercase
98 | =/ pos (flop (fand "1" bech))
99 | ?~ pos ~
100 | =/ last-1=@ i.pos
101 | ?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum)
102 | ~
103 | =/ hrp (scag last-1 bech)
104 | =/ encoded-data-and-checksum=(list @)
105 | (slag +(last-1) bech)
106 | =/ data-and-checksum=(list @)
107 | %+ murn encoded-data-and-checksum
108 | charset-to-value
109 | ?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET
110 | ~
111 | ?. (verify-checksum hrp data-and-checksum)
112 | ~
113 | =/ checksum-pos (sub (lent data-and-checksum) 6)
114 | `[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)]
115 | :: +from-address: BIP173 bech32 address encoding to hex
116 | :: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
117 | :: expects to drop a leading 5-bit 0 (the witness version)
118 | ::
119 | ++ from-address
120 | |= body=cord
121 | ^- hexb
122 | ~| "Invalid bech32 address"
123 | =/ d=(unit raw-decoded) (decode-raw body)
124 | ?> ?=(^ d)
125 | =/ bs=bits (from-atoms:bit 5 data.u.d)
126 | =/ byt-len=@ (div (sub wid.bs 5) 8)
127 | ?> =(5^0b0 (take:bit 5 bs))
128 | ?> ?| =(20 byt-len)
129 | =(32 byt-len)
130 | ==
131 | [byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))]
132 | :: pubkey is the 33 byte ECC compressed public key
133 | ::
134 | ++ encode-pubkey
135 | |= [=network pubkey=byts]
136 | ^- (unit cord)
137 | ?. =(33 wid.pubkey)
138 | ~|('pubkey must be a 33 byte ECC compressed public key' !!)
139 | =/ prefix (~(get by prefixes) network)
140 | ?~ prefix ~
141 | :- ~
142 | %+ encode-raw u.prefix
143 | [0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])]
144 | --
145 |
--------------------------------------------------------------------------------
/tanote/lib/azimuthio.hoon:
--------------------------------------------------------------------------------
1 | /- rpc=json-rpc
2 | /+ ethereum, azimuth, strandio
3 | =, strand=strand:strandio
4 | =, jael
5 | |%
6 | ++ tract azimuth:contracts:azimuth
7 | ++ fetch-point
8 | |= [url=@ta who=ship]
9 | =/ m (strand ,point:azimuth)
10 | ^- form:m
11 | =/ =request:rpc:ethereum
12 | :+ %eth-call
13 | =- [from=~ to=tract gas=~ price=~ value=~ data=-]
14 | (encode-call:rpc:ethereum 'points(uint32)' [%uint `@`who]~)
15 | [%label %latest]
16 | ;< jon=json bind:m (request-rpc url `'point' request)
17 | =/ res=cord (so:dejs:format jon)
18 | =/ =point:eth-noun:azimuth
19 | (decode-results:abi:ethereum res point:eth-type:azimuth)
20 | ::
21 | =/ =request:rpc:ethereum
22 | :+ %eth-call
23 | =- [from=~ to=tract gas=~ price=~ value=~ data=-]
24 | (encode-call:rpc:ethereum 'rights(uint32)' [%uint `@`who]~)
25 | [%label %latest]
26 | ;< jon=json bind:m (request-rpc url `'deed' request)
27 | =/ res=cord (so:dejs:format jon)
28 | =/ =deed:eth-noun:azimuth
29 | (decode-results:abi:ethereum res deed:eth-type:azimuth)
30 | ::
31 | (pure:m (point-from-eth:azimuth who point deed))
32 | ::
33 | ++ request-rpc
34 | |= [url=@ta id=(unit @t) req=request:rpc:ethereum]
35 | =/ m (strand ,json)
36 | ^- form:m
37 | %+ (retry json) `10
38 | =/ m (strand ,(unit json))
39 | ^- form:m
40 | |^
41 | =/ =request:http
42 | :* method=%'POST'
43 | url=url
44 | header-list=['Content-Type'^'application/json' ~]
45 | ^= body
46 | %- some %- as-octt:mimes:html
47 | %- en-json:html
48 | (request-to-json:rpc:ethereum id req)
49 | ==
50 | ;< ~ bind:m (send-request:strandio request)
51 | ;< rep=(unit client-response:iris) bind:m
52 | take-maybe-response:strandio
53 | ?~ rep
54 | (pure:m ~)
55 | (parse-response u.rep)
56 | ::
57 | ++ parse-response
58 | |= =client-response:iris
59 | =/ m (strand ,(unit json))
60 | ^- form:m
61 | ?> ?=(%finished -.client-response)
62 | ?~ full-file.client-response
63 | (pure:m ~)
64 | =/ body=@t q.data.u.full-file.client-response
65 | =/ jon=(unit json) (de-json:html body)
66 | ?~ jon
67 | (pure:m ~)
68 | =, dejs-soft:format
69 | =/ array=(unit (list response:rpc))
70 | ((ar parse-one-response) u.jon)
71 | ?~ array
72 | =/ res=(unit response:rpc) (parse-one-response u.jon)
73 | ?~ res
74 | (strand-fail:strandio %request-rpc-parse-error >id< ~)
75 | ?: ?=(%error -.u.res)
76 | (strand-fail:strandio %request-rpc-error >id< >+.res< ~)
77 | ?. ?=(%result -.u.res)
78 | (strand-fail:strandio %request-rpc-fail >u.res< ~)
79 | (pure:m `res.u.res)
80 | (strand-fail:strandio %request-rpc-batch >%not-implemented< ~)
81 | :: (pure:m `[%batch u.array])
82 | ::
83 | ++ parse-one-response
84 | |= =json
85 | ^- (unit response:rpc)
86 | =/ res=(unit [@t ^json])
87 | %. json
88 | =, dejs-soft:format
89 | (ot id+so result+some ~)
90 | ?^ res `[%result u.res]
91 | ~| parse-one-response=json
92 | :+ ~ %error %- need
93 | %. json
94 | =, dejs-soft:format
95 | (ot id+so error+(ot code+no message+so ~) ~)
96 | --
97 | ::
98 | ++ retry
99 | |* result=mold
100 | |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))]
101 | =/ m (strand ,result)
102 | =| try=@ud
103 | |- ^- form:m
104 | =* loop $
105 | ?: =(crash-after `try)
106 | (strand-fail:strandio %retry-too-many ~)
107 | ;< ~ bind:m (backoff:strandio try ~m1)
108 | ;< res=(unit result) bind:m computation
109 | ?^ res
110 | (pure:m u.res)
111 | loop(try +(try))
112 | ::
113 | ++ get-latest-block
114 | |= url=@ta
115 | =/ m (strand ,block)
116 | ^- form:m
117 | ;< =json bind:m (request-rpc url `'block number' %eth-block-number ~)
118 | (get-block-by-number url (parse-eth-block-number:rpc:ethereum json))
119 | ::
120 | ++ get-block-by-number
121 | |= [url=@ta =number:block]
122 | =/ m (strand ,block)
123 | ^- form:m
124 | |^
125 | ;< =json bind:m
126 | (request-rpc url `'block by number' %eth-get-block-by-number number |)
127 | =/ =block (parse-block json)
128 | ?. =(number number.id.block)
129 | (strand-fail:strandio %reorg-detected >number< >block< ~)
130 | (pure:m block)
131 | ::
132 | ++ parse-block
133 | |= =json
134 | ^- block
135 | =< [[&1 &2] |2]
136 | ^- [@ @ @]
137 | ~| json
138 | %. json
139 | =, dejs:format
140 | %- ot
141 | :~ hash+parse-hex-result:rpc:ethereum
142 | number+parse-hex-result:rpc:ethereum
143 | 'parentHash'^parse-hex-result:rpc:ethereum
144 | ==
145 | --
146 | --
147 |
--------------------------------------------------------------------------------
/tanote/lib/tanote.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | +$ note [by=@p as=tape if=[@ux @p] to=(list @p) re=tape text=tape]
3 | +$ history [regards=tape versions=(list note)]
4 | +$ store (list history)
5 | +$ front [tab=tape tags=(set tape) tugs=(set tape) regards=tape histories=store]
6 | ++ add-note-history
7 | |= [n=note h=history]
8 | ^- history
9 | ?: =(regards.h re.n)
10 | ?~ versions.h
11 | [regards.h ~[n]]
12 | [regards.h [n versions.h]]
13 | [re.n ~[n]]
14 | ++ add-note-store
15 | |= [n=note s0=store]
16 | =/ found=history (find-store-regards s0 re.n)
17 | ?: =(found [re.n ~])
18 | [[re.n ~[n]] s0]
19 | =/ s1=store ~
20 | |-
21 | ^- store
22 | ?~ s0
23 | s1
24 | =/ h0=history +2:s0
25 | ?: =(re.n regards.h0)
26 | $(s0 +3:s0, s1 [[regards.h0 [n versions.h0]] s1])
27 | $(s0 +3:s0, s1 [h0 s1])
28 | ++ default-tags
29 | |= ~
30 | ^- (set tape)
31 | (sy ~["*" "/"])
32 | ++ display-tags
33 | |= s=store
34 | ^- (set tape)
35 | (~(uni in (default-tags)) (extract-tags-store s))
36 | ++ display-backlinks
37 | |= s=store
38 | ^- (set tape)
39 | (extract-backlinks-store s)
40 | ++ extract-backlink
41 | |= [start=@ud text=tape]
42 | =/ cursor=@ud (add 2 start)
43 | =/ max=@ud (lent text)
44 | =/ backlink=tape ~
45 | |-
46 | ^- tape
47 | ?: =(cursor (dec max))
48 | ~
49 | =/ t0=@t (snag cursor text)
50 | =/ t1=@t (snag +(cursor) text)
51 | ?: =(~[t0 t1] "]]")
52 | (flop backlink)
53 | $(cursor +(cursor), backlink [t0 backlink])
54 | ++ extract-backlinks-history
55 | |= h=history
56 | (extract-backlinks-note (snag 0 versions.h))
57 | ++ extract-backlinks-note
58 | |= n=note
59 | ^- (set tape)
60 | (~(uni in (sy ~[as.n])) (extract-backlinks-tape (index-backlinks text.n) text.n))
61 | ++ extract-backlinks-store
62 | |= s=store
63 | =/ backlinks=(set tape) ~
64 | |-
65 | ^- (set tape)
66 | ?~ s
67 | backlinks
68 | $(s +3:s, backlinks (~(uni in backlinks) (extract-backlinks-history +2:s)))
69 | ++ extract-backlinks-tape
70 | |= [starts=(list @ud) text=tape]
71 | =/ backlinks=(set tape) ~
72 | |-
73 | ^- (set tape)
74 | ?~ starts
75 | backlinks
76 | $(starts +3:starts, backlinks (~(put in backlinks) (extract-backlink +2:starts text)))
77 | ++ extract-tag
78 | |= [oi=@ud text=tape]
79 | =/ max=@ (lent text)
80 | =/ allowed=tape "#-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~"
81 | =/ tag=tape ~
82 | |-
83 | ^- tape
84 | ?: =(oi max)
85 | (flop tag)
86 | =/ t=@t (snag oi text)
87 | ?~ (find ~[t] allowed)
88 | (flop tag)
89 | $(oi +(oi), tag [t tag])
90 | ++ extract-tags-history
91 | |= h=history
92 | (extract-tags-note (snag 0 versions.h))
93 | ++ extract-tags-note
94 | |= n=note
95 | ^- (set tape)
96 | (extract-tags-tape (index-tags text.n) text.n)
97 | ++ extract-tags-store
98 | |= s=store
99 | =/ tags=(set tape) ~
100 | |-
101 | ^- (set tape)
102 | ?~ s
103 | tags
104 | $(s +3:s, tags (~(uni in tags) (extract-tags-history +2:s)))
105 | ++ extract-tags-tape
106 | |= [starts=(list @ud) text=tape]
107 | =/ tags=(set tape) ~
108 | |-
109 | ^- (set tape)
110 | ?~ starts
111 | tags
112 | $(starts +3:starts, tags (~(put in tags) (extract-tag +2:starts text)))
113 | ++ filter-front-regards
114 | |= f=front
115 | ^- front
116 | ?~ regards.f
117 | f
118 | [tab=tab.f tags=tags.f tugs=tugs.f regards=regards.f histories=~[(find-store-regards histories.f regards.f)]]
119 | ++ filter-front-tugs
120 | |= f=front
121 | ^- front
122 | ?~ tugs.f
123 | f
124 | [tab=tab.f tags=tags.f tugs=tugs.f regards=regards.f histories=(filter-store-tags histories.f tugs.f)]
125 | ++ find-store-regards
126 | |= [s=store regards=tape]
127 | |-
128 | ^- history
129 | ?~ s
130 | [regards ~]
131 | =/ h=history +2:s
132 | ?: =(regards.h regards)
133 | h
134 | $(s +3:s)
135 | ++ filter-store-tag
136 | |= [unfiltered=store tag=tape]
137 | =/ filtered=store ~
138 | |-
139 | ^- store
140 | ?~ unfiltered
141 | filtered
142 | ?: (~(has in (extract-tags-history +2:unfiltered)) tag)
143 | $(unfiltered +3:unfiltered, filtered [+2:unfiltered filtered])
144 | $(unfiltered +3:unfiltered)
145 | ++ filter-store-tags
146 | |= [unfiltered=store tags=(set tape)]
147 | =/ filtered=store ~
148 | |-
149 | ^- store
150 | ?~ unfiltered
151 | filtered
152 | ?: .= tags
153 | (~(int in tags) (extract-tags-history +2:unfiltered))
154 | $(unfiltered +3:unfiltered, filtered [+2:unfiltered filtered])
155 | $(unfiltered +3:unfiltered)
156 | ++ index-backlinks
157 | |= text=tape
158 | (fand "[[" text)
159 | ++ index-tags
160 | |= text=tape
161 | (weld (fand "#" text) (fand "~" text))
162 | ++ list-regards-store
163 | |= s=store
164 | =/ regards=(list tape) ~
165 | |-
166 | ^- (list tape)
167 | ?~ s
168 | regards
169 | =/ h=history +2:s
170 | $(s +3:s, regards [regards.h regards])
171 | --
172 | :: DO NOT EDIT THIS FILE. Auto-generated from default tanote.md by lit.
173 |
--------------------------------------------------------------------------------
/tanote/sur/hark-store.hoon:
--------------------------------------------------------------------------------
1 | ^?
2 | ::
3 | :: %hark-store: Notification, unreads store
4 | ::
5 | :: Timeboxing & binning:
6 | ::
7 | :: Unread notifications accumulate in $unreads. They are grouped by
8 | :: their $bin. A notification may become read by either:
9 | :: a) being read by a %read-count or %read-each or %read-note
10 | :: b) being read by a %seen
11 | ::
12 | :: If a) then we insert the corresponding bin into $reads at the
13 | :: current timestamp
14 | :: If b) then we empty $unreads and move all bins to $reads at the
15 | :: current timestamp
16 | ::
17 | :: Unread tracking:
18 | :: Unread tracking has two 'modes' which may be used concurrently,
19 | :: if necessary.
20 | ::
21 | :: count:
22 | :: This stores the unreads as a simple atom, describing the number
23 | :: of unread items. May be increased with %unread-count and
24 | :: set to zero with %read-count. Ideal for high-frequency linear
25 | :: datastructures, e.g. chat
26 | :: each:
27 | :: This stores the unreads as a set of paths, describing the set of
28 | :: unread items. Unreads may be added to the set with %unread-each
29 | :: and removed with %read-each. Ideal for non-linear, low-frequency
30 | :: datastructures, e.g. blogs
31 | ::
32 | |%
33 | :: $place: A location, under which landscape stores stats
34 | ::
35 | :: .desk must match q.byk.bowl
36 | :: Examples:
37 | :: A chat:
38 | :: [%landscape /~dopzod/urbit-help]
39 | :: A note in a notebook:
40 | :: [%landscape /~darrux-landes/feature-requests/12374893234232]
41 | :: A group:
42 | :: [%hark-group-hook /~bitbet-bolbel/urbit-community]
43 | :: Comments on a link
44 | :: [%landscape /~dabben-larbet/urbit-in-the-news/17014118450499614194868/2]
45 | ::
46 | +$ place [=desk =path]
47 | ::
48 | :: $bin: Identifier for grouping notifications
49 | ::
50 | :: Examples
51 | :: A mention in a chat:
52 | :: [/mention %landscape /~dopzod/urbit-help]
53 | :: New messages in a chat
54 | :: [/message %landscape /~dopzod/urbit-help]
55 | :: A new comment in a notebook:
56 | :: [/comment %landscape /~darrux-landes/feature-requests/12374893234232/2]
57 | ::
58 | +$ bin [=path =place]
59 | ::
60 | :: $lid: Reference to a timebox
61 | ::
62 | +$ lid
63 | $% [%archive =time]
64 | [%seen ~]
65 | [%unseen ~]
66 | ==
67 | :: $content: Notification content
68 | +$ content
69 | $% [%ship =ship]
70 | [%text =cord]
71 | ==
72 | ::
73 | :: $body: A notification body
74 | ::
75 | +$ body
76 | $: title=(list content)
77 | content=(list content)
78 | =time
79 | binned=path
80 | link=path
81 | ==
82 | ::
83 | +$ notification
84 | [date=@da =bin body=(list body)]
85 | :: $timebox: Group of notificatons
86 | +$ timebox
87 | (map bin notification)
88 | :: $archive: Archived notifications, ordered by time
89 | +$ archive
90 | ((mop @da timebox) gth)
91 | ::
92 | +$ action
93 | $% :: hook actions
94 | ::
95 | :: %add-note: add a notification
96 | [%add-note =bin =body]
97 | ::
98 | :: %del-place: Underlying resource disappeared, remove all
99 | :: associated notifications
100 | [%del-place =place]
101 | :: %unread-count: Change unread count by .count
102 | [%unread-count =place inc=? count=@ud]
103 | :: %unread-each: Add .path to list of unreads for .place
104 | [%unread-each =place =path]
105 | :: %saw-place: Update last-updated for .place to now.bowl
106 | [%saw-place =place time=(unit time)]
107 | :: store actions
108 | ::
109 | :: %archive: archive single notification
110 | :: if .time is ~, then archiving unread notification
111 | :: else, archiving read notification
112 | [%archive =lid =bin]
113 | :: %read-count: set unread count to zero
114 | [%read-count =place]
115 | :: %read-each: remove path from unreads for .place
116 | [%read-each =place =path]
117 | :: %read-note: Read note at .bin
118 | [%read-note =bin]
119 | :: %archive-all: Archive all notifications
120 | [%archive-all ~]
121 | :: %opened: User opened notifications, reset timeboxing logic.
122 | ::
123 | [%opened ~]
124 | ::
125 | :: XX: previously in hark-store, now deprecated
126 | :: the hooks responsible for creating notifications may offer pokes
127 | :: similar to this
128 | :: [%read-graph =resource]
129 | :: [%read-group =resource]
130 | :: [%remove-graph =resource]
131 | ::
132 | ==
133 | :: .stats: Statistics for a .place
134 | ::
135 | +$ stats
136 | $: count=@ud
137 | each=(set path)
138 | last=@da
139 | timebox=(unit @da)
140 | ==
141 | ::
142 | +$ update
143 | $% action
144 | :: %more: more updates
145 | [%archived =time =lid =notification]
146 | [%more more=(list update)]
147 | :: %note-read: note has been read with timestamp
148 | [%note-read =time =bin]
149 | [%added =notification]
150 | :: %timebox: description of timebox.
151 | ::
152 | [%timebox =lid =(list notification)]
153 | :: %place-stats: description of .stats for a .place
154 | [%place-stats =place =stats]
155 | :: %place-stats: stats for all .places
156 | [%all-stats places=(map place stats)]
157 | ==
158 | --
159 |
160 |
--------------------------------------------------------------------------------
/tanote/gen/testlib.hoon:
--------------------------------------------------------------------------------
1 | /+ tanote
2 | :- %say
3 | |= *
4 | :- %noun
5 | =/ test0=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~ "test" "This is a test."]
6 | =/ test1=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~[~ponhec-picwen] "test" "This is a test."]
7 | =/ test2=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~[~ponhec-picwen ~nocsyx-lassul] "test" "This is a test."]
8 | =/ tagbl0=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~[~ponhec-picwen ~nocsyx-lassul] "tag and backlink" "This is a test with a #tag and a [[backlink]]."]
9 | =/ test10=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~ "another test" "This is a #test with a [[backlink]]."]
10 | =/ test11=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~[~ponhec-picwen] "another test" "This is another #test with two #tag and two [[backlink]] for [[tanote]]."]
11 | =/ test12=note:tanote [~ponhec-picwen "tester" [0x0 ~ponhec-picwen] ~[~ponhec-picwen ~nocsyx-lassul] "another test" "This is another #test with an #array of #tag and more [[backlink]] for [[tanote]] [[test data]]."]
12 | =/ history0=history:tanote ["test" ~[test2 test1 test0]]
13 | =/ history1=history:tanote ["another test" ~[test12 test11 test10]]
14 | =/ latest-history0=note:tanote (snag 0 versions.history0)
15 | =/ store0=store:tanote ~[history0 history1]
16 | :- (default-tags:tanote)
17 | :- .= (default-tags:tanote)
18 | (sy ~["/" "*"])
19 | :- (index-tags:tanote "This is a test.")
20 | :- .= (index-tags:tanote "This is a test.")
21 | ~
22 | :- (index-tags:tanote "This is a #hash test.")
23 | :- .= (index-tags:tanote "This is a #hash test.")
24 | ~[10]
25 | :- (index-tags:tanote "This is a multiple-#hash ~ponhec-picwen.")
26 | :- .= (index-tags:tanote "This is a multiple-#hash ~ponhec-picwen.")
27 | ~[19 25]
28 | :- .= (index-backlinks:tanote "This is a test.")
29 | ~
30 | :- .= (index-backlinks:tanote "This is a [[hash]] test.")
31 | ~[10]
32 | :- .= (index-backlinks:tanote "This is a multiple-[[hash]] [[~ponhec-picwen]].")
33 | ~[19 28]
34 | :- .= (extract-tag:tanote 10 "This is a #hash test.")
35 | "#hash"
36 | :- .= (extract-tag:tanote 19 "This is a multiple-#hash #test.")
37 | "#hash"
38 | :- .= (extract-tag:tanote 25 "This is a multiple-#hash ~ponhec-picwen.")
39 | "~ponhec-picwen"
40 | :- .= (extract-tags-tape:tanote ~ "This is a test.")
41 | ~
42 | :- (extract-tags-tape:tanote ~[10] "This is a #hash test.")
43 | :- .= (extract-tags-tape:tanote ~[10] "This is a #hash test.")
44 | (sy ~["#hash"])
45 | :- (extract-tags-tape:tanote ~[19 25] "This is a multiple-#hash ~ponhec-picwen.")
46 | :- .= (extract-tags-tape:tanote ~[19 25] "This is a multiple-#hash ~ponhec-picwen.")
47 | (sy ~["#hash" "~ponhec-picwen"])
48 | :- .= (extract-backlink:tanote 10 "This is a [[hash]] test.")
49 | "hash"
50 | :- .= (extract-backlink:tanote 19 "This is a multiple-[[hash]] [[test]].")
51 | "hash"
52 | :- (extract-backlink:tanote 28 "This is a multiple-[[hash]] [[test]].")
53 | :- .= (extract-backlink:tanote 28 "This is a multiple-[[hash]] [[test]].")
54 | "test"
55 | :- .= (extract-backlinks-tape:tanote ~ "This is a test.")
56 | ~
57 | :- (extract-backlinks-tape:tanote ~[10] "This is a [[hash]] test.")
58 | :- .= (extract-backlinks-tape:tanote ~[10] "This is a [[hash]] test.")
59 | (sy ~["hash"])
60 | :- (extract-backlinks-tape:tanote ~[19 28] "This is a multiple-[[link]] [[~ponhec-picwen]].")
61 | :- .= (extract-backlinks-tape:tanote ~[19 28] "This is a multiple-[[link]] [[~ponhec-picwen]].")
62 | (sy ~["link" "~ponhec-picwen"])
63 | :- test0
64 | :- test1
65 | :- test2
66 | :- `history:tanote`["test" ~[test2 test1 test0]]
67 | :- .= history0
68 | `history:tanote`["test" ~[test2 test1 test0]]
69 | :- .= regards.history0
70 | "test"
71 | :- .= versions.history0
72 | ~[test2 test1 test0]
73 | :- .= +2:versions.history0
74 | test2
75 | :- .= (snag 0 versions.history0)
76 | test2
77 | :- .= latest-history0
78 | test2
79 | :- .= to.latest-history0
80 | ~[~ponhec-picwen ~nocsyx-lassul]
81 | :- .= by.latest-history0
82 | ~ponhec-picwen
83 | :- .= as.latest-history0
84 | "tester"
85 | :- .= if.latest-history0
86 | [0x0 ~ponhec-picwen]
87 | :- .= re.latest-history0
88 | "test"
89 | :- .= text.latest-history0
90 | "This is a test."
91 | :- .= (extract-tags-tape:tanote (index-tags:tanote text.latest-history0) text.latest-history0)
92 | ~
93 | :- .= (extract-backlinks-tape:tanote (index-backlinks:tanote text.latest-history0) text.latest-history0)
94 | ~
95 | :- .= (extract-tags-tape:tanote (index-tags:tanote text.tagbl0) text.tagbl0)
96 | (sy ~["#tag"])
97 | :- .= (extract-backlinks-tape:tanote (index-backlinks:tanote text.tagbl0) text.tagbl0)
98 | (sy ~["backlink"])
99 | :- .= (extract-tags-note:tanote tagbl0)
100 | (sy ~["#tag"])
101 | :- .= (extract-backlinks-note:tanote tagbl0)
102 | (sy ~["backlink"])
103 | :- .= (extract-tags-history:tanote history0)
104 | ~
105 | :- .= (extract-backlinks-history:tanote history0)
106 | ~
107 | :- .= (extract-tags-history:tanote history1)
108 | (sy ~["#array" "#tag" "#test"])
109 | :- .= (extract-backlinks-history:tanote history1)
110 | (sy ~["backlink" "tanote" "test data"])
111 | :- store0
112 | :- .= (extract-tags-store:tanote store0)
113 | (sy ~["#array" "#tag" "#test"])
114 | :- .= (extract-backlinks-store:tanote store0)
115 | (sy ~["backlink" "tanote" "test data"])
116 | ~
117 | :: DO NOT EDIT THIS FILE. Auto-generated from verbose testlib.md by lit.
118 |
--------------------------------------------------------------------------------
/tanote/lib/strand.hoon:
--------------------------------------------------------------------------------
1 | |%
2 | +$ card card:agent:gall
3 | +$ input
4 | $% [%poke =cage]
5 | [%sign =wire =sign-arvo]
6 | [%agent =wire =sign:agent:gall]
7 | [%watch =path]
8 | ==
9 | +$ strand-input [=bowl in=(unit input)]
10 | +$ tid @tatid
11 | +$ bowl
12 | $: our=ship
13 | src=ship
14 | tid=tid
15 | mom=(unit tid)
16 | wex=boat:gall
17 | sup=bitt:gall
18 | eny=@uvJ
19 | now=@da
20 | byk=beak
21 | ==
22 | ::
23 | :: cards: cards to send immediately. These will go out even if a
24 | :: later stage of the computation fails, so they shouldn't have
25 | :: any semantic effect on the rest of the system.
26 | :: Alternately, they may record an entry in contracts with
27 | :: enough information to undo the effect if the computation
28 | :: fails.
29 | :: wait: don't move on, stay here. The next sign should come back
30 | :: to this same callback.
31 | :: skip: didn't expect this input; drop it down to be handled
32 | :: elsewhere
33 | :: cont: continue computation with new callback.
34 | :: fail: abort computation; don't send effects
35 | :: done: finish computation; send effects
36 | ::
37 | ++ strand-output-raw
38 | |* a=mold
39 | $~ [~ %done *a]
40 | $: cards=(list card)
41 | $= next
42 | $% [%wait ~]
43 | [%skip ~]
44 | [%cont self=(strand-form-raw a)]
45 | [%fail err=(pair term tang)]
46 | [%done value=a]
47 | ==
48 | ==
49 | ::
50 | ++ strand-form-raw
51 | |* a=mold
52 | $-(strand-input (strand-output-raw a))
53 | ::
54 | :: Abort strand computation with error message
55 | ::
56 | ++ strand-fail
57 | |= err=(pair term tang)
58 | |= strand-input
59 | [~ %fail err]
60 | ::
61 | :: Asynchronous transcaction monad.
62 | ::
63 | :: Combo of four monads:
64 | :: - Reader on input
65 | :: - Writer on card
66 | :: - Continuation
67 | :: - Exception
68 | ::
69 | ++ strand
70 | |* a=mold
71 | |%
72 | ++ output (strand-output-raw a)
73 | ::
74 | :: Type of an strand computation.
75 | ::
76 | ++ form (strand-form-raw a)
77 | ::
78 | :: Monadic pure. Identity computation for bind.
79 | ::
80 | ++ pure
81 | |= arg=a
82 | ^- form
83 | |= strand-input
84 | [~ %done arg]
85 | ::
86 | :: Monadic bind. Combines two computations, associatively.
87 | ::
88 | ++ bind
89 | |* b=mold
90 | |= [m-b=(strand-form-raw b) fun=$-(b form)]
91 | ^- form
92 | |= input=strand-input
93 | =/ b-res=(strand-output-raw b)
94 | (m-b input)
95 | ^- output
96 | :- cards.b-res
97 | ?- -.next.b-res
98 | %wait [%wait ~]
99 | %skip [%skip ~]
100 | %cont [%cont ..$(m-b self.next.b-res)]
101 | %fail [%fail err.next.b-res]
102 | %done [%cont (fun value.next.b-res)]
103 | ==
104 | ::
105 | :: The strand monad must be evaluted in a particular way to maintain
106 | :: its monadic character. +take:eval implements this.
107 | ::
108 | ++ eval
109 | |%
110 | :: Indelible state of a strand
111 | ::
112 | +$ eval-form
113 | $: =form
114 | ==
115 | ::
116 | :: Convert initial form to eval-form
117 | ::
118 | ++ from-form
119 | |= =form
120 | ^- eval-form
121 | form
122 | ::
123 | :: The cases of results of +take
124 | ::
125 | +$ eval-result
126 | $% [%next ~]
127 | [%fail err=(pair term tang)]
128 | [%done value=a]
129 | ==
130 | ::
131 | ++ validate-mark
132 | |= [in=* =mark =bowl]
133 | ^- cage
134 | =+ .^ =dais:clay %cb
135 | /(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[mark]
136 | ==
137 | =/ res (mule |.((vale.dais in)))
138 | ?: ?=(%| -.res)
139 | ~|(%spider-mark-fail (mean leaf+"spider: ames vale fail {}" p.res))
140 | [mark p.res]
141 | ::
142 | :: Take a new sign and run the strand against it
143 | ::
144 | ++ take
145 | :: cards: accumulate throughout recursion the cards to be
146 | :: produced now
147 | =| cards=(list card)
148 | |= [=eval-form =strand-input]
149 | ^- [[(list card) =eval-result] _eval-form]
150 | =* take-loop $
151 | =. in.strand-input
152 | ?~ in.strand-input ~
153 | =/ in u.in.strand-input
154 | ?. ?=(%agent -.in) `in
155 | ?. ?=(%fact -.sign.in) `in
156 | ::
157 | :- ~
158 | :+ %agent wire.in
159 | [%fact (validate-mark q.q.cage.sign.in p.cage.sign.in bowl.strand-input)]
160 | :: run the strand callback
161 | ::
162 | =/ =output (form.eval-form strand-input)
163 | :: add cards to cards
164 | ::
165 | =. cards
166 | %+ welp
167 | cards
168 | :: XX add tag to wires?
169 | cards.output
170 | :: case-wise handle next steps
171 | ::
172 | ?- -.next.output
173 | %wait [[cards %next ~] eval-form]
174 | %skip [[cards %next ~] eval-form]
175 | %fail [[cards %fail err.next.output] eval-form]
176 | %done [[cards %done value.next.output] eval-form]
177 | %cont
178 | :: recurse to run continuation with initialization input
179 | ::
180 | %_ take-loop
181 | form.eval-form self.next.output
182 | strand-input [bowl.strand-input ~]
183 | ==
184 | ==
185 | --
186 | --
187 | --
188 | ::
189 |
--------------------------------------------------------------------------------
/tanote/lib/hark-store.hoon:
--------------------------------------------------------------------------------
1 | /- sur=hark-store
2 | ^?
3 | =, sur
4 | =< [. sur]
5 | |%
6 |
7 | ++ enjs
8 | =, enjs:format
9 | |%
10 | ++ update
11 | |= upd=^update
12 | ^- json
13 | %+ frond -.upd
14 | ?+ -.upd a+~
15 | %added (notification +.upd)
16 | %add-note (add-note +.upd)
17 | %timebox (timebox +.upd)
18 | %more (more +.upd)
19 | %read-each (read-each +.upd)
20 | %read-count (place +.upd)
21 | %unread-each (read-each +.upd)
22 | %unread-count (unread-count +.upd)
23 | %saw-place (saw-place +.upd)
24 | %all-stats (all-stats +.upd)
25 | %del-place (place +.upd)
26 | ::%read-note (index +.upd)
27 | ::%note-read (note-read +.upd)
28 | %archived (archived +.upd)
29 | ==
30 | ::
31 | ++ add-note
32 | |= [bi=^bin bo=^body]
33 | %- pairs
34 | :~ bin+(bin bi)
35 | body+(body bo)
36 | ==
37 | ::
38 | ++ saw-place
39 | |= [p=^place t=(unit ^time)]
40 | %- pairs
41 | :~ place+(place p)
42 | time+?~(t ~ (time u.t))
43 | ==
44 | ::
45 | ++ archived
46 | |= [t=^time l=^lid n=^notification]
47 | %- pairs
48 | :~ lid+(lid l)
49 | time+s+(scot %ud t)
50 | notification+(notification n)
51 | ==
52 | ::
53 | ++ note-read
54 | |= *
55 | (pairs ~)
56 | ::
57 | ++ all-stats
58 | |= places=(map ^place ^stats)
59 | ^- json
60 | :- %a
61 | ^- (list json)
62 | %+ turn ~(tap by places)
63 | |= [p=^place s=^stats]
64 | %- pairs
65 | :~ stats+(stats s)
66 | place+(place p)
67 |
68 | ==
69 | ::
70 | ++ stats
71 | |= s=^stats
72 | ^- json
73 | %- pairs
74 | :~ each+a+(turn ~(tap in each.s) (cork spat (lead %s)))
75 | last+(time last.s)
76 | count+(numb count.s)
77 | ==
78 | ++ more
79 | |= upds=(list ^update)
80 | ^- json
81 | a+(turn upds update)
82 | ::
83 | ++ place
84 | |= =^place
85 | %- pairs
86 | :~ desk+s+desk.place
87 | path+s+(spat path.place)
88 | ==
89 | ::
90 | ++ bin
91 | |= =^bin
92 | %- pairs
93 | :~ place+(place place.bin)
94 | path+s+(spat path.bin)
95 | ==
96 | ++ notification
97 | |= ^notification
98 | ^- json
99 | %- pairs
100 | :~ time+(time date)
101 | bin+(^bin bin)
102 | body+(bodies body)
103 | ==
104 | ++ bodies
105 | |= bs=(list ^body)
106 | ^- json
107 | a+(turn bs body)
108 | ::
109 | ++ contents
110 | |= cs=(list ^content)
111 | ^- json
112 | a+(turn cs content)
113 | ::
114 | ++ content
115 | |= c=^content
116 | ^- json
117 | %+ frond -.c
118 | ?- -.c
119 | %ship s+(scot %p ship.c)
120 | %text s+cord.c
121 | ==
122 | ::
123 | ++ body
124 | |= ^body
125 | ^- json
126 | %- pairs
127 | :~ title+(contents title)
128 | content+(contents content)
129 | time+(^time time)
130 | link+s+(spat link)
131 | ==
132 | ::
133 | ++ binned-notification
134 | |= [=^bin =^notification]
135 | %- pairs
136 | :~ bin+(^bin bin)
137 | notification+(^notification notification)
138 | ==
139 | ++ lid
140 | |= l=^lid
141 | ^- json
142 | %+ frond -.l
143 | ?- -.l
144 | ?(%seen %unseen) ~
145 | %archive s+(scot %ud time.l)
146 | ==
147 | ::
148 | ++ timebox
149 | |= [li=^lid l=(list ^notification)]
150 | ^- json
151 | %- pairs
152 | :~ lid+(lid li)
153 | notifications+a+(turn l notification)
154 | ==
155 | ::
156 | ++ read-each
157 | |= [p=^place pax=^path]
158 | %- pairs
159 | :~ place+(place p)
160 | path+(path pax)
161 | ==
162 | ::
163 | ++ unread-count
164 | |= [p=^place inc=? count=@ud]
165 | %- pairs
166 | :~ place+(place p)
167 | inc+b+inc
168 | count+(numb count)
169 | ==
170 | --
171 | ++ dejs
172 | =, dejs:format
173 | |%
174 | ++ ship (su ;~(pfix sig fed:ag))
175 | :: TODO: fix +stab
176 | ::
177 | ++ pa
178 | |= j=json
179 | ^- path
180 | ?> ?=(%s -.j)
181 | ?: =('/' p.j) /
182 | (stab p.j)
183 | ::
184 | ++ place
185 | %- ot
186 | :~ desk+so
187 | path+pa
188 | ==
189 | ::
190 | ++ bin
191 | %- ot
192 | :~ path+pa
193 | place+place
194 | ==
195 | ::
196 | ++ read-each
197 | %- ot
198 | :~ place+place
199 | path+pa
200 | ==
201 | ::
202 | :: parse date as @ud
203 | :: TODO: move to zuse
204 | ++ sd
205 | |= jon=json
206 | ^- @da
207 | ?> ?=(%s -.jon)
208 | `@da`(rash p.jon dem:ag)
209 | ::
210 | ++ lid
211 | %- of
212 | :~ archive+sd
213 | unseen+ul
214 | seen+ul
215 | ==
216 | ::
217 | ++ archive
218 | %- ot
219 | :~ lid+lid
220 | bin+bin
221 | ==
222 | ++ content
223 | %- of
224 | :~ text+so
225 | ship+ship
226 | ==
227 | ::
228 | ++ body
229 | %- ot
230 | :~ title+(ar content)
231 | content+(ar content)
232 | time+di
233 | binned+pa
234 | link+pa
235 | ==
236 | ::
237 | ++ add-note
238 | %- ot
239 | :~ bin+bin
240 | body+body
241 | ==
242 | ::
243 | ++ action
244 | ^- $-(json ^action)
245 | %- of
246 | :~ archive-all+ul
247 | archive+archive
248 | opened+ul
249 | read-count+place
250 | read-each+read-each
251 | read-note+bin
252 | add-note+add-note
253 | ==
254 | --
255 | --
256 |
--------------------------------------------------------------------------------
/tanote/sur/sole.hoon:
--------------------------------------------------------------------------------
1 | ::
2 | :::: /hoon/sole/sur
3 | ::
4 | ^?
5 | |%
6 | +$ sole-action :: sole to app
7 | $: id=@ta :: duct id
8 | $= dat
9 | $% :: [%abo ~] :: reset interaction
10 | [%det sole-change] :: command line edit
11 | [%ret ~] :: submit and clear
12 | [%clr ~] :: exit context
13 | [%tab pos=@ud] :: tab complete
14 | == ::
15 | ==
16 | +$ sole-buffer (list @c) :: command state
17 | +$ sole-change :: network change
18 | $: ler=sole-clock :: destination clock
19 | haw=@uvH :: source hash
20 | ted=sole-edit :: state change
21 | == ::
22 | +$ sole-clock [own=@ud his=@ud] :: vector clock
23 | +$ sole-edit :: shared state change
24 | $% [%del p=@ud] :: delete one at
25 | [%ins p=@ud q=@c] :: insert at
26 | [%mor p=(list sole-edit)] :: combination
27 | [%nop ~] :: no-op
28 | [%set p=sole-buffer] :: discontinuity
29 | == ::
30 | +$ sole-effect :: app to sole
31 | $% [%bel ~] :: beep
32 | [%blk p=@ud q=@c] :: blink+match char at
33 | [%bye ~] :: close session
34 | [%clr ~] :: clear screen
35 | [%det sole-change] :: edit command
36 | [%err p=@ud] :: error point
37 | [%klr p=styx] :: styled text line
38 | [%mor p=(list sole-effect)] :: multiple effects
39 | [%nex ~] :: save clear command
40 | [%pro sole-prompt] :: set prompt
41 | [%sag p=path q=*] :: save to jamfile
42 | [%sav p=path q=@] :: save to file
43 | [%tab p=(list [=cord =tank])] :: tab-complete list
44 | [%tan p=(list tank)] :: classic tank
45 | :: [%taq p=tanq] :: modern tank
46 | [%txt p=tape] :: text line
47 | [%url p=@t] :: activate url
48 | == ::
49 | +$ sole-command :: command state
50 | $: pos=@ud :: cursor position
51 | say=sole-share :: cursor
52 | == ::
53 | +$ sole-prompt :: prompt definition
54 | $: vis=? :: command visible
55 | tag=term :: history mode
56 | cad=styx :: caption
57 | == ::
58 | +$ sole-share :: symmetric state
59 | $: ven=sole-clock :: our vector clock
60 | leg=(list sole-edit) :: unmerged edits
61 | buf=sole-buffer :: sole state
62 | == ::
63 | :: ::
64 | :: ::
65 | ++ sole-dialog :: standard dialog
66 | |* out=$-(* *) :: output structure
67 | $-(sole-input (sole-result out)) :: output function
68 | :: ::
69 | +$ sole-input tape :: prompt input
70 | ++ sole-result :: conditional result
71 | |* out=$-(* *) :: output structure
72 | $@(@ud (sole-product out)) :: error position
73 | :: ::
74 | ++ sole-product :: success result
75 | |* out=$-(* *) ::
76 | %+ pair (list tank) ::
77 | %+ each (unit out) :: ~ is abort
78 | (pair sole-prompt (sole-dialog out)) :: ask and continue
79 | :: ::
80 | +$ sole-gen :: XX virtual type
81 | $% [%say $-((sole-args) (cask))] :: direct noun
82 | [%ask $-((sole-args) (sole-product (cask)))] :: dialog
83 | == ::
84 | ++ sole-args :: generator arguments
85 | |* _[* *] ::
86 | ,[[now=@da eny=@uvJ bek=beak] [,+<- ,+<+]] ::
87 | --
88 |
--------------------------------------------------------------------------------
/tanote/lib/docket.hoon:
--------------------------------------------------------------------------------
1 | /- *docket
2 | |%
3 | ::
4 | ++ mime
5 | |%
6 | +$ draft
7 | $: title=(unit @t)
8 | info=(unit @t)
9 | color=(unit @ux)
10 | glob-http=(unit [=url hash=@uvH])
11 | glob-ames=(unit [=ship hash=@uvH])
12 | base=(unit term)
13 | site=(unit path)
14 | image=(unit url)
15 | version=(unit version)
16 | website=(unit url)
17 | license=(unit cord)
18 | ==
19 | ::
20 | ++ finalize
21 | |= =draft
22 | ^- (unit docket)
23 | ?~ title.draft ~
24 | ?~ info.draft ~
25 | ?~ color.draft ~
26 | ?~ version.draft ~
27 | ?~ website.draft ~
28 | ?~ license.draft ~
29 | =/ href=(unit href)
30 | ?^ site.draft `[%site u.site.draft]
31 | ?~ base.draft ~
32 | ?^ glob-http.draft
33 | `[%glob u.base hash.u.glob-http %http url.u.glob-http]:draft
34 | ?~ glob-ames.draft
35 | ~
36 | `[%glob u.base hash.u.glob-ames %ames ship.u.glob-ames]:draft
37 | ?~ href ~
38 | =, draft
39 | :- ~
40 | :* %1
41 | u.title
42 | u.info
43 | u.color
44 | u.href
45 | image
46 | u.version
47 | u.website
48 | u.license
49 | ==
50 | ::
51 | ++ from-clauses
52 | =| =draft
53 | |= cls=(list clause)
54 | ^- (unit docket)
55 | =* loop $
56 | ?~ cls (finalize draft)
57 | =* clause i.cls
58 | =. draft
59 | ?- -.clause
60 | %title draft(title `title.clause)
61 | %info draft(info `info.clause)
62 | %color draft(color `color.clause)
63 | %glob-http draft(glob-http `[url hash]:clause)
64 | %glob-ames draft(glob-ames `[ship hash]:clause)
65 | %base draft(base `base.clause)
66 | %site draft(site `path.clause)
67 | %image draft(image `url.clause)
68 | %version draft(version `version.clause)
69 | %website draft(website `website.clause)
70 | %license draft(license `license.clause)
71 | ==
72 | loop(cls t.cls)
73 | ::
74 | ++ to-clauses
75 | |= d=docket
76 | ^- (list clause)
77 | %- zing
78 | :~ :~ title+title.d
79 | info+info.d
80 | color+color.d
81 | version+version.d
82 | website+website.d
83 | license+license.d
84 | ==
85 | ?~ image.d ~ ~[image+u.image.d]
86 | ?: ?=(%site -.href.d) ~[site+path.href.d]
87 | =/ ref=glob-reference glob-reference.href.d
88 | :~ base+base.href.d
89 | ?- -.location.ref
90 | %http [%glob-http url.location.ref hash.ref]
91 | %ames [%glob-ames ship.location.ref hash.ref]
92 | == == ==
93 | ::
94 | ++ spit-clause
95 | |= =clause
96 | ^- tape
97 | %+ weld " {(trip -.clause)}+"
98 | ?+ -.clause "'{(trip +.clause)}'"
99 | %color (scow %ux color.clause)
100 | %site (spud path.clause)
101 | ::
102 | %glob-http
103 | "['{(trip url.clause)}' {(scow %uv hash.clause)}]"
104 | ::
105 | %glob-ames
106 | "[{(scow %p ship.clause)} {(scow %uv hash.clause)}]"
107 | ::
108 | %version
109 | =, version.clause
110 | "[{(scow %ud major)} {(scow %ud minor)} {(scow %ud patch)}]"
111 | ==
112 | ::
113 | ++ spit-docket
114 | |= dock=docket
115 | ^- tape
116 | ;: welp
117 | ":~\0a"
118 | `tape`(zing (join "\0a" (turn (to-clauses dock) spit-clause)))
119 | "\0a=="
120 | ==
121 | --
122 | ::
123 | ++ enjs
124 | =, enjs:format
125 | |%
126 | ::
127 | ++ charge-update
128 | |= u=^charge-update
129 | ^- json
130 | %+ frond -.u
131 | ^- json
132 | ?- -.u
133 | %del-charge s+desk.u
134 | ::
135 | %initial
136 | %- pairs
137 | %+ turn ~(tap by initial.u)
138 | |=([=desk c=^charge] [desk (charge c)])
139 | ::
140 | %add-charge
141 | %- pairs
142 | :~ desk+s+desk.u
143 | charge+(charge charge.u)
144 | ==
145 | ==
146 | ::
147 | ++ num
148 | |= a=@u
149 | ^- ^tape
150 | =/ p=json (numb a)
151 | ?> ?=(%n -.p)
152 | (trip p.p)
153 | ::
154 | ++ version
155 | |= v=^version
156 | ^- json
157 | :- %s
158 | %- crip
159 | "{(num major.v)}.{(num minor.v)}.{(num patch.v)}"
160 | ::
161 | ++ merge
162 | |= [a=json b=json]
163 | ^- json
164 | ?> &(?=(%o -.a) ?=(%o -.b))
165 | [%o (~(uni by p.a) p.b)]
166 | ::
167 | ++ href
168 | |= h=^href
169 | %+ frond -.h
170 | ?- -.h
171 | %site s+(spat path.h)
172 | %glob
173 | %- pairs
174 | :~ base+s+base.h
175 | glob-reference+(glob-reference glob-reference.h)
176 | ==
177 | ==
178 | ::
179 | ++ glob-reference
180 | |= ref=^glob-reference
181 | %- pairs
182 | :~ hash+s+(scot %uv hash.ref)
183 | location+(glob-location location.ref)
184 | ==
185 | ::
186 | ++ glob-location
187 | |= loc=^glob-location
188 | ^- json
189 | %+ frond -.loc
190 | ?- -.loc
191 | %http s+url.loc
192 | %ames s+(scot %p ship.loc)
193 | ==
194 | ::
195 | ++ charge
196 | |= c=^charge
197 | %+ merge (docket docket.c)
198 | %- pairs
199 | :~ chad+(chad chad.c)
200 | ==
201 | ::
202 | ++ docket
203 | |= d=^docket
204 | ^- json
205 | %- pairs
206 | :~ title+s+title.d
207 | info+s+info.d
208 | color+s+(scot %ux color.d)
209 | href+(href href.d)
210 | image+?~(image.d ~ s+u.image.d)
211 | version+(version version.d)
212 | license+s+license.d
213 | website+s+website.d
214 | ==
215 | ::
216 | ++ chad
217 | |= c=^chad
218 | %+ frond -.c
219 | ?+ -.c ~
220 | %hung s+err.c
221 | ==
222 | --
223 | --
224 |
--------------------------------------------------------------------------------
/tanote/lib/jose.hoon:
--------------------------------------------------------------------------------
1 | /+ primitive-rsa, *pkcs
2 | =* rsa primitive-rsa
3 | |%
4 | :: +en-base64url: url-safe base64 encoding, without padding
5 | ::
6 | ++ en-base64url
7 | ~(en base64:mimes:html | &)
8 | :: +de-base64url: url-safe base64 decoding, without padding
9 | ::
10 | ++ de-base64url
11 | ~(de base64:mimes:html | &)
12 | :: |octn: encode/decode unsigned atoms as big-endian octet stream
13 | ::
14 | ++ octn
15 | |%
16 | ++ en |=(a=@u `octs`[(met 3 a) (swp 3 a)])
17 | ++ de |=(a=octs `@u`(rev 3 p.a q.a))
18 | --
19 | :: +eor: explicit sort order comparator
20 | ::
21 | :: Lookup :a and :b in :lit, and pass their indices to :com.
22 | ::
23 | ++ eor
24 | |= [com=$-([@ @] ?) lit=(list)]
25 | |= [a=* b=*]
26 | ^- ?
27 | (fall (bind (both (find ~[a] lit) (find ~[b] lit)) com) |)
28 | :: +en-json-sort: json encoding with sorted object keys
29 | ::
30 | :: XX move %zuse with sorting optional?
31 | ::
32 | ++ en-json-sort :: XX rename
33 | |^ |=([sor=$-(^ ?) val=json] (apex val sor ""))
34 | :: :: ++apex:en-json:html
35 | ++ apex
36 | =, en-json:html
37 | |= [val=json sor=$-(^ ?) rez=tape]
38 | ^- tape
39 | ?~ val (weld "null" rez)
40 | ?- -.val
41 | %a
42 | :- '['
43 | =. rez [']' rez]
44 | !.
45 | ?~ p.val rez
46 | |-
47 | ?~ t.p.val ^$(val i.p.val)
48 | ^$(val i.p.val, rez [',' $(p.val t.p.val)])
49 | ::
50 | %b (weld ?:(p.val "true" "false") rez)
51 | %n (weld (trip p.val) rez)
52 | %s
53 | :- '"'
54 | =. rez ['"' rez]
55 | =+ viz=(trip p.val)
56 | !.
57 | |- ^- tape
58 | ?~ viz rez
59 | =+ hed=(jesc i.viz)
60 | ?: ?=([@ ~] hed)
61 | [i.hed $(viz t.viz)]
62 | (weld hed $(viz t.viz))
63 | ::
64 | %o
65 | :- '{'
66 | =. rez ['}' rez]
67 | =/ viz
68 | %+ sort ~(tap by p.val)
69 | |=((pair) (sor (head p) (head q)))
70 | ?~ viz rez
71 | !.
72 | |- ^+ rez
73 | ?~ t.viz ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)])
74 | =. rez [',' $(viz t.viz)]
75 | ^$(val [%s p.i.viz], rez [':' ^$(val q.i.viz)])
76 | ==
77 | --
78 | :: %/lib/jose
79 | ::
80 | :: |jwk: json representations of cryptographic keys (rfc7517)
81 | ::
82 | :: Url-safe base64 encoding of key parameters in big-endian byte order.
83 | :: RSA-only for now
84 | ::
85 | ++ jwk
86 | |%
87 | :: |en:jwk: encoding of json cryptographic keys
88 | ::
89 | ++ en
90 | => |%
91 | :: +numb:en:jwk: base64-url encode big-endian number
92 | ::
93 | ++ numb (corl en-base64url en:octn)
94 | --
95 | |%
96 | :: +pass:en:jwk: json encode public key
97 | ::
98 | ++ pass
99 | |= k=key:rsa
100 | ^- json
101 | [%o (my kty+s+'RSA' n+s+(numb n.pub.k) e+s+(numb e.pub.k) ~)]
102 | :: +ring:en:jwk: json encode private key
103 | ::
104 | ++ ring
105 | |= k=key:rsa
106 | ^- json
107 | ~| %rsa-need-ring
108 | ?> ?=(^ sek.k)
109 | :- %o %- my :~
110 | kty+s+'RSA'
111 | n+s+(numb n.pub.k)
112 | e+s+(numb e.pub.k)
113 | d+s+(numb d.u.sek.k)
114 | p+s+(numb p.u.sek.k)
115 | q+s+(numb q.u.sek.k)
116 | ==
117 | --
118 | :: |de:jwk: decoding of json cryptographic keys
119 | ::
120 | ++ de
121 | =, dejs-soft:format
122 | => |%
123 | :: +numb:de:jwk: parse base64-url big-endian number
124 | ::
125 | ++ numb (cu (cork de-base64url (lift de:octn)) so)
126 | --
127 | |%
128 | :: +pass:de:jwk: decode json public key
129 | ::
130 | ++ pass
131 | %+ ci
132 | =/ a (unit @ux)
133 | |= [kty=@t n=a e=a]
134 | ^- (unit key:rsa)
135 | =/ pub (both n e)
136 | ?~(pub ~ `[u.pub ~])
137 | (ot kty+(su (jest 'RSA')) n+numb e+numb ~)
138 | :: +ring:de:jwk: decode json private key
139 | ::
140 | ++ ring
141 | %+ ci
142 | =/ a (unit @ux)
143 | |= [kty=@t n=a e=a d=a p=a q=a]
144 | ^- (unit key:rsa)
145 | =/ pub (both n e)
146 | =/ sek :(both d p q)
147 | ?:(|(?=(~ pub) ?=(~ sek)) ~ `[u.pub sek])
148 | (ot kty+(su (jest 'RSA')) n+numb e+numb d+numb p+numb q+numb ~)
149 | --
150 | :: |thumb:jwk: "thumbprint" json-encoded key (rfc7638)
151 | ::
152 | ++ thumb
153 | |%
154 | :: +pass:thumb:jwk: thumbprint json-encoded public key
155 | ::
156 | ++ pass
157 | |= k=key:rsa
158 | (en-base64url 32 (shax (crip (en-json-sort aor (pass:en k)))))
159 | :: +ring:thumb:jwk: thumbprint json-encoded private key
160 | ::
161 | ++ ring !!
162 | --
163 | --
164 | :: |jws: json web signatures (rfc7515)
165 | ::
166 | :: Note: flattened signature form only.
167 | ::
168 | ++ jws
169 | |%
170 | :: +sign:jws: sign json value
171 | ::
172 | ++ sign
173 | |= [k=key:rsa pro=json lod=json]
174 | |^ ^- json
175 | =. pro header
176 | =/ protect=cord (encode pro)
177 | =/ payload=cord (encode lod)
178 | :- %o %- my :~
179 | protected+s+protect
180 | payload+s+payload
181 | signature+s+(sign protect payload)
182 | ==
183 | :: +header:sign:jws: set signature algorithm in header
184 | ::
185 | ++ header
186 | ?> ?=([%o *] pro)
187 | ^- json
188 | [%o (~(put by p.pro) %alg s+'RS256')]
189 | :: +encode:sign:jws: encode json for signing
190 | ::
191 | :: Alphabetically sort object keys, url-safe base64 encode
192 | :: the serialized json.
193 | ::
194 | ++ encode
195 | |= jon=json
196 | %- en-base64url
197 | %- as-octt:mimes:html
198 | (en-json-sort aor jon)
199 | :: +sign:sign:jws: compute signature
200 | ::
201 | :: Url-safe base64 encode in big-endian byte order.
202 | ::
203 | ++ sign
204 | |= [protect=cord payload=cord]
205 | =/ msg=@t (rap 3 ~[protect '.' payload])
206 | =/ sig=@ud (~(sign rs256 k) (met 3 msg) msg)
207 | =/ len=@ud (met 3 n.pub.k)
208 | (en-base64url len (rev 3 len sig))
209 | --
210 | :: +verify:jws: verify signature
211 | ::
212 | ++ verify !!
213 | --
214 | --
215 |
--------------------------------------------------------------------------------