@hasna/todos 0.15.35 → 0.15.46

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.
Files changed (92) hide show
  1. package/dist/cli/cloud-router.d.ts +52 -18
  2. package/dist/cli/cloud-router.d.ts.map +1 -1
  3. package/dist/cli/commands/agent-commands.d.ts.map +1 -1
  4. package/dist/cli/commands/plan-template-commands.d.ts.map +1 -1
  5. package/dist/cli/commands/project-commands.d.ts.map +1 -1
  6. package/dist/cli/commands/task-commands.d.ts.map +1 -1
  7. package/dist/cli/commands/task-subtree-transfer-commands.d.ts +3 -0
  8. package/dist/cli/commands/task-subtree-transfer-commands.d.ts.map +1 -0
  9. package/dist/cli/index.js +3430 -827
  10. package/dist/cli/stage-a.d.ts.map +1 -1
  11. package/dist/contracts.js +66 -58
  12. package/dist/db/plan-comments.d.ts +14 -0
  13. package/dist/db/plan-comments.d.ts.map +1 -0
  14. package/dist/db/schema.d.ts.map +1 -1
  15. package/dist/db/task-crud.d.ts.map +1 -1
  16. package/dist/db/task-graph.d.ts.map +1 -1
  17. package/dist/db/task-lifecycle.d.ts.map +1 -1
  18. package/dist/db/task-lists.d.ts.map +1 -1
  19. package/dist/db/task-relations.d.ts.map +1 -1
  20. package/dist/index.d.ts +3 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1897 -334
  23. package/dist/lib/comment-cursor.d.ts +19 -0
  24. package/dist/lib/comment-cursor.d.ts.map +1 -1
  25. package/dist/lib/import-export-bridge.d.ts.map +1 -1
  26. package/dist/lib/instant-compare.d.ts +35 -0
  27. package/dist/lib/instant-compare.d.ts.map +1 -0
  28. package/dist/mcp/index.js +2403 -501
  29. package/dist/mcp.js +8 -4
  30. package/dist/pr-groups/postgres.d.ts.map +1 -1
  31. package/dist/project-registration/postgres.d.ts.map +1 -1
  32. package/dist/project-registration.js +290 -81
  33. package/dist/registry.d.ts +1 -1
  34. package/dist/registry.d.ts.map +1 -1
  35. package/dist/registry.js +73 -58
  36. package/dist/release-provenance.json +5 -5
  37. package/dist/sdk/index.d.ts +1 -1
  38. package/dist/sdk/index.d.ts.map +1 -1
  39. package/dist/sdk/index.js +35 -0
  40. package/dist/sdk/v1.generated.d.ts +141 -0
  41. package/dist/sdk/v1.generated.d.ts.map +1 -1
  42. package/dist/server/cloud.d.ts +12 -2
  43. package/dist/server/cloud.d.ts.map +1 -1
  44. package/dist/server/index.js +5161 -8425
  45. package/dist/server/openapi.d.ts +2714 -1937
  46. package/dist/server/openapi.d.ts.map +1 -1
  47. package/dist/server/v1.d.ts +2 -1
  48. package/dist/server/v1.d.ts.map +1 -1
  49. package/dist/storage/config.d.ts +12 -30
  50. package/dist/storage/config.d.ts.map +1 -1
  51. package/dist/storage/index.d.ts +2 -2
  52. package/dist/storage/index.d.ts.map +1 -1
  53. package/dist/storage/interfaces.d.ts +13 -2
  54. package/dist/storage/interfaces.d.ts.map +1 -1
  55. package/dist/storage/local-sqlite.d.ts.map +1 -1
  56. package/dist/storage/postgres-adapter.d.ts.map +1 -1
  57. package/dist/storage/timestamp-backfill.d.ts +62 -0
  58. package/dist/storage/timestamp-backfill.d.ts.map +1 -0
  59. package/dist/storage.d.ts +2 -2
  60. package/dist/storage.d.ts.map +1 -1
  61. package/dist/storage.js +268 -74
  62. package/dist/task-manifest/postgres.d.ts.map +1 -1
  63. package/dist/task-manifest.js +15 -6
  64. package/dist/task-subtree-transfer/authority.d.ts +27 -0
  65. package/dist/task-subtree-transfer/authority.d.ts.map +1 -0
  66. package/dist/task-subtree-transfer/backend.d.ts +9 -0
  67. package/dist/task-subtree-transfer/backend.d.ts.map +1 -0
  68. package/dist/task-subtree-transfer/canonical.d.ts +14 -0
  69. package/dist/task-subtree-transfer/canonical.d.ts.map +1 -0
  70. package/dist/task-subtree-transfer/http.d.ts +16 -0
  71. package/dist/task-subtree-transfer/http.d.ts.map +1 -0
  72. package/dist/task-subtree-transfer/index.d.ts +6 -0
  73. package/dist/task-subtree-transfer/index.d.ts.map +1 -0
  74. package/dist/task-subtree-transfer/planner.d.ts +24 -0
  75. package/dist/task-subtree-transfer/planner.d.ts.map +1 -0
  76. package/dist/task-subtree-transfer/postgres.d.ts +19 -0
  77. package/dist/task-subtree-transfer/postgres.d.ts.map +1 -0
  78. package/dist/task-subtree-transfer/schema-sql.d.ts +5 -0
  79. package/dist/task-subtree-transfer/schema-sql.d.ts.map +1 -0
  80. package/dist/task-subtree-transfer/sqlite.d.ts +16 -0
  81. package/dist/task-subtree-transfer/sqlite.d.ts.map +1 -0
  82. package/dist/task-subtree-transfer/types.d.ts +148 -0
  83. package/dist/task-subtree-transfer/types.d.ts.map +1 -0
  84. package/dist/task-subtree-transfer.d.ts +2 -0
  85. package/dist/task-subtree-transfer.d.ts.map +1 -0
  86. package/dist/task-subtree-transfer.js +1878 -0
  87. package/dist/testing.d.ts +41 -7
  88. package/dist/testing.d.ts.map +1 -1
  89. package/dist/testing.js +44 -1
  90. package/dist/types/index.d.ts +24 -0
  91. package/dist/types/index.d.ts.map +1 -1
  92. package/package.json +8 -4
@@ -12,7 +12,7 @@ export interface TodosPackageSource {
12
12
  version: string;
13
13
  }
14
14
  export interface TodosPackageExportContract {
15
- subpath: "." | "./sdk" | "./mcp" | "./registry" | "./contracts" | "./storage" | "./testing" | "./project-registration" | "./task-manifest";
15
+ subpath: "." | "./sdk" | "./mcp" | "./registry" | "./contracts" | "./storage" | "./testing" | "./project-registration" | "./task-manifest" | "./task-subtree-transfer";
16
16
  import: string;
17
17
  types: string;
18
18
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,aAAa,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EACH,GAAG,GACH,OAAO,GACP,OAAO,GACP,YAAY,GACZ,aAAa,GACb,WAAW,GACX,WAAW,GACX,wBAAwB,GACxB,iBAAiB,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C,YAAY,EAAE,uBAAuB,CAAC;IACtC,SAAS,EAAE,sBAAsB,CAAC;IAClC,GAAG,EAAE,gBAAgB,CAAC;IACtB,YAAY,EAAE,yBAAyB,CAAC;CACzC;AAED,eAAO,MAAM,qBAAqB,EAAE,0BAA0B,EAgE7D,CAAC;AAUF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B,GAAG,aAAa,CAc3F;AAED,eAAO,MAAM,cAAc,eAEzB,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,cAAc,CAAC;IAC5B,UAAU,EAAE,aAAa,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EACH,GAAG,GACH,OAAO,GACP,OAAO,GACP,YAAY,GACZ,aAAa,GACb,WAAW,GACX,WAAW,GACX,wBAAwB,GACxB,iBAAiB,GACjB,yBAAyB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,EAAE,0BAA0B,EAAE,CAAC;IACtC,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C,YAAY,EAAE,uBAAuB,CAAC;IACtC,SAAS,EAAE,sBAAsB,CAAC;IAClC,GAAG,EAAE,gBAAgB,CAAC;IACtB,YAAY,EAAE,yBAAyB,CAAC;CACzC;AAED,eAAO,MAAM,qBAAqB,EAAE,0BAA0B,EAuE7D,CAAC;AAUF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B,GAAG,aAAa,CAc3F;AAED,eAAO,MAAM,cAAc,eAEzB,CAAC"}
package/dist/registry.js CHANGED
@@ -2676,6 +2676,20 @@ function ensureSchema(db) {
2676
2676
  ensureIndex("CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_event ON webhook_deliveries(event)");
2677
2677
  ensureColumn("task_comments", "type", "TEXT DEFAULT 'comment'");
2678
2678
  ensureColumn("task_comments", "progress_pct", "INTEGER");
2679
+ ensureTable("plan_comments", `
2680
+ CREATE TABLE plan_comments (
2681
+ id TEXT PRIMARY KEY,
2682
+ plan_id TEXT NOT NULL REFERENCES plans(id) ON DELETE CASCADE,
2683
+ agent_id TEXT,
2684
+ session_id TEXT,
2685
+ content TEXT NOT NULL,
2686
+ type TEXT DEFAULT 'comment' CHECK(type IN ('comment', 'progress', 'note')),
2687
+ progress_pct INTEGER CHECK(progress_pct IS NULL OR (progress_pct >= 0 AND progress_pct <= 100)),
2688
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
2689
+ machine_id TEXT,
2690
+ synced_at TEXT
2691
+ )`);
2692
+ ensureIndex("CREATE INDEX IF NOT EXISTS idx_plan_comments_plan ON plan_comments(plan_id)");
2679
2693
  ensureColumn("projects", "machine_id", "TEXT");
2680
2694
  ensureColumn("projects", "synced_at", "TEXT");
2681
2695
  ensureColumn("tasks", "machine_id", "TEXT");
@@ -3657,6 +3671,7 @@ var init_machines = __esm(() => {
3657
3671
  "task_lists",
3658
3672
  "plans",
3659
3673
  "task_comments",
3674
+ "plan_comments",
3660
3675
  "sessions",
3661
3676
  "task_history",
3662
3677
  "webhooks",
@@ -4160,20 +4175,16 @@ var init_sync_utils = __esm(() => {
4160
4175
  // src/storage/config.ts
4161
4176
  var exports_config = {};
4162
4177
  __export(exports_config, {
4163
- parseStorageMode: () => parseStorageMode,
4164
4178
  parseStorageBackend: () => parseStorageBackend,
4165
4179
  loadTodosStorageConfig: () => loadTodosStorageConfig,
4166
4180
  loadStorageConfig: () => loadStorageConfig,
4167
4181
  isTodosShadowEnabled: () => isTodosShadowEnabled,
4168
- isTodosRemoteStorageEnabled: () => isTodosRemoteStorageEnabled,
4169
4182
  isTodosPostgresBackend: () => isTodosPostgresBackend,
4170
4183
  getTodosStorageShadowEnvName: () => getTodosStorageShadowEnvName,
4171
- getTodosStorageMode: () => getTodosStorageMode,
4172
4184
  getTodosStorageEnvName: () => getTodosStorageEnvName,
4173
4185
  getTodosStorageDatabaseUrl: () => getTodosStorageDatabaseUrl,
4174
4186
  getTodosStorageDatabaseEnv: () => getTodosStorageDatabaseEnv,
4175
4187
  getTodosStorageBackend: () => getTodosStorageBackend,
4176
- getStorageMode: () => getStorageMode,
4177
4188
  getStorageDatabaseUrl: () => getStorageDatabaseUrl,
4178
4189
  getStorageDatabaseEnv: () => getStorageDatabaseEnv,
4179
4190
  getCanonicalTodosRdsConfig: () => getCanonicalTodosRdsConfig,
@@ -4183,7 +4194,6 @@ __export(exports_config, {
4183
4194
  TODOS_STORAGE_FALLBACK_ENV: () => TODOS_STORAGE_FALLBACK_ENV,
4184
4195
  TODOS_STORAGE_ENV: () => TODOS_STORAGE_ENV,
4185
4196
  STORAGE_TABLES: () => STORAGE_TABLES,
4186
- REMOVED_STORAGE_MODE_ENV_KEYS: () => REMOVED_STORAGE_MODE_ENV_KEYS,
4187
4197
  CANONICAL_TODOS_RDS_RUNTIME_PATH_ENV: () => CANONICAL_TODOS_RDS_RUNTIME_PATH_ENV,
4188
4198
  CANONICAL_TODOS_RDS_DATABASE: () => CANONICAL_TODOS_RDS_DATABASE,
4189
4199
  CANONICAL_TODOS_RDS_CLUSTER_ENV: () => CANONICAL_TODOS_RDS_CLUSTER_ENV
@@ -4238,9 +4248,6 @@ function loadStorageConfig(env = process.env) {
4238
4248
  function isTodosPostgresBackend(config) {
4239
4249
  return config.mode === "postgres";
4240
4250
  }
4241
- function isTodosRemoteStorageEnabled(config) {
4242
- return isTodosPostgresBackend(config);
4243
- }
4244
4251
  function assertTodosRemoteStorageConfig(config) {
4245
4252
  if (!isTodosPostgresBackend(config))
4246
4253
  return;
@@ -4256,32 +4263,15 @@ function parseStorageBackend(value) {
4256
4263
  return "sqlite";
4257
4264
  if (normalized === "postgres" || normalized === "postgresql")
4258
4265
  return "postgres";
4259
- if (["local", "remote", "cloud", "hybrid", "self_hosted"].includes(normalized)) {
4260
- throw new Error(`${TODOS_STORAGE_ENV.databaseUrl} selects the backend. Deployment modes no longer exist: ` + `delete the storage-mode variable and set ${TODOS_STORAGE_ENV.databaseUrl} to select the ` + `postgresql backend, or leave it unset for sqlite.`);
4261
- }
4262
4266
  throw new Error(`Storage backend must be sqlite or postgres`);
4263
4267
  }
4264
- function parseStorageMode(value) {
4265
- return parseStorageBackend(value);
4266
- }
4267
4268
  function getTodosStorageBackend(env = process.env) {
4268
- for (const key of REMOVED_STORAGE_MODE_ENV_KEYS) {
4269
- if (Object.hasOwn(env, key) && env[key] !== undefined) {
4270
- throw new Error(`${key} was removed. Deployment modes no longer exist: delete the storage-mode variable. ` + `Set ${TODOS_STORAGE_ENV.databaseUrl} to select the postgresql backend, ` + `or leave it unset for sqlite.`);
4271
- }
4272
- }
4273
4269
  if (!getTodosStorageDatabaseUrl(env))
4274
4270
  return "sqlite";
4275
4271
  if (isTodosShadowEnabled(env))
4276
4272
  return "sqlite";
4277
4273
  return "postgres";
4278
4274
  }
4279
- function getTodosStorageMode(env = process.env) {
4280
- return getTodosStorageBackend(env);
4281
- }
4282
- function getStorageMode(env = process.env) {
4283
- return getTodosStorageBackend(env);
4284
- }
4285
4275
  function isTodosShadowEnabled(env = process.env) {
4286
4276
  return parseBoolean(readStorageEnv(env, "shadow").value, false);
4287
4277
  }
@@ -4348,7 +4338,7 @@ function parsePositiveInteger(value, fallback) {
4348
4338
  }
4349
4339
  return parsed;
4350
4340
  }
4351
- var TODOS_STORAGE_TABLES, STORAGE_TABLES, TODOS_STORAGE_ENV, TODOS_STORAGE_FALLBACK_ENV, REMOVED_STORAGE_MODE_ENV_KEYS, CANONICAL_TODOS_RDS_CLUSTER_ENV = "HASNA_TODOS_RDS_CLUSTER", CANONICAL_TODOS_RDS_RUNTIME_PATH_ENV = "HASNA_TODOS_RDS_RUNTIME_PATH", CANONICAL_TODOS_RDS_DATABASE = "todos";
4341
+ var TODOS_STORAGE_TABLES, STORAGE_TABLES, TODOS_STORAGE_ENV, TODOS_STORAGE_FALLBACK_ENV, CANONICAL_TODOS_RDS_CLUSTER_ENV = "HASNA_TODOS_RDS_CLUSTER", CANONICAL_TODOS_RDS_RUNTIME_PATH_ENV = "HASNA_TODOS_RDS_RUNTIME_PATH", CANONICAL_TODOS_RDS_DATABASE = "todos";
4352
4342
  var init_config = __esm(() => {
4353
4343
  TODOS_STORAGE_TABLES = [
4354
4344
  "todos_sync_records",
@@ -4387,12 +4377,6 @@ var init_config = __esm(() => {
4387
4377
  syncBatchSize: "TODOS_SYNC_BATCH_SIZE",
4388
4378
  syncDryRun: "TODOS_SYNC_DRY_RUN"
4389
4379
  };
4390
- REMOVED_STORAGE_MODE_ENV_KEYS = [
4391
- "HASNA_TODOS_STORAGE_MODE",
4392
- "HASNA_TODOS_MODE",
4393
- "TODOS_STORAGE_MODE",
4394
- "TODOS_MODE"
4395
- ];
4396
4380
  });
4397
4381
 
4398
4382
  // src/storage/shadow-outbox-schema.ts
@@ -6857,22 +6841,31 @@ function updateTaskList(id, input, db) {
6857
6841
  throw new TaskListNotFoundError(id);
6858
6842
  const sets = ["updated_at = ?"];
6859
6843
  const params = [now()];
6860
- if (input.slug !== undefined) {
6861
- const slug = slugify(input.slug);
6862
- if (!slug)
6863
- throw new Error("Invalid task-list slug \u2014 must be non-empty kebab-case");
6864
- const duplicate = existing.project_id ? d.query("SELECT id FROM task_lists WHERE project_id = ? AND slug = ? AND id != ?").get(existing.project_id, slug, id) : d.query("SELECT id FROM task_lists WHERE project_id IS NULL AND slug = ? AND id != ?").get(slug, id);
6844
+ const projectId = input.project_id === "" || input.project_id === null ? null : input.project_id === undefined ? existing.project_id : input.project_id;
6845
+ const scopeChanged = projectId !== existing.project_id;
6846
+ const effectiveSlug = input.slug !== undefined ? slugify(input.slug) : existing.slug;
6847
+ if (input.slug !== undefined && !effectiveSlug) {
6848
+ throw new Error("Invalid task-list slug \u2014 must be non-empty kebab-case");
6849
+ }
6850
+ if (scopeChanged || input.slug !== undefined && effectiveSlug !== existing.slug) {
6851
+ const duplicate = projectId ? d.query("SELECT id FROM task_lists WHERE project_id = ? AND slug = ? AND id != ?").get(projectId, effectiveSlug, id) : d.query("SELECT id FROM task_lists WHERE project_id IS NULL AND slug = ? AND id != ?").get(effectiveSlug, id);
6865
6852
  if (duplicate) {
6866
- throw new ResourceConflictError("TASK_LIST_SLUG_CONFLICT", `Task list with slug "${slug}" already exists in this scope`);
6853
+ throw new ResourceConflictError("TASK_LIST_SLUG_CONFLICT", `Task list with slug "${effectiveSlug}" already exists in this scope`);
6867
6854
  }
6868
- if (slug !== existing.slug) {
6855
+ if (scopeChanged || effectiveSlug !== existing.slug) {
6869
6856
  releaseCanonicalSlugClaims("task_list", id, d);
6870
- if (!claimCanonicalSlug("task_list", taskListSlugScopeKey(existing.project_id), slug, id, d)) {
6871
- throw new ResourceConflictError("TASK_LIST_SLUG_CONFLICT", `Task list with slug "${slug}" already exists in this scope`);
6857
+ if (!claimCanonicalSlug("task_list", taskListSlugScopeKey(projectId), effectiveSlug, id, d)) {
6858
+ throw new ResourceConflictError("TASK_LIST_SLUG_CONFLICT", `Task list with slug "${effectiveSlug}" already exists in this scope`);
6872
6859
  }
6873
6860
  }
6861
+ }
6862
+ if (input.slug !== undefined) {
6874
6863
  sets.push("slug = ?");
6875
- params.push(slug);
6864
+ params.push(effectiveSlug);
6865
+ }
6866
+ if (projectId !== existing.project_id) {
6867
+ sets.push("project_id = ?");
6868
+ params.push(projectId);
6876
6869
  }
6877
6870
  if (input.name !== undefined) {
6878
6871
  sets.push("name = ?");
@@ -8658,7 +8651,7 @@ function getTaskGraph(taskId, direction = "both", db) {
8658
8651
  const deps = getTaskDependencies(t.id, d);
8659
8652
  const hasUnfinishedDeps = deps.some((dep) => {
8660
8653
  const depTask = getTask(dep.depends_on, d);
8661
- return depTask && depTask.status !== "completed";
8654
+ return depTask && isBlockingDependencyStatus(depTask.status);
8662
8655
  });
8663
8656
  return { id: t.id, short_id: t.short_id, title: t.title, status: t.status, priority: t.priority, is_blocked: hasUnfinishedDeps };
8664
8657
  }
@@ -8918,7 +8911,7 @@ function getBlockingDeps(id, db) {
8918
8911
  const blocking = [];
8919
8912
  for (const dep of deps) {
8920
8913
  const task = getTask(dep.depends_on, d);
8921
- if (task && task.status !== "completed")
8914
+ if (task && isBlockingDependencyStatus(task.status))
8922
8915
  blocking.push(task);
8923
8916
  }
8924
8917
  return blocking;
@@ -9242,7 +9235,7 @@ function getNextTask(agentId, filters, db) {
9242
9235
  conditions.push(`id IN (SELECT task_id FROM task_tags WHERE tag IN (${placeholders}))`);
9243
9236
  params.push(...filters.tags);
9244
9237
  }
9245
- conditions.push("id NOT IN (SELECT td.task_id FROM task_dependencies td JOIN tasks dep ON dep.id = td.depends_on WHERE dep.status != 'completed')");
9238
+ conditions.push("id NOT IN (SELECT td.task_id FROM task_dependencies td JOIN tasks dep ON dep.id = td.depends_on WHERE dep.status NOT IN ('completed', 'cancelled'))");
9246
9239
  const where = conditions.join(" AND ");
9247
9240
  let recentProjectIds = [];
9248
9241
  const assignedAliasParams = [];
@@ -9286,7 +9279,7 @@ function getActiveWork(filters, db) {
9286
9279
  }
9287
9280
  function getTasksChangedSince(since, filters, db) {
9288
9281
  const d = db || getDatabase();
9289
- const conditions = ["updated_at > ?"];
9282
+ const conditions = ["(julianday(updated_at) IS NULL OR julianday(updated_at) > julianday(?))"];
9290
9283
  const params = [since];
9291
9284
  if (filters?.project_id) {
9292
9285
  conditions.push("project_id = ?");
@@ -9321,8 +9314,8 @@ function failTask(id, agentId, reason, options, db) {
9321
9314
  const safeMeta = sanitizePreWriteValue(meta, "task.failure.metadata");
9322
9315
  const timestamp2 = now();
9323
9316
  const failTx = d.transaction(() => {
9324
- const res = d.run(`UPDATE tasks SET status = 'failed', reason = ?, locked_by = NULL, locked_at = NULL, metadata = ?, version = version + 1, updated_at = ?
9325
- WHERE id = ? AND version = ?`, [safeReason, JSON.stringify(safeMeta), timestamp2, id, task.version]);
9317
+ const res = d.run(`UPDATE tasks SET status = 'failed', reason = ?, locked_by = NULL, locked_at = NULL, completed_at = COALESCE(completed_at, ?), metadata = ?, version = version + 1, updated_at = ?
9318
+ WHERE id = ? AND version = ?`, [safeReason, timestamp2, JSON.stringify(safeMeta), timestamp2, id, task.version]);
9326
9319
  if (res.changes === 0) {
9327
9320
  const current = getTask(id, d);
9328
9321
  throw new VersionConflictError(id, task.version, current?.version ?? -1);
@@ -9334,6 +9327,7 @@ function failTask(id, agentId, reason, options, db) {
9334
9327
  status: "failed",
9335
9328
  locked_by: null,
9336
9329
  locked_at: null,
9330
+ completed_at: task.completed_at ?? timestamp2,
9337
9331
  reason: safeReason,
9338
9332
  metadata: safeMeta,
9339
9333
  version: task.version + 1,
@@ -9982,13 +9976,20 @@ function updateTaskStored(id, input, db) {
9982
9976
  if (isTerminalStatus(input.status)) {
9983
9977
  sets.push("locked_by = NULL");
9984
9978
  sets.push("locked_at = NULL");
9985
- }
9986
- if (input.status === "completed") {
9987
- sets.push("completed_at = ?");
9988
- params.push(completionTimestamp);
9979
+ if (input.status === "completed") {
9980
+ sets.push("completed_at = ?");
9981
+ params.push(completionTimestamp);
9982
+ } else {
9983
+ sets.push("completed_at = COALESCE(completed_at, ?)");
9984
+ params.push(completionTimestamp);
9985
+ }
9989
9986
  } else if (task.status === "completed" && input.completed_at === undefined) {
9990
9987
  sets.push("completed_at = NULL");
9991
9988
  }
9989
+ if (input.status === "in_progress") {
9990
+ sets.push("started_at = COALESCE(started_at, ?)");
9991
+ params.push(timestamp2);
9992
+ }
9992
9993
  }
9993
9994
  if (input.priority !== undefined) {
9994
9995
  sets.push("priority = ?");
@@ -10126,7 +10127,6 @@ function updateTaskStored(id, input, db) {
10126
10127
  if (input.approved_by !== undefined)
10127
10128
  logTaskChange(id, "approve", "approved_by", null, input.approved_by, agentId, d);
10128
10129
  const reopened = input.status !== undefined && input.status !== "completed" && task.status === "completed" && input.completed_at === undefined;
10129
- const completedNow = input.status === "completed";
10130
10130
  const terminalNow = input.status !== undefined && isTerminalStatus(input.status);
10131
10131
  const updatedTask = {
10132
10132
  ...task,
@@ -10137,7 +10137,8 @@ function updateTaskStored(id, input, db) {
10137
10137
  updated_at: timestamp2,
10138
10138
  locked_by: terminalNow ? null : task.locked_by,
10139
10139
  locked_at: terminalNow ? null : task.locked_at,
10140
- completed_at: completedNow ? completionTimestamp : reopened ? null : input.completed_at !== undefined ? input.completed_at : task.completed_at,
10140
+ completed_at: input.status === "completed" ? completionTimestamp : input.completed_at !== undefined ? input.completed_at : terminalNow ? task.completed_at ?? completionTimestamp : reopened ? null : task.completed_at,
10141
+ started_at: input.status === "in_progress" ? task.started_at ?? timestamp2 : task.started_at,
10141
10142
  sla_minutes: input.sla_minutes !== undefined ? input.sla_minutes : task.sla_minutes,
10142
10143
  actual_minutes: input.actual_minutes ?? task.actual_minutes,
10143
10144
  confidence: input.confidence !== undefined ? input.confidence : task.confidence,
@@ -10198,6 +10199,9 @@ function deleteTask(id, db) {
10198
10199
  version: row.version
10199
10200
  }, d);
10200
10201
  const result = d.run("DELETE FROM tasks WHERE id = ?", [id]);
10202
+ if (result.changes > 0) {
10203
+ d.run("DELETE FROM task_dependencies WHERE task_id = ? OR depends_on = ?", [id, id]);
10204
+ }
10201
10205
  return result.changes > 0;
10202
10206
  }
10203
10207
  var init_task_crud = __esm(() => {
@@ -12805,7 +12809,7 @@ var init_tasks = __esm(() => {
12805
12809
  // package.json
12806
12810
  var package_default = {
12807
12811
  name: "@hasna/todos",
12808
- version: "0.15.35",
12812
+ version: "0.15.46",
12809
12813
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
12810
12814
  type: "module",
12811
12815
  main: "dist/index.js",
@@ -12851,6 +12855,10 @@ var package_default = {
12851
12855
  "./task-manifest": {
12852
12856
  types: "./dist/task-manifest.d.ts",
12853
12857
  import: "./dist/task-manifest.js"
12858
+ },
12859
+ "./task-subtree-transfer": {
12860
+ types: "./dist/task-subtree-transfer.d.ts",
12861
+ import: "./dist/task-subtree-transfer.js"
12854
12862
  }
12855
12863
  },
12856
12864
  workspaces: [
@@ -12864,8 +12872,8 @@ var package_default = {
12864
12872
  "README.md"
12865
12873
  ],
12866
12874
  scripts: {
12867
- build: "rm -rf dist dashboard/dist && cd dashboard && bun install --frozen-lockfile && bun run build && cd .. && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts src/testing.ts src/project-registration.ts src/task-manifest.ts --outdir dist --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && tsc --emitDeclarationOnly --outDir dist",
12868
- "build:server": "rm -rf dist && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts src/testing.ts src/project-registration.ts src/task-manifest.ts --outdir dist --target bun --external '@hasna/contracts' --external '@hasna/contracts/*'",
12875
+ build: "rm -rf dist dashboard/dist && cd dashboard && bun install --frozen-lockfile && bun run build && cd .. && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts src/testing.ts src/project-registration.ts src/task-manifest.ts src/task-subtree-transfer.ts --outdir dist --root src --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && tsc --emitDeclarationOnly --outDir dist",
12876
+ "build:server": "rm -rf dist && bun build src/cli/index.tsx --outdir dist/cli --target bun --external ink --external react --external chalk --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/server/index.ts --outdir dist/server --target bun && bun build src/sdk/index.ts --outdir dist/sdk --target bun --external '@hasna/contracts' --external '@hasna/contracts/*' && bun build src/index.ts src/mcp.ts src/registry.ts src/contracts.ts src/storage.ts src/testing.ts src/project-registration.ts src/task-manifest.ts src/task-subtree-transfer.ts --outdir dist --target bun --external '@hasna/contracts' --external '@hasna/contracts/*'",
12869
12877
  migrate: "bun run src/server/index.ts migrate",
12870
12878
  "backfill:comment-redaction": "bun run src/server/index.ts redact-comments",
12871
12879
  "generate:sdk": "bun run scripts/generate-sdk.ts",
@@ -12919,7 +12927,7 @@ var package_default = {
12919
12927
  author: "Andrei Hasna <andrei@hasna.com>",
12920
12928
  license: "Apache-2.0",
12921
12929
  dependencies: {
12922
- "@hasna/contracts": "0.5.2",
12930
+ "@hasna/contracts": "0.13.4",
12923
12931
  "@hasna/events": "^0.1.11",
12924
12932
  "@modelcontextprotocol/sdk": "^1.12.1",
12925
12933
  chalk: "^5.4.1",
@@ -25105,6 +25113,13 @@ var TODOS_PACKAGE_EXPORTS = [
25105
25113
  types: "./dist/task-manifest.d.ts",
25106
25114
  description: "Transactional package-owned authority for deterministic plan and task graph manifests.",
25107
25115
  stability: "stable"
25116
+ },
25117
+ {
25118
+ subpath: "./task-subtree-transfer",
25119
+ import: "./dist/task-subtree-transfer.js",
25120
+ types: "./dist/task-subtree-transfer.d.ts",
25121
+ description: "Atomic package-owned authority for existing task-subtree project transfers and rollback.",
25122
+ stability: "stable"
25108
25123
  }
25109
25124
  ];
25110
25125
  function source8(version) {
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "packageName": "@hasna/todos",
3
- "packageVersion": "0.15.35",
3
+ "packageVersion": "0.15.46",
4
4
  "repository": "https://github.com/hasna/todos.git",
5
- "gitCommit": "0d94d7e2b58f09974c00f68b96c09acfd25128a8",
6
- "gitTree": "44f6dc53a613820140b8f2ec1b5deb6e2d367edd",
7
- "sourceTreeSha256": "35acd37b72272fe8e51d841bc0a58de973d20adb78ce8cf0963a9d3c895fbea1",
8
- "generatedAt": "2026-08-17T17:25:19.000Z"
5
+ "gitCommit": "c80f00ce94d3a8a18c6c3810127cf4a7bb7b2353",
6
+ "gitTree": "744ca8f8d9f3b8c2afff7f9c92df419dc8a64ad8",
7
+ "sourceTreeSha256": "60f8de83b04c4b91fbcf564f95f0f9cb5998683b8e35512a4bd42577c1edd8ba",
8
+ "generatedAt": "2026-08-22T22:48:59.000Z"
9
9
  }
@@ -10,7 +10,7 @@
10
10
  export { TodosClient, createClient } from "./client.js";
11
11
  export type { TodosClientOptions } from "./client.js";
12
12
  export { TodosV1Client, ApiError as TodosV1ApiError } from "./v1.generated.js";
13
- export type { TodosV1ClientOptions, Task as TodosV1Task, Project as TodosV1Project, TaskManifestBindingLookupRequest as TodosV1TaskManifestBindingLookupRequest, TaskManifestBindingLookupResult as TodosV1TaskManifestBindingLookupResult, TaskManifestBindingLookupResponse as TodosV1TaskManifestBindingLookupResponse, ProjectRegistrationCapability as TodosV1ProjectRegistrationCapability, ProjectRegistrationReceipt as TodosV1ProjectRegistrationReceipt, ProjectRegistrationRequest as TodosV1ProjectRegistrationRequest, ProjectRegistrationLookupRequest as TodosV1ProjectRegistrationLookupRequest, ProjectResource as TodosV1ProjectResource, ProjectResourcePage as TodosV1ProjectResourcePage, TaskComment as TodosV1TaskComment, CreateTaskInput as TodosV1CreateTaskInput, UpdateTaskInput as TodosV1UpdateTaskInput, FailTaskInput as TodosV1FailTaskInput, TaskFailureResult as TodosV1TaskFailureResult, CreateProjectInput as TodosV1CreateProjectInput, ProjectTaskListEnsureApplyInput as TodosV1ProjectTaskListEnsureApplyInput, ProjectTaskListRollbackInput as TodosV1ProjectTaskListRollbackInput, ProjectTaskListEnsureReceipt as TodosV1ProjectTaskListEnsureReceipt, ProjectTaskListEnsureResult as TodosV1ProjectTaskListEnsureResult, ProjectTaskListRollbackResult as TodosV1ProjectTaskListRollbackResult, CreateTaskCommentInput as TodosV1CreateTaskCommentInput, AdmitPrGroupInput as TodosV1AdmitPrGroupInput, RecoverPrGroupInput as TodosV1RecoverPrGroupInput, AppendPrGroupEventInput as TodosV1AppendPrGroupEventInput, PrGroupCiProof as TodosV1PrGroupCiProof, PrGroupCleanupProof as TodosV1PrGroupCleanupProof, PrGroupRecord as TodosV1PrGroupRecord, PrGroupAttemptRecord as TodosV1PrGroupAttemptRecord, PrGroupEventRecord as TodosV1PrGroupEventRecord, PrGroupStateView as TodosV1PrGroupStateView, PrGroupEventPage as TodosV1PrGroupEventPage, PrGroupMutationResult as TodosV1PrGroupMutationResult, } from "./v1.generated.js";
13
+ export type { TodosV1ClientOptions, Task as TodosV1Task, Project as TodosV1Project, TaskManifestBindingLookupRequest as TodosV1TaskManifestBindingLookupRequest, TaskManifestBindingLookupResult as TodosV1TaskManifestBindingLookupResult, TaskManifestBindingLookupResponse as TodosV1TaskManifestBindingLookupResponse, TaskSubtreeTransferExpectedTask as TodosV1TaskSubtreeTransferExpectedTask, TaskSubtreeTransferSharedPlanSplit as TodosV1TaskSubtreeTransferSharedPlanSplit, TaskSubtreeTransferInspectRequest as TodosV1TaskSubtreeTransferInspectRequest, TaskSubtreeTransferInspection as TodosV1TaskSubtreeTransferInspection, TaskSubtreeTransferApplyRequest as TodosV1TaskSubtreeTransferApplyRequest, TaskSubtreeTransferTaskImage as TodosV1TaskSubtreeTransferTaskImage, TaskSubtreeTransferPlanImage as TodosV1TaskSubtreeTransferPlanImage, TaskSubtreeTransferImage as TodosV1TaskSubtreeTransferImage, TaskSubtreeTransferReceipt as TodosV1TaskSubtreeTransferReceipt, TaskSubtreeTransferResult as TodosV1TaskSubtreeTransferResult, TaskSubtreeTransferCapability as TodosV1TaskSubtreeTransferCapability, TaskSubtreeTransferRollbackRequest as TodosV1TaskSubtreeTransferRollbackRequest, TaskSubtreeTransferReadExactRequest as TodosV1TaskSubtreeTransferReadExactRequest, ProjectRegistrationCapability as TodosV1ProjectRegistrationCapability, ProjectRegistrationReceipt as TodosV1ProjectRegistrationReceipt, ProjectRegistrationRequest as TodosV1ProjectRegistrationRequest, ProjectRegistrationLookupRequest as TodosV1ProjectRegistrationLookupRequest, ProjectResource as TodosV1ProjectResource, ProjectResourcePage as TodosV1ProjectResourcePage, TaskComment as TodosV1TaskComment, CreateTaskInput as TodosV1CreateTaskInput, UpdateTaskInput as TodosV1UpdateTaskInput, FailTaskInput as TodosV1FailTaskInput, TaskFailureResult as TodosV1TaskFailureResult, CreateProjectInput as TodosV1CreateProjectInput, ProjectTaskListEnsureApplyInput as TodosV1ProjectTaskListEnsureApplyInput, ProjectTaskListRollbackInput as TodosV1ProjectTaskListRollbackInput, ProjectTaskListEnsureReceipt as TodosV1ProjectTaskListEnsureReceipt, ProjectTaskListEnsureResult as TodosV1ProjectTaskListEnsureResult, ProjectTaskListRollbackResult as TodosV1ProjectTaskListRollbackResult, CreateTaskCommentInput as TodosV1CreateTaskCommentInput, AdmitPrGroupInput as TodosV1AdmitPrGroupInput, RecoverPrGroupInput as TodosV1RecoverPrGroupInput, AppendPrGroupEventInput as TodosV1AppendPrGroupEventInput, PrGroupCiProof as TodosV1PrGroupCiProof, PrGroupCleanupProof as TodosV1PrGroupCleanupProof, PrGroupRecord as TodosV1PrGroupRecord, PrGroupAttemptRecord as TodosV1PrGroupAttemptRecord, PrGroupEventRecord as TodosV1PrGroupEventRecord, PrGroupStateView as TodosV1PrGroupStateView, PrGroupEventPage as TodosV1PrGroupEventPage, PrGroupMutationResult as TodosV1PrGroupMutationResult, } from "./v1.generated.js";
14
14
  export type { AdmitPrGroupInput, AppendPrGroupEventInput, PrGroupAdapterViews, PrGroupAttemptRecord, PrGroupCiProof, PrGroupCleanupProof, PrGroupDecisionEnvelopeAdapter, PrGroupEventListOptions, PrGroupEventPage, PrGroupEventRecord, PrGroupEvidenceRefAdapter, PrGroupMutationResult, PrGroupProofBundleAdapter, PrGroupRecord, PrGroupStateView, PrGroupWorkRunAdapter, RecoverPrGroupInput, } from "../pr-groups/types.js";
15
15
  export { TodosAPIError, TodosNotFoundError, TodosConflictError, TodosUnauthorizedError, TodosRateLimitError, TodosTimeoutError, } from "./types.js";
16
16
  export type { SSEEvent, CursorPage, ListOptions, TaskListResponse, TaskStatusResponse, TaskNextResponse, TaskActiveResponse, TaskStaleResponse, TaskChangedResponse, TaskContextResponse, TaskProgressResponse, TaskAttachmentsResponse, TaskFailResponse, TaskBulkResponse, AgentMeResponse, AgentQueueResponse, OrgNode, PlanWithTasks, ReportResponse, DoctorResponse, DoctorIssue, } from "./types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,OAAO,EAAE,aAAa,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,oBAAoB,EACpB,IAAI,IAAI,WAAW,EACnB,OAAO,IAAI,cAAc,EACzB,gCAAgC,IAAI,uCAAuC,EAC3E,+BAA+B,IAAI,sCAAsC,EACzE,iCAAiC,IAAI,wCAAwC,EAC7E,6BAA6B,IAAI,oCAAoC,EACrE,0BAA0B,IAAI,iCAAiC,EAC/D,0BAA0B,IAAI,iCAAiC,EAC/D,gCAAgC,IAAI,uCAAuC,EAC3E,eAAe,IAAI,sBAAsB,EACzC,mBAAmB,IAAI,0BAA0B,EACjD,WAAW,IAAI,kBAAkB,EACjC,eAAe,IAAI,sBAAsB,EACzC,eAAe,IAAI,sBAAsB,EACzC,aAAa,IAAI,oBAAoB,EACrC,iBAAiB,IAAI,wBAAwB,EAC7C,kBAAkB,IAAI,yBAAyB,EAC/C,+BAA+B,IAAI,sCAAsC,EACzE,4BAA4B,IAAI,mCAAmC,EACnE,4BAA4B,IAAI,mCAAmC,EACnE,2BAA2B,IAAI,kCAAkC,EACjE,6BAA6B,IAAI,oCAAoC,EACrE,sBAAsB,IAAI,6BAA6B,EACvD,iBAAiB,IAAI,wBAAwB,EAC7C,mBAAmB,IAAI,0BAA0B,EACjD,uBAAuB,IAAI,8BAA8B,EACzD,cAAc,IAAI,qBAAqB,EACvC,mBAAmB,IAAI,0BAA0B,EACjD,aAAa,IAAI,oBAAoB,EACrC,oBAAoB,IAAI,2BAA2B,EACnD,kBAAkB,IAAI,yBAAyB,EAC/C,gBAAgB,IAAI,uBAAuB,EAC3C,gBAAgB,IAAI,uBAAuB,EAC3C,qBAAqB,IAAI,4BAA4B,GACtD,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,8BAA8B,EAC9B,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdk/index.ts"],"names":[],"mappings":"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"}
package/dist/sdk/index.js CHANGED
@@ -1082,6 +1082,41 @@ class TodosV1Client {
1082
1082
  init
1083
1083
  });
1084
1084
  }
1085
+ async applyTaskSubtreeTransfer(body, init) {
1086
+ return this.request("POST", `/v1/task-subtree-transfer/apply`, {
1087
+ body,
1088
+ query: undefined,
1089
+ init
1090
+ });
1091
+ }
1092
+ async getTaskSubtreeTransferCapability(init) {
1093
+ return this.request("GET", `/v1/task-subtree-transfer/capability`, {
1094
+ body: undefined,
1095
+ query: undefined,
1096
+ init
1097
+ });
1098
+ }
1099
+ async inspectTaskSubtreeTransfer(body, init) {
1100
+ return this.request("POST", `/v1/task-subtree-transfer/inspect`, {
1101
+ body,
1102
+ query: undefined,
1103
+ init
1104
+ });
1105
+ }
1106
+ async readExactTaskSubtreeTransfer(body, init) {
1107
+ return this.request("POST", `/v1/task-subtree-transfer/read-exact`, {
1108
+ body,
1109
+ query: undefined,
1110
+ init
1111
+ });
1112
+ }
1113
+ async rollbackTaskSubtreeTransfer(body, init) {
1114
+ return this.request("POST", `/v1/task-subtree-transfer/rollback`, {
1115
+ body,
1116
+ query: undefined,
1117
+ init
1118
+ });
1119
+ }
1085
1120
  async listTasks(query, init) {
1086
1121
  return this.request("GET", `/v1/tasks`, {
1087
1122
  body: undefined,
@@ -123,6 +123,126 @@ export interface TaskManifestApplyResult {
123
123
  export interface TaskManifestApplyResponse {
124
124
  "result": TaskManifestApplyResult;
125
125
  }
126
+ export interface TaskSubtreeTransferExpectedTask {
127
+ "task_id": string;
128
+ "version": number;
129
+ }
130
+ export interface TaskSubtreeTransferSharedPlanSplit {
131
+ "source_plan_id": string;
132
+ "destination_plan_id": string;
133
+ }
134
+ export interface TaskSubtreeTransferInspectRequest {
135
+ "source_project_id": string;
136
+ "destination_project_id": string;
137
+ "destination_task_list_id": string;
138
+ "root_task_id": string;
139
+ "destination_parent_id": string | null;
140
+ }
141
+ export interface TaskSubtreeTransferInspection {
142
+ "source_project_id": string;
143
+ "destination_project_id": string;
144
+ "destination_task_list_id": string;
145
+ "root_task_id": string;
146
+ "destination_parent_id": string | null;
147
+ "expected_root_parent_id": string | null;
148
+ "source_population_digest": string;
149
+ "expected_tasks": Array<TaskSubtreeTransferExpectedTask>;
150
+ "contained_plan_ids": Array<string>;
151
+ "shared_plan_ids": Array<string>;
152
+ "complete": true;
153
+ }
154
+ export interface TaskSubtreeTransferApplyRequest {
155
+ "source_project_id": string;
156
+ "destination_project_id": string;
157
+ "destination_task_list_id": string;
158
+ "root_task_id": string;
159
+ "destination_parent_id": string | null;
160
+ "version": 1;
161
+ "operation_id": string;
162
+ "step_id": string;
163
+ "idempotency_key": string;
164
+ "precondition_digest": string;
165
+ "expected_root_parent_id": string | null;
166
+ "source_population_digest": string;
167
+ "expected_tasks": Array<TaskSubtreeTransferExpectedTask>;
168
+ "shared_plan_splits": Array<TaskSubtreeTransferSharedPlanSplit>;
169
+ }
170
+ export interface TaskSubtreeTransferTaskImage {
171
+ "task_id": string;
172
+ "project_id": string | null;
173
+ "parent_id": string | null;
174
+ "plan_id": string | null;
175
+ "task_list_id": string | null;
176
+ "version": number;
177
+ "updated_at": string;
178
+ }
179
+ export interface TaskSubtreeTransferPlanImage {
180
+ "plan_id": string;
181
+ "project_id": string | null;
182
+ "task_list_id": string | null;
183
+ "updated_at": string;
184
+ }
185
+ export interface TaskSubtreeTransferImage {
186
+ "tasks": Array<TaskSubtreeTransferTaskImage>;
187
+ "plans": Array<TaskSubtreeTransferPlanImage>;
188
+ }
189
+ export interface TaskSubtreeTransferReceipt {
190
+ "receipt_id": string;
191
+ "authority": "todos";
192
+ "route": "todos.task-subtree-transfer.v1";
193
+ "schema_version": 1;
194
+ "kind": "apply" | "rollback";
195
+ "operation_id": string;
196
+ "step_id": string;
197
+ "idempotency_key": string;
198
+ "request_digest": string;
199
+ "precondition_digest": string;
200
+ "result_digest": string;
201
+ "apply_receipt_id": string | null;
202
+ "source_project_id": string;
203
+ "destination_project_id": string;
204
+ "destination_task_list_id": string;
205
+ "root_task_id": string;
206
+ "source_population_digest": string;
207
+ "prior_image": TaskSubtreeTransferImage;
208
+ "post_image": TaskSubtreeTransferImage;
209
+ "shared_plan_splits": Array<TaskSubtreeTransferSharedPlanSplit>;
210
+ "created_at": string;
211
+ }
212
+ export interface TaskSubtreeTransferResult {
213
+ "duplicate": boolean;
214
+ "receipt": TaskSubtreeTransferReceipt;
215
+ "moved_task_ids": Array<string>;
216
+ "moved_plan_ids": Array<string>;
217
+ "complete": true;
218
+ }
219
+ export interface TaskSubtreeTransferCapability {
220
+ "authority": "todos";
221
+ "route": "todos.task-subtree-transfer.v1";
222
+ "schema_version": 1;
223
+ "tenant_id": string;
224
+ "backend": "sqlite" | "postgresql" | "http";
225
+ "exact_descendant_closure": true;
226
+ "complete_source_population_digest": true;
227
+ "per_task_version_cas": true;
228
+ "explicit_shared_plan_splits": true;
229
+ "atomic_apply": true;
230
+ "immutable_forward_inverse_receipts": true;
231
+ "prior_image_receipts": true;
232
+ "cas_protected_rollback": true;
233
+ "preserves_descendant_parent_ids": true;
234
+ "preserves_task_and_relation_identities": true;
235
+ }
236
+ export interface TaskSubtreeTransferRollbackRequest {
237
+ "receipt_id": string;
238
+ "operation_id": string;
239
+ "step_id": string;
240
+ "idempotency_key": string;
241
+ "precondition_digest": string;
242
+ }
243
+ export interface TaskSubtreeTransferReadExactRequest {
244
+ "receipt_id": string;
245
+ }
126
246
  export interface TaskManifestCompensateRequest {
127
247
  "receipt_id": string;
128
248
  "operation_id": string;
@@ -567,6 +687,7 @@ export interface UpdateTaskListInput {
567
687
  "name"?: string;
568
688
  "description"?: string;
569
689
  "metadata"?: Record<string, unknown>;
690
+ "project_id"?: string | null;
570
691
  }
571
692
  export interface CreateTaskCommentInput {
572
693
  "content": string;
@@ -1130,6 +1251,26 @@ export declare class TodosV1Client {
1130
1251
  compensateTaskManifest(body: TaskManifestCompensateRequest, init?: RequestInit): Promise<TaskManifestCompensateResponse>;
1131
1252
  /** Read one exact immutable task-manifest apply receipt */
1132
1253
  readExactTaskManifest(body: TaskManifestReadExactRequest, init?: RequestInit): Promise<TaskManifestApplyResponse>;
1254
+ /** Apply one exact task subtree transfer atomically with CAS and immutable receipt */
1255
+ applyTaskSubtreeTransfer(body: TaskSubtreeTransferApplyRequest, init?: RequestInit): Promise<{
1256
+ "result": TaskSubtreeTransferResult;
1257
+ }>;
1258
+ /** Read the current task-subtree-transfer authority capability and tenant */
1259
+ getTaskSubtreeTransferCapability(init?: RequestInit): Promise<{
1260
+ "capability": TaskSubtreeTransferCapability;
1261
+ }>;
1262
+ /** Inspect one exact task subtree and complete source population snapshot */
1263
+ inspectTaskSubtreeTransfer(body: TaskSubtreeTransferInspectRequest, init?: RequestInit): Promise<{
1264
+ "inspection": TaskSubtreeTransferInspection;
1265
+ }>;
1266
+ /** Read one exact immutable task-subtree-transfer receipt */
1267
+ readExactTaskSubtreeTransfer(body: TaskSubtreeTransferReadExactRequest, init?: RequestInit): Promise<{
1268
+ "result": TaskSubtreeTransferResult;
1269
+ }>;
1270
+ /** Rollback one exact task-subtree-transfer receipt with CAS protection */
1271
+ rollbackTaskSubtreeTransfer(body: TaskSubtreeTransferRollbackRequest, init?: RequestInit): Promise<{
1272
+ "result": TaskSubtreeTransferResult;
1273
+ }>;
1133
1274
  /** List tasks */
1134
1275
  listTasks(query?: {
1135
1276
  "status"?: "pending" | "in_progress" | "completed" | "failed" | "cancelled" | Array<"pending" | "in_progress" | "completed" | "failed" | "cancelled">;