Firefox is now at version 12.0. Basic AppleScript support (such as getting the URL of the current window) hasn’t worked since version 3.5, and it was intermittently broken in some earlier versions.

Michael Tsai

Realistically, Shelf is going to stop being useful at some point in the next couple of years.

  • The Apple App Store doesn’t permit the sort of AppleScript usage that it relies on, so it’s never going to be an App Store app.

  • As a result (and also as part of a longer-term trend, really), no-one really cares about AppleScript any more. Not that Firefox was ever an exemplary citizen in this respect.

  • Google are killing the social graph API that provided most of the discovery for it.

  • Increasingly few of the services that I’m interested in provide RSS feeds to their data, preferring to be iPhone apps or walled gardens.


Released Shelf 0.0.12

Another week, another Shelf release – this one is 0.0.12 – read the release notes or download the binary.

Loads of stuff in this one, but muttley may like the fact that you can now turn off the background poller and have Shelf look for context only when you hit a global shortcut key. This will also make life nicer for people with smaller screens who don’t want this widow popping to the foreground every time it can figure out who you’re looking at.

Other than that, there are lots of improvements. Shelf should be faster and make less gratuitous network requests. Feed display is prettier, and I make an effort to display recently updated feeds at the top, rather than in random order.

Irritating RSS feed links

A side-effect of all this Google Social lunacy is that I’m seeing a lot of URLs for people that I wouldn’t normally have put in their Address Book entries. For instance, Simon Wistow’s Vox page links to his gestalt page which in turn links to his use.perl page, so I see all of these URLs in Shelf. It fetches the pages, and discovers that there’s a single RSS feed advertised on the use.perl page – But this RSS feed is nothing to do with Simon’s page – it’s the main use.perl article feed. Shelf doesn’t know this, of course, so Simon’s display in my Shelf window contains all recent use.perl articles.

The HTML spec seems to imply to me that rel=”alternate” links are for linking to the same content, but represented in a different way, not some completely unrelated content that happens to be hosted on the same domain. This is very annoying.

I’m picking on use.perl unreasonably here, of course. Lots of people do it. use.perl is just the first one I noticed. Followed by (author modules pages have an RSS feed of the master module upload list). But there are others.

Released Shelf 0.0.11

So, I have a new release of Shelf, having finally been inspired to put a bit of effort into the scary refactorings I was putting off. It’s internally much better than the last one, though I still have places I can take it. Feature-wise, it’s only a little better, though. Feeds look nicer. It should be fast, and caches the contents of remote feeds better, so it’ll thrash the network less.

The big thing is the Google Social Graph integration. Disabled by default, because it’s a privacy nightmare, I can ask Google who the current page in our web browser belongs to, to found out a person to display in Shelf. Once I’ve got a person, I can also ask Google what other URLs they advertise about themselves, so you no longer have to stuff dozens of URLs into your Address Book cards just to see interesting things about people. Looking at Brad’s homepage is a good torture test..

I’m alwo working towards making Simon happier, with a couple of preferences determining how the window should be displayed. It’s not all the way there yet, but I’m moving..

Get the full release notes here.

Shelf and the Google Social API

The current trunk version of Shelf uses the Google Social Graph API to figure out who owns the web page you’re looking at. If it can’t find a person in the local address book who owns the URL, Shelf can now ask Google if there are any other pages on the internet that link to that page with a rel=”me” relation, and look for those pages in the local address book. So for instance, if I visit my linkedin profile page, Shelf will display context about me, as linkedin links to Likewise, any page that I link to from will be considered mine as well. This elevates Shelf’s context-finding ability to practically magical levels in some cases.

Alas, there are disadvantages. Most superficially, the context-deriving part of Shelf was never designed to make long-running network queries, and so lives in the GUI code. Calling the Google API blocks the GUI thread. This sucks. Fixable, of course, but it makes the current development version somewhat choppy.

More serious is that Shelf now sends the URL of every web page I visit, and the homepages of everyone who’s twitters I read, and the base URLs of every RSS feed I read, to Google. I want to look for context in the email signatures of people that send me mail too, so soon it’ll be sending the homepages of everyone who mails me as well. Some people would consider this creepy. Actually most people would consider it creepy. And I don’t blame them. I don’t really have a solution for this one either, other than a big clearly-labeled option to turn it on.

On the API

For this sort of use the Social Graph API is great. Although all this information is available through just fetching the source of the current page and looking for links myself, there’s no way I’d want Shelf as a local GUI app to be doing that sort of thing. Google aren’t exposing anything I couldn’t have found out myself, but they’re doing it in a simple and fast manner, and using the API is trivially easy. No API keys, dealing with XML, registering my app or anything. I love that they just went with JSON as the format, and hang everything else.

Where’s the next release?

On a related note, Shelf development has been a little slow recently. Partially I’ve been distracted by shipping important features for Dopplr, but mostly it’s because I’ve hit a sort of psychic barrier of progression. Shelf needs a decent caching layer. And a threaded context discovery layer. And a much better event-driven model for display stuff, so it makes a more controlled number of network requests to fetch RSS feeds. Basically, now I’ve explored the problem, I want to rewrite the whole thing to take advantage of my understanding. And that’s boring. So I’m not doing anything. I’ll get over it.

Yet Another Shelf Release (0.0.8)

These version numbers are just jumping around randomly now. Well, ok, they’re not, but not every version escapes to the world. Anyway, download the new Shelf – this one has an icon! And it now includes Sparkle, so it’ll update itself automatically from now on – you can stop visiting my blog every 10 minutes to see if I’ve released a new version now.

Incidentally, Sparkle is <i>stupidly</i> easy to install – everyone should use it. It’s awesome.

I’m going to start keeping a proper ChangeLog now, because I have no idea what’s in this version. Better cacheing? I think it’ll also use as a source of Clues, so if you’re having trouble getting the app to do anything, just open Address Book and look at a card – you’re guaranteed to see something.

A usable Shelf release

Right, Shelf has now reached version 0.0.6 – download it (there are newer versions out now – get those). It’s good enough that I’m running it full time now. Thanks to Mark Fowler, it can now pull clues from Firefox, which is a relief. I’ve also added Address Book and iChat support, although the iChat stuff is a little hokey – it assumes you’re not using tabbed chats, and that you speak English. Sorry. The iChat AppleScript dictionary is lousy.


It’s been suggested that I could work out twitter feed and Flickr photostream URLs about people based on their name / nick / email. I’m currently shying away from deriving too many things about a person magically. For instance, I could work out (and cache, obviously) a Flickr username for a person from their email address. Quite apart from the horrible privacy implications of sending the email addresses of everyone you read mail from to Flickr, I just don’t like the approach. I’d much rather encourage a rich address book with lots of data in it. This has the side-effect that Shelf will also recognise my Flickr page as belonging to me.

Shelf ported to Python

Ruby turned out to be a bit of a pain for Shelf – I needed many external libraries and the Ruby bridge does a fairly bad job of packaging them all. I’ve ported the thing to Python now and it seems better – in fact, it’s better enough that I can actually produce a binary! Check out the downloadable action! – MacOS 10.5 only, and this is very unlikely to change. Deal with it.

It’ll pull context from Safari, NetNewsWire,, Adium and Twitterific. Adding new apps is easy, I just haven’t yet. It’ll display only the person’s name, email addresses, and street address. And there will be errors if the street address is incomplete. It’s a PROOF OF CONCEPT. Jeez. Quit whining. There is code to fetch the recent feeds of their pages, but it’s disabled because the app blocks while it’s doing it, making it practically unusable.

Update: [Version 0.0.2 now available]( – it’s a little smarter, and tries to parse microformats in the source of the current Safari tab now.Another Update: Hmm, packaging things is _hard_. Never mind, try [version 0.0.5]( – it actually _works_, and does RSS feeds and Flickr photos and twitter messages and threading and things. I’m getting happier and happier with this..

Rather than me updating this page all the time, just go to the Shelf project page and get the most recent binary from there.

Shelf – Context for MacOS

I really miss Dashboard. It was an effort to display some context around whatever person you were interacting with at any given moment – look at an email from Paul, or open an IM chat with him and you’d see things that he’d blogged or uploaded to Flickr recently. Genius. From the screenshots, it looks practically magic, tying into incoming SMS messages, IM conversations, the RSS feed reader, etc.

Alas, I never had a fully working Dashboard setup locally, mostly because applications had to actively participate in the process – they sent things called ‘cluepackets’ to the dashboard application containing hints about the current context. Because of this design, every app involved needed its source code patched and a recompile. This was a complete pain. Obviously, had everything gone to plan, the patches would have been merged and everyone would have been happy. I presume that Dashboard failed because the bootstrapping process was so hard that no-one used it.

Anyway, inspired by both Dashboard and Aaron‘s obsession with the address book, I’ve had a stab at doing it again, but worse.


Shelf will look at the current foreground application, and try to figure out if what you’re looking at corresponds to a person in your Address Book. Then it’ll tell you things about them.

Update 2008/01/08: I have downloadable versions of Shelf now. Go to the project page and download one.

Shelf screenshot

It’s for MacOS. Because on MacOS, I have OSA – I can interrogate most (well-written) applications about their state in a beautiful, language-agnostic and fast manner. I can ask for the email address of the current mail. I can ask Safari what the URL of the foreground window is. I can ask Adium for the account details of the current chat. I can ask NetNewsWire for the homepage URL of the current subscription. And I can ask the system what app is in the foreground. I can also interrogate the system address book via the Cocoa bindings for same and find out what users have got that email address, or URL, or AIM screen name. And then I can take all the other information about them in their address book entry, and figure out some context. Oh, and the thing’s written in Ruby, because the Ruby scripting bridge is a thing of serious beauty and should be played with by everyone.

Good thing

So, advantages. I don’t have the bootstrapping problem, because most MacOS applications already have enough of a scripting interface that I can extract information from them. Firefox is proving to be a serious problem, alas, but I’ve hit no other apps I can’t get something useful out of.

Once I have an Addressbook record as context, I can update the interface with a picture of the person and their name/company (direct from the address book, so easy). As a ‘will this work?’ experiment, I’m parsing every referenced URL in the address book card for RSS feeds, and displaying those as context. And (because I work there) I have special-case Dopplr support that tells me where the person is in the world and where they’re going next. This means that when someone IMs me, a window pops up and tells me where they are, when they’re back, and what they’ve blogged recently. Awesome.

addressbook screenshot

The system address book is great – it has multiple email address and URLs for people, so I’m indicating things like Dopplr username by just putting the url to my traveller page in my address book entry. I can parse the username out later and use it to call the API with. This has the advantage that if I visit my Dopplr page in Safari, hey, wow, that URL is in the address book, and it knows that it’s me again. Flickr is the next obvious choice for special-casing, but the principle extends to anything.

Bad thing

Disadvantages. Firstly, urgh, I’m polling. Every 2 seconds, I ask the system for the foreground application, then ask that application (if I know how) for context. This is probably a little heavy (is it? I’m guessing..). Secondly, I have to do explicit work for every app out there. The huge advantages of Dashboard’s cluepacket approach over mine were that packets were pushed instantly on a change of context, and that a new application was responsible for sending its own cluepackets.

Actually, this is easy. My app should have a ‘change context’ OSA method that other applications can call. Smart apps can tell me when their context changes, and I’ll just poll everyone else. Once I’ve taken over the world, everyone will be pushing messages to me, and I can deprecate the poll interface. Genius.

Recently, most of the crazy apps I’ve put here have been labelled as ‘proof of concept’. This one is different. This one probably won’t even build on your computer. I’m putting things up here as a was of musing about technique. For instance, Dashboard had a far better design than this app. It had a nice pipeline thing going for it, whereas I just have a class per foreground application, this class must produce an Address Book record, then I just interrogate every context producer for information and display it. This is silly – if I’m looking at Paul’s Flickr photos page, I don’t need my app showing me the thumbnails again, I might be much more interested in where he is right now. Hell, in a perfect world, it would work out the dates of the photos I’m looking at, and show me where he was at that time.


Clever things I could (and want to) do:

  • If the foreground URL doesn’t belong to a user, look for hcard markup in the source HTML and try to derive a person from that. Right now, for instance, I’ll only recognise your Flickr page as belonging to you if it’s one of the URLs against your address book card. But Flickr pages are marked up with enough hcard that I should be just able to figure it out.

  • More intelligence around context – as above, if I’m looking at a blog of a friend, I want to see other things, not their blog again.

  • Remembering connections – if I figure out a local person from a Flickr page via hcard markup rather than an Address Book URL, why not remember their Flickr username and display their photos when they email me?

Many of these features are difficult, mostly because of my core design right now – I derive an Address Book entry from the current application, then derive context from that entry. This hampers cleverness somewhat – I really need to pass around a lot more information about how I derived this person, and keep a local cache of conclusions about them. Maybe the person isn’t in my address book – I get email from people I don’t know! But their email address might correspond to a Gravatar so I could show a picture of them. Maybe the mail has some URLs in the .sig and I could find their blog. Maybe they’ve commented on my blog in the past and I’d like links to the comments. Likewise, if I find, via hcard in the source of a page, that a page is about someone I know, should I update Address Book and add URLs for them? Probably not a good idea. So I need a local store of connections as well.

Now what?

I don’t know. It’s very tempting to rewrite the thing in Python before it gets any more complex. Partially this is because the Ruby feedparser dependencies are a bugger, but mostly it’s because I don’t want my python sk1llz to atrophy down to nothing. Recently everything I do is in Ruby, and I don’t like that. Shelf also desperately needs some work done to make it asynchronous, and cache things – when I look at an email right now, it’ll hang for 5 minutes while it goes off and fetches 20 RSS feeds, every time I change the person I’m looking at. Not exactly pleasant. But the ‘find out about a person’ is really just a trivial example of the sort of things you can do once you know who they are. The ‘derive context from current machine state’ side of things is much more interesting.