@wspc/cli 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1230,9 +1230,9 @@ var ConfigStore = class {
1230
1230
  };
1231
1231
 
1232
1232
  // src/version.ts
1233
- var VERSION = "0.0.11";
1234
- var SPEC_SHA = "5ae5d422";
1235
- var SPEC_FETCHED_AT = "2026-06-09T04:35:08.355Z";
1233
+ var VERSION = "0.0.12";
1234
+ var SPEC_SHA = "869ea6a3";
1235
+ var SPEC_FETCHED_AT = "2026-06-09T06:41:08.172Z";
1236
1236
  var API_BASE = "https://api.wspc.ai";
1237
1237
 
1238
1238
  // src/index.ts
@@ -1599,9 +1599,24 @@ function render(ctx, data) {
1599
1599
  const specific = SPECIFIC_RENDERERS[ctx.kind];
1600
1600
  if (specific) {
1601
1601
  specific(target, ctx.display);
1602
- return;
1602
+ } else {
1603
+ renderGeneric(target, ctx.display);
1604
+ }
1605
+ renderPaginationFooter(data);
1606
+ }
1607
+ function renderPaginationFooter(data) {
1608
+ if (data === null || typeof data !== "object") return;
1609
+ const d = data;
1610
+ if (typeof d.next_cursor === "string" && d.next_cursor.length > 0) {
1611
+ process.stdout.write(dim(` \u2026 more results \u2014 re-run with --cursor ${d.next_cursor}`) + "\n");
1612
+ }
1613
+ const id = typeof d.id === "string" ? d.id : "<id>";
1614
+ if (typeof d.children_next_cursor === "string" && d.children_next_cursor.length > 0) {
1615
+ process.stdout.write(dim(` \u2026 more children \u2014 wspc todo ls --parent ${id}`) + "\n");
1616
+ }
1617
+ if (typeof d.comments_next_cursor === "string" && d.comments_next_cursor.length > 0) {
1618
+ process.stdout.write(dim(` \u2026 more comments \u2014 wspc todo comment ls ${id}`) + "\n");
1603
1619
  }
1604
- renderGeneric(target, ctx.display);
1605
1620
  }
1606
1621
  function drillDataPath(data, dataPath) {
1607
1622
  if (!dataPath) return data;
@@ -1874,7 +1889,7 @@ var inviteAcceptCommand = new Command("accept").description("Accept an invite an
1874
1889
 
1875
1890
  // src/generated/cli/keys/create.ts
1876
1891
  import { Command as Command2 } from "commander";
1877
- var keyCreateCommand = new Command2("create").description("Create a new API key (full value returned once)").option("--label <value>", "label").action(async (opts) => {
1892
+ var keyCreateCommand = new Command2("create").description("Create a new API key (full value returned once)").option("--label <value>", "Human-readable label for the new key (1\u201360 chars after trimming). Pick something that identifies where the key will live \u2014 agent name, machine, or environment \u2014 so you can recognise it later in `wspc keys list`.").action(async (opts) => {
1878
1893
  const client2 = await loadSdkClient();
1879
1894
  const result = await keyCreate({
1880
1895
  client: client2._rawClient,
@@ -1913,7 +1928,7 @@ var keyListCommand = new Command3("ls").description("List active API keys").acti
1913
1928
 
1914
1929
  // src/generated/cli/org/invite.ts
1915
1930
  import { Command as Command4 } from "commander";
1916
- var orgInviteCreateCommand = new Command4("invite").description("Invite an email to join the caller's organization").option("--email <value>", "email").action(async (opts) => {
1931
+ var orgInviteCreateCommand = new Command4("invite").description("Invite an email to join the caller's organization").option("--email <value>", "Email address to invite into the caller's organization.").action(async (opts) => {
1917
1932
  const client2 = await loadSdkClient();
1918
1933
  const result = await orgInviteCreate({
1919
1934
  client: client2._rawClient,
@@ -1970,7 +1985,7 @@ var orgGetCommand = new Command6("show").description("Get the authenticated user
1970
1985
 
1971
1986
  // src/generated/cli/org/rename.ts
1972
1987
  import { Command as Command7 } from "commander";
1973
- var orgUpdateCommand = new Command7("rename").description("Update the authenticated user's organization").option("--name <value>", "name").action(async (opts) => {
1988
+ var orgUpdateCommand = new Command7("rename").description("Update the authenticated user's organization").option("--name <value>", "The new name for the organization. Cannot be empty or purely whitespace.").action(async (opts) => {
1974
1989
  const client2 = await loadSdkClient();
1975
1990
  const result = await orgUpdate({
1976
1991
  client: client2._rawClient,
@@ -2048,7 +2063,7 @@ var invitesListCommand = new Command10("invites").description("List invites addr
2048
2063
 
2049
2064
  // src/generated/cli/org/members.ts
2050
2065
  import { Command as Command11 } from "commander";
2051
- var orgMembersListCommand = new Command11("members").description("List members of the authenticated user's organization").option("--cursor <value>", "cursor").option("--limit <value>", "limit").action(async (opts) => {
2066
+ var orgMembersListCommand = new Command11("members").description("List members of the authenticated user's organization").option("--cursor <value>", "Opaque pagination cursor. Pass the `next_cursor` returned by the previous page to fetch the next slice. Omit on the first call.").option("--limit <value>", "Maximum members to return. Clamped to [1, 100]. Defaults to 50.").action(async (opts) => {
2052
2067
  const client2 = await loadSdkClient();
2053
2068
  const result = await orgMembersList({
2054
2069
  client: client2._rawClient,
@@ -2112,7 +2127,7 @@ var keyRevokeCommand = new Command13("rm").description("Soft-revoke an API key")
2112
2127
 
2113
2128
  // src/generated/cli/keys/edit.ts
2114
2129
  import { Command as Command14 } from "commander";
2115
- var keyUpdateCommand = new Command14("edit").description("Update an active API key's label").argument("<id>", "id").option("--label <value>", "label").action(async (id, opts) => {
2130
+ var keyUpdateCommand = new Command14("edit").description("Update an active API key's label").argument("<id>", "id").option("--label <value>", "Human-readable label for the key (1\u201360 chars after trimming).").action(async (id, opts) => {
2116
2131
  const client2 = await loadSdkClient();
2117
2132
  const result = await keyUpdate({
2118
2133
  client: client2._rawClient,
@@ -2242,7 +2257,7 @@ function parseAttendee(input) {
2242
2257
  }
2243
2258
 
2244
2259
  // src/generated/cli/event/add.ts
2245
- var eventCreateCommand = new Command16("add").description("Schedule a calendar event").argument("<title>", "title").option("--description <value>", "description").option("--start <value>", "start").option("--end <value>", "end").option("-l, --location <value>", "location").option("-u, --url <value>", "url").option("--status <value>", "status").option("--attendee <value>", "attendee", (val, memo) => {
2260
+ var eventCreateCommand = new Command16("add").description("Schedule a calendar event").argument("<title>", "title").option("--description <value>", "Free-form notes about the event (agenda, dial-in instructions, etc.). Markdown formatted (CommonMark + GFM tables, strikethrough, task lists); stored verbatim. Invitation emails include the raw source \u2014 most email clients display it as plain text.").option("--start <value>", "Accepts ISO 8601 datetime with offset (e.g. `2026-06-01T12:30:00+08:00`) for timed events, or ISO date-only (e.g. `2026-06-01`) for all-day. The `wspc` CLI additionally accepts natural-language phrases (`tomorrow 12:30pm`, `next Monday 9am`) and resolves them to ISO before sending; the server itself only accepts ISO. All-day uses RFC 5545 exclusive end: a one-day event on 6/1 is `start=2026-06-01, end=2026-06-02`; both endpoints must be the same type.").option("--end <value>", "Accepts ISO 8601 datetime with offset (e.g. `2026-06-01T12:30:00+08:00`) for timed events, or ISO date-only (e.g. `2026-06-01`) for all-day. The `wspc` CLI additionally accepts natural-language phrases (`tomorrow 12:30pm`, `next Monday 9am`) and resolves them to ISO before sending; the server itself only accepts ISO. All-day uses RFC 5545 exclusive end: a one-day event on 6/1 is `start=2026-06-01, end=2026-06-02`; both endpoints must be the same type.").option("-l, --location <value>", "Free-text location \u2014 physical address, room, or short note. Separate from `url` (meeting link).").option("-u, --url <value>", "Optional meeting link (Zoom / Meet / etc.). Kept separate from `location` so calendar clients can render it as a join action.").option("--status <value>", "Lifecycle status. `confirmed`: the event will happen (default). `tentative`: organizer has not finalized; still visible in lists. `cancelled`: the event was called off but the record is kept so attendees can be notified and history audited; distinct from soft-delete (DELETE `/calendar/events/{id}`) which hides the event from default list responses.").option("--attendee <value>", "Up to 50 unique attendees (deduped case-insensitively by email). If non-empty, each attendee receives an invitation email with an `.ics` REQUEST attachment as a side effect of creation.", (val, memo) => {
2246
2261
  memo.push(val);
2247
2262
  return memo;
2248
2263
  }, []).option("--all-day", "all_day").option("--tz <zone>", "IANA timezone for relative time parsing").action(async (title, opts) => {
@@ -2292,7 +2307,7 @@ var eventCreateCommand = new Command16("add").description("Schedule a calendar e
2292
2307
 
2293
2308
  // src/generated/cli/event/ls.ts
2294
2309
  import { Command as Command17 } from "commander";
2295
- var eventListCommand = new Command17("ls").description("List calendar events").option("--q <value>", "q").option("--from <value>", "from").option("--to <value>", "to").option("--end-from <value>", "end_from").option("--end-to <value>", "end_to").option("--cursor <value>", "cursor").option("--limit <value>", "limit").option("--include-deleted <value>", "include_deleted").option("--include-past <value>", "include_past").option("--tz <zone>", "IANA timezone for relative time parsing").action(async (opts) => {
2310
+ var eventListCommand = new Command17("ls").description("List calendar events").option("--q <value>", "Optional full-text search across title, description, and location (case-insensitive substring).").option("--from <value>", "Inclusive lower bound on the event `start` (ISO datetime with offset, or ISO date-only). When ANY of `start_from`/`start_to`/`end_from`/`end_to` is provided, the implicit past filter is disabled.").option("--to <value>", "Inclusive upper bound on the event `start`.").option("--end-from <value>", "Inclusive lower bound on the event `end`.").option("--end-to <value>", "Inclusive upper bound on the event `end`.").option("--cursor <value>", "Opaque pagination cursor returned in `next_cursor` of a previous response.").option("--limit <value>", "Maximum number of events to return. Clamped to `[1, 200]`. Default is server-defined.").option("--include-deleted <value>", "When `true`, include soft-deleted events. Default `false`.").option("--include-past <value>", "When omitted or `false`, events whose `end` is before now are hidden. Pass `true` to include them. Ignored when any of `start_from`/`start_to`/`end_from`/`end_to` is provided \u2014 explicit time bounds always win.").option("--tz <zone>", "IANA timezone for relative time parsing").action(async (opts) => {
2296
2311
  const zone = resolveTimezone(opts.tz);
2297
2312
  let fromValue;
2298
2313
  if (opts.from !== void 0) {
@@ -2330,7 +2345,7 @@ var eventListCommand = new Command17("ls").description("List calendar events").o
2330
2345
 
2331
2346
  // src/generated/cli/event/rm.ts
2332
2347
  import { Command as Command18 } from "commander";
2333
- var eventDeleteCommand = new Command18("rm").description("Soft-delete a calendar event").argument("<id>", "id").option("--expected-version <value>", "expected_version").action(async (id, opts) => {
2348
+ var eventDeleteCommand = new Command18("rm").description("Soft-delete a calendar event").argument("<id>", "id").option("--expected-version <value>", "Optional optimistic lock. Omit to let the server use the current version; pass only to fail with 409 `VERSION_CONFLICT` if someone else has mutated the event since you last read.").action(async (id, opts) => {
2334
2349
  const client2 = await loadSdkClient();
2335
2350
  const result = await eventDelete({
2336
2351
  client: client2._rawClient,
@@ -2354,7 +2369,7 @@ var eventDeleteCommand = new Command18("rm").description("Soft-delete a calendar
2354
2369
 
2355
2370
  // src/generated/cli/event/show.ts
2356
2371
  import { Command as Command19 } from "commander";
2357
- var eventGetCommand = new Command19("show").description("Get a calendar event by id").argument("<id>", "id").option("--include-deleted <value>", "include_deleted").action(async (id, opts) => {
2372
+ var eventGetCommand = new Command19("show").description("Get a calendar event by id").argument("<id>", "id").option("--include-deleted <value>", "When `true`, return the row even if soft-deleted. Default `false` (returns 404).").action(async (id, opts) => {
2358
2373
  const client2 = await loadSdkClient();
2359
2374
  const result = await eventGet({
2360
2375
  client: client2._rawClient,
@@ -2378,7 +2393,7 @@ var eventGetCommand = new Command19("show").description("Get a calendar event by
2378
2393
 
2379
2394
  // src/generated/cli/event/set.ts
2380
2395
  import { Command as Command20 } from "commander";
2381
- var eventUpdateCommand = new Command20("set").description("Update a calendar event").argument("<id>", "id").option("--expected-version <value>", "expected_version").option("--title <value>", "title").option("--description <value>", "description").option("--start <value>", "start").option("--end <value>", "end").option("-l, --location <value>", "location").option("-u, --url <value>", "url").option("--status <value>", "status").option("--attendee <value>", "attendee", (val, memo) => {
2396
+ var eventUpdateCommand = new Command20("set").description("Update a calendar event").argument("<id>", "id").option("--expected-version <value>", "Optional optimistic lock. Omit to let the server use the current version; pass only to fail the call if someone else has mutated the event since you last read. On mismatch the server returns 409 `VERSION_CONFLICT` with `extra.expected_version` and `extra.actual_version`.").option("--title <value>", "New event title. Omit to leave unchanged.").option("--description <value>", "New description. Markdown formatted (CommonMark + GFM tables, strikethrough, task lists). Pass an empty string to clear; omit to leave unchanged.").option("--start <value>", "Accepts ISO 8601 datetime with offset (e.g. `2026-06-01T12:30:00+08:00`) for timed events, or ISO date-only (e.g. `2026-06-01`) for all-day. The `wspc` CLI additionally accepts natural-language phrases (`tomorrow 12:30pm`, `next Monday 9am`) and resolves them to ISO before sending; the server itself only accepts ISO. All-day uses RFC 5545 exclusive end: a one-day event on 6/1 is `start=2026-06-01, end=2026-06-02`; both endpoints must be the same type.").option("--end <value>", "Accepts ISO 8601 datetime with offset (e.g. `2026-06-01T12:30:00+08:00`) for timed events, or ISO date-only (e.g. `2026-06-01`) for all-day. The `wspc` CLI additionally accepts natural-language phrases (`tomorrow 12:30pm`, `next Monday 9am`) and resolves them to ISO before sending; the server itself only accepts ISO. All-day uses RFC 5545 exclusive end: a one-day event on 6/1 is `start=2026-06-01, end=2026-06-02`; both endpoints must be the same type.").option("-l, --location <value>", "New location. Pass an empty string to clear; omit to leave unchanged.").option("-u, --url <value>", "New meeting link. Pass an empty string to clear; omit to leave unchanged.").option("--status <value>", "Lifecycle status. `confirmed`: the event will happen (default). `tentative`: organizer has not finalized; still visible in lists. `cancelled`: the event was called off but the record is kept so attendees can be notified and history audited; distinct from soft-delete (DELETE `/calendar/events/{id}`) which hides the event from default list responses.").option("--attendee <value>", "If provided, REPLACES the attendee list (after case-insensitive email dedupe, up to 50). Added attendees receive a fresh invitation, kept attendees receive an update email, removed attendees receive a cancellation.", (val, memo) => {
2382
2397
  memo.push(val);
2383
2398
  return memo;
2384
2399
  }, []).option("--all-day", "all_day").option("--tz <zone>", "IANA timezone for relative time parsing").action(async (id, opts) => {
@@ -2474,7 +2489,7 @@ var emailAliasCreateCommand = new Command22("add").description("Create a receivi
2474
2489
 
2475
2490
  // src/generated/cli/alias/ls.ts
2476
2491
  import { Command as Command23 } from "commander";
2477
- var emailAliasListCommand = new Command23("ls").description("List the caller's aliases").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
2492
+ var emailAliasListCommand = new Command23("ls").description("List the caller's aliases").option("--include-deleted <value>", "When `true`, include soft-deleted aliases (with `deleted_at` set) alongside active ones. Defaults to `false`.").action(async (opts) => {
2478
2493
  const client2 = await loadSdkClient();
2479
2494
  const result = await emailAliasList({
2480
2495
  client: client2._rawClient,
@@ -2599,7 +2614,7 @@ var emailDomainGetCommand = new Command28("show").description("Get one cached cu
2599
2614
 
2600
2615
  // src/generated/cli/email/show.ts
2601
2616
  import { Command as Command29 } from "commander";
2602
- var emailGetCommand = new Command29("show").description("Get an inbound email by id").argument("<id>", "id").option("--include-html <value>", "include_html").option("--include-deleted <value>", "include_deleted").action(async (id, opts) => {
2617
+ var emailGetCommand = new Command29("show").description("Get an inbound email by id").argument("<id>", "id").option("--include-html <value>", "When `true`, fetch the HTML body from R2 and include it as `html_body` in the response. Costs an extra R2 read; omit if you only need text.").option("--include-deleted <value>", "When `true`, allow fetching a soft-deleted email. Defaults to `false` (returns 404 for soft-deleted rows).").action(async (id, opts) => {
2603
2618
  const client2 = await loadSdkClient();
2604
2619
  const result = await emailGet({
2605
2620
  client: client2._rawClient,
@@ -2624,7 +2639,7 @@ var emailGetCommand = new Command29("show").description("Get an inbound email by
2624
2639
 
2625
2640
  // src/generated/cli/email/ls.ts
2626
2641
  import { Command as Command30 } from "commander";
2627
- var emailListCommand = new Command30("ls").description("List inbound emails").option("--limit <value>", "limit").option("--alias-email <value>", "alias_email").option("--unread-only <value>", "unread_only").option("--since <value>", "since").option("--cursor <value>", "cursor").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
2642
+ var emailListCommand = new Command30("ls").description("List inbound emails").option("--limit <value>", "Max items to return (clamped to 1-100). Defaults to 20 server-side.").option("--alias-email <value>", "If set, only return emails received on this full alias email address.").option("--unread-only <value>", "When `true`, only return emails with `is_read=false`.").option("--since <value>", "Unix epoch milliseconds \u2014 only return emails with `received_at >= since`. Useful for incremental sync.").option("--cursor <value>", "Opaque pagination cursor returned in `next_cursor` of a previous response.").option("--include-deleted <value>", "When `true`, also return soft-deleted emails. Defaults to `false`.").action(async (opts) => {
2628
2643
  const client2 = await loadSdkClient();
2629
2644
  const result = await emailList({
2630
2645
  client: client2._rawClient,
@@ -2738,7 +2753,7 @@ var pushConfigDeleteCommand = new Command34("rm").description("Remove a push tra
2738
2753
 
2739
2754
  // src/generated/cli/push/config/set.ts
2740
2755
  import { Command as Command35 } from "commander";
2741
- var pushConfigSetCommand = new Command35("set").description("Register or update a push transport").option("--transport <value>", "transport").option("--target-bot-username <value>", "target_bot_username").action(async (opts) => {
2756
+ var pushConfigSetCommand = new Command35("set").description("Register or update a push transport").option("--transport <value>", "Transport discriminator. `telegram` is the only supported value today \u2014 push delivers via a Telegram bot DM. Future transports (web push, iOS/Android, generic webhook) will be added as additional discriminator values.").option("--target-bot-username <value>", "Telegram bot username (with leading `@`, 5\u201332 alphanumeric/underscore characters). This is the bot the user has already started a chat with \u2014 wspc DMs notifications to it via the Telegram Bot API.").action(async (opts) => {
2742
2757
  const client2 = await loadSdkClient();
2743
2758
  const result = await pushConfigSet({
2744
2759
  client: client2._rawClient,
@@ -2780,7 +2795,7 @@ var pushConfigGetCommand = new Command36("show").description("List the caller's
2780
2795
 
2781
2796
  // src/generated/cli/push/test.ts
2782
2797
  import { Command as Command37 } from "commander";
2783
- var pushTestCommand = new Command37("test").description("Send a test push notification").option("--transport <value>", "transport").action(async (opts) => {
2798
+ var pushTestCommand = new Command37("test").description("Send a test push notification").option("--transport <value>", "Which transport to send the test message through. Must match a transport the caller has already registered via `POST /push/config`; today only `telegram` is supported.").action(async (opts) => {
2784
2799
  const client2 = await loadSdkClient();
2785
2800
  const result = await pushTest({
2786
2801
  client: client2._rawClient,
@@ -2828,7 +2843,7 @@ var todoCommentCreateCommand = new Command38("add").description("Add a comment t
2828
2843
 
2829
2844
  // src/generated/cli/todo/comment/ls.ts
2830
2845
  import { Command as Command39 } from "commander";
2831
- var todoCommentListCommand = new Command39("ls").description("List comments on a todo").argument("<id>", "id").option("--order <value>", "order").option("--include-deleted <value>", "include_deleted").option("--limit <value>", "limit").option("--cursor <value>", "cursor").action(async (id, opts) => {
2846
+ var todoCommentListCommand = new Command39("ls").description("List comments on a todo").argument("<id>", "id").option("--order <value>", "order").option("--include-deleted <value>", "include_deleted").option("--limit <value>", "Max comments to return. Clamped to [1, 200]. Default 50 server-side.").option("--cursor <value>", "Opaque pagination cursor returned in `next_cursor` of a previous response.").action(async (id, opts) => {
2832
2847
  const client2 = await loadSdkClient();
2833
2848
  const result = await todoCommentList({
2834
2849
  client: client2._rawClient,
@@ -2877,7 +2892,7 @@ var projectCreateCommand = new Command40("add").description("Create a project").
2877
2892
 
2878
2893
  // src/generated/cli/todo/project/ls.ts
2879
2894
  import { Command as Command41 } from "commander";
2880
- var projectListCommand = new Command41("ls").description("List projects").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
2895
+ var projectListCommand = new Command41("ls").description("List projects").option("--include-deleted <value>", "Set to `true` to include soft-deleted projects in the response.").action(async (opts) => {
2881
2896
  const client2 = await loadSdkClient();
2882
2897
  const result = await projectList({
2883
2898
  client: client2._rawClient,
@@ -2898,7 +2913,7 @@ var projectListCommand = new Command41("ls").description("List projects").option
2898
2913
 
2899
2914
  // src/generated/cli/todo/rule/ls.ts
2900
2915
  import { Command as Command42 } from "commander";
2901
- var recurrenceRuleListCommand = new Command42("ls").description("List recurring todo rules").option("--project-id <value>", "project_id").option("--user-id <value>", "user_id").action(async (opts) => {
2916
+ var recurrenceRuleListCommand = new Command42("ls").description("List recurring todo rules").option("--project-id <value>", "Project id filter. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").action(async (opts) => {
2902
2917
  const client2 = await loadSdkClient();
2903
2918
  const result = await recurrenceRuleList({
2904
2919
  client: client2._rawClient,
@@ -2920,7 +2935,7 @@ var recurrenceRuleListCommand = new Command42("ls").description("List recurring
2920
2935
 
2921
2936
  // src/generated/cli/todo/add.ts
2922
2937
  import { Command as Command43 } from "commander";
2923
- var todoCreateCommand = new Command43("add").description("Create a todo").argument("<title>", "title").option("-p, --project <value>", "project_id").option("--description <value>", "description").option("--parent-id <value>", "parent_id").option("--status <value>", "status").option("--due-at <value>", "due_at").option("--type-id <value>", "type_id").option("--custom-fields <value>", "custom_fields").action(async (title, opts) => {
2938
+ var todoCreateCommand = new Command43("add").description("Create a todo").argument("<title>", "title").option("-p, --project <value>", "Project id to assign this todo to. It must be an active project in the caller's organization.").option("--description <value>", "Free-form details about the todo. Fully supports GFM Markdown (tables, strikethrough, task lists). Stored verbatim; client applications are responsible for rendering. Optional. Passing `null` is strictly rejected.").option("--parent-id <value>", "Parent todo ID (`tod_<ULID>`) to attach this todo as a child under another todo. Omit or pass `null` to create a root-level todo. Nesting is limited to one level; attempting to set a child todo as a parent will trigger `PARENT_IS_CHILD`.").option("--status <value>", "Initial status of the todo. Omit to default to `open`. Allowed values: `open`, `in_progress`, `done`, `cancelled`.").option("--due-at <value>", 'Optional calendar due date in ISO date-only format (`YYYY-MM-DD`). Stored without timezone offsets to represent the same local calendar day globally. Pass `""` or omit the field to skip setting a due date. Passing `null` is strictly rejected.').option("--type-id <value>", "Type id this todo belongs to. Omit to use the project's default type. When project_id is also supplied, the type must belong to the same project. New server-generated type ids use typ_<ULID>; legacy ids remain accepted.").option("--custom-fields <value>", "Custom field values keyed by the field's immutable `key` (not the human `label`). Each value must match the declared field type: string fields require string values, and string_array fields require string arrays. Providing a key that is not declared on the resolved todo type is strictly rejected with `UNDECLARED_FIELD`. Missing required fields that lack a default value are rejected with `FIELD_REQUIRED`. Defaults declared on the type are auto-applied at create time.").action(async (title, opts) => {
2924
2939
  const client2 = await loadSdkClient();
2925
2940
  const result = await todoCreate({
2926
2941
  client: client2._rawClient,
@@ -2948,7 +2963,7 @@ var todoCreateCommand = new Command43("add").description("Create a todo").argume
2948
2963
 
2949
2964
  // src/generated/cli/todo/ls.ts
2950
2965
  import { Command as Command44 } from "commander";
2951
- var todoListCommand = new Command44("ls").description("List todos with filters").option("-p, --project <value>", "project_id").option("--user-id <value>", "user_id").option("--parent-id <value>", "parent_id").option("-s, --status <value>", "status").option("--include-deleted <value>", "include_deleted").option("--include-templates <value>", "include_templates").option("--due-after <value>", "due_after").option("--due-before <value>", "due_before").option("--type-id <value>", "type_id").option("--sort-by <value>", "sort_by").option("--order <value>", "order").option("--include-orphan-fields <value>", "include_orphan_fields").option("--limit <value>", "limit").option("--cursor <value>", "cursor").action(async (opts) => {
2966
+ var todoListCommand = new Command44("ls").description("List todos with filters").option("-p, --project <value>", "Filter by project. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").option("--parent-id <value>", "parent_id").option("-s, --status <value>", "status").option("--include-deleted <value>", "include_deleted").option("--include-templates <value>", "include_templates").option("--due-after <value>", "due_after").option("--due-before <value>", "due_before").option("--type-id <value>", "type_id").option("--sort-by <value>", "sort_by").option("--order <value>", "order").option("--include-orphan-fields <value>", "include_orphan_fields").option("--limit <value>", "Max todos to return. Clamped to [1, 200]. Default 50 server-side.").option("--cursor <value>", "Opaque pagination cursor returned in `next_cursor` of a previous response.").action(async (opts) => {
2952
2967
  const client2 = await loadSdkClient();
2953
2968
  const result = await todoList({
2954
2969
  client: client2._rawClient,
@@ -2982,7 +2997,7 @@ var todoListCommand = new Command44("ls").description("List todos with filters")
2982
2997
 
2983
2998
  // src/generated/cli/todo/type/ls.ts
2984
2999
  import { Command as Command45 } from "commander";
2985
- var todoTypeListCommand = new Command45("ls").description("List todo types").option("--project-id <value>", "project_id").option("--user-id <value>", "user_id").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
3000
+ var todoTypeListCommand = new Command45("ls").description("List todo types").option("--project-id <value>", "Project id filter. Required. Unknown, cross-organization, or soft-deleted project ids return NOT_FOUND.").option("--user-id <value>", "user_id").option("--include-deleted <value>", "include_deleted").action(async (opts) => {
2986
3001
  const client2 = await loadSdkClient();
2987
3002
  const result = await todoTypeList({
2988
3003
  client: client2._rawClient,
@@ -3101,7 +3116,7 @@ var todoGetCommand = new Command49("show").description("Get a todo by id").argum
3101
3116
 
3102
3117
  // src/generated/cli/todo/update.ts
3103
3118
  import { Command as Command50 } from "commander";
3104
- var todoUpdateCommand = new Command50("update").description("Update a todo").argument("<id>", "id").option("--expected-version <value>", "expected_version").option("--title <value>", "title").option("--description <value>", "description").option("--parent-id <value>", "parent_id").option("--status <value>", "status").option("--due-at <value>", "due_at").option("--type-id <value>", "type_id").option("--custom-fields <value>", "custom_fields").option("--user-id <value>", "user_id").action(async (id, opts) => {
3119
+ var todoUpdateCommand = new Command50("update").description("Update a todo").argument("<id>", "id").option("--expected-version <value>", "expected_version").option("--title <value>", "New title. Omit to leave the existing title unchanged. Must be non-empty when supplied.").option("--description <value>", 'New description. Markdown formatted (CommonMark + GFM tables, strikethrough, task lists). Pass empty string `""` explicitly to clear an existing description, or omit to leave unchanged. Passing `null` is strictly rejected.').option("--parent-id <value>", "Re-parent the todo. Pass a valid parent ID to attach under another todo, pass `null` to move it back to the root level, or omit to leave unchanged. Nesting is limited to one level; attempting to set a child todo as a parent will trigger `PARENT_IS_CHILD`.").option("--status <value>", "New status of the todo. Allowed transitions: `open` \u2794 `in_progress` \u2794 `done`. `cancelled` represents a terminal state. Transitioning to `done` automatically emits a `captureTodoCompleted` analytics event. Omit to leave the existing status unchanged.").option("--due-at <value>", 'Update calendar due date in ISO date-only format (`YYYY-MM-DD`). Pass `""` explicitly to clear an existing due date, or omit to leave it unchanged. Passing `null` is strictly rejected.').option("--type-id <value>", "Re-assign this todo to a different active type. The new type must belong to the todo's same project; otherwise the request fails with TYPE_PROJECT_MISMATCH. New server-generated type ids use typ_<ULID>; legacy ids remain accepted.").option("--custom-fields <value>", "PATCH semantics: only the keys present in this map change. Pass `null` for a key (e.g. `custom_fields: { priority: null }`) to explicitly delete that custom field value. Array values are replaced wholesale with no element-level diff. Providing a key that is not declared on the effective todo type is rejected with `UNDECLARED_FIELD`.").option("--user-id <value>", "Reassign the owner (assignee) user ID of this todo. Target user must belong to the same organization.").action(async (id, opts) => {
3105
3120
  const client2 = await loadSdkClient();
3106
3121
  const result = await todoUpdate({
3107
3122
  client: client2._rawClient,