takibibase 1.15.1 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +5 -3
- package/package.json +1 -1
- package/takibi.mjs +20 -8
package/SKILL.md
CHANGED
|
@@ -71,9 +71,11 @@ error hints.
|
|
|
71
71
|
follow-up). Needs the create cap; naming anyone other than yourself
|
|
72
72
|
needs Orchestrator. The card lands at To do, unassigned unless
|
|
73
73
|
`--assignee` names someone — claim it before driving it.
|
|
74
|
-
- `takibi tasks update <id> [--title …] [--body …] [--due …]` —
|
|
75
|
-
card without spinning a follow-up (at least one flag; empty `--due`
|
|
76
|
-
clears the date).
|
|
74
|
+
- `takibi tasks update <id> [--title …] [--body …] [--due …] [--blocked [--reason …]] [--unblocked]` —
|
|
75
|
+
amend a card without spinning a follow-up (at least one flag; empty `--due`
|
|
76
|
+
clears the date). `--blocked` flags the card (optional `--reason`, max 500
|
|
77
|
+
chars, also usable alone to rewrite the reason); `--unblocked` clears the
|
|
78
|
+
flag and its reason. A holder edits its own card; an orchestrator may
|
|
77
79
|
edit any card on the board. Title/body edits need the create cap.
|
|
78
80
|
- `@name` in a task names the handoff target: the FIRST explicit
|
|
79
81
|
`assign to @name` (or the first @name clearly meaning "who gets the
|
package/package.json
CHANGED
package/takibi.mjs
CHANGED
|
@@ -39,7 +39,7 @@ import { homedir } from 'node:os';
|
|
|
39
39
|
import { basename, join } from 'node:path';
|
|
40
40
|
|
|
41
41
|
/** Baked fallback; the published package re-reads package.json next door. */
|
|
42
|
-
const BAKED_VERSION = '1.
|
|
42
|
+
const BAKED_VERSION = '1.16.0';
|
|
43
43
|
const CLI_INFO = (() => {
|
|
44
44
|
try {
|
|
45
45
|
const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'));
|
|
@@ -377,7 +377,7 @@ Commands:
|
|
|
377
377
|
tasks create Open a fresh card [--title/--body/--assignee/--due]
|
|
378
378
|
tasks claim <id> Claim an open to-do card (atomic, one winner)
|
|
379
379
|
tasks status <id> <st> Move a card: todo | in_progress | review | done [--note <text>]
|
|
380
|
-
tasks update <id> Amend a card's title, body,
|
|
380
|
+
tasks update <id> Amend a card's title, body, due date, or blocked state [--title/--body/--due/--blocked/--unblocked/--reason]
|
|
381
381
|
tasks handoff <id> <profile> Hand a card you hold to another profile [--review --note <text>]
|
|
382
382
|
tasks follow-up <id> Spin a fresh linked todo off any card [--title/--body/--assignee/--due]
|
|
383
383
|
tasks escalate <id> Ask the Founder for help on a held card [--reason <text>]
|
|
@@ -493,9 +493,9 @@ function parseArgv(argv) {
|
|
|
493
493
|
i = ni;
|
|
494
494
|
}
|
|
495
495
|
else if (a.startsWith('--folder=')) globals.folder = a.slice('--folder='.length);
|
|
496
|
-
else if (a === '--query' || a === '-q' || a === '--q' || a === '-k' || a === '--limit' || a === '--max-chars' || a === '--all' || a === '--review' || a === '--add' || a === '--note' || a === '--reason' || a === '--size' || a === '--hash' || a === '--markdown' || a === '--title' || a === '--body' || a === '--assignee' || a === '--due' || a === '--problem' || a === '--tried' || a === '--worked' || a === '--failed' || a === '--next-time' || a === '--source' || a === '--since' || a === '--run-id' || a === '--install' || a === '--force' || a === '--agents' || a === '--claude' || a === '--codex' || a === '--dir') {
|
|
496
|
+
else if (a === '--query' || a === '-q' || a === '--q' || a === '-k' || a === '--limit' || a === '--max-chars' || a === '--all' || a === '--review' || a === '--add' || a === '--note' || a === '--reason' || a === '--size' || a === '--hash' || a === '--markdown' || a === '--title' || a === '--body' || a === '--assignee' || a === '--due' || a === '--blocked' || a === '--unblocked' || a === '--problem' || a === '--tried' || a === '--worked' || a === '--failed' || a === '--next-time' || a === '--source' || a === '--since' || a === '--run-id' || a === '--install' || a === '--force' || a === '--agents' || a === '--claude' || a === '--codex' || a === '--dir') {
|
|
497
497
|
rest.push(a);
|
|
498
|
-
if (a !== '--all' && a !== '--review' && a !== '--install' && a !== '--force' && a !== '--agents' && a !== '--claude' && a !== '--codex') {
|
|
498
|
+
if (a !== '--all' && a !== '--review' && a !== '--blocked' && a !== '--unblocked' && a !== '--install' && a !== '--force' && a !== '--agents' && a !== '--claude' && a !== '--codex') {
|
|
499
499
|
const [v, ni] = takeValue(a, i);
|
|
500
500
|
rest.push(v);
|
|
501
501
|
i = ni;
|
|
@@ -856,25 +856,37 @@ async function cmdTasks(tokens, globals) {
|
|
|
856
856
|
return;
|
|
857
857
|
}
|
|
858
858
|
if (sub === 'update') {
|
|
859
|
-
const usage = 'Usage: takibi tasks update <id> [--title <text>] [--body <text>] [--due <date>]';
|
|
859
|
+
const usage = 'Usage: takibi tasks update <id> [--title <text>] [--body <text>] [--due <date>] [--blocked] [--unblocked] [--reason <text>]';
|
|
860
860
|
const [id, ...flagTokens] = rest;
|
|
861
861
|
if (!id || id.startsWith('--')) throw usageError(usage);
|
|
862
862
|
let title;
|
|
863
863
|
let body;
|
|
864
864
|
let due;
|
|
865
|
+
let blocked;
|
|
866
|
+
let reason;
|
|
865
867
|
for (let i = 0; i < flagTokens.length; i++) {
|
|
866
868
|
const f = flagTokens[i];
|
|
867
869
|
if (f === '--title') title = flagTokens[++i];
|
|
868
870
|
else if (f === '--body') body = flagTokens[++i];
|
|
869
871
|
else if (f === '--due') due = flagTokens[++i];
|
|
872
|
+
else if (f === '--blocked') {
|
|
873
|
+
if (blocked === false) throw usageError(`--blocked and --unblocked conflict. ${usage}`);
|
|
874
|
+
blocked = true;
|
|
875
|
+
} else if (f === '--unblocked') {
|
|
876
|
+
if (blocked === true) throw usageError(`--blocked and --unblocked conflict. ${usage}`);
|
|
877
|
+
blocked = false;
|
|
878
|
+
} else if (f === '--reason') reason = flagTokens[++i];
|
|
870
879
|
else throw usageError(`Unexpected ${JSON.stringify(f)}. ${usage}`);
|
|
871
880
|
}
|
|
872
|
-
if (title === undefined && body === undefined && due === undefined) {
|
|
873
|
-
throw usageError(`Nothing to change — pass at least one of --title, --body, --due. ${usage}`);
|
|
881
|
+
if (title === undefined && body === undefined && due === undefined && blocked === undefined && reason === undefined) {
|
|
882
|
+
throw usageError(`Nothing to change — pass at least one of --title, --body, --due, --blocked, --unblocked, --reason. ${usage}`);
|
|
874
883
|
}
|
|
875
884
|
if (title !== undefined && title.trim() === '') throw usageError('--title needs non-empty text.');
|
|
876
885
|
if (title !== undefined && title.trim().length > 300) throw usageError('--title is max 300 chars.');
|
|
877
886
|
if (body !== undefined && body.length > 20000) throw usageError('--body is max 20000 chars.');
|
|
887
|
+
if (blocked === false && reason !== undefined) throw usageError('--reason cannot ride with --unblocked (unblocking clears the reason).');
|
|
888
|
+
if (reason !== undefined && reason.trim() === '') throw usageError('--reason needs non-empty text.');
|
|
889
|
+
if (reason !== undefined && reason.length > 500) throw usageError('--reason is max 500 chars.');
|
|
878
890
|
// An explicit empty --due clears the date (the server treats '' and
|
|
879
891
|
// null as clear). Create keeps rejecting it: omit and clear are the
|
|
880
892
|
// same on POST.
|
|
@@ -883,7 +895,7 @@ async function cmdTasks(tokens, globals) {
|
|
|
883
895
|
const data = await api('PATCH', `/v1/tasks/${id}`, {
|
|
884
896
|
...ctx,
|
|
885
897
|
query: qparams([['projectId', ctx.projectId]]),
|
|
886
|
-
body: { title: title?.trim(), body, dueAt: due },
|
|
898
|
+
body: { title: title?.trim(), body, dueAt: due, blocked, blockedReason: reason },
|
|
887
899
|
label: 'tasks update',
|
|
888
900
|
});
|
|
889
901
|
if (ctx.json) out(JSON.stringify(data, null, 2));
|