This is the expected behavior. Tap needs to discover tasks 'somehow'. Loading all the files under a lib directory arbitrarily is obviously not acceptable so solutions that use live code don't work. You could make a separate manifest file but that's new overhead. I decided to use a comment-based marker to indicate when a .rb file has a task to-be-discovered.
That marker is '::manifest' (it's a Lazydoc constant attribute).
In your example here, Goodnight could be used by tap but tap doesn't know it exists because there isn't a '::manifest' comment. Yeah, it is overhead but I think it's the least amount of overhead possible and it allows you to define tasks that are by design not picked up by 'tap' (like base classes, for instance).
[lib/goodnight.rb]
# ::manifest <this is the summary string on the command line>
class Goodnight < Tap::Task
config :message, 'goodnight' # a goodnight message
def process(name)
puts "#{message} #{name}"
end
end
That should solve it!