@hasna/todos 0.15.34 → 0.15.35

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.
@@ -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.15.34",
73
+ version: "0.15.35",
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",
@@ -145,6 +145,9 @@ var init_package = __esm(() => {
145
145
  "verify:release-review": "bun run scripts/verify-npm-release-agent-review.ts",
146
146
  "verify:attested-container-candidate": "bun run scripts/attested-container-candidate.ts verify",
147
147
  "test:attested-container-candidate": "bun test scripts/attested-container-candidate.test.ts",
148
+ "emit:iapp-deployment-compatibility-vector": "bun run scripts/attested-container-compatibility-vector.ts emit",
149
+ "verify:iapp-deployment-compatibility-vector": "bun run scripts/attested-container-compatibility-vector.ts verify",
150
+ "test:attested-container-compatibility-vector": "bun test scripts/attested-container-compatibility-vector.test.ts",
148
151
  "issue:release-review": "bun run scripts/issue-npm-release-agent-review.ts",
149
152
  prepublishOnly: "bun run scripts/verify-public-release.ts --mode=publish",
150
153
  postinstall: "mkdir -p $HOME/.hasna/todos $HOME/.hasna/todos/training 2>/dev/null || true"
@@ -3113,8 +3116,12 @@ class PostgresJsonRecordStore {
3113
3116
  OR ($11::text <> $2
3114
3117
  AND NOT EXISTS (SELECT 1 FROM parent_chain WHERE object_id = $2)
3115
3118
  AND NOT EXISTS (SELECT 1 FROM parent_chain WHERE cycle))) AS parent_acyclic,
3116
- (SELECT count(*) FROM locked_plans) = jsonb_array_length($7::jsonb) AS all_plans_found,
3117
- ($8::text IS NULL OR EXISTS (SELECT 1 FROM locked_plans WHERE object_id = $8)) AS target_plan_found,
3119
+ (COALESCE((SELECT payload->>'plan_id' FROM locked_task), '')
3120
+ IS DISTINCT FROM COALESCE($3::jsonb->>'plan_id', '')) AS membership_changed,
3121
+ (NOT (COALESCE((SELECT payload->>'plan_id' FROM locked_task), '')
3122
+ IS DISTINCT FROM COALESCE($3::jsonb->>'plan_id', ''))
3123
+ OR $8::text IS NULL
3124
+ OR EXISTS (SELECT 1 FROM locked_plans WHERE object_id = $8)) AS target_plan_found,
3118
3125
  (SELECT payload->>'project_id' FROM locked_plans WHERE object_id = $8) AS target_project_id
3119
3126
  ), guarded AS (
3120
3127
  SELECT
@@ -3137,7 +3144,6 @@ class PostgresJsonRecordStore {
3137
3144
  AND guarded.version_matches
3138
3145
  AND guarded.parent_found
3139
3146
  AND guarded.parent_acyclic
3140
- AND guarded.all_plans_found
3141
3147
  AND guarded.target_plan_found
3142
3148
  AND NOT guarded.project_conflict
3143
3149
  ON CONFLICT (service, object_type, object_id) DO UPDATE SET
@@ -3153,7 +3159,7 @@ class PostgresJsonRecordStore {
3153
3159
  RETURNING payload
3154
3160
  )
3155
3161
  SELECT guarded.task_found, guarded.version_matches, guarded.parent_found, guarded.parent_acyclic,
3156
- guarded.all_plans_found, guarded.target_plan_found, guarded.project_conflict,
3162
+ guarded.membership_changed, guarded.target_plan_found, guarded.project_conflict,
3157
3163
  (SELECT payload FROM stored) AS payload,
3158
3164
  (SELECT payload FROM locked_task) AS current_payload
3159
3165
  FROM guarded`, [
@@ -3185,7 +3191,7 @@ class PostgresJsonRecordStore {
3185
3191
  if (parentGuard && !row?.parent_acyclic && parentGuard.parentId) {
3186
3192
  throw new ResourceConflictError("TASK_PARENT_CYCLE", `TASK_PARENT_CYCLE: assigning parent ${parentGuard.parentId} to task ${value.id} would create or retain a parent cycle`);
3187
3193
  }
3188
- if (!row?.all_plans_found || !row.target_plan_found) {
3194
+ if (!row?.target_plan_found) {
3189
3195
  throw new PlanProjectLinkError("PLAN_PROJECT_LINK_PLAN_NOT_FOUND", `Plan membership changed through a missing plan: ${targetPlanId ?? planIds.join(", ")}`, { plan_ids: planIds, target_plan_id: targetPlanId });
3190
3196
  }
3191
3197
  if (row.project_conflict) {
@@ -4394,17 +4400,26 @@ async function getChangedSince(since, filters, store) {
4394
4400
  async function createProject(input, store, context) {
4395
4401
  const timestamp = new Date().toISOString();
4396
4402
  const derivedSlug = slugifyRaw(input.name);
4397
- const taskListId = input.task_list_id === undefined ? `todos-${derivedSlug}` : slugifyRaw(input.task_list_id);
4403
+ const taskListId = input.task_list_id === undefined ? derivedSlug : slugifyRaw(input.task_list_id);
4398
4404
  if (!derivedSlug || !taskListId)
4399
4405
  throw new Error("Project name and task-list slug must be non-empty");
4406
+ const parentId = input.parent_id ?? null;
4407
+ const id = randomUUID();
4408
+ if (parentId !== null) {
4409
+ const parent = await store.get("projects", parentId);
4410
+ if (!parent)
4411
+ throw new ProjectNotFoundError(parentId);
4412
+ await assertNotProjectAncestorPostgres(id, parentId, store);
4413
+ }
4400
4414
  const project = {
4401
- id: randomUUID(),
4415
+ id,
4402
4416
  name: input.name,
4403
4417
  path: input.path,
4404
4418
  description: input.description ?? null,
4405
4419
  task_list_id: taskListId,
4406
4420
  task_prefix: input.task_prefix ?? await generateProjectPrefix(input.name, store),
4407
4421
  task_counter: 0,
4422
+ parent_id: parentId,
4408
4423
  created_at: timestamp,
4409
4424
  updated_at: timestamp,
4410
4425
  machine_id: store.machineId(context),
@@ -4412,12 +4427,38 @@ async function createProject(input, store, context) {
4412
4427
  };
4413
4428
  return store.upsert("projects", project, context);
4414
4429
  }
4430
+ async function assertNotProjectAncestorPostgres(projectId, candidateParentId, store) {
4431
+ const all = await store.list("projects");
4432
+ const byId = new Map(all.map((project) => [project.id, project.parent_id ?? null]));
4433
+ let cursor = candidateParentId;
4434
+ const seen = new Set;
4435
+ while (cursor !== null) {
4436
+ if (cursor === projectId) {
4437
+ throw new ResourceConflictError("PROJECT_PARENT_CYCLE", `Project "${projectId}" cannot be placed under its own descendant`);
4438
+ }
4439
+ if (seen.has(cursor))
4440
+ break;
4441
+ seen.add(cursor);
4442
+ cursor = byId.get(cursor) ?? null;
4443
+ }
4444
+ }
4415
4445
  async function updateProject(id, input, store) {
4416
4446
  if ("task_list_id" in input) {
4417
4447
  throw new Error("task_list_id cannot be changed by updateProject; use renameProject for an atomic canonical rename");
4418
4448
  }
4419
4449
  const project = await requireRecord("projects", id, store);
4420
- const updated = { ...project, ...definedPatch(input), updated_at: new Date().toISOString() };
4450
+ if (input.parent_id !== undefined && input.parent_id !== null) {
4451
+ const parent = await store.get("projects", input.parent_id);
4452
+ if (!parent)
4453
+ throw new ProjectNotFoundError(input.parent_id);
4454
+ await assertNotProjectAncestorPostgres(id, input.parent_id, store);
4455
+ }
4456
+ const updated = {
4457
+ ...project,
4458
+ ...definedPatch(input),
4459
+ ...input.parent_id !== undefined ? { parent_id: input.parent_id } : {},
4460
+ updated_at: new Date().toISOString()
4461
+ };
4421
4462
  return store.upsert("projects", updated);
4422
4463
  }
4423
4464
  async function createPlan(input, store, context) {
@@ -9136,6 +9177,10 @@ var init_migrations = __esm(() => {
9136
9177
  );
9137
9178
  INSERT OR IGNORE INTO _migrations (id) VALUES (70);
9138
9179
  COMMIT;
9180
+ `,
9181
+ `BEGIN;
9182
+ INSERT OR IGNORE INTO _migrations (id) VALUES (71);
9183
+ COMMIT;
9139
9184
  `
9140
9185
  ];
9141
9186
  });
@@ -9809,6 +9854,8 @@ function ensureSchema(db) {
9809
9854
  ensureColumn("projects", "task_list_id", "TEXT");
9810
9855
  ensureColumn("projects", "task_prefix", "TEXT");
9811
9856
  ensureColumn("projects", "task_counter", "INTEGER NOT NULL DEFAULT 0");
9857
+ ensureColumn("projects", "parent_id", "TEXT REFERENCES projects(id) ON DELETE SET NULL");
9858
+ ensureIndex("CREATE INDEX IF NOT EXISTS idx_projects_parent_id ON projects(parent_id)");
9812
9859
  ensureColumn("tasks", "plan_id", "TEXT REFERENCES plans(id) ON DELETE SET NULL");
9813
9860
  ensureColumn("tasks", "task_list_id", "TEXT REFERENCES task_lists(id) ON DELETE SET NULL");
9814
9861
  ensureColumn("tasks", "short_id", "TEXT");
@@ -11725,10 +11772,12 @@ __export(exports_projects, {
11725
11772
  renameProject: () => renameProject,
11726
11773
  removeProjectSource: () => removeProjectSource,
11727
11774
  removeMachineLocalPath: () => removeMachineLocalPath,
11775
+ orderProjectsParentFirst: () => orderProjectsParentFirst,
11728
11776
  nextTaskShortId: () => nextTaskShortId2,
11729
11777
  listProjects: () => listProjects,
11730
11778
  listProjectSources: () => listProjectSources,
11731
11779
  listMachineLocalPaths: () => listMachineLocalPaths,
11780
+ listChildProjects: () => listChildProjects,
11732
11781
  getProjectWithSources: () => getProjectWithSources,
11733
11782
  getProjectByPath: () => getProjectByPath,
11734
11783
  getProject: () => getProject,
@@ -11736,6 +11785,7 @@ __export(exports_projects, {
11736
11785
  ensureProject: () => ensureProject,
11737
11786
  deleteProject: () => deleteProject,
11738
11787
  createProject: () => createProject2,
11788
+ assertNotProjectAncestor: () => assertNotProjectAncestor,
11739
11789
  addProjectSource: () => addProjectSource
11740
11790
  });
11741
11791
  function slugify(name) {
@@ -11767,17 +11817,24 @@ function createProject2(input, db) {
11767
11817
  const id = uuid();
11768
11818
  const timestamp2 = now();
11769
11819
  const derivedSlug = slugify(input.name);
11770
- const taskListId = input.task_list_id === undefined ? `todos-${derivedSlug}` : slugify(input.task_list_id);
11820
+ const taskListId = input.task_list_id === undefined ? derivedSlug : slugify(input.task_list_id);
11771
11821
  if (!derivedSlug || !taskListId)
11772
11822
  throw new Error("Project name and task-list slug must be non-empty");
11773
11823
  const slugConflict = d.query("SELECT id FROM projects WHERE task_list_id = ? LIMIT 1").get(taskListId);
11774
11824
  if (slugConflict || !claimCanonicalSlug("project", "global", taskListId, id, d)) {
11775
11825
  throw new ResourceConflictError("PROJECT_SLUG_CONFLICT", `Project slug "${taskListId}" already exists`);
11776
11826
  }
11827
+ const parentId = input.parent_id ?? null;
11828
+ if (parentId !== null) {
11829
+ const parent = getProject(parentId, d);
11830
+ if (!parent)
11831
+ throw new ProjectNotFoundError(parentId);
11832
+ assertNotProjectAncestor(id, parentId, d);
11833
+ }
11777
11834
  const taskPrefix = input.task_prefix || generatePrefix(input.name, d);
11778
11835
  const machineId = currentStorageMachineId(d);
11779
- d.run(`INSERT INTO projects (id, name, path, description, task_list_id, task_prefix, task_counter, created_at, updated_at, machine_id)
11780
- VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, ?)`, [id, input.name, input.path, input.description || null, taskListId, taskPrefix, timestamp2, timestamp2, machineId]);
11836
+ d.run(`INSERT INTO projects (id, name, path, description, task_list_id, task_prefix, task_counter, parent_id, created_at, updated_at, machine_id)
11837
+ VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?)`, [id, input.name, input.path, input.description || null, taskListId, taskPrefix, parentId, timestamp2, timestamp2, machineId]);
11781
11838
  return getProject(id, d);
11782
11839
  })();
11783
11840
  }
@@ -11802,6 +11859,64 @@ function listProjects(db) {
11802
11859
  const d = db || getDatabase();
11803
11860
  return d.query("SELECT * FROM projects ORDER BY name").all();
11804
11861
  }
11862
+ function listChildProjects(parentId, db) {
11863
+ const d = db || getDatabase();
11864
+ return d.query("SELECT * FROM projects WHERE parent_id = ? ORDER BY name").all(parentId);
11865
+ }
11866
+ function orderProjectsParentFirst(projects) {
11867
+ const projectId = (project) => {
11868
+ const id = project.id;
11869
+ return typeof id === "string" && id.length > 0 ? id : null;
11870
+ };
11871
+ const parentId = (project) => {
11872
+ const parent = project.parent_id;
11873
+ return parent == null ? null : String(parent);
11874
+ };
11875
+ const byId = new Set;
11876
+ for (const project of projects) {
11877
+ const id = projectId(project);
11878
+ if (id !== null)
11879
+ byId.add(id);
11880
+ }
11881
+ const ordered = [];
11882
+ const emitted = new Set;
11883
+ let remaining = [...projects];
11884
+ let progress = true;
11885
+ while (progress && remaining.length > 0) {
11886
+ progress = false;
11887
+ const deferred = [];
11888
+ for (const project of remaining) {
11889
+ const parent = parentId(project);
11890
+ if (parent === null || emitted.has(parent) || !byId.has(parent)) {
11891
+ ordered.push(project);
11892
+ const id = projectId(project);
11893
+ if (id !== null)
11894
+ emitted.add(id);
11895
+ progress = true;
11896
+ } else {
11897
+ deferred.push(project);
11898
+ }
11899
+ }
11900
+ remaining = deferred;
11901
+ }
11902
+ ordered.push(...remaining);
11903
+ return ordered;
11904
+ }
11905
+ function assertNotProjectAncestor(projectId, ancestorId, db) {
11906
+ const d = db || getDatabase();
11907
+ let cursor = ancestorId;
11908
+ const seen = new Set;
11909
+ while (cursor !== null) {
11910
+ if (cursor === projectId) {
11911
+ throw new ResourceConflictError("PROJECT_PARENT_CYCLE", `Project "${projectId}" cannot be placed under its own descendant`);
11912
+ }
11913
+ if (seen.has(cursor))
11914
+ break;
11915
+ seen.add(cursor);
11916
+ const row = d.query("SELECT parent_id FROM projects WHERE id = ?").get(cursor);
11917
+ cursor = row?.parent_id ?? null;
11918
+ }
11919
+ }
11805
11920
  function updateProject2(id, input, db) {
11806
11921
  const d = db || getDatabase();
11807
11922
  const project = getProject(id, d);
@@ -11824,6 +11939,16 @@ function updateProject2(id, input, db) {
11824
11939
  sets.push("path = ?");
11825
11940
  params.push(input.path);
11826
11941
  }
11942
+ if (input.parent_id !== undefined) {
11943
+ if (input.parent_id !== null) {
11944
+ const parent = getProject(input.parent_id, d);
11945
+ if (!parent)
11946
+ throw new ProjectNotFoundError(input.parent_id);
11947
+ assertNotProjectAncestor(id, input.parent_id, d);
11948
+ }
11949
+ sets.push("parent_id = ?");
11950
+ params.push(input.parent_id);
11951
+ }
11827
11952
  params.push(id);
11828
11953
  d.run(`UPDATE projects SET ${sets.join(", ")} WHERE id = ?`, params);
11829
11954
  return getProject(id, d);
@@ -20119,7 +20244,7 @@ function importSqliteTodosStorageSnapshot(snapshot, db) {
20119
20244
  }
20120
20245
  }
20121
20246
  };
20122
- applyRows("projects", "projects", PROJECT_COLUMNS, snapshot.projects, "updated_at");
20247
+ applyRows("projects", "projects", PROJECT_COLUMNS, orderProjectsParentFirst(snapshot.projects), "updated_at");
20123
20248
  applyRows("project_machine_paths", "project_machine_paths", PROJECT_MACHINE_PATH_COLUMNS, snapshot.projectMachinePaths ?? [], "updated_at");
20124
20249
  applyRows("agents", "agents", AGENT_COLUMNS, snapshot.agents, "last_seen_at");
20125
20250
  applyRows("task_lists", "task_lists", TASK_LIST_COLUMNS, snapshot.taskLists, "updated_at");
@@ -20350,6 +20475,7 @@ var init_sqlite_snapshot = __esm(() => {
20350
20475
  "task_list_id",
20351
20476
  "task_prefix",
20352
20477
  "task_counter",
20478
+ "parent_id",
20353
20479
  "created_at",
20354
20480
  "updated_at",
20355
20481
  "machine_id",
@@ -21131,7 +21257,7 @@ class StagedSqliteTodosProjectRegistrationTransaction {
21131
21257
  }
21132
21258
  async createProject(input) {
21133
21259
  const derivedSlug = normalizeSlug(input.name);
21134
- const taskListId = input.task_list_id === undefined ? `todos-${derivedSlug}` : normalizeSlug(input.task_list_id);
21260
+ const taskListId = input.task_list_id === undefined ? derivedSlug : normalizeSlug(input.task_list_id);
21135
21261
  if (!derivedSlug || !taskListId) {
21136
21262
  throw new Error("Project name and task-list slug must be non-empty");
21137
21263
  }
@@ -21143,6 +21269,7 @@ class StagedSqliteTodosProjectRegistrationTransaction {
21143
21269
  task_list_id: taskListId,
21144
21270
  task_prefix: input.task_prefix ?? this.availableProjectPrefix(input.name),
21145
21271
  task_counter: 0,
21272
+ parent_id: input.parent_id ?? null,
21146
21273
  created_at: now(),
21147
21274
  updated_at: now(),
21148
21275
  machine_id: currentStorageMachineId(this.db)
@@ -21153,14 +21280,15 @@ class StagedSqliteTodosProjectRegistrationTransaction {
21153
21280
  try {
21154
21281
  const result = this.db.run(`INSERT INTO projects (
21155
21282
  id, name, path, description, task_list_id, task_prefix,
21156
- task_counter, created_at, updated_at, machine_id
21157
- ) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, ?)`, [
21283
+ task_counter, parent_id, created_at, updated_at, machine_id
21284
+ ) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?)`, [
21158
21285
  project.id,
21159
21286
  project.name,
21160
21287
  project.path,
21161
21288
  project.description,
21162
21289
  project.task_list_id,
21163
21290
  project.task_prefix,
21291
+ project.parent_id,
21164
21292
  project.created_at,
21165
21293
  project.updated_at,
21166
21294
  project.machine_id ?? null
@@ -21444,7 +21572,10 @@ function taskListSlug(projectSlug) {
21444
21572
  if (!slug || slug !== projectSlug) {
21445
21573
  throw new TodosProjectRegistrationError("TODOS_PROJECT_REGISTRATION_INVALID_INPUT", "project_slug must be canonical kebab-case");
21446
21574
  }
21447
- return `todos-${slug}`;
21575
+ return slug;
21576
+ }
21577
+ function legacyTaskListSlug(projectSlug) {
21578
+ return `todos-${normalizeSlug(projectSlug)}`;
21448
21579
  }
21449
21580
  function deterministicTaskPrefix(projectSlug) {
21450
21581
  const letters = projectSlug.replace(/[^a-z0-9]/gi, "").toUpperCase();
@@ -21963,6 +22094,12 @@ class PackageOwnedTodosProjectRegistrationAuthority {
21963
22094
  created_by_operation: false
21964
22095
  };
21965
22096
  }
22097
+ if (request.bind_existing === true && conflict2.path === path && conflict2.task_list_id === legacyTaskListSlug(request.project_slug)) {
22098
+ return {
22099
+ record: boundExistingProjectRecord(conflict2),
22100
+ created_by_operation: false
22101
+ };
22102
+ }
21966
22103
  return this.terminalFor(transaction, request, normalizedCallDigest(request), "target_already_exists", { targetId: conflict2.id });
21967
22104
  }
21968
22105
  await this.fault("before_object_write", request);
@@ -21999,6 +22136,15 @@ class PackageOwnedTodosProjectRegistrationAuthority {
21999
22136
  }
22000
22137
  return this.terminalFor(transaction, request, normalizedCallDigest(request), "target_already_exists", { targetId: conflict.id });
22001
22138
  }
22139
+ if (request.bind_existing === true) {
22140
+ const legacy = await transaction.findTaskListConflict(todosProjectId, legacyTaskListSlug(request.project_slug));
22141
+ if (legacy && legacy.project_id === todosProjectId) {
22142
+ return {
22143
+ record: boundExistingTaskListRecord(legacy),
22144
+ created_by_operation: false
22145
+ };
22146
+ }
22147
+ }
22002
22148
  await this.fault("before_object_write", request);
22003
22149
  const taskList = await transaction.createTaskList({
22004
22150
  name: request.project_name,
@@ -30738,7 +30884,8 @@ function buildV1OpenApiDocument(version = getPackageVersion()) {
30738
30884
  path: { type: "string", minLength: 1 },
30739
30885
  description: { type: "string" },
30740
30886
  task_list_id: { type: "string", minLength: 1, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" },
30741
- task_prefix: { type: "string", minLength: 1 }
30887
+ task_prefix: { type: "string", minLength: 1 },
30888
+ parent_id: { type: "string", minLength: 1 }
30742
30889
  }
30743
30890
  },
30744
30891
  UpdateProjectInput: {
@@ -30748,7 +30895,8 @@ function buildV1OpenApiDocument(version = getPackageVersion()) {
30748
30895
  properties: {
30749
30896
  name: { type: "string", minLength: 1 },
30750
30897
  path: { type: "string", minLength: 1 },
30751
- description: { type: "string", nullable: true }
30898
+ description: { type: "string", nullable: true },
30899
+ parent_id: { type: "string", minLength: 1, nullable: true }
30752
30900
  }
30753
30901
  },
30754
30902
  RenameProjectInput: {
@@ -33047,6 +33195,7 @@ var init_openapi = __esm(() => {
33047
33195
  task_list_id: { type: "string", nullable: true },
33048
33196
  task_prefix: { type: "string", nullable: true },
33049
33197
  task_counter: { type: "number" },
33198
+ parent_id: { type: "string", nullable: true },
33050
33199
  created_at: { type: "string" },
33051
33200
  updated_at: { type: "string" }
33052
33201
  }
@@ -34464,7 +34613,7 @@ function validateProjectPatch(value) {
34464
34613
  if (!value || typeof value !== "object" || Array.isArray(value))
34465
34614
  return { ok: false, message: "project patch must be an object" };
34466
34615
  const body2 = value;
34467
- const allowed = new Set(["name", "path", "description"]);
34616
+ const allowed = new Set(["name", "path", "description", "parent_id"]);
34468
34617
  const unknown = Object.keys(body2).find((key2) => !allowed.has(key2));
34469
34618
  if (unknown)
34470
34619
  return { ok: false, message: `unknown project field: ${unknown}` };
@@ -34476,13 +34625,15 @@ function validateProjectPatch(value) {
34476
34625
  return { ok: false, message: "path must be a non-empty string" };
34477
34626
  if (body2["description"] !== undefined && body2["description"] !== null && typeof body2["description"] !== "string")
34478
34627
  return { ok: false, message: "description must be a string or null" };
34628
+ if (body2["parent_id"] !== undefined && body2["parent_id"] !== null && (typeof body2["parent_id"] !== "string" || !body2["parent_id"].trim()))
34629
+ return { ok: false, message: "parent_id must be a string or null" };
34479
34630
  return { ok: true, patch: body2 };
34480
34631
  }
34481
34632
  function validateProjectCreate(value) {
34482
34633
  if (!value || typeof value !== "object" || Array.isArray(value))
34483
34634
  return { ok: false, message: "project body must be an object" };
34484
34635
  const body2 = value;
34485
- const allowed = new Set(["name", "path", "description", "task_list_id", "task_prefix"]);
34636
+ const allowed = new Set(["name", "path", "description", "task_list_id", "task_prefix", "parent_id"]);
34486
34637
  const unknown = Object.keys(body2).find((key2) => !allowed.has(key2));
34487
34638
  if (unknown)
34488
34639
  return { ok: false, message: `unknown project field: ${unknown}` };
@@ -34500,6 +34651,9 @@ function validateProjectCreate(value) {
34500
34651
  if (body2["task_prefix"] !== undefined && (typeof body2["task_prefix"] !== "string" || !body2["task_prefix"].trim())) {
34501
34652
  return { ok: false, message: "task_prefix must be a non-empty string" };
34502
34653
  }
34654
+ if (body2["parent_id"] !== undefined && (typeof body2["parent_id"] !== "string" || !body2["parent_id"].trim())) {
34655
+ return { ok: false, message: "parent_id must be a non-empty string" };
34656
+ }
34503
34657
  return { ok: true, input: body2 };
34504
34658
  }
34505
34659
  function validatePlanCreate(value) {
@@ -60849,7 +61003,31 @@ function classifyRemoteRequestError(baseUrl, route, error3) {
60849
61003
  }
60850
61004
  throw error3;
60851
61005
  }
60852
- function protectRemoteClient(client) {
61006
+ function withBoundedRemoteRequest(options, requestTimeoutMs, run) {
61007
+ const controller = new AbortController;
61008
+ const onBaseAbort = () => controller.abort();
61009
+ if (options?.signal) {
61010
+ if (options.signal.aborted)
61011
+ controller.abort();
61012
+ else
61013
+ options.signal.addEventListener("abort", onBaseAbort, { once: true });
61014
+ }
61015
+ let timer;
61016
+ const deadline = new Promise((_, reject) => {
61017
+ timer = setTimeout(() => {
61018
+ controller.abort();
61019
+ reject(new DOMException(`Todos remote request exceeded the ${requestTimeoutMs}ms bounded request timeout`, "AbortError"));
61020
+ }, requestTimeoutMs);
61021
+ });
61022
+ const attempt = run({ ...options, signal: controller.signal });
61023
+ attempt.catch(() => {});
61024
+ return Promise.race([attempt, deadline]).finally(() => {
61025
+ if (timer)
61026
+ clearTimeout(timer);
61027
+ options?.signal?.removeEventListener("abort", onBaseAbort);
61028
+ });
61029
+ }
61030
+ function protectRemoteClient(client, requestTimeoutMs) {
60853
61031
  const baseUrl = remoteAuthorityBase(client);
60854
61032
  const protect = async (route, request) => {
60855
61033
  try {
@@ -60858,25 +61036,26 @@ function protectRemoteClient(client) {
60858
61036
  return classifyRemoteRequestError(baseUrl, route, error3);
60859
61037
  }
60860
61038
  };
61039
+ const bounded = (options, run) => withBoundedRemoteRequest(options, requestTimeoutMs, run);
60861
61040
  const transport = client.transport;
60862
61041
  const protectedTransport = {
60863
61042
  baseUrl: transport.baseUrl,
60864
- request: (method, path, body2, options) => protect(path, () => transport.request(method, path, body2, options)),
60865
- get: (path, options) => protect(path, () => transport.get(path, options)),
60866
- post: (path, body2, options) => protect(path, () => transport.post(path, body2, options)),
60867
- put: (path, body2, options) => protect(path, () => transport.put(path, body2, options)),
60868
- patch: (path, body2, options) => protect(path, () => transport.patch(path, body2, options)),
60869
- del: (path, body2, options) => protect(path, () => transport.del(path, body2, options))
61043
+ request: (method, path, body2, options) => protect(path, () => bounded(options, (opts) => transport.request(method, path, body2, opts))),
61044
+ get: (path, options) => protect(path, () => bounded(options, (opts) => transport.get(path, opts))),
61045
+ post: (path, body2, options) => protect(path, () => bounded(options, (opts) => transport.post(path, body2, opts))),
61046
+ put: (path, body2, options) => protect(path, () => bounded(options, (opts) => transport.put(path, body2, opts))),
61047
+ patch: (path, body2, options) => protect(path, () => bounded(options, (opts) => transport.patch(path, body2, opts))),
61048
+ del: (path, body2, options) => protect(path, () => bounded(options, (opts) => transport.del(path, body2, opts)))
60870
61049
  };
60871
61050
  return {
60872
61051
  name: client.name,
60873
61052
  baseUrl: client.baseUrl,
60874
61053
  transport: protectedTransport,
60875
- list: (resource, options) => protect(`/${resource}`, () => client.list(resource, options)),
60876
- get: (resource, id, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => client.get(resource, id, options)),
60877
- create: (resource, body2, options) => protect(`/${resource}`, () => client.create(resource, body2, options)),
60878
- update: (resource, id, patch, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => client.update(resource, id, patch, options)),
60879
- delete: (resource, id, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => client.delete(resource, id, options))
61054
+ list: (resource, options) => protect(`/${resource}`, () => bounded(options, (opts) => client.list(resource, opts))),
61055
+ get: (resource, id, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => bounded(options, (opts) => client.get(resource, id, opts))),
61056
+ create: (resource, body2, options) => protect(`/${resource}`, () => bounded(options, (opts) => client.create(resource, body2, opts))),
61057
+ update: (resource, id, patch, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => bounded(options, (opts) => client.update(resource, id, patch, opts))),
61058
+ delete: (resource, id, options) => protect(`/${resource}/${encodeURIComponent(id)}`, () => bounded(options, (opts) => client.delete(resource, id, opts)))
60880
61059
  };
60881
61060
  }
60882
61061
  function remoteAuthorityBase(client) {
@@ -60897,17 +61076,18 @@ async function requiredRemoteRoute(client, route, request, recognized404Codes =
60897
61076
  throw error3;
60898
61077
  }
60899
61078
  }
60900
- function getTodosCloudClient(env = process.env) {
61079
+ function getTodosCloudClient(env = process.env, requestTimeoutMs = REMOTE_REQUEST_TIMEOUT_MS) {
60901
61080
  if (requestedTransport(env) !== "http")
60902
61081
  return null;
60903
61082
  const resolved = resolveStorageClient("todos", requireTodosRemoteAuthorityEnv(env), {
60904
- fetchImpl: (input, init) => globalThis.fetch(input, { ...init, redirect: "manual" })
61083
+ fetchImpl: (input, init) => globalThis.fetch(input, { ...init, redirect: "manual" }),
61084
+ timeoutMs: requestTimeoutMs
60905
61085
  });
60906
61086
  if (resolved.transport === "cloud-http")
60907
- return protectRemoteClient(resolved.client);
61087
+ return protectRemoteClient(resolved.client, requestTimeoutMs);
60908
61088
  const transportName = resolved.transport;
60909
61089
  if (transportName === "http")
60910
- return protectRemoteClient(resolved.client);
61090
+ return protectRemoteClient(resolved.client, requestTimeoutMs);
60911
61091
  return null;
60912
61092
  }
60913
61093
  function unwrapTask(raw) {
@@ -61379,7 +61559,7 @@ async function cloudResolveTaskListRef(client, ref, projectId) {
61379
61559
  return input.toLowerCase();
61380
61560
  return (await cloudResolveTaskList(client, ref, projectId)).id;
61381
61561
  }
61382
- var UUID_RE, completionCapabilityCache, retryCapabilityCache, taskCreatorCapabilityCache, gitRefCapabilityCache, remoteCommandCapabilityCache, LEGACY_STORAGE_MODE_KEYS, PRIORITY_RANK, listTagsCapabilityCache;
61562
+ var UUID_RE, completionCapabilityCache, retryCapabilityCache, taskCreatorCapabilityCache, gitRefCapabilityCache, remoteCommandCapabilityCache, LEGACY_STORAGE_MODE_KEYS, REMOTE_REQUEST_TIMEOUT_MS = 1e4, PRIORITY_RANK, listTagsCapabilityCache;
61383
61563
  var init_cloud_router = __esm(() => {
61384
61564
  init_storage();
61385
61565
  init_types();
@@ -61907,7 +62087,7 @@ function addSourceOnce(projectId, type, name, uri, metadata, db) {
61907
62087
  function bootstrapProject(options = {}, db) {
61908
62088
  const d = db || getDatabase();
61909
62089
  const discovery = discoverProjectWorkspace(options.path);
61910
- const taskListSlug2 = options.taskListSlug || `todos-${slugify(options.name || discovery.projectName)}`;
62090
+ const taskListSlug2 = options.taskListSlug || slugify(options.name || discovery.projectName);
61911
62091
  if (options.dryRun) {
61912
62092
  return {
61913
62093
  dryRun: true,
@@ -67875,6 +68055,7 @@ function registerTaskProjectTools(server, ctx) {
67875
68055
  name: exports_external.string().describe("Project name"),
67876
68056
  path: exports_external.string().describe("Unique filesystem path for the project"),
67877
68057
  description: exports_external.string().optional(),
68058
+ parent_id: exports_external.string().optional().describe("Optional parent project id to create this as a sub-project"),
67878
68059
  status: exports_external.enum(["active", "completed", "on_hold", "archived"]).optional(),
67879
68060
  short_id: exports_external.string().nullable().optional().describe("Short ID (auto-generated if omitted)"),
67880
68061
  metadata: exports_external.record(exports_external.unknown()).optional()
@@ -99462,6 +99643,7 @@ function createAgentProjectDemoBundle() {
99462
99643
  task_list_id: ids.list,
99463
99644
  task_prefix: "DEMO",
99464
99645
  task_counter: 4,
99646
+ parent_id: null,
99465
99647
  created_at: createdAt,
99466
99648
  updated_at: completedAt
99467
99649
  });
@@ -114,6 +114,10 @@ export declare function buildV1OpenApiDocument(version?: string): {
114
114
  readonly task_counter: {
115
115
  readonly type: "number";
116
116
  };
117
+ readonly parent_id: {
118
+ readonly type: "string";
119
+ readonly nullable: true;
120
+ };
117
121
  readonly created_at: {
118
122
  readonly type: "string";
119
123
  };
@@ -1972,6 +1976,10 @@ export declare function buildV1OpenApiDocument(version?: string): {
1972
1976
  type: string;
1973
1977
  minLength: number;
1974
1978
  };
1979
+ parent_id: {
1980
+ type: string;
1981
+ minLength: number;
1982
+ };
1975
1983
  };
1976
1984
  };
1977
1985
  UpdateProjectInput: {
@@ -1991,6 +1999,11 @@ export declare function buildV1OpenApiDocument(version?: string): {
1991
1999
  type: string;
1992
2000
  nullable: boolean;
1993
2001
  };
2002
+ parent_id: {
2003
+ type: string;
2004
+ minLength: number;
2005
+ nullable: boolean;
2006
+ };
1994
2007
  };
1995
2008
  };
1996
2009
  RenameProjectInput: {
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/server/openapi.ts"],"names":[],"mappings":"AAi3BA,wBAAgB,sBAAsB,CAAC,OAAO,SAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6jEnE"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/server/openapi.ts"],"names":[],"mappings":"AAk3BA,wBAAgB,sBAAsB,CAAC,OAAO,SAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+jEnE"}
@@ -1 +1 @@
1
- {"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAuB,oBAAoB,EAAmD,MAAM,0BAA0B,CAAC;AAC3I,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oCAAoC,EACpC,sBAAsB,EACtB,6BAA6B,EAC7B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AA0BpB,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACxC,iBAAiB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,qBAAqB,CAAC;IAChD,+BAA+B,CAAC,EAAE,OAAO,oCAAoC,CAAC;IAC9E,wBAAwB,CAAC,EAAE,OAAO,6BAA6B,CAAC;CACjE;AAmYD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAiB1E;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAapE;AA4ED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,YAAY,GAAE,qBAA0B,GACvC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAkuC1B"}
1
+ {"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAuB,oBAAoB,EAAmD,MAAM,0BAA0B,CAAC;AAC3I,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,oCAAoC,EACpC,sBAAsB,EACtB,6BAA6B,EAC7B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AA0BpB,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACxC,iBAAiB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,qBAAqB,CAAC;IAChD,+BAA+B,CAAC,EAAE,OAAO,oCAAoC,CAAC;IAC9E,wBAAwB,CAAC,EAAE,OAAO,6BAA6B,CAAC;CACjE;AAuYD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAiB1E;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAapE;AA4ED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,YAAY,GAAE,qBAA0B,GACvC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAkuC1B"}