Tinderbox Forum

Taming TB with Alfred

[Clarification: I have not yet shared the workflow; hope to do that this week or next.]

Tinderbox is a conceptually simple tool, once you grasp how it goes about its business. Many on this forum complain about the difficult learning curve, and this is my attempt to make some things simpler.

What you want to do and the mechanics of doing it

One trouble, I believe, comes from the multitude of steps involved in conceptually simple tasks. These steps are trivial and logical to someone who understand TB well, but for a newcomer, these can seem like magical incantations.

As illustration, consider a few conceptually very similar tasks. Imagine yourself in the map view with the note “Tinderbox Way” selected, a note with the prototype “Book”. Three tasks concerning colors include: change the background color of the map; change the background color of the note, and change the background color of all books. Two parallel tasks concern changing the font of this note or the font of all book notes.

Under the hood, each of these is setting one attribute of one note. The precise sequence of clicks to make this happen is spread in many places, however, and especially changing the attributes of the prototype note (something you need to do to affect all books) is easy to describe: go there, change it, come back, but for a novice, those instructions don’t always add up to “and Bob’s your uncle”.

An Alternative using Alfred

I am in the process of creating an Alfred workflow that will ease some of this for me. Over the next few messages in this thread, I will show screenshots of it in action. My hope is to get feedback before I release this to the community.

What Alfred enables is a context-specific set of suggestions for actions. Here, it consists of a Python script that talks to TB and gets information about the currently selected note and other details. Based on this, it can suggest actions. Should you pick one of the suggestions, the action is executed. Alfred is just the butler you call for help occasionally, and mostly you are using TB as Eastgate intended.

Seeking your feedback

For the examples shown below, do let me know if these will be helpful to you, or any other suggestions you may have for improvements. Thanks!

I begin with setting attributes. Imagine yourself with this note selected:


I have set up an Alfred workflow that triggers when I press F1. In the query box, if I type “=”, it offers suggestions for setting attributes.


The symbol on the left suggests that the value is not yet fully specified.

I can add a few letters from the name of the attribute, and the list gets narrowed down. Say, I typed “fon”:


This understands acronyms. So I could have said NF for NameFont or MBC for MapBackgroundColor.

I still haven’t said what value to use. I will type a space after “fon” and start typing the name of a font, and see the completion list now:

And if I press enter, or press something such as ⌘7, the corresponding action is executed. Of course, I could have typed a fuller name than “fon” or “co” to narrow down the list.

Understanding values

This system has some understanding of values that TB uses. For colors, you can use “blue” or #0000FF or 0 0 255. For boolean attributes, you can use T, F, 0, 1, Y, N, True, Yes, etc. You can even set more exotic attributes:


Uniform syntax for related actions

To set an attribute for the container rather than the note, start with “==”:


To set an attribute for the prototype (so that it affects all books), start with “=.”


In subsequent messages on this thread, I will describe how to create prototypes, set a container so that all children have a particular prototype, how to tell the system that your book instances are often linked to author instances so that appropriate links are suggested, and finally, how to specify suggestions for children notes, as recently asked for by @jbmanos here.


1 Like

This installment concerns managing prototypes: the ability to set prototypes for new notes, create prototypes quickly, and “importing” prototypes from a config file.

Setting a prototype

Continuing from the previous example, I already have a prototype “book” (and also another I did not mention, p_config).

Let’s say that I created a new note, “Eastgate”, and selected it.


If I press my magical key F1 and type a “.” for prototypes, I get these suggestions:


But I want to use a different prototype that doesn’t yet exist: “company”. So I just add “company” after the “.”, and the suggestions change:


If I now press “enter” or press ⌘1, then a new proto is created (in /meta/protos) and attached to the current note:


What if all notes in a container should have a particular proto?

I now create a new note, “Companies”, select it, and press F1. The command for setting the prototype for new children of a note is “…”. Under the hood, it manipulates the $OnAdd attribute of the note:


Note that the suggestions show all prototypes currently in the doc. If you had typed more, this list gets filtered down to those that match:


The second option there (which I need to work on to look prettier) is that maybe you want to create a new prototype “com” and use it for the children here.

Importing protos

This is WIP (as is everything here, really, but this more so). If the document contains a note at the path /meta/config/protos containing a YAML description of several potential protos, these can be imported or updated: here is an example from the Text of that note:


Now, Alfred, starting with “!” can suggest importing or updating this proto. If you change your mind about the font, change it, and reimport. Plus, since this is just text, you can easily copy it elsewhere. Maybe you want a global store of your protos that you use everywhere, and this could be one mechanism of keeping things synced cheaply:



Feedback sought and welcomed!

1 Like

Telling Tb about typical links

Continuing with our example, imagine that for notes with prototype “book”, you expect to have links to authors.

You can specify this in the text of the note at /meta/config/links


This says that “book” is linked to “author” and the link type is “by”.

In my document, I currently have one instance each of the prototypes book (“Tinderbox way”) and author (“Mark Bernstein”). If I have selected the note “Tinderbox Way” invoke Alfred and type “-”, it suggests possible links to create. The possibilities shown are only for prototypes suggested in the config above, so I get just one suggestion.


If this is not the author I want, I can type in the name, and a suggestion is made to create a note with that name, make it an Author, and link to it:


And if I press enter, I get:


Not shown here is the ability to add notes in other containers. For the created note, suggested destinations include the current container and all containers that have a note with the destination prototype. Thus, if you keep all your authors in some container, you can create the new author there.

One final installment left in this series, coming right up.



Developing Ideas

Suppose you write a lot about people. You may have a prototype called “Person”, and there are certain kinds of notes you tend to associate with people: “Early Childhood”, “Education”, “Books written”, “Controversies”, etc. There may be dozens of these, and not all are relevant to all individuals.

This last installment concerns the ability to specify these kinds of “development of idea” ideas such that for a particular note, context sensitive suggestions are offered. This is also a memory jog of sorts, in the style desired by @jbmanos.

Specifying development suggestions

This is set in /meta/config/develop, and an example is:


Now, when you select a person note and invoke Alfred with a comma, you get suggestions for children:


These children, if added, will of course have their attributes set appropriately. Let’s say we choose ⌘2. Now a child is added for controversies, and this is the note we select next.

What should happen when we invoke Alfred with a comma? There is no prototype associated with the selected note, so no suggestions are made about children. But the container has a prototype – person – and all its suggestions have not been “used”. Thus we get:


Note that “Controversies” is already exists, so that is not suggested again.


And that concludes a tour of what has been built.It is easy to add more functionality, accessible through a uniform interface, with appropriate help and good messages so you know what selecting a possibility will do.

If anything were possible, what would you want through a mechanism such as this?


I plan to add a command “?” that lists the high-level possibilities, and have a secondary hep with each, right in the tool. The goal is to make life easier and reduce cognitive burden, so these little things must be addressed.

This is amazing! Did I miss a link to download the Alfred workflows?

Nope, you did not miss it :slight_smile: I hope to be able to package it up cleanly and share next week. Never shared an Alfred workflow before, so some learning there.

Updated the original note to make this clear.


Thanks for these, which are a generous contribution to the Tinderbox community.

Where I’m confused is that this seems to exchange one complexity for another and with a single point of failure unless a community shares the maintenance of the scripts.

I guess the reason I’m confused is an opening assumption:

There is a mispresumtion of ‘need’ and ‘want’ in the first part. To use a prototype does note require 3 colours to be changed. I feel this is a bit misleading to an audience looking for help. In fact the OP is describing their workflow, but i feel the conflation to being any/everyone’s need is over-reaching.

Also, “The precise sequence of clicks to make this happen is spread in many places,” is not accurate but rather a presumption based on a misunderstanding.

Much of what is described here could be done with action code within the app.

Please don’t read this as an aversion to use of other external automations of Tinderbox, even if it involves buying/leaning an extra tool instead of learning the tool actually being used.

I guess where I’m missing the point is what the real underlying problem is. As far as I can see the Alfred script needs the same information (i.e. the name of some (system) attributes) as you need to do the task as quickly within the app. If you don’t know what attribute you need to change, how does this extra scripting help?


Thanks, Mark, I will try to address your concerns, which may be shared by many.

I did not mean to imply that anyone would need to do all three. Rather, my point is that all three are in some sense very similar, as are the tasks for changing fonts. There is a uniformity in the design and uniformity in what TB does with your actions. What I hope to provide is, for that person who understands that an attribute needs to be changed, a single place to change all attributes.

I would be happy to be proved to have misunderstood how TB works. If you are at a note, and you need to change some attribute of the proto, how do you do it? How many steps are involved? Are those steps clear to a novice? My point is that a user may be at a state of having the right intent (“I want to change attribute X of the proto”) but may not yet know what steps to make that happen.

Let me make clearer what I meant by “many places”. To change the default attribute values, we have to press ⌘1 and go to the first subtab of the second tab, summon up the value and change it. To change visual attributes for a note, it is ⌘1, fourth tab, one of the subtabs. For changing the map background color attribute of a note, it is “go to that map by pressing ↓on that note and right click”. To change the attribute OnAdd, I am not sure what to do (is it “set it in the Rule subtab of gear tab of ⌘1”?) There are other things that are set by going to ⌘8. The beauty of TB is that all these things are attributes: no more and no less, and a uniform access to them could reduce cognitive load, at least for me.

To you, who has a decade plus of TB under their belt, those may all seem the same action (just as, perhaps, English speakers think that playing a sport and playing violin and somewhat related). To a novice, those are fundamentally different actions (just as, in many other languages, there are different verbs for those two "play"s, making them seem further apart than to the English ear).

There may be indeed a uniform way of setting all these things. If there is, we have not done a good enough job at education: I for one do not know how, and that is not for a lack of effort on my part.

That is absolutely true. I am adding zero new functionality. I am merely making some parts easier to access. In fact, for the most part, I am using evaluate() action code that is also used by rules and agents and whatnot.

It helps in a few different ways, I think.

  • Since we can provide Alfred a full list of attributes, it can tell you the attributes (along with a help message) when you type a name partially. Say you remember that the name included the word “Color” in it somewhere. You are shown a list of all color attributes to jog your memory.
  • It understands values, so that I don’t need to remember if a value should be typed as True or true or yes or 1. All of those work. It takes care of quoting, so that what would be finicky otherwise can be done a bit more safely. More importantly, it shows you what it is going to do before you do it.
  • Alfred has some smarts, and can remember your prior selections. Thus, if you are in the habit of changing one particular attribute often, that is the one that is suggested at the top.
  • This can change some multi-step actions into a single step: creating a new proto in a standard location and making it the proto for the current note can be accomplished in one step without moving to that container which holds the proto. Conceptually, you knew that is the action you wanted. Mechanics of making that happen can be abbreviated somewhat, as here.
  • You are right that this does not reduce the effort involved in certain actions. What it does is provide a uniform way of changing a limited set of things. It has different complexity tradeoffs that using TB directly; for certain tasks, this is a a good bargain. For other tasks, this is a bad bargain, and there you should use TB as it is. Think of this as an additional tool, not, heaven forbid, a replacement: the underlying TB doc stays a TB doc throughout. Alfred just comes in occasionally and helps with some little bit here and there.

Finally, the reason for making the long series of messages was to get feedback. As you say, it is presumptuous of me to guess what others need. That is why I am asking what would be useful, and some of those things that people may find useful could easily be fitted in.

Warm regards,

1 Like

Thanks for this useful and expansive reply. Busy right now so a better reflection of this must wait but wanted to say thinks and, as laid bare via separate communication, I’d originally miss-parsed this as creating structure as a means to understanding than the much more productive approach of easing creation of structure already divined form the data. The first is simply process-addiction, whereas the latter is a force-multiplier which can, I think, work well for those looking to use more automation. :slight_smile:

Yes, this is a great service to us Alfred users! Thank you a million!