PyObjC Plug-ins
I hope to write up something more detailed and in better form eventually (here it is), but the following is a first attempt. It helps if you know Python and it's good to become familiar w/ PyObjC.
0) Assuming you have a fairly good idea of how you want the UI aspects of your plug-in to work, examine the existing functionality of QS – perhaps what you want to do can be done already. If it can't, consider other extension mechanisms – e.g. Automator, OnMyCommand, Applescript. Assuming you still want to do things in PyObjC, continue.
1) Attempt to find some existing functionality that is similar. Attempt to determine whether it lives in a plug-in and if so, which one. Find the Info.plist file for the plug-in (it will likely be in PlugIn-Name.qsplugin/Contents/). Study the Info.plist file and try to figure out what it means (e.g. there's existing documentation in the Quicksilver manual for this, and after making an honest attempt, asking questions is probably not a bad idea).
2) Taking your fairly good idea of how you want the UI to work (remember the assumption in step 0?) and your insight gained in step 1, create an Info.plist file for your plug-in. Copying and modifying an existing Info.plist file may be a good place to start. Note that it is NOT recommended to start w/ an Info.plist file from an existing PyObjC plug-in – the reason for this is that there is extra stuff that gets put in there by the build process and it may be confusing (well, if you know what to ignore, it's not so bad).
3) Create a directory for your plug-in and place the Info.plist file in there. Download the following two files into the directory:
http://quicksilver.blacktree.com/public/ytrewq1/tiger/setup.py http://quicksilver.blacktree.com/public/ytrewq1/tiger/Makefile
You'll need to edit the first line in the Makefile to reflect the name of your plug-in – see ~/Library/Application Support/Quicksilver/PlugIns/ to get an idea of naming conventions. I'm hoping to do away w/ this editing step in the future – we'll see what happens.
All of my plug-ins use the same setup.py file so you may not have to edit yours.
4) Install PyObjC and py2app. Actually, if you build and install PyObjC in an appropriate manner, it will install py2app for you. Either way should work. Note that I haven't tested w/ stuff from DarwinPorts just yet, so I recommend avoiding that at the moment. Also, consider installing pyflakes as the 'test' target provided by the Makefile uses this. pyflakes is like pychecker. Ah, you may need the Developer Tools to use 'make' – I'm not sure about this. I think the Property List Editor application may also come w/ Developer Tools and you may find this handy when viewing/editing Info.plist files.
Make sure you also have Quicksilver (B42 or greater) and the PyObjC Support plug-in installed.
5) Implement the functionality which your Info.plist designates in a Python file and place this file in the directory from step 3. For example, for the Timer plug-in, I do this in a file named 'YTTimer.py'. Note that all of my PyObjC plug-ins ship with the source to this portion – study away:
http://blacktree.cocoaforge.com/forums/viewtopic.php?p=11256
There is some convenience functionality provided by a class named 'YTQSPlugIn' that may be helpful for you so I suggest checking out how it is used in the source mentioned above. The source that provides this class is available via:
http://quicksilver.blacktree.com/public/ytrewq1/tiger/YTPyObjCCore.py
If you end up wanting your plug-in to use icons which you provide, create suitably sized png files and place them in the directory from step 3. Similarly for nib files, rtf files, and .lproj directories. All of these will be included in the built plug-in by the build process. See setup.py for details of which kinds of files get included.
The value for CFBundleExecutable in Info.plist is used by setup.py and the convenience functionality in YTPyObjCCore.py in certain ways. The current assumption is that if your plug-in is implemented in a file named, say, 'YTTimer.py', the value you should specify for CFBundleExecutable is 'YTTimer'.
6) To build your plug-in, from the command line, do 'make'. To build and install your plug-in, do 'make install'. To clean up build files, do 'make clean'. To make a tgz file like the ones you find via the forums, do 'make tgz'. To perform some checking on your plug-in's code, do 'make test'.
That's basically it as far as the overall process is concerned.
Points to be careful of:
1) AFAIU, a single Python interpreter is shared among all PyObjC plug-ins for QS. This means some coordination/care is required among PyObjC plug-in developers – for simple stuff, it may be a non-issue. I don't know if this restriction/limitation is practically liftable, I sure wish it could be.
2) I don't recommend doing any network-related code just yet – because of 1 and my experiences w/ the Bloglines plug-in and the alternative del.icio.us plug-in, I concluded that to do network stuff it would be better to use the Twisted framework. I haven't worked out the details fully yet (though I've had some luck experimenting w/ that approach) so this isn't ready yet – it's also the reason I'm not releasing my revised Atom Actions plug-in just yet.
Have fun!
ytrewq1