@hasna/todos 0.12.1 → 0.12.2

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/README.md CHANGED
@@ -719,6 +719,26 @@ workflow is available to MCP clients through `list_template_library`,
719
719
  `create_task_from_template`, `preview_template`, `export_template`, and
720
720
  `import_template`.
721
721
 
722
+ ## Moving Tasks Between Plans
723
+
724
+ Plan assignment is editable after creation, so reorganizing a backlog never
725
+ requires deleting and recreating tasks (which would lose history, comments, and
726
+ assignments):
727
+
728
+ ```bash
729
+ todos add "My task" --plan <plan-id> # assign at creation
730
+ todos update <task-id> --plan <plan-id> # move one task to another plan
731
+ todos update <task-id> --clear-plan # detach from its plan
732
+ todos bulk plan --plan <plan-id> <id> <id> # move many tasks at once
733
+ todos bulk move-plan --clear-plan <id> <id> # detach many tasks at once
734
+ todos plans --show <plan-id> # verify the plan's task set
735
+ ```
736
+
737
+ Plan references accept a UUID, a plan slug, a plan name, or a unique id prefix.
738
+ An unknown or ambiguous reference exits non-zero before any task is modified.
739
+ All of these run against whichever authority the CLI is configured for: local
740
+ SQLite, or the shared `/v1` dataset under a self-hosted/cloud authority.
741
+
722
742
  ## Local Git Traceability
723
743
 
724
744
  Tasks can be linked to local git evidence without contacting hosted services:
@@ -1 +1 @@
1
- {"version":3,"file":"task-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/task-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDzC,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ5D;AA2ND,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAu1CpD"}
1
+ {"version":3,"file":"task-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/task-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoDzC,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ5D;AA2ND,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAi3CpD"}
package/dist/cli/index.js CHANGED
@@ -2123,7 +2123,7 @@ var package_default;
2123
2123
  var init_package = __esm(() => {
2124
2124
  package_default = {
2125
2125
  name: "@hasna/todos",
2126
- version: "0.12.1",
2126
+ version: "0.12.2",
2127
2127
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
2128
2128
  type: "module",
2129
2129
  main: "dist/index.js",
@@ -5984,6 +5984,8 @@ function commandSupportsRemote(invocation) {
5984
5984
  return true;
5985
5985
  case "bulk": {
5986
5986
  const action = positionalArgs(args)[0];
5987
+ if (action === "plan" || action === "move-plan")
5988
+ return true;
5987
5989
  return Boolean(action && ["done", "complete", "start", "delete"].includes(action)) && !hasOption(args, "--plan") && !hasOption(args, "--clear-plan");
5988
5990
  }
5989
5991
  default:
@@ -19992,7 +19994,7 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
19992
19994
  handleError(new Error("Task not found."));
19993
19995
  }
19994
19996
  });
19995
- program2.command("bulk <action> <ids...>").description("Bulk operation on multiple tasks (done, start, delete, plan)").option("--plan <id>", "Plan ID for the plan/move-plan action").option("--clear-plan", "Remove plan assignment for the plan/move-plan action").action(async (action, ids, opts) => {
19997
+ program2.command("bulk <action> <ids...>").description("Bulk operation on multiple tasks (done, start, delete, plan/move-plan)").option("--plan <id>", "Plan ID for the plan/move-plan action").option("--clear-plan", "Remove plan assignment for the plan/move-plan action").action(async (action, ids, opts) => {
19996
19998
  const globalOpts = program2.opts();
19997
19999
  const results = [];
19998
20000
  const cloud = getTodosCloudClient();
@@ -20000,12 +20002,27 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
20000
20002
  if (isPlanAction && Boolean(opts.plan) === Boolean(opts.clearPlan)) {
20001
20003
  handleError(new Error("Use exactly one of --plan or --clear-plan with bulk plan."));
20002
20004
  }
20003
- const planId = isPlanAction ? opts.plan ? resolvePlanId(opts.plan) : null : undefined;
20004
20005
  const knownActions = new Set(["done", "complete", "start", "delete", "plan", "move-plan"]);
20005
20006
  if (!knownActions.has(action)) {
20006
- handleError(new Error(`Unknown action: ${action}. Use: done, start, delete, plan`));
20007
+ handleError(new Error(`Unknown action: ${action}. Use: done, start, delete, plan (alias: move-plan)`));
20007
20008
  }
20008
20009
  if (cloud) {
20010
+ let cloudPlanId;
20011
+ if (isPlanAction) {
20012
+ if (opts.plan) {
20013
+ try {
20014
+ const projectScope = globalOpts.project ? await cloudResolveProjectRef(cloud, globalOpts.project) : undefined;
20015
+ const plan = await cloudResolvePlan(cloud, opts.plan, projectScope);
20016
+ if (!plan)
20017
+ throw new Error(`Could not resolve plan ID: ${opts.plan}`);
20018
+ cloudPlanId = plan.id;
20019
+ } catch (e) {
20020
+ handleError(e);
20021
+ }
20022
+ } else {
20023
+ cloudPlanId = null;
20024
+ }
20025
+ }
20009
20026
  for (const rawId of ids) {
20010
20027
  try {
20011
20028
  const resolvedId = await resolveTaskIdForCommand(rawId, cloud);
@@ -20019,7 +20036,7 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
20019
20036
  const current = await cloudGetTask(cloud, resolvedId);
20020
20037
  if (!current)
20021
20038
  throw new Error(`Task not found: ${rawId}`);
20022
- await cloudUpdateTask(cloud, resolvedId, { version: current.version, plan_id: planId });
20039
+ await cloudUpdateTask(cloud, resolvedId, { version: current.version, plan_id: cloudPlanId });
20023
20040
  }
20024
20041
  results.push({ id: resolvedId, success: true });
20025
20042
  } catch (e) {
@@ -20038,6 +20055,7 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
20038
20055
  }
20039
20056
  return;
20040
20057
  }
20058
+ const planId = isPlanAction ? opts.plan ? resolvePlanId(opts.plan) : null : undefined;
20041
20059
  for (const rawId of ids) {
20042
20060
  try {
20043
20061
  const resolvedId = resolveTaskId(rawId);
@@ -20058,7 +20076,7 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
20058
20076
  updateTask(resolvedId, { version: current.version, plan_id: planId });
20059
20077
  results.push({ id: resolvedId, success: true });
20060
20078
  } else {
20061
- handleError(new Error(`Unknown action: ${action}. Use: done, start, delete, plan`));
20079
+ handleError(new Error(`Unknown action: ${action}. Use: done, start, delete, plan (alias: move-plan)`));
20062
20080
  }
20063
20081
  } catch (e) {
20064
20082
  results.push({ id: rawId, success: false, error: e instanceof Error ? e.message : String(e) });
@@ -1 +1 @@
1
- {"version":3,"file":"stage-a.d.ts","sourceRoot":"","sources":["../../src/cli/stage-a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,WAAW,CAAC;AAO1C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,+BAA+B,GACvC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;AAyB/E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;CAuBgB,CAAC;AAsBvD,wBAAgB,kCAAkC,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAAG,IAAI,CASnH;AAoJD;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,GAAE,MAAM,EAA0B,EACtC,GAAG,GAAE,GAAwB,GAC5B,+BAA+B,CAgBjC"}
1
+ {"version":3,"file":"stage-a.d.ts","sourceRoot":"","sources":["../../src/cli/stage-a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,WAAW,CAAC;AAO1C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,+BAA+B,GACvC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;AAyB/E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;CAuBgB,CAAC;AAsBvD,wBAAgB,kCAAkC,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAAG,IAAI,CASnH;AAyJD;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,GAAE,MAAM,EAA0B,EACtC,GAAG,GAAE,GAAwB,GAC5B,+BAA+B,CAgBjC"}
package/dist/contracts.js CHANGED
@@ -11823,7 +11823,7 @@ var init_tasks = __esm(() => {
11823
11823
  // package.json
11824
11824
  var package_default = {
11825
11825
  name: "@hasna/todos",
11826
- version: "0.12.1",
11826
+ version: "0.12.2",
11827
11827
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
11828
11828
  type: "module",
11829
11829
  main: "dist/index.js",
package/dist/index.js CHANGED
@@ -11936,7 +11936,7 @@ var init_dispatches = __esm(() => {
11936
11936
  // package.json
11937
11937
  var package_default = {
11938
11938
  name: "@hasna/todos",
11939
- version: "0.12.1",
11939
+ version: "0.12.2",
11940
11940
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
11941
11941
  type: "module",
11942
11942
  main: "dist/index.js",
package/dist/mcp/index.js CHANGED
@@ -34187,7 +34187,7 @@ var package_default;
34187
34187
  var init_package = __esm(() => {
34188
34188
  package_default = {
34189
34189
  name: "@hasna/todos",
34190
- version: "0.12.1",
34190
+ version: "0.12.2",
34191
34191
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
34192
34192
  type: "module",
34193
34193
  main: "dist/index.js",
package/dist/mcp.js CHANGED
@@ -41,7 +41,7 @@ var __require = import.meta.require;
41
41
  // package.json
42
42
  var package_default = {
43
43
  name: "@hasna/todos",
44
- version: "0.12.1",
44
+ version: "0.12.2",
45
45
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
46
46
  type: "module",
47
47
  main: "dist/index.js",
package/dist/registry.js CHANGED
@@ -11823,7 +11823,7 @@ var init_tasks = __esm(() => {
11823
11823
  // package.json
11824
11824
  var package_default = {
11825
11825
  name: "@hasna/todos",
11826
- version: "0.12.1",
11826
+ version: "0.12.2",
11827
11827
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
11828
11828
  type: "module",
11829
11829
  main: "dist/index.js",
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "packageName": "@hasna/todos",
3
- "packageVersion": "0.12.1",
3
+ "packageVersion": "0.12.2",
4
4
  "repository": "https://github.com/hasna/todos.git",
5
- "gitCommit": "1fb083dab19cc751a06cd177d0b87781f9f700cb",
6
- "gitTree": "67c0f87525b006b30636690ee2fb83b5a8a08491",
7
- "sourceTreeSha256": "b8a8a90f23007fbcfa102de8ef9b05b82ef7f81f294b09ba53e44a0b6838a73c",
8
- "generatedAt": "2026-07-24T15:32:54.000Z"
5
+ "gitCommit": "6271f2144e08ad291b34c6d38d46a3cdadb14647",
6
+ "gitTree": "9f02f36bf7e73db36e738655b28841cf16fa5f6e",
7
+ "sourceTreeSha256": "520a72ea1d578387cf7403547f2deba823df0105214b6f404227e5f7c244f63f",
8
+ "generatedAt": "2026-07-24T21:29:56.000Z"
9
9
  }
@@ -70,7 +70,7 @@ var package_default;
70
70
  var init_package = __esm(() => {
71
71
  package_default = {
72
72
  name: "@hasna/todos",
73
- version: "0.12.1",
73
+ version: "0.12.2",
74
74
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
75
75
  type: "module",
76
76
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.12.1",
3
+ "version": "0.12.2",
4
4
  "description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",