Repository navigation
Releases: Paliverse/workboard
Releases · Paliverse/workboard
Release list
WorkBoard 0.3.10
Added
- Authors couldn't edit or remove their own timeline notes without hand-editing
board.json.note REF edit NOTE_IDandnote REF rm NOTE_IDnow do it (note.editandnote.rmincall, withid). Only the author may change a note; others getowned. Each change adds anote-editedornote-removedhistory event, and an edited note carrieseditedAtand shows "edited" in the browser. Editing a note clears earlier acknowledgements of it, so an edited finding shows in the card owner's inbox again, even if it was posted before its subtask was accepted. Notes the subtask workflow writes itself (results, acceptances, takeovers) can't be changed.editorrmwithout a note ID is plain note text. - On Windows, npm installed only
workboard.cmdandwb.cmd, so every argument went throughcmd.exe: line breaks cut the command short, quotes,%,^and&were mangled, Rust-based shells such as omp's refused multi-line arguments with "batch file arguments are invalid", and Python'ssubprocesscouldn't findworkboardat all. Global npm installs now also getworkboard.exeandwb.exe, a small launcher that runs the real binary with the arguments untouched; killing the launcher (a caller's timeout) also ends the binary, while servers and upgrades the binary starts keep running. npm copies it after install, and each run through the.cmdshim restores it if it is missing or outdated.npm uninstall -gleaves the two launchers behind; run on their own they say what is missing and how to fix it, and the uninstall instructions list them.
Changed
- A note summary over 160 characters or with a line break was refused, so agents retried or cut their own text. The summary now keeps its first line, cut at a word break with "…" if still too long, and the full text moves to the top of the body. This holds for the CLI,
calland the browser API. Only a body that ends up over the body limit is refused, and results report"summaryMoved": true. note 12 "text"failed because--summarywas required. The text can now be given positionally ("text"incall); giving both is refused with both named.- Commands that write a card recorded the writer as
agentwhen no label was set. They now refuse withinvalidand ask for--actor,"actor"in the call request, orWORKBOARD_ACTOR. Reads still work without a label, and the browser still recordsuser. - A
callrequest with a key its op doesn't take said onlyOP doesn't take "x", and a guessed key that replaced a required one ({"op":"search","query":…}) was reported assearch needs "terms". The unknown key is now reported first, with the keys the op takes and, for common guesses, the key to use:search doesn't take "query" (use "terms"); search takes: terms, limit, fields, board, actor. - An unknown
callop said onlyop X is not available in call. It now lists every call op and names the right one for common guesses (list/get → query or context, move → fly, claim → start or subtask.claim, create/new → add, help →workboard COMMAND --helpoutside call). On the command line, argparse's "invalid choice" for those guesses gains adid you mean workboard fly?line. - Input to
callthat wasn't JSON failed with a bare decoder message such asExpecting value: line 1 column 1 (char 0). The error now quotes the first 60 characters that arrived; when the double quotes are missing (a shell stripped them, or bash brace-expanded the object) it says so and shows the heredoc form. Empty stdin shows the heredoc form too.
WorkBoard 0.3.9
Fixed
- The browser's "Sort cards by newest" sorted each column once, so every card added later, including those agents add from the CLI, landed at the bottom of its column. The board menu now has a "Newest cards first" setting instead, which persists for each board in that browser: while it is on, every column except Done lists cards newest first, and dragging a card within a column is refused with a hint to turn it off (moving a card to another column still works). Turning it off restores the manual order. The saved card order is left untouched, and the
sort-cardsstructure operation in the HTTP API is unchanged.
WorkBoard 0.3.8
Changed
- The card's owner finishes a delegated step in one request:
subtask.donewith aresulton available work, or on work it holds aftersubtask.claimorsubtask.takeover, completes the step and accepts it at once, and the timeline records both. Before, available work was refused until claimed, and the owner then had tosubtask.acceptits own result. Work another worker holds still needssubtask.takeoverwith a reason first, and other workers' results still needsubtask.accept. In the browser, the card owner's checkbox on an available delegated step is enabled and finishes it the same way. The card'sdonerefusal points to this, and the skill tells Main to close a step it did, a superseded step or a gone worker's step this way. wait --subtaskreturns at once only when that subtask changed after--after, not whenever anything on its card did. Each delegated subtask now haschangedRev, the board revision that last changed it or a note on it, set by the server like the card's. Subtasks already on disk get a stamp the next time their card is saved with a change; until then, and for plain checklist subtasks,waitfalls back to the card'schangedRev. The skill drops its line about waiting again after achangedwith nothing new.- A card keeps its whole
history. Before, only the last 40 entries were kept, so a long-running card lost its oldest events; rows already dropped are not restored.showwithout--fullstill prints the last 10, andcontextstill leaves history out unless--full.
WorkBoard 0.3.7
Fixed
- Blocking a card hid its
review,blockerandclaimrows frominbox, becauseblockclears the owner, so Main lost sight of finished and running work. The actor who blocked the card now still sees them, by the same holder rule asdigest's MINE andquery --mine.findingrows wait until the card is In Progress again, sinceackneeds it. The browser shows a Blocked card's results without Accept and Request changes buttons until it is resumed, since review needs In Progress. - The
handoffprompt printed the worker's requests as one JSON object on one line, so pasting it intoworkboard callwasinvalid("each call request needs a string op"). It now prints each request on its own line: read, claim, resume (blocked work only), publish, complete.--jsonrequestsis unchanged. - Refusals name the op that clears them. The card's
donerefusal follows each subtask that keeps the card open with its next step:subtask.takeoverwith a reason if the actor holding it is gone, or for available work, claim and finish it orsubtask.rmit.subtask accepton work that isn't completed gives the same hint. Incall, an unknownsubtask.*orcomment.*action said "argument op: invalid choice"; it now names the op and lists the real ones:unknown op "subtask.edit"; subtask ops: add, done, …. - An HTTP card edit (
PATCH api/card/{ref}) could blank the write-up of a Done card, whichdonerefuses. Changing a Done card'swriteupto blank or whitespace-only text is nowinvalid(422); other columns are unchanged. - The skill lists
noteasresume's reason andsubtask.rmamong the ops, and tells Main to drop a superseded step withsubtask.rm(aftersubtask.takeoverif another worker still claims it). It tells a worker whosewaitreturnedchangedwith nothing new on its subtask to wait again with the returnedrev, and says a Blocked card you blocked keeps its inbox rows. Its cardtakeoverline could be read as allowing a takeover only when the user asks; it now says "only if the user asks or the holder is your own gone worker".
WorkBoard 0.3.6
Added
inboxlists aclaimrow for each delegated subtask another actor holds on the owner's In Progress card, withowner,state(claimedorblocked),claimedAtandlastActivityAt(the latest of the claim and that subtask's notes), so after a restart Main sees what is still running and which worker went quiet. A blocked subtask lists itsblockerrow first. The browser's Inbox shows them as "Assignment in progress" or "Assignment blocked", and its count leaves them out.wait --subtaskaddsnotesto its result: the entries posted on that subtask while it waited, so a worker reads Main's answer without anothercontext. It is[]after a timeout or an immediate return.
Changed
doneworks from Backlog and Task too, so work found already done needs nostartfirst. Outside In Progress the card's dependencies must be completed (deps); a Blocked card isstate(useresume), and so is a Done card (usereworkorreopen). The browser'scompleteandsubmitfollow the same rule.add --column inprogress("column":"inprogress"incall) creates and starts a card in one request, withstart's dependency and WIP checks, and makes you its owner; a refusal creates nothing. Before,addtook only Backlog or Task. The browser's card creation uses the same code: titles are trimmed, and a card created In Progress recordsstartin its history.- Every delegated result needs
subtask acceptbefore the card'sdone, and before subtasks that list it as a prerequisite can be claimed or handed off. A result whose review wasn't required used to count once completed; existing ones now show REVIEW PENDING indigestand the browser until accepted.review.requiredis alwaystrue, anddoctordoesn't report the storedfalseit replaces. - Subtasks are one flat list. Boards with nested subtasks load flat, each subtask just before the ones it held, keep their delegations, and are saved flat on the next write;
doctordoesn't report the change.context --subtaskreturns only that subtask (focus.ancestorIdsis gone),wait --subtaskwatches only that subtask, andsubtask rmremoves only the listed IDs. The browser drops its fold and "Add sub-item" controls. contextleaves out the card's history unless--full("full":true);omitted.historycounts all of it. Before, it kept the last 25 entries.handoffprints a prompt of about six lines: the card, the subtask, the scope (or "read-only: edit no files"), a takeover or blocked line when one applies, the requests on one line forworkboard call, and a pointer to the skill's Worker section. Card text is JSON-quoted as data.--jsonreturns onlyok,rev,num,worker,previousOwner,writeScope,scopeWarnings,requestsandprompt;commands,placeholders,call,assignment,title,cardId,board,boardName,parentOwner,origin,notes,peersandancestorIdsare gone. The write scope is always the subtask's saved one.digest --jsonhassweepCandidateCount(a number) instead of thesweepCandidateslist of card IDs, and itsminerows are{num, title, column}withoutid.inboxleaves out findings on a subtask that come before Main's acceptance of it in the timeline; notes posted later still show.handoffrequests carry the worker'sboardandactor, so the prompt names plainworkboard calland no board or worker name passes through a shell (names such asR&Dused to split the command on Windows).- The agent skill is shorter (about 1,700 words instead of 2,500). It asks for
expectedRevonly on cards you don't hold, and coversaddinto In Progress,donefrom Task, accepting every result, the slim handoff, inboxclaimrows andwaitnotes. Rarely used actions left the skill but not the CLI, and its Commands block became a list of ops. docs/agents.md now points to the skill instead of repeating it.
Removed
subtask add --parent: subtasks no longer nest."parent"in acallrequest isinvalid(subtask.add doesn't take "parent").subtask configure --review-requiredand--no-review-required, since every result needs acceptance."reviewRequired": trueincallisinvalid, andreviewRequiredin the HTTPconfigureis 422.handoff --write-scope,--peerand--fields. Set the scope withsubtask configure --scopebefore the handoff.
Fixed
workboard upgradethrough npm could install the previous version right after a release, because npm answered from its cached package data. It now runsnpm install -g --prefer-online @paliverse/workboard@latest.
WorkBoard 0.3.5
Fixed
- The card's owner was refused (
owned, "only the current claimant or the parent owner can publish") when postingnote --subtaskon a plain checklist step of its own card. The owner may now note any subtask of its card, so a step's evidence stays with that step. - A worker can post
note --subtaskon its delegated subtask aftersubtask done, including after Main accepted it, for example a recheck verdict. Before, the worker had toundone, note anddoneagain, which rewrote the subtask's history and briefly showed approved work as open. note --subtaskchecks the summary and body before permission, so a too-long summary isinvalidin the first reply instead of after anownedrefusal and a retry.- The
callhint foridon a subtask action no longer suggests asubtaskslist that delegated actions refuse. - In
call, a list for an option that takes one value kept only its last item, and an empty list sent nothing. Both are nowinvalid:notes takes one value, not a list,scope is an empty list; omit it or use clearScope to clear. callerrors name request keys instead of the parser's names: a missing field isnote needs "summary"orsubtask.claim needs "subtask" or "subtasks"instead of "the following arguments are required: what", an unknown key iscontext doesn't take "fields", and usage errors show"camelKey"without the--*-stdinalternatives thatcallrefuses.- In
call, acard,column, attachmentidoracknote ID starting with-(such as-h) reached the parser, and a request that printed help ended the whole stream. Both are nowinvalid, and later requests still run. context,note,handoffandwaitincallsay they take one subtask ID insubtaskwhen givenidorsubtasks.wait --subtaskmissed notes posted on that subtask, so a worker waiting for Main's answer timed out. A note on the watched subtask now wakes it.query --columnandlist --columncompared the raw text, soin-progressorIn Progressmatched nothing and a misspelled column returned an empty list. They now take the same column names asfly, plus any column the board itself has, and an unknown column isinvalid.- A worker holding a delegated subtask couldn't post
note --subtaskonce the card left In Progress (state). It can now post on any column, for example after the card is Done. A refusal names the subtask's holder and suggests a card note instead. - A
resulton plain checklist steps (subtask done) was silently dropped. It is nowinvalid, and the error says to post the evidence withnote --subtask. - Lifecycle and subtask commands check their input (reasons,
until, write-ups, results, target columns, dependency IDs) before ownership, so bad input from someone who may not act isinvalidin the first reply instead ofowned. - Refusals name what blocks you: the card's
donelists each subtask that keeps it open and what it waits for;start,depends,subtask claim,subtask doneandhandoffname each unmet prerequisite; a refused ID in a multi-IDacceptand the delegated IDs in another multi-ID action are named. subtask donewith a new result on accepted work said to reopen it withundone, which was refused, andundonenamed "Main" as the acceptor. Both now name who accepted it and say to post later evidence withnote --subtask.- A worker command on a card that isn't In Progress now says to post the result with
note --subtaskand wait for the owner to start or resume the card.add --delegated,delegateandrmon another owner's card say to ask that owner instead of suggestingtakeover, and a claimant refusal points tosubtask takeoverfor a worker that is gone.
Added
subtask accepttakes several subtask IDs ("subtasks":[...]incall) and accepts them in one revision; if any can't be accepted, none are.digest --jsonaddsmine: the cards you hold, as listed under MINE in the text output.add --notes TEXTor--notes-stdin(notesincall) sets the pinned notes when the card is created; with--fromit replaces the copied notes.subtask REF done ID --result-stdinreads the result from stdin.search --limit Nkeeps the N newest hits, andsearch --fields LISTpicks the hit fields, as inquery.handoff --fields LISTkeeps only the listed keys in--json, plusok,revandnum;"fields":"prompt"returns just the brief.handoffon a subtask another worker holds (claimed or blocked) returns a takeover brief for the replacement worker:previousOwnernames the holder, and the claim step issubtask takeoverwith a{reason}placeholder. Blocked work also gets aresumestep. Before, it was refused.handoffwithout a write scope returns a read-only brief that tells the worker to edit no files. Before, it was refused, and Main had to brief read-only workers by hand.contexthas the card'snumat the top, next torev.scopeWarningsrows addclaimedAtandlastActivityAt(the latest note on that subtask, or its claim), so Main can tell a stale claim from active work.inboxalso lists completed results that need no review, withreview.requiredfalse;subtask acceptclears them. They still don't hold updone.
Changed
search --jsonhits are{num, title, column}instead of full cards; ask for more with--fields.donewithout a write-up, or with a blank one, isinvalid(wasstate).stateis always status 409.addinto a later column,fly REF done, and moving a card into or out of Blocked withflyorstartreturned 422.attachment addwith a missing--fileisnot_found(wasio).- An existing
export --outdestination is status 422, like otherinvaliderrors (was 409). - On claimed or blocked work,
subtask configure --scopecan only grow the saved scope: send the saved paths plus the new ones. Dropping a path, or--clear-scope, is refused withstate, since the worker may be editing it. - A worker command (
done,undone,block,resume,release) on a subtask nobody has claimed isstate, saying to claim it first (wasowned, "held by nobody"). subtask configure,accept,request-changesandackon a card that isn't In Progress arestate, saying to start or resume it first (wasowned).- Removing delegated subtasks (
subtask rm) needs the card's owner, or a card without one (owned). handoff'scommands.completereads the result from stdin (--result-stdin) instead of a--result={result}argument, so multi-line results survive npm's Windows shim.
WorkBoard 0.3.4
Added
handoff --jsonaddsrequests, the worker's four steps (read, claim, publish, complete) ascallrequests, andcall, the argument array that runs them. Workers fill in{summary},{body}and{result}and send the requests on stdin, so multi-line findings and results survive npm's Windowsworkboard.cmdshim; the argument-arraycommandsstay unchanged. The handoff prompt now shows thecallform.
Fixed
digestmarked an In Progress card READY TO CLOSE once every subtask was ticked, even while a delegated subtask still awaited its required review, sodonewas then refused. It now says REVIEW PENDING untildonewould pass, and the browser's card badge does the same ("Review pending").- In
call, a subtask action that names the subtask withidinstead ofsubtasknow fails with an error saying to usesubtask. Before, it said "the following arguments are required: what".
Changed
- The skill and docs explain that
query --mineanddigest's MINE include Blocked cards you blocked, and that one opencallcan chain requests that need an earlier result'srev. They also say to write the remaining review, integration or release work as subtasks, and that Main may take over cards held by its own workers whose sessions ended.
WorkBoard 0.3.3
Changed
- The agent skill is rewritten for
call: a table of request keys, a whole session and a worker's requests as JSON, and advice to batch related requests into onecall. It now covers the refusals agents actually hit (priorityiscritical|mid|low,addonly into Backlog or Task,doneonly from In Progress, subtask IDs go insubtaskrather thanid), read-only delegated work withouthandoff, and replacing a worker that is gone withsubtask takeover. Every JSON example and command form in it runs against the CLI. It no longer has a 6 KB size limit. - The contributor guide, pull request template and issue forms are gone. Running from source and the tests are described in docs/install.md.
WorkBoard 0.3.2
Fixed
- 0.3.1 made a one-shot command's board read slower: the first read in each process also stored a parsed copy for reuse, which only
calland the server ever reuse. The first read now keeps only the text it read, and the second read of an unchanged board makes the copy. On a 3.7 MB board, the firstcontextin a process took 107 ms instead of 133 ms (0.3.0: 116 ms).
WorkBoard 0.3.1
Changed
- A WorkBoard process reuses its parse of a board while
board.jsonis unchanged, socalland the server answer reads without parsing the whole board again. Any commit, by any process, forces a fresh parse, and each reader gets its own copy. On a real 790-card, 3.7 MB board, 20contextrequests in onecalltook 343 ms instead of 1319 ms: about 7 ms per request after the first instead of 64 ms.callalso builds its argument parser once instead of per request. - Writes parse the board once instead of three times.
savecompares cards against the board the transaction loaded under the lock instead of reading it again, and the backup no longer re-parses the bytes it writes to find their revision. On the same board, onenotetook 316 ms instead of 436 ms, and 10 notes in onecall1.9 s instead of 3.2 s.