::                                                      ::  ::
::::  /hook/core/dojo/app                               ::  ::::
  ::                                                    ::    ::
/?  314                                                 ::  arvo kelvin
/-  *console                                            ::  console structures
/+  console                                             ::  console library
::                                                      ::  ::
::::                                                    ::  ::::
  !:                                                    ::    ::
=>  |%                                                  ::  external structures
    ++  house                                           ::  all state
      $:  hoc=(map bone session)                        ::  conversations
      ==                                                ::
    ++  session                                         ::  per conversation
      $:  say=console-share                             ::  command-line state
          syd=desk                                      ::  active desk 
          luc=(unit case)                               ::  special case
          poy=(unit dojo-project)                       ::  working 
          var=(map term cage)                           ::  variable state
          old=(set term)                                ::  used TLVs
      ==                                                ::
    ++  dojo-command                                    ::
      $%  [%flat p=path q=dojo-source]                  ::  noun to unix atom
          [%pill p=path q=dojo-source]                  ::  noun to unix pill
          [%poke p=goal q=dojo-source]                  ::  make and poke
          [%show p=dojo-source]                         ::  print
          [%verb p=term q=dojo-source]                  ::  store variable
      ==                                                ::
    ++  dojo-source                                     ::  construction node
      $:  p=@ud                                         ::  assembly index
          q=dojo-build                                  ::  general build
      ==                                                ::
    ++  dojo-build                                      ::  one ford step
      $%  [%ex p=twig]                                  ::  hoon expression
          [%di p=dojo-model]                            ::  dialog
          [%dv p=path]                                  ::  gate from source
          [%fi p=(list dojo-filter) q=dojo-source]      ::  filter pipeline
          [%sc p=dojo-model]                            ::  script
          [%tu p=(list dojo-source)]                    ::  tuple
          [%va p=term]                                  ::  dojo variable
      ==                                                ::
    ++  dojo-filter                                     ::  pipeline filter
      $%  [%a p=twig]                                   ::  direct gate
          [%b p=mark]                                   ::  simple transmute
          [%c p=dojo-source]                            ::  full filter
      ==                                                ::
    ++  dojo-model                                      ::  data construction 
      $:  p=dojo-server                                 ::  core source
          q=dojo-config                                 ::  configuration
      ==                                                ::
    ++  dojo-server                                     ::  numbered device
      $:  p=@ud                                         ::  assembly index
          q=path                                        ::  gate path
      ==                                                ::
    ++  dojo-config                                     ::  configuration
      $:  p=(list dojo-source)                          ::  by order
          q=(map term (unit dojo-source))               ::  by keyword
      ==                                                ::
    ++  dojo-project                                    ::  construction state
      $:  mad=dojo-command                              ::  operation
          num=@ud                                       ::  number of tasks
          cud=(unit dojo-source)                        ::  now solving
          pux=(unit path)                               ::  ford working
          pro=(unit vase)                               ::  prompting loop
          per=(unit console-edit)                       ::  pending reverse
          job=(map ,@ud dojo-build)                     ::  problems
          rez=(map ,@ud cage)                           ::  results
      ==                                                ::
    ++  bead  ,[p=(set beam) q=cage]                    ::  computed result
    ++  goal  ,[p=ship q=term]                          ::  flat application
    ++  gift                                            ::  out result <-$
      $%  [%mean p=ares]                                ::  error
          [%nice ~]                                     ::  acknowledge
          [%rush %console-effect console-effect]        ::  
      ==                                                ::
    ++  hapt  ,[p=ship q=path]                          ::  
    ++  move  ,[p=bone q=(mold note gift)]              ::
    ++  hood                                            ::  assembly plan
      $:  zus=@ud                                       ::  zuse kelvin
          sur=(list hoot)                               ::  structures
          lib=(list hoof)                               ::  libraries
          fan=(list horn)                               ::  resources
          src=(list hoop)                               ::  program
      ==                                                ::
    ++  hoof  (pair term (unit (pair case ship)))       ::  resource reference
    ++  hoot  (pair bean hoof)                          ::  structure gate/core
    ++  hoop                                            ::  source in hood
      $%  [%& p=twig]                                   ::  direct twig
          [%| p=beam]                                   ::  resource location   
      ==                                                ::
    ++  horn                                            ::  resource tree
      $%  [%ape p=twig]                                 ::  /~  twig by hand
          [%arg p=twig]                                 ::  /$  argument
          [%day p=horn]                                 ::  /|  list by @dr
          [%dub p=term q=horn]                          ::  /=  apply face
          [%fan p=(list horn)]                          ::  /.  list
          [%for p=path q=horn]                          ::  /,  descend
          [%hel p=@ud q=horn]                           ::  /%  propagate heel
          [%hub p=horn]                                 ::  /@  list by @ud
          [%man p=(map span horn)]                      ::  /*  hetero map
          [%nap p=horn]                                 ::  /_  homo map
          [%now p=horn]                                 ::  /&  list by @da
          [%saw p=twig q=horn]                          ::  /;  operate on
          [%see p=beam q=horn]                          ::  /:  relative to
          [%sic p=tile q=horn]                          ::  /^  cast
          [%toy p=mark]                                 ::  /mark/  static
      ==                                                ::
    ++  silk                                            ::  construction layer
      $&  [p=silk q=silk]                               ::  cons
      $%  [%bake p=mark q=beam r=path]                  ::  local synthesis
          [%boil p=mark q=beam r=path]                  ::  general synthesis
          [%call p=silk q=silk]                         ::  slam
          [%cast p=mark q=silk]                         ::  translate
          [%done p=(set beam) q=cage]                   ::  literal
          [%dude p=tank q=silk]                         ::  error wrap
          [%dune p=(set beam) q=(unit cage)]            ::  unit literal
          [%mute p=silk q=(list (pair wing silk))]      ::  mutant
          [%plan p=beam q=spur r=hood]                  ::  structured assembly
          [%reef ~]                                     ::  kernel reef
          [%ride p=twig q=silk]                         ::  silk thru twig
          [%vale p=mark q=ship r=*]                     ::  validate [our his]
      ==                                                ::
    ++  note-ford                                       ::  note to ford
      $%  [%exec p=@p q=(unit silk)]                    ::  make / kill
      ==                                                ::
    ++  note-gall                                       ::  note to %gall
      $%  [%mess p=[p=ship q=path] q=ship r=cage]       ::
      ==                                                ::
    ++  sign-gall                                       ::  sign from %gall
      $%  [%mean p=ares]                                ::
          [%nice ~]                                     ::
      ==                                                ::
    ++  sign-ford                                       ::  sign from ford
      $%  [%made p=(each bead (list tank))]             ::  computed result
      ==                                                ::
    ++  note                                            ::  out request $->
      $%  [%f note-ford]                                ::
          [%g note-gall]                                ::
      ==                                                ::
    ++  sign                                            ::  in result $<-
      $%  [%f sign-ford]                                ::
          [%g sign-gall]                                ::
      ==                                                ::
    --                                                  ::
::                                                      ::
::::                                                    ::
  ::                                                    ::
|_  $:  hid=hide                                        ::  system state
        house                                           ::  program state
    ==                                                  ::
++  he                                                  ::  per session
  |_  [[ost=bone moz=(list move)] session]              ::
  ++  dp                                                ::  dojo parser
    |%  
    ++  dp-command                                      ::  ++dojo-command
      %+  knee  *dojo-command  |.  ~+
      ;~  pose
        %+  stag  %poke
        ;~  pfix  bar
          %+  cook
            |=  [a=goal b=(each dojo-source (pair path dojo-config))]
            ^-  (pair goal dojo-source)
            ?-  -.b
              %&  [a p.b]
              %|  [a [0 %di [0 [%gun q.a p.p.b]] q.p.b]]
            ==
          ;~  plug
            dp-goal
            ;~  pose
              (stag %& ;~(pfix ace dp-source))
              (stag %| ;~(plug (plus ;~(pfix fas sym)) dp-config))
            ==
          ==
        ==
      ::
        %+  stag  %verb
        ;~  pfix  tis
          ;~(plug sym ;~(pfix ace dp-source))
        ==
      ::
        %+  stag  %flat 
        ;~  pfix  pat
          ;~(plug (most fas sym) ;~(pfix ace dp-source))
        ==
      ::
        %+  stag  %pill
        ;~  pfix  lus
          ;~(plug (most fas sym) ;~(pfix ace dp-source))
        ==
      ::
        (stag %show dp-source)
      ==
    ++  dp-source  (stag 0 dp-build)                    ::  ++dojo-source
    ++  dp-build                                        ::  ++dojo-build
      %+  knee  *dojo-build  |.  ~+
      ;~  pose
        (ifix [sel ser] (stag %tu (most ace dp-source)))
        ;~(pfix col (stag %di dp-model-gun))
        ;~(pfix pam (stag %sc dp-model-sic))
        ;~(pfix buc (stag %va sym))
        (stag %ex dp-twig)
      ==
    :: 
    ++  dp-goal                                         ::  ++goal
      %+  cook  |=(a=goal a)
      ;~  pose
        ;~  plug
          ;~(pfix sig fed:ag) 
          ;~(pfix fas sym)
        ==
        (cook |=(a=term `goal`[our.hid a]) sym)
      ==
    ++  dp-model-gun  ;~(plug dp-server-gun dp-config)  ::  ++dojo-model
    ++  dp-model-sic  ;~(plug dp-server-sic dp-config)  ::  ++dojo-model
    ++  dp-server-gun   (stag 0 (stag %gun dp-device))  ::  ++dojo-server
    ++  dp-server-sic   (stag 0 (stag %sic dp-device))  ::  ++dojo-server
    ++  dp-twig         wide:(vang & ~)                 ::  ++twig
    ++  dp-device       (most fas sym)                  ::  ++dojo-device
    ++  dp-value                                        ::  ++dojo-source
      %+  cook  |=(a=dojo-source a)
      %+  stag  0
      ;~  pose
        (ifix [kel ker] (stag %tu (most ace dp-source)))
        (stag %va ;~(pfix buc sym))
        (stag %ex dp-twig)
      ==
    ::
    ++  dp-config                                       ::  ++dojo-config
      %+  cook  |=(a=dojo-config a)
      ;~  plug
        (star ;~(pfix ace dp-value))
        %+  cook
          ~(gas by *(map term (unit dojo-source)))
        %+  more  
          ;~(plug com ace)
        ;~  plug 
          ;~(pfix tis sym)
          ;~  pose 
            ;~(pfix ace (stag ~ dp-value)) 
            (easy ~)
          ==
        ==
      ==
    --
  ::
  ++  dy                                                ::  project work
    |_  dojo-project                                    ::
    ++  dy-abet  +>(poy `+<)                            ::  resolve
    ++  dy-amok  +>(poy ~)                              ::  terminate
    ++  dy-ford                                         ::  send work to ford
      |=  [pax=path kas=silk]
      ^+  +>+>
      ?>  ?=(~ pux)
      (he-pass(poy `+>+<(pux `pax)) pax %f %exec our.hid `kas)
    ::
    ++  dy-stop                                         ::  stop work
      ^+  +>
      ?~  pux  +>
      (he-pass(poy ~) u.pux %f %exec our.hid ~)
    ::
    ++  dy-slam                                         ::  call by ford
      |=  [pax=path gat=vase sam=vase]
      ^+  +>+>
      (dy-ford pax %call [%done ~ %noun gat] [%done ~ %noun sam])
    ::
    ++  dy-rush                                         ::  send effects, abet
      |=  fec=console-effect
      ^+  +>+>
      (he-rush(poy `+>+<) fec)
    ::
    ++  dy-rash                                         ::  send effects, amok
      |=  fec=console-effect
      ^+  +>+>
      (he-rush(poy ~) fec)
    ::
    ++  dy-init-command                                 ::  ++dojo-command
      |=  mad=dojo-command
      ^+  [mad +>]
      ?-  -.mad
        %flat  =^(src +>.$ (dy-init-source q.mad) [[%flat p.mad src] +>.$])
        %pill  =^(src +>.$ (dy-init-source q.mad) [[%pill p.mad src] +>.$])
        %poke  =^(src +>.$ (dy-init-source q.mad) [[%poke p.mad src] +>.$])
        %show  =^(src +>.$ (dy-init-source p.mad) [[%show src] +>.$])
        %verb  =^(src +>.$ (dy-init-source q.mad) [[%verb p.mad src] +>.$])
      ==
    ::
    ++  dy-init-source-unit                             ::  (unit dojo-source)
      |=  urc=(unit dojo-source)
      ^+  [urc +>]
      ?~  urc  [~ +>]
      =^  src  +>  (dy-init-source u.urc)
      [`src +>.$]
    ::
    ++  dy-init-source                                  ::  ++dojo-source
      |=  src=dojo-source
      ^+  [src +>]
      =^  bul  +>  (dy-init-build q.src)
      =:  p.src  num
          q.src  bul
        ==
      [src +>.$(num +(num), job (~(put by job) num q.src))]
    ::
    ++  dy-init-build                                   ::  ++dojo-build
      |=  bul=dojo-build
      ^+  [bul +>]
      ?-    -.bul
        %ex  [bul +>.$]
        %di  =^(mod +>.$ (dy-init-model p.bul) [[%di mod] +>.$])
        %dv  [bul +>.$]
        %fi  !!
        %sc  !!
        %tu  =^  dof  +>.$
                 |-  ^+  [p.bul +>.^$]
                 ?~  p.bul  [~ +>.^$]
                 =^  dis  +>.^$  (dy-init-source i.p.bul)
                 =^  mor  +>.^$  $(p.bul t.p.bul)
                 [[dis mor] +>.^$]
             [[%tu dof] +>.$]
        %va  [bul +>.$]
      ==
    ::
    ++  dy-init-model                                   ::  ++dojo-model
      |=  mol=dojo-model
      ^+  [mol +>]
      =^  one  +>.$  (dy-init-server p.mol)
      =^  two  +>.$  (dy-init-config q.mol)
      [[one two] +>.$]
    ::
    ++  dy-init-server                                  ::  ++dojo-server
      |=  srv=dojo-server
      =.  p.srv  num
      [srv +>.$(num +(num), job (~(put by job) num [%dv q.srv]))]
    ::
    ++  dy-init-config                                  ::  prepare config
      |=  cig=dojo-config
      ^+  [cig +>]
      =^  ord  +>.$  (dy-init-ordered p.cig)
      =^  key  +>.$  (dy-init-named q.cig)
      [[ord key] +>.$]
    ::
    ++  dy-init-ordered                                 ::  (list dojo-source)
      |=  ord=(list dojo-source)
      ^+  [ord +>]
      ?~  ord  [~ +>.$]
      =^  fir  +>.$  (dy-init-source i.ord)
      =^  mor  +>.$  $(ord t.ord)
      [[fir mor] +>.$]
    ::
    ++  dy-init-named                                   ::  (map @tas dojo-src)
      |=  key=(map term (unit dojo-source))
      ^+  [key +>.$]
      ?~  key  [~ +>.$]
      =^  top  +>.$  (dy-init-source-unit q.n.key)
      =^  lef  +>.$  $(key l.key)
      =^  rit  +>.$  $(key r.key)
      [[[p.n.key top] lef rit] +>.$]
    ::
    ++  dy-init                                         ::  full initialize
      ^+  .
      =^(dam . (dy-init-command mad) +(mad dam))
    ::
    ++  dy-hand                                         ::  complete step
      |=  cag=cage
      ^+  +>+>
      ?>  ?=(^ cud)
      (dy-step(cud ~, rez (~(put by rez) p.u.cud cag)) +(p.u.cud))
    ::
    ++  dy-meal                                         ::  vase to cage
      |=  vax=vase
      ?.  &(?=(@ -.q.vax) ((sane %tas) -.q.vax))
        ~&  %dy-meal-cage
        (dy-rash %bel ~)
      (dy-hand -.q.vax (slot 3 vax))
    ::
    ++  dy-made-edit                                    ::  console edit
      |=  cag=cage
      ^+  +>+>
      ?>  ?=(^ per)
      ?^  q.q.cag  
        dy-abet(per ~)
      =^  lic  say  (~(transmit cs say) u.per)
      (dy-rush(per ~) %mor [%bel ~] [%det lic] ~)
    ::
    ++  dy-done                                         ::  dialog submit
      |=  txt=tape
      ?>  ?=(^ pro)
      (dy-slam /dial u.pro !>(txt))
    ::
    ++  dy-over                                         ::  finish construction
      ^+  +>
      ?-    -.mad
          %poke       
        ~&  [%dy-over-poke p.mad]
        %-  he-pass(poy ~)
        :*  /poke
            %g
            %mess
            [p.p.mad [q.p.mad ~]]
            our.hid 
            (~(got by rez) p.q.mad)
        ==
      ::
          %flat
        =+  out=q.q:(~(got by rez) p.q.mad)
        ?^  out 
          (dy-rash %tan [%leaf "not an atom"]~)
        (dy-rash %sav p.mad out)
      ::
          %pill
        (dy-rash %sag p.mad q.q:(~(got by rez) p.q.mad))
      ::
          %verb
        dy-amok(var (~(put by var) p.mad (~(got by rez) p.q.mad)))
      ::
          %show
        (dy-rash %tan (sell q:(~(got by rez) p.p.mad)) ~)
      ==
    ::
    ++  dy-edit                                         ::  handle edit
      |=  cal=console-change
      ^+  +>+>
      =+  old=buf.say
      =^  dat  say  (~(receive cs say) cal)
      =.  dat  (~(inverse cs say(buf old)) dat)
      ?:  |(?=(^ per) ?=(^ pux) ?=(~ pro))
        ~&  %dy-edit-busy
        =^  lic  say  (~(transmit cs say) dat)
        (dy-rush %mor [%det lic] [%bel ~] ~)
      (dy-slam(per `dat) /edit u.pro !>((tufa buf.say)))
    ::
    ++  dy-type                                         ::  console action
      |=  act=console-action
      ?-  -.act
        %det  (dy-edit +.act)
        %ret  (dy-done (tufa buf.say))
      ==
    ::
    ++  dy-cage       |=(num=@ud (~(got by rez) num))   ::  known cage
    ++  dy-vase       |=(num=@ud q:(dy-cage num))       ::  known vase
    ++  dy-silk-vase  |=(vax=vase [%done ~ %noun vax])  ::  vase to silk
    ++  dy-silk-config                                  ::  configure
      |=  [cag=cage cig=dojo-config]
      ^-  silk
      :+  %ride  [%cnzy %$]
      :+  %mute  [%done ~ cag]
      ^-  (list (pair wing silk))
      :*  :-  [[~ 12] ~]
          (dy-silk-vase !>([now=lat.hid bec=he-beak]))
      ::
          :-  [[~ 26] ~]
          %-  dy-silk-vase
          |-  ^-  vase
          ?~  p.cig  !>(~)
          (slop (dy-vase p.i.p.cig) $(p.cig t.p.cig))
      ::
          %+  turn  (~(tap by q.cig))
          |=  [a=term b=(unit dojo-source)]
          ^-  (pair wing silk)
          :-  [a [~ 27] ~]
          %-  dy-silk-vase
          ?~(b !>([~ ~]) (dy-vase p.u.b))
      ==
    ::
    ++  dy-silk-init-dial                               ::  init and config
      |=  [cag=cage cig=dojo-config]
      ^-  silk
      (dy-silk-config cag cig)
    ::
    ++  dy-silk-device                                  ::  device to silk
      |=  pax=path
      ^-  silk
      [%boil %gate [he-beak (flop pax)] ~]
    ::
    ++  dy-made-dial                                    ::  dialog product
      |=  cag=cage
      ^+  +>+>
      ?.  ?=([~ ~ *] q.q.cag)
        ~&  %dy-made-dial-fail
        (dy-rash %bel ~)
      =+  tan=((list tank) +14.q.q.cag)
      =.  +>+>.$  (he-rush %tan tan)
      =+  vax=(spec (slot 15 q.cag))
      ?+    -.q.vax  !!
          %& 
        ?~  +.q.vax
          ~&  %dy-made-dial-abort
          (dy-rash %bel ~)
        (dy-meal (slot 7 vax))
      ::
          %|
        =<  he-pone
        %-  dy-rush(pro `(slap (slot 7 vax) [%cnzy %q]))
        [%pro (console-prompt +<.q.vax)]
      ==
    ::
    ++  dy-make                                         ::  build step
      ^+  +>
      ?>  ?=(^ cud)
      %-  dy-ford
      ^-  (pair path silk)
      ?+  -.q.u.cud  !!
        %di  [/dial (dy-silk-init-dial (dy-cage p.p.p.q.u.cud) q.p.q.u.cud)]
        %dv  [/hand (dy-silk-device p.q.u.cud)]
        %ex  [/hand [%ride p.q.u.cud [%reef ~]]]
        %tu  :-  /hand
             :+  %done  ~
             :-  %noun
             |-  ^-  vase
             ?~  p.q.u.cud  !!
             =+  hed=(dy-vase p.i.p.q.u.cud)
             ?~  t.p.q.u.cud  hed
             (slop hed $(p.q.u.cud t.p.q.u.cud))
      ==
    ::
    ++  dy-step                                         ::  advance project
      |=  nex=@ud
      ^+  +>+>
      ?>  ?=(~ cud)
      ?:  =(nex num)
        dy-over
      dy-make(cud `[nex (~(got by job) nex)])
    --
  ::
  ++  he-dope                                           ::  sole user of ++dp
    |=  txt=tape                                        ::
    ^-  (each (unit dojo-command) hair)                 ::  prefix/result
    =+  vex=(dp-command:dp [1 1] txt)
    ?.  =(+((lent txt)) q.p.vex)                        ::  fully parsed
      [%| p.vex]                                        ::  syntax error
    [%& ?~(q.vex ~ `p.u.q.vex)]                         ::  prefix/complete
  ::
  ++  he-duke                                           ::  ++he-dope variant
    |=  txt=tape
    ^-  (each dojo-command ,@ud)
    =+  foy=(he-dope txt)
    ?-  -.foy
      %|  [%| q.p.foy]
      %&  ?~(p.foy [%| (lent txt)] [%& u.p.foy])
    ==
  ::
  ++  he-abet                                           ::  resolve
    [(flop moz) %_(+> hoc (~(put by hoc) ost +<+))]
  ::
  ++  he-beak                                           ::  logical beam
    ^-  beak
    [our.hid syd ?^(luc u.luc [%da lat.hid])]
  ::
  ++  he-give                                           ::  emit gift
    |=  git=gift
    ^+  +>
    %_(+> moz [[ost %give git] moz])
  ::
  ++  he-pass
    |=  [pax=path noy=note]
    %_(+> moz [[ost %pass pax noy] moz])
  ::
  ++  he-rush                                           ::  emit update
    |=  fec=console-effect 
    ^+  +>
    (he-give %rush %console-effect fec)
  ::
  ++  he-peer                                           ::  subscribe to
    he-prom
  ::
  ++  he-pine                                           ::  restore prompt
    ^+  .
    ?^  poy  .
    he-prom:he-pone
  ::
  ++  he-pone                                           ::  clear prompt
    ^+  .
    =^  cal  say  (~(transmit cs say) [%set ~])
    (he-rush %mor [%det cal] ~)
  ::
  ++  he-prom                                           ::  send prompt
    %-  he-rush
    :-  %pro
    [& %$ (tuba (weld (scow %p our.hid) ":dojo> "))]
  ::
  ++  he-made                                           ::  result from ford
    |=  [pax=path rey=(each bead (list tank))]
    ^+  +>
    ?>  ?=(^ poy)
    =<  he-pine
    ?-  -.rey
      %&  %.  q.p.rey
          =+  dye=~(. dy u.poy(pux ~))
          ?+  pax  !!
            [%hand ~]  dy-hand:dye
            [%dial ~]  dy-made-dial:dye
            [%edit ~]  dy-made-edit:dye
          ==
      %|  ~&  [%he-made-fail pax]
          (he-rush(poy ~) %tan p.rey)
    ==
  ::
  ++  he-like                                           ::  accept line
    |=  buf=(list ,@c)
    =(%& -:(he-dope (tufa buf)))
  ::
  ++  he-stir                                           ::  apply change
    |=  cal=console-change
    ^+  +>
    =^  dut  say  (~(remit cs say) cal he-like)
    ?~  dut
      +>.$
    (he-rush %mor [%det u.dut] [%bel ~] ~)
  ::
  ++  he-plan                                           ::  execute command
    |=  mad=dojo-command
    ^+  +>
    ?>  ?=(~ poy)
    he-pine:(dy-step:~(dy-init dy mad [0 ~ ~ ~ ~ ~ ~]) 0)
  ::
  ++  he-done                                           ::  parse command
    |=  txt=tape
    ^+  +>
    =+  doy=(he-duke txt)
    ?-    -.doy
        %|  
      %-  he-rush 
      :~  %mor 
          [%tan [%leaf "syntax error at {<p.doy>}"]~]
          [%bel ~]
      ==
    ::
        %&
      =+  old=(weld "> " (tufa buf.say))
      =^  cal  say  (~(transmit cs say) [%set ~])
      %.  p.doy
      =<  he-plan
      %-  he-rush
      :~  %mor
          [%txt old]
          [%nex ~]
          [%det cal]
      ==
    ==
  ::
  ++  he-type                                           ::  apply input
    |=  act=console-action
    ^+  +>
    ?^  poy
      he-pine:(~(dy-type dy u.poy) act)
    ?-  -.act
      %det  (he-stir +.act)
      %ret  (he-done (tufa buf.say))
    ==
  --
::
++  peer
  |=  [ost=bone her=ship pax=path]
  ^-  [(list move) _+>]
  ?<  (~(has by hoc) ost)
  ?>  =(/console pax)
  ?>  =(her our.hid)
  =<  he-abet
  %~  he-peer  he
  :-  [ost ~]
  ^-  session
  :*  *console-share  ::  say=console-share
      %main           ::  syd=desk
      ~               ::  luc=(unit case)
      ~               ::  poy=(unit dojo-project)
      ~               ::  var=(map term cage)
      ~               ::  old=(set term)
  ==
::
++  poke-console-action
  |=  [ost=bone her=ship act=console-action]
  ^-  [(list move) _+>]
  he-abet:(~(he-type he [ost [ost %give %nice ~]~] (~(got by hoc) ost)) act)
::
++  pour
  |=  [ost=bone pax=path sih=sign]
  ^-  [(list move) _+>]
  ::  ~&  [%dojo-pour pax]
  ?-    -.sih
      %f
    he-abet:(~(he-made he [[ost ~] (~(got by hoc) ost)]) pax +>.sih)
  ::
      %g
    ~&  [%dojo-pour sih]
    [~ +>.$]
  ==
--