<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>seelabs blog</title>
    <subtitle>Notes on seelabs: break a big thing into littler things that add up.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://blog.seelabs.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://blog.seelabs.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-14T00:00:00+00:00</updated>
    <id>https://blog.seelabs.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Seelabs for b-liner users</title>
        <published>2026-10-14T00:00:00+00:00</published>
        <updated>2026-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://blog.seelabs.com/seelabs-for-b-liner-users/"/>
        <id>https://blog.seelabs.com/seelabs-for-b-liner-users/</id>
        
        <content type="html" xml:base="https://blog.seelabs.com/seelabs-for-b-liner-users/">&lt;p&gt;For a while I used b-liner almost every day. I used it for research, exploring
new ideas, and quick and dirty scheduling. It fits the way I work. Since I&#39;m
mostly a Linux and Emacs user, I switched to using Emacs&#39; org-mode many years
ago. Seelabs takes what I liked best about b-liner and combines it with ideas
from org-mode, GitHub, ProjectionLab (the app I use for financial planning),
vim, and some ideas of my own.&lt;/p&gt;
&lt;h2 id=&quot;largest-changes-from-b-liner&quot;&gt;Largest changes from b-liner&lt;/h2&gt;
&lt;p&gt;The biggest added functionality from b-liner is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;timelines (including directly editing timelines)&lt;/li&gt;
&lt;li&gt;simulations for both scheduling and financial models&lt;/li&gt;
&lt;li&gt;dependencies for scheduling&lt;/li&gt;
&lt;li&gt;periods: a period is one slice of a model&#39;s timeline. It&#39;s useful for
financial models where a node representing &quot;liquid net worth&quot; has different
values over time, or a node representing &quot;social security&quot; has different
values if the person is younger or older than 67 for the period&lt;/li&gt;
&lt;li&gt;scenarios (&quot;what ifs&quot;)&lt;/li&gt;
&lt;li&gt;collaboration (including permissions on sub-trees and GitHub-style pull
requests)&lt;/li&gt;
&lt;li&gt;fields instead of spreadsheets (fields are reactive. If you change a field
value dependent fields automatically update)&lt;/li&gt;
&lt;li&gt;fields can optionally be displayed on a node, and different widgets can be
used to display field values on a node (a &quot;percent done&quot; progress bar, for
example)&lt;/li&gt;
&lt;li&gt;different formula model. Seelabs uses Python expressions and guards. A &quot;guard&quot;
is used to let fields act differently for different periods, or act
differently if a node has children or not&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I tried to keep b-liner&#39;s main editing functions, but there&#39;s also a vim-like
mode for interacting with the model.&lt;/p&gt;
&lt;h2 id=&quot;use-cases&quot;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;I&#39;d like to use this for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Financial modeling. I&#39;d like to use seelabs for what I&#39;m currently doing in
ProjectionLab.&lt;/li&gt;
&lt;li&gt;Scheduling, especially quick and dirty schedules like I used to do with b-liner.&lt;/li&gt;
&lt;li&gt;Summarize daily web sites into a tree for quick browsing without the
temptation to spend too much time on the sites.&lt;/li&gt;
&lt;li&gt;Collaborative research. Start fleshing out a topic and let other people
contribute by submitting PRs or just directly editing the tree (and using
permissions to keep things sane).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;simple-navigating-and-editing&quot;&gt;Simple Navigating and Editing&lt;/h2&gt;
&lt;p&gt;I no longer have access to b-liner, so my memory of b-liner editing commands may
be off. These are the fundamental commands to create and edit trees:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Action&lt;/th&gt;&lt;th&gt;Key&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Add a sibling to the current node&lt;/td&gt;&lt;td&gt;Enter&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Add a child to the current node&lt;/td&gt;&lt;td&gt;Ctrl-Enter&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Hide/Show the current node&#39;s children&lt;/td&gt;&lt;td&gt;Tab&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;When you add a new node you&#39;ll immediately enter the node&#39;s headline.&lt;/p&gt;
&lt;p&gt;The arrow keys change what the current node is.&lt;/p&gt;
&lt;p&gt;The one non-b-liner key you&#39;ll need at this point is &lt;code&gt;i&lt;/code&gt;. If you press &lt;code&gt;i&lt;/code&gt; it
will let you edit the current node&#39;s headline.&lt;/p&gt;
&lt;p&gt;There&#39;s more functionality to introduce, of course. But those few commands will
get you going and let you create simple outlines.&lt;/p&gt;
&lt;h2 id=&quot;f-is-your-friend&quot;&gt;&lt;code&gt;f&lt;/code&gt; is your friend&lt;/h2&gt;
&lt;p&gt;I&#39;m a heavy keyboard user. Seelabs is designed so you can efficiently use it
without ever touching the mouse. An important way this is done is with &quot;hints&quot;.
The &lt;code&gt;f&lt;/code&gt; key is used for hints (&lt;code&gt;f&lt;/code&gt; is your friend). It lets you quickly jump to
any node or press any control. If you press &lt;code&gt;f&lt;/code&gt;, each node will display a &quot;hint&quot;
or short tag consisting of one or two letters. If you type the letters in a
hint, it will set the current node to the node whose hint you typed.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;f&lt;/code&gt; will also display hints next to controls. So it&#39;s easy to press buttons or
select items in drop-down boxes using hints.&lt;/p&gt;
&lt;p&gt;Hints can also be used to quickly cut any node, or add a child to any node,
or paste a sub-tree as a child on any node. The way this works is almost all
commands take the form of [count] operator target, where operator is usually a
single character (e.g. &lt;code&gt;d&lt;/code&gt; for cut). If you want to cut a particular node and
it&#39;s not the current node, type &lt;code&gt;df&lt;/code&gt;, then type the hint, and the node whose
hint you typed will be cut. This works for almost all commands. &lt;code&gt;z&lt;/code&gt; is the
hide/show command. So &lt;code&gt;zf&lt;/code&gt; lets you pick any node to hide/show the children. As
an aside, typing the same letter twice usually means &quot;act on the current node&quot;.
So &lt;code&gt;dd&lt;/code&gt; cuts the current node. &lt;code&gt;zz&lt;/code&gt; hides/shows the current node (Tab also
works). Working with a tree this way is similar to how vim commands work.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; shows every key available where you are, and &lt;code&gt;u&lt;/code&gt; undoes anything.&lt;/p&gt;
&lt;p&gt;There are also &lt;code&gt;:&lt;/code&gt; commands, like in vim. Not everything is available as a
visible GUI element right now.&lt;/p&gt;
&lt;p&gt;It&#39;s very powerful, but of course, this is for power users. Using the mouse,
arrow keys, and Ctrl-x, Ctrl-c, and Ctrl-v also work (and I&#39;ll make sure every
&lt;code&gt;:&lt;/code&gt; command is available on the GUI somewhere). While I don&#39;t expect many users
to adapt to the [count]-operator-target workflow, I do hope users will still use
&lt;code&gt;f&lt;/code&gt; to quickly set the current node.&lt;/p&gt;
&lt;h2 id=&quot;fields&quot;&gt;Fields&lt;/h2&gt;
&lt;p&gt;b-liner supported hierarchical spreadsheets. This was very powerful. Seelabs
doesn&#39;t have spreadsheets. Instead, nodes can have fields. Fields can be
literals, and common data types for scheduling and financial models are
supported:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Holds&lt;/th&gt;&lt;th&gt;Example&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Text&lt;/td&gt;&lt;td&gt;A string.&lt;/td&gt;&lt;td&gt;&lt;code&gt;Kitchen remodel&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Integer&lt;/td&gt;&lt;td&gt;A whole number.&lt;/td&gt;&lt;td&gt;&lt;code&gt;42&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Float&lt;/td&gt;&lt;td&gt;A decimal number.&lt;/td&gt;&lt;td&gt;&lt;code&gt;3.75&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Boolean&lt;/td&gt;&lt;td&gt;&lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;.&lt;/td&gt;&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Date&lt;/td&gt;&lt;td&gt;A calendar date.&lt;/td&gt;&lt;td&gt;&lt;code&gt;2026-11-02&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Timestamp&lt;/td&gt;&lt;td&gt;A date plus a time of day.&lt;/td&gt;&lt;td&gt;&lt;code&gt;2026-11-02 14:30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Duration&lt;/td&gt;&lt;td&gt;Elapsed time: &lt;code&gt;1d&lt;/code&gt; = 24h, &lt;code&gt;1w&lt;/code&gt; = 7d.&lt;/td&gt;&lt;td&gt;&lt;code&gt;2d&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Effort&lt;/td&gt;&lt;td&gt;Working time: &lt;code&gt;1d&lt;/code&gt; = 8h, &lt;code&gt;1w&lt;/code&gt; = 5d, &lt;code&gt;1mo&lt;/code&gt; = 20d.&lt;/td&gt;&lt;td&gt;&lt;code&gt;3d&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Currency&lt;/td&gt;&lt;td&gt;Money: an exact amount plus a currency code.&lt;/td&gt;&lt;td&gt;&lt;code&gt;$1,250.00&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Url&lt;/td&gt;&lt;td&gt;An http(s) link, with an optional display label.&lt;/td&gt;&lt;td&gt;&lt;code&gt;https://seelabs.com&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Fields can also be formulas. When adding a field, a field has one of three
&quot;value shapes&quot;: simple, rollup, and guarded.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Simple&lt;/dt&gt;
&lt;dd&gt;A value or formula with no condition.&lt;/dd&gt;
&lt;dt&gt;Rollup&lt;/dt&gt;
&lt;dd&gt;A value computed from the node&#39;s children (sum, count, max, min, average,
weighted average, custom formula), or the node&#39;s own value when it has no
children.&lt;/dd&gt;
&lt;dt&gt;Guarded&lt;/dt&gt;
&lt;dd&gt;A list of conditional values; the first whose condition holds is used.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The formulas in seelabs are Python expressions. There&#39;s an embedded expression
engine on the seelabs server (Starlark).&lt;/p&gt;
&lt;p&gt;&quot;Rollup&quot; is how I usually used spreadsheets in b-liner. I had a task that I
would break down into sub-tasks and the parent would hold the sum of the effort
or cost of the sub-tasks.&lt;/p&gt;
&lt;p&gt;&quot;Guards&quot; are used in many places in seelabs. They are really just a way to write
cascading &quot;if&quot; statements.&lt;/p&gt;
&lt;p&gt;You can add fields to a node by typing &lt;code&gt;F&lt;/code&gt; to toggle the &quot;fields&quot; panel. This is
where you can edit the fields on a node. You can also group fields into logical
categories and assign permissions to groups of fields.&lt;/p&gt;
&lt;h2 id=&quot;display-on-node&quot;&gt;Display On Node&lt;/h2&gt;
&lt;p&gt;You can decide if a field&#39;s value should be visible on a node, and how the value
should be displayed. Most of the time text will be used, but other widgets are
available (progress bars, status boxes, checkboxes). Guards can also be used to
display different widgets based on different conditions.&lt;/p&gt;
&lt;h2 id=&quot;node-types&quot;&gt;Node types&lt;/h2&gt;
&lt;p&gt;Once you assign fields to a node, you may want to give that node a type. For
example, in a schedule you may have nodes that have fields for tasks (effort,
predecessors), and you may have nodes for resources that have fields for
department and hourly rate. When you add nodes to different parts of the model
you want to add the right type of node. Node types let you do this. Nodes can
restrict what types of nodes can be children, and you can define a default node
type to be added if the user doesn&#39;t specify one (for example, task nodes add
other task nodes as children).&lt;/p&gt;
&lt;h2 id=&quot;timelines&quot;&gt;Timelines&lt;/h2&gt;
&lt;p&gt;These are Gantt charts. For schedules, they know about dependencies and will
draw arrows for the dependency. Most bars are editable and changes made to the
timeline will be made in the tree model. For financial models, it&#39;s useful to
view the different plots while looking at the timeline (both will use the same
x-axis so it&#39;s easy to compare). This makes it easy to match up major events
like &quot;retirement&quot; with changes to plots like &quot;liquid net worth&quot;.&lt;/p&gt;
&lt;h2 id=&quot;simulations&quot;&gt;Simulations&lt;/h2&gt;
&lt;p&gt;Fields can have values drawn from a distribution. For example, in a schedule, a
task may have an effort with an optimistic, pessimistic, and likely effort
value. This will be modeled as a &quot;pert&quot; distribution. A simulation can then be
run and all the fields that take their values from a distribution will be
sampled and all the other dependent values re-calculated. These are then saved
as distributions themselves. When many replications of this have been run, all
the saved distributions can be viewed and conclusions drawn. For example, what
is the probability a parent task will be done at a particular date? What is the
date that I have a 90% chance that this parent task will be complete?&lt;/p&gt;
&lt;p&gt;Simulations work the same way for financial models as well, but they are more
computationally expensive because they need to simulate over many periods of
time (financial model fields have a value per model &quot;period&quot;).&lt;/p&gt;
&lt;h2 id=&quot;financial-models&quot;&gt;Financial Models&lt;/h2&gt;
&lt;p&gt;There is some special functionality to support financial models. &quot;Periods&quot;, of
course. There are also currency data types (with currency codes - so if you own a
house in Canada, it knows the value is in CAD and there&#39;s a way to convert to
USD in the model). There are also functions that work with currencies so all the
parts add up as an accountant would expect. For example, the &quot;allocate&quot; function
would split $100 three ways as $33.34, $33.33, and $33.33; the &quot;drain&quot; function
withdraws from accounts in order.&lt;/p&gt;
&lt;p&gt;There is also a useful plot in financial models that shows a particular value
over the model&#39;s period (typically &quot;net worth&quot; or &quot;liquid net worth&quot;).&lt;/p&gt;
&lt;p&gt;With simulations, you&#39;ll get a &quot;fan chart&quot; that shows a Field across the
Periods. There&#39;s a line for the median outcome, and bands around it for less
likely outcomes. You can also add &quot;goals&quot;, such as &quot;liquid net worth &amp;gt; 0&quot; and
see how often that goal is met during a simulation. There&#39;s also a plot of the
distribution of the main value at the given period (e.g. &quot;what&#39;s the simulation
say the distribution of my net worth will be in 2045?&quot;). Scenarios (what-ifs)
can also be plotted against the main model.&lt;/p&gt;
&lt;p&gt;Financial models can handle inflation and one-time events as well. There&#39;s a
Claude skill called &lt;code&gt;/lets-see-finance&lt;/code&gt; to design an initial financial model that
you can then tweak yourself.&lt;/p&gt;
&lt;h2 id=&quot;what-if-scenarios&quot;&gt;What-if Scenarios&lt;/h2&gt;
&lt;p&gt;Both schedules and financial models need to compare what happens if different
choices are made. What happens if I buy a vacation house? What if I retire at 65
or 70? Should I refinance my mortgage or not? Hire now or next quarter? In
seelabs each of those is a &quot;Scenario&quot; — a named alternative to your main model.
A scenario holds just the changes that make it. Edit the main model and every
Scenario follows along.&lt;/p&gt;
&lt;p&gt;&quot;Simulate all&quot; runs the main model and every Scenario on the &lt;em&gt;same&lt;/em&gt; random
draws. This means every model sees the same crashes and booms and the only
difference between them is the choice you&#39;re weighing.&lt;/p&gt;
&lt;p&gt;Then it lines up each goal&#39;s chance side by side. For example:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Goal&lt;/th&gt;&lt;th&gt;Retire at 65&lt;/th&gt;&lt;th&gt;Retire at 70&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Savings stay above zero&lt;/td&gt;&lt;td&gt;64%&lt;/td&gt;&lt;td&gt;81%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;You also have the option to accept a scenario to make it part of the main model.&lt;/p&gt;
&lt;h2 id=&quot;more-on-schedules&quot;&gt;More On Schedules&lt;/h2&gt;
&lt;p&gt;Seelabs is already a good tool for quick and dirty schedules, which is what I
used b-liner for. There&#39;s some additional support for task dependencies, Gantt
charts, and simulations. Critical paths, optimization, and constraint solving
are partially complete.&lt;/p&gt;
&lt;h2 id=&quot;collaboration&quot;&gt;Collaboration&lt;/h2&gt;
&lt;p&gt;There are two ways to collaborate. One is allowing live editing by everyone who
has access to it. Permissions can make this reasonable. Permission can allow or
deny reading or writing on a project, node, or group of fields. For example,
salaries can be put in a group and most people could be denied access to the
salary, but could still participate in estimating efforts in task breakdowns
without seeing sensitive salary information.&lt;/p&gt;
&lt;p&gt;The second way is GitHub-like pull requests. This works, but it&#39;s a little wonky
right now (the live view doesn&#39;t quite fit with the model). How this works is
people can submit &quot;pull requests&quot; to your project. This shows each change their
model would make to the project. Users can comment on the differences. Finally,
the project owner can decide to merge or close the PR.&lt;/p&gt;
&lt;h2 id=&quot;browser-extension&quot;&gt;Browser Extension&lt;/h2&gt;
&lt;p&gt;There&#39;s also a browser extension that adds the page you&#39;re reading as a node to
the current node (or a pinned &quot;target&quot; node). This seems like a good way to
easily add references for a topic and put it in a tree with all your other
thoughts on that topic.&lt;/p&gt;
&lt;h2 id=&quot;lets-see&quot;&gt;/lets-see&lt;/h2&gt;
&lt;p&gt;There is an interface to Claude Code called &quot;/lets-see&quot; with sub-categories for
scheduling, financial models, and research.&lt;/p&gt;
&lt;h2 id=&quot;try-it&quot;&gt;Try It&lt;/h2&gt;
&lt;p&gt;There are read-only demo trees at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://beta.seelabs.com/jellyfish/landing/trees/financial-model&quot;&gt;Financial model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://beta.seelabs.com/jellyfish/landing/trees/schedule&quot;&gt;Schedule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://beta.seelabs.com/jellyfish/landing/trees/research&quot;&gt;Research&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Type &lt;code&gt;?&lt;/code&gt; for a list of key bindings (that page scrolls). Look at the timeline
and simulation pages. And remember &lt;code&gt;f&lt;/code&gt; is your friend.&lt;/p&gt;
</content>
        
    </entry>
</feed>
