diff --git a/.sqlx/query-08f040920cffc4ee2c639f36b685cafed69a8d525e419eabc6a0471ade36a521.json b/.sqlx/query-08f040920cffc4ee2c639f36b685cafed69a8d525e419eabc6a0471ade36a521.json
new file mode 100644
index 00000000000..383c36d9d01
--- /dev/null
+++ b/.sqlx/query-08f040920cffc4ee2c639f36b685cafed69a8d525e419eabc6a0471ade36a521.json
@@ -0,0 +1,24 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT p->>'jid' AS \"jid!\" FROM whatsapp_group_roster r\n CROSS JOIN LATERAL jsonb_array_elements(r.metadata->'participants') p\n WHERE r.account_id = $1 AND r.group_jid = $2 AND p->>'alternateJid' = $3\n AND p->>'jid' LIKE '%@s.whatsapp.net'\n LIMIT 1",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "jid!",
+ "type_info": "Text"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text",
+ "Text"
+ ]
+ },
+ "nullable": [
+ null
+ ]
+ },
+ "hash": "08f040920cffc4ee2c639f36b685cafed69a8d525e419eabc6a0471ade36a521"
+}
diff --git a/.sqlx/query-0f01a5b08dba2c0c7069d295be4f3cf8faad938d4c5076bc339eb11929e606d7.json b/.sqlx/query-0f01a5b08dba2c0c7069d295be4f3cf8faad938d4c5076bc339eb11929e606d7.json
deleted file mode 100644
index 55526cac7b0..00000000000
--- a/.sqlx/query-0f01a5b08dba2c0c7069d295be4f3cf8faad938d4c5076bc339eb11929e606d7.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "db_name": "PostgreSQL",
- "query": "SELECT g.id,g.name,g.user_id,\n (SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id = g.id AND m.message_id IS NOT NULL\n AND m.deleted_at IS NULL AND m.origin <> 'history'\n AND NOT EXISTS (SELECT 1 FROM whatsapp_external_person p WHERE p.id = m.person_id AND p.user_id = $2)\n AND (r.message_id IS NULL OR (m.source_at,m.id) > (r.read_at,r.message_id))) AS \"unread_count!\",\n (SELECT max(source_at) FROM whatsapp_group_message WHERE binding_id = g.id AND message_id IS NOT NULL) AS last_message_at\n FROM whatsapp_group g LEFT JOIN whatsapp_group_read_state r ON r.group_id = g.id AND r.user_id = $2\n WHERE g.id = $1",
- "describe": {
- "columns": [
- {
- "ordinal": 0,
- "name": "id",
- "type_info": "Uuid"
- },
- {
- "ordinal": 1,
- "name": "name",
- "type_info": "Text"
- },
- {
- "ordinal": 2,
- "name": "user_id",
- "type_info": "Text"
- },
- {
- "ordinal": 3,
- "name": "unread_count!",
- "type_info": "Int8"
- },
- {
- "ordinal": 4,
- "name": "last_message_at",
- "type_info": "Timestamptz"
- }
- ],
- "parameters": {
- "Left": [
- "Uuid",
- "Text"
- ]
- },
- "nullable": [
- false,
- false,
- false,
- null,
- null
- ]
- },
- "hash": "0f01a5b08dba2c0c7069d295be4f3cf8faad938d4c5076bc339eb11929e606d7"
-}
diff --git a/.sqlx/query-1aa1e6a2988d0f0211ad76883050aaae6f48eee637532ae83e661048b3e4f16f.json b/.sqlx/query-1aa1e6a2988d0f0211ad76883050aaae6f48eee637532ae83e661048b3e4f16f.json
deleted file mode 100644
index 1268ccfe7a1..00000000000
--- a/.sqlx/query-1aa1e6a2988d0f0211ad76883050aaae6f48eee637532ae83e661048b3e4f16f.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "db_name": "PostgreSQL",
- "query": "SELECT g.id,g.name,g.user_id,g.group_jid,g.state,g.adopted_at,\n (SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id=g.id AND m.message_id IS NOT NULL\n AND m.deleted_at IS NULL AND m.origin<>'history'\n AND NOT EXISTS(SELECT 1 FROM whatsapp_external_person p WHERE p.id=m.person_id AND p.user_id=$1)\n AND (r.message_id IS NULL OR (m.source_at,m.id)>(r.read_at,r.message_id))) AS \"unread_count!\",\n (SELECT max(source_at) FROM whatsapp_group_message WHERE binding_id=g.id AND message_id IS NOT NULL) AS last_message_at,\n roster.metadata AS \"metadata?\"\n FROM whatsapp_group g\n LEFT JOIN whatsapp_group_read_state r ON r.group_id=g.id AND r.user_id=$1\n LEFT JOIN whatsapp_linked_account a ON a.user_id=$1\n LEFT JOIN whatsapp_group_roster roster ON roster.account_id=a.id AND roster.group_jid=g.group_jid\n WHERE whatsapp_group_can_view(g.id,$1)\n AND (r.user_id IS NOT NULL OR EXISTS (SELECT 1 FROM entity_access ea\n WHERE ea.entity_id=g.id AND ea.entity_type='whatsapp_group'\n AND (ea.source_id=$1 OR ea.source_id IN (SELECT team_id::text FROM team_user WHERE user_id=$1)\n OR ea.source_id IN (SELECT channel_id::text FROM comms_channel_participants WHERE user_id=$1 AND left_at IS NULL))))\n ORDER BY g.adopted_at DESC LIMIT 2000",
- "describe": {
- "columns": [
- {
- "ordinal": 0,
- "name": "id",
- "type_info": "Uuid"
- },
- {
- "ordinal": 1,
- "name": "name",
- "type_info": "Text"
- },
- {
- "ordinal": 2,
- "name": "user_id",
- "type_info": "Text"
- },
- {
- "ordinal": 3,
- "name": "group_jid",
- "type_info": "Text"
- },
- {
- "ordinal": 4,
- "name": "state",
- "type_info": "Text"
- },
- {
- "ordinal": 5,
- "name": "adopted_at",
- "type_info": "Timestamptz"
- },
- {
- "ordinal": 6,
- "name": "unread_count!",
- "type_info": "Int8"
- },
- {
- "ordinal": 7,
- "name": "last_message_at",
- "type_info": "Timestamptz"
- },
- {
- "ordinal": 8,
- "name": "metadata?",
- "type_info": "Jsonb"
- }
- ],
- "parameters": {
- "Left": [
- "Text"
- ]
- },
- "nullable": [
- false,
- false,
- false,
- false,
- false,
- false,
- null,
- null,
- false
- ]
- },
- "hash": "1aa1e6a2988d0f0211ad76883050aaae6f48eee637532ae83e661048b3e4f16f"
-}
diff --git a/.sqlx/query-24e02b9f9df426d070d8f52a6a167e94f381ab8457c515c42287830741b73c7c.json b/.sqlx/query-24e02b9f9df426d070d8f52a6a167e94f381ab8457c515c42287830741b73c7c.json
new file mode 100644
index 00000000000..8078d0dd53c
--- /dev/null
+++ b/.sqlx/query-24e02b9f9df426d070d8f52a6a167e94f381ab8457c515c42287830741b73c7c.json
@@ -0,0 +1,41 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT id, backfill_imported, backfill_cursor, adopted_at FROM whatsapp_group\n WHERE user_id = $1 AND group_jid = $2 AND state = 'active'\n AND backfill_state IN ('pending', 'running', 'waiting_for_phone')\n ORDER BY id FOR UPDATE",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "id",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 1,
+ "name": "backfill_imported",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 2,
+ "name": "backfill_cursor",
+ "type_info": "Jsonb"
+ },
+ {
+ "ordinal": 3,
+ "name": "adopted_at",
+ "type_info": "Timestamptz"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Text",
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ false,
+ true,
+ false
+ ]
+ },
+ "hash": "24e02b9f9df426d070d8f52a6a167e94f381ab8457c515c42287830741b73c7c"
+}
diff --git a/.sqlx/query-25a3546a1d143befc191768ce7ca378bf2817eeec4629ae8b7b30aea1bcfe06c.json b/.sqlx/query-25a3546a1d143befc191768ce7ca378bf2817eeec4629ae8b7b30aea1bcfe06c.json
new file mode 100644
index 00000000000..d8fd852bebb
--- /dev/null
+++ b/.sqlx/query-25a3546a1d143befc191768ce7ca378bf2817eeec4629ae8b7b30aea1bcfe06c.json
@@ -0,0 +1,25 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "UPDATE whatsapp_group g SET backfill_state = $3,\n backfill_requested_at = CASE WHEN $4 THEN now() ELSE g.backfill_requested_at END\n FROM (SELECT id, backfill_state FROM whatsapp_group WHERE id = $1 FOR UPDATE) old\n WHERE g.id = old.id AND g.user_id = $2\n AND g.backfill_state IN ('pending', 'running', 'waiting_for_phone')\n RETURNING old.backfill_state AS \"previous!\"",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "previous!",
+ "type_info": "Text"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text",
+ "Text",
+ "Bool"
+ ]
+ },
+ "nullable": [
+ true
+ ]
+ },
+ "hash": "25a3546a1d143befc191768ce7ca378bf2817eeec4629ae8b7b30aea1bcfe06c"
+}
diff --git a/.sqlx/query-32c807a8fae0af855391049ebc09c800888830ae050c4647a795c842e60f9d0c.json b/.sqlx/query-32c807a8fae0af855391049ebc09c800888830ae050c4647a795c842e60f9d0c.json
new file mode 100644
index 00000000000..42c9511e297
--- /dev/null
+++ b/.sqlx/query-32c807a8fae0af855391049ebc09c800888830ae050c4647a795c842e60f9d0c.json
@@ -0,0 +1,59 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT g.id,g.name,g.user_id,g.backfill_state,g.backfill_imported,\n (SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id = g.id AND m.message_id IS NOT NULL\n AND m.deleted_at IS NULL AND m.origin <> 'history'\n AND NOT EXISTS (SELECT 1 FROM whatsapp_external_person p WHERE p.id = m.person_id AND p.user_id = $2)\n AND (r.message_id IS NULL OR (m.source_at,m.id) > (r.read_at,r.message_id))) AS \"unread_count!\",\n (SELECT max(source_at) FROM whatsapp_group_message WHERE binding_id = g.id AND message_id IS NOT NULL) AS last_message_at\n FROM whatsapp_group g LEFT JOIN whatsapp_group_read_state r ON r.group_id = g.id AND r.user_id = $2\n WHERE g.id = $1",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "id",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 1,
+ "name": "name",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "user_id",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 3,
+ "name": "backfill_state",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 4,
+ "name": "backfill_imported",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 5,
+ "name": "unread_count!",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 6,
+ "name": "last_message_at",
+ "type_info": "Timestamptz"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ false,
+ false,
+ true,
+ false,
+ null,
+ null
+ ]
+ },
+ "hash": "32c807a8fae0af855391049ebc09c800888830ae050c4647a795c842e60f9d0c"
+}
diff --git a/.sqlx/query-623edc4d3e056156b23a4d38687772408a07e15b7bd395cee96bfd3c8f326fd0.json b/.sqlx/query-623edc4d3e056156b23a4d38687772408a07e15b7bd395cee96bfd3c8f326fd0.json
new file mode 100644
index 00000000000..2ebcb790e3e
--- /dev/null
+++ b/.sqlx/query-623edc4d3e056156b23a4d38687772408a07e15b7bd395cee96bfd3c8f326fd0.json
@@ -0,0 +1,52 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT chat_jid, kind, name, last_activity_at, archived, pinned FROM whatsapp_chat\n WHERE account_id = $1 ORDER BY last_activity_at DESC NULLS LAST, chat_jid LIMIT 5000",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "chat_jid",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 1,
+ "name": "kind",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "name",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 3,
+ "name": "last_activity_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 4,
+ "name": "archived",
+ "type_info": "Bool"
+ },
+ {
+ "ordinal": 5,
+ "name": "pinned",
+ "type_info": "Bool"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Uuid"
+ ]
+ },
+ "nullable": [
+ false,
+ false,
+ true,
+ true,
+ false,
+ false
+ ]
+ },
+ "hash": "623edc4d3e056156b23a4d38687772408a07e15b7bd395cee96bfd3c8f326fd0"
+}
diff --git a/.sqlx/query-7ba6c8eb1f7085b499db0bc85e4e16a04e83825fba90b1ee54aed1dccd2691e3.json b/.sqlx/query-7ba6c8eb1f7085b499db0bc85e4e16a04e83825fba90b1ee54aed1dccd2691e3.json
new file mode 100644
index 00000000000..a9137b11463
--- /dev/null
+++ b/.sqlx/query-7ba6c8eb1f7085b499db0bc85e4e16a04e83825fba90b1ee54aed1dccd2691e3.json
@@ -0,0 +1,17 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "UPDATE whatsapp_group SET backfill_state = $2, backfill_imported = $3, backfill_cursor = $4,\n backfill_requested_at = NULL\n WHERE id = $1",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text",
+ "Int4",
+ "Jsonb"
+ ]
+ },
+ "nullable": []
+ },
+ "hash": "7ba6c8eb1f7085b499db0bc85e4e16a04e83825fba90b1ee54aed1dccd2691e3"
+}
diff --git a/.sqlx/query-8d7c3fc8a759d0bc6e72dc9a7c97cf274d7f92f55683af8645dca6ca5125ed46.json b/.sqlx/query-8d7c3fc8a759d0bc6e72dc9a7c97cf274d7f92f55683af8645dca6ca5125ed46.json
new file mode 100644
index 00000000000..f431ff62374
--- /dev/null
+++ b/.sqlx/query-8d7c3fc8a759d0bc6e72dc9a7c97cf274d7f92f55683af8645dca6ca5125ed46.json
@@ -0,0 +1,82 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT g.id,g.name,g.user_id,g.group_jid,g.state,g.adopted_at,g.backfill_state,g.backfill_imported,\n (SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id=g.id AND m.message_id IS NOT NULL\n AND m.deleted_at IS NULL AND m.origin<>'history'\n AND NOT EXISTS(SELECT 1 FROM whatsapp_external_person p WHERE p.id=m.person_id AND p.user_id=$1)\n AND (r.message_id IS NULL OR (m.source_at,m.id)>(r.read_at,r.message_id))) AS \"unread_count!\",\n (SELECT max(source_at) FROM whatsapp_group_message WHERE binding_id=g.id AND message_id IS NOT NULL) AS last_message_at,\n roster.metadata AS \"metadata?\"\n FROM whatsapp_group g\n LEFT JOIN whatsapp_group_read_state r ON r.group_id=g.id AND r.user_id=$1\n LEFT JOIN whatsapp_linked_account a ON a.user_id=$1\n LEFT JOIN whatsapp_group_roster roster ON roster.account_id=a.id AND roster.group_jid=g.group_jid\n WHERE whatsapp_group_can_view(g.id,$1)\n AND (r.user_id IS NOT NULL OR EXISTS (SELECT 1 FROM entity_access ea\n WHERE ea.entity_id=g.id AND ea.entity_type='whatsapp_group'\n AND (ea.source_id=$1 OR ea.source_id IN (SELECT team_id::text FROM team_user WHERE user_id=$1)\n OR ea.source_id IN (SELECT channel_id::text FROM comms_channel_participants WHERE user_id=$1 AND left_at IS NULL))))\n ORDER BY g.adopted_at DESC LIMIT 2000",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "id",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 1,
+ "name": "name",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "user_id",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 3,
+ "name": "group_jid",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 4,
+ "name": "state",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 5,
+ "name": "adopted_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 6,
+ "name": "backfill_state",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 7,
+ "name": "backfill_imported",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 8,
+ "name": "unread_count!",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 9,
+ "name": "last_message_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 10,
+ "name": "metadata?",
+ "type_info": "Jsonb"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ false,
+ null,
+ null,
+ false
+ ]
+ },
+ "hash": "8d7c3fc8a759d0bc6e72dc9a7c97cf274d7f92f55683af8645dca6ca5125ed46"
+}
diff --git a/.sqlx/query-feaac846feefd19a0d1e2a3ed8ae574ffdb48d75441cd0ec5f96e0066b1b87c1.json b/.sqlx/query-b4ca13f663d78e9839a95b921f85252fa9069d30fe664ed8abce4271b6027293.json
similarity index 78%
rename from .sqlx/query-feaac846feefd19a0d1e2a3ed8ae574ffdb48d75441cd0ec5f96e0066b1b87c1.json
rename to .sqlx/query-b4ca13f663d78e9839a95b921f85252fa9069d30fe664ed8abce4271b6027293.json
index 80ea38c1920..92572982977 100644
--- a/.sqlx/query-feaac846feefd19a0d1e2a3ed8ae574ffdb48d75441cd0ec5f96e0066b1b87c1.json
+++ b/.sqlx/query-b4ca13f663d78e9839a95b921f85252fa9069d30fe664ed8abce4271b6027293.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "INSERT INTO whatsapp_group (id, group_jid, name, user_id, state, share_permission_id) VALUES ($1,$2,$3,$4,'active',$5) RETURNING id, group_jid, user_id, state, adopted_at",
+ "query": "INSERT INTO whatsapp_group (id, group_jid, name, user_id, state, share_permission_id, backfill_state) VALUES ($1,$2,$3,$4,'active',$5,'pending') RETURNING id, group_jid, user_id, state, adopted_at",
"describe": {
"columns": [
{
@@ -46,5 +46,5 @@
false
]
},
- "hash": "feaac846feefd19a0d1e2a3ed8ae574ffdb48d75441cd0ec5f96e0066b1b87c1"
+ "hash": "b4ca13f663d78e9839a95b921f85252fa9069d30fe664ed8abce4271b6027293"
}
diff --git a/.sqlx/query-c412870d6e6e8be6878bfe1bd793ce3292bc74417b2f18890c481265f4f2a1d6.json b/.sqlx/query-c412870d6e6e8be6878bfe1bd793ce3292bc74417b2f18890c481265f4f2a1d6.json
new file mode 100644
index 00000000000..872480ff795
--- /dev/null
+++ b/.sqlx/query-c412870d6e6e8be6878bfe1bd793ce3292bc74417b2f18890c481265f4f2a1d6.json
@@ -0,0 +1,65 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "SELECT g.id, g.group_jid, g.backfill_state AS \"state!\", g.backfill_imported, g.backfill_cursor,\n g.adopted_at, g.backfill_requested_at, c.anchor AS \"anchor?\"\n FROM whatsapp_group g\n LEFT JOIN whatsapp_chat c ON c.account_id = $1 AND c.chat_jid = g.group_jid\n WHERE g.user_id = $2 AND g.state = 'active'\n AND g.backfill_state IN ('pending', 'running', 'waiting_for_phone')\n ORDER BY g.adopted_at, g.id LIMIT 20",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "id",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 1,
+ "name": "group_jid",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "state!",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 3,
+ "name": "backfill_imported",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 4,
+ "name": "backfill_cursor",
+ "type_info": "Jsonb"
+ },
+ {
+ "ordinal": 5,
+ "name": "adopted_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 6,
+ "name": "backfill_requested_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 7,
+ "name": "anchor?",
+ "type_info": "Jsonb"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ false,
+ true,
+ false,
+ true,
+ false,
+ true,
+ true
+ ]
+ },
+ "hash": "c412870d6e6e8be6878bfe1bd793ce3292bc74417b2f18890c481265f4f2a1d6"
+}
diff --git a/.sqlx/query-ca90bf3789dc312e956c7153adab75c8a048dc949b0a59baf4e002f97b36643a.json b/.sqlx/query-ca90bf3789dc312e956c7153adab75c8a048dc949b0a59baf4e002f97b36643a.json
new file mode 100644
index 00000000000..52690b2f2af
--- /dev/null
+++ b/.sqlx/query-ca90bf3789dc312e956c7153adab75c8a048dc949b0a59baf4e002f97b36643a.json
@@ -0,0 +1,21 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "INSERT INTO whatsapp_chat AS c (account_id, chat_jid, kind, name, last_activity_at, archived, pinned, anchor)\n VALUES ($1, $2, $3, $4, $5, COALESCE($6, false), COALESCE($7, false), $8)\n ON CONFLICT (account_id, chat_jid) DO UPDATE SET\n name = COALESCE(excluded.name, c.name),\n last_activity_at = GREATEST(c.last_activity_at, excluded.last_activity_at),\n archived = COALESCE($6, c.archived),\n pinned = COALESCE($7, c.pinned),\n anchor = CASE WHEN excluded.anchor IS NOT NULL AND (c.anchor IS NULL\n OR (excluded.anchor->>'at')::timestamptz >= (c.anchor->>'at')::timestamptz)\n THEN excluded.anchor ELSE c.anchor END,\n updated_at = now()\n WHERE c.name IS DISTINCT FROM COALESCE(excluded.name, c.name)\n OR c.last_activity_at IS DISTINCT FROM GREATEST(c.last_activity_at, excluded.last_activity_at)\n OR c.archived IS DISTINCT FROM COALESCE($6, c.archived)\n OR c.pinned IS DISTINCT FROM COALESCE($7, c.pinned)\n OR (excluded.anchor IS NOT NULL AND c.anchor IS DISTINCT FROM excluded.anchor AND (c.anchor IS NULL\n OR (excluded.anchor->>'at')::timestamptz >= (c.anchor->>'at')::timestamptz))",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text",
+ "Text",
+ "Text",
+ "Timestamptz",
+ "Bool",
+ "Bool",
+ "Jsonb"
+ ]
+ },
+ "nullable": []
+ },
+ "hash": "ca90bf3789dc312e956c7153adab75c8a048dc949b0a59baf4e002f97b36643a"
+}
diff --git a/.sqlx/query-d97f6d326a00dc82c793bee806800fbe5fb9b11e7269931ce956fda4f2f03bec.json b/.sqlx/query-d97f6d326a00dc82c793bee806800fbe5fb9b11e7269931ce956fda4f2f03bec.json
new file mode 100644
index 00000000000..4b3f0c991e0
--- /dev/null
+++ b/.sqlx/query-d97f6d326a00dc82c793bee806800fbe5fb9b11e7269931ce956fda4f2f03bec.json
@@ -0,0 +1,19 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "UPDATE whatsapp_chat c SET\n name = COALESCE($3, c.name),\n last_activity_at = GREATEST(c.last_activity_at, $4),\n archived = COALESCE($5, c.archived),\n pinned = COALESCE($6, c.pinned),\n updated_at = now()\n WHERE c.account_id = $1 AND c.chat_jid = $2\n AND (c.name IS DISTINCT FROM COALESCE($3, c.name)\n OR c.last_activity_at IS DISTINCT FROM GREATEST(c.last_activity_at, $4)\n OR c.archived IS DISTINCT FROM COALESCE($5, c.archived)\n OR c.pinned IS DISTINCT FROM COALESCE($6, c.pinned))",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Left": [
+ "Uuid",
+ "Text",
+ "Text",
+ "Timestamptz",
+ "Bool",
+ "Bool"
+ ]
+ },
+ "nullable": []
+ },
+ "hash": "d97f6d326a00dc82c793bee806800fbe5fb9b11e7269931ce956fda4f2f03bec"
+}
diff --git a/.sqlx/query-68381ba2360701e8c5d30633d243a32d7e5646ec8b2ae66ab0ae3a8a7ded0c95.json b/.sqlx/query-f376b23fdfc65eac1e9043a5eb25fa3e94257cdf185bbfea48e7c4b76c97fbf0.json
similarity index 71%
rename from .sqlx/query-68381ba2360701e8c5d30633d243a32d7e5646ec8b2ae66ab0ae3a8a7ded0c95.json
rename to .sqlx/query-f376b23fdfc65eac1e9043a5eb25fa3e94257cdf185bbfea48e7c4b76c97fbf0.json
index 84a962e0c53..76ef2f3628c 100644
--- a/.sqlx/query-68381ba2360701e8c5d30633d243a32d7e5646ec8b2ae66ab0ae3a8a7ded0c95.json
+++ b/.sqlx/query-f376b23fdfc65eac1e9043a5eb25fa3e94257cdf185bbfea48e7c4b76c97fbf0.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT b.id, b.group_jid, b.user_id, b.state, b.adopted_at\n FROM whatsapp_group b JOIN whatsapp_group_membership m ON m.binding_id = b.id\n WHERE b.group_jid = $1 AND b.state = 'active'\n AND m.account_id = $2 AND m.generation = $3 AND m.consent_ended_at IS NULL\n AND m.remote_member AND m.reconciled\n AND $4 >= date_trunc('second', b.adopted_at) - make_interval(secs => $6)\n AND $4 >= date_trunc('second', m.consent_at) - make_interval(secs => $6)\n AND whatsapp_group_can_view(b.id, $5)\n ORDER BY b.id LIMIT 100",
+ "query": "SELECT b.id, b.group_jid, b.user_id, b.state, b.adopted_at\n FROM whatsapp_group b JOIN whatsapp_group_membership m ON m.binding_id = b.id\n WHERE b.group_jid = $1 AND b.state = 'active'\n AND m.account_id = $2 AND m.generation = $3 AND m.consent_ended_at IS NULL\n AND m.remote_member AND m.reconciled\n AND CASE WHEN $7 THEN b.user_id = $5 ELSE\n $4 >= date_trunc('second', b.adopted_at) - make_interval(secs => $6)\n AND $4 >= date_trunc('second', m.consent_at) - make_interval(secs => $6) END\n AND whatsapp_group_can_view(b.id, $5)\n ORDER BY b.id LIMIT 100",
"describe": {
"columns": [
{
@@ -36,7 +36,8 @@
"Int8",
"Timestamptz",
"Text",
- "Float8"
+ "Float8",
+ "Bool"
]
},
"nullable": [
@@ -47,5 +48,5 @@
false
]
},
- "hash": "68381ba2360701e8c5d30633d243a32d7e5646ec8b2ae66ab0ae3a8a7ded0c95"
+ "hash": "f376b23fdfc65eac1e9043a5eb25fa3e94257cdf185bbfea48e7c4b76c97fbf0"
}
diff --git a/Cargo.lock b/Cargo.lock
index c1670e3cbce..43f01d6127c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -21602,6 +21602,7 @@ dependencies = [
"axum",
"base64 0.22.1",
"chrono",
+ "flate2",
"futures",
"hmac 0.12.1",
"nom 8.0.0",
diff --git a/apps/web/src/features/external-view/components/in-macro-section.test.tsx b/apps/web/src/features/external-view/components/in-macro-section.test.tsx
index 4eaca027bae..123843d3a23 100644
--- a/apps/web/src/features/external-view/components/in-macro-section.test.tsx
+++ b/apps/web/src/features/external-view/components/in-macro-section.test.tsx
@@ -6,7 +6,7 @@ import {
within,
} from '@solidjs/testing-library';
import { afterEach, beforeEach, expect, it, vi } from 'vitest';
-import { InMacroSection } from './in-macro-section';
+import { InMacroGroups } from './in-macro-section';
beforeEach(() => {
vi.stubGlobal(
@@ -26,7 +26,7 @@ afterEach(() => {
it('lists readable groups with unread counts and marks read-only ones', () => {
const onOpenGroup = vi.fn();
render(() => (
- {
isPending={false}
isError={false}
activeGroupId="group-family"
- open
- onOpenChange={vi.fn()}
onOpenGroup={onOpenGroup}
onRetry={vi.fn()}
/>
diff --git a/apps/web/src/features/external-view/components/in-macro-section.tsx b/apps/web/src/features/external-view/components/in-macro-section.tsx
index d89140b4410..6ad61415c00 100644
--- a/apps/web/src/features/external-view/components/in-macro-section.tsx
+++ b/apps/web/src/features/external-view/components/in-macro-section.tsx
@@ -1,9 +1,10 @@
-import { CollapsibleSection, ViewSidebar } from '@app/components/view-shell';
+import { ViewSidebar } from '@app/components/view-shell';
import type { GroupSummary } from '@app/features/whatsapp-group/core/group';
+import UsersThreeIcon from '@phosphor/users-three.svg';
import { Button } from '@ui';
import { For, Match, Show, Switch } from 'solid-js';
-function UnreadCount(props: { count: number }) {
+export function UnreadCount(props: { count: number }) {
return (
0}>
+
+
+
0 }}
@@ -46,72 +50,58 @@ function GroupRow(props: {
);
}
-/** WhatsApp groups this viewer can read in Macro: their own and shared ones. */
-export function InMacroSection(props: {
+/**
+ * WhatsApp groups this viewer can read in Macro, their own and shared ones,
+ * as rows nested under WhatsApp in External's sidebar.
+ */
+export function InMacroGroups(props: {
groups: GroupSummary[] | undefined;
isPending: boolean;
isError: boolean;
activeGroupId: string | undefined;
- open: boolean;
- onOpenChange: (open: boolean) => void;
onOpenGroup: (groupId: string) => void;
onRetry: () => void;
}) {
- const unread = () =>
- (props.groups ?? []).reduce((sum, group) => sum + group.unreadCount, 0);
return (
-
-
-
- In Macro
-
-
-
-
-
-
-
-
-
- {(groups) => (
-
-
- }
- >
- {(group) => (
- props.onOpenGroup(group.id)}
- />
- )}
-
-
- )}
-
-
-
-
-
-
- Couldn't load your groups.
-
- Try again
-
-
-
-
-
-
+
+
+ {(groups) => (
+
+
+
+ )}
+
+
+
+
+
+
+
+
);
}
diff --git a/apps/web/src/features/external-view/external-view.tsx b/apps/web/src/features/external-view/external-view.tsx
index abfe40f29ff..66894ee0f4b 100644
--- a/apps/web/src/features/external-view/external-view.tsx
+++ b/apps/web/src/features/external-view/external-view.tsx
@@ -16,7 +16,7 @@ import { createSignal, Show } from 'solid-js';
import { z } from 'zod';
import { whatsappGroupApi } from '../whatsapp-group/queries/production-api';
import { WhatsAppLinked } from '../whatsapp-linked/whatsapp-linked';
-import { InMacroSection } from './components/in-macro-section';
+import { InMacroGroups, UnreadCount } from './components/in-macro-section';
/**
* External: accounts on outside messaging apps that bring conversations into
@@ -61,19 +61,19 @@ export function ExternalView() {
navigate({ route: externalRoute, params: {} }),
'external-view'
);
- const [inMacroOpen, setInMacroOpen] = createSignal(true);
- const inMacroSection = () => (
- (
+ fireAndForget(groups.refetch(), 'external-view')}
/>
);
+ const unread = () =>
+ (inMacro() ?? []).reduce((sum, group) => sum + group.unreadCount, 0);
const whatsappPage = () => (
<>
@@ -82,14 +82,22 @@ export function ExternalView() {
WhatsApp
-
+
{/* The top bar is desktop chrome; touch layouts title the page here. */}
-
+
WhatsApp
{/* Touch has no sidebar: the groups in Macro lead the page. */}
- {inMacroSection()}
+
@@ -114,18 +122,25 @@ export function ExternalView() {
- setGroupsOpen((open) => !open)}
onClick={openWhatsApp}
>
-
+
- WhatsApp
-
+ WhatsApp
+
+
+
+
+
+ {inMacroGroups()}
+
- {inMacroSection()}
diff --git a/apps/web/src/features/notifications/use-notification-updates.ts b/apps/web/src/features/notifications/use-notification-updates.ts
index 86257b3e859..03235771bf7 100644
--- a/apps/web/src/features/notifications/use-notification-updates.ts
+++ b/apps/web/src/features/notifications/use-notification-updates.ts
@@ -12,7 +12,6 @@ import {
refetchSoupEntity,
} from '@queries/soup/normalized-cache';
import { teamKeys } from '@queries/team/keys';
-import { invalidateWhatsappGroups } from '@queries/whatsapp-groups';
import { onCleanup } from 'solid-js';
import { match, P } from 'ts-pattern';
import { shareEntity } from '../access-requests/core/types';
@@ -155,9 +154,8 @@ export function handleNotificationUpdate(notification: UnifiedNotification) {
.with({ tag: 'call_started' }, () => {
refreshChannel(notification);
})
- .with({ tag: 'whatsapp_group_message' }, () => {
- fireAndForget(invalidateWhatsappGroups(), 'whatsapp-group.notification');
- })
+ // DSS's `whatsapp_changed` push already refreshes what an open page shows.
+ .with({ tag: 'whatsapp_group_message' }, () => {})
.with({ tag: 'new_email' }, () => {
refreshEmailThread(notification);
})
diff --git a/apps/web/src/features/whatsapp-group/AGENTS.md b/apps/web/src/features/whatsapp-group/AGENTS.md
index ba2c8794ccb..b0d8110ab65 100644
--- a/apps/web/src/features/whatsapp-group/AGENTS.md
+++ b/apps/web/src/features/whatsapp-group/AGENTS.md
@@ -36,6 +36,15 @@ lists belong to `features/whatsapp-linked` and `features/external-view`.
- Row actions are getters: `ChannelMessage` reads them once per row.
- Reads do not poll; DSS pushes `whatsapp_changed`, with one fallback
re-fetch 3 s after opening. Only in-flight sends poll their progress.
+- History imported after adding (`backfill` on the detail) lands older than
+ the rows shown; the view keeps its distance from the bottom when rows appear
+ above, and says "Importing history…" / "Waiting for … phone" until DSS
+ reports `done` or `partial`.
+- Images, video and audio play inline: `fileUrl` resolves the imported
+ document's presigned URL and `InboundMedia` hands it to Chat's
+ `MediaPreview` (or an audio player); `groupMessageData` keeps them out of
+ the document chips. DSS sends no dimensions, so images size on load.
+- Senders show their WhatsApp name (`imported_author`), Macro users included.
- Use backend limits for text, files, edits and deletes.
- Keep phone numbers and message bodies out of telemetry.
- Soup/search registration is deferred; External is the list entry point.
diff --git a/apps/web/src/features/whatsapp-group/core/group.ts b/apps/web/src/features/whatsapp-group/core/group.ts
index 70a0b17e2b2..27dfdbb1673 100644
--- a/apps/web/src/features/whatsapp-group/core/group.ts
+++ b/apps/web/src/features/whatsapp-group/core/group.ts
@@ -9,6 +9,15 @@ export type GroupSummary = {
/** False for viewers who can only read. */
canSend: boolean;
};
+/**
+ * Importing the chat's earlier messages from the owner's phone after it was
+ * added. Absent for groups added before imports existed.
+ */
+export type GroupBackfill = {
+ state: 'pending' | 'running' | 'waiting_for_phone' | 'done' | 'partial';
+ /** Messages the phone sent, including ones already shown. */
+ imported: number;
+};
export type GroupDetail = {
id: string;
name: string;
@@ -20,6 +29,7 @@ export type GroupDetail = {
lastReadMessageId?: string;
unreadCount: number;
members: { id: string; name: string; admin: boolean }[];
+ backfill?: GroupBackfill;
limits: {
textBytes: number;
attachmentBytes: number;
@@ -119,6 +129,13 @@ export function composerNote(group: GroupDetail): string {
.otherwise(() => 'Sending to WhatsApp is unavailable right now');
}
+/** "Message Test 11 as +1…": the composer says who is sending. */
+export function composerPlaceholder(group: GroupDetail): string {
+ return group.phone
+ ? `Message ${group.name} as ${group.phone}`
+ : `Message ${group.name}`;
+}
+
/** A send's outcome after DSS recorded it. */
export function recordedOutcome(
progress: SendProgress
@@ -160,3 +177,30 @@ function deliveryFailure(progress: SendProgress): string {
)
.otherwise(() => "WhatsApp didn't accept this message.");
}
+
+/** While history is still coming from the owner's phone; quiet once it settled. */
+export function backfillStatus(
+ backfill: GroupBackfill | undefined,
+ /** The import runs on the owner's phone; others are told whose. */
+ viewerOwns: boolean
+): string | undefined {
+ if (!backfill) return undefined;
+ return match(backfill.state)
+ .with(P.union('pending', 'running'), () => 'Importing history…')
+ .with('waiting_for_phone', () =>
+ viewerOwns
+ ? 'Waiting for your phone to import history'
+ : "Waiting for the owner's phone to import history"
+ )
+ .with(P.union('done', 'partial'), () => undefined)
+ .exhaustive();
+}
+
+/** Shown above the oldest message once the import stopped at its limit. */
+export function historyStartNote(
+ backfill: GroupBackfill | undefined
+): string | undefined {
+ return backfill?.state === 'partial'
+ ? 'Earlier messages stay in WhatsApp'
+ : undefined;
+}
diff --git a/apps/web/src/features/whatsapp-group/queries/capabilities.ts b/apps/web/src/features/whatsapp-group/queries/capabilities.ts
index a4aa4c0f04c..2e9869b1047 100644
--- a/apps/web/src/features/whatsapp-group/queries/capabilities.ts
+++ b/apps/web/src/features/whatsapp-group/queries/capabilities.ts
@@ -3,8 +3,8 @@ import { Telemetry } from '@macro-inc/observability';
import { queryReadyGate } from '@queries/gate';
import { useBinaryDocumentQuery } from '@queries/storage/binary-document';
import {
+ invalidateWhatsappGroup,
invalidateWhatsappGroupList,
- invalidateWhatsappGroups,
refreshWhatsappGroupTimeline,
useWhatsappGroupDeliveryQuery,
useWhatsappGroupQueries,
@@ -160,7 +160,7 @@ export function createWhatsAppGroupCapabilities(
() => api.stopSync(groupId()),
groupId()
);
- await invalidateWhatsappGroups();
+ invalidateWhatsappGroup(groupId());
},
};
}
diff --git a/apps/web/src/features/whatsapp-group/queries/production-api.ts b/apps/web/src/features/whatsapp-group/queries/production-api.ts
index 45edd8a13bd..decaa8906d7 100644
--- a/apps/web/src/features/whatsapp-group/queries/production-api.ts
+++ b/apps/web/src/features/whatsapp-group/queries/production-api.ts
@@ -145,6 +145,9 @@ export const whatsappGroupApi: WhatsAppGroupApi = {
'WhatsApp participant',
admin: person.admin,
})),
+ backfill: view.backfill
+ ? { state: view.backfill.state, imported: view.backfill.imported }
+ : undefined,
limits: {
textBytes: view.limits.text_limit_bytes,
attachmentBytes: view.limits.attachment_limit_bytes,
diff --git a/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.test.tsx b/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.test.tsx
index fc35f5e502f..6fe7304fae8 100644
--- a/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.test.tsx
+++ b/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.test.tsx
@@ -11,7 +11,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/solid-query';
import { err } from 'neverthrow';
import { afterEach, beforeEach, expect, it, vi } from 'vitest';
import { WhatsAppGroupProvider } from '../context/whatsapp-group-context';
-import { createFakeGroup, group } from '../tests/fake-capabilities';
+import { createFakeGroup, group, messages } from '../tests/fake-capabilities';
import { WhatsAppGroupView } from './whatsapp-group-view';
const mocks = vi.hoisted(() => ({
@@ -70,7 +70,11 @@ function mount(fake: ReturnType) {
+ Share
+
+ }
onConnect={connect}
/>
@@ -86,7 +90,10 @@ it('renders WhatsApp messages as channel rows with quotes and reactions', () =>
const fake = createFakeGroup();
const { share } = mount(fake);
expect(screen.getByText('Ana Ruiz')).toBeTruthy();
- expect(screen.getByText('Sending as +14155550142')).toBeTruthy();
+ // The composer says who is sending.
+ expect(mocks.composer?.input.placeholder).toBe(
+ 'Message Design Crit as +14155550142'
+ );
// WhatsApp's `*updated*` renders bold.
expect(screen.getByText('updated').className).toContain('font-bold');
expect(
@@ -184,3 +191,89 @@ it('offers actions on rows that rendered before the viewer could send', () => {
fireEvent.pointerEnter(row);
expect(screen.getByRole('button', { name: 'Reply' })).toBeTruthy();
});
+
+it('says while history imports and shows older messages as they land', () => {
+ const fake = createFakeGroup({
+ group: { ...group, backfill: { state: 'running', imported: 0 } },
+ messages: [messages[1]],
+ });
+ mount(fake);
+ expect(screen.getByText('WhatsApp · Importing history…')).toBeTruthy();
+ expect(screen.getByRole('status').textContent).toBe('Importing history…');
+
+ fake.setGroup({
+ ...group,
+ backfill: { state: 'waiting_for_phone', imported: 1 },
+ });
+ fake.setMessages(messages);
+ expect(screen.getByRole('status').textContent).toBe(
+ 'Waiting for your phone to import history'
+ );
+ const ids = [...document.querySelectorAll('[data-message-id]')].map((row) =>
+ row.getAttribute('data-message-id')
+ );
+ expect(ids).toEqual(['message-1', 'message-2']);
+
+ fake.setGroup({ ...group, backfill: { state: 'done', imported: 1 } });
+ expect(screen.queryByText(/Importing history|Waiting for/)).toBeNull();
+ expect(screen.getByText('WhatsApp').textContent).toBe('WhatsApp');
+
+ fake.setGroup({ ...group, backfill: { state: 'partial', imported: 500 } });
+ expect(screen.getByText('Earlier messages stay in WhatsApp')).toBeTruthy();
+});
+
+it('tells a shared viewer whose phone the import waits for', () => {
+ const fake = createFakeGroup({
+ group: {
+ ...group,
+ accessLevel: 'view',
+ canSend: false,
+ sendReason: 'no_account',
+ backfill: { state: 'waiting_for_phone', imported: 0 },
+ },
+ messages: [],
+ });
+ mount(fake);
+ expect(
+ screen.getAllByText(/Waiting for the owner's phone to import history/)
+ ).toHaveLength(2);
+ // Not "No messages yet" while history is still coming.
+ expect(screen.queryByText(/No messages yet/)).toBeNull();
+});
+
+it('plays imported images and voice notes inline, like Chat', () => {
+ const fake = createFakeGroup({
+ messages: [
+ {
+ ...messages[0],
+ body: '',
+ attachments: [
+ {
+ ordinal: 0,
+ state: 'ready',
+ fileName: 'photo.jpeg',
+ mime: 'image/jpeg',
+ documentId: 'document-photo',
+ },
+ {
+ ordinal: 1,
+ state: 'ready',
+ fileName: 'voice.ogg',
+ mime: 'audio/ogg',
+ documentId: 'document-voice',
+ },
+ ],
+ },
+ ],
+ });
+ mount(fake);
+ expect(
+ screen.getByRole('button', { name: 'Open image viewer' })
+ ).toBeTruthy();
+ const voice = screen.getByLabelText('voice.ogg');
+ expect(voice.getAttribute('src')).toBe(
+ 'https://files.example.test/document-voice'
+ );
+ // Not as document chips.
+ expect(screen.queryByText('photo.jpeg')).toBeNull();
+});
diff --git a/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.tsx b/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.tsx
index a27ff6a4d6a..e2d185f32f5 100644
--- a/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.tsx
+++ b/apps/web/src/features/whatsapp-group/views/whatsapp-group-view.tsx
@@ -9,6 +9,7 @@ import { DateDivider } from '@channel/Message/DateDivider';
import { NewDivider } from '@channel/Message/NewDivider';
import { SenderName } from '@channel/Message/SenderName';
import { MaybeMessageActionDrawerManager } from '@channel/Mobile/MessageActionDrawerManager';
+import { HeaderActionButton } from '@components/app/HeaderActionButton';
import { FloatRegionOrInline } from '@components/app/mobile/float-regions/FloatRegion';
import { StaticMarkdownContext } from '@core/component/LexicalMarkdown/component/core/StaticMarkdown';
import { toast } from '@core/component/Toast/Toast';
@@ -17,6 +18,8 @@ import type {
MessageActions,
} from '@core/messages/types';
import { fireAndForget } from '@core/util/fireAndForget';
+import UsersThreeIcon from '@phosphor/users-three.svg';
+import WhatsappIcon from '@phosphor/whatsapp-logo.svg';
import { Button, ConfirmDialog } from '@ui';
import {
createEffect,
@@ -24,17 +27,26 @@ import {
createSignal,
For,
type JSX,
+ mapArray,
onCleanup,
onMount,
Show,
} from 'solid-js';
import { InboundAttachmentPlaceholder } from '../components/inbound-attachment';
+import {
+ InboundMedia,
+ type InboundMediaFile,
+} from '../components/inbound-media';
import { useWhatsAppGroup } from '../context/whatsapp-group-context';
+import { type InboundAttachment, inlineMediaKind } from '../core/attachments';
import { whatsappToMarkdown } from '../core/formatting';
import {
+ backfillStatus,
canChangeMessage,
composerNote,
+ composerPlaceholder,
type GroupMessage,
+ historyStartNote,
} from '../core/group';
import { groupMessageData, senderKey } from '../core/message-data';
import {
@@ -59,10 +71,38 @@ function quotePreview(message: GroupMessage) {
return message.body || message.attachments[0]?.fileName || 'Attachment';
}
+/** A message's images, video and voice notes, played inline. */
+function MessageMedia(props: { attachments: InboundAttachment[] }) {
+ const source = useWhatsAppGroup();
+ const media = createMemo(() =>
+ props.attachments.flatMap((attachment) => {
+ const kind = inlineMediaKind(attachment);
+ return kind && attachment.documentId
+ ? [{ attachment, kind, documentId: attachment.documentId }]
+ : [];
+ })
+ );
+ const files = mapArray(media, (file) => {
+ const url = source.fileUrl(() => file.documentId);
+ return (): InboundMediaFile => ({
+ id: file.documentId,
+ kind: file.kind,
+ fileName: file.attachment.fileName,
+ url: url.data,
+ });
+ });
+ return (
+ 0}>
+ file())} />
+
+ );
+}
+
export function WhatsAppGroupView(props: {
userId?: string;
leading?: JSX.Element;
- onShare: () => void;
+ /** The Share control; the host owns the share dialog. */
+ share: JSX.Element;
onConnect: () => void;
}) {
const source = useWhatsAppGroup();
@@ -90,6 +130,10 @@ export function WhatsAppGroupView(props: {
let scroller: HTMLDivElement | undefined;
let alive = true;
let newest: string | undefined;
+ let oldest: string | undefined;
+ // Distance from the bottom at the last scroll, to hold the view in place
+ // when imported history lands above it.
+ let fromBottom = 0;
onCleanup(() => {
alive = false;
});
@@ -178,6 +222,28 @@ export function WhatsAppGroupView(props: {
markRead();
});
});
+ createEffect(() => {
+ const first = rows()[0]?.id;
+ const grewAbove = !!oldest && !!first && first !== oldest;
+ oldest = first;
+ if (!grewAbove || !scroller) return;
+ scroller.scrollTop =
+ scroller.scrollHeight - scroller.clientHeight - fromBottom;
+ });
+ const memberLabel = () => {
+ const count = source.group.data?.members.length;
+ if (count === undefined) return 'Members';
+ return count === 1 ? '1 member' : `${count} members`;
+ };
+ const importing = () =>
+ backfillStatus(
+ source.group.data?.backfill,
+ source.group.data?.accessLevel === 'owner'
+ );
+ const historyStart = () =>
+ source.hasOlder()
+ ? undefined
+ : historyStartNote(source.group.data?.backfill);
const older = async () => {
const height = scroller?.scrollHeight ?? 0;
const offset = scroller?.scrollTop ?? 0;
@@ -276,29 +342,32 @@ export function WhatsAppGroupView(props: {
class="flex h-full min-h-0 min-w-0 flex-col bg-panel text-ink touch:pt-(--mobile-content-inset-top)"
style={{ '--user-icon-width': '32px', '--message-padding-x': '16px' }}
>
-
+
{props.leading}
-
-
+
+
+
+
+
{source.group.data?.name ?? 'WhatsApp group'}
- WhatsApp
+
+
+
+ }
+ tooltip="WhatsApp members"
+ onClick={() => setRoster((value) => !value)}
+ />
+ {props.share}
- setRoster((value) => !value)}
- >
- Members
-
-
- Share
-
@@ -338,14 +407,12 @@ export function WhatsAppGroupView(props: {
role="log"
aria-label="WhatsApp messages"
onScroll={() => {
- if (
- scroller &&
+ if (!scroller) return;
+ fromBottom =
scroller.scrollHeight -
- scroller.scrollTop -
- scroller.clientHeight <
- 60
- )
- markRead();
+ scroller.scrollTop -
+ scroller.clientHeight;
+ if (fromBottom < 60) markRead();
}}
>
@@ -382,7 +449,21 @@ export function WhatsAppGroupView(props: {
-
+
+
+ {(note) => (
+
+ {note()}
+
+ )}
+
+
+
No messages yet. New WhatsApp messages will appear here.
@@ -452,6 +533,7 @@ export function WhatsAppGroupView(props: {
)}
{content}
+
0}>
@@ -504,9 +586,6 @@ export function WhatsAppGroupView(props: {
>
-
- {composerNote(group())}
-
{(target) => (
}
userId={userId()}
- onShare={share}
+ share={
+
+ }
onConnect={() => navigate({ route: externalRoute, params: {} })}
/>
diff --git a/apps/web/src/features/whatsapp-linked/AGENTS.md b/apps/web/src/features/whatsapp-linked/AGENTS.md
index 39a94444223..f45dad7edec 100644
--- a/apps/web/src/features/whatsapp-linked/AGENTS.md
+++ b/apps/web/src/features/whatsapp-linked/AGENTS.md
@@ -3,22 +3,29 @@
## What it is
Personal WhatsApp accounts linked as devices (External tab → WhatsApp): link an
-account by QR, list its groups, and add a group as its own shareable Macro
-entity. Each person sends from their own account. Behind the `enable-whatsapp-linked` flag.
+account by QR, list its WhatsApp chats, and add a group as its own shareable
+Macro entity. Each person sends from their own account. Behind the `enable-whatsapp-linked` flag.
## Start here
- `whatsapp-linked.tsx`: production wiring (shared queries + split navigation).
- `context/whatsapp-linked-context.tsx`: the capability contract tests fake.
-- `views/whatsapp-page.tsx`: account states, the Add to Macro and Can't be
- added sections, and the pairing/confirm dialogs.
+- `views/whatsapp-page.tsx`: account states, the header (search + account
+ strip), the Add to Macro and Can't be added sections (plus In Macro while
+ searching), and the pairing/confirm dialogs.
+- `components/chat-list.tsx`: one-line chat rows styled like Macro's list rows
+ (`bg-list-hover`, actions on hover/focus, always on touch).
+- `core/chat.ts`: chat sections, search matching and row wording.
## Scope
- Owns: the WhatsApp account page, pairing dialog and one-click adoption
(no dialog; DSS names the group after WhatsApp).
- Group timeline and sending: `features/whatsapp-group`; no channel integration.
-- Not here: the External tab shell, its In Macro sidebar and the
+- One account at a time: there is no replace flow; switching means
+ Disconnect, then Connect.
+- Not here: the External tab shell, the groups nested under WhatsApp in its
+ sidebar and the
`/external/whatsapp/:groupId` route → `features/external-view`;
HTTP → `lib/service-clients/service-storage/whatsapp-linked.ts`; shared
queries → `lib/queries/whatsapp-linked`; DSS routes → `crates/whatsapp_linked`.
@@ -37,6 +44,10 @@ entity. Each person sends from their own account. Behind the `enable-whatsapp-li
(`Linked*`); change `crates/whatsapp_linked` and regenerate, never hand-type.
- Adoption failures carry DSS's `LinkedError` code (`whatsappErrorResponse`);
`core/adopt.ts` words each one. Never show a catch-all message.
+- The chat list (`GET /meta/linked/chats`) arrives sorted by recent activity;
+ keep DSS's order. Sections follow its `group`/`shared`/`canAdd`/
+ `cannotAddReason` fields; direct chats are listed but not addable until DSS
+ says `canAdd`.
- Adoption grants access only to its owner; the generic Share dialog manages
later access. No special audience lists or WhatsApp membership requirement
for viewing.
diff --git a/apps/web/src/features/whatsapp-linked/components/account-card.tsx b/apps/web/src/features/whatsapp-linked/components/account-card.tsx
index 8aa62dc45e6..cc52e4f754a 100644
--- a/apps/web/src/features/whatsapp-linked/components/account-card.tsx
+++ b/apps/web/src/features/whatsapp-linked/components/account-card.tsx
@@ -1,4 +1,7 @@
-import { Button, Item } from '@ui';
+import DotsThreeIcon from '@phosphor/dots-three.svg';
+import LinkBreakIcon from '@phosphor/link-break.svg';
+import WhatsappIcon from '@phosphor/whatsapp-logo.svg';
+import { Button, Dropdown, Item } from '@ui';
import type { WhatsAppAccount } from '../core/account';
import { WhatsAppTile } from './whatsapp-tile';
@@ -42,42 +45,50 @@ export function ConnectCard(props: {
);
}
-/** The linked account and its Disconnect action. */
-export function AccountCard(props: {
+/**
+ * The linked account as a slim strip above the chat list: number, state, and
+ * a menu to disconnect it. One account at a time: to switch, disconnect and
+ * connect again.
+ */
+export function AccountStrip(props: {
account: WhatsAppAccount;
pending: boolean;
onDisconnect: () => void;
- onReplace: () => void;
}) {
return (
- -
-
-
- {props.account.phone ?? 'Your WhatsApp'}
- Connected · linked device
-
-
- Use a different account
-
-
-
-
-
+
+
+
+
+ {props.account.phone ?? 'Your WhatsApp'}
+
+
+
+
- Disconnect
-
-
-
+
+
+
+
+
+
+ Disconnect
+
+
+
+
+
);
}
diff --git a/apps/web/src/features/whatsapp-linked/components/chat-list.tsx b/apps/web/src/features/whatsapp-linked/components/chat-list.tsx
new file mode 100644
index 00000000000..471e16095bd
--- /dev/null
+++ b/apps/web/src/features/whatsapp-linked/components/chat-list.tsx
@@ -0,0 +1,257 @@
+import { formatRelativeDate } from '@core/util/time';
+import CaretDownIcon from '@phosphor/caret-down.svg';
+import PlusIcon from '@phosphor/plus.svg';
+import UserIcon from '@phosphor/user.svg';
+import UsersThreeIcon from '@phosphor/users-three.svg';
+import { Button, cn } from '@ui';
+import { CollapseTransition } from '@ui/components/CollapseTransition';
+import { createSignal, For, type JSX, Match, Show, Switch } from 'solid-js';
+import { cannotAddLabel, chatMetadata, type WhatsAppChat } from '../core/chat';
+
+/** A list heading, on the same 16px rail as the rows' icons. */
+export function ChatSectionHeading(props: { id: string; children: string }) {
+ return (
+
+ );
+}
+
+/**
+ * One line per chat, like Macro's other lists: icon, name, muted kind and
+ * last activity. `actions` show on hover or focus (always on touch); `status`
+ * stays visible.
+ */
+function ChatRow(props: {
+ chat: WhatsAppChat;
+ actions?: JSX.Element;
+ status?: JSX.Element;
+ error?: string;
+ /** Keep the actions visible, e.g. while an add is in flight. */
+ pinActions?: boolean;
+}) {
+ return (
+
+
+ }
+ >
+
+
+
+
+ {props.chat.name}
+
+
+
+
+
+ {props.error}
+
+
+
+
+
+
+
+ {props.actions}
+
+
+
+ {(at) => (
+
+ )}
+
+
+
+ );
+}
+
+/** Chats this viewer already added; they also live in External's sidebar. */
+export function InMacroChatList(props: {
+ chats: WhatsAppChat[];
+ onOpenGroup: (groupId: string) => void;
+}) {
+ return (
+
+
+ {(chat) => (
+
+
+ {(own) => (
+ props.onOpenGroup(own().groupId)}
+ >
+ Open
+
+ )}
+
+ }
+ />
+
+ )}
+
+
+ );
+}
+
+/**
+ * Chats the viewer can bring into Macro with one click, and ones someone
+ * already shared with them.
+ */
+export function AddableChatList(props: {
+ chats: WhatsAppChat[];
+ canAdd: boolean;
+ /** JIDs whose add is in flight. */
+ adding: ReadonlySet;
+ errors: Readonly>;
+ /** Shown when nothing is left to add. */
+ empty: string;
+ onAdd: (chat: WhatsAppChat) => void;
+ onOpenGroup: (groupId: string) => void;
+}) {
+ return (
+
+ );
+}
+
+/** Chats Macro can't hold yet, folded away with the reason for each. */
+export function UnsupportedChatList(props: {
+ chats: WhatsAppChat[];
+ /** Searching unfolds the list so matches show. */
+ forceOpen: boolean;
+}) {
+ const [open, setOpen] = createSignal(false);
+ const expanded = () => open() || props.forceOpen;
+ return (
+
+
+
+
+
+ {(chat) => (
+
+
+
+ )}
+
+
+
+
+ );
+}
diff --git a/apps/web/src/features/whatsapp-linked/components/group-list.tsx b/apps/web/src/features/whatsapp-linked/components/group-list.tsx
deleted file mode 100644
index a74220c745a..00000000000
--- a/apps/web/src/features/whatsapp-linked/components/group-list.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import CaretDownIcon from '@phosphor/caret-down.svg';
-import PlusIcon from '@phosphor/plus.svg';
-import { Avatar, Button, cn, Item } from '@ui';
-import { CollapseTransition } from '@ui/components/CollapseTransition';
-import { createSignal, For, type JSX, Match, Show, Switch } from 'solid-js';
-import {
- groupInitials,
- unsupportedReason,
- type WhatsAppGroup,
-} from '../core/group';
-
-function GroupRow(props: {
- group: WhatsAppGroup;
- children: JSX.Element;
- error?: string;
-}) {
- return (
- -
-
-
- {groupInitials(props.group.name)}
-
-
-
- {props.group.name}
-
- {props.group.memberCount === 1
- ? '1 member'
- : `${props.group.memberCount} members`}
-
-
-
- {props.error}
-
-
-
- {props.children}
-
- );
-}
-
-/**
- * Groups the viewer can bring into Macro with one click, and ones someone
- * already shared with them.
- */
-export function AddableGroupList(props: {
- groups: WhatsAppGroup[];
- canAdd: boolean;
- /** JIDs whose add is in flight. */
- adding: ReadonlySet;
- errors: Readonly>;
- onAdd: (group: WhatsAppGroup) => void;
- onOpenGroup: (groupId: string) => void;
-}) {
- return (
-
-
- Every WhatsApp group you can add is already in Macro.
-
- }
- >
- {(group) => (
-
-
- props.onAdd(group)}
- >
-
- {props.adding.has(group.jid) ? 'Adding…' : 'Add to Macro'}
-
- }
- >
-
- {(shared) => (
- props.onOpenGroup(shared().groupId)}
- >
-
- Shared with you by {shared().ownerName} ·
-
- Open
-
- )}
-
-
-
-
- )}
-
-
- );
-}
-
-/** Groups Macro can't hold, folded away with the reason for each. */
-export function UnsupportedGroupList(props: { groups: WhatsAppGroup[] }) {
- const [open, setOpen] = createSignal(false);
- return (
-
- setOpen((value) => !value)}
- >
- Can't be added ({props.groups.length})
-
-
-
-
-
- {(group) => (
-
-
-
- {group.unsupported
- ? unsupportedReason(group.unsupported)
- : undefined}
-
-
-
- )}
-
-
-
-
- );
-}
diff --git a/apps/web/src/features/whatsapp-linked/context/whatsapp-linked-context.tsx b/apps/web/src/features/whatsapp-linked/context/whatsapp-linked-context.tsx
index 24328983157..f4acf9eeea2 100644
--- a/apps/web/src/features/whatsapp-linked/context/whatsapp-linked-context.tsx
+++ b/apps/web/src/features/whatsapp-linked/context/whatsapp-linked-context.tsx
@@ -7,7 +7,7 @@ import {
} from 'solid-js';
import type { WhatsAppAccount } from '../core/account';
import type { AdoptFailure } from '../core/adopt';
-import type { WhatsAppGroup } from '../core/group';
+import type { WhatsAppChat } from '../core/chat';
import type { PairingStep, PasskeyChallenge } from '../core/pairing';
/** A server read as the WhatsApp page needs it; `data` is set once loaded. */
@@ -73,15 +73,18 @@ export type WhatsAppLinkedCapabilities = {
features: SourceRead<{ pairing: boolean; adoption: boolean }>;
/** The person's own account, `null` when they never connected one. */
account: SourceRead;
- /** Groups of the connected account; read only while `enabled`. */
- groups: (enabled: Accessor) => SourceRead;
+ /**
+ * The connected account's WhatsApp chat list, newest activity first; read
+ * only while `enabled`.
+ */
+ chats: (enabled: Accessor) => SourceRead;
/** The live step of one pairing, polled while it is open. */
pairing: (pairingId: Accessor) => SourceRead;
passkey: PasskeyCapability;
- /** `replace` retires the current identity for a different WhatsApp account. */
- connect: (replace: boolean) => ResultAsync;
+ /** One account at a time: switching means disconnecting first. */
+ connect: () => ResultAsync;
cancelPairing: (pairingId: string) => ResultAsync;
- /** Pairing finished: refresh the account and its groups. */
+ /** Pairing finished: refresh the account and its chats. */
pairingFinished: () => Promise;
disconnect: (
generation: number
diff --git a/apps/web/src/features/whatsapp-linked/core/chat.ts b/apps/web/src/features/whatsapp-linked/core/chat.ts
new file mode 100644
index 00000000000..4dc049b665a
--- /dev/null
+++ b/apps/web/src/features/whatsapp-linked/core/chat.ts
@@ -0,0 +1,71 @@
+/** Where a WhatsApp chat already is in Macro for this viewer. */
+export type InMacro =
+ | { kind: 'own'; groupId: string }
+ | { kind: 'shared'; groupId: string; ownerId: string; ownerName: string };
+
+/** A conversation in the connected account's WhatsApp chat list. */
+export type WhatsAppChat = {
+ jid: string;
+ kind: 'group' | 'direct';
+ /** WhatsApp's subject or contact name, or DSS's fallback; never empty. */
+ name: string;
+ /** Newest message WhatsApp reported, when known. */
+ lastActivityAt: string | undefined;
+ archived: boolean;
+ inMacro: InMacro | undefined;
+ /** "Add to Macro" works now. */
+ canAdd: boolean;
+ /** DSS's reason this chat can't be added, when it can't. */
+ cannotAddReason: string | undefined;
+};
+
+/**
+ * The WhatsApp page's three lists, in DSS's recent-activity order. `query`
+ * keeps the chats whose name matches.
+ */
+export function chatSections(chats: WhatsAppChat[], query = '') {
+ const visible = chats.filter((chat) => matchesChatQuery(chat, query));
+ return {
+ inMacro: visible.filter((chat) => chat.inMacro?.kind === 'own'),
+ /** Not yet in Macro for this viewer, or shared with them by someone else. */
+ addable: visible.filter(
+ (chat) =>
+ chat.inMacro?.kind !== 'own' &&
+ (chat.canAdd || chat.inMacro?.kind === 'shared')
+ ),
+ unsupported: visible.filter(
+ (chat) => !chat.inMacro && !chat.canAdd && !!chat.cannotAddReason
+ ),
+ };
+}
+
+const fold = (text: string) =>
+ text.normalize('NFD').replace(/\p{M}/gu, '').toLocaleLowerCase();
+
+/** Case- and accent-insensitive; a phone number matches with or without spacing. */
+export function matchesChatQuery(chat: WhatsAppChat, query: string): boolean {
+ const wanted = fold(query.trim());
+ if (!wanted) return true;
+ if (fold(chat.name).includes(wanted)) return true;
+ const digits = wanted.replace(/[\s()+-]/g, '');
+ return /^\d+$/.test(digits) && chat.name.replace(/\D/g, '').includes(digits);
+}
+
+/** DSS's refusal sentence, shortened for direct chats. */
+export function cannotAddLabel(chat: WhatsAppChat): string | undefined {
+ if (chat.kind === 'direct') return "Can't add direct chats yet";
+ const reason = chat.cannotAddReason;
+ return reason
+ ? `${reason.charAt(0).toUpperCase()}${reason.slice(1)}`
+ : undefined;
+}
+
+/** "Group", "Direct chat · Archived"; the row shows last activity apart. */
+export function chatMetadata(chat: WhatsAppChat): string {
+ return [
+ chat.kind === 'direct' ? 'Direct chat' : 'Group',
+ chat.archived ? 'Archived' : undefined,
+ ]
+ .filter(Boolean)
+ .join(' · ');
+}
diff --git a/apps/web/src/features/whatsapp-linked/core/core.test.ts b/apps/web/src/features/whatsapp-linked/core/core.test.ts
index 2270542f159..020bc9990a0 100644
--- a/apps/web/src/features/whatsapp-linked/core/core.test.ts
+++ b/apps/web/src/features/whatsapp-linked/core/core.test.ts
@@ -1,6 +1,5 @@
import { describe, expect, it } from 'vitest';
import { accountStatus, phoneFromJid } from './account';
-import { groupInitials } from './group';
import { formatCountdown, pairingStep, secondsLeft } from './pairing';
describe('pairingStep', () => {
@@ -70,10 +69,3 @@ describe('account', () => {
).toEqual({ kind: 'not-connected', reconnect: false });
});
});
-
-describe('group', () => {
- it('uses at most two letter initials', () => {
- expect(groupInitials('Launch War Room')).toBe('LW');
- expect(groupInitials('🎉 Design Crit')).toBe('DC');
- });
-});
diff --git a/apps/web/src/features/whatsapp-linked/core/group.ts b/apps/web/src/features/whatsapp-linked/core/group.ts
deleted file mode 100644
index 8f1d734ee55..00000000000
--- a/apps/web/src/features/whatsapp-linked/core/group.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { match } from 'ts-pattern';
-
-/** Where a WhatsApp group already is in Macro for this viewer. */
-export type InMacro =
- | { kind: 'own'; groupId: string }
- | { kind: 'shared'; groupId: string; ownerId: string; ownerName: string };
-
-/** A WhatsApp group the connected account belongs to. */
-export type WhatsAppGroup = {
- jid: string;
- /** WhatsApp's subject, or DSS's member-name fallback for unnamed groups. */
- name: string;
- memberCount: number;
- inMacro: InMacro | undefined;
- /** Why this group cannot be added, when it cannot. */
- unsupported: 'community' | 'disappearing' | undefined;
-};
-
-/** The WhatsApp page's two lists; groups already added live in External's sidebar. */
-export function groupSections(groups: WhatsAppGroup[]) {
- return {
- /** Not yet in Macro for this viewer, or shared with them by someone else. */
- addable: groups.filter(
- (group) => !group.unsupported && group.inMacro?.kind !== 'own'
- ),
- unsupported: groups.filter(
- (group) => group.unsupported && group.inMacro?.kind !== 'own'
- ),
- };
-}
-
-export function unsupportedReason(
- reason: NonNullable
-): string {
- return match(reason)
- .with('community', () => 'WhatsApp communities aren’t supported yet')
- .with('disappearing', () => 'Disappearing messages are on')
- .exhaustive();
-}
-
-/** Up to two initials from the words of a group name that start with a letter. */
-export function groupInitials(name: string): string {
- return name
- .split(/\s+/)
- .filter((word) => /^\p{L}/u.test(word))
- .slice(0, 2)
- .map((word) => word[0]?.toLocaleUpperCase() ?? '')
- .join('');
-}
diff --git a/apps/web/src/features/whatsapp-linked/primitives/pairing-flow.ts b/apps/web/src/features/whatsapp-linked/primitives/pairing-flow.ts
index bd1e46f3aa5..9121023a85b 100644
--- a/apps/web/src/features/whatsapp-linked/primitives/pairing-flow.ts
+++ b/apps/web/src/features/whatsapp-linked/primitives/pairing-flow.ts
@@ -15,7 +15,7 @@ export type PairingFlow = {
secondsLeft: Accessor;
/** Starting a pairing failed before any dialog opened. */
startFailed: Accessor;
- start: (replace: boolean) => Promise;
+ start: () => Promise;
/** Shows a pairing started elsewhere, e.g. handed off to Macro desktop. */
resume: (pairingId: string) => void;
pairingId: Accessor;
@@ -41,7 +41,6 @@ export function createPairingFlow(
>
): PairingFlow {
const [current, setCurrent] = createSignal();
- const [replacing, setReplacing] = createSignal(false);
const [startFailed, setStartFailed] = createSignal(false);
const [handedOff, setHandedOff] = createSignal(false);
const [passkey, setPasskey] = createSignal({
@@ -52,9 +51,7 @@ export function createPairingFlow(
() => current()?.expiresAt ?? poll.data?.expiresAt
);
- // While replacing, the old account still reads linked; only the new
- // pairing's own success counts.
- const linkedByAccount = () => !replacing() && accountLinked();
+ const linkedByAccount = accountLinked;
const step = (): PairingStep => {
const polled = poll.data?.step ?? { kind: 'preparing' };
// The deadline is the server's; once it passes, a stale QR is not scannable.
@@ -81,10 +78,9 @@ export function createPairingFlow(
)
);
- const start = async (replace: boolean) => {
+ const start = async () => {
setStartFailed(false);
- setReplacing(replace);
- const started = await capabilities.connect(replace);
+ const started = await capabilities.connect();
if (started.isErr()) {
setStartFailed(true);
return;
@@ -139,7 +135,6 @@ export function createPairingFlow(
startFailed,
start,
resume: (pairingId) => {
- setReplacing(false);
setHandedOff(false);
setPasskey({ kind: 'idle' });
setCurrent({ pairingId });
@@ -148,7 +143,7 @@ export function createPairingFlow(
passkey,
handOff: () => setHandedOff(true),
confirmPasskey,
- retry: () => start(replacing()),
+ retry: start,
cancel,
};
}
diff --git a/apps/web/src/features/whatsapp-linked/queries/decode.ts b/apps/web/src/features/whatsapp-linked/queries/decode.ts
index aed0dc22865..484d6e27f13 100644
--- a/apps/web/src/features/whatsapp-linked/queries/decode.ts
+++ b/apps/web/src/features/whatsapp-linked/queries/decode.ts
@@ -1,11 +1,12 @@
import { ThrownResultError } from '@core/util/result';
import type { LinkedAccount } from '@service-storage/generated/schemas/linkedAccount';
-import type { LinkedGroupInfo } from '@service-storage/generated/schemas/linkedGroupInfo';
+import type { LinkedChat } from '@service-storage/generated/schemas/linkedChat';
+import type { LinkedChats } from '@service-storage/generated/schemas/linkedChats';
import type { LinkedPairState } from '@service-storage/generated/schemas/linkedPairState';
import { match } from 'ts-pattern';
import { phoneFromJid, type WhatsAppAccount } from '../core/account';
import type { AdoptRefusal } from '../core/adopt';
-import type { WhatsAppGroup } from '../core/group';
+import type { WhatsAppChat } from '../core/chat';
import { type PairingStep, pairingStep } from '../core/pairing';
export function decodeAccount(
@@ -22,29 +23,28 @@ export function decodeAccount(
}
/** `ownerName` resolves a Macro user id; production reads the shared name cache. */
-export function decodeGroup(
- group: LinkedGroupInfo,
+export function decodeChat(
+ chat: LinkedChat,
ownerName: (ownerId: string) => string
-): WhatsAppGroup {
+): WhatsAppChat {
return {
- jid: group.jid,
- name: group.name,
- memberCount: group.participants.length,
- inMacro: group.group
- ? { kind: 'own', groupId: group.group.id }
- : group.shared
+ jid: chat.jid,
+ kind: chat.kind,
+ name: chat.name,
+ lastActivityAt: chat.lastActivityAt ?? undefined,
+ archived: chat.archived,
+ inMacro: chat.group
+ ? { kind: 'own', groupId: chat.group.id }
+ : chat.shared
? {
kind: 'shared',
- groupId: group.shared.id,
- ownerId: group.shared.owner_id,
- ownerName: ownerName(group.shared.owner_id),
+ groupId: chat.shared.id,
+ ownerId: chat.shared.owner_id,
+ ownerName: ownerName(chat.shared.owner_id),
}
: undefined,
- unsupported: group.community
- ? 'community'
- : group.disappearing
- ? 'disappearing'
- : undefined,
+ canAdd: chat.canAdd,
+ cannotAddReason: chat.cannotAddReason ?? undefined,
};
}
@@ -72,14 +72,12 @@ export function decodeAdoptRefusal(error: unknown): AdoptRefusal {
.otherwise(() => ({ reason: 'unavailable' }));
}
-/** By name, so adding a group or a refetch never moves a row. */
-export function decodeGroups(
- groups: LinkedGroupInfo[],
+/** DSS's order (newest activity first) is kept. */
+export function decodeChats(
+ chats: LinkedChats,
ownerName: (ownerId: string) => string
-): WhatsAppGroup[] {
- return groups
- .map((group) => decodeGroup(group, ownerName))
- .sort((a, b) => a.name.localeCompare(b.name));
+): WhatsAppChat[] {
+ return chats.chats.map((chat) => decodeChat(chat, ownerName));
}
export function decodePairing(state: LinkedPairState): {
diff --git a/apps/web/src/features/whatsapp-linked/queries/production-capabilities.ts b/apps/web/src/features/whatsapp-linked/queries/production-capabilities.ts
index 323d82d70d8..c363a48e8c1 100644
--- a/apps/web/src/features/whatsapp-linked/queries/production-capabilities.ts
+++ b/apps/web/src/features/whatsapp-linked/queries/production-capabilities.ts
@@ -12,8 +12,8 @@ import {
useDisconnectWhatsappMutation,
useSubmitWhatsappPasskeyMutation,
useWhatsappLinkedAccountQuery,
+ useWhatsappLinkedChatsQuery,
useWhatsappLinkedConfigurationQuery,
- useWhatsappLinkedGroupsQuery,
useWhatsappLinkedPairingQuery,
} from '@queries/whatsapp-linked';
import {
@@ -31,7 +31,7 @@ import type {
} from '../context/whatsapp-linked-context';
import { accountStatus, type WhatsAppAccount } from '../core/account';
import type { AdoptFailure } from '../core/adopt';
-import type { WhatsAppGroup } from '../core/group';
+import type { WhatsAppChat } from '../core/chat';
import {
authenticateWhatsAppPasskey,
canAuthenticatePasskey,
@@ -40,7 +40,7 @@ import {
import {
decodeAccount,
decodeAdoptRefusal,
- decodeGroups,
+ decodeChats,
decodePairing,
} from './decode';
@@ -67,24 +67,26 @@ function sourceRead(
};
}
-/** The page has loaded once the account, and a connected account's groups, have. */
+/** The page has loaded once the account, and a connected account's chats, have. */
function pageLoad(
account: SourceRead,
- groups: SourceRead | undefined
+ chats: SourceRead | undefined
): WhatsappLoadResult | undefined {
if (account.isError) return { outcome: 'error' };
if (account.data === undefined) return;
if (accountStatus(account.data).kind !== 'connected')
return { outcome: 'success', attrs: { 'whatsapp.connected': false } };
- if (groups?.isError) return { outcome: 'error' };
- const list = groups?.data;
+ if (chats?.isError) return { outcome: 'error' };
+ const list = chats?.data;
if (!list) return;
return {
outcome: 'success',
attrs: {
'whatsapp.connected': true,
- 'whatsapp.groups.count': list.length,
- 'whatsapp.groups.in_macro': list.filter((group) => group.inMacro).length,
+ 'whatsapp.chats.count': list.length,
+ 'whatsapp.chats.direct': list.filter((chat) => chat.kind === 'direct')
+ .length,
+ 'whatsapp.chats.in_macro': list.filter((chat) => chat.inMacro).length,
},
};
}
@@ -123,26 +125,25 @@ export function createWhatsAppLinkedCapabilities(host: {
useWhatsappLinkedAccountQuery(currentUser),
(view) => decodeAccount(view.account)
);
- const [groupsRead, setGroupsRead] =
- createSignal>();
- traceWhatsappLoad('page.load', () => pageLoad(account, groupsRead()));
+ const [chatsRead, setChatsRead] = createSignal>();
+ traceWhatsappLoad('page.load', () => pageLoad(account, chatsRead()));
return {
features: sourceRead(useWhatsappLinkedConfigurationQuery(), (features) => ({
pairing: features.pairing,
adoption: features.adoption,
})),
account,
- groups: (enabled: Accessor) => {
+ chats: (enabled: Accessor) => {
const read = sourceRead(
- useWhatsappLinkedGroupsQuery(currentUser, enabled),
- (groups) =>
- decodeGroups(groups, (ownerId) =>
+ useWhatsappLinkedChatsQuery(currentUser, enabled),
+ (chats) =>
+ decodeChats(chats, (ownerId) =>
isMacroId(ownerId)
? getDisplayName(ownerId) || 'a teammate'
: 'a teammate'
)
);
- setGroupsRead(() => read);
+ setChatsRead(() => read);
return read;
},
passkey,
@@ -151,8 +152,8 @@ export function createWhatsAppLinkedCapabilities(host: {
useWhatsappLinkedPairingQuery(currentUser, pairingId),
decodePairing
),
- connect: (replace) =>
- ResultAsync.fromPromise(connect.mutateAsync(replace), failure).map(
+ connect: () =>
+ ResultAsync.fromPromise(connect.mutateAsync(), failure).map(
(pairing) => ({ pairingId: pairing.id, expiresAt: pairing.expires_at })
),
cancelPairing: (pairingId) =>
diff --git a/apps/web/src/features/whatsapp-linked/tests/fake-capabilities.ts b/apps/web/src/features/whatsapp-linked/tests/fake-capabilities.ts
index 297a719ad7f..c1bb0edfb63 100644
--- a/apps/web/src/features/whatsapp-linked/tests/fake-capabilities.ts
+++ b/apps/web/src/features/whatsapp-linked/tests/fake-capabilities.ts
@@ -10,7 +10,7 @@ import type {
} from '../context/whatsapp-linked-context';
import type { WhatsAppAccount } from '../core/account';
import type { AdoptFailure } from '../core/adopt';
-import type { WhatsAppGroup } from '../core/group';
+import type { WhatsAppChat } from '../core/chat';
import type { PairingStep } from '../core/pairing';
function signalRead(
@@ -35,13 +35,13 @@ function signalRead(
/** Server state a test drives by setting signals; actions are spies. */
export function createFakeWhatsApp(initial: {
account: WhatsAppAccount | null;
- groups?: WhatsAppGroup[];
+ chats?: WhatsAppChat[];
passkey?: PasskeyCapability;
}) {
const [account, setAccount] = signalRead(
initial.account
);
- const [groups, setGroups] = signalRead(initial.groups);
+ const [chats, setChats] = signalRead(initial.chats);
const [features] = signalRead({ pairing: true, adoption: true });
const [pairing, setPairingRead] = signalRead(undefined);
const setPairing = (step: PairingStep, expiresAt?: string) =>
@@ -49,13 +49,13 @@ export function createFakeWhatsApp(initial: {
step,
expiresAt: expiresAt ?? new Date(Date.now() + 52_000).toISOString(),
});
- const groupsEnabled: Accessor[] = [];
+ const chatsEnabled: Accessor[] = [];
const capabilities = {
features,
account,
- groups: vi.fn((enabled: Accessor) => {
- groupsEnabled.push(enabled);
- return groups;
+ chats: vi.fn((enabled: Accessor) => {
+ chatsEnabled.push(enabled);
+ return chats;
}),
passkey: initial.passkey ?? {
kind: 'handoff',
@@ -64,9 +64,7 @@ export function createFakeWhatsApp(initial: {
},
pairing: vi.fn((_pairingId: Accessor) => pairing),
connect: vi.fn(
- (
- _replace: boolean
- ): ResultAsync<
+ (): ResultAsync<
{ pairingId: string; expiresAt: string },
RequestFailure
> =>
@@ -94,5 +92,5 @@ export function createFakeWhatsApp(initial: {
isDisconnecting: () => false,
openGroup: vi.fn(),
} satisfies WhatsAppLinkedCapabilities;
- return { capabilities, setAccount, setGroups, setPairing, groupsEnabled };
+ return { capabilities, setAccount, setChats, setPairing, chatsEnabled };
}
diff --git a/apps/web/src/features/whatsapp-linked/views/whatsapp-page.test.tsx b/apps/web/src/features/whatsapp-linked/views/whatsapp-page.test.tsx
index 0ecb7466594..1d6802d610b 100644
--- a/apps/web/src/features/whatsapp-linked/views/whatsapp-page.test.tsx
+++ b/apps/web/src/features/whatsapp-linked/views/whatsapp-page.test.tsx
@@ -49,39 +49,59 @@ const dialogOpen = () =>
.queryAllByRole('dialog')
.some((dialog) => !dialog.hasAttribute('data-closed'));
-const groups = [
+const chat = {
+ kind: 'group' as const,
+ lastActivityAt: undefined,
+ archived: false,
+ inMacro: undefined,
+ canAdd: true,
+ cannotAddReason: undefined,
+};
+
+/** DSS's order: newest activity first. */
+const chats = [
{
+ ...chat,
+ jid: '14155550199@s.whatsapp.net',
+ kind: 'direct' as const,
+ name: 'Ana Ruiz',
+ lastActivityAt: '2025-03-07T10:00:00Z',
+ canAdd: false,
+ cannotAddReason: "direct chats can't be added to Macro yet",
+ },
+ {
+ ...chat,
jid: '120363001@g.us',
name: 'Design Crit',
- memberCount: 14,
+ lastActivityAt: '2025-03-06T10:00:00Z',
inMacro: { kind: 'own' as const, groupId: 'group-design' },
- unsupported: undefined,
+ canAdd: false,
},
{
+ ...chat,
jid: '120363003@g.us',
name: 'Launch War Room',
- memberCount: 23,
- inMacro: undefined,
- unsupported: undefined,
+ lastActivityAt: '2025-03-05T10:00:00Z',
},
{
+ ...chat,
jid: '120363004@g.us',
name: 'Ana, Ben, +2',
- memberCount: 4,
inMacro: {
kind: 'shared' as const,
groupId: 'group-family',
ownerId: 'macro|ana@example.test',
ownerName: 'Ana Silva',
},
- unsupported: undefined,
+ canAdd: false,
},
{
+ ...chat,
jid: '120363005@g.us',
name: 'Neighbourhood',
- memberCount: 120,
- inMacro: undefined,
- unsupported: 'community' as const,
+ archived: true,
+ canAdd: false,
+ cannotAddReason: "community groups can't be added to Macro",
},
];
@@ -95,10 +115,10 @@ describe('not connected', () => {
expect(
screen.getByText(/unofficial WhatsApp client/, { exact: false })
).toBeTruthy();
- expect(fake.groupsEnabled[0]?.()).toBe(false);
+ expect(fake.chatsEnabled[0]?.()).toBe(false);
fireEvent.click(screen.getByRole('button', { name: 'Connect' }));
- expect(fake.capabilities.connect).toHaveBeenCalledWith(false);
+ expect(fake.capabilities.connect).toHaveBeenCalledOnce();
const dialog = within(await screen.findByRole('dialog'));
expect(dialog.getByText('Link WhatsApp')).toBeTruthy();
expect(dialog.getByText('Preparing code…')).toBeTruthy();
@@ -186,60 +206,63 @@ describe('not connected', () => {
});
describe('connected', () => {
- it('links a different account only after confirming the replacement', async () => {
- const fake = createFakeWhatsApp({
- account: { generation: 3, phone: '+14155550142', health: 'connected' },
- groups,
- });
- mount(fake);
-
- fireEvent.click(
- screen.getByRole('button', { name: 'Use a different account' })
- );
- expect(fake.capabilities.connect).not.toHaveBeenCalled();
- const confirm = within(await screen.findByRole('dialog'));
- fireEvent.click(
- confirm.getByRole('button', { name: 'Link another account' })
- );
- await waitFor(() =>
- expect(fake.capabilities.connect).toHaveBeenCalledWith(true)
- );
- expect(await screen.findByText('Link WhatsApp')).toBeTruthy();
- // The old account still reads linked; only the new pairing closes it.
- expect(dialogOpen()).toBe(true);
- });
-
- it('lists groups to add, opens shared ones, and disconnects after confirming', async () => {
+ it('lists chats to add by recent activity, opens shared ones, and disconnects after confirming', async () => {
const fake = createFakeWhatsApp({
account: { generation: 3, phone: '+14155550142', health: 'connected' },
- groups,
+ chats,
});
mount(fake);
expect(screen.getByText('+14155550142')).toBeTruthy();
- expect(screen.getByText('Connected · linked device')).toBeTruthy();
- expect(fake.groupsEnabled[0]?.()).toBe(true);
+ expect(screen.getByText('Connected')).toBeTruthy();
+ expect(fake.chatsEnabled[0]?.()).toBe(true);
+ // Added chats live in External's sidebar until a search finds them.
+ expect(
+ screen.queryByRole('list', { name: 'WhatsApp chats in Macro' })
+ ).toBeNull();
+
const list = within(
screen.getByRole('list', { name: 'Groups to add to Macro' })
);
- // Groups already in Macro live in External's sidebar, not here.
expect(list.queryByText('Design Crit')).toBeNull();
- expect(list.getByText('23 members')).toBeTruthy();
+ expect(list.getAllByRole('listitem').map((row) => row.textContent)).toEqual(
+ [
+ 'Launch War RoomGroupAdd to MacroMar 5, 2025',
+ 'Ana, Ben, +2GroupShared with you by Ana SilvaOpen',
+ ]
+ );
fireEvent.click(
- list.getByRole('button', { name: /Shared with you by Ana Silva/ })
+ list.getByRole('button', { name: /shared with you by Ana Silva/i })
);
expect(fake.capabilities.openGroup).toHaveBeenCalledWith('group-family');
expect(screen.queryByText('Neighbourhood')).toBeNull();
fireEvent.click(
- screen.getByRole('button', { name: /Can't be added \(1\)/ })
+ screen.getByRole('button', { name: /Can't be added \(2\)/ })
+ );
+ const unsupported = within(
+ screen.getByRole('list', { name: "Can't be added" })
+ );
+ const direct = within(
+ unsupported.getByText('Ana Ruiz').closest('li') as HTMLElement
);
- expect(await screen.findByText('Neighbourhood')).toBeTruthy();
+ expect(direct.getByText('Direct chat')).toBeTruthy();
+ expect(direct.getByText('Mar 7, 2025')).toBeTruthy();
+ expect(direct.getByText("Can't add direct chats yet")).toBeTruthy();
+ expect(direct.queryByRole('button')).toBeNull();
expect(
- screen.getByText('WhatsApp communities aren’t supported yet')
+ unsupported.getByText("Community groups can't be added to Macro")
).toBeTruthy();
+ expect(unsupported.getByText('Group · Archived')).toBeTruthy();
- fireEvent.click(screen.getByRole('button', { name: 'Disconnect' }));
+ fireEvent.keyDown(
+ screen.getByRole('button', { name: 'WhatsApp account options' }),
+ { key: 'Enter' }
+ );
+ fireEvent.keyDown(
+ await screen.findByRole('menuitem', { name: 'Disconnect' }),
+ { key: 'Enter' }
+ );
const confirm = within(await screen.findByRole('dialog'));
expect(confirm.getByText('Disconnect WhatsApp?')).toBeTruthy();
fireEvent.click(confirm.getByRole('button', { name: 'Disconnect' }));
@@ -253,10 +276,62 @@ describe('connected', () => {
expect(screen.getByRole('button', { name: 'Connect' })).toBeTruthy();
});
+ it('searches every section, added chats included, by name or phone digits', async () => {
+ const fake = createFakeWhatsApp({
+ account: { generation: 3, phone: '+14155550142', health: 'connected' },
+ chats: [
+ ...chats,
+ {
+ ...chat,
+ jid: '14155550123@s.whatsapp.net',
+ kind: 'direct' as const,
+ name: '+1 415-555-0123',
+ canAdd: false,
+ cannotAddReason: "direct chats can't be added to Macro yet",
+ },
+ ],
+ });
+ mount(fake);
+
+ const search = screen.getByRole('searchbox', {
+ name: 'Search WhatsApp chats',
+ });
+ fireEvent.input(search, { target: { value: 'design' } });
+ const inMacro = within(
+ screen.getByRole('list', { name: 'WhatsApp chats in Macro' })
+ );
+ fireEvent.click(inMacro.getByRole('button', { name: 'Open' }));
+ expect(fake.capabilities.openGroup).toHaveBeenCalledWith('group-design');
+
+ fireEvent.input(search, { target: { value: 'ana' } });
+ const list = within(
+ screen.getByRole('list', { name: 'Groups to add to Macro' })
+ );
+ expect(list.getByText('Ana, Ben, +2')).toBeTruthy();
+ expect(list.queryByText('Launch War Room')).toBeNull();
+ expect(
+ screen.queryByRole('list', { name: 'WhatsApp chats in Macro' })
+ ).toBeNull();
+ // Matches in the folded section show without unfolding it.
+ expect(
+ screen
+ .getByRole('button', { name: /Can't be added \(1\)/ })
+ .getAttribute('aria-expanded')
+ ).toBe('true');
+ expect(screen.getByText('Ana Ruiz')).toBeTruthy();
+
+ fireEvent.input(search, { target: { value: '4155550123' } });
+ expect(screen.getByText('+1 415-555-0123')).toBeTruthy();
+ expect(screen.queryByText('Ana Ruiz')).toBeNull();
+
+ fireEvent.input(search, { target: { value: 'nothing like it' } });
+ expect(screen.getByText('No chats to add match your search.')).toBeTruthy();
+ });
+
it('adds a group in one click, without a dialog', async () => {
const fake = createFakeWhatsApp({
account: { generation: 3, phone: '+14155550142', health: 'connected' },
- groups,
+ chats,
});
mount(fake);
@@ -270,7 +345,7 @@ describe('connected', () => {
it('says exactly why adding failed, on the group it failed for', async () => {
const fake = createFakeWhatsApp({
account: { generation: 3, phone: '+14155550142', health: 'connected' },
- groups,
+ chats,
});
fake.capabilities.adopt.mockReturnValueOnce(
errAsync({ kind: 'adopt-failed', reason: 'disconnected' })
diff --git a/apps/web/src/features/whatsapp-linked/views/whatsapp-page.tsx b/apps/web/src/features/whatsapp-linked/views/whatsapp-page.tsx
index a83ae27955c..0f5aab2fdbd 100644
--- a/apps/web/src/features/whatsapp-linked/views/whatsapp-page.tsx
+++ b/apps/web/src/features/whatsapp-linked/views/whatsapp-page.tsx
@@ -1,22 +1,25 @@
+import { SearchBar } from '@app/components/view-shell';
import { fireAndForget } from '@core/util/fireAndForget';
import { Button, ConfirmDialog } from '@ui';
-import { createSignal, Match, onMount, Show, Switch } from 'solid-js';
+import { createSignal, type JSX, Match, onMount, Show, Switch } from 'solid-js';
import { match } from 'ts-pattern';
-import { AccountCard, ConnectCard } from '../components/account-card';
+import { AccountStrip, ConnectCard } from '../components/account-card';
import {
- AddableGroupList,
- UnsupportedGroupList,
-} from '../components/group-list';
+ AddableChatList,
+ ChatSectionHeading,
+ InMacroChatList,
+ UnsupportedChatList,
+} from '../components/chat-list';
import { PairingDialog, type PasskeyMode } from '../components/pairing-dialog';
import { useWhatsAppLinked } from '../context/whatsapp-linked-context';
import { accountStatus } from '../core/account';
import { adoptFailureMessage } from '../core/adopt';
-import { groupSections, type WhatsAppGroup } from '../core/group';
+import { chatSections, type WhatsAppChat } from '../core/chat';
import { createPairingFlow } from '../primitives/pairing-flow';
function Notice(props: { children: string }) {
return (
-
+
{props.children}
);
@@ -24,7 +27,7 @@ function Notice(props: { children: string }) {
function LoadFailure(props: { what: string; onRetry: () => void }) {
return (
-
+
Couldn't load {props.what}.
Try again
@@ -33,9 +36,22 @@ function LoadFailure(props: { what: string; onRetry: () => void }) {
);
}
+function ChatSection(props: {
+ id: string;
+ title: string;
+ children: JSX.Element;
+}) {
+ return (
+
+ {props.title}
+ {props.children}
+
+ );
+}
+
/**
- * The External tab's WhatsApp page: link an account, then add its groups.
- * Groups already in Macro are listed in External's sidebar.
+ * The External tab's WhatsApp page: link an account, then add its chats from
+ * WhatsApp's chat list, newest activity first.
*/
export function WhatsAppPage(props: {
/** A pairing to show at once, handed off by id from another device. */
@@ -55,7 +71,8 @@ export function WhatsAppPage(props: {
return current?.kind === 'not-connected' ? current : undefined;
};
const connected = () => linked() !== undefined;
- const groups = whatsapp.groups(connected);
+ const chats = whatsapp.chats(connected);
+ const [query, setQuery] = createSignal('');
const pairing = createPairingFlow(connected, whatsapp);
// A pairing handed off from a browser opens here in Macro desktop.
onMount(() => {
@@ -75,7 +92,6 @@ export function WhatsAppPage(props: {
.exhaustive();
};
const [confirmingDisconnect, setConfirmingDisconnect] = createSignal(false);
- const [confirmingReplace, setConfirmingReplace] = createSignal(false);
const [notice, setNotice] = createSignal();
const [adding, setAdding] = createSignal>(new Set());
const [addErrors, setAddErrors] = createSignal>({});
@@ -104,24 +120,24 @@ export function WhatsAppPage(props: {
else next.delete(jid);
return next;
});
- const adopt = async (group: WhatsAppGroup) => {
- if (adding().has(group.jid)) return;
- setAddErrors(({ [group.jid]: _previous, ...rest }) => rest);
- setPending(group.jid, true);
- const result = await whatsapp.adopt(group.jid);
- setPending(group.jid, false);
+ const adopt = async (chat: WhatsAppChat) => {
+ if (adding().has(chat.jid)) return;
+ setAddErrors(({ [chat.jid]: _previous, ...rest }) => rest);
+ setPending(chat.jid, true);
+ const result = await whatsapp.adopt(chat.jid);
+ setPending(chat.jid, false);
if (result.isErr())
setAddErrors((current) => ({
...current,
- [group.jid]: adoptFailureMessage(result.error),
+ [chat.jid]: adoptFailureMessage(result.error),
}));
};
return (
-
+
-
+
Loading your WhatsApp connection…
@@ -134,56 +150,89 @@ export function WhatsAppPage(props: {
{(current) => (
<>
- setConfirmingDisconnect(true)}
- onReplace={() => setConfirmingReplace(true)}
- />
-
- Couldn't start linking WhatsApp. Try again.
-
- {(text) => {text()} }
+
+
+
+
+
setConfirmingDisconnect(true)}
+ />
+
+
+
+ Couldn't start linking WhatsApp. Try again.
+
+
+ {(text) => {text()} }
+
+
-
- {(list) => (
- <>
-
-
+ {(list) => {
+ const sections = () => chatSections(list(), query());
+ const searching = () => query().trim() !== '';
+ return (
+ <>
+ {/* External's sidebar (or the phone's drill-in list)
+ already lists added chats; here only search hits. */}
+
+
+
+
+
+
- Add to Macro
-
-
- fireAndForget(adopt(group), 'whatsapp-linked.adopt')
- }
- onOpenGroup={whatsapp.openGroup}
- />
-
-
-
-
- >
- )}
+
+ fireAndForget(
+ adopt(chat),
+ 'whatsapp-linked.adopt'
+ )
+ }
+ onOpenGroup={whatsapp.openGroup}
+ />
+
+
+
+
+ >
+ );
+ }}
-
-
- Loading groups…
+
+
+ Loading chats…
-
-
+
+
disconnect(current().account.generation)}
/>
- {
- setConfirmingReplace(false);
- fireAndForget(pairing.start(true), 'whatsapp-linked.replace');
- }}
- />
>
)}
{(current) => (
-
+
pairing.start(false)}
+ onConnect={() => pairing.start()}
/>
Couldn't start linking WhatsApp. Try again.
diff --git a/apps/web/src/lib/queries/access-requests/requests.ts b/apps/web/src/lib/queries/access-requests/requests.ts
index d709b371b38..f260a59bfa2 100644
--- a/apps/web/src/lib/queries/access-requests/requests.ts
+++ b/apps/web/src/lib/queries/access-requests/requests.ts
@@ -14,7 +14,7 @@ import { refreshActiveGraphqlSoupQueries } from '../soup/graphql/active-queries'
import { soupKeys } from '../soup/keys';
import { invalidateAllSoup } from '../soup/normalized-cache';
import { databasesKeys, entityKeys } from '../storage/keys';
-import { invalidateWhatsappGroups } from '../whatsapp-groups';
+import { invalidateWhatsappGroup } from '../whatsapp-groups';
import { accessRequestKeys } from './keys';
export function fetchAccessRequestState(entity: ShareEntity, offset = 0) {
@@ -51,7 +51,7 @@ export function invalidateAccessRequests(entity: ShareEntity) {
export function refreshSharedAccess(entity: ShareEntity) {
fireAndForget(invalidateAccessRequests(entity), 'access-requests');
if (entity.entityType === 'whatsapp_group') {
- fireAndForget(invalidateWhatsappGroups(), 'access-requests');
+ invalidateWhatsappGroup(entity.entityId);
return;
}
// Permissions change list membership even when the item was never cached.
diff --git a/apps/web/src/lib/queries/whatsapp-groups/index.ts b/apps/web/src/lib/queries/whatsapp-groups/index.ts
index 0ed25a46245..4c3fdfacbe8 100644
--- a/apps/web/src/lib/queries/whatsapp-groups/index.ts
+++ b/apps/web/src/lib/queries/whatsapp-groups/index.ts
@@ -124,8 +124,17 @@ export function invalidateWhatsappGroupList() {
queryKey: whatsappGroupsKeys.list._def,
});
}
-export function invalidateWhatsappGroups() {
- return queryClient.invalidateQueries({ queryKey: whatsappGroupsKeys._def });
+/**
+ * One group changed for everyone who reads it (sharing, syncing): its
+ * detail, whoever's cache holds it, and every group list. Its timeline is
+ * unchanged.
+ */
+export function invalidateWhatsappGroup(groupId: string) {
+ queryClient.invalidateQueries({ queryKey: whatsappGroupsKeys.list._def });
+ queryClient.invalidateQueries({
+ queryKey: whatsappGroupsKeys.detail._def,
+ predicate: (query) => query.queryKey.at(-1) === groupId,
+ });
}
/** A send was recorded: its row and the group's place in lists follow. */
export function refreshWhatsappGroupTimeline(userId: string, groupId: string) {
diff --git a/apps/web/src/lib/queries/whatsapp-groups/share-permissions.ts b/apps/web/src/lib/queries/whatsapp-groups/share-permissions.ts
index 8a4dd7b1abe..f450d80ca82 100644
--- a/apps/web/src/lib/queries/whatsapp-groups/share-permissions.ts
+++ b/apps/web/src/lib/queries/whatsapp-groups/share-permissions.ts
@@ -1,7 +1,6 @@
-import { fireAndForget } from '@core/util/fireAndForget';
import type { UpdateSharePermissionRequestV2 } from '@service-storage/generated/schemas/updateSharePermissionRequestV2';
import { whatsappGroupsClient } from '@service-storage/whatsapp-groups';
-import { invalidateWhatsappGroups } from './index';
+import { invalidateWhatsappGroup } from './index';
export function fetchWhatsappGroupPermissions(groupId: string) {
return whatsappGroupsClient.permissions(groupId);
@@ -11,7 +10,6 @@ export async function updateWhatsappGroupPermissions(
request: UpdateSharePermissionRequestV2
) {
const result = await whatsappGroupsClient.updatePermissions(groupId, request);
- if (result.isOk())
- fireAndForget(invalidateWhatsappGroups(), 'whatsapp-group.share');
+ if (result.isOk()) invalidateWhatsappGroup(groupId);
return result;
}
diff --git a/apps/web/src/lib/queries/whatsapp-groups/sync.ts b/apps/web/src/lib/queries/whatsapp-groups/sync.ts
index 41eec0ca946..97df959488d 100644
--- a/apps/web/src/lib/queries/whatsapp-groups/sync.ts
+++ b/apps/web/src/lib/queries/whatsapp-groups/sync.ts
@@ -42,12 +42,12 @@ function fallbackRefetch(refetch: () => void) {
const refreshGroupLists = () =>
Promise.all([
- queryClient.invalidateQueries({ queryKey: whatsappLinkedKeys.groups._def }),
+ queryClient.invalidateQueries({ queryKey: whatsappLinkedKeys.chats._def }),
queryClient.invalidateQueries({ queryKey: whatsappGroupsKeys.list._def }),
]);
/**
- * While External is open: the owner's WhatsApp groups (`groups`) and every
+ * While External is open: the owner's WhatsApp chat list (`groups`) and every
* readable group's summary (`group`, for unread counts and names).
*/
export function useWhatsappGroupListsSync() {
@@ -61,7 +61,7 @@ export function useWhatsappGroupListsSync() {
cancel();
if (change.scope === 'groups') {
queryClient.invalidateQueries({
- queryKey: whatsappLinkedKeys.groups._def,
+ queryKey: whatsappLinkedKeys.chats._def,
});
}
queryClient.invalidateQueries({ queryKey: whatsappGroupsKeys.list._def });
diff --git a/apps/web/src/lib/queries/whatsapp-linked/index.ts b/apps/web/src/lib/queries/whatsapp-linked/index.ts
index 2fb6ce7acbe..c5ccf23cd9d 100644
--- a/apps/web/src/lib/queries/whatsapp-linked/index.ts
+++ b/apps/web/src/lib/queries/whatsapp-linked/index.ts
@@ -5,7 +5,7 @@ import { whatsappLinkedClient as client } from '@service-storage/whatsapp-linked
import { queryOptions, useMutation, useQuery } from '@tanstack/solid-query';
import type { Accessor } from 'solid-js';
import { queryClient } from '../client';
-import { invalidateWhatsappGroups } from '../whatsapp-groups';
+import { invalidateWhatsappGroupList } from '../whatsapp-groups';
import { whatsappLinkedKeys } from './keys';
import { whatsappOperation } from './operation';
@@ -40,10 +40,10 @@ function pairingOptions(userId: string, pairingId: string) {
});
}
-function groupsOptions(userId: string, enabled: boolean) {
+function chatsOptions(userId: string, enabled: boolean) {
return queryOptions({
- queryKey: whatsappLinkedKeys.groups(userId).queryKey,
- queryFn: () => throwOnErr(client.groups),
+ queryKey: whatsappLinkedKeys.chats(userId).queryKey,
+ queryFn: () => throwOnErr(client.chats),
enabled: !!userId && enabled,
staleTime: 10_000,
});
@@ -67,27 +67,25 @@ export function useWhatsappLinkedPairingQuery(
return useQuery(() => pairingOptions(userId(), pairingId()));
}
-/** Groups the connected account belongs to, with their adopted channel. */
-export function useWhatsappLinkedGroupsQuery(
+/** The connected account's chat list, newest activity first, with Macro state. */
+export function useWhatsappLinkedChatsQuery(
userId: Accessor,
enabled: Accessor
) {
- return useQuery(() => groupsOptions(userId(), enabled()));
+ return useQuery(() => chatsOptions(userId(), enabled()));
}
const invalidateAccount = () =>
queryClient.invalidateQueries({
queryKey: whatsappLinkedKeys.account._def,
});
-const invalidateGroups = () =>
- queryClient.invalidateQueries({ queryKey: whatsappLinkedKeys.groups._def });
+const invalidateChats = () =>
+ queryClient.invalidateQueries({ queryKey: whatsappLinkedKeys.chats._def });
export function useConnectWhatsappMutation() {
return useMutation(() => ({
- mutationFn: (replace: boolean) =>
- whatsappOperation('connect', () =>
- throwOnErr(() => client.connect(replace))
- ),
+ mutationFn: () =>
+ whatsappOperation('connect', () => throwOnErr(() => client.connect())),
onSuccess: invalidateAccount,
}));
}
@@ -98,7 +96,7 @@ export function useDisconnectWhatsappMutation() {
whatsappOperation('disconnect', () =>
throwOnErr(() => client.disconnect(authorizationGeneration))
),
- onSuccess: () => Promise.all([invalidateAccount(), invalidateGroups()]),
+ onSuccess: () => Promise.all([invalidateAccount(), invalidateChats()]),
}));
}
@@ -112,9 +110,9 @@ export function useCancelWhatsappPairingMutation() {
}));
}
-/** Pairing finished: the account and its groups changed. */
+/** Pairing finished: the account and its chats changed. */
export function refreshWhatsappLinkedAccount() {
- return Promise.all([invalidateAccount(), invalidateGroups()]);
+ return Promise.all([invalidateAccount(), invalidateChats()]);
}
export function useSubmitWhatsappPasskeyMutation() {
@@ -133,6 +131,6 @@ export function useAdoptWhatsappGroupMutation() {
throwOnErr(() => client.adopt(request))
),
onSuccess: () =>
- Promise.all([invalidateGroups(), invalidateWhatsappGroups()]),
+ Promise.all([invalidateChats(), invalidateWhatsappGroupList()]),
}));
}
diff --git a/apps/web/src/lib/queries/whatsapp-linked/keys.ts b/apps/web/src/lib/queries/whatsapp-linked/keys.ts
index 4616cf813d6..ec7f8b36885 100644
--- a/apps/web/src/lib/queries/whatsapp-linked/keys.ts
+++ b/apps/web/src/lib/queries/whatsapp-linked/keys.ts
@@ -6,5 +6,5 @@ export const whatsappLinkedKeys = createQueryKeys('whatsapp-linked', {
configuration: null,
account: (userId: string) => [userId],
pairing: (userId: string, pairingId: string) => [userId, pairingId],
- groups: (userId: string) => [userId],
+ chats: (userId: string) => [userId],
});
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/index.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/index.ts
index 039b7928d02..192b389fc18 100644
--- a/apps/web/src/lib/service-clients/service-storage/generated/schemas/index.ts
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/index.ts
@@ -1210,7 +1210,16 @@ export * from './linkedAdoptGroup';
export * from './linkedAttachment';
export * from './linkedAttachmentDocumentId';
export * from './linkedAttachmentState';
+export * from './linkedBackfill';
+export * from './linkedBackfillState';
export * from './linkedCapabilities';
+export * from './linkedChat';
+export * from './linkedChatCannotAddReason';
+export * from './linkedChatGroup';
+export * from './linkedChatKind';
+export * from './linkedChatLastActivityAt';
+export * from './linkedChatShared';
+export * from './linkedChats';
export * from './linkedConnect';
export * from './linkedDeliveryState';
export * from './linkedDisconnect';
@@ -2251,6 +2260,7 @@ export * from './whatsAppGroupReaction';
export * from './whatsAppGroupSender';
export * from './whatsAppGroupSenderUserId';
export * from './whatsAppGroupSummary';
+export * from './whatsAppGroupSummaryBackfill';
export * from './whatsAppGroupSummaryLastMessageAt';
export * from './whatsAppGroupSummarySendReason';
export * from './whatsappGroupMessagesParams';
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfill.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfill.ts
new file mode 100644
index 00000000000..cba996efdb2
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfill.ts
@@ -0,0 +1,20 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedBackfillState } from './linkedBackfillState';
+
+/**
+ * Earlier messages imported after adding a group.
+ */
+export interface LinkedBackfill {
+ /**
+ * Messages received from the phone so far (including ones already shown).
+ * @minimum 0
+ */
+ imported: number;
+ /** Progress. */
+ state: LinkedBackfillState;
+}
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfillState.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfillState.ts
new file mode 100644
index 00000000000..1f13e8293e6
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedBackfillState.ts
@@ -0,0 +1,21 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+
+/**
+ * Where importing a group's earlier messages stands.
+ */
+export type LinkedBackfillState =
+ (typeof LinkedBackfillState)[keyof typeof LinkedBackfillState];
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const LinkedBackfillState = {
+ pending: 'pending',
+ running: 'running',
+ waiting_for_phone: 'waiting_for_phone',
+ done: 'done',
+ partial: 'partial',
+} as const;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChat.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChat.ts
new file mode 100644
index 00000000000..e89ef3f11b7
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChat.ts
@@ -0,0 +1,38 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedChatCannotAddReason } from './linkedChatCannotAddReason';
+import type { LinkedChatGroup } from './linkedChatGroup';
+import type { LinkedChatKind } from './linkedChatKind';
+import type { LinkedChatLastActivityAt } from './linkedChatLastActivityAt';
+import type { LinkedChatShared } from './linkedChatShared';
+
+/**
+ * One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.
+ */
+export interface LinkedChat {
+ /** Archived in WhatsApp. */
+ archived: boolean;
+ /** "Add to Macro" works now. */
+ canAdd: boolean;
+ /** Why it can't be added, when it is neither added, shared nor addable. */
+ cannotAddReason?: LinkedChatCannotAddReason;
+ group?: LinkedChatGroup;
+ /** WhatsApp chat JID: a group, or the other person's phone-number JID
+(LID when WhatsApp never told us the number). */
+ jid: string;
+ /** Group or direct chat. */
+ kind: LinkedChatKind;
+ /** Newest activity WhatsApp reported (message or history sync); `null`
+when unknown. The list is sorted by it, newest first, unknown last. */
+ lastActivityAt?: LinkedChatLastActivityAt;
+ /** Group: the subject, or member names for an unnamed group. Direct: the
+contact or WhatsApp name, else `+`. Always non-empty. */
+ name: string;
+ /** Pinned in WhatsApp. */
+ pinned: boolean;
+ shared?: LinkedChatShared;
+}
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatCannotAddReason.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatCannotAddReason.ts
new file mode 100644
index 00000000000..d84295b74ff
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatCannotAddReason.ts
@@ -0,0 +1,11 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+
+/**
+ * Why it can't be added, when it is neither added, shared nor addable.
+ */
+export type LinkedChatCannotAddReason = string | null;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatGroup.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatGroup.ts
new file mode 100644
index 00000000000..7bbaa39e6d3
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatGroup.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedGroupReference } from './linkedGroupReference';
+
+export type LinkedChatGroup = null | LinkedGroupReference;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatKind.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatKind.ts
new file mode 100644
index 00000000000..bd86f786d4e
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatKind.ts
@@ -0,0 +1,18 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+
+/**
+ * Whether a WhatsApp chat is a group or a one-to-one chat.
+ */
+export type LinkedChatKind =
+ (typeof LinkedChatKind)[keyof typeof LinkedChatKind];
+
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export const LinkedChatKind = {
+ group: 'group',
+ direct: 'direct',
+} as const;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatLastActivityAt.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatLastActivityAt.ts
new file mode 100644
index 00000000000..f36225354d8
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatLastActivityAt.ts
@@ -0,0 +1,12 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+
+/**
+ * Newest activity WhatsApp reported (message or history sync); `null`
+when unknown. The list is sorted by it, newest first, unknown last.
+ */
+export type LinkedChatLastActivityAt = string | null;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatShared.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatShared.ts
new file mode 100644
index 00000000000..b7af0b6c304
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChatShared.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedSharedGroupReference } from './linkedSharedGroupReference';
+
+export type LinkedChatShared = null | LinkedSharedGroupReference;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChats.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChats.ts
new file mode 100644
index 00000000000..15ef8db0b5b
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/linkedChats.ts
@@ -0,0 +1,15 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedChat } from './linkedChat';
+
+/**
+ * The caller's WhatsApp chat list.
+ */
+export interface LinkedChats {
+ /** Newest activity first; chats with unknown activity last, by name. */
+ chats: LinkedChat[];
+}
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummary.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummary.ts
index 199d849fa7d..396e762eb62 100644
--- a/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummary.ts
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummary.ts
@@ -4,6 +4,7 @@
* document_storage_service
* OpenAPI spec version: 0.1.0
*/
+import type { WhatsAppGroupSummaryBackfill } from './whatsAppGroupSummaryBackfill';
import type { WhatsAppGroupSummaryLastMessageAt } from './whatsAppGroupSummaryLastMessageAt';
import type { WhatsAppGroupSummarySendReason } from './whatsAppGroupSummarySendReason';
@@ -11,6 +12,7 @@ import type { WhatsAppGroupSummarySendReason } from './whatsAppGroupSummarySendR
* Adopted group visible through ordinary entity sharing.
*/
export interface WhatsAppGroupSummary {
+ backfill?: WhatsAppGroupSummaryBackfill;
/** Caller may currently send from their own account. */
can_send: boolean;
/** Entity identifier. */
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummaryBackfill.ts b/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummaryBackfill.ts
new file mode 100644
index 00000000000..10afa54ceec
--- /dev/null
+++ b/apps/web/src/lib/service-clients/service-storage/generated/schemas/whatsAppGroupSummaryBackfill.ts
@@ -0,0 +1,9 @@
+/**
+ * Generated by orval v7.21.0 🍺
+ * Do not edit manually.
+ * document_storage_service
+ * OpenAPI spec version: 0.1.0
+ */
+import type { LinkedBackfill } from './linkedBackfill';
+
+export type WhatsAppGroupSummaryBackfill = null | LinkedBackfill;
diff --git a/apps/web/src/lib/service-clients/service-storage/generated/zod.ts b/apps/web/src/lib/service-clients/service-storage/generated/zod.ts
index b3848207021..8bfae36be91 100644
--- a/apps/web/src/lib/service-clients/service-storage/generated/zod.ts
+++ b/apps/web/src/lib/service-clients/service-storage/generated/zod.ts
@@ -49214,6 +49214,90 @@ export const linkedAccountResponse = zod
})
.describe('Owner-scoped account state, including not connected.');
+/**
+ * @summary The caller's WhatsApp chat list (groups and direct chats), newest
+activity first, with what can be added to Macro.
+ */
+export const linkedChatsResponse = zod
+ .object({
+ chats: zod
+ .array(
+ zod
+ .object({
+ archived: zod.boolean().describe('Archived in WhatsApp.'),
+ canAdd: zod.boolean().describe('\"Add to Macro\" works now.'),
+ cannotAddReason: zod
+ .string()
+ .nullish()
+ .describe(
+ "Why it can't be added, when it is neither added, shared nor addable."
+ ),
+ group: zod
+ .union([
+ zod.null(),
+ zod
+ .object({
+ id: zod.uuid().describe('Group entity id.'),
+ name: zod
+ .string()
+ .describe('Display name, following WhatsApp.'),
+ })
+ .describe('A group entity bound to a remote group.'),
+ ])
+ .optional(),
+ jid: zod
+ .string()
+ .describe(
+ "WhatsApp chat JID: a group, or the other person's phone-number JID\n(LID when WhatsApp never told us the number)."
+ ),
+ kind: zod
+ .enum(['group', 'direct'])
+ .describe(
+ 'Whether a WhatsApp chat is a group or a one-to-one chat.'
+ ),
+ lastActivityAt: zod.iso
+ .datetime({})
+ .nullish()
+ .describe(
+ 'Newest activity WhatsApp reported (message or history sync); `null`\nwhen unknown. The list is sorted by it, newest first, unknown last.'
+ ),
+ name: zod
+ .string()
+ .describe(
+ 'Group: the subject, or member names for an unnamed group. Direct: the\ncontact or WhatsApp name, else `+`. Always non-empty.'
+ ),
+ pinned: zod.boolean().describe('Pinned in WhatsApp.'),
+ shared: zod
+ .union([
+ zod.null(),
+ zod
+ .object({
+ id: zod.uuid().describe('Group entity id.'),
+ name: zod
+ .string()
+ .describe('Display name, following WhatsApp.'),
+ owner_id: zod
+ .string()
+ .describe(
+ 'Macro user who added the group and shared it.'
+ ),
+ })
+ .describe(
+ "Another person's group entity the caller can view."
+ ),
+ ])
+ .optional(),
+ })
+ .describe(
+ "One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it."
+ )
+ )
+ .describe(
+ 'Newest activity first; chats with unknown activity last, by name.'
+ ),
+ })
+ .describe("The caller's WhatsApp chat list.");
+
/**
* @summary Server rollout switches.
*/
@@ -49454,8 +49538,34 @@ export const linkedPasskeyBody = zod.object({});
/**
* @summary List adopted groups the caller can view, including without WhatsApp.
*/
+export const whatsappGroupsResponseBackfillImportedMin = 0;
+
export const whatsappGroupsResponseItem = zod
.object({
+ backfill: zod
+ .union([
+ zod.null(),
+ zod
+ .object({
+ imported: zod
+ .number()
+ .min(whatsappGroupsResponseBackfillImportedMin)
+ .describe(
+ 'Messages received from the phone so far (including ones already shown).'
+ ),
+ state: zod
+ .enum([
+ 'pending',
+ 'running',
+ 'waiting_for_phone',
+ 'done',
+ 'partial',
+ ])
+ .describe("Where importing a group's earlier messages stands."),
+ })
+ .describe('Earlier messages imported after adding a group.'),
+ ])
+ .optional(),
can_send: zod
.boolean()
.describe('Caller may currently send from their own account.'),
@@ -49495,6 +49605,8 @@ export const whatsappGroupParams = zod.object({
group_id: zod.uuid(),
});
+export const whatsappGroupResponseBackfillImportedMin = 0;
+
export const whatsappGroupResponseLimitsAttachmentLimitBytesMin = 0;
export const whatsappGroupResponseLimitsMaxAttachmentsMin = 0;
@@ -49505,6 +49617,30 @@ export const whatsappGroupResponseLimitsTextLimitBytesMin = 0;
export const whatsappGroupResponse = zod
.object({
+ backfill: zod
+ .union([
+ zod.null(),
+ zod
+ .object({
+ imported: zod
+ .number()
+ .min(whatsappGroupResponseBackfillImportedMin)
+ .describe(
+ 'Messages received from the phone so far (including ones already shown).'
+ ),
+ state: zod
+ .enum([
+ 'pending',
+ 'running',
+ 'waiting_for_phone',
+ 'done',
+ 'partial',
+ ])
+ .describe("Where importing a group's earlier messages stands."),
+ })
+ .describe('Earlier messages imported after adding a group.'),
+ ])
+ .optional(),
can_send: zod
.boolean()
.describe('Caller may currently send from their own account.'),
diff --git a/apps/web/src/lib/service-clients/service-storage/openapi.json b/apps/web/src/lib/service-clients/service-storage/openapi.json
index 98b444366c2..f5ea543636e 100644
--- a/apps/web/src/lib/service-clients/service-storage/openapi.json
+++ b/apps/web/src/lib/service-clients/service-storage/openapi.json
@@ -16047,6 +16047,25 @@
}
}
},
+ "/meta/linked/chats": {
+ "get": {
+ "tags": ["whatsapp_linked::inbound::router"],
+ "summary": "The caller's WhatsApp chat list (groups and direct chats), newest\nactivity first, with what can be added to Macro.",
+ "operationId": "linked_chats",
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LinkedChats"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/meta/linked/configuration": {
"get": {
"tags": ["whatsapp_linked::inbound::router"],
@@ -33385,6 +33404,28 @@
"description": "Where an attachment of a linked message stands.",
"enum": ["loading", "ready", "unavailable", "unsupported"]
},
+ "LinkedBackfill": {
+ "type": "object",
+ "description": "Earlier messages imported after adding a group.",
+ "required": ["state", "imported"],
+ "properties": {
+ "imported": {
+ "type": "integer",
+ "format": "int32",
+ "description": "Messages received from the phone so far (including ones already shown).",
+ "minimum": 0
+ },
+ "state": {
+ "$ref": "#/components/schemas/LinkedBackfillState",
+ "description": "Progress."
+ }
+ }
+ },
+ "LinkedBackfillState": {
+ "type": "string",
+ "description": "Where importing a group's earlier messages stands.",
+ "enum": ["pending", "running", "waiting_for_phone", "done", "partial"]
+ },
"LinkedCapabilities": {
"type": "object",
"description": "Operations implemented for linked groups, independent of current permission.",
@@ -33437,6 +33478,87 @@
}
}
},
+ "LinkedChat": {
+ "type": "object",
+ "description": "One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.",
+ "required": ["jid", "kind", "name", "archived", "pinned", "canAdd"],
+ "properties": {
+ "archived": {
+ "type": "boolean",
+ "description": "Archived in WhatsApp."
+ },
+ "canAdd": {
+ "type": "boolean",
+ "description": "\"Add to Macro\" works now."
+ },
+ "cannotAddReason": {
+ "type": ["string", "null"],
+ "description": "Why it can't be added, when it is neither added, shared nor addable."
+ },
+ "group": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedGroupReference",
+ "description": "The caller's own Macro group for this chat, once added."
+ }
+ ]
+ },
+ "jid": {
+ "type": "string",
+ "description": "WhatsApp chat JID: a group, or the other person's phone-number JID\n(LID when WhatsApp never told us the number)."
+ },
+ "kind": {
+ "$ref": "#/components/schemas/LinkedChatKind",
+ "description": "Group or direct chat."
+ },
+ "lastActivityAt": {
+ "type": ["string", "null"],
+ "format": "date-time",
+ "description": "Newest activity WhatsApp reported (message or history sync); `null`\nwhen unknown. The list is sorted by it, newest first, unknown last."
+ },
+ "name": {
+ "type": "string",
+ "description": "Group: the subject, or member names for an unnamed group. Direct: the\ncontact or WhatsApp name, else `+`. Always non-empty."
+ },
+ "pinned": {
+ "type": "boolean",
+ "description": "Pinned in WhatsApp."
+ },
+ "shared": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedSharedGroupReference",
+ "description": "Someone else's Macro group for this chat shared with the caller, when\nthe caller has not added their own."
+ }
+ ]
+ }
+ }
+ },
+ "LinkedChatKind": {
+ "type": "string",
+ "description": "Whether a WhatsApp chat is a group or a one-to-one chat.",
+ "enum": ["group", "direct"]
+ },
+ "LinkedChats": {
+ "type": "object",
+ "description": "The caller's WhatsApp chat list.",
+ "required": ["chats"],
+ "properties": {
+ "chats": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LinkedChat"
+ },
+ "description": "Newest activity first; chats with unknown activity last, by name."
+ }
+ }
+ },
"LinkedConnect": {
"type": "object",
"description": "Explicit pairing intent; replacement is a separate deliberate action.",
@@ -44597,6 +44719,17 @@
"description": "Adopted group visible through ordinary entity sharing.",
"required": ["id", "name", "user_id", "unread_count", "can_send"],
"properties": {
+ "backfill": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedBackfill",
+ "description": "Importing earlier messages after the group was added; `null` for\ngroups added before this existed."
+ }
+ ]
+ },
"can_send": {
"type": "boolean",
"description": "Caller may currently send from their own account."
diff --git a/apps/web/src/lib/service-clients/service-storage/whatsapp-linked.ts b/apps/web/src/lib/service-clients/service-storage/whatsapp-linked.ts
index 4607737ab11..75ac81ffa2f 100644
--- a/apps/web/src/lib/service-clients/service-storage/whatsapp-linked.ts
+++ b/apps/web/src/lib/service-clients/service-storage/whatsapp-linked.ts
@@ -5,9 +5,9 @@ import type { ObjectLike } from '@core/util/result';
import type { AdoptedGroup } from './generated/schemas/adoptedGroup';
import type { LinkedAccountView } from './generated/schemas/linkedAccountView';
import type { LinkedAdoptGroup } from './generated/schemas/linkedAdoptGroup';
+import type { LinkedChats } from './generated/schemas/linkedChats';
import type { LinkedDisconnect } from './generated/schemas/linkedDisconnect';
import type { LinkedFeatures } from './generated/schemas/linkedFeatures';
-import type { LinkedGroupInfo } from './generated/schemas/linkedGroupInfo';
import type { LinkedPairing } from './generated/schemas/linkedPairing';
import type { LinkedPairState } from './generated/schemas/linkedPairState';
import type { LinkedPasskeyBody } from './generated/schemas/linkedPasskeyBody';
@@ -31,9 +31,9 @@ function post(url: string, body: unknown) {
export const whatsappLinkedClient = {
configuration: () => fetchWithToken(`${root}/configuration`),
account: () => fetchWithToken(`${root}/account`),
- /** Starts an owner-bound pairing; `replace` retires the retained identity. */
- connect: (replace: boolean) =>
- post(`${root}/connect`, { replace }),
+ /** Starts an owner-bound pairing. One account at a time: switching means
+ * disconnecting first, so the web never retires a linked identity here. */
+ connect: () => post(`${root}/connect`, { replace: false }),
disconnect: (authorizationGeneration: number) =>
post(`${root}/disconnect`, {
authorization_generation: authorizationGeneration,
@@ -46,7 +46,8 @@ export const whatsappLinkedClient = {
/** The WebAuthn assertion answering WhatsApp's passkey challenge. */
passkey: (id: string, response: LinkedPasskeyBody) =>
post>(`${pairing(id)}/passkey`, response),
- groups: () => fetchWithToken(`${root}/groups`),
+ /** Every WhatsApp chat, newest activity first; asks DSS for a group refresh. */
+ chats: () => fetchWithToken(`${root}/chats`),
adopt: (request: LinkedAdoptGroup) =>
post(`${root}/groups/adopt`, request),
};
diff --git a/apps/web/tests/functional/whatsapp-linked.spec.ts b/apps/web/tests/functional/whatsapp-linked.spec.ts
index 7500cdaea3a..b4e70ddc32f 100644
--- a/apps/web/tests/functional/whatsapp-linked.spec.ts
+++ b/apps/web/tests/functional/whatsapp-linked.spec.ts
@@ -3,10 +3,12 @@ import { expect, type Page, test } from '@playwright/test';
const USER_ID = 'macro|wa-tester@example.test';
-type Group = {
+/** One row of the account's WhatsApp chat list. */
+type Chat = {
jid: string;
+ kind: 'group' | 'direct';
name: string;
- members: number;
+ lastActivityAt: string | null;
group: { id: string; name: string } | null;
shared?: { id: string; name: string; owner_id: string };
};
@@ -21,7 +23,11 @@ type LinkedServer = {
state: string;
};
pairingState: string;
- groups: Group[];
+ chats: Chat[];
+ /** The added group's history import, as `GET /whatsapp-groups/{id}` reports it. */
+ backfill: { state: string; imported: number } | null;
+ /** History the owner's phone sent so far, older than everything shown. */
+ imported: unknown[];
requests: string[];
adoptions: unknown[];
passkeyAnswers: unknown[];
@@ -41,23 +47,35 @@ function server(): LinkedServer {
return {
account: null,
pairingState: 'qr',
- groups: [
+ backfill: null,
+ imported: [],
+ chats: [
+ {
+ jid: '14155550199@s.whatsapp.net',
+ kind: 'direct',
+ name: 'Ana Ruiz',
+ lastActivityAt: '2026-10-21T10:00:00Z',
+ group: null,
+ },
{
jid: '120363001@g.us',
+ kind: 'group',
name: 'Design Crit',
- members: 14,
+ lastActivityAt: '2026-10-21T09:00:00Z',
group: { id: GROUP_ID, name: 'design-crit' },
},
{
jid: '120363003@g.us',
+ kind: 'group',
name: 'Launch War Room',
- members: 23,
+ lastActivityAt: '2026-10-20T09:00:00Z',
group: null,
},
{
jid: '120363004@g.us',
+ kind: 'group',
name: 'Ana, Ben, +2',
- members: 4,
+ lastActivityAt: null,
group: null,
shared: {
id: 'group-shared-family',
@@ -202,6 +220,7 @@ async function mount(page: Page, state: LinkedServer, query = '') {
? '14155550142@s.whatsapp.net'
: null,
unread_count: 1,
+ backfill: state.backfill,
roster: {
participants: [
{
@@ -238,6 +257,7 @@ async function mount(page: Page, state: LinkedServer, query = '') {
},
]
: [
+ ...state.imported,
incomingMessage,
{
...incomingMessage,
@@ -320,7 +340,7 @@ async function mount(page: Page, state: LinkedServer, query = '') {
});
if (path === 'whatsapp-groups')
return route.fulfill({
- json: state.groups
+ json: state.chats
.filter((item) => item.group)
.map((item) => ({
id: item.group?.id,
@@ -370,27 +390,26 @@ async function mount(page: Page, state: LinkedServer, query = '') {
},
});
}
- if (path === 'groups' && method === 'GET')
+ if (path === 'chats' && method === 'GET')
return route.fulfill({
- json: state.groups.map((group) => ({
- jid: group.jid,
- name: group.name,
- announce: false,
- community: false,
- disappearing: false,
- observedAt: '2026-10-20T12:00:00Z',
- group: group.group,
- shared: group.shared ?? null,
- participants: Array.from({ length: group.members }, (_, i) => ({
- jid: `1415555${String(i).padStart(4, '0')}@s.whatsapp.net`,
- admin: i === 0,
+ json: {
+ chats: state.chats.map((chat) => ({
+ ...chat,
+ archived: false,
+ pinned: false,
+ shared: chat.group ? null : (chat.shared ?? null),
+ canAdd: chat.kind === 'group' && !chat.group && !chat.shared,
+ cannotAddReason:
+ chat.kind === 'direct'
+ ? "direct chats can't be added to Macro yet"
+ : null,
})),
- })),
+ },
});
if (path === 'groups/adopt' && method === 'POST') {
const body = route.request().postDataJSON() as { group_jid: string };
state.adoptions.push(body);
- const group = state.groups.find(({ jid }) => jid === body.group_jid);
+ const group = state.chats.find(({ jid }) => jid === body.group_jid);
if (group) group.group = { id: 'group-new', name: group.name };
return route.fulfill({
json: {
@@ -445,10 +464,28 @@ test('links WhatsApp by QR, then adds a shareable WhatsApp group', async ({
const groups = page.getByRole('list', { name: 'Groups to add to Macro' });
await expect(groups.getByText('Launch War Room')).toBeVisible();
- // Already in Macro: listed in External's sidebar instead.
await expect(groups.getByText('Design Crit')).toHaveCount(0);
+ // Direct chats are listed by recent activity but can't be added yet.
+ await page.getByRole('button', { name: /Can't be added \(1\)/ }).click();
+ const direct = page
+ .getByRole('list', { name: "Can't be added" })
+ .getByRole('listitem')
+ .filter({ hasText: 'Ana Ruiz' });
+ await expect(direct.getByText("Can't add direct chats yet")).toBeVisible();
+ await expect(direct.getByRole('button')).toHaveCount(0);
+ const search = page.getByRole('searchbox', { name: 'Search WhatsApp chats' });
+ await search.fill('design');
+ await expect(
+ page
+ .getByRole('list', { name: 'WhatsApp chats in Macro' })
+ .getByText('Design Crit')
+ ).toBeVisible();
+ await search.fill('launch');
+ await expect(groups.getByRole('listitem')).toHaveCount(1);
+ await search.fill('');
+ await expect(groups.getByRole('listitem')).toHaveCount(2);
await groups
- .getByRole('button', { name: /Shared with you by Group Owner/ })
+ .getByRole('button', { name: /shared with you by Group Owner/i })
.click();
expect(await page.evaluate(() => window.openedGroups)).toEqual([
'group-shared-family',
@@ -496,7 +533,7 @@ test('External lists groups in Macro with unread counts and read-only tags', asy
page,
}) => {
const state = server();
- state.groups[1].group = { id: 'group-shared', name: 'Launch War Room' };
+ state.chats[2].group = { id: 'group-shared', name: 'Launch War Room' };
const unexpected = await mount(page, state, '?view=in-macro');
const nav = page.getByRole('navigation', {
name: 'WhatsApp groups in Macro',
@@ -598,7 +635,9 @@ test('an independent group reads, replies, reacts and pages through channel rows
await expect(
page.getByRole('heading', { name: 'Design Crit' })
).toBeVisible();
- await expect(page.getByText('Sending as +14155550142')).toBeVisible();
+ await expect(
+ page.getByRole('textbox', { name: 'Message Design Crit as +14155550142' })
+ ).toBeVisible();
await expect(page.getByText('Loading design.pdf…')).toBeVisible();
await expect(page.getByText(/may already have arrived/)).toHaveCount(0);
await expect.poll(() => state.readMessages).toContain('message-2');
@@ -636,6 +675,40 @@ test('an independent group reads, replies, reacts and pages through channel rows
expect(unexpected).toEqual([]);
});
+test('history imported after adding shows up older, with the import state', async ({
+ page,
+}) => {
+ const state = server();
+ state.backfill = { state: 'waiting_for_phone', imported: 0 };
+ const unexpected = await mount(page, state, `?group=${GROUP_ID}`);
+ await expect(
+ page.getByText('WhatsApp · Waiting for your phone to import history')
+ ).toBeVisible();
+ // The phone answers; the next read (push or fallback re-fetch) shows it.
+ state.backfill = { state: 'done', imported: 1 };
+ state.imported = [
+ {
+ ...incomingMessage,
+ id: 'message-imported',
+ body: 'From before the group was added',
+ sent_at: '2026-10-19T10:00:00Z',
+ reactions: [],
+ attachments: [],
+ },
+ ];
+ await expect(page.getByText('From before the group was added')).toBeVisible();
+ await expect(page.getByText(/import history|Importing history/)).toHaveCount(
+ 0
+ );
+ const ids = await page
+ .locator('[data-message-id]')
+ .evaluateAll((rows) =>
+ rows.map((row) => row.getAttribute('data-message-id'))
+ );
+ expect(ids.slice(0, 2)).toEqual(['message-imported', 'message-1']);
+ expect(unexpected).toEqual([]);
+});
+
test('a refused send leaves the conversation, says why and restores the draft', async ({
page,
}) => {
@@ -719,7 +792,11 @@ for (const mobile of [false, true]) {
await page.emulateMedia({ colorScheme: dark ? 'dark' : 'light' });
const state = server();
const unexpected = await mount(page, state, `?group=${GROUP_ID}`);
- await expect(page.getByText('Sending as +14155550142')).toBeVisible();
+ await expect(
+ page.getByRole('textbox', {
+ name: 'Message Design Crit as +14155550142',
+ })
+ ).toBeVisible();
await expect(
page.getByRole('textbox', { name: 'Message Design Crit' })
).toBeVisible();
diff --git a/apps/web/tests/functional/whatsapp-linked/fixture.tsx b/apps/web/tests/functional/whatsapp-linked/fixture.tsx
index 29d88c9bba9..e62c34106e3 100644
--- a/apps/web/tests/functional/whatsapp-linked/fixture.tsx
+++ b/apps/web/tests/functional/whatsapp-linked/fixture.tsx
@@ -1,12 +1,13 @@
import { EmailLinksContextProvider } from '@core/context/emailLinks';
import { ImperativeDialogHost } from '@ui';
import '@fontsource-variable/inter';
-import { InMacroSection } from '@app/features/external-view/components/in-macro-section';
+import { InMacroGroups } from '@app/features/external-view/components/in-macro-section';
import { WhatsAppGroupProvider } from '@app/features/whatsapp-group/context/whatsapp-group-context';
import { createWhatsAppGroupCapabilities } from '@app/features/whatsapp-group/queries/capabilities';
import { whatsappGroupApi } from '@app/features/whatsapp-group/queries/production-api';
import { WhatsAppGroupView } from '@app/features/whatsapp-group/views/whatsapp-group-view';
import { getPermissions } from '@core/component/SharePermissions';
+import { ShareTrigger } from '@core/component/TopBar/ShareButton';
import { useShareModal } from '@core/component/TopBar/shareModal';
import { useUserId } from '@core/context/user';
import { Route, Router } from '@solidjs/router';
@@ -84,7 +85,13 @@ function GroupHarness(props: { groupId: string }) {
+ }
onConnect={() => {
location.search = '';
}}
@@ -100,13 +107,11 @@ function InMacroHarness() {
const groups = useWhatsappGroupsQuery(whatsappGroupApi, () => userId() ?? '');
return (
- {}}
onOpenGroup={(groupId) => window.openedGroups.push(groupId)}
onRetry={() => {}}
/>
diff --git a/crates/agent_code_mode/src/domain/documentation.json b/crates/agent_code_mode/src/domain/documentation.json
index 495be5c0aa0..7be9d807a4c 100644
--- a/crates/agent_code_mode/src/domain/documentation.json
+++ b/crates/agent_code_mode/src/domain/documentation.json
@@ -80,8 +80,8 @@
{
"name": "channels",
"description": "Read and send channel messages; read and share standalone WhatsApp groups, discover remote groups, and send from the credential owner’s own member account with media and delivery. Pairing stays in the app.",
- "overview": "\n# Class: ChannelNamespace\n\n## Constructors\n\n### Constructor\n\n> **new ChannelNamespace**(`client`): `ChannelNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelNamespace`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `labels` | `readonly` | [`ChannelLabelsNamespace`](../../labels/classes/ChannelLabelsNamespace.md) | Team-shared labels that group channels in the Chat sidebar. |\n\n## Methods\n\n### activity()\n\n> **activity**(): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\nRecent channel activity, with channel and user handles.\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`Channel`](../../channel/classes/Channel.md)\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### create()\n\n> **create**(`opts`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### dm()\n\n> **dm**(`recipient`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\nAll channels the authenticated user is a member of.\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\n***\n\n### private()\n\n> **private**(`recipients`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### search()\n\n> **search**(`query`, `opts?`): `AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nSearch channels by name (client-side fuzzy filter on the full channel list)\nor by content (server-side unified search).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `query` | `string` |\n| `opts?` | [`SearchOpts`](../../../search/interfaces/SearchOpts.md) |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n\n\n# Class: WhatsAppNamespace\n\nOperate on an account already paired through the Macro app.\n\n## Constructors\n\n### Constructor\n\n> **new WhatsAppNamespace**(`client`): `WhatsAppNamespace`\n\nBind existing-account operations to this authenticated client.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`WhatsAppNamespace`\n\n## Methods\n\n### account()\n\n> **account**(): `Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\nCurrent owner's account, or undefined when no account has been connected.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\nReference an adopted entity without fetching it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\n***\n\n### groups()\n\n> **groups**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\nAdopted groups shared with the caller, including without WhatsApp.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\n***\n\n### remoteGroups()\n\n> **remoteGroups**(): `Promise`\\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\\>\n\nGroups discoverable through the caller's own connected account.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\\>\n",
- "documentation": "# Macro SDK: channels\n\nGenerated by TypeDoc. Paths below refer to the canonical Markdown hierarchy. Other entity handles are documented in their named section; request core for shared SDK helpers.\n\n\n# Type Alias: BulkUpdateEntityPropertyOptionsResponse\n\n> **BulkUpdateEntityPropertyOptionsResponse** = \\{ `properties`: [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[]; \\}\n\nResponse for a bulk option update: each property's reconciled final ids.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `properties` | [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[] | The final option ids per updated property. |\n\n\n\n# Type Alias: DataType\n\n> **DataType** = `\"BOOLEAN\"` \\| `\"DATE\"` \\| `\"NUMBER\"` \\| `\"STRING\"` \\| `\"SELECT_NUMBER\"` \\| `\"SELECT_STRING\"` \\| `\"TAG\"` \\| `\"ENTITY\"` \\| `\"LINK\"`\n\nData type for property values, determining storage and validation.\n\n\n\n# Type Alias: EntityProperty\n\n> **EntityProperty** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; \\}\n\nAssignment of a property definition to a specific entity (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `created_at` | `string` |\n| `entity_id` | `string` |\n| `entity_type` | [`EntityType`](EntityType.md) |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n\n\n\n# Type Alias: EntityPropertyOptionSelectionResponse\n\n> **EntityPropertyOptionSelectionResponse** = \\{ `option_ids`: `string`[]; `property_id`: `string`; \\}\n\nThe reconciled final option ids stored for one property after a bulk update.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `option_ids` | `string`[] | The final option ids the server persisted, in stored order. |\n| `property_id` | `string` | The property definition the options belong to. |\n\n\n\n# Type Alias: EntityPropertyWithDefinition\n\n> **EntityPropertyWithDefinition** = \\{ `definition`: [`PropertyDefinition`](PropertyDefinition.md); `options?`: [`PropertyOption`](PropertyOption.md)[] \\| `null`; `property`: [`EntityProperty`](EntityProperty.md); `value?`: `null` \\| [`PropertyValue`](PropertyValue.md); \\}\n\nEntity property with its definition, value, and options (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `definition` | [`PropertyDefinition`](PropertyDefinition.md) |\n| `options?` | [`PropertyOption`](PropertyOption.md)[] \\| `null` |\n| `property` | [`EntityProperty`](EntityProperty.md) |\n| `value?` | `null` \\| [`PropertyValue`](PropertyValue.md) |\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `specific_message_id?`: `string` \\| `null`; \\}\n\nEntity reference for entity-type property values.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | - |\n| `entity_type` | [`EntityType`](EntityType.md) | - |\n| `specific_message_id?` | `string` \\| `null` | For CHANNEL, CHAT, THREAD entity types - optional specific message ID. This allows referencing a specific message within a thread/channel/chat. |\n\n\n\n# Type Alias: EntityType\n\n> **EntityType** = `\"CALENDAR_EVENT\"` \\| `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"CONTACT\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"TASK\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nType of entity that can be referenced by entity properties.\n\n\n\n# Type Alias: PropertyDefinition\n\n> **PropertyDefinition** = \\{ `created_at`: `string`; `data_type`: [`DataType`](DataType.md); `display_name`: `string`; `id`: `string`; `is_metadata`: `boolean`; `is_multi_select`: `boolean`; `is_system`: `boolean`; `owner`: [`PropertyOwner`](PropertyOwner.md); `specific_entity_type`: `null` \\| [`EntityType`](EntityType.md); `updated_at`: `string`; \\}\n\nProperty definition model (service representation).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | - |\n| `data_type` | [`DataType`](DataType.md) | - |\n| `display_name` | `string` | - |\n| `id` | `string` | - |\n| `is_metadata` | `boolean` | Flag to indicate if this is a system-generated metadata property. Not stored in database - computed at service layer. |\n| `is_multi_select` | `boolean` | - |\n| `is_system` | `boolean` | Flag to indicate if this is a system property (stored in DB). |\n| `owner` | [`PropertyOwner`](PropertyOwner.md) | - |\n| `specific_entity_type` | `null` \\| [`EntityType`](EntityType.md) | - |\n| `updated_at` | `string` | - |\n\n\n\n# Type Alias: PropertyOption\n\n> **PropertyOption** = \\{ `color`: `string` \\| `null`; `created_at`: `string`; `display_order`: `number`; `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; `value`: [`PropertyOptionValue`](PropertyOptionValue.md); \\}\n\nA selectable option for select-type properties (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `color` | `string` \\| `null` |\n| `created_at` | `string` |\n| `display_order` | `number` |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n| `value` | [`PropertyOptionValue`](PropertyOptionValue.md) |\n\n\n\n# Type Alias: PropertyOptionValue\n\n> **PropertyOptionValue** = \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\}\n\nThe value of a property option - either a string or a number.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"string\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"string\"` | - |\n| `value` | `string` | String value for SelectString properties |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"number\"` | - |\n| `value` | `number` | Number value for SelectNumber properties |\n\n\n\n# Type Alias: PropertyOwner\n\n> **PropertyOwner** = \\{ `scope`: `\"user\"`; `user_id`: `string`; \\} \\| \\{ `scope`: `\"team\"`; `team_id`: `string`; \\} \\| \\{ `database_id`: `string`; `scope`: `\"database\"`; \\} \\| \\{ `scope`: `\"system\"`; \\}\n\nDefines who owns a property - user-scoped, team-scoped, database-scoped, or system.\n\n\n\n# Type Alias: PropertyTargetEntityType\n\n> **PropertyTargetEntityType** = `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nCanonical type of an entity receiving properties.\n\nTasks are documents at API boundaries. `Task` intentionally does not exist\nhere; task classification is resolved by the properties domain from the\ndocument subtype.\n\n\n\n# Type Alias: PropertyTargetReference\n\n> **PropertyTargetReference** = \\{ `entity_id`: `string`; `entity_type`: [`PropertyTargetEntityType`](PropertyTargetEntityType.md); \\}\n\nCanonical reference to an entity receiving properties.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Entity identifier. |\n| `entity_type` | [`PropertyTargetEntityType`](PropertyTargetEntityType.md) | Canonical entity type. |\n\n\n\n# Type Alias: PropertyValue\n\n> **PropertyValue** = \\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"Number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"String\"`; `value`: `string`; \\} \\| \\{ `type`: `\"Date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\} \\| \\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\} \\| \\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\nProperty value (service representation).\n\nRepresents the actual value stored for an entity property.\nThis is serialized to/from JSONB in the database.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Boolean\"` | - |\n| `value` | `boolean` | Boolean value Serializes as: {\"type\": \"Boolean\", \"value\": true} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Number\"` | - |\n| `value` | `number` | Numeric value Serializes as: {\"type\": \"Number\", \"value\": 42.5} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"String\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"String\"` | - |\n| `value` | `string` | String value Serializes as: {\"type\": \"String\", \"value\": \"text\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Date\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Date\"` | - |\n| `value` | `string` | Date/timestamp value Serializes as: {\"type\": \"Date\", \"value\": \"2025-01-01T00:00:00Z\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"SelectOption\"` | - |\n| `value` | `string`[] | Select option(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"SelectOption\", \"value\": [\"uuid\"]} (length 0 or 1) Multi-select: {\"type\": \"SelectOption\", \"value\": [\"uuid1\", \"uuid2\", ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"EntityReference\"` | - |\n| `value` | [`EntityReference`](EntityReference.md)[] | Entity reference(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"EntityReference\", \"value\": [{...}]} (length 0 or 1) Multi-select: {\"type\": \"EntityReference\", \"value\": [{...}, {...}, ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Link\"` | - |\n| `value` | `string`[] | Link value(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"Link\", \"value\": [\"https://example.com\"]} (length 0 or 1) Multi-select: {\"type\": \"Link\", \"value\": [\"https://example.com\", \"https://other.com\"]} (length 0+) |\n\n\n\n# Type Alias: SetPropertyValue\n\n> **SetPropertyValue** = \\{ `type`: `\"boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `option_id`: `string`; `type`: `\"select_option\"`; \\} \\| \\{ `option_ids`: `string`[]; `type`: `\"multi_select_option\"`; \\} \\| \\{ `reference`: [`EntityReference`](EntityReference.md); `type`: `\"entity_reference\"`; \\} \\| \\{ `references`: [`EntityReference`](EntityReference.md)[]; `type`: `\"multi_entity_reference\"`; \\} \\| \\{ `type`: `\"link\"`; `url`: `string`; \\} \\| \\{ `type`: `\"multi_link\"`; `urls`: `string`[]; \\}\n\nType-safe enum for setting entity property values - provides compile-time validation.\n\n\n\n# Type Alias: AccessLevel\n\n> **AccessLevel** = `\"view\"` \\| `\"comment\"` \\| `\"edit\"` \\| `\"owner\"`\n\nOrdered from least to most access top -> bottom\n\n\n\n# Type Alias: ActivityType\n\n> **ActivityType** = `\"view\"` \\| `\"interact\"`\n\nThe kind of activity a user performs in a channel.\n\n\n\n# Type Alias: ApiActivity\n\n> **ApiActivity** = \\{ `channel_id`: `string`; `created_at`: `string`; `id`: `string`; `interacted_at?`: `string` \\| `null`; `updated_at`: `string`; `user_id`: `string`; `viewed_at?`: `string` \\| `null`; \\}\n\nA user's activity (view/interaction) within a channel.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `created_at` | `string` | When the activity row was created. |\n| `id` | `string` | Activity id. |\n| `interacted_at?` | `string` \\| `null` | The last time the user interacted with the channel. |\n| `updated_at` | `string` | When the activity row was last updated. |\n| `user_id` | `string` | User id. |\n| `viewed_at?` | `string` \\| `null` | The last time the user viewed the channel. |\n\n\n\n# Type Alias: ApiChannelAttachment\n\n> **ApiChannelAttachment** = \\{ `channel_id`: `string`; `created_at`: `string`; `entity_id`: `string`; `entity_type`: `string`; `height?`: `number` \\| `null`; `id`: `string`; `message_id`: `string`; `sender_id`: `string`; `width?`: `number` \\| `null`; \\}\n\nA channel-level attachment.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `created_at` | `string` | When the attachment was created. |\n| `entity_id` | `string` | Entity id. |\n| `entity_type` | `string` | Type of entity. |\n| `height?` | `number` \\| `null` | Height (for images). |\n| `id` | `string` | Attachment id. |\n| `message_id` | `string` | Message id this attachment belongs to. |\n| `sender_id` | `string` | The user who sent the message containing this attachment. |\n| `width?` | `number` \\| `null` | Width (for images). |\n\n\n\n# Type Alias: ApiChannelAttachmentsPage\n\n> **ApiChannelAttachmentsPage** = \\{ `items`: [`ApiChannelAttachment`](ApiChannelAttachment.md)[]; `next_cursor?`: `string` \\| `null`; \\}\n\nPaginated response of channel attachments.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `items` | [`ApiChannelAttachment`](ApiChannelAttachment.md)[] | Attachments on this page. |\n| `next_cursor?` | `string` \\| `null` | Cursor for the next page, null if no more pages. |\n\n\n\n# Type Alias: ApiChannelDetail\n\n> **ApiChannelDetail** = \\{ `channel_id`: `string`; `channel_name`: `string`; `channel_type`: [`ChannelType`](ChannelType.md); `participants`: [`ApiChannelParticipant`](ApiChannelParticipant.md)[]; \\}\n\nChannel detail: metadata and active participants.\n\nMessages are read through `/messages/channel/{channel_id}`.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `channel_name` | `string` | Resolved display name from the viewer's perspective. |\n| `channel_type` | [`ChannelType`](ChannelType.md) | Channel type. |\n| `participants` | [`ApiChannelParticipant`](ApiChannelParticipant.md)[] | Active participants. |\n\n\n\n# Type Alias: ApiChannelParticipant\n\n> **ApiChannelParticipant** = \\{ `channel_id`: `string`; `joined_at`: `string`; `role`: [`ApiParticipantRole`](ApiParticipantRole.md); `user_id`: `string`; \\}\n\nA channel participant.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `joined_at` | `string` | When the user joined. |\n| `role` | [`ApiParticipantRole`](ApiParticipantRole.md) | Role in the channel. |\n| `user_id` | `string` | User id. |\n\n\n\n# Type Alias: ApiParticipantRole\n\n> **ApiParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nParticipant role in a channel.\n\n\n\n# Type Alias: BotSenderProfile\n\n> **BotSenderProfile** = \\{ `avatar_url?`: `string` \\| `null`; `name`: `string`; \\}\n\nPublic bot profile attached to bot-authored messages.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `avatar_url?` | `string` \\| `null` | Bot avatar URL. |\n| `name` | `string` | Bot display name. |\n\n\n\n# Type Alias: ChannelLabel\n\n> **ChannelLabel** = \\{ `channelCount`: `number`; `channelIds`: `string`[]; `createdAt`: `string`; `id`: `string`; `name`: `string`; `rule?`: `null` \\| [`ChannelLabelRule`](ChannelLabelRule.md); `sortOrder`: `number`; `teamId?`: `string` \\| `null`; `updatedAt`: `string`; \\}\n\nA shared or account-private label grouping chat channels in the sidebar.\n\n`channel_ids` is viewer-relative: it lists only the labelled channels the\nrequesting user participates in. `channel_count` counts every channel in\nthe label so clients can warn accurately before a delete.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelCount` | `number` | All assignments for a manual label; visible matches for a smart tag. |\n| `channelIds` | `string`[] | Channels in this label that the requesting user participates in. |\n| `createdAt` | `string` | When the label was created. |\n| `id` | `string` | Stable label id. |\n| `name` | `string` | Display name, unique within the scope (case-insensitive). |\n| `rule?` | `null` \\| [`ChannelLabelRule`](ChannelLabelRule.md) | - |\n| `sortOrder` | `number` | Manual ordering value within the scope; lower sorts first. |\n| `teamId?` | `string` \\| `null` | Owning team, or `None` for account-private labels. |\n| `updatedAt` | `string` | When the label was last renamed or reordered. |\n\n\n\n# Type Alias: ChannelLabelRule\n\n> **ChannelLabelRule** = \\{ `attribute`: `\"name\"`; `contains`: `string`; \\}\n\nCase-insensitive, literal substring matching on the channel name.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attribute` | `\"name\"` | - |\n| `contains` | `string` | The substring to find anywhere in the name. |\n\n\n\n# Type Alias: ChannelSharePermission\n\n> **ChannelSharePermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `channel_id`: `string`; \\}\n\nThe channel share permission\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level for the channel |\n| `channel_id` | `string` | The channel id |\n\n\n\n# Type Alias: ChannelType\n\n> **ChannelType** = `\"public\"` \\| `\"private\"` \\| `\"direct_message\"` \\| `\"team\"`\n\nType of channel.\n\n\n\n# Type Alias: CountedReaction\n\n> **CountedReaction** = \\{ `emoji`: `string`; `users`: `string`[]; \\}\n\nReaction emoji and the users who added it.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `emoji` | `string` | Emoji being reacted with. |\n| `users` | `string`[] | User identifiers. |\n\n\n\n# Type Alias: DocumentId\n\n> **DocumentId** = `string`\n\nA validated document identifier. Historical document ids need not be UUIDs.\n\n\n\n# Type Alias: EntityPermission\n\n> **EntityPermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\} \\| \\{ `type`: `\"channel_view_only\"`; \\} \\| \\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\} \\| \\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\nA user's permission for an entity, discriminated by entity kind.\n\nItems (documents, chats, projects, threads) use access levels.\nChannels use view-only permission or participant roles.\n\n## Union Members\n\n### Type Literal\n\n\\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level the user has. |\n| `type` | `\"access_level\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"channel_view_only\"`; \\}\n\n***\n\n### Type Literal\n\n\\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`ParticipantRole`](ParticipantRole.md) | The role the user has in the channel. |\n| `type` | `\"channel_role\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`TeamRole`](TeamRole.md) | The role the user has in the team. |\n| `type` | `\"team_role\"` | - |\n\n\n\n# Type Alias: GetChannelAttachmentsResponses\n\n> **GetChannelAttachmentsResponses** = \\{ `200`: [`ApiChannelAttachmentsPage`](ApiChannelAttachmentsPage.md); \\}\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `200` | [`ApiChannelAttachmentsPage`](ApiChannelAttachmentsPage.md) |\n\n\n\n# Type Alias: GetChannelParticipantsResponses\n\n> **GetChannelParticipantsResponses** = \\{ `200`: [`ApiChannelParticipant`](ApiChannelParticipant.md)[]; \\}\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `200` | [`ApiChannelParticipant`](ApiChannelParticipant.md)[] |\n\n\n\n# Type Alias: ImportedAuthor\n\n> **ImportedAuthor** = \\{ `name`: `string`; \\}\n\nDisplay attribution for a comment imported from an external document.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `name` | `string` | Original author text; never interpreted as an authenticated principal. |\n\n\n\n# Type Alias: LinkShare\n\n> **LinkShare** = `\"PUBLIC\"` \\| `\"TEAM\"`\n\nDefines who can access an item through its share link.\n\n\n\n# Type Alias: LinkedAccount\n\n> **LinkedAccount** = \\{ `authorization_generation`: `number`; `id`: `string`; `identity_jid?`: `string` \\| `null`; `state`: [`LinkedAccountState`](LinkedAccountState.md); `user_id`: `string`; \\}\n\nOne person's account, never owned by a workspace.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `authorization_generation` | `number` | Explicit consent generation; reconnecting a socket never changes it. |\n| `id` | `string` | Stable account identity. |\n| `identity_jid?` | `string` \\| `null` | WhatsApp-verified identity, absent until the first pairing succeeds. |\n| `state` | [`LinkedAccountState`](LinkedAccountState.md) | Lifecycle. |\n| `user_id` | `string` | Authenticated owner. |\n\n\n\n# Type Alias: LinkedAccountState\n\n> **LinkedAccountState** = `\"pairing\"` \\| `\"connected\"` \\| `\"logged_out\"` \\| `\"disconnected\"`\n\nAccount lifecycle. Transport outages are not stored: a connected account\nstays connected while its session service reconnects.\n\n\n\n# Type Alias: LinkedAttachment\n\n> **LinkedAttachment** = \\{ `document_id?`: `string` \\| `null`; `file_name`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](LinkedAttachmentState.md); \\}\n\nOne attachment of a linked message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `document_id?` | `string` \\| `null` | The private document, once ready. |\n| `file_name` | `string` | Display filename. |\n| `mime` | `string` | Declared MIME type. |\n| `ordinal` | `number` | Position within the message. |\n| `size` | `number` | Declared size in bytes. |\n| `state` | [`LinkedAttachmentState`](LinkedAttachmentState.md) | Current state. |\n\n\n\n# Type Alias: LinkedAttachmentState\n\n> **LinkedAttachmentState** = `\"loading\"` \\| `\"ready\"` \\| `\"unavailable\"` \\| `\"unsupported\"`\n\nWhere an attachment of a linked message stands.\n\n\n\n# Type Alias: LinkedCapabilities\n\n> **LinkedCapabilities** = \\{ `attachment_limit_bytes`: `number`; `attachment_types`: `string`[]; `max_attachments`: `number`; `mutation_window_seconds`: `number`; `mutations`: [`LinkedMutation`](LinkedMutation.md)[]; `text_limit_bytes`: `number`; \\}\n\nOperations implemented for linked groups, independent of current permission.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachment_limit_bytes` | `number` | Largest attachment in bytes. |\n| `attachment_types` | `string`[] | Supported attachment MIME types. |\n| `max_attachments` | `number` | Attachments per send. |\n| `mutation_window_seconds` | `number` | Edits and deletes are offered this long after sending. |\n| `mutations` | [`LinkedMutation`](LinkedMutation.md)[] | Supported message operations. |\n| `text_limit_bytes` | `number` | Maximum UTF-8 bytes per text send. |\n\n\n\n# Type Alias: LinkedDeliveryState\n\n> **LinkedDeliveryState** = `\"pending\"` \\| `\"sending\"` \\| `\"unknown\"` \\| `\"accepted\"` \\| `\"sent\"` \\| `\"delivered\"` \\| `\"read\"` \\| `\"failed\"`\n\nObserved send state. `unknown` means the request may have reached WhatsApp;\nit is never sent again automatically.\n\n\n\n# Type Alias: LinkedGroupInfo\n\n> **LinkedGroupInfo** = \\{ `announce`: `boolean`; `community`: `boolean`; `disappearing`: `boolean`; `group?`: `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md); `jid`: `string`; `name`: `string`; `observedAt`: `string`; `participants`: [`LinkedParticipant`](LinkedParticipant.md)[]; `shared?`: `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md); \\}\n\nOne full metadata read of a group, never an incomplete membership delta.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `announce` | `boolean` | Only admins may post. |\n| `community` | `boolean` | Community announcement or parent group, outside the supported surface. |\n| `disappearing` | `boolean` | Disappearing messages are on; content is not retained. |\n| `group?` | `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md) | - |\n| `jid` | `string` | Remote group JID. |\n| `name` | `string` | Current subject. |\n| `observedAt` | `string` | When the session service read this metadata. |\n| `participants` | [`LinkedParticipant`](LinkedParticipant.md)[] | Full roster. |\n| `shared?` | `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md) | - |\n\n\n\n# Type Alias: LinkedGroupReference\n\n> **LinkedGroupReference** = \\{ `id`: `string`; `name`: `string`; \\}\n\nA group entity bound to a remote group.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Group entity id. |\n| `name` | `string` | Display name, following WhatsApp. |\n\n\n\n# Type Alias: LinkedIdentity\n\n> **LinkedIdentity** = \\{ `alternateJid?`: `string` \\| `null`; `displayName?`: `string` \\| `null`; `jid`: `string`; \\}\n\nVerified sender aliases, supplied only by protocol metadata.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `alternateJid?` | `string` \\| `null` | Verified alternate identity, never inferred from a name or phone typed by a user. |\n| `displayName?` | `string` \\| `null` | Untrusted display name. |\n| `jid` | `string` | Phone-number or LID account JID. |\n\n\n\n# Type Alias: LinkedMediaKind\n\n> **LinkedMediaKind** = `\"image\"` \\| `\"audio\"` \\| `\"video\"` \\| `\"document\"`\n\nAttachment categories WhatsApp distinguishes.\n\n\n\n# Type Alias: LinkedMutation\n\n> **LinkedMutation** = `\"reaction\"` \\| `\"edit\"` \\| `\"delete\"`\n\nDeliberate operations on an existing linked-group message.\n\n\n\n# Type Alias: LinkedParticipant\n\n> **LinkedParticipant** = [`LinkedIdentity`](LinkedIdentity.md) & \\{ `admin`: `boolean`; \\}\n\nCurrent remote participant; Macro access is a separate grant.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `admin` | `boolean` | Group admin; only admins post in announcement groups. |\n\n\n\n# Type Alias: LinkedReplyBlock\n\n> **LinkedReplyBlock** = `\"sending_disabled\"` \\| `\"no_account\"` \\| `\"disconnected\"` \\| `\"not_observing\"` \\| `\"not_allowed_in_group\"` \\| `\"group_unavailable\"`\n\nWhy the viewer cannot send now.\n\n\n\n# Type Alias: LinkedReplyContent\n\n> **LinkedReplyContent** = \\{ `text`: `string`; `type`: `\"text\"`; \\} \\| \\{ `caption?`: `string` \\| `null`; `type`: `\"media\"`; `upload_id`: `string`; \\} \\| \\{ `message_id`: `string`; `operation`: [`LinkedMutation`](LinkedMutation.md); `text?`: `string` \\| `null`; `type`: `\"mutation\"`; \\}\n\nContent of a deliberate send.\n\n## Union Members\n\n### Type Literal\n\n\\{ `text`: `string`; `type`: `\"text\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `text` | `string` | UTF-8 text, at most [`TEXT_LIMIT_BYTES`] bytes. |\n| `type` | `\"text\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `caption?`: `string` \\| `null`; `type`: `\"media\"`; `upload_id`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `caption?` | `string` \\| `null` | Optional caption; audio has none. |\n| `type` | `\"media\"` | - |\n| `upload_id` | `string` | The staged upload, which becomes the message's private document. |\n\n***\n\n### Type Literal\n\n\\{ `message_id`: `string`; `operation`: [`LinkedMutation`](LinkedMutation.md); `text?`: `string` \\| `null`; `type`: `\"mutation\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `message_id` | `string` | Existing group message, resolved to its WhatsApp source by the server. |\n| `operation` | [`LinkedMutation`](LinkedMutation.md) | Explicit operation. |\n| `text?` | `string` \\| `null` | Replacement text or emoji; absent for delete, empty to remove a reaction. |\n| `type` | `\"mutation\"` | - |\n\n\n\n# Type Alias: LinkedSendProgress\n\n> **LinkedSendProgress** = \\{ `created_at`: `string`; `error_code?`: `string` \\| `null`; `group_id`: `string`; `id`: `string`; `message_id?`: `string` \\| `null`; `payload`: [`LinkedSendReply`](LinkedSendReply.md); `state`: [`LinkedDeliveryState`](LinkedDeliveryState.md); `user_id`: `string`; \\}\n\nDurable result of a deliberate send.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Intent creation time. |\n| `error_code?` | `string` \\| `null` | Sanitized failure code. |\n| `group_id` | `string` | Group entity. |\n| `id` | `string` | Stable intent id. |\n| `message_id?` | `string` \\| `null` | Group message, once WhatsApp accepted it. |\n| `payload` | [`LinkedSendReply`](LinkedSendReply.md) | The original request, so a failed draft can be recovered. |\n| `state` | [`LinkedDeliveryState`](LinkedDeliveryState.md) | Current state. |\n| `user_id` | `string` | Person who submitted it. |\n\n\n\n# Type Alias: LinkedSendReply\n\n> **LinkedSendReply** = \\{ `idempotency_key`: `string`; `message`: [`LinkedReplyContent`](LinkedReplyContent.md); `reply_to?`: `string` \\| `null`; \\}\n\nExplicit send action from a person. Only deliberate sends reach WhatsApp.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `idempotency_key` | `string` | Stable client intent key. A changed payload with this key is a conflict. |\n| `message` | [`LinkedReplyContent`](LinkedReplyContent.md) | Content. |\n| `reply_to?` | `string` \\| `null` | Group message being quoted, within this group. |\n\n\n\n# Type Alias: LinkedSharedGroupReference\n\n> **LinkedSharedGroupReference** = \\{ `id`: `string`; `name`: `string`; `owner_id`: `string`; \\}\n\nAnother person's group entity the caller can view.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Group entity id. |\n| `name` | `string` | Display name, following WhatsApp. |\n| `owner_id` | `string` | Macro user who added the group and shared it. |\n\n\n\n# Type Alias: LinkedUploadedAttachment\n\n> **LinkedUploadedAttachment** = \\{ `filename`: `string`; `kind`: [`LinkedMediaKind`](LinkedMediaKind.md); `upload_id`: `string`; \\}\n\nA staged attachment, sent only by a later deliberate send.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `filename` | `string` | Display filename. |\n| `kind` | [`LinkedMediaKind`](LinkedMediaKind.md) | Category. |\n| `upload_id` | `string` | Use as `upload_id` in a media send; also the future document id. |\n\n\n\n# Type Alias: Message\n\n> **Message** = \\{ `attachments`: [`MessageAttachment`](MessageAttachment.md)[]; `bot_profile?`: `null` \\| [`BotSenderProfile`](BotSenderProfile.md); `content`: `string`; `created_at`: `string`; `deleted_at?`: `string` \\| `null`; `edited_at?`: `string` \\| `null`; `guest_name?`: `string` \\| `null`; `id`: `string`; `imported_author?`: `null` \\| [`ImportedAuthor`](ImportedAuthor.md); `mentions`: [`SimpleMention`](SimpleMention.md)[]; `parent`: [`MessageParent`](MessageParent.md); `reactions`: [`CountedReaction`](CountedReaction.md)[]; `sender_id`: `string`; `thread_id?`: `string` \\| `null`; `triggered_by?`: `string` \\| `null`; `updated_at`: `string`; \\}\n\nShared message representation for channel timelines and entity discussions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachments` | [`MessageAttachment`](MessageAttachment.md)[] | Attached entities. |\n| `bot_profile?` | `null` \\| [`BotSenderProfile`](BotSenderProfile.md) | - |\n| `content` | `string` | Macro Markdown body. |\n| `created_at` | `string` | Creation time. |\n| `deleted_at?` | `string` \\| `null` | Message tombstone, independent of thread deletion. |\n| `edited_at?` | `string` \\| `null` | Last content edit, if any. |\n| `guest_name?` | `string` \\| `null` | Display name of a verified call guest, retained after the call ends. |\n| `id` | `string` | Message UUID. |\n| `imported_author?` | `null` \\| [`ImportedAuthor`](ImportedAuthor.md) | - |\n| `mentions` | [`SimpleMention`](SimpleMention.md)[] | Tracked mentions, retained when a caller changes attachments only. |\n| `parent` | [`MessageParent`](MessageParent.md) | Entity that owns this conversation. |\n| `reactions` | [`CountedReaction`](CountedReaction.md)[] | Aggregated reactions. |\n| `sender_id` | `string` | Authenticated actor or owner of imported content. |\n| `thread_id?` | `string` \\| `null` | Root message UUID for replies; absent on roots. |\n| `triggered_by?` | `string` \\| `null` | User who triggered a bot-authored message. |\n| `updated_at` | `string` | Last persisted update. |\n\n\n\n# Type Alias: MessageAttachment\n\n> **MessageAttachment** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: `string`; `height?`: `number` \\| `null`; `id`: `string`; `width?`: `number` \\| `null`; \\}\n\nAn entity attached to a message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | When the attachment was added. |\n| `entity_id` | `string` | Attached entity identifier. |\n| `entity_type` | `string` | Attached entity type. |\n| `height?` | `number` \\| `null` | Optional media height. |\n| `id` | `string` | Attachment UUID. |\n| `width?` | `number` \\| `null` | Optional media width. |\n\n\n\n# Type Alias: MessageCursor\n\n> **MessageCursor** = \\{ `created_at`: `string`; `id`: `string`; \\}\n\nCursor for a chronological parent timeline.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Last message creation time or activity occurrence time. |\n| `id` | `string` | Last entry UUID, used to break timestamp ties across both sources. |\n\n\n\n# Type Alias: MessageParent\n\n> **MessageParent** = \\{ `id`: `string`; `type`: `\"channel\"`; \\} \\| \\{ `id`: [`DocumentId`](DocumentId.md); `type`: `\"document\"`; \\} \\| \\{ `id`: `string`; `type`: `\"initiative\"`; \\} \\| \\{ `id`: `string`; `type`: `\"crm_company\"`; \\} \\| \\{ `id`: `string`; `type`: `\"crm_contact\"`; \\} \\| \\{ `id`: `string`; `type`: `\"call\"`; \\}\n\nThe entity whose permissions and lifecycle govern a message.\n\n## Union Members\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"channel\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A channel, including direct messages. |\n| `type` | `\"channel\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: [`DocumentId`](DocumentId.md); `type`: `\"document\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | [`DocumentId`](DocumentId.md) | A document, including tasks and PDFs. |\n| `type` | `\"document\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"initiative\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | An initiative, presented as a project in the application. |\n| `type` | `\"initiative\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"crm_company\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A CRM company. |\n| `type` | `\"crm_company\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"crm_contact\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A CRM contact. |\n| `type` | `\"crm_contact\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"call\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A video call and its persistent chat thread. |\n| `type` | `\"call\"` | - |\n\n\n\n# Type Alias: ParticipantRole\n\n> **ParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nThe role a user has within a channel.\n\n\n\n# Type Alias: SharePermissionV2\n\n> **SharePermissionV2** = \\{ `channelSharePermissions?`: [`ChannelSharePermission`](ChannelSharePermission.md)[] \\| `null`; `id`: `string`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `owner`: `string`; `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`ChannelSharePermission`](ChannelSharePermission.md)[] \\| `null` | The channel share permissions for the item |\n| `id` | `string` | The share permission id |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `owner` | `string` | The owner of the item |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: SimpleMention\n\n> **SimpleMention** = \\{ `entity_id`: `string`; `entity_type`: `string`; \\}\n\nA mention tracked in a message body.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Mentioned entity identifier. |\n| `entity_type` | `string` | Mentioned entity type. |\n\n\n\n# Type Alias: SmartTagChannelMatch\n\n> **SmartTagChannelMatch** = \\{ `id`: `string`; `name`: `string`; \\}\n\nA channel visible to the caller that matches a smart tag rule.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Channel id. |\n| `name` | `string` | Channel display name. |\n\n\n\n# Type Alias: SmartTagPreview\n\n> **SmartTagPreview** = \\{ `channels`: [`SmartTagChannelMatch`](SmartTagChannelMatch.md)[]; `totalCount`: `number`; \\}\n\nA bounded preview and the total number of visible channels matching a rule.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channels` | [`SmartTagChannelMatch`](SmartTagChannelMatch.md)[] | First matches, in alphabetical order. |\n| `totalCount` | `number` | Number of matching channels the caller participates in, including overflow. |\n\n\n\n# Type Alias: TeamRole\n\n> **TeamRole** = `\"member\"` \\| `\"admin\"` \\| `\"owner\"`\n\nThe role a user has within a team.\n\nOrdered least to most privileged so comparisons reflect access strength.\n\n\n\n# Type Alias: UpdateChannelSharePermission\n\n> **UpdateChannelSharePermission** = \\{ `accessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `channelId`: `string`; `operation`: [`UpdateOperation`](UpdateOperation.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `accessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `channelId` | `string` | The channel id |\n| `operation` | [`UpdateOperation`](UpdateOperation.md) | The type of operation to be performed on the chanel share permission You can add, remove or replace and existing permission |\n\n\n\n# Type Alias: UpdateOperation\n\n> **UpdateOperation** = `\"add\"` \\| `\"remove\"` \\| `\"replace\"`\n\n\n\n# Type Alias: UpdateSharePermissionRequestV2\n\n> **UpdateSharePermissionRequestV2** = \\{ `channelSharePermissions?`: [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null` | Any channel share permissions to be created/updated/removed |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: WhatsAppGroupDetail\n\n> **WhatsAppGroupDetail** = [`WhatsAppGroupSummary`](WhatsAppGroupSummary.md) & \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `limits`: [`LinkedCapabilities`](LinkedCapabilities.md); `roster?`: `null` \\| [`LinkedGroupInfo`](LinkedGroupInfo.md); `sending_identity?`: `string` \\| `null`; `share_permission`: [`SharePermissionV2`](SharePermissionV2.md); \\}\n\nFull group detail and current viewer capabilities.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | Caller's effective permission. |\n| `limits` | [`LinkedCapabilities`](LinkedCapabilities.md) | Size and mutation limits. |\n| `roster?` | `null` \\| [`LinkedGroupInfo`](LinkedGroupInfo.md) | - |\n| `sending_identity?` | `string` \\| `null` | Caller's own phone identity, never another account's identity. |\n| `share_permission` | [`SharePermissionV2`](SharePermissionV2.md) | Owner-controlled standard sharing configuration. |\n\n\n\n# Type Alias: WhatsAppGroupMessage\n\n> **WhatsAppGroupMessage** = \\{ `attachments`: [`LinkedAttachment`](LinkedAttachment.md)[]; `body`: `string`; `deleted`: `boolean`; `delivery_state?`: `null` \\| [`LinkedDeliveryState`](LinkedDeliveryState.md); `edited_at?`: `string` \\| `null`; `id`: `string`; `reactions`: [`WhatsAppGroupReaction`](WhatsAppGroupReaction.md)[]; `received_at`: `string`; `reply_to?`: `string` \\| `null`; `sender`: [`WhatsAppGroupSender`](WhatsAppGroupSender.md); `sent_at`: `string`; \\}\n\nOne message in an adopted group.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachments` | [`LinkedAttachment`](LinkedAttachment.md)[] | Imported or pending attachments. |\n| `body` | `string` | Plain WhatsApp text. |\n| `deleted` | `boolean` | Deleted for everyone. |\n| `delivery_state?` | `null` \\| [`LinkedDeliveryState`](LinkedDeliveryState.md) | - |\n| `edited_at?` | `string` \\| `null` | Last edit timestamp. |\n| `id` | `string` | Stable message id. |\n| `reactions` | [`WhatsAppGroupReaction`](WhatsAppGroupReaction.md)[] | Reactions grouped by emoji. |\n| `received_at` | `string` | Timestamp first received by Macro. |\n| `reply_to?` | `string` \\| `null` | Message quoted by this one. |\n| `sender` | [`WhatsAppGroupSender`](WhatsAppGroupSender.md) | Sender. |\n| `sent_at` | `string` | Timestamp assigned by WhatsApp. |\n\n\n\n# Type Alias: WhatsAppGroupReaction\n\n> **WhatsAppGroupReaction** = \\{ `count`: `number`; `emoji`: `string`; `mine`: `boolean`; \\}\n\nGrouped reactions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `count` | `number` | Number of reacting people. |\n| `emoji` | `string` | Emoji. |\n| `mine` | `boolean` | Caller has this reaction. |\n\n\n\n# Type Alias: WhatsAppGroupSender\n\n> **WhatsAppGroupSender** = \\{ `name`: `string`; `person_id`: `string`; `user_id?`: `string` \\| `null`; \\}\n\nMessage sender from protocol-verified identity evidence.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `name` | `string` | Display name, never authentication evidence. |\n| `person_id` | `string` | External person identity. |\n| `user_id?` | `string` \\| `null` | Verified Macro user association, if present. |\n\n\n\n# Type Alias: WhatsAppGroupSummary\n\n> **WhatsAppGroupSummary** = \\{ `can_send`: `boolean`; `id`: `string`; `last_message_at?`: `string` \\| `null`; `name`: `string`; `send_reason?`: `null` \\| [`LinkedReplyBlock`](LinkedReplyBlock.md); `unread_count`: `number`; `user_id`: `string`; \\}\n\nAdopted group visible through ordinary entity sharing.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `can_send` | `boolean` | Caller may currently send from their own account. |\n| `id` | `string` | Entity identifier. |\n| `last_message_at?` | `string` \\| `null` | Latest message timestamp. |\n| `name` | `string` | Display name. |\n| `send_reason?` | `null` \\| [`LinkedReplyBlock`](LinkedReplyBlock.md) | - |\n| `unread_count` | `number` | Unread live messages for this viewer. |\n| `user_id` | `string` | Actual entity owner. |\n\n\n\n# Class: ChannelActivity\n\nA user's channel activity marker.\n\n## Constructors\n\n### Constructor\n\n> **new ChannelActivity**(`client`, `channel`, `record`): `ChannelActivity`\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `channel` | [`Channel`](../../channel/classes/Channel.md) | Related channel. |\n| `record` | [`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md) | - |\n\n#### Returns\n\n`ChannelActivity`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `channel` | `readonly` | [`Channel`](../../channel/classes/Channel.md) | Related channel. |\n\n## Accessors\n\n### id\n\n#### Get Signature\n\n> **get** **id**(): `string`\n\nActivity identity.\n\n##### Returns\n\n`string`\n\n## Methods\n\n### createdAt()\n\n> **createdAt**(): `string`\n\nCreation time.\n\n#### Returns\n\n`string`\n\n***\n\n### recordInteraction()\n\n> **recordInteraction**(`type`): `Promise`\\<`ChannelActivity`\\>\n\nRecord a view or interaction in this channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `type` | [`ActivityType`](../../../../../generated/storage/types.gen/type-aliases/ActivityType.md) |\n\n#### Returns\n\n`Promise`\\<`ChannelActivity`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): [`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md)\n\nSerialize activity without credentials.\n\n#### Returns\n\n[`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md)\n\n***\n\n### user()\n\n> **user**(): [`User`](../../../users/user/classes/User.md)\n\nUser who interacted.\n\n#### Returns\n\n[`User`](../../../users/user/classes/User.md)\n\n\n\n# Class: Channel\n\nA channel.\n\n## Extends\n\n- [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md)\\<`ChannelDetail`\\>\n\n## Properties\n\n| Property | Modifier | Type | Default value | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `readonly` | `\"channel\"` | `'channel'` | Favorites identify channels as `channel`. | [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`entityType`](../../../entity/classes/PropertiedEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | `undefined` | - | - | [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`id`](../../../entity/classes/PropertiedEntity.md#property-id) |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | `...` | The channel's display name, resolved from the viewer's perspective. | - | - |\n| `type` | `readonly` | () => `Promise`\\<[`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md)\\> | `...` | The channel's type (e.g. `public`, `dm`, `private`). | - | - |\n| `search` | `static` | (`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`Channel`\\> | `...` | Search channels by content, most relevant first, auto-paginated. | - | - |\n\n## Methods\n\n### addParticipants()\n\n> **addParticipants**(`users`): `Promise`\\<`void`\\>\n\nAdd users to the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `users` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### agentConversations()\n\n> **agentConversations**(): `Promise`\\<[`AgentConversation`](../../../agent-sessions/conversation/classes/AgentConversation.md)[]\\>\n\nConversations maintained by agents in this channel.\n\n#### Returns\n\n`Promise`\\<[`AgentConversation`](../../../agent-sessions/conversation/classes/AgentConversation.md)[]\\>\n\n***\n\n### attachments()\n\n> **attachments**(`opts?`): `AsyncGenerator`\\<[`ApiChannelAttachment`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelAttachment.md)\\>\n\nThe attachments posted in this channel, auto-paginated.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts?` | \\{ `pageSize?`: `number`; `type?`: `string`; \\} | - |\n| `opts.pageSize?` | `number` | - |\n| `opts.type?` | `string` | Filter by type: `static` for images/videos, `dss` for documents. |\n\n#### Returns\n\n`AsyncGenerator`\\<[`ApiChannelAttachment`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelAttachment.md)\\>\n\n***\n\n### delete()\n\n> **delete**(): `Promise`\\<`void`\\>\n\nDelete the channel. This is not reversible.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\nRemove a property from this entity, given its [properties](#properties) entry.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`deleteProperty`](../../../entity/classes/PropertiedEntity.md#deleteproperty)\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Channel`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`favorite`](../../../entity/classes/PropertiedEntity.md#favorite)\n\n***\n\n### join()\n\n> **join**(): `Promise`\\<`void`\\>\n\nJoin the channel as the current user.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### joinCode()\n\n> **joinCode**(): `Promise`\\<`string`\\>\n\nA reusable code that lets a user join this channel.\n\n#### Returns\n\n`Promise`\\<`string`\\>\n\n***\n\n### leave()\n\n> **leave**(): `Promise`\\<`void`\\>\n\nLeave the channel as the current user.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### message()\n\n> **message**(`id`): [`Message`](../../message/classes/Message.md)\n\nA handle to a message in this channel by id.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Message`](../../message/classes/Message.md)\n\n***\n\n### messages()\n\n> **messages**(`opts?`): `AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\nRoot messages in this channel, most recent first, auto-paginated.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `pageSize?`: `number`; \\} |\n| `opts.pageSize?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### messagesAfter()\n\n> **messagesAfter**(`after`, `opts?`): `AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\nRoot messages created or replied to at or after `after`, most recent\nfirst, auto-paginated. Use it to catch up after a disconnect.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `after` | `string` \\| `Date` |\n| `opts?` | \\{ `pageSize?`: `number`; \\} |\n| `opts.pageSize?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### messageThreadById()\n\n> **messageThreadById**(`id`): [`MessageThread`](../../../messages/thread/classes/MessageThread.md)\n\nA shared message thread scoped to this resource.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`MessageThread`](../../../messages/thread/classes/MessageThread.md)\n\n***\n\n### participants()\n\n> **participants**(): `Promise`\\<[`ApiChannelParticipant`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelParticipant.md)[]\\>\n\nThe channel's members, with their roles and join times.\n\n#### Returns\n\n`Promise`\\<[`ApiChannelParticipant`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelParticipant.md)[]\\>\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`permission`](../../../entity/classes/PropertiedEntity.md#permission)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\nThe properties set on this entity, each with its definition, value, and options.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`properties`](../../../entity/classes/PropertiedEntity.md#properties)\n\n***\n\n### propertyReference()\n\n> **propertyReference**(): [`PropertyTargetReference`](../../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\nThis entity's reference for bulk property operations.\n\n#### Returns\n\n[`PropertyTargetReference`](../../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`propertyReference`](../../../entity/classes/PropertiedEntity.md#propertyreference)\n\n***\n\n### recordActivity()\n\n> **recordActivity**(`type`): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)\\>\n\nRecord a view or interaction in this channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `type` | [`ActivityType`](../../../../../generated/storage/types.gen/type-aliases/ActivityType.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)\\>\n\n***\n\n### removeParticipants()\n\n> **removeParticipants**(`users`): `Promise`\\<`void`\\>\n\nRemove users from the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `users` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### rename()\n\n> **rename**(`name`): `Promise`\\<`void`\\>\n\nRename the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `name` | `string` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### send()\n\n> **send**(`body`, `opts?`): `Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nPost a message. Plain text, or a rich body composed with `msg`.\n\nWorks with a channel webhook token as well as a normal one — see\n[postToChannel](../../post/functions/postToChannel.md) for which endpoint that picks and what it costs.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n| `opts?` | \\{ `thread?`: [`Thread`](../../thread/classes/Thread.md); \\} |\n| `opts.thread?` | [`Thread`](../../thread/classes/Thread.md) |\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### setPicture()\n\n> **setPicture**(`picture?`): `Promise`\\<`void`\\>\n\nSet an uploaded profile picture, or clear it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `picture?` | [`ChannelPicture`](../../picture/classes/ChannelPicture.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\nSet a property value on this entity, or attach the property without a\nvalue when `value` is omitted.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`setProperty`](../../../entity/classes/PropertiedEntity.md#setproperty)\n\n***\n\n### timelinePage()\n\n> **timelinePage**(`selection?`): `Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: [`Message`](../../message/classes/Message.md); `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\nA mixed message and activity timeline page.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `selection?` | [`TimelineOptions`](../../../messages/thread/interfaces/TimelineOptions.md)\\<[`Message`](../../message/classes/Message.md)\\> |\n\n#### Returns\n\n`Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: [`Message`](../../message/classes/Message.md); `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`toJSON`](../../../entity/classes/PropertiedEntity.md#tojson)\n\n***\n\n### typing()\n\n> **typing**(`action`, `opts?`): `Promise`\\<`void`\\>\n\nBroadcast a typing indicator, optionally scoped to a thread.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `action` | `\"stop\"` \\| `\"start\"` |\n| `opts?` | \\{ `thread?`: [`Thread`](../../thread/classes/Thread.md); \\} |\n| `opts.thread?` | [`Thread`](../../thread/classes/Thread.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Channel`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`unfavorite`](../../../entity/classes/PropertiedEntity.md#unfavorite)\n\n***\n\n### updatePropertyOptions()\n\n> **updatePropertyOptions**(`changes`): `Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\nApply multi-select option deltas atomically across this entity's properties.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `changes` | [`PropertyOptionDelta`](../../../entity/interfaces/PropertyOptionDelta.md)[] |\n\n#### Returns\n\n`Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`updatePropertyOptions`](../../../entity/classes/PropertiedEntity.md#updatepropertyoptions)\n\n***\n\n### webUrl()\n\n> **webUrl**(): `string`\n\nThe channel's URL in the Macro web app.\n\n#### Returns\n\n`string`\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `Channel`\n\nA handle to a channel by id. Details load on first access.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`Channel`\n\n***\n\n### create()\n\n> `static` **create**(`client`, `opts`): `Promise`\\<`Channel`\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n***\n\n### dm()\n\n> `static` **dm**(`client`, `recipient`): `Promise`\\<`Channel`\\>\n\nOpen (creating if needed) the DM channel with a user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n***\n\n### private()\n\n> `static` **private**(`client`, `recipients`): `Promise`\\<`Channel`\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n\n\n# Type Alias: ChannelAttachment\n\n> **ChannelAttachment** = [`GetChannelAttachmentsResponses`](../../../../../generated/storage/types.gen/type-aliases/GetChannelAttachmentsResponses.md)\\[`200`\\]\\[`\"items\"`\\]\\[`number`\\]\n\nA file or entity attached to a message in a channel.\n\n\n\n# Type Alias: ChannelParticipant\n\n> **ChannelParticipant** = [`GetChannelParticipantsResponses`](../../../../../generated/storage/types.gen/type-aliases/GetChannelParticipantsResponses.md)\\[`200`\\]\\[`number`\\]\n\nA member of a channel, with their role and join time.\n\n\n\n# Class: ChannelLabelsNamespace\n\nShared or private channel labels: named groups of channels shown in the Chat\nsidebar. Every member of the team sees the same labels in the same order,\nand any member may create, rename, delete, or move channels between them;\neach change applies to the whole team. Users without a team have private\nlabels belonging to their account.\n\nA label's `channelIds` lists only the channels the authenticated user is a\nmember of. Manual labels count all assignments; smart tags count visible\nmatches. A channel can be in one manual label and any number of matching\nsmart tags per team or account. Direct messages cannot be grouped.\n\n## Constructors\n\n### Constructor\n\n> **new ChannelLabelsNamespace**(`client`): `ChannelLabelsNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelLabelsNamespace`\n\n## Methods\n\n### create()\n\n> **create**(`name`, `channels?`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nCreate a label and atomically move `channels` into it. Names are unique\nwithin the team or account, case-insensitively.\n\n#### Parameters\n\n| Parameter | Type | Default value |\n| ------ | ------ | ------ |\n| `name` | `string` | `undefined` |\n| `channels?` | [`Channel`](../../channel/classes/Channel.md)[] | `[]` |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### createSmartTag()\n\n> **createSmartTag**(`name`, `rule`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nCreate a smart tag whose membership follows an attribute rule automatically.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `name` | `string` |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### delete()\n\n> **delete**(`label`): `Promise`\\<`void`\\>\n\nDelete a label for the whole team; its channels return to the plain list.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)[]\\>\n\nEvery label in the authenticated user's shared or private scope.\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)[]\\>\n\n***\n\n### previewSmartTag()\n\n> **previewSmartTag**(`rule`): `Promise`\\<[`SmartTagPreview`](../../../../../generated/storage/types.gen/type-aliases/SmartTagPreview.md)\\>\n\nPreview the first matches and total visible count without creating a tag.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`SmartTagPreview`](../../../../../generated/storage/types.gen/type-aliases/SmartTagPreview.md)\\>\n\n***\n\n### rename()\n\n> **rename**(`label`, `name`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nRename a label for the whole team.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n| `name` | `string` |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### setLabel()\n\n> **setLabel**(`channel`, `label`): `Promise`\\<`void`\\>\n\nMove a channel into `label`, or out of any label when `label` is `undefined`.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `channel` | [`Channel`](../../channel/classes/Channel.md) |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) \\| `undefined` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### updateSmartTag()\n\n> **updateSmartTag**(`label`, `name`, `rule`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nUpdate the name and matching rule of an existing smart tag.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n| `name` | `string` |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n\n\n# Class: Message\n\nA message in a channel. A thin handle: `id` and `channelId` are known up\nfront, and record-backed fields (`content`, `author`) load lazily on first\naccess and cache. Actions carry the ids for you.\n\n## Extends\n\n- [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md)\\<[`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Default value | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n| `channelId` | `readonly` | `string` | `undefined` | - | - | - |\n| `content` | `readonly` | () => `Promise`\\<`string`\\> | `...` | The message body. | - | - |\n| `createdAt` | `readonly` | () => `Promise`\\<`string`\\> | `...` | When the message was created. | - | - |\n| `editedAt` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | `...` | When the message was last edited, if it has been. | - | - |\n| `entityType` | `readonly` | `\"channel_message\"` | `'channel_message'` | Favorites identify channel messages as `channel_message`. | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`entityType`](../../../entity/classes/FavoritableEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | `undefined` | - | - | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`id`](../../../entity/classes/FavoritableEntity.md#property-id) |\n| `mentions` | `readonly` | [`SimpleMention`](../../../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] | `[]` | Entities mentioned in this message, when a list, thread, or event supplied them. | - | - |\n| `updatedAt` | `readonly` | () => `Promise`\\<`string`\\> | `...` | When the message was last updated. | - | - |\n\n## Methods\n\n### author()\n\n> **author**(): `Promise`\\<[`User`](../../../users/user/classes/User.md)\\>\n\nThe user who sent this message.\n\n#### Returns\n\n`Promise`\\<[`User`](../../../users/user/classes/User.md)\\>\n\n***\n\n### channel()\n\n> **channel**(): [`Channel`](../../channel/classes/Channel.md)\n\nThe channel this message is in.\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### delete()\n\n> **delete**(): `Promise`\\<`void`\\>\n\nDelete this message.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### edit()\n\n> **edit**(`body`): `Promise`\\<`Message`\\>\n\nReplace this message's body.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) | Plain text, or a rich body composed with msg. |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Message`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`favorite`](../../../entity/classes/FavoritableEntity.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`permission`](../../../entity/classes/FavoritableEntity.md#permission)\n\n***\n\n### react()\n\n> **react**(`emoji`): `Promise`\\<`Message`\\>\n\nAdd an emoji reaction to this message.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `emoji` | `string` |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### reply()\n\n> **reply**(`body`): `Promise`\\<`Message`\\>\n\nPost a reply in this message's thread.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### thread()\n\n> **thread**(): [`Thread`](../../thread/classes/Thread.md)\n\nThe thread rooted at this message.\n\n#### Returns\n\n[`Thread`](../../thread/classes/Thread.md)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`toJSON`](../../../entity/classes/FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Message`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`unfavorite`](../../../entity/classes/FavoritableEntity.md#unfavorite)\n\n***\n\n### unreact()\n\n> **unreact**(`emoji`): `Promise`\\<`Message`\\>\n\nRemove one of your emoji reactions from this message.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `emoji` | `string` |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `channelId`, `id`, `mentions?`): `Message`\n\nA handle to a message by id. Fields load on first access.\n\n#### Parameters\n\n| Parameter | Type | Default value |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | `undefined` |\n| `channelId` | `string` | `undefined` |\n| `id` | `string` | `undefined` |\n| `mentions?` | [`SimpleMention`](../../../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] | `[]` |\n\n#### Returns\n\n`Message`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `channelId`, `data`): `Message`\n\nBuild a root or reply from a message record (pre-seeded, no fetch).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `channelId` | `string` |\n| `data` | [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md) |\n\n#### Returns\n\n`Message`\n\n\n\n# Type Alias: MessageData\n\n> **MessageData** = [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md)\n\nThe API's representation of a message; the same record the document comment API returns.\n\n\n\n# Class: ChannelNamespace\n\n## Constructors\n\n### Constructor\n\n> **new ChannelNamespace**(`client`): `ChannelNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelNamespace`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `labels` | `readonly` | [`ChannelLabelsNamespace`](../../labels/classes/ChannelLabelsNamespace.md) | Team-shared labels that group channels in the Chat sidebar. |\n\n## Methods\n\n### activity()\n\n> **activity**(): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\nRecent channel activity, with channel and user handles.\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`Channel`](../../channel/classes/Channel.md)\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### create()\n\n> **create**(`opts`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### dm()\n\n> **dm**(`recipient`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\nAll channels the authenticated user is a member of.\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\n***\n\n### private()\n\n> **private**(`recipients`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### search()\n\n> **search**(`query`, `opts?`): `AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nSearch channels by name (client-side fuzzy filter on the full channel list)\nor by content (server-side unified search).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `query` | `string` |\n| `opts?` | [`SearchOpts`](../../../search/interfaces/SearchOpts.md) |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n\n\n# Class: ChannelPicture\n\nAn uploaded channel profile picture in static file storage.\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `id` | `readonly` | `string` |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `id`: `string`; \\}\n\nSerialize the uploaded picture reference.\n\n#### Returns\n\n\\{ `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n***\n\n### byId()\n\n> `static` **byId**(`id`): `ChannelPicture`\n\nConstruct a reference from the upload receipt.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n`ChannelPicture`\n\n\n\n# Function: postToChannel()\n\n> **postToChannel**(`client`, `target`, `body`): `Promise`\\<`string`\\>\n\nPost a message using the endpoint supported by the caller's credentials.\n\nMost credentials use `POST /messages/channel/{id}`. User-owned bots without\nan acting user instead use `POST /channels/{id}/webhook`, which authorizes\nthrough channel membership. The bot owner is read from `GET /bots/me` and\ncached by the client.\n\nThe webhook endpoint supports content only. Mentions in `` tags still\nwork, but threads and attachments are not supported.\n\nPosting to a `Thread` puts the message in that thread; to a `Channel`, at the\nchannel root. One target rather than a channel plus a thread id, so the two\ncan't disagree.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `target` | [`Channel`](../../channel/classes/Channel.md) \\| [`Thread`](../../thread/classes/Thread.md) |\n| `body` | [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n\n## Returns\n\n`Promise`\\<`string`\\>\n\n\n\n# Class: Thread\n\nA thread within a channel, rooted at a top-level message. Replies and\nthread-scoped posting live here.\n\n## Constructors\n\n### Constructor\n\n> **new Thread**(`client`, `channelId`, `rootId`): `Thread`\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `channelId` | `string` | - |\n| `rootId` | `string` | The id of the message this thread hangs off. |\n\n#### Returns\n\n`Thread`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `channelId` | `readonly` | `string` | - |\n| `rootId` | `readonly` | `string` | The id of the message this thread hangs off. |\n\n## Methods\n\n### channel()\n\n> **channel**(): [`Channel`](../../channel/classes/Channel.md)\n\nThe channel this thread is in.\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### replies()\n\n> **replies**(): `Promise`\\<[`Message`](../../message/classes/Message.md)[]\\>\n\nList the replies in this thread, oldest first.\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)[]\\>\n\n***\n\n### reply()\n\n> **reply**(`body`): `Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nPost a reply in this thread.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) | Plain text, or a rich body composed with msg. |\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nThe created reply.\n\n***\n\n### root()\n\n> **root**(): [`Message`](../../message/classes/Message.md)\n\nThe message this thread hangs off.\n\n#### Returns\n\n[`Message`](../../message/classes/Message.md)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `channelId`: `string`; `rootId`: `string`; \\}\n\nSerialize the thread identity without its authenticated client.\n\n#### Returns\n\n\\{ `channelId`: `string`; `rootId`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `channelId` | `string` |\n| `rootId` | `string` |\n\n\n\n# Class: WhatsAppAccount\n\nThe current user's WhatsApp account, connected through the Macro app.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `identity` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Verified remote identity, absent until pairing succeeds. | - |\n| `owner` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | The Macro user who owns this account. | - |\n| `state` | `readonly` | () => `Promise`\\<[`LinkedAccountState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccountState.md)\\> | Account connection state; call refresh before polling it again. | - |\n\n## Methods\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppAccount`\\>\n\nDiscard cached connection state and load its current value.\n\n#### Returns\n\n`Promise`\\<`WhatsAppAccount`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppAccount`\n\nReference an account; reads still enforce the authenticated owner's scope.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppAccount`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `record`): `WhatsAppAccount`\n\nSeed an account handle from an API record.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `record` | [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md) |\n\n#### Returns\n\n`WhatsAppAccount`\n\n\n\n# Class: WhatsAppGroup\n\nIndependently shareable adopted WhatsApp group entity.\n\n## Extends\n\n- [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md)\\<[`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ |\n| `canSend` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether the caller can send from their own connected account. | - | - |\n| `entityType` | `readonly` | `\"whatsapp_group\"` | Canonical sharing and favorites kind. | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`entityType`](../../../entity/classes/FavoritableEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | - | - | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`id`](../../../entity/classes/FavoritableEntity.md#property-id) |\n| `limits` | `readonly` | () => `Promise`\\<[`LinkedCapabilities`](../../../../../generated/storage/types.gen/type-aliases/LinkedCapabilities.md)\\> | Supported sizes and mutation window. | - | - |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | Display name. | - | - |\n| `owner` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | Actual owner, independent of WhatsApp membership. | - | - |\n| `roster` | `readonly` | () => `Promise`\\<[`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) \\| `undefined`\\> | Current remote roster, when available. | - | - |\n| `sendingIdentity` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Caller's own verified sending identity. | - | - |\n| `sendReason` | `readonly` | () => `Promise`\\<`NonNullable`\\ \\| `undefined`\\> | Reason sending is blocked. | - | - |\n| `unreadCount` | `readonly` | () => `Promise`\\<`number`\\> | Per-user unread count. | - | - |\n\n## Methods\n\n### delivery()\n\n> **delivery**(`sends`): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\nRead delivery for selected caller-owned intents or messages.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `sends` | ([`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) \\| [`WhatsAppSend`](../../send/classes/WhatsAppSend.md))[] |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\n***\n\n### detach()\n\n> **detach**(): `Promise`\\<`void`\\>\n\nStop observation while preserving history and established sharing.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`WhatsAppGroup`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`favorite`](../../../entity/classes/FavoritableEntity.md#favorite)\n\n***\n\n### markRead()\n\n> **markRead**(`message`): `Promise`\\<`void`\\>\n\nAdvance the caller's own read cursor.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### messageAttachments()\n\n> **messageAttachments**(`messages`): `Promise`\\<\\{ `attachments`: \\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]; `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}[]\\>\n\nRead attachment states for selected messages.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `messages` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)[] |\n\n#### Returns\n\n`Promise`\\<\\{ `attachments`: \\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]; `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}[]\\>\n\n***\n\n### messages()\n\n> **messages**(`options?`): `AsyncGenerator`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)\\>\n\nIterate newest-first timeline pages lazily.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options?` | \\{ `limit?`: `number`; \\} |\n| `options.limit?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)\\>\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`permission`](../../../entity/classes/FavoritableEntity.md#permission)\n\n***\n\n### permissions()\n\n> **permissions**(): `Promise`\\<[`SharePermissionV2`](../../../../../generated/storage/types.gen/type-aliases/SharePermissionV2.md)\\>\n\nRead standard link/team sharing settings.\n\n#### Returns\n\n`Promise`\\<[`SharePermissionV2`](../../../../../generated/storage/types.gen/type-aliases/SharePermissionV2.md)\\>\n\n***\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppGroup`\\>\n\nReload detail, permissions and caller capabilities.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n***\n\n### reply()\n\n> **reply**(`content`, `options`): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)\\>\n\nPersonal sessions and owner API credentials can send. Bots never send.\nPreserve the idempotency key; uncertain outcomes are never automatically resent.\nThe server enforces one request per second per user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `content` | [`WhatsAppReply`](../type-aliases/WhatsAppReply.md) |\n| `options` | \\{ `idempotencyKey`: `string`; `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\} |\n| `options.idempotencyKey` | `string` |\n| `options.replyTo?` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)\\>\n\n***\n\n### sends()\n\n> **sends**(): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\nRead only the caller's pending, uncertain or failed sends.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`toJSON`](../../../entity/classes/FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`WhatsAppGroup`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`unfavorite`](../../../entity/classes/FavoritableEntity.md#unfavorite)\n\n***\n\n### updatePermissions()\n\n> **updatePermissions**(`update`): `Promise`\\<`void`\\>\n\nActual owner updates standard link/team sharing settings.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `update` | [`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### upload()\n\n> **upload**(`file`): `Promise`\\<[`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md)\\>\n\nStage a supported attachment for a deliberate send.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `file` | `Blob` \\| `File` |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md)\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppGroup`\n\nReference an adopted group; access is checked on each request.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppGroup`\n\n\n\n# Type Alias: WhatsAppReply\n\n> **WhatsAppReply** = \\{ `text`: `string`; `type`: `\"text\"`; \\} \\| \\{ `caption?`: `string`; `type`: `\"media\"`; `upload`: [`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md); \\} \\| \\{ `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); `operation`: `\"reaction\"` \\| `\"edit\"` \\| `\"delete\"`; `text?`: `string`; `type`: `\"mutation\"`; \\}\n\nDeliberate content from the credential owner's own WhatsApp account.\n\n\n\n# Class: WhatsAppMessage\n\nMessage in an independently shared WhatsApp group.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `attachments` | `readonly` | () => `Promise`\\<\\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]\\> | Attachment state and imported document handles. | - |\n| `body` | `readonly` | () => `Promise`\\<`string`\\> | Plain WhatsApp text. | - |\n| `deleted` | `readonly` | () => `Promise`\\<`boolean`\\> | Deleted for everyone. | - |\n| `deliveryState` | `readonly` | () => `Promise`\\<`NonNullable`\\ \\| `undefined`\\> | Caller-owned send's delivery state, when present. | - |\n| `editedAt` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Last edit time. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `reactions` | `readonly` | () => `Promise`\\<[`WhatsAppGroupReaction`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupReaction.md)[]\\> | Grouped emoji counts and caller's own reaction. | - |\n| `replyTo` | `readonly` | () => `Promise`\\<`WhatsAppMessage` \\| `undefined`\\> | Quoted message in this group. | - |\n| `sender` | `readonly` | () => `Promise`\\<[`WhatsAppGroupSender`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupSender.md)\\> | Protocol-verified sender association and display name. | - |\n| `sentAt` | `readonly` | () => `Promise`\\<`string`\\> | WhatsApp timestamp. | - |\n\n## Accessors\n\n### groupId\n\n#### Get Signature\n\n> **get** **groupId**(): `string`\n\nGroup identity for checking reply/mutation scope.\n\n##### Returns\n\n`string`\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `group`, `id`): `WhatsAppMessage`\n\nReference a message within its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppMessage`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `group`, `record`): `WhatsAppMessage`\n\nSeed a message handle from a timeline response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md) |\n\n#### Returns\n\n`WhatsAppMessage`\n\n\n\n# Class: WhatsAppNamespace\n\nOperate on an account already paired through the Macro app.\n\n## Constructors\n\n### Constructor\n\n> **new WhatsAppNamespace**(`client`): `WhatsAppNamespace`\n\nBind existing-account operations to this authenticated client.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`WhatsAppNamespace`\n\n## Methods\n\n### account()\n\n> **account**(): `Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\nCurrent owner's account, or undefined when no account has been connected.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\nReference an adopted entity without fetching it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\n***\n\n### groups()\n\n> **groups**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\nAdopted groups shared with the caller, including without WhatsApp.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\n***\n\n### remoteGroups()\n\n> **remoteGroups**(): `Promise`\\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\\>\n\nGroups discoverable through the caller's own connected account.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\\>\n\n\n\n# Class: WhatsAppRemoteGroup\n\nAn existing group joined by the current user's connected WhatsApp account.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `announce` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether only remote administrators can post. | - |\n| `community` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether this group is an unsupported community parent or announcement group. | - |\n| `disappearing` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether disappearing messages prevent retention of group content. | - |\n| `group` | `readonly` | () => `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \\| `undefined`\\> | The current user's own Macro group for this remote group, once added. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | The WhatsApp subject, or the other members' names for an unnamed group. | - |\n| `observedAt` | `readonly` | () => `Promise`\\<`string`\\> | When the session service last observed this metadata. | - |\n| `participants` | `readonly` | () => `Promise`\\<[`LinkedParticipant`](../../../../../generated/storage/types.gen/type-aliases/LinkedParticipant.md)[]\\> | Current remote roster; membership alone does not grant Macro history access. | - |\n| `shared` | `readonly` | () => `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \\| `undefined`\\> | Someone else's Macro group for this remote group, shared with the current user. | - |\n\n## Methods\n\n### adopt()\n\n> **adopt**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\\>\n\nAdd the group to Macro as the current user's own group, named after\nWhatsApp; adding it again returns the same group. Share it through the\nnormal entity sharing endpoints.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\\>\n\n***\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppRemoteGroup`\\>\n\nReload the group's roster and adoption state.\n\n#### Returns\n\n`Promise`\\<`WhatsAppRemoteGroup`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppRemoteGroup`\n\nReference a remote group by its verified JID.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppRemoteGroup`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `record`): `WhatsAppRemoteGroup`\n\nSeed a group handle from the current account's roster.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `record` | [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) |\n\n#### Returns\n\n`WhatsAppRemoteGroup`\n\n\n\n# Class: WhatsAppSend\n\nOne deliberate send intent. Unknown outcomes must never be automatically resent.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `createdAt` | `readonly` | () => `Promise`\\<`string`\\> | When the send intent was created. | - |\n| `errorCode` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Sanitized failure code, when present. | - |\n| `group` | `readonly` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) | Group entity containing this send. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `message` | `readonly` | () => `Promise`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) \\| `undefined`\\> | Group message once WhatsApp accepted the send. | - |\n| `state` | `readonly` | () => `Promise`\\<[`LinkedDeliveryState`](../../../../../generated/storage/types.gen/type-aliases/LinkedDeliveryState.md)\\> | Last observed delivery state; refresh explicitly to poll again. | - |\n\n## Methods\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppSend`\\>\n\nFetch current delivery state without retrying or submitting the message.\n\n#### Returns\n\n`Promise`\\<`WhatsAppSend`\\>\n\n***\n\n### request()\n\n> **request**(): `Promise`\\<\\{ `idempotencyKey`: `string`; `message`: [`WhatsAppReply`](../../group/type-aliases/WhatsAppReply.md); `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}\\>\n\nInspect the original intent for reconciliation; never resubmit an unknown outcome automatically.\n\n#### Returns\n\n`Promise`\\<\\{ `idempotencyKey`: `string`; `message`: [`WhatsAppReply`](../../group/type-aliases/WhatsAppReply.md); `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `group`, `id`): `WhatsAppSend`\n\nReference a send intent within its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppSend`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `group`, `record`): `WhatsAppSend`\n\nSeed a send handle from a server response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md) |\n\n#### Returns\n\n`WhatsAppSend`\n\n\n\n# Class: WhatsAppUpload\n\nA staged attachment scoped to one adopted group; use it in a deliberate media send.\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `filename?` | `readonly` | `string` | Display filename supplied by the server. |\n| `groupId` | `readonly` | `string` | The group this upload can be sent to. |\n| `id` | `readonly` | `string` | Correlation identity of the staged upload. |\n| `kind?` | `readonly` | [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) | Media category supplied by the server. |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `filename`: `string` \\| `undefined`; `groupId`: `string`; `id`: `string`; `kind`: [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined`; \\}\n\nSerialize the upload reference without credentials.\n\n#### Returns\n\n\\{ `filename`: `string` \\| `undefined`; `groupId`: `string`; `id`: `string`; `kind`: [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `filename` | `string` \\| `undefined` |\n| `groupId` | `string` |\n| `id` | `string` |\n| `kind` | [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined` |\n\n***\n\n### byId()\n\n> `static` **byId**(`group`, `id`): `WhatsAppUpload`\n\nReference a previously staged upload in its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppUpload`\n\n***\n\n### from()\n\n> `static` **from**(`group`, `record`): `WhatsAppUpload`\n\nSeed a handle from the server's upload receipt.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`LinkedUploadedAttachment`](../../../../../generated/storage/types.gen/type-aliases/LinkedUploadedAttachment.md) |\n\n#### Returns\n\n`WhatsAppUpload`\n"
+ "overview": "\n# Class: ChannelNamespace\n\n## Constructors\n\n### Constructor\n\n> **new ChannelNamespace**(`client`): `ChannelNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelNamespace`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `labels` | `readonly` | [`ChannelLabelsNamespace`](../../labels/classes/ChannelLabelsNamespace.md) | Team-shared labels that group channels in the Chat sidebar. |\n\n## Methods\n\n### activity()\n\n> **activity**(): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\nRecent channel activity, with channel and user handles.\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`Channel`](../../channel/classes/Channel.md)\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### create()\n\n> **create**(`opts`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### dm()\n\n> **dm**(`recipient`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\nAll channels the authenticated user is a member of.\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\n***\n\n### private()\n\n> **private**(`recipients`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### search()\n\n> **search**(`query`, `opts?`): `AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nSearch channels by name (client-side fuzzy filter on the full channel list)\nor by content (server-side unified search).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `query` | `string` |\n| `opts?` | [`SearchOpts`](../../../search/interfaces/SearchOpts.md) |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n\n\n# Class: WhatsAppNamespace\n\nOperate on an account already paired through the Macro app.\n\n## Constructors\n\n### Constructor\n\n> **new WhatsAppNamespace**(`client`): `WhatsAppNamespace`\n\nBind existing-account operations to this authenticated client.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`WhatsAppNamespace`\n\n## Methods\n\n### account()\n\n> **account**(): `Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\nCurrent owner's account, or undefined when no account has been connected.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\nReference an adopted entity without fetching it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\n***\n\n### groups()\n\n> **groups**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\nAdopted groups shared with the caller, including without WhatsApp.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n",
+ "documentation": "# Macro SDK: channels\n\nGenerated by TypeDoc. Paths below refer to the canonical Markdown hierarchy. Other entity handles are documented in their named section; request core for shared SDK helpers.\n\n\n# Type Alias: BulkUpdateEntityPropertyOptionsResponse\n\n> **BulkUpdateEntityPropertyOptionsResponse** = \\{ `properties`: [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[]; \\}\n\nResponse for a bulk option update: each property's reconciled final ids.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `properties` | [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[] | The final option ids per updated property. |\n\n\n\n# Type Alias: DataType\n\n> **DataType** = `\"BOOLEAN\"` \\| `\"DATE\"` \\| `\"NUMBER\"` \\| `\"STRING\"` \\| `\"SELECT_NUMBER\"` \\| `\"SELECT_STRING\"` \\| `\"TAG\"` \\| `\"ENTITY\"` \\| `\"LINK\"`\n\nData type for property values, determining storage and validation.\n\n\n\n# Type Alias: EntityProperty\n\n> **EntityProperty** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; \\}\n\nAssignment of a property definition to a specific entity (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `created_at` | `string` |\n| `entity_id` | `string` |\n| `entity_type` | [`EntityType`](EntityType.md) |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n\n\n\n# Type Alias: EntityPropertyOptionSelectionResponse\n\n> **EntityPropertyOptionSelectionResponse** = \\{ `option_ids`: `string`[]; `property_id`: `string`; \\}\n\nThe reconciled final option ids stored for one property after a bulk update.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `option_ids` | `string`[] | The final option ids the server persisted, in stored order. |\n| `property_id` | `string` | The property definition the options belong to. |\n\n\n\n# Type Alias: EntityPropertyWithDefinition\n\n> **EntityPropertyWithDefinition** = \\{ `definition`: [`PropertyDefinition`](PropertyDefinition.md); `options?`: [`PropertyOption`](PropertyOption.md)[] \\| `null`; `property`: [`EntityProperty`](EntityProperty.md); `value?`: `null` \\| [`PropertyValue`](PropertyValue.md); \\}\n\nEntity property with its definition, value, and options (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `definition` | [`PropertyDefinition`](PropertyDefinition.md) |\n| `options?` | [`PropertyOption`](PropertyOption.md)[] \\| `null` |\n| `property` | [`EntityProperty`](EntityProperty.md) |\n| `value?` | `null` \\| [`PropertyValue`](PropertyValue.md) |\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `specific_message_id?`: `string` \\| `null`; \\}\n\nEntity reference for entity-type property values.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | - |\n| `entity_type` | [`EntityType`](EntityType.md) | - |\n| `specific_message_id?` | `string` \\| `null` | For CHANNEL, CHAT, THREAD entity types - optional specific message ID. This allows referencing a specific message within a thread/channel/chat. |\n\n\n\n# Type Alias: EntityType\n\n> **EntityType** = `\"CALENDAR_EVENT\"` \\| `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"CONTACT\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"TASK\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nType of entity that can be referenced by entity properties.\n\n\n\n# Type Alias: PropertyDefinition\n\n> **PropertyDefinition** = \\{ `created_at`: `string`; `data_type`: [`DataType`](DataType.md); `display_name`: `string`; `id`: `string`; `is_metadata`: `boolean`; `is_multi_select`: `boolean`; `is_system`: `boolean`; `owner`: [`PropertyOwner`](PropertyOwner.md); `specific_entity_type`: `null` \\| [`EntityType`](EntityType.md); `updated_at`: `string`; \\}\n\nProperty definition model (service representation).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | - |\n| `data_type` | [`DataType`](DataType.md) | - |\n| `display_name` | `string` | - |\n| `id` | `string` | - |\n| `is_metadata` | `boolean` | Flag to indicate if this is a system-generated metadata property. Not stored in database - computed at service layer. |\n| `is_multi_select` | `boolean` | - |\n| `is_system` | `boolean` | Flag to indicate if this is a system property (stored in DB). |\n| `owner` | [`PropertyOwner`](PropertyOwner.md) | - |\n| `specific_entity_type` | `null` \\| [`EntityType`](EntityType.md) | - |\n| `updated_at` | `string` | - |\n\n\n\n# Type Alias: PropertyOption\n\n> **PropertyOption** = \\{ `color`: `string` \\| `null`; `created_at`: `string`; `display_order`: `number`; `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; `value`: [`PropertyOptionValue`](PropertyOptionValue.md); \\}\n\nA selectable option for select-type properties (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `color` | `string` \\| `null` |\n| `created_at` | `string` |\n| `display_order` | `number` |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n| `value` | [`PropertyOptionValue`](PropertyOptionValue.md) |\n\n\n\n# Type Alias: PropertyOptionValue\n\n> **PropertyOptionValue** = \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\}\n\nThe value of a property option - either a string or a number.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"string\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"string\"` | - |\n| `value` | `string` | String value for SelectString properties |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"number\"` | - |\n| `value` | `number` | Number value for SelectNumber properties |\n\n\n\n# Type Alias: PropertyOwner\n\n> **PropertyOwner** = \\{ `scope`: `\"user\"`; `user_id`: `string`; \\} \\| \\{ `scope`: `\"team\"`; `team_id`: `string`; \\} \\| \\{ `database_id`: `string`; `scope`: `\"database\"`; \\} \\| \\{ `scope`: `\"system\"`; \\}\n\nDefines who owns a property - user-scoped, team-scoped, database-scoped, or system.\n\n\n\n# Type Alias: PropertyTargetEntityType\n\n> **PropertyTargetEntityType** = `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nCanonical type of an entity receiving properties.\n\nTasks are documents at API boundaries. `Task` intentionally does not exist\nhere; task classification is resolved by the properties domain from the\ndocument subtype.\n\n\n\n# Type Alias: PropertyTargetReference\n\n> **PropertyTargetReference** = \\{ `entity_id`: `string`; `entity_type`: [`PropertyTargetEntityType`](PropertyTargetEntityType.md); \\}\n\nCanonical reference to an entity receiving properties.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Entity identifier. |\n| `entity_type` | [`PropertyTargetEntityType`](PropertyTargetEntityType.md) | Canonical entity type. |\n\n\n\n# Type Alias: PropertyValue\n\n> **PropertyValue** = \\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"Number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"String\"`; `value`: `string`; \\} \\| \\{ `type`: `\"Date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\} \\| \\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\} \\| \\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\nProperty value (service representation).\n\nRepresents the actual value stored for an entity property.\nThis is serialized to/from JSONB in the database.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Boolean\"` | - |\n| `value` | `boolean` | Boolean value Serializes as: {\"type\": \"Boolean\", \"value\": true} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Number\"` | - |\n| `value` | `number` | Numeric value Serializes as: {\"type\": \"Number\", \"value\": 42.5} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"String\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"String\"` | - |\n| `value` | `string` | String value Serializes as: {\"type\": \"String\", \"value\": \"text\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Date\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Date\"` | - |\n| `value` | `string` | Date/timestamp value Serializes as: {\"type\": \"Date\", \"value\": \"2025-01-01T00:00:00Z\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"SelectOption\"` | - |\n| `value` | `string`[] | Select option(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"SelectOption\", \"value\": [\"uuid\"]} (length 0 or 1) Multi-select: {\"type\": \"SelectOption\", \"value\": [\"uuid1\", \"uuid2\", ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"EntityReference\"` | - |\n| `value` | [`EntityReference`](EntityReference.md)[] | Entity reference(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"EntityReference\", \"value\": [{...}]} (length 0 or 1) Multi-select: {\"type\": \"EntityReference\", \"value\": [{...}, {...}, ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Link\"` | - |\n| `value` | `string`[] | Link value(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"Link\", \"value\": [\"https://example.com\"]} (length 0 or 1) Multi-select: {\"type\": \"Link\", \"value\": [\"https://example.com\", \"https://other.com\"]} (length 0+) |\n\n\n\n# Type Alias: SetPropertyValue\n\n> **SetPropertyValue** = \\{ `type`: `\"boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `option_id`: `string`; `type`: `\"select_option\"`; \\} \\| \\{ `option_ids`: `string`[]; `type`: `\"multi_select_option\"`; \\} \\| \\{ `reference`: [`EntityReference`](EntityReference.md); `type`: `\"entity_reference\"`; \\} \\| \\{ `references`: [`EntityReference`](EntityReference.md)[]; `type`: `\"multi_entity_reference\"`; \\} \\| \\{ `type`: `\"link\"`; `url`: `string`; \\} \\| \\{ `type`: `\"multi_link\"`; `urls`: `string`[]; \\}\n\nType-safe enum for setting entity property values - provides compile-time validation.\n\n\n\n# Type Alias: AccessLevel\n\n> **AccessLevel** = `\"view\"` \\| `\"comment\"` \\| `\"edit\"` \\| `\"owner\"`\n\nOrdered from least to most access top -> bottom\n\n\n\n# Type Alias: ActivityType\n\n> **ActivityType** = `\"view\"` \\| `\"interact\"`\n\nThe kind of activity a user performs in a channel.\n\n\n\n# Type Alias: ApiActivity\n\n> **ApiActivity** = \\{ `channel_id`: `string`; `created_at`: `string`; `id`: `string`; `interacted_at?`: `string` \\| `null`; `updated_at`: `string`; `user_id`: `string`; `viewed_at?`: `string` \\| `null`; \\}\n\nA user's activity (view/interaction) within a channel.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `created_at` | `string` | When the activity row was created. |\n| `id` | `string` | Activity id. |\n| `interacted_at?` | `string` \\| `null` | The last time the user interacted with the channel. |\n| `updated_at` | `string` | When the activity row was last updated. |\n| `user_id` | `string` | User id. |\n| `viewed_at?` | `string` \\| `null` | The last time the user viewed the channel. |\n\n\n\n# Type Alias: ApiChannelAttachment\n\n> **ApiChannelAttachment** = \\{ `channel_id`: `string`; `created_at`: `string`; `entity_id`: `string`; `entity_type`: `string`; `height?`: `number` \\| `null`; `id`: `string`; `message_id`: `string`; `sender_id`: `string`; `width?`: `number` \\| `null`; \\}\n\nA channel-level attachment.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `created_at` | `string` | When the attachment was created. |\n| `entity_id` | `string` | Entity id. |\n| `entity_type` | `string` | Type of entity. |\n| `height?` | `number` \\| `null` | Height (for images). |\n| `id` | `string` | Attachment id. |\n| `message_id` | `string` | Message id this attachment belongs to. |\n| `sender_id` | `string` | The user who sent the message containing this attachment. |\n| `width?` | `number` \\| `null` | Width (for images). |\n\n\n\n# Type Alias: ApiChannelAttachmentsPage\n\n> **ApiChannelAttachmentsPage** = \\{ `items`: [`ApiChannelAttachment`](ApiChannelAttachment.md)[]; `next_cursor?`: `string` \\| `null`; \\}\n\nPaginated response of channel attachments.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `items` | [`ApiChannelAttachment`](ApiChannelAttachment.md)[] | Attachments on this page. |\n| `next_cursor?` | `string` \\| `null` | Cursor for the next page, null if no more pages. |\n\n\n\n# Type Alias: ApiChannelDetail\n\n> **ApiChannelDetail** = \\{ `channel_id`: `string`; `channel_name`: `string`; `channel_type`: [`ChannelType`](ChannelType.md); `participants`: [`ApiChannelParticipant`](ApiChannelParticipant.md)[]; \\}\n\nChannel detail: metadata and active participants.\n\nMessages are read through `/messages/channel/{channel_id}`.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `channel_name` | `string` | Resolved display name from the viewer's perspective. |\n| `channel_type` | [`ChannelType`](ChannelType.md) | Channel type. |\n| `participants` | [`ApiChannelParticipant`](ApiChannelParticipant.md)[] | Active participants. |\n\n\n\n# Type Alias: ApiChannelParticipant\n\n> **ApiChannelParticipant** = \\{ `channel_id`: `string`; `joined_at`: `string`; `role`: [`ApiParticipantRole`](ApiParticipantRole.md); `user_id`: `string`; \\}\n\nA channel participant.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_id` | `string` | Channel id. |\n| `joined_at` | `string` | When the user joined. |\n| `role` | [`ApiParticipantRole`](ApiParticipantRole.md) | Role in the channel. |\n| `user_id` | `string` | User id. |\n\n\n\n# Type Alias: ApiParticipantRole\n\n> **ApiParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nParticipant role in a channel.\n\n\n\n# Type Alias: BotSenderProfile\n\n> **BotSenderProfile** = \\{ `avatar_url?`: `string` \\| `null`; `name`: `string`; \\}\n\nPublic bot profile attached to bot-authored messages.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `avatar_url?` | `string` \\| `null` | Bot avatar URL. |\n| `name` | `string` | Bot display name. |\n\n\n\n# Type Alias: ChannelLabel\n\n> **ChannelLabel** = \\{ `channelCount`: `number`; `channelIds`: `string`[]; `createdAt`: `string`; `id`: `string`; `name`: `string`; `rule?`: `null` \\| [`ChannelLabelRule`](ChannelLabelRule.md); `sortOrder`: `number`; `teamId?`: `string` \\| `null`; `updatedAt`: `string`; \\}\n\nA shared or account-private label grouping chat channels in the sidebar.\n\n`channel_ids` is viewer-relative: it lists only the labelled channels the\nrequesting user participates in. `channel_count` counts every channel in\nthe label so clients can warn accurately before a delete.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelCount` | `number` | All assignments for a manual label; visible matches for a smart tag. |\n| `channelIds` | `string`[] | Channels in this label that the requesting user participates in. |\n| `createdAt` | `string` | When the label was created. |\n| `id` | `string` | Stable label id. |\n| `name` | `string` | Display name, unique within the scope (case-insensitive). |\n| `rule?` | `null` \\| [`ChannelLabelRule`](ChannelLabelRule.md) | - |\n| `sortOrder` | `number` | Manual ordering value within the scope; lower sorts first. |\n| `teamId?` | `string` \\| `null` | Owning team, or `None` for account-private labels. |\n| `updatedAt` | `string` | When the label was last renamed or reordered. |\n\n\n\n# Type Alias: ChannelLabelRule\n\n> **ChannelLabelRule** = \\{ `attribute`: `\"name\"`; `contains`: `string`; \\}\n\nCase-insensitive, literal substring matching on the channel name.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attribute` | `\"name\"` | - |\n| `contains` | `string` | The substring to find anywhere in the name. |\n\n\n\n# Type Alias: ChannelSharePermission\n\n> **ChannelSharePermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `channel_id`: `string`; \\}\n\nThe channel share permission\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level for the channel |\n| `channel_id` | `string` | The channel id |\n\n\n\n# Type Alias: ChannelType\n\n> **ChannelType** = `\"public\"` \\| `\"private\"` \\| `\"direct_message\"` \\| `\"team\"`\n\nType of channel.\n\n\n\n# Type Alias: CountedReaction\n\n> **CountedReaction** = \\{ `emoji`: `string`; `users`: `string`[]; \\}\n\nReaction emoji and the users who added it.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `emoji` | `string` | Emoji being reacted with. |\n| `users` | `string`[] | User identifiers. |\n\n\n\n# Type Alias: DocumentId\n\n> **DocumentId** = `string`\n\nA validated document identifier. Historical document ids need not be UUIDs.\n\n\n\n# Type Alias: EntityPermission\n\n> **EntityPermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\} \\| \\{ `type`: `\"channel_view_only\"`; \\} \\| \\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\} \\| \\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\nA user's permission for an entity, discriminated by entity kind.\n\nItems (documents, chats, projects, threads) use access levels.\nChannels use view-only permission or participant roles.\n\n## Union Members\n\n### Type Literal\n\n\\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level the user has. |\n| `type` | `\"access_level\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"channel_view_only\"`; \\}\n\n***\n\n### Type Literal\n\n\\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`ParticipantRole`](ParticipantRole.md) | The role the user has in the channel. |\n| `type` | `\"channel_role\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`TeamRole`](TeamRole.md) | The role the user has in the team. |\n| `type` | `\"team_role\"` | - |\n\n\n\n# Type Alias: GetChannelAttachmentsResponses\n\n> **GetChannelAttachmentsResponses** = \\{ `200`: [`ApiChannelAttachmentsPage`](ApiChannelAttachmentsPage.md); \\}\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `200` | [`ApiChannelAttachmentsPage`](ApiChannelAttachmentsPage.md) |\n\n\n\n# Type Alias: GetChannelParticipantsResponses\n\n> **GetChannelParticipantsResponses** = \\{ `200`: [`ApiChannelParticipant`](ApiChannelParticipant.md)[]; \\}\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `200` | [`ApiChannelParticipant`](ApiChannelParticipant.md)[] |\n\n\n\n# Type Alias: ImportedAuthor\n\n> **ImportedAuthor** = \\{ `name`: `string`; \\}\n\nDisplay attribution for a comment imported from an external document.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `name` | `string` | Original author text; never interpreted as an authenticated principal. |\n\n\n\n# Type Alias: LinkShare\n\n> **LinkShare** = `\"PUBLIC\"` \\| `\"TEAM\"`\n\nDefines who can access an item through its share link.\n\n\n\n# Type Alias: LinkedAccount\n\n> **LinkedAccount** = \\{ `authorization_generation`: `number`; `id`: `string`; `identity_jid?`: `string` \\| `null`; `state`: [`LinkedAccountState`](LinkedAccountState.md); `user_id`: `string`; \\}\n\nOne person's account, never owned by a workspace.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `authorization_generation` | `number` | Explicit consent generation; reconnecting a socket never changes it. |\n| `id` | `string` | Stable account identity. |\n| `identity_jid?` | `string` \\| `null` | WhatsApp-verified identity, absent until the first pairing succeeds. |\n| `state` | [`LinkedAccountState`](LinkedAccountState.md) | Lifecycle. |\n| `user_id` | `string` | Authenticated owner. |\n\n\n\n# Type Alias: LinkedAccountState\n\n> **LinkedAccountState** = `\"pairing\"` \\| `\"connected\"` \\| `\"logged_out\"` \\| `\"disconnected\"`\n\nAccount lifecycle. Transport outages are not stored: a connected account\nstays connected while its session service reconnects.\n\n\n\n# Type Alias: LinkedAttachment\n\n> **LinkedAttachment** = \\{ `document_id?`: `string` \\| `null`; `file_name`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](LinkedAttachmentState.md); \\}\n\nOne attachment of a linked message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `document_id?` | `string` \\| `null` | The private document, once ready. |\n| `file_name` | `string` | Display filename. |\n| `mime` | `string` | Declared MIME type. |\n| `ordinal` | `number` | Position within the message. |\n| `size` | `number` | Declared size in bytes. |\n| `state` | [`LinkedAttachmentState`](LinkedAttachmentState.md) | Current state. |\n\n\n\n# Type Alias: LinkedAttachmentState\n\n> **LinkedAttachmentState** = `\"loading\"` \\| `\"ready\"` \\| `\"unavailable\"` \\| `\"unsupported\"`\n\nWhere an attachment of a linked message stands.\n\n\n\n# Type Alias: LinkedBackfill\n\n> **LinkedBackfill** = \\{ `imported`: `number`; `state`: [`LinkedBackfillState`](LinkedBackfillState.md); \\}\n\nEarlier messages imported after adding a group.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `imported` | `number` | Messages received from the phone so far (including ones already shown). |\n| `state` | [`LinkedBackfillState`](LinkedBackfillState.md) | Progress. |\n\n\n\n# Type Alias: LinkedBackfillState\n\n> **LinkedBackfillState** = `\"pending\"` \\| `\"running\"` \\| `\"waiting_for_phone\"` \\| `\"done\"` \\| `\"partial\"`\n\nWhere importing a group's earlier messages stands.\n\n\n\n# Type Alias: LinkedCapabilities\n\n> **LinkedCapabilities** = \\{ `attachment_limit_bytes`: `number`; `attachment_types`: `string`[]; `max_attachments`: `number`; `mutation_window_seconds`: `number`; `mutations`: [`LinkedMutation`](LinkedMutation.md)[]; `text_limit_bytes`: `number`; \\}\n\nOperations implemented for linked groups, independent of current permission.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachment_limit_bytes` | `number` | Largest attachment in bytes. |\n| `attachment_types` | `string`[] | Supported attachment MIME types. |\n| `max_attachments` | `number` | Attachments per send. |\n| `mutation_window_seconds` | `number` | Edits and deletes are offered this long after sending. |\n| `mutations` | [`LinkedMutation`](LinkedMutation.md)[] | Supported message operations. |\n| `text_limit_bytes` | `number` | Maximum UTF-8 bytes per text send. |\n\n\n\n# Type Alias: LinkedChat\n\n> **LinkedChat** = \\{ `archived`: `boolean`; `canAdd`: `boolean`; `cannotAddReason?`: `string` \\| `null`; `group?`: `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md); `jid`: `string`; `kind`: [`LinkedChatKind`](LinkedChatKind.md); `lastActivityAt?`: `string` \\| `null`; `name`: `string`; `pinned`: `boolean`; `shared?`: `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md); \\}\n\nOne chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `archived` | `boolean` | Archived in WhatsApp. |\n| `canAdd` | `boolean` | \"Add to Macro\" works now. |\n| `cannotAddReason?` | `string` \\| `null` | Why it can't be added, when it is neither added, shared nor addable. |\n| `group?` | `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md) | - |\n| `jid` | `string` | WhatsApp chat JID: a group, or the other person's phone-number JID (LID when WhatsApp never told us the number). |\n| `kind` | [`LinkedChatKind`](LinkedChatKind.md) | Group or direct chat. |\n| `lastActivityAt?` | `string` \\| `null` | Newest activity WhatsApp reported (message or history sync); `null` when unknown. The list is sorted by it, newest first, unknown last. |\n| `name` | `string` | Group: the subject, or member names for an unnamed group. Direct: the contact or WhatsApp name, else `+`. Always non-empty. |\n| `pinned` | `boolean` | Pinned in WhatsApp. |\n| `shared?` | `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md) | - |\n\n\n\n# Type Alias: LinkedChatKind\n\n> **LinkedChatKind** = `\"group\"` \\| `\"direct\"`\n\nWhether a WhatsApp chat is a group or a one-to-one chat.\n\n\n\n# Type Alias: LinkedDeliveryState\n\n> **LinkedDeliveryState** = `\"pending\"` \\| `\"sending\"` \\| `\"unknown\"` \\| `\"accepted\"` \\| `\"sent\"` \\| `\"delivered\"` \\| `\"read\"` \\| `\"failed\"`\n\nObserved send state. `unknown` means the request may have reached WhatsApp;\nit is never sent again automatically.\n\n\n\n# Type Alias: LinkedGroupInfo\n\n> **LinkedGroupInfo** = \\{ `announce`: `boolean`; `community`: `boolean`; `disappearing`: `boolean`; `group?`: `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md); `jid`: `string`; `name`: `string`; `observedAt`: `string`; `participants`: [`LinkedParticipant`](LinkedParticipant.md)[]; `shared?`: `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md); \\}\n\nOne full metadata read of a group, never an incomplete membership delta.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `announce` | `boolean` | Only admins may post. |\n| `community` | `boolean` | Community announcement or parent group, outside the supported surface. |\n| `disappearing` | `boolean` | Disappearing messages are on; content is not retained. |\n| `group?` | `null` \\| [`LinkedGroupReference`](LinkedGroupReference.md) | - |\n| `jid` | `string` | Remote group JID. |\n| `name` | `string` | Current subject. |\n| `observedAt` | `string` | When the session service read this metadata. |\n| `participants` | [`LinkedParticipant`](LinkedParticipant.md)[] | Full roster. |\n| `shared?` | `null` \\| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md) | - |\n\n\n\n# Type Alias: LinkedGroupReference\n\n> **LinkedGroupReference** = \\{ `id`: `string`; `name`: `string`; \\}\n\nA group entity bound to a remote group.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Group entity id. |\n| `name` | `string` | Display name, following WhatsApp. |\n\n\n\n# Type Alias: LinkedIdentity\n\n> **LinkedIdentity** = \\{ `alternateJid?`: `string` \\| `null`; `displayName?`: `string` \\| `null`; `jid`: `string`; \\}\n\nVerified sender aliases, supplied only by protocol metadata.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `alternateJid?` | `string` \\| `null` | Verified alternate identity, never inferred from a name or phone typed by a user. |\n| `displayName?` | `string` \\| `null` | Untrusted display name. |\n| `jid` | `string` | Phone-number or LID account JID. |\n\n\n\n# Type Alias: LinkedMediaKind\n\n> **LinkedMediaKind** = `\"image\"` \\| `\"audio\"` \\| `\"video\"` \\| `\"document\"`\n\nAttachment categories WhatsApp distinguishes.\n\n\n\n# Type Alias: LinkedMutation\n\n> **LinkedMutation** = `\"reaction\"` \\| `\"edit\"` \\| `\"delete\"`\n\nDeliberate operations on an existing linked-group message.\n\n\n\n# Type Alias: LinkedParticipant\n\n> **LinkedParticipant** = [`LinkedIdentity`](LinkedIdentity.md) & \\{ `admin`: `boolean`; \\}\n\nCurrent remote participant; Macro access is a separate grant.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `admin` | `boolean` | Group admin; only admins post in announcement groups. |\n\n\n\n# Type Alias: LinkedReplyBlock\n\n> **LinkedReplyBlock** = `\"sending_disabled\"` \\| `\"no_account\"` \\| `\"disconnected\"` \\| `\"not_observing\"` \\| `\"not_allowed_in_group\"` \\| `\"group_unavailable\"`\n\nWhy the viewer cannot send now.\n\n\n\n# Type Alias: LinkedReplyContent\n\n> **LinkedReplyContent** = \\{ `text`: `string`; `type`: `\"text\"`; \\} \\| \\{ `caption?`: `string` \\| `null`; `type`: `\"media\"`; `upload_id`: `string`; \\} \\| \\{ `message_id`: `string`; `operation`: [`LinkedMutation`](LinkedMutation.md); `text?`: `string` \\| `null`; `type`: `\"mutation\"`; \\}\n\nContent of a deliberate send.\n\n## Union Members\n\n### Type Literal\n\n\\{ `text`: `string`; `type`: `\"text\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `text` | `string` | UTF-8 text, at most [`TEXT_LIMIT_BYTES`] bytes. |\n| `type` | `\"text\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `caption?`: `string` \\| `null`; `type`: `\"media\"`; `upload_id`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `caption?` | `string` \\| `null` | Optional caption; audio has none. |\n| `type` | `\"media\"` | - |\n| `upload_id` | `string` | The staged upload, which becomes the message's private document. |\n\n***\n\n### Type Literal\n\n\\{ `message_id`: `string`; `operation`: [`LinkedMutation`](LinkedMutation.md); `text?`: `string` \\| `null`; `type`: `\"mutation\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `message_id` | `string` | Existing group message, resolved to its WhatsApp source by the server. |\n| `operation` | [`LinkedMutation`](LinkedMutation.md) | Explicit operation. |\n| `text?` | `string` \\| `null` | Replacement text or emoji; absent for delete, empty to remove a reaction. |\n| `type` | `\"mutation\"` | - |\n\n\n\n# Type Alias: LinkedSendProgress\n\n> **LinkedSendProgress** = \\{ `created_at`: `string`; `error_code?`: `string` \\| `null`; `group_id`: `string`; `id`: `string`; `message_id?`: `string` \\| `null`; `payload`: [`LinkedSendReply`](LinkedSendReply.md); `state`: [`LinkedDeliveryState`](LinkedDeliveryState.md); `user_id`: `string`; \\}\n\nDurable result of a deliberate send.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Intent creation time. |\n| `error_code?` | `string` \\| `null` | Sanitized failure code. |\n| `group_id` | `string` | Group entity. |\n| `id` | `string` | Stable intent id. |\n| `message_id?` | `string` \\| `null` | Group message, once WhatsApp accepted it. |\n| `payload` | [`LinkedSendReply`](LinkedSendReply.md) | The original request, so a failed draft can be recovered. |\n| `state` | [`LinkedDeliveryState`](LinkedDeliveryState.md) | Current state. |\n| `user_id` | `string` | Person who submitted it. |\n\n\n\n# Type Alias: LinkedSendReply\n\n> **LinkedSendReply** = \\{ `idempotency_key`: `string`; `message`: [`LinkedReplyContent`](LinkedReplyContent.md); `reply_to?`: `string` \\| `null`; \\}\n\nExplicit send action from a person. Only deliberate sends reach WhatsApp.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `idempotency_key` | `string` | Stable client intent key. A changed payload with this key is a conflict. |\n| `message` | [`LinkedReplyContent`](LinkedReplyContent.md) | Content. |\n| `reply_to?` | `string` \\| `null` | Group message being quoted, within this group. |\n\n\n\n# Type Alias: LinkedSharedGroupReference\n\n> **LinkedSharedGroupReference** = \\{ `id`: `string`; `name`: `string`; `owner_id`: `string`; \\}\n\nAnother person's group entity the caller can view.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Group entity id. |\n| `name` | `string` | Display name, following WhatsApp. |\n| `owner_id` | `string` | Macro user who added the group and shared it. |\n\n\n\n# Type Alias: LinkedUploadedAttachment\n\n> **LinkedUploadedAttachment** = \\{ `filename`: `string`; `kind`: [`LinkedMediaKind`](LinkedMediaKind.md); `upload_id`: `string`; \\}\n\nA staged attachment, sent only by a later deliberate send.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `filename` | `string` | Display filename. |\n| `kind` | [`LinkedMediaKind`](LinkedMediaKind.md) | Category. |\n| `upload_id` | `string` | Use as `upload_id` in a media send; also the future document id. |\n\n\n\n# Type Alias: Message\n\n> **Message** = \\{ `attachments`: [`MessageAttachment`](MessageAttachment.md)[]; `bot_profile?`: `null` \\| [`BotSenderProfile`](BotSenderProfile.md); `content`: `string`; `created_at`: `string`; `deleted_at?`: `string` \\| `null`; `edited_at?`: `string` \\| `null`; `guest_name?`: `string` \\| `null`; `id`: `string`; `imported_author?`: `null` \\| [`ImportedAuthor`](ImportedAuthor.md); `mentions`: [`SimpleMention`](SimpleMention.md)[]; `parent`: [`MessageParent`](MessageParent.md); `reactions`: [`CountedReaction`](CountedReaction.md)[]; `sender_id`: `string`; `thread_id?`: `string` \\| `null`; `triggered_by?`: `string` \\| `null`; `updated_at`: `string`; \\}\n\nShared message representation for channel timelines and entity discussions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachments` | [`MessageAttachment`](MessageAttachment.md)[] | Attached entities. |\n| `bot_profile?` | `null` \\| [`BotSenderProfile`](BotSenderProfile.md) | - |\n| `content` | `string` | Macro Markdown body. |\n| `created_at` | `string` | Creation time. |\n| `deleted_at?` | `string` \\| `null` | Message tombstone, independent of thread deletion. |\n| `edited_at?` | `string` \\| `null` | Last content edit, if any. |\n| `guest_name?` | `string` \\| `null` | Display name of a verified call guest, retained after the call ends. |\n| `id` | `string` | Message UUID. |\n| `imported_author?` | `null` \\| [`ImportedAuthor`](ImportedAuthor.md) | - |\n| `mentions` | [`SimpleMention`](SimpleMention.md)[] | Tracked mentions, retained when a caller changes attachments only. |\n| `parent` | [`MessageParent`](MessageParent.md) | Entity that owns this conversation. |\n| `reactions` | [`CountedReaction`](CountedReaction.md)[] | Aggregated reactions. |\n| `sender_id` | `string` | Authenticated actor or owner of imported content. |\n| `thread_id?` | `string` \\| `null` | Root message UUID for replies; absent on roots. |\n| `triggered_by?` | `string` \\| `null` | User who triggered a bot-authored message. |\n| `updated_at` | `string` | Last persisted update. |\n\n\n\n# Type Alias: MessageAttachment\n\n> **MessageAttachment** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: `string`; `height?`: `number` \\| `null`; `id`: `string`; `width?`: `number` \\| `null`; \\}\n\nAn entity attached to a message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | When the attachment was added. |\n| `entity_id` | `string` | Attached entity identifier. |\n| `entity_type` | `string` | Attached entity type. |\n| `height?` | `number` \\| `null` | Optional media height. |\n| `id` | `string` | Attachment UUID. |\n| `width?` | `number` \\| `null` | Optional media width. |\n\n\n\n# Type Alias: MessageCursor\n\n> **MessageCursor** = \\{ `created_at`: `string`; `id`: `string`; \\}\n\nCursor for a chronological parent timeline.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Last message creation time or activity occurrence time. |\n| `id` | `string` | Last entry UUID, used to break timestamp ties across both sources. |\n\n\n\n# Type Alias: MessageParent\n\n> **MessageParent** = \\{ `id`: `string`; `type`: `\"channel\"`; \\} \\| \\{ `id`: [`DocumentId`](DocumentId.md); `type`: `\"document\"`; \\} \\| \\{ `id`: `string`; `type`: `\"initiative\"`; \\} \\| \\{ `id`: `string`; `type`: `\"crm_company\"`; \\} \\| \\{ `id`: `string`; `type`: `\"crm_contact\"`; \\} \\| \\{ `id`: `string`; `type`: `\"call\"`; \\}\n\nThe entity whose permissions and lifecycle govern a message.\n\n## Union Members\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"channel\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A channel, including direct messages. |\n| `type` | `\"channel\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: [`DocumentId`](DocumentId.md); `type`: `\"document\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | [`DocumentId`](DocumentId.md) | A document, including tasks and PDFs. |\n| `type` | `\"document\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"initiative\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | An initiative, presented as a project in the application. |\n| `type` | `\"initiative\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"crm_company\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A CRM company. |\n| `type` | `\"crm_company\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"crm_contact\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A CRM contact. |\n| `type` | `\"crm_contact\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `id`: `string`; `type`: `\"call\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | A video call and its persistent chat thread. |\n| `type` | `\"call\"` | - |\n\n\n\n# Type Alias: ParticipantRole\n\n> **ParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nThe role a user has within a channel.\n\n\n\n# Type Alias: SharePermissionV2\n\n> **SharePermissionV2** = \\{ `channelSharePermissions?`: [`ChannelSharePermission`](ChannelSharePermission.md)[] \\| `null`; `id`: `string`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `owner`: `string`; `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`ChannelSharePermission`](ChannelSharePermission.md)[] \\| `null` | The channel share permissions for the item |\n| `id` | `string` | The share permission id |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `owner` | `string` | The owner of the item |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: SimpleMention\n\n> **SimpleMention** = \\{ `entity_id`: `string`; `entity_type`: `string`; \\}\n\nA mention tracked in a message body.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Mentioned entity identifier. |\n| `entity_type` | `string` | Mentioned entity type. |\n\n\n\n# Type Alias: SmartTagChannelMatch\n\n> **SmartTagChannelMatch** = \\{ `id`: `string`; `name`: `string`; \\}\n\nA channel visible to the caller that matches a smart tag rule.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `id` | `string` | Channel id. |\n| `name` | `string` | Channel display name. |\n\n\n\n# Type Alias: SmartTagPreview\n\n> **SmartTagPreview** = \\{ `channels`: [`SmartTagChannelMatch`](SmartTagChannelMatch.md)[]; `totalCount`: `number`; \\}\n\nA bounded preview and the total number of visible channels matching a rule.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channels` | [`SmartTagChannelMatch`](SmartTagChannelMatch.md)[] | First matches, in alphabetical order. |\n| `totalCount` | `number` | Number of matching channels the caller participates in, including overflow. |\n\n\n\n# Type Alias: TeamRole\n\n> **TeamRole** = `\"member\"` \\| `\"admin\"` \\| `\"owner\"`\n\nThe role a user has within a team.\n\nOrdered least to most privileged so comparisons reflect access strength.\n\n\n\n# Type Alias: UpdateChannelSharePermission\n\n> **UpdateChannelSharePermission** = \\{ `accessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `channelId`: `string`; `operation`: [`UpdateOperation`](UpdateOperation.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `accessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `channelId` | `string` | The channel id |\n| `operation` | [`UpdateOperation`](UpdateOperation.md) | The type of operation to be performed on the chanel share permission You can add, remove or replace and existing permission |\n\n\n\n# Type Alias: UpdateOperation\n\n> **UpdateOperation** = `\"add\"` \\| `\"remove\"` \\| `\"replace\"`\n\n\n\n# Type Alias: UpdateSharePermissionRequestV2\n\n> **UpdateSharePermissionRequestV2** = \\{ `channelSharePermissions?`: [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null` | Any channel share permissions to be created/updated/removed |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: WhatsAppGroupDetail\n\n> **WhatsAppGroupDetail** = [`WhatsAppGroupSummary`](WhatsAppGroupSummary.md) & \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `limits`: [`LinkedCapabilities`](LinkedCapabilities.md); `roster?`: `null` \\| [`LinkedGroupInfo`](LinkedGroupInfo.md); `sending_identity?`: `string` \\| `null`; `share_permission`: [`SharePermissionV2`](SharePermissionV2.md); \\}\n\nFull group detail and current viewer capabilities.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | Caller's effective permission. |\n| `limits` | [`LinkedCapabilities`](LinkedCapabilities.md) | Size and mutation limits. |\n| `roster?` | `null` \\| [`LinkedGroupInfo`](LinkedGroupInfo.md) | - |\n| `sending_identity?` | `string` \\| `null` | Caller's own phone identity, never another account's identity. |\n| `share_permission` | [`SharePermissionV2`](SharePermissionV2.md) | Owner-controlled standard sharing configuration. |\n\n\n\n# Type Alias: WhatsAppGroupMessage\n\n> **WhatsAppGroupMessage** = \\{ `attachments`: [`LinkedAttachment`](LinkedAttachment.md)[]; `body`: `string`; `deleted`: `boolean`; `delivery_state?`: `null` \\| [`LinkedDeliveryState`](LinkedDeliveryState.md); `edited_at?`: `string` \\| `null`; `id`: `string`; `reactions`: [`WhatsAppGroupReaction`](WhatsAppGroupReaction.md)[]; `received_at`: `string`; `reply_to?`: `string` \\| `null`; `sender`: [`WhatsAppGroupSender`](WhatsAppGroupSender.md); `sent_at`: `string`; \\}\n\nOne message in an adopted group.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attachments` | [`LinkedAttachment`](LinkedAttachment.md)[] | Imported or pending attachments. |\n| `body` | `string` | Plain WhatsApp text. |\n| `deleted` | `boolean` | Deleted for everyone. |\n| `delivery_state?` | `null` \\| [`LinkedDeliveryState`](LinkedDeliveryState.md) | - |\n| `edited_at?` | `string` \\| `null` | Last edit timestamp. |\n| `id` | `string` | Stable message id. |\n| `reactions` | [`WhatsAppGroupReaction`](WhatsAppGroupReaction.md)[] | Reactions grouped by emoji. |\n| `received_at` | `string` | Timestamp first received by Macro. |\n| `reply_to?` | `string` \\| `null` | Message quoted by this one. |\n| `sender` | [`WhatsAppGroupSender`](WhatsAppGroupSender.md) | Sender. |\n| `sent_at` | `string` | Timestamp assigned by WhatsApp. |\n\n\n\n# Type Alias: WhatsAppGroupReaction\n\n> **WhatsAppGroupReaction** = \\{ `count`: `number`; `emoji`: `string`; `mine`: `boolean`; \\}\n\nGrouped reactions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `count` | `number` | Number of reacting people. |\n| `emoji` | `string` | Emoji. |\n| `mine` | `boolean` | Caller has this reaction. |\n\n\n\n# Type Alias: WhatsAppGroupSender\n\n> **WhatsAppGroupSender** = \\{ `name`: `string`; `person_id`: `string`; `user_id?`: `string` \\| `null`; \\}\n\nMessage sender from protocol-verified identity evidence.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `name` | `string` | Display name, never authentication evidence. |\n| `person_id` | `string` | External person identity. |\n| `user_id?` | `string` \\| `null` | Verified Macro user association, if present. |\n\n\n\n# Type Alias: WhatsAppGroupSummary\n\n> **WhatsAppGroupSummary** = \\{ `backfill?`: `null` \\| [`LinkedBackfill`](LinkedBackfill.md); `can_send`: `boolean`; `id`: `string`; `last_message_at?`: `string` \\| `null`; `name`: `string`; `send_reason?`: `null` \\| [`LinkedReplyBlock`](LinkedReplyBlock.md); `unread_count`: `number`; `user_id`: `string`; \\}\n\nAdopted group visible through ordinary entity sharing.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `backfill?` | `null` \\| [`LinkedBackfill`](LinkedBackfill.md) | - |\n| `can_send` | `boolean` | Caller may currently send from their own account. |\n| `id` | `string` | Entity identifier. |\n| `last_message_at?` | `string` \\| `null` | Latest message timestamp. |\n| `name` | `string` | Display name. |\n| `send_reason?` | `null` \\| [`LinkedReplyBlock`](LinkedReplyBlock.md) | - |\n| `unread_count` | `number` | Unread live messages for this viewer. |\n| `user_id` | `string` | Actual entity owner. |\n\n\n\n# Class: ChannelActivity\n\nA user's channel activity marker.\n\n## Constructors\n\n### Constructor\n\n> **new ChannelActivity**(`client`, `channel`, `record`): `ChannelActivity`\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `channel` | [`Channel`](../../channel/classes/Channel.md) | Related channel. |\n| `record` | [`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md) | - |\n\n#### Returns\n\n`ChannelActivity`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `channel` | `readonly` | [`Channel`](../../channel/classes/Channel.md) | Related channel. |\n\n## Accessors\n\n### id\n\n#### Get Signature\n\n> **get** **id**(): `string`\n\nActivity identity.\n\n##### Returns\n\n`string`\n\n## Methods\n\n### createdAt()\n\n> **createdAt**(): `string`\n\nCreation time.\n\n#### Returns\n\n`string`\n\n***\n\n### recordInteraction()\n\n> **recordInteraction**(`type`): `Promise`\\<`ChannelActivity`\\>\n\nRecord a view or interaction in this channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `type` | [`ActivityType`](../../../../../generated/storage/types.gen/type-aliases/ActivityType.md) |\n\n#### Returns\n\n`Promise`\\<`ChannelActivity`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): [`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md)\n\nSerialize activity without credentials.\n\n#### Returns\n\n[`ApiActivity`](../../../../../generated/storage/types.gen/type-aliases/ApiActivity.md)\n\n***\n\n### user()\n\n> **user**(): [`User`](../../../users/user/classes/User.md)\n\nUser who interacted.\n\n#### Returns\n\n[`User`](../../../users/user/classes/User.md)\n\n\n\n# Class: Channel\n\nA channel.\n\n## Extends\n\n- [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md)\\<`ChannelDetail`\\>\n\n## Properties\n\n| Property | Modifier | Type | Default value | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `readonly` | `\"channel\"` | `'channel'` | Favorites identify channels as `channel`. | [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`entityType`](../../../entity/classes/PropertiedEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | `undefined` | - | - | [`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`id`](../../../entity/classes/PropertiedEntity.md#property-id) |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | `...` | The channel's display name, resolved from the viewer's perspective. | - | - |\n| `type` | `readonly` | () => `Promise`\\<[`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md)\\> | `...` | The channel's type (e.g. `public`, `dm`, `private`). | - | - |\n| `search` | `static` | (`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`Channel`\\> | `...` | Search channels by content, most relevant first, auto-paginated. | - | - |\n\n## Methods\n\n### addParticipants()\n\n> **addParticipants**(`users`): `Promise`\\<`void`\\>\n\nAdd users to the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `users` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### agentConversations()\n\n> **agentConversations**(): `Promise`\\<[`AgentConversation`](../../../agent-sessions/conversation/classes/AgentConversation.md)[]\\>\n\nConversations maintained by agents in this channel.\n\n#### Returns\n\n`Promise`\\<[`AgentConversation`](../../../agent-sessions/conversation/classes/AgentConversation.md)[]\\>\n\n***\n\n### attachments()\n\n> **attachments**(`opts?`): `AsyncGenerator`\\<[`ApiChannelAttachment`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelAttachment.md)\\>\n\nThe attachments posted in this channel, auto-paginated.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts?` | \\{ `pageSize?`: `number`; `type?`: `string`; \\} | - |\n| `opts.pageSize?` | `number` | - |\n| `opts.type?` | `string` | Filter by type: `static` for images/videos, `dss` for documents. |\n\n#### Returns\n\n`AsyncGenerator`\\<[`ApiChannelAttachment`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelAttachment.md)\\>\n\n***\n\n### delete()\n\n> **delete**(): `Promise`\\<`void`\\>\n\nDelete the channel. This is not reversible.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\nRemove a property from this entity, given its [properties](#properties) entry.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`deleteProperty`](../../../entity/classes/PropertiedEntity.md#deleteproperty)\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Channel`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`favorite`](../../../entity/classes/PropertiedEntity.md#favorite)\n\n***\n\n### join()\n\n> **join**(): `Promise`\\<`void`\\>\n\nJoin the channel as the current user.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### joinCode()\n\n> **joinCode**(): `Promise`\\<`string`\\>\n\nA reusable code that lets a user join this channel.\n\n#### Returns\n\n`Promise`\\<`string`\\>\n\n***\n\n### leave()\n\n> **leave**(): `Promise`\\<`void`\\>\n\nLeave the channel as the current user.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### message()\n\n> **message**(`id`): [`Message`](../../message/classes/Message.md)\n\nA handle to a message in this channel by id.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Message`](../../message/classes/Message.md)\n\n***\n\n### messages()\n\n> **messages**(`opts?`): `AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\nRoot messages in this channel, most recent first, auto-paginated.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `pageSize?`: `number`; \\} |\n| `opts.pageSize?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### messagesAfter()\n\n> **messagesAfter**(`after`, `opts?`): `AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\nRoot messages created or replied to at or after `after`, most recent\nfirst, auto-paginated. Use it to catch up after a disconnect.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `after` | `string` \\| `Date` |\n| `opts?` | \\{ `pageSize?`: `number`; \\} |\n| `opts.pageSize?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### messageThreadById()\n\n> **messageThreadById**(`id`): [`MessageThread`](../../../messages/thread/classes/MessageThread.md)\n\nA shared message thread scoped to this resource.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`MessageThread`](../../../messages/thread/classes/MessageThread.md)\n\n***\n\n### participants()\n\n> **participants**(): `Promise`\\<[`ApiChannelParticipant`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelParticipant.md)[]\\>\n\nThe channel's members, with their roles and join times.\n\n#### Returns\n\n`Promise`\\<[`ApiChannelParticipant`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelParticipant.md)[]\\>\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`permission`](../../../entity/classes/PropertiedEntity.md#permission)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\nThe properties set on this entity, each with its definition, value, and options.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`properties`](../../../entity/classes/PropertiedEntity.md#properties)\n\n***\n\n### propertyReference()\n\n> **propertyReference**(): [`PropertyTargetReference`](../../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\nThis entity's reference for bulk property operations.\n\n#### Returns\n\n[`PropertyTargetReference`](../../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`propertyReference`](../../../entity/classes/PropertiedEntity.md#propertyreference)\n\n***\n\n### recordActivity()\n\n> **recordActivity**(`type`): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)\\>\n\nRecord a view or interaction in this channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `type` | [`ActivityType`](../../../../../generated/storage/types.gen/type-aliases/ActivityType.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)\\>\n\n***\n\n### removeParticipants()\n\n> **removeParticipants**(`users`): `Promise`\\<`void`\\>\n\nRemove users from the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `users` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### rename()\n\n> **rename**(`name`): `Promise`\\<`void`\\>\n\nRename the channel.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `name` | `string` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### send()\n\n> **send**(`body`, `opts?`): `Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nPost a message. Plain text, or a rich body composed with `msg`.\n\nWorks with a channel webhook token as well as a normal one — see\n[postToChannel](../../post/functions/postToChannel.md) for which endpoint that picks and what it costs.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n| `opts?` | \\{ `thread?`: [`Thread`](../../thread/classes/Thread.md); \\} |\n| `opts.thread?` | [`Thread`](../../thread/classes/Thread.md) |\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\n***\n\n### setPicture()\n\n> **setPicture**(`picture?`): `Promise`\\<`void`\\>\n\nSet an uploaded profile picture, or clear it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `picture?` | [`ChannelPicture`](../../picture/classes/ChannelPicture.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\nSet a property value on this entity, or attach the property without a\nvalue when `value` is omitted.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`setProperty`](../../../entity/classes/PropertiedEntity.md#setproperty)\n\n***\n\n### timelinePage()\n\n> **timelinePage**(`selection?`): `Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: [`Message`](../../message/classes/Message.md); `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\nA mixed message and activity timeline page.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `selection?` | [`TimelineOptions`](../../../messages/thread/interfaces/TimelineOptions.md)\\<[`Message`](../../message/classes/Message.md)\\> |\n\n#### Returns\n\n`Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: [`Message`](../../message/classes/Message.md); `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`ApiChannelDetail`](../../../../../generated/storage/types.gen/type-aliases/ApiChannelDetail.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`toJSON`](../../../entity/classes/PropertiedEntity.md#tojson)\n\n***\n\n### typing()\n\n> **typing**(`action`, `opts?`): `Promise`\\<`void`\\>\n\nBroadcast a typing indicator, optionally scoped to a thread.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `action` | `\"stop\"` \\| `\"start\"` |\n| `opts?` | \\{ `thread?`: [`Thread`](../../thread/classes/Thread.md); \\} |\n| `opts.thread?` | [`Thread`](../../thread/classes/Thread.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Channel`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`unfavorite`](../../../entity/classes/PropertiedEntity.md#unfavorite)\n\n***\n\n### updatePropertyOptions()\n\n> **updatePropertyOptions**(`changes`): `Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\nApply multi-select option deltas atomically across this entity's properties.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `changes` | [`PropertyOptionDelta`](../../../entity/interfaces/PropertyOptionDelta.md)[] |\n\n#### Returns\n\n`Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\n#### Inherited from\n\n[`PropertiedEntity`](../../../entity/classes/PropertiedEntity.md).[`updatePropertyOptions`](../../../entity/classes/PropertiedEntity.md#updatepropertyoptions)\n\n***\n\n### webUrl()\n\n> **webUrl**(): `string`\n\nThe channel's URL in the Macro web app.\n\n#### Returns\n\n`string`\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `Channel`\n\nA handle to a channel by id. Details load on first access.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`Channel`\n\n***\n\n### create()\n\n> `static` **create**(`client`, `opts`): `Promise`\\<`Channel`\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n***\n\n### dm()\n\n> `static` **dm**(`client`, `recipient`): `Promise`\\<`Channel`\\>\n\nOpen (creating if needed) the DM channel with a user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n***\n\n### private()\n\n> `static` **private**(`client`, `recipients`): `Promise`\\<`Channel`\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<`Channel`\\>\n\n\n\n# Type Alias: ChannelAttachment\n\n> **ChannelAttachment** = [`GetChannelAttachmentsResponses`](../../../../../generated/storage/types.gen/type-aliases/GetChannelAttachmentsResponses.md)\\[`200`\\]\\[`\"items\"`\\]\\[`number`\\]\n\nA file or entity attached to a message in a channel.\n\n\n\n# Type Alias: ChannelParticipant\n\n> **ChannelParticipant** = [`GetChannelParticipantsResponses`](../../../../../generated/storage/types.gen/type-aliases/GetChannelParticipantsResponses.md)\\[`200`\\]\\[`number`\\]\n\nA member of a channel, with their role and join time.\n\n\n\n# Class: ChannelLabelsNamespace\n\nShared or private channel labels: named groups of channels shown in the Chat\nsidebar. Every member of the team sees the same labels in the same order,\nand any member may create, rename, delete, or move channels between them;\neach change applies to the whole team. Users without a team have private\nlabels belonging to their account.\n\nA label's `channelIds` lists only the channels the authenticated user is a\nmember of. Manual labels count all assignments; smart tags count visible\nmatches. A channel can be in one manual label and any number of matching\nsmart tags per team or account. Direct messages cannot be grouped.\n\n## Constructors\n\n### Constructor\n\n> **new ChannelLabelsNamespace**(`client`): `ChannelLabelsNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelLabelsNamespace`\n\n## Methods\n\n### create()\n\n> **create**(`name`, `channels?`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nCreate a label and atomically move `channels` into it. Names are unique\nwithin the team or account, case-insensitively.\n\n#### Parameters\n\n| Parameter | Type | Default value |\n| ------ | ------ | ------ |\n| `name` | `string` | `undefined` |\n| `channels?` | [`Channel`](../../channel/classes/Channel.md)[] | `[]` |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### createSmartTag()\n\n> **createSmartTag**(`name`, `rule`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nCreate a smart tag whose membership follows an attribute rule automatically.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `name` | `string` |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### delete()\n\n> **delete**(`label`): `Promise`\\<`void`\\>\n\nDelete a label for the whole team; its channels return to the plain list.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)[]\\>\n\nEvery label in the authenticated user's shared or private scope.\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)[]\\>\n\n***\n\n### previewSmartTag()\n\n> **previewSmartTag**(`rule`): `Promise`\\<[`SmartTagPreview`](../../../../../generated/storage/types.gen/type-aliases/SmartTagPreview.md)\\>\n\nPreview the first matches and total visible count without creating a tag.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`SmartTagPreview`](../../../../../generated/storage/types.gen/type-aliases/SmartTagPreview.md)\\>\n\n***\n\n### rename()\n\n> **rename**(`label`, `name`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nRename a label for the whole team.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n| `name` | `string` |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n***\n\n### setLabel()\n\n> **setLabel**(`channel`, `label`): `Promise`\\<`void`\\>\n\nMove a channel into `label`, or out of any label when `label` is `undefined`.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `channel` | [`Channel`](../../channel/classes/Channel.md) |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) \\| `undefined` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### updateSmartTag()\n\n> **updateSmartTag**(`label`, `name`, `rule`): `Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\nUpdate the name and matching rule of an existing smart tag.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `label` | [`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md) |\n| `name` | `string` |\n| `rule` | [`ChannelLabelRule`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabelRule.md) |\n\n#### Returns\n\n`Promise`\\<[`ChannelLabel`](../../../../../generated/storage/types.gen/type-aliases/ChannelLabel.md)\\>\n\n\n\n# Class: Message\n\nA message in a channel. A thin handle: `id` and `channelId` are known up\nfront, and record-backed fields (`content`, `author`) load lazily on first\naccess and cache. Actions carry the ids for you.\n\n## Extends\n\n- [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md)\\<[`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Default value | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n| `channelId` | `readonly` | `string` | `undefined` | - | - | - |\n| `content` | `readonly` | () => `Promise`\\<`string`\\> | `...` | The message body. | - | - |\n| `createdAt` | `readonly` | () => `Promise`\\<`string`\\> | `...` | When the message was created. | - | - |\n| `editedAt` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | `...` | When the message was last edited, if it has been. | - | - |\n| `entityType` | `readonly` | `\"channel_message\"` | `'channel_message'` | Favorites identify channel messages as `channel_message`. | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`entityType`](../../../entity/classes/FavoritableEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | `undefined` | - | - | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`id`](../../../entity/classes/FavoritableEntity.md#property-id) |\n| `mentions` | `readonly` | [`SimpleMention`](../../../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] | `[]` | Entities mentioned in this message, when a list, thread, or event supplied them. | - | - |\n| `updatedAt` | `readonly` | () => `Promise`\\<`string`\\> | `...` | When the message was last updated. | - | - |\n\n## Methods\n\n### author()\n\n> **author**(): `Promise`\\<[`User`](../../../users/user/classes/User.md)\\>\n\nThe user who sent this message.\n\n#### Returns\n\n`Promise`\\<[`User`](../../../users/user/classes/User.md)\\>\n\n***\n\n### channel()\n\n> **channel**(): [`Channel`](../../channel/classes/Channel.md)\n\nThe channel this message is in.\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### delete()\n\n> **delete**(): `Promise`\\<`void`\\>\n\nDelete this message.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### edit()\n\n> **edit**(`body`): `Promise`\\<`Message`\\>\n\nReplace this message's body.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) | Plain text, or a rich body composed with msg. |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Message`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`favorite`](../../../entity/classes/FavoritableEntity.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`permission`](../../../entity/classes/FavoritableEntity.md#permission)\n\n***\n\n### react()\n\n> **react**(`emoji`): `Promise`\\<`Message`\\>\n\nAdd an emoji reaction to this message.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `emoji` | `string` |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### reply()\n\n> **reply**(`body`): `Promise`\\<`Message`\\>\n\nPost a reply in this message's thread.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### thread()\n\n> **thread**(): [`Thread`](../../thread/classes/Thread.md)\n\nThe thread rooted at this message.\n\n#### Returns\n\n[`Thread`](../../thread/classes/Thread.md)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`toJSON`](../../../entity/classes/FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Message`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`unfavorite`](../../../entity/classes/FavoritableEntity.md#unfavorite)\n\n***\n\n### unreact()\n\n> **unreact**(`emoji`): `Promise`\\<`Message`\\>\n\nRemove one of your emoji reactions from this message.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `emoji` | `string` |\n\n#### Returns\n\n`Promise`\\<`Message`\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `channelId`, `id`, `mentions?`): `Message`\n\nA handle to a message by id. Fields load on first access.\n\n#### Parameters\n\n| Parameter | Type | Default value |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | `undefined` |\n| `channelId` | `string` | `undefined` |\n| `id` | `string` | `undefined` |\n| `mentions?` | [`SimpleMention`](../../../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] | `[]` |\n\n#### Returns\n\n`Message`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `channelId`, `data`): `Message`\n\nBuild a root or reply from a message record (pre-seeded, no fetch).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `channelId` | `string` |\n| `data` | [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md) |\n\n#### Returns\n\n`Message`\n\n\n\n# Type Alias: MessageData\n\n> **MessageData** = [`Message`](../../../../../generated/storage/types.gen/type-aliases/Message.md)\n\nThe API's representation of a message; the same record the document comment API returns.\n\n\n\n# Class: ChannelNamespace\n\n## Constructors\n\n### Constructor\n\n> **new ChannelNamespace**(`client`): `ChannelNamespace`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`ChannelNamespace`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `labels` | `readonly` | [`ChannelLabelsNamespace`](../../labels/classes/ChannelLabelsNamespace.md) | Team-shared labels that group channels in the Chat sidebar. |\n\n## Methods\n\n### activity()\n\n> **activity**(): `Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\nRecent channel activity, with channel and user handles.\n\n#### Returns\n\n`Promise`\\<[`ChannelActivity`](../../activity/classes/ChannelActivity.md)[]\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`Channel`](../../channel/classes/Channel.md)\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### create()\n\n> **create**(`opts`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nCreate a channel. The caller becomes the owner.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `name?`: `string`; `participants?`: [`User`](../../../users/user/classes/User.md)[]; `team?`: [`Team`](../../../teams/team/classes/Team.md); `type`: [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md); \\} | - |\n| `opts.name?` | `string` | - |\n| `opts.participants?` | [`User`](../../../users/user/classes/User.md)[] | Participants to add, excluding the owner. |\n| `opts.team?` | [`Team`](../../../teams/team/classes/Team.md) | Team, for team channels. |\n| `opts.type` | [`ChannelType`](../../../../../generated/storage/types.gen/type-aliases/ChannelType.md) | - |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### dm()\n\n> **dm**(`recipient`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipient` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### list()\n\n> **list**(): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\nAll channels the authenticated user is a member of.\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)[]\\>\n\n***\n\n### private()\n\n> **private**(`recipients`): `Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nOpen (creating if needed) the private group channel with a set of users.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `recipients` | [`User`](../../../users/user/classes/User.md)[] |\n\n#### Returns\n\n`Promise`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n***\n\n### search()\n\n> **search**(`query`, `opts?`): `AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\nSearch channels by name (client-side fuzzy filter on the full channel list)\nor by content (server-side unified search).\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `query` | `string` |\n| `opts?` | [`SearchOpts`](../../../search/interfaces/SearchOpts.md) |\n\n#### Returns\n\n`AsyncGenerator`\\<[`Channel`](../../channel/classes/Channel.md)\\>\n\n\n\n# Class: ChannelPicture\n\nAn uploaded channel profile picture in static file storage.\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `id` | `readonly` | `string` |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `id`: `string`; \\}\n\nSerialize the uploaded picture reference.\n\n#### Returns\n\n\\{ `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n***\n\n### byId()\n\n> `static` **byId**(`id`): `ChannelPicture`\n\nConstruct a reference from the upload receipt.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n`ChannelPicture`\n\n\n\n# Function: postToChannel()\n\n> **postToChannel**(`client`, `target`, `body`): `Promise`\\<`string`\\>\n\nPost a message using the endpoint supported by the caller's credentials.\n\nMost credentials use `POST /messages/channel/{id}`. User-owned bots without\nan acting user instead use `POST /channels/{id}/webhook`, which authorizes\nthrough channel membership. The bot owner is read from `GET /bots/me` and\ncached by the client.\n\nThe webhook endpoint supports content only. Mentions in `` tags still\nwork, but threads and attachments are not supported.\n\nPosting to a `Thread` puts the message in that thread; to a `Channel`, at the\nchannel root. One target rather than a channel plus a thread id, so the two\ncan't disagree.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `target` | [`Channel`](../../channel/classes/Channel.md) \\| [`Thread`](../../thread/classes/Thread.md) |\n| `body` | [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) |\n\n## Returns\n\n`Promise`\\<`string`\\>\n\n\n\n# Class: Thread\n\nA thread within a channel, rooted at a top-level message. Replies and\nthread-scoped posting live here.\n\n## Constructors\n\n### Constructor\n\n> **new Thread**(`client`, `channelId`, `rootId`): `Thread`\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `client` | `MacroClient` | - |\n| `channelId` | `string` | - |\n| `rootId` | `string` | The id of the message this thread hangs off. |\n\n#### Returns\n\n`Thread`\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `channelId` | `readonly` | `string` | - |\n| `rootId` | `readonly` | `string` | The id of the message this thread hangs off. |\n\n## Methods\n\n### channel()\n\n> **channel**(): [`Channel`](../../channel/classes/Channel.md)\n\nThe channel this thread is in.\n\n#### Returns\n\n[`Channel`](../../channel/classes/Channel.md)\n\n***\n\n### replies()\n\n> **replies**(): `Promise`\\<[`Message`](../../message/classes/Message.md)[]\\>\n\nList the replies in this thread, oldest first.\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)[]\\>\n\n***\n\n### reply()\n\n> **reply**(`body`): `Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nPost a reply in this thread.\n\n#### Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../../../../mentions/interfaces/RichMessage.md) | Plain text, or a rich body composed with msg. |\n\n#### Returns\n\n`Promise`\\<[`Message`](../../message/classes/Message.md)\\>\n\nThe created reply.\n\n***\n\n### root()\n\n> **root**(): [`Message`](../../message/classes/Message.md)\n\nThe message this thread hangs off.\n\n#### Returns\n\n[`Message`](../../message/classes/Message.md)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `channelId`: `string`; `rootId`: `string`; \\}\n\nSerialize the thread identity without its authenticated client.\n\n#### Returns\n\n\\{ `channelId`: `string`; `rootId`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `channelId` | `string` |\n| `rootId` | `string` |\n\n\n\n# Class: WhatsAppAccount\n\nThe current user's WhatsApp account, connected through the Macro app.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `identity` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Verified remote identity, absent until pairing succeeds. | - |\n| `owner` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | The Macro user who owns this account. | - |\n| `state` | `readonly` | () => `Promise`\\<[`LinkedAccountState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccountState.md)\\> | Account connection state; call refresh before polling it again. | - |\n\n## Methods\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppAccount`\\>\n\nDiscard cached connection state and load its current value.\n\n#### Returns\n\n`Promise`\\<`WhatsAppAccount`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppAccount`\n\nReference an account; reads still enforce the authenticated owner's scope.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppAccount`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `record`): `WhatsAppAccount`\n\nSeed an account handle from an API record.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `record` | [`LinkedAccount`](../../../../../generated/storage/types.gen/type-aliases/LinkedAccount.md) |\n\n#### Returns\n\n`WhatsAppAccount`\n\n\n\n# Class: WhatsAppChat\n\nOne chat of the current user's WhatsApp chat list: a group or a direct chat.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `archived` | `readonly` | () => `Promise`\\<`boolean`\\> | Archived in WhatsApp. | - |\n| `canAdd` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether adding it to Macro works now. | - |\n| `cannotAddReason` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Why it can't be added, when it is neither added, shared nor addable. | - |\n| `group` | `readonly` | () => `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \\| `undefined`\\> | The current user's own Macro group for this chat, once added. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `kind` | `readonly` | () => `Promise`\\<[`LinkedChatKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedChatKind.md)\\> | `group` or `direct`. | - |\n| `lastActivityAt` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Newest activity WhatsApp reported, when known. | - |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | Group subject (or member names), or the other person's name or number. | - |\n| `pinned` | `readonly` | () => `Promise`\\<`boolean`\\> | Pinned in WhatsApp. | - |\n| `shared` | `readonly` | () => `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \\| `undefined`\\> | Someone else's Macro group for this chat, shared with the current user. | - |\n\n## Methods\n\n### adopt()\n\n> **adopt**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\\>\n\nAdd a group chat to Macro as the current user's own group; its earlier\nmessages are imported from the phone. Adding it again returns the same\ngroup. Direct chats can't be added yet.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\\>\n\n***\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppChat`\\>\n\nReload the chat's list entry.\n\n#### Returns\n\n`Promise`\\<`WhatsAppChat`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppChat`\n\nReference a chat by its WhatsApp JID.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppChat`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `record`): `WhatsAppChat`\n\nSeed a chat handle from the chat list.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `record` | [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md) |\n\n#### Returns\n\n`WhatsAppChat`\n\n\n\n# Class: WhatsAppGroup\n\nIndependently shareable adopted WhatsApp group entity.\n\n## Extends\n\n- [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md)\\<[`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Overrides | Inherited from |\n| ------ | ------ | ------ | ------ | ------ | ------ |\n| `backfill` | `readonly` | () => `Promise`\\<[`LinkedBackfill`](../../../../../generated/storage/types.gen/type-aliases/LinkedBackfill.md) \\| `undefined`\\> | Importing earlier messages from the owner's phone after adding, if any. | - | - |\n| `canSend` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether the caller can send from their own connected account. | - | - |\n| `entityType` | `readonly` | `\"whatsapp_group\"` | Canonical sharing and favorites kind. | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`entityType`](../../../entity/classes/FavoritableEntity.md#property-entitytype) | - |\n| `id` | `public readonly` | `string` | - | - | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`id`](../../../entity/classes/FavoritableEntity.md#property-id) |\n| `limits` | `readonly` | () => `Promise`\\<[`LinkedCapabilities`](../../../../../generated/storage/types.gen/type-aliases/LinkedCapabilities.md)\\> | Supported sizes and mutation window. | - | - |\n| `name` | `readonly` | () => `Promise`\\<`string`\\> | Display name. | - | - |\n| `owner` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | Actual owner, independent of WhatsApp membership. | - | - |\n| `roster` | `readonly` | () => `Promise`\\<[`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) \\| `undefined`\\> | Current remote roster, when available. | - | - |\n| `sendingIdentity` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Caller's own verified sending identity. | - | - |\n| `sendReason` | `readonly` | () => `Promise`\\<`NonNullable`\\ \\| `undefined`\\> | Reason sending is blocked. | - | - |\n| `unreadCount` | `readonly` | () => `Promise`\\<`number`\\> | Per-user unread count. | - | - |\n\n## Methods\n\n### delivery()\n\n> **delivery**(`sends`): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\nRead delivery for selected caller-owned intents or messages.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `sends` | ([`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) \\| [`WhatsAppSend`](../../send/classes/WhatsAppSend.md))[] |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\n***\n\n### detach()\n\n> **detach**(): `Promise`\\<`void`\\>\n\nStop observation while preserving history and established sharing.\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`WhatsAppGroup`\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`favorite`](../../../entity/classes/FavoritableEntity.md#favorite)\n\n***\n\n### markRead()\n\n> **markRead**(`message`): `Promise`\\<`void`\\>\n\nAdvance the caller's own read cursor.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### messageAttachments()\n\n> **messageAttachments**(`messages`): `Promise`\\<\\{ `attachments`: \\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]; `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}[]\\>\n\nRead attachment states for selected messages.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `messages` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)[] |\n\n#### Returns\n\n`Promise`\\<\\{ `attachments`: \\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]; `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}[]\\>\n\n***\n\n### messages()\n\n> **messages**(`options?`): `AsyncGenerator`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)\\>\n\nIterate newest-first timeline pages lazily.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options?` | \\{ `limit?`: `number`; \\} |\n| `options.limit?` | `number` |\n\n#### Returns\n\n`AsyncGenerator`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md)\\>\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`permission`](../../../entity/classes/FavoritableEntity.md#permission)\n\n***\n\n### permissions()\n\n> **permissions**(): `Promise`\\<[`SharePermissionV2`](../../../../../generated/storage/types.gen/type-aliases/SharePermissionV2.md)\\>\n\nRead standard link/team sharing settings.\n\n#### Returns\n\n`Promise`\\<[`SharePermissionV2`](../../../../../generated/storage/types.gen/type-aliases/SharePermissionV2.md)\\>\n\n***\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppGroup`\\>\n\nReload detail, permissions and caller capabilities.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n***\n\n### reply()\n\n> **reply**(`content`, `options`): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)\\>\n\nPersonal sessions and owner API credentials can send. Bots never send.\nPreserve the idempotency key; uncertain outcomes are never automatically resent.\nThe server enforces one request per second per user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `content` | [`WhatsAppReply`](../type-aliases/WhatsAppReply.md) |\n| `options` | \\{ `idempotencyKey`: `string`; `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\} |\n| `options.idempotencyKey` | `string` |\n| `options.replyTo?` | [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)\\>\n\n***\n\n### sends()\n\n> **sends**(): `Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\nRead only the caller's pending, uncertain or failed sends.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppSend`](../../send/classes/WhatsAppSend.md)[]\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`WhatsAppGroupDetail`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupDetail.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`toJSON`](../../../entity/classes/FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`WhatsAppGroup`\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`WhatsAppGroup`\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`unfavorite`](../../../entity/classes/FavoritableEntity.md#unfavorite)\n\n***\n\n### updatePermissions()\n\n> **updatePermissions**(`update`): `Promise`\\<`void`\\>\n\nActual owner updates standard link/team sharing settings.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `update` | [`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### upload()\n\n> **upload**(`file`): `Promise`\\<[`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md)\\>\n\nStage a supported attachment for a deliberate send.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `file` | `Blob` \\| `File` |\n\n#### Returns\n\n`Promise`\\<[`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md)\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `id`): `WhatsAppGroup`\n\nReference an adopted group; access is checked on each request.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppGroup`\n\n\n\n# Type Alias: WhatsAppReply\n\n> **WhatsAppReply** = \\{ `text`: `string`; `type`: `\"text\"`; \\} \\| \\{ `caption?`: `string`; `type`: `\"media\"`; `upload`: [`WhatsAppUpload`](../../upload/classes/WhatsAppUpload.md); \\} \\| \\{ `message`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); `operation`: `\"reaction\"` \\| `\"edit\"` \\| `\"delete\"`; `text?`: `string`; `type`: `\"mutation\"`; \\}\n\nDeliberate content from the credential owner's own WhatsApp account.\n\n\n\n# Class: WhatsAppMessage\n\nMessage in an independently shared WhatsApp group.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `attachments` | `readonly` | () => `Promise`\\<\\{ `document`: [`Document`](../../../documents/document/classes/Document.md) \\| `undefined`; `fileName`: `string`; `mime`: `string`; `ordinal`: `number`; `size`: `number`; `state`: [`LinkedAttachmentState`](../../../../../generated/storage/types.gen/type-aliases/LinkedAttachmentState.md); \\}[]\\> | Attachment state and imported document handles. | - |\n| `body` | `readonly` | () => `Promise`\\<`string`\\> | Plain WhatsApp text. | - |\n| `deleted` | `readonly` | () => `Promise`\\<`boolean`\\> | Deleted for everyone. | - |\n| `deliveryState` | `readonly` | () => `Promise`\\<`NonNullable`\\ \\| `undefined`\\> | Caller-owned send's delivery state, when present. | - |\n| `editedAt` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Last edit time. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `reactions` | `readonly` | () => `Promise`\\<[`WhatsAppGroupReaction`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupReaction.md)[]\\> | Grouped emoji counts and caller's own reaction. | - |\n| `replyTo` | `readonly` | () => `Promise`\\<`WhatsAppMessage` \\| `undefined`\\> | Quoted message in this group. | - |\n| `sender` | `readonly` | () => `Promise`\\<[`WhatsAppGroupSender`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupSender.md)\\> | Protocol-verified sender association and display name. | - |\n| `sentAt` | `readonly` | () => `Promise`\\<`string`\\> | WhatsApp timestamp. | - |\n\n## Accessors\n\n### groupId\n\n#### Get Signature\n\n> **get** **groupId**(): `string`\n\nGroup identity for checking reply/mutation scope.\n\n##### Returns\n\n`string`\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `group`, `id`): `WhatsAppMessage`\n\nReference a message within its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppMessage`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `group`, `record`): `WhatsAppMessage`\n\nSeed a message handle from a timeline response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`WhatsAppGroupMessage`](../../../../../generated/storage/types.gen/type-aliases/WhatsAppGroupMessage.md) |\n\n#### Returns\n\n`WhatsAppMessage`\n\n\n\n# Class: WhatsAppNamespace\n\nOperate on an account already paired through the Macro app.\n\n## Constructors\n\n### Constructor\n\n> **new WhatsAppNamespace**(`client`): `WhatsAppNamespace`\n\nBind existing-account operations to this authenticated client.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n\n#### Returns\n\n`WhatsAppNamespace`\n\n## Methods\n\n### account()\n\n> **account**(): `Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\nCurrent owner's account, or undefined when no account has been connected.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppAccount`](../../account/classes/WhatsAppAccount.md) \\| `undefined`\\>\n\n***\n\n### byId()\n\n> **byId**(`id`): [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\nReference an adopted entity without fetching it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `id` | `string` |\n\n#### Returns\n\n[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\n\n***\n\n### groups()\n\n> **groups**(): `Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\nAdopted groups shared with the caller, including without WhatsApp.\n\n#### Returns\n\n`Promise`\\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\\>\n\n\n\n# Class: WhatsAppSend\n\nOne deliberate send intent. Unknown outcomes must never be automatically resent.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `createdAt` | `readonly` | () => `Promise`\\<`string`\\> | When the send intent was created. | - |\n| `errorCode` | `readonly` | () => `Promise`\\<`string` \\| `undefined`\\> | Sanitized failure code, when present. | - |\n| `group` | `readonly` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) | Group entity containing this send. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `message` | `readonly` | () => `Promise`\\<[`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md) \\| `undefined`\\> | Group message once WhatsApp accepted the send. | - |\n| `state` | `readonly` | () => `Promise`\\<[`LinkedDeliveryState`](../../../../../generated/storage/types.gen/type-aliases/LinkedDeliveryState.md)\\> | Last observed delivery state; refresh explicitly to poll again. | - |\n\n## Methods\n\n### refresh()\n\n> **refresh**(): `Promise`\\<`WhatsAppSend`\\>\n\nFetch current delivery state without retrying or submitting the message.\n\n#### Returns\n\n`Promise`\\<`WhatsAppSend`\\>\n\n***\n\n### request()\n\n> **request**(): `Promise`\\<\\{ `idempotencyKey`: `string`; `message`: [`WhatsAppReply`](../../group/type-aliases/WhatsAppReply.md); `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}\\>\n\nInspect the original intent for reconciliation; never resubmit an unknown outcome automatically.\n\n#### Returns\n\n`Promise`\\<\\{ `idempotencyKey`: `string`; `message`: [`WhatsAppReply`](../../group/type-aliases/WhatsAppReply.md); `replyTo?`: [`WhatsAppMessage`](../../message/classes/WhatsAppMessage.md); \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `group`, `id`): `WhatsAppSend`\n\nReference a send intent within its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppSend`\n\n***\n\n### from()\n\n> `static` **from**(`client`, `group`, `record`): `WhatsAppSend`\n\nSeed a send handle from a server response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`LinkedSendProgress`](../../../../../generated/storage/types.gen/type-aliases/LinkedSendProgress.md) |\n\n#### Returns\n\n`WhatsAppSend`\n\n\n\n# Class: WhatsAppUpload\n\nA staged attachment scoped to one adopted group; use it in a deliberate media send.\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `filename?` | `readonly` | `string` | Display filename supplied by the server. |\n| `groupId` | `readonly` | `string` | The group this upload can be sent to. |\n| `id` | `readonly` | `string` | Correlation identity of the staged upload. |\n| `kind?` | `readonly` | [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) | Media category supplied by the server. |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `filename`: `string` \\| `undefined`; `groupId`: `string`; `id`: `string`; `kind`: [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined`; \\}\n\nSerialize the upload reference without credentials.\n\n#### Returns\n\n\\{ `filename`: `string` \\| `undefined`; `groupId`: `string`; `id`: `string`; `kind`: [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `filename` | `string` \\| `undefined` |\n| `groupId` | `string` |\n| `id` | `string` |\n| `kind` | [`LinkedMediaKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedMediaKind.md) \\| `undefined` |\n\n***\n\n### byId()\n\n> `static` **byId**(`group`, `id`): `WhatsAppUpload`\n\nReference a previously staged upload in its original group.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `id` | `string` |\n\n#### Returns\n\n`WhatsAppUpload`\n\n***\n\n### from()\n\n> `static` **from**(`group`, `record`): `WhatsAppUpload`\n\nSeed a handle from the server's upload receipt.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `group` | [`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) |\n| `record` | [`LinkedUploadedAttachment`](../../../../../generated/storage/types.gen/type-aliases/LinkedUploadedAttachment.md) |\n\n#### Returns\n\n`WhatsAppUpload`\n"
},
{
"name": "crm",
@@ -177,6 +177,6 @@
"name": "core",
"description": "SDK construction, entity handles, lazy fields, search options, events and shared types.",
"overview": "\n# Interface: MacroOpts\n\nOptions passed to `new Macro(opts)` and stored on `MacroClient`.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `auth?` | [`MacroAuth`](../type-aliases/MacroAuth.md) | How to authenticate. Takes precedence over `token`. Falls back to `MACRO_API_KEY` (a user API key or bearer token) or `MACRO_BOT_TOKEN` (bot). |\n| `env?` | [`Env`](../type-aliases/Env.md) | Which Macro environment to talk to. Falls back to the MACRO_ENV env var, then `'prod'`. |\n| `hosts?` | `Partial`\\<`Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\> | Override individual service hosts (e.g. point one at localhost). |\n| `onRequest?` | (`event`) => `void` | Optional generated API operation events; excludes arguments, URLs and response data. |\n| `requestedAs?` | `string` | User id the bot acts for, sent as `x-macro-bot-for-macro-user-id` on every request. Bot auth only. Set via `macro.requestedAs(user)` rather than directly. |\n| `token?` | [`TokenSource`](../type-aliases/TokenSource.md) | Shorthand for `auth: { type: 'user', token }`. Accepts a Settings API key (`mak_…`) or a bearer token. |\n| `webAppUrl?` | `string` | Override the web app base URL (e.g. for local frontend dev). Also reads MACRO_WEB_URL. |\n| `webhookSecret?` | `string` | Signing secret for verifying incoming persisted-webhook deliveries. Required only for `macro.events.webhook()` / `macro.events.handle()`. SSE via `macro.events.listen()` uses the API token and does not need this. Falls back to MACRO_WEBHOOK_SECRET. |\n| `wsVerify?` | `string` | - |\n\n\n\n# Type Alias: BotScope\n\n> **BotScope** = `\"user\"` \\| `\"team\"`\n\nAccess scope for bot-authenticated requests. `user` acts with the\nrequested-as user's access (requires `requestedAs`); `team` acts with the\nbot's owning team's access (team-owned bots only).\n\n\n\n# Type Alias: Env\n\n> **Env** = `\"dev\"` \\| `\"prod\"` \\| `\"local\"`\n\n\n\n# Type Alias: MacroAuth\n\n> **MacroAuth** = \\{ `apiKey?`: `never`; `token`: [`TokenSource`](TokenSource.md); `type`: `\"user\"`; \\} \\| \\{ `apiKey`: `string`; `token?`: `never`; `type`: `\"user\"`; \\} \\| \\{ `scope?`: [`BotScope`](BotScope.md); `token`: [`TokenSource`](TokenSource.md); `type`: `\"bot\"`; \\}\n\nHow the SDK authenticates with Macro.\n\nA user has exactly one of two credential fields.\n\n- `token`: a bearer token, or a `mak_` API key. The SDK picks the header\n from the prefix at send time.\n- `apiKey`: a Settings → API Keys key, always sent as\n `x-macro-user-api-key`. Not prefix-checked, so keys that predate the\n `mak_` prefix work here.\n\nA bot uses an `mbot_` token as `x-macro-bot-token` plus\n`x-macro-bot-scope`, defaulting to `user` when `requestedAs` is set and\n`team` otherwise.\n\n\n\n# Type Alias: ServiceName\n\n> **ServiceName** = `\"agent-harness\"` \\| `\"storage\"` \\| `\"auth\"` \\| `\"email\"` \\| `\"calendar\"` \\| `\"cognition\"` \\| `\"notification\"` \\| `\"properties\"` \\| `\"search\"` \\| `\"scheduled-action\"` \\| `\"static-files\"` \\| `\"connection\"` \\| `\"contacts\"` \\| `\"unfurl\"`\n\nThe backend services the SDK talks to. Note `search` and `properties` are\nserved on the storage host, so they point there.\n\n\n\n# Type Alias: TokenSource\n\n> **TokenSource** = `string` \\| (() => `string` \\| `Promise`\\<`string`\\>)\n\nA credential string, or a (possibly async) function that returns one.\n\n\n\n# Variable: HOSTS\n\n> `const` **HOSTS**: `Record`\\<[`Env`](../type-aliases/Env.md), `Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\>\n\n\n\n# Variable: WEB\\_APP\\_URLS\n\n> `const` **WEB\\_APP\\_URLS**: `Record`\\<[`Env`](../type-aliases/Env.md), `string`\\>\n\n\n\n# Class: Macro\\\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` *extends* [`MacroOpts`](../../config/interfaces/MacroOpts.md) | [`MacroOpts`](../../config/interfaces/MacroOpts.md) |\n\n## Constructors\n\n### Constructor\n\n> **new Macro**\\<`T`\\>(`opts`): `Macro`\\<`T`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts` | `T` |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `_client` | `readonly` | `MacroClient` | Direct access to the underlying hey-api service clients. |\n| `agents` | `readonly` | [`AgentNamespace`](../../entities/agents/namespace/classes/AgentNamespace.md) | agents resources and operations. |\n| `agentSessions` | `readonly` | [`AgentSessionNamespace`](../../entities/agent-sessions/namespace/classes/AgentSessionNamespace.md) | - |\n| `ai` | `readonly` | [`AiNamespace`](../../entities/ai/namespace/classes/AiNamespace.md) | - |\n| `apiKeys` | `readonly` | [`ApiKeyNamespace`](../../entities/api-keys/namespace/classes/ApiKeyNamespace.md) | apiKeys resources and operations. |\n| `bots` | `readonly` | [`BotsNamespace`](../../entities/bots/namespace/classes/BotsNamespace.md) | - |\n| `calendar` | `readonly` | [`CalendarNamespace`](../../entities/calendar/namespace/classes/CalendarNamespace.md) | - |\n| `calls` | `readonly` | [`CallRecordNamespace`](../../entities/calls/namespace/classes/CallRecordNamespace.md) | - |\n| `channels` | `readonly` | [`ChannelNamespace`](../../entities/channels/namespace/classes/ChannelNamespace.md) | - |\n| `crm` | `readonly` | [`CrmNamespace`](../../entities/crm/namespace/classes/CrmNamespace.md) | - |\n| `databases` | `readonly` | [`DatabaseNamespace`](../../entities/databases/namespace/classes/DatabaseNamespace.md) | - |\n| `documents` | `readonly` | [`DocumentNamespace`](../../entities/documents/namespace/classes/DocumentNamespace.md) | - |\n| `email` | `readonly` | [`EmailNamespace`](../../entities/email/namespace/classes/EmailNamespace.md) | - |\n| `entityMentions` | `readonly` | [`EntityMentionNamespace`](../../entities/entity-mentions/namespace/classes/EntityMentionNamespace.md) | entityMentions resources and operations. |\n| `events` | `readonly` | [`MacroEvents`](../../events/receiver/classes/MacroEvents.md) | - |\n| `favorites` | `readonly` | [`FavoritesNamespace`](../../entities/favorites/namespace/classes/FavoritesNamespace.md) | - |\n| `foreignEntities` | `readonly` | [`ForeignEntityNamespace`](../../entities/foreign/namespace/classes/ForeignEntityNamespace.md) | - |\n| `forms` | `readonly` | [`FormNamespace`](../../entities/forms/namespace/classes/FormNamespace.md) | Build forms and submit answers without granting respondents database access. |\n| `githubPullRequests` | `readonly` | [`GithubPullRequestNamespace`](../../entities/github-pull-requests/namespace/classes/GithubPullRequestNamespace.md) | githubPullRequests resources and operations. |\n| `harnesses` | `readonly` | [`HarnessNamespace`](../../entities/harnesses/namespace/classes/HarnessNamespace.md) | harnesses resources and operations. |\n| `initiatives` | `readonly` | [`InitiativeNamespace`](../../entities/initiatives/namespace/classes/InitiativeNamespace.md) | initiatives resources and operations. |\n| `meetings` | `readonly` | [`MeetingNamespace`](../../entities/meetings/namespace/classes/MeetingNamespace.md) | meetings resources and operations. |\n| `notifications` | `readonly` | [`NotificationNamespace`](../../entities/notifications/namespace/classes/NotificationNamespace.md) | - |\n| `pins` | `readonly` | [`PinsNamespace`](../../entities/pins/namespace/classes/PinsNamespace.md) | - |\n| `projects` | `readonly` | [`ProjectNamespace`](../../entities/projects/namespace/classes/ProjectNamespace.md) | - |\n| `properties` | `readonly` | [`PropertiesNamespace`](../../entities/properties/namespace/classes/PropertiesNamespace.md) | - |\n| `routines` | `readonly` | [`RoutineNamespace`](../../entities/routines/namespace/classes/RoutineNamespace.md) | routines resources and operations. |\n| `tasks` | `readonly` | [`TaskNamespace`](../../entities/tasks/namespace/classes/TaskNamespace.md) | - |\n| `teams` | `readonly` | [`TeamNamespace`](../../entities/teams/namespace/classes/TeamNamespace.md) | - |\n| `unfurls` | `readonly` | [`UnfurlNamespace`](../../entities/unfurls/namespace/classes/UnfurlNamespace.md) | unfurls resources and operations. |\n| `users` | `readonly` | [`UserNamespace`](../../entities/users/namespace/classes/UserNamespace.md) | - |\n| `webAppUrl` | `readonly` | `string` | Base URL of the Macro web app, used to build entity URLs. |\n| `webhooks` | `readonly` | [`WebhooksNamespace`](../../entities/webhooks/namespace/classes/WebhooksNamespace.md) | - |\n| `whatsapp` | `readonly` | [`WhatsAppNamespace`](../../entities/whatsapp/namespace/classes/WhatsAppNamespace.md) | Personal WhatsApp groups and shared group operations. |\n\n## Methods\n\n### myPrincipalId()\n\n> **myPrincipalId**(): `Promise`\\<`string`\\>\n\nThe authenticated caller's mentionable principal — `bot|` for bot\nauth, `macro|` for user auth — fetched once and cached.\n\n#### Returns\n\n`Promise`\\<`string`\\>\n\n***\n\n### requestedAs()\n\n> **requestedAs**(`user`): `Macro`\\<`T`\\>\n\nClone of this SDK acting on behalf of `user` (sent as\n`x-macro-bot-for-macro-user-id`). Bot auth only — throws for user auth,\nsince a user token always acts as its own user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../entities/users/user/classes/User.md) |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n\n\n# Type Alias: RequestActivity\n\n> **RequestActivity** = \\{ `id`: `number`; `operation`: `string`; `service`: `string`; `status`: `\"started\"` \\| `\"completed\"` \\| `\"failed\"`; \\}\n\nA generated SDK operation lifecycle. Contains no arguments, URLs or response data.\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `id` | `number` |\n| `operation` | `string` |\n| `service` | `string` |\n| `status` | `\"started\"` \\| `\"completed\"` \\| `\"failed\"` |\n",
- "documentation": "# Macro SDK: core\n\nGenerated by TypeDoc. Paths below refer to the canonical Markdown hierarchy. Other entity handles are documented in their named section; request core for shared SDK helpers.\n\n\n# Type Alias: BulkUpdateEntityPropertyOptionsResponse\n\n> **BulkUpdateEntityPropertyOptionsResponse** = \\{ `properties`: [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[]; \\}\n\nResponse for a bulk option update: each property's reconciled final ids.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `properties` | [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[] | The final option ids per updated property. |\n\n\n\n# Type Alias: DataType\n\n> **DataType** = `\"BOOLEAN\"` \\| `\"DATE\"` \\| `\"NUMBER\"` \\| `\"STRING\"` \\| `\"SELECT_NUMBER\"` \\| `\"SELECT_STRING\"` \\| `\"TAG\"` \\| `\"ENTITY\"` \\| `\"LINK\"`\n\nData type for property values, determining storage and validation.\n\n\n\n# Type Alias: EntityProperty\n\n> **EntityProperty** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; \\}\n\nAssignment of a property definition to a specific entity (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `created_at` | `string` |\n| `entity_id` | `string` |\n| `entity_type` | [`EntityType`](EntityType.md) |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n\n\n\n# Type Alias: EntityPropertyOptionSelectionResponse\n\n> **EntityPropertyOptionSelectionResponse** = \\{ `option_ids`: `string`[]; `property_id`: `string`; \\}\n\nThe reconciled final option ids stored for one property after a bulk update.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `option_ids` | `string`[] | The final option ids the server persisted, in stored order. |\n| `property_id` | `string` | The property definition the options belong to. |\n\n\n\n# Type Alias: EntityPropertyWithDefinition\n\n> **EntityPropertyWithDefinition** = \\{ `definition`: [`PropertyDefinition`](PropertyDefinition.md); `options?`: [`PropertyOption`](PropertyOption.md)[] \\| `null`; `property`: [`EntityProperty`](EntityProperty.md); `value?`: `null` \\| [`PropertyValue`](PropertyValue.md); \\}\n\nEntity property with its definition, value, and options (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `definition` | [`PropertyDefinition`](PropertyDefinition.md) |\n| `options?` | [`PropertyOption`](PropertyOption.md)[] \\| `null` |\n| `property` | [`EntityProperty`](EntityProperty.md) |\n| `value?` | `null` \\| [`PropertyValue`](PropertyValue.md) |\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `specific_message_id?`: `string` \\| `null`; \\}\n\nEntity reference for entity-type property values.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | - |\n| `entity_type` | [`EntityType`](EntityType.md) | - |\n| `specific_message_id?` | `string` \\| `null` | For CHANNEL, CHAT, THREAD entity types - optional specific message ID. This allows referencing a specific message within a thread/channel/chat. |\n\n\n\n# Type Alias: EntityType\n\n> **EntityType** = `\"CALENDAR_EVENT\"` \\| `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"CONTACT\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"TASK\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nType of entity that can be referenced by entity properties.\n\n\n\n# Type Alias: PropertyDefinition\n\n> **PropertyDefinition** = \\{ `created_at`: `string`; `data_type`: [`DataType`](DataType.md); `display_name`: `string`; `id`: `string`; `is_metadata`: `boolean`; `is_multi_select`: `boolean`; `is_system`: `boolean`; `owner`: [`PropertyOwner`](PropertyOwner.md); `specific_entity_type`: `null` \\| [`EntityType`](EntityType.md); `updated_at`: `string`; \\}\n\nProperty definition model (service representation).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | - |\n| `data_type` | [`DataType`](DataType.md) | - |\n| `display_name` | `string` | - |\n| `id` | `string` | - |\n| `is_metadata` | `boolean` | Flag to indicate if this is a system-generated metadata property. Not stored in database - computed at service layer. |\n| `is_multi_select` | `boolean` | - |\n| `is_system` | `boolean` | Flag to indicate if this is a system property (stored in DB). |\n| `owner` | [`PropertyOwner`](PropertyOwner.md) | - |\n| `specific_entity_type` | `null` \\| [`EntityType`](EntityType.md) | - |\n| `updated_at` | `string` | - |\n\n\n\n# Type Alias: PropertyOption\n\n> **PropertyOption** = \\{ `color`: `string` \\| `null`; `created_at`: `string`; `display_order`: `number`; `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; `value`: [`PropertyOptionValue`](PropertyOptionValue.md); \\}\n\nA selectable option for select-type properties (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `color` | `string` \\| `null` |\n| `created_at` | `string` |\n| `display_order` | `number` |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n| `value` | [`PropertyOptionValue`](PropertyOptionValue.md) |\n\n\n\n# Type Alias: PropertyOptionValue\n\n> **PropertyOptionValue** = \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\}\n\nThe value of a property option - either a string or a number.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"string\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"string\"` | - |\n| `value` | `string` | String value for SelectString properties |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"number\"` | - |\n| `value` | `number` | Number value for SelectNumber properties |\n\n\n\n# Type Alias: PropertyOwner\n\n> **PropertyOwner** = \\{ `scope`: `\"user\"`; `user_id`: `string`; \\} \\| \\{ `scope`: `\"team\"`; `team_id`: `string`; \\} \\| \\{ `database_id`: `string`; `scope`: `\"database\"`; \\} \\| \\{ `scope`: `\"system\"`; \\}\n\nDefines who owns a property - user-scoped, team-scoped, database-scoped, or system.\n\n\n\n# Type Alias: PropertyTargetEntityType\n\n> **PropertyTargetEntityType** = `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nCanonical type of an entity receiving properties.\n\nTasks are documents at API boundaries. `Task` intentionally does not exist\nhere; task classification is resolved by the properties domain from the\ndocument subtype.\n\n\n\n# Type Alias: PropertyTargetReference\n\n> **PropertyTargetReference** = \\{ `entity_id`: `string`; `entity_type`: [`PropertyTargetEntityType`](PropertyTargetEntityType.md); \\}\n\nCanonical reference to an entity receiving properties.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Entity identifier. |\n| `entity_type` | [`PropertyTargetEntityType`](PropertyTargetEntityType.md) | Canonical entity type. |\n\n\n\n# Type Alias: PropertyValue\n\n> **PropertyValue** = \\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"Number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"String\"`; `value`: `string`; \\} \\| \\{ `type`: `\"Date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\} \\| \\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\} \\| \\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\nProperty value (service representation).\n\nRepresents the actual value stored for an entity property.\nThis is serialized to/from JSONB in the database.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Boolean\"` | - |\n| `value` | `boolean` | Boolean value Serializes as: {\"type\": \"Boolean\", \"value\": true} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Number\"` | - |\n| `value` | `number` | Numeric value Serializes as: {\"type\": \"Number\", \"value\": 42.5} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"String\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"String\"` | - |\n| `value` | `string` | String value Serializes as: {\"type\": \"String\", \"value\": \"text\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Date\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Date\"` | - |\n| `value` | `string` | Date/timestamp value Serializes as: {\"type\": \"Date\", \"value\": \"2025-01-01T00:00:00Z\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"SelectOption\"` | - |\n| `value` | `string`[] | Select option(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"SelectOption\", \"value\": [\"uuid\"]} (length 0 or 1) Multi-select: {\"type\": \"SelectOption\", \"value\": [\"uuid1\", \"uuid2\", ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"EntityReference\"` | - |\n| `value` | [`EntityReference`](EntityReference.md)[] | Entity reference(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"EntityReference\", \"value\": [{...}]} (length 0 or 1) Multi-select: {\"type\": \"EntityReference\", \"value\": [{...}, {...}, ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Link\"` | - |\n| `value` | `string`[] | Link value(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"Link\", \"value\": [\"https://example.com\"]} (length 0 or 1) Multi-select: {\"type\": \"Link\", \"value\": [\"https://example.com\", \"https://other.com\"]} (length 0+) |\n\n\n\n# Type Alias: SetPropertyValue\n\n> **SetPropertyValue** = \\{ `type`: `\"boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `option_id`: `string`; `type`: `\"select_option\"`; \\} \\| \\{ `option_ids`: `string`[]; `type`: `\"multi_select_option\"`; \\} \\| \\{ `reference`: [`EntityReference`](EntityReference.md); `type`: `\"entity_reference\"`; \\} \\| \\{ `references`: [`EntityReference`](EntityReference.md)[]; `type`: `\"multi_entity_reference\"`; \\} \\| \\{ `type`: `\"link\"`; `url`: `string`; \\} \\| \\{ `type`: `\"multi_link\"`; `urls`: `string`[]; \\}\n\nType-safe enum for setting entity property values - provides compile-time validation.\n\n\n\n# Type Alias: AgentSessionFilters\n\n> **AgentSessionFilters** = \\{ `ids?`: `string`[]; `include?`: `boolean`; `owners?`: `string`[]; \\}\n\nFilters for agent sessions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `ids?` | `string`[] | Agent session ids to filter by. Empty to include all accessible sessions. |\n| `include?` | `boolean` | Opt this query into agent sessions at all. Agent sessions are off by default — see [`crate::ast::agent_session::AgentSessionLiteral::Include`]. Asking for specific `ids` or `owners` also opts in. |\n| `owners?` | `string`[] | Filter by session owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Empty to include every owner. |\n\n\n\n# Type Alias: CalendarEventFilters\n\n> **CalendarEventFilters** = \\{ `attendees?`: `string`[]; `calendar_event_ids?`: `string`[]; `ends_after?`: `string` \\| `null`; `organizers?`: `string`[]; `starts_before?`: `string` \\| `null`; `statuses?`: `string`[]; \\}\n\nFilters for canonical calendar-event entities.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attendees?` | `string`[] | Attendee email addresses. |\n| `calendar_event_ids?` | `string`[] | Canonical event ids. |\n| `ends_after?` | `string` \\| `null` | Include master events ending after this instant. |\n| `organizers?` | `string`[] | Organizer email addresses. |\n| `starts_before?` | `string` \\| `null` | Include master events starting before this instant. |\n| `statuses?` | `string`[] | Event statuses such as `confirmed`, `tentative`, or `cancelled`. |\n\n\n\n# Type Alias: CallFilters\n\n> **CallFilters** = \\{ `attended?`: `boolean` \\| `null`; `call_ids?`: `string`[]; `channel_ids?`: `string`[]; `speaker_ids?`: `string`[]; `status?`: `null` \\| [`CallStatus`](CallStatus.md); \\}\n\nFilters for call records.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attended?` | `boolean` \\| `null` | Legacy filter by whether the requesting user attended the call. Prefer [`CallFilters::status`] for new callers. `None` = no filter, `Some(true)` = only calls the user joined, `Some(false)` = only calls the user did not join. |\n| `call_ids?` | `string`[] | Call record IDs to filter by. Empty to include all calls. |\n| `channel_ids?` | `string`[] | Channel IDs to filter calls by. Empty to include all calls. |\n| `speaker_ids?` | `string`[] | Speaker macro user ids. Empty to include all. |\n| `status?` | `null` \\| [`CallStatus`](CallStatus.md) | - |\n\n\n\n# Type Alias: CallStatus\n\n> **CallStatus** = `\"ATTENDED\"` \\| `\"MISSED\"` \\| `\"UNATTENDED\"`\n\nViewer-relative attendance status for a call record.\nSerializes as `ATTENDED`, `MISSED`, or `UNATTENDED`.\n\n\n\n# Type Alias: ChannelFilters\n\n> **ChannelFilters** = \\{ `channel_ids?`: `string`[]; `channel_types?`: `string`[]; `importance?`: `boolean` \\| `null`; `is_participant?`: `boolean` \\| `null`; `mentions?`: `string`[]; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `org_id?`: `number` \\| `null`; `sender_ids?`: `string`[]; `team_id?`: `string` \\| `null`; `thread_ids?`: `string`[]; \\}\n\nThe channel message filters used to filter down what channel messages you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_ids?` | `string`[] | Channel IDs to search within. Examples: ['general']. Empty to search all accessible channels. |\n| `channel_types?` | `string`[] | Channel types to filter by. Examples: ['public'], ['direct_message', 'private']. Empty to search all channel types. |\n| `importance?` | `boolean` \\| `null` | Filter by channel importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `is_participant?` | `boolean` \\| `null` | Filter by whether the requesting user is an active participant of the channel. Presence of this filter also widens the candidate set to team channels of the user's teams that they have not joined, so `false` matches those channels. None to ignore (participant channels only, today's default). |\n| `mentions?` | `string`[] | Channel user mentions to search for. Examples: ['@username']. Empty if not filtering by mentions. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by channel notification state. |\n| `org_id?` | `number` \\| `null` | Channel organization ID to search within. Empty to ignore organization filtering. |\n| `sender_ids?` | `string`[] | Sender IDs to search within. Examples: ['user1']. Empty to search all accessible senders. |\n| `team_id?` | `string` \\| `null` | Channel team ID to search within. Empty to ignore team filtering. |\n| `thread_ids?` | `string`[] | Channel thread IDs to search within. Examples: ['thread123']. Empty to search all threads. |\n\n\n\n# Type Alias: ChannelThreadFilters\n\n> **ChannelThreadFilters** = \\{ `channel_ids?`: `string`[]; `participant_ids?`: `string`[]; `root_sender_ids?`: `string`[]; `thread_ids?`: `string`[]; \\}\n\nThe channel thread filters used to filter down channel-thread entities.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_ids?` | `string`[] | Channel IDs containing the thread. Empty to include threads from all accessible channels. |\n| `participant_ids?` | `string`[] | Thread participant user IDs. A participant is the root message sender, anyone who replied in the thread, or anyone @-mentioned in the thread (group mentions like **Here** count through their per-user expansion at send time). Empty to include threads regardless of participants. |\n| `root_sender_ids?` | `string`[] | Sender IDs for the root thread message. Empty to include all root senders. |\n| `thread_ids?` | `string`[] | Channel thread parent message IDs to include. Empty to include all accessible threads. |\n\n\n\n# Type Alias: ChatFilters\n\n> **ChatFilters** = \\{ `chat_ids?`: `string`[]; `importance?`: `boolean` \\| `null`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; `role?`: `string`[]; \\}\n\nThe chat filters used to filter down what chats you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `chat_ids?` | `string`[] | Chat ids to search over. Examples: ['chat1'], ['chat1', 'chat2']. When provided, chat search will only match results on these chats. Empty to search all accessible chats. |\n| `importance?` | `boolean` \\| `null` | Filter by chat importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by chat notification state. |\n| `owners?` | `string`[] | Filter by chat owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Examples: ['project1']. Empty to ignore project filtering. |\n| `role?` | `string`[] | Chat message roles to search. Examples: ['user'], ['assistant']. Empty to search all roles. |\n\n\n\n# Type Alias: CrmCompanyFilters\n\n> **CrmCompanyFilters** = \\{ `company_ids?`: `string`[]; `hidden?`: `boolean` \\| `null`; \\}\n\nThe crm company filters used to narrow which CRM companies appear in soup.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `company_ids?` | `string`[] | CRM company ids to filter by. Examples: ['11111111-...']. Empty to include all of the team's visible CRM companies. |\n| `hidden?` | `boolean` \\| `null` | Optional `crm_companies.hidden` filter. `None` = visible only (default for back-compat with non-admin callers). `Some(false)` = visible only (explicit). `Some(true)` = hidden only — requires admin/owner team role; enforced by the CRM service from the caller's team receipt. |\n\n\n\n# Type Alias: DocumentFilters\n\n> **DocumentFilters** = \\{ `document_ids?`: `string`[]; `file_types?`: `string`[]; `importance?`: `boolean` \\| `null`; `is_email_attachment?`: `boolean` \\| `null`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; `sub_types?`: `string`[]; `task_filters?`: [`TaskFilters`](TaskFilters.md); \\}\n\nThe document filters used to filter down what documents you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `document_ids?` | `string`[] | Document ids to search over. Examples: ['doc1'], ['doc1', 'doc2']. Empty to search all accessible documents. |\n| `file_types?` | `string`[] | Document file types to search. Examples: ['pdf'], ['md', 'txt']. Empty to search all file types. |\n| `importance?` | `boolean` \\| `null` | Filter by document importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `is_email_attachment?` | `boolean` \\| `null` | Filter by email attachment status. true = only email attachments, false = only non-email attachments, None = both. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by document notification state. |\n| `owners?` | `string`[] | Filter by document owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Examples: ['project1']. filtering. Empty to ignore project filtering. |\n| `sub_types?` | `string`[] | Filter by document sub type. Examples: ['task']. Empty to search all sub types. |\n| `task_filters?` | [`TaskFilters`](TaskFilters.md) | Task-specific filters that only apply to task subtype documents. |\n\n\n\n# Type Alias: EmailFilters\n\n> **EmailFilters** = \\{ `bcc?`: `string`[]; `calendar_only?`: `boolean` \\| `null`; `cc?`: `string`[]; `crm_addresses?`: `string`[]; `crm_domains?`: `string`[]; `email_thread_ids?`: `string`[]; `exclude_labels?`: `string`[]; `importance?`: `boolean` \\| `null`; `include_labels?`: `string`[]; `is_read?`: `boolean` \\| `null`; `link_ids?`: `string`[]; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `project_ids?`: `string`[]; `recipients?`: `string`[]; `senders?`: `string`[]; `shared?`: [`SharedEmailFilter`](SharedEmailFilter.md); \\}\n\nThe email filters used to filter down what emails you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `bcc?` | `string`[] | Email BCC addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by BCC. |\n| `calendar_only?` | `boolean` \\| `null` | When `Some(true)`, only include threads that have at least one message with an iCalendar attachment (`.ics` filename or `application/ics` mime type). `Some(false)` and `None` apply no constraint. |\n| `cc?` | `string`[] | Email CC addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by CC. |\n| `crm_addresses?` | `string`[] | CRM-scoped address filter. When non-empty, expands visibility to every teammate's mailbox and restricts to threads involving any of these fully-qualified addresses. Each address is authorized against `crm_contacts` + `crm_companies` (contact must not be hidden, company must not be hidden, `email_sync` must be true). Mutually exclusive with `crm_domains`. |\n| `crm_domains?` | `string`[] | CRM-scoped domain filter. When non-empty, expands visibility to every teammate's mailbox and restricts to threads involving any of these domains (in any of sender/cc/bcc/recipient). Each domain is authorized against `crm_domains` + `crm_companies` (must exist for the caller's team, company must not be hidden, `email_sync` must be true). Mutually exclusive with `crm_addresses`. |\n| `email_thread_ids?` | `string`[] | Email thread IDs to filter by. Examples: ['thread-uuid-1']. Empty to search all threads. |\n| `exclude_labels?` | `string`[] | Exclude emails that have any of these labels. Supports both Gmail system labels (e.g. \"CATEGORY_PROMOTIONS\") and user-created labels. Empty to not exclude any labels. Note: SPAM and TRASH emails are not indexed in OpenSearch, so they are already excluded by default. |\n| `importance?` | `boolean` \\| `null` | Filter by email importance. None to not filter. True to show only important emails (drafts, personal, sent, or uncategorized). False to show only unimportant emails (those categorized as promotions, social, updates, or forums). |\n| `include_labels?` | `string`[] | Only include emails that have at least one of these labels. Supports both Gmail system labels (e.g. \"INBOX\", \"CATEGORY_PROMOTIONS\") and user-created labels (e.g. \"github\"). Empty to not filter by included labels. Note: SPAM and TRASH emails are not indexed in OpenSearch, so they will never appear in results regardless of this filter. |\n| `is_read?` | `boolean` \\| `null` | Filter by the email thread's read flag, independently of notification state. |\n| `link_ids?` | `string`[] | Restrict to specific inboxes by email_links.id. Empty means \"any inbox the caller can access\" (soup expands to the full set at the router edge). |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by email notification state. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Empty to ignore project filtering. |\n| `recipients?` | `string`[] | Email Recipient addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by Recipient. |\n| `senders?` | `string`[] | Email sender addresses to filter by. Examples: ['user@example.com']. Empty to search all senders. |\n| `shared?` | [`SharedEmailFilter`](SharedEmailFilter.md) | Controls whether shared email threads are included in results. Defaults to \"exclude\" (only the user's own threads). |\n\n\n\n# Type Alias: EntityFilters\n\n> **EntityFilters** = \\{ `agent_session_filters?`: [`AgentSessionFilters`](AgentSessionFilters.md); `calendar_event_filters?`: [`CalendarEventFilters`](CalendarEventFilters.md); `call_filters?`: [`CallFilters`](CallFilters.md); `channel_filters?`: [`ChannelFilters`](ChannelFilters.md); `channel_thread_filters?`: [`ChannelThreadFilters`](ChannelThreadFilters.md); `chat_filters?`: [`ChatFilters`](ChatFilters.md); `crm_company_filters?`: [`CrmCompanyFilters`](CrmCompanyFilters.md); `document_filters?`: [`DocumentFilters`](DocumentFilters.md); `email_filters?`: [`EmailFilters`](EmailFilters.md); `favorites_only?`: `boolean` \\| `null`; `foreign_entity_filters?`: [`ForeignEntityFilters`](ForeignEntityFilters.md); `initiative_filters?`: [`InitiativeFilters`](InitiativeFilters.md); `project_filters?`: [`ProjectFilters`](ProjectFilters.md); `property_filters?`: [`PropertyFilter`](PropertyFilter.md)[]; `tag_filter_mode?`: [`TagFilterMode`](TagFilterMode.md); `tag_option_ids?`: `string`[]; \\}\n\na bundle of all of the filters for each entity type\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `agent_session_filters?` | [`AgentSessionFilters`](AgentSessionFilters.md) | the bundled [AgentSessionFilters] |\n| `calendar_event_filters?` | [`CalendarEventFilters`](CalendarEventFilters.md) | the bundled [CalendarEventFilters] |\n| `call_filters?` | [`CallFilters`](CallFilters.md) | the bundled [CallFilters] |\n| `channel_filters?` | [`ChannelFilters`](ChannelFilters.md) | the bundled [ChannelFilters] |\n| `channel_thread_filters?` | [`ChannelThreadFilters`](ChannelThreadFilters.md) | the bundled [ChannelThreadFilters] |\n| `chat_filters?` | [`ChatFilters`](ChatFilters.md) | the bundled [ChatFilters] |\n| `crm_company_filters?` | [`CrmCompanyFilters`](CrmCompanyFilters.md) | the bundled [CrmCompanyFilters] |\n| `document_filters?` | [`DocumentFilters`](DocumentFilters.md) | the bundled [DocumentFilters] |\n| `email_filters?` | [`EmailFilters`](EmailFilters.md) | the bundled [EmailFilters] |\n| `favorites_only?` | `boolean` \\| `null` | Restrict results to the authenticated viewer's favorites when true. |\n| `foreign_entity_filters?` | [`ForeignEntityFilters`](ForeignEntityFilters.md) | the bundled [ForeignEntityFilters] |\n| `initiative_filters?` | [`InitiativeFilters`](InitiativeFilters.md) | Initiative filters. Initiatives are opt-in. |\n| `project_filters?` | [`ProjectFilters`](ProjectFilters.md) | the bundled [ProjectFilters] |\n| `property_filters?` | [`PropertyFilter`](PropertyFilter.md)[] | property-based filters applied across entity types |\n| `tag_filter_mode?` | [`TagFilterMode`](TagFilterMode.md) | How the `tag_option_ids` combine: `any` (default) matches entities holding at least one selected tag, `all` requires every selected tag. |\n| `tag_option_ids?` | `string`[] | tag option ids matched against `properties.values`, OR'd together across all tag definitions. Option ids are globally unique, so the match ignores the owning definition id (personal and team tags combine into one OR). |\n\n\n\n# Type Alias: ForeignEntityFilters\n\n> **ForeignEntityFilters** = \\{ `foreign_entity_ids?`: `string`[]; `foreign_entity_sources?`: `string`[]; `ids?`: `string`[]; `includes_me?`: `boolean`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); \\}\n\nFilters for foreign entity records.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `foreign_entity_ids?` | `string`[] | External entity identifiers to filter by. Empty to include all external IDs. |\n| `foreign_entity_sources?` | `string`[] | External source names to filter by. Empty to include all sources. |\n| `ids?` | `string`[] | Internal foreign entity record IDs to filter by. Empty to include all records. |\n| `includes_me?` | `boolean` | When true, only return foreign entities whose metadata lists the requesting user as a participant (GitHub `involves:me` semantics for `github_pull_request` records). False or absent applies no filter. Serialized in filter ASTs as the `\"me\"` literal. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by the notification state of the foreign entity (e.g. whether the requesting user's GitHub PR notification is done/seen). |\n\n\n\n# Type Alias: InitiativeFilters\n\n> **InitiativeFilters** = \\{ `due_after?`: `string` \\| `null`; `due_before?`: `string` \\| `null`; `include?`: `boolean`; `initiative_ids?`: `string`[]; `name?`: `string` \\| `null`; `owners?`: `string`[]; \\}\n\nFilters for initiatives.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `due_after?` | `string` \\| `null` | Inclusive lower due-date bound. |\n| `due_before?` | `string` \\| `null` | Inclusive upper due-date bound. |\n| `include?` | `boolean` | Opt this query into initiatives at all. Initiatives are off by default — see [`crate::ast::initiative::InitiativeLiteral::Include`]. Asking for specific `initiative_ids` or `owners` also opts in. |\n| `initiative_ids?` | `string`[] | Initiative ids to filter by. Empty to include all accessible initiatives. |\n| `name?` | `string` \\| `null` | Case-insensitive name substring. |\n| `owners?` | `string`[] | Filter by initiative owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Empty to include every owner. |\n\n\n\n# Type Alias: NotificationFilters\n\n> **NotificationFilters** = \\{ `states?`: [`NotificationState`](NotificationState.md)[]; \\}\n\nNotification-level filters that apply to an entity type.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `states?` | [`NotificationState`](NotificationState.md)[] | Include entities with a non-deleted notification in any of these exact states. Empty means no notification restriction. Active means `[unseen, seen]`. |\n\n\n\n# Type Alias: NotificationState\n\n> **NotificationState** = `\"unseen\"` \\| `\"seen\"` \\| `\"done\"`\n\nThe mutually exclusive lifecycle states of a user's notification.\n\n\n\n# Type Alias: ProjectFilters\n\n> **ProjectFilters** = \\{ `importance?`: `boolean` \\| `null`; `include_root?`: `boolean`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; \\}\n\nThe project filters used to filter down what projects you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `importance?` | `boolean` \\| `null` | Filter by project importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `include_root?` | `boolean` | When true, `project_ids` also matches the projects themselves in addition to their children. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by project notification state. |\n| `owners?` | `string`[] | Filter by project owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | Project IDs to search within. Examples: ['project1']. Empty to search all accessible projects. By default matches children of these projects; set `include_root` to also match the projects themselves. |\n\n\n\n# Type Alias: PropertyFilter\n\n> **PropertyFilter** = \\{ `entity_ids?`: `string`[]; `entity_type?`: `string` \\| `null`; `option_ids?`: `string`[]; `property_definition_id`: `string`; \\}\n\nA single property-based filter condition.\n\nEach filter targets a specific property definition on entities of a given type,\nmatching against select option UUIDs or entity reference IDs.\nMultiple values within a single filter are OR'd together.\nMultiple filters are AND'd together.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_ids?` | `string`[] | Entity reference IDs to match. Multiple values are OR'd together. |\n| `entity_type?` | `string` \\| `null` | The entity type for the property lookup (e.g., \"TASK\", \"DOCUMENT\", \"PROJECT\"). When None, matches across all entity types. |\n| `option_ids?` | `string`[] | Select option UUIDs to match. Multiple values are OR'd together. |\n| `property_definition_id` | `string` | The UUID of the property definition to filter on. |\n\n\n\n# Type Alias: SharedEmailFilter\n\n> **SharedEmailFilter** = `\"exclude\"` \\| `\"include\"` \\| `\"only\"`\n\nControls whether shared email threads are included in results.\n\n\n\n# Type Alias: TagFilterMode\n\n> **TagFilterMode** = `\"any\"` \\| `\"all\"`\n\nHow multiple `tag_option_ids` combine when filtering.\n\n\n\n# Type Alias: TaskFilters\n\n> **TaskFilters** = \\{ `include_cbm_atm_nc?`: `boolean` \\| `null`; \\}\n\nTask-only filters nested under document filters.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `include_cbm_atm_nc?` | `boolean` \\| `null` | Include tasks that are created by me, assigned to me, and not completed, even when they do not match other document filters. |\n\n\n\n# Type Alias: AccessLevel\n\n> **AccessLevel** = `\"view\"` \\| `\"comment\"` \\| `\"edit\"` \\| `\"owner\"`\n\nOrdered from least to most access top -> bottom\n\n\n\n# Type Alias: AccessRequest\n\n> **AccessRequest** = \\{ `createdAt`: `string`; `grantedLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `id`: `string`; `requestedLevel`: [`AccessLevel`](AccessLevel.md); `requesterId`: `string`; `resolvedAt?`: `string` \\| `null`; `retryAfter?`: `string` \\| `null`; `revision`: `number`; `status`: [`RequestStatus`](RequestStatus.md); `updatedAt`: `string`; \\}\n\nLatest request for one person and one entity.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `createdAt` | `string` | Start of this request attempt. |\n| `grantedLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `id` | `string` | Stable request identity across revisions. |\n| `requestedLevel` | [`AccessLevel`](AccessLevel.md) | Requested upgrade. |\n| `requesterId` | `string` | Person requesting access. |\n| `resolvedAt?` | `string` \\| `null` | When the request stopped being pending. |\n| `retryAfter?` | `string` \\| `null` | Earliest next submission or level change; cancellation preserves this deadline. Submissions wait one minute, denials wait 24 hours, and approval clears it. |\n| `revision` | `number` | Optimistic concurrency token. |\n| `status` | [`RequestStatus`](RequestStatus.md) | Current outcome. |\n| `updatedAt` | `string` | Most recent change. |\n\n\n\n# Type Alias: EntityPermission\n\n> **EntityPermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\} \\| \\{ `type`: `\"channel_view_only\"`; \\} \\| \\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\} \\| \\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\nA user's permission for an entity, discriminated by entity kind.\n\nItems (documents, chats, projects, threads) use access levels.\nChannels use view-only permission or participant roles.\n\n## Union Members\n\n### Type Literal\n\n\\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level the user has. |\n| `type` | `\"access_level\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"channel_view_only\"`; \\}\n\n***\n\n### Type Literal\n\n\\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`ParticipantRole`](ParticipantRole.md) | The role the user has in the channel. |\n| `type` | `\"channel_role\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`TeamRole`](TeamRole.md) | The role the user has in the team. |\n| `type` | `\"team_role\"` | - |\n\n\n\n# Type Alias: FavoriteEntityRef\n\n> **FavoriteEntityRef** = \\{ `entityId`: `string`; `entityType`: `\"user\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"project\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"team\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"`; \\}\n\nA reference to a favorited entity.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entityId` | `string` | The id of the favorited entity. |\n| `entityType` | `\"user\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"project\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"team\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | The type of the favorited entity. |\n\n\n\n# Type Alias: LinkShare\n\n> **LinkShare** = `\"PUBLIC\"` \\| `\"TEAM\"`\n\nDefines who can access an item through its share link.\n\n\n\n# Type Alias: MessageCursor\n\n> **MessageCursor** = \\{ `created_at`: `string`; `id`: `string`; \\}\n\nCursor for a chronological parent timeline.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Last message creation time or activity occurrence time. |\n| `id` | `string` | Last entry UUID, used to break timestamp ties across both sources. |\n\n\n\n# Type Alias: MessageDirection\n\n> **MessageDirection** = `\"older\"` \\| `\"newer\"`\n\nDirection through a parent timeline, retaining channel cursor semantics.\n\n\n\n# Type Alias: ParticipantRole\n\n> **ParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nThe role a user has within a channel.\n\n\n\n# Type Alias: RequestStatus\n\n> **RequestStatus** = `\"pending\"` \\| `\"granted\"` \\| `\"denied\"` \\| `\"cancelled\"`\n\nDurable outcome; reading a notification never changes it.\n\n\n\n# Type Alias: ResolveRequest\n\n> **ResolveRequest** = \\{ `grantedLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `revision`: `number`; \\}\n\nOwner's decision; omission of a granted level means deny.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `grantedLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `revision` | `number` | Request revision being reviewed. |\n\n\n\n# Type Alias: ShareEntityType\n\n> **ShareEntityType** = `\"document\"` \\| `\"chat\"` \\| `\"project\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"call\"` \\| `\"email_thread\"` \\| `\"agent_session\"` \\| `\"whatsapp_group\"`\n\nAn entity type with an existing Share surface.\n\n\n\n# Type Alias: SimpleMention\n\n> **SimpleMention** = \\{ `entity_id`: `string`; `entity_type`: `string`; \\}\n\nA mention tracked in a message body.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Mentioned entity identifier. |\n| `entity_type` | `string` | Mentioned entity type. |\n\n\n\n# Type Alias: TeamRole\n\n> **TeamRole** = `\"member\"` \\| `\"admin\"` \\| `\"owner\"`\n\nThe role a user has within a team.\n\nOrdered least to most privileged so comparisons reflect access strength.\n\n\n\n# Type Alias: ThreadAnchor\n\n> **ThreadAnchor** = \\{ `mark_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"markdown\"`; \\} \\| \\{ `anchor_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"pdf_highlight\"`; \\} \\| \\{ `anchor_id`: `string`; `type`: `\"pdf_placeable\"`; \\} \\| \\{ `range`: `string`; `sheetId`: `string`; `sheetName`: `string`; `type`: `\"spreadsheet\"`; \\} \\| \\{ `nodeId?`: `string` \\| `null`; `pageId`: `string`; `type`: `\"fig\"`; `x`: `number`; `y`: `number`; \\}\n\nA thread's location within its document. PDF geometry remains annotation-owned.\n\n## Union Members\n\n### Type Literal\n\n\\{ `mark_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"markdown\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `mark_id` | `string` | Mark UUID serialized in the document. |\n| `marked_text?` | `string` \\| `null` | The marked text as it read when the discussion was created, already trimmed and bounded. Absent on threads created or imported before snapshots were captured: the text a mark covers cannot be recovered from the mark id alone. |\n| `type` | `\"markdown\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `anchor_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"pdf_highlight\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `anchor_id` | `string` | Highlight annotation UUID. |\n| `marked_text?` | `string` \\| `null` | The text the highlight covers, trimmed and bounded like a markdown snapshot. The highlight owns it and it can be edited there, so it is read from the highlight whenever the thread is, never stored on the thread. Absent when the highlight carries no text. |\n| `type` | `\"pdf_highlight\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `anchor_id`: `string`; `type`: `\"pdf_placeable\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `anchor_id` | `string` | Placeable annotation UUID. |\n| `type` | `\"pdf_placeable\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `range`: `string`; `sheetId`: `string`; `sheetName`: `string`; `type`: `\"spreadsheet\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `range` | `string` | A1 cell or range, such as B4 or B4:C9. |\n| `sheetId` | `string` | Stable sheet identity within the workbook. |\n| `sheetName` | `string` | Sheet name when the discussion was created. |\n| `type` | `\"spreadsheet\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `nodeId?`: `string` \\| `null`; `pageId`: `string`; `type`: `\"fig\"`; `x`: `number`; `y`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `nodeId?` | `string` \\| `null` | Layer the pin follows; absent for a pin on the bare canvas. |\n| `pageId` | `string` | Page (canvas) the pin is on. |\n| `type` | `\"fig\"` | - |\n| `x` | `number` | Horizontal offset from the layer's origin, or the page's when the pin is on no layer, in design units. |\n| `y` | `number` | Vertical offset, measured like `x`. |\n\n\n\n# Type Alias: ThreadState\n\n> **ThreadState** = \\{ `anchor?`: `null` \\| [`ThreadAnchor`](ThreadAnchor.md); `created_at`: `string`; `deleted_at?`: `string` \\| `null`; `resolved`: `boolean`; `root_id`: `string`; `updated_at`: `string`; `user_id`: `string`; \\}\n\nState belonging to a whole thread, keyed by its root message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `anchor?` | `null` \\| [`ThreadAnchor`](ThreadAnchor.md) | - |\n| `created_at` | `string` | Creation time of the discussion. |\n| `deleted_at?` | `string` \\| `null` | Explicit deletion of the entire thread, distinct from root deletion. |\n| `resolved` | `boolean` | Whether this discussion has been resolved. |\n| `root_id` | `string` | Root message UUID; there is no separate thread identity. |\n| `updated_at` | `string` | Last state change. |\n| `user_id` | `string` | User who owns this discussion, including imported discussions. |\n\n\n\n# Type Alias: UpdateChannelSharePermission\n\n> **UpdateChannelSharePermission** = \\{ `accessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `channelId`: `string`; `operation`: [`UpdateOperation`](UpdateOperation.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `accessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `channelId` | `string` | The channel id |\n| `operation` | [`UpdateOperation`](UpdateOperation.md) | The type of operation to be performed on the chanel share permission You can add, remove or replace and existing permission |\n\n\n\n# Type Alias: UpdateOperation\n\n> **UpdateOperation** = `\"add\"` \\| `\"remove\"` \\| `\"replace\"`\n\n\n\n# Type Alias: UpdateSharePermissionRequestV2\n\n> **UpdateSharePermissionRequestV2** = \\{ `channelSharePermissions?`: [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null` | Any channel share permissions to be created/updated/removed |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: WebhookFilter\n\n> **WebhookFilter** = \\{ `events`: `string`[]; `ids?`: `string`[] \\| `null`; \\}\n\nEvent and optional entity-id constraints used to match webhook deliveries.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `events` | `string`[] | Event names matched by this filter. |\n| `ids?` | `string`[] \\| `null` | Entity ids matched by this filter. When absent, the filter matches all entity ids. |\n\n\n\n# Type Alias: WebhookScope\n\n> **WebhookScope** = `\"user\"` \\| `\"team\"`\n\nScope that owns a newly-created webhook.\n\nClients serialize this, so both derives are used. `Display`/`FromStr`\nspell the same names as serde, for query strings and config values.\n\n\n\n# Interface: MacroOpts\n\nOptions passed to `new Macro(opts)` and stored on `MacroClient`.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `auth?` | [`MacroAuth`](../type-aliases/MacroAuth.md) | How to authenticate. Takes precedence over `token`. Falls back to `MACRO_API_KEY` (a user API key or bearer token) or `MACRO_BOT_TOKEN` (bot). |\n| `env?` | [`Env`](../type-aliases/Env.md) | Which Macro environment to talk to. Falls back to the MACRO_ENV env var, then `'prod'`. |\n| `hosts?` | `Partial`\\<`Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\> | Override individual service hosts (e.g. point one at localhost). |\n| `onRequest?` | (`event`) => `void` | Optional generated API operation events; excludes arguments, URLs and response data. |\n| `requestedAs?` | `string` | User id the bot acts for, sent as `x-macro-bot-for-macro-user-id` on every request. Bot auth only. Set via `macro.requestedAs(user)` rather than directly. |\n| `token?` | [`TokenSource`](../type-aliases/TokenSource.md) | Shorthand for `auth: { type: 'user', token }`. Accepts a Settings API key (`mak_…`) or a bearer token. |\n| `webAppUrl?` | `string` | Override the web app base URL (e.g. for local frontend dev). Also reads MACRO_WEB_URL. |\n| `webhookSecret?` | `string` | Signing secret for verifying incoming persisted-webhook deliveries. Required only for `macro.events.webhook()` / `macro.events.handle()`. SSE via `macro.events.listen()` uses the API token and does not need this. Falls back to MACRO_WEBHOOK_SECRET. |\n| `wsVerify?` | `string` | - |\n\n\n\n# Type Alias: BotScope\n\n> **BotScope** = `\"user\"` \\| `\"team\"`\n\nAccess scope for bot-authenticated requests. `user` acts with the\nrequested-as user's access (requires `requestedAs`); `team` acts with the\nbot's owning team's access (team-owned bots only).\n\n\n\n# Type Alias: Env\n\n> **Env** = `\"dev\"` \\| `\"prod\"` \\| `\"local\"`\n\n\n\n# Type Alias: MacroAuth\n\n> **MacroAuth** = \\{ `apiKey?`: `never`; `token`: [`TokenSource`](TokenSource.md); `type`: `\"user\"`; \\} \\| \\{ `apiKey`: `string`; `token?`: `never`; `type`: `\"user\"`; \\} \\| \\{ `scope?`: [`BotScope`](BotScope.md); `token`: [`TokenSource`](TokenSource.md); `type`: `\"bot\"`; \\}\n\nHow the SDK authenticates with Macro.\n\nA user has exactly one of two credential fields.\n\n- `token`: a bearer token, or a `mak_` API key. The SDK picks the header\n from the prefix at send time.\n- `apiKey`: a Settings → API Keys key, always sent as\n `x-macro-user-api-key`. Not prefix-checked, so keys that predate the\n `mak_` prefix work here.\n\nA bot uses an `mbot_` token as `x-macro-bot-token` plus\n`x-macro-bot-scope`, defaulting to `user` when `requestedAs` is set and\n`team` otherwise.\n\n\n\n# Type Alias: ServiceName\n\n> **ServiceName** = `\"agent-harness\"` \\| `\"storage\"` \\| `\"auth\"` \\| `\"email\"` \\| `\"calendar\"` \\| `\"cognition\"` \\| `\"notification\"` \\| `\"properties\"` \\| `\"search\"` \\| `\"scheduled-action\"` \\| `\"static-files\"` \\| `\"connection\"` \\| `\"contacts\"` \\| `\"unfurl\"`\n\nThe backend services the SDK talks to. Note `search` and `properties` are\nserved on the storage host, so they point there.\n\n\n\n# Type Alias: TokenSource\n\n> **TokenSource** = `string` \\| (() => `string` \\| `Promise`\\<`string`\\>)\n\nA credential string, or a (possibly async) function that returns one.\n\n\n\n# Variable: HOSTS\n\n> `const` **HOSTS**: `Record`\\<[`Env`](../type-aliases/Env.md), `Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\>\n\n\n\n# Variable: WEB\\_APP\\_URLS\n\n> `const` **WEB\\_APP\\_URLS**: `Record`\\<[`Env`](../type-aliases/Env.md), `string`\\>\n\n\n\n# Abstract Class: FavoritableEntity\\\n\nAn entity the favorites API can address, and so can be (un)favorited.\n\n## Extends\n\n- [`MacroEntity`](MacroEntity.md)\\<`Detail`\\>\n\n## Extended by\n\n- [`CallRecord`](../../calls/call-record/classes/CallRecord.md)\n- [`Message`](../../channels/message/classes/Message.md)\n- [`Contact`](../../crm/contact/classes/Contact.md)\n- [`PropertiedEntity`](PropertiedEntity.md)\n- [`ForeignEntity`](../../foreign/foreign-entity/classes/ForeignEntity.md)\n- [`WhatsAppGroup`](../../whatsapp/group/classes/WhatsAppGroup.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Implements\n\n- [`Favoritable`](../interfaces/Favoritable.md)\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `abstract readonly` | `\"project\"` \\| `\"user\"` \\| `\"team\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | How the entity-addressed APIs (favorites) identify this entity's type. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](MacroEntity.md).[`id`](MacroEntity.md#property-id) |\n\n## Methods\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Favoritable`](../interfaces/Favoritable.md).[`favorite`](../interfaces/Favoritable.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](MacroEntity.md).[`toJSON`](MacroEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Favoritable`](../interfaces/Favoritable.md).[`unfavorite`](../interfaces/Favoritable.md#unfavorite)\n\n\n\n# Abstract Class: MacroEntity\\\n\nBase for entity handles: a free-to-construct `(client, id)` pair whose\ndetail record loads lazily on first field access and is dropped after any\nmutation. Subclasses implement fetch and build their surface from\nfield and mutate.\n\n## Extended by\n\n- [`AgentSession`](../../agent-sessions/agent-session/classes/AgentSession.md)\n- [`CodeExecution`](../../agent-sessions/code-execution/classes/CodeExecution.md)\n- [`SessionReview`](../../agent-sessions/review/classes/SessionReview.md)\n- [`Agent`](../../agents/agent/classes/Agent.md)\n- [`UserApiKey`](../../api-keys/api-key/classes/UserApiKey.md)\n- [`Calendar`](../../calendar/calendar/classes/Calendar.md)\n- [`CalendarEvent`](../../calendar/event/classes/CalendarEvent.md)\n- [`CalendarNote`](../../calendar/note/classes/CalendarNote.md)\n- [`CallMessage`](../../calls/message/classes/CallMessage.md)\n- [`ChatMessage`](../../chats/generation/classes/ChatMessage.md)\n- [`CrmComment`](../../crm/comment/classes/CrmComment.md)\n- [`CrmPipeline`](../../crm/pipeline/classes/CrmPipeline.md)\n- [`PipelineTable`](../../crm/pipeline/classes/PipelineTable.md)\n- [`PipelineRow`](../../crm/pipeline/classes/PipelineRow.md)\n- [`PipelineColumn`](../../crm/pipeline/classes/PipelineColumn.md)\n- [`Database`](../../databases/database/classes/Database.md)\n- [`DocumentAnchor`](../../documents/anchor/classes/DocumentAnchor.md)\n- [`Comment`](../../documents/comment/classes/Comment.md)\n- [`EmailAttachment`](../../email/attachment/classes/EmailAttachment.md)\n- [`EmailFilter`](../../email/filter/classes/EmailFilter.md)\n- [`Label`](../../email/label/classes/Label.md)\n- [`Link`](../../email/link/classes/Link.md)\n- [`EmailMessage`](../../email/message/classes/EmailMessage.md)\n- [`FavoritableEntity`](FavoritableEntity.md)\n- [`Form`](../../forms/form/classes/Form.md)\n- [`GithubPullRequest`](../../github-pull-requests/pull-request/classes/GithubPullRequest.md)\n- [`Harness`](../../harnesses/harness/classes/Harness.md)\n- [`HarnessPairing`](../../harnesses/pairing/classes/HarnessPairing.md)\n- [`Initiative`](../../initiatives/initiative/classes/Initiative.md)\n- [`Meeting`](../../meetings/meeting/classes/Meeting.md)\n- [`MessageThread`](../../messages/thread/classes/MessageThread.md)\n- [`Notification`](../../notifications/notification/classes/Notification.md)\n- [`Routine`](../../routines/routine/classes/Routine.md)\n- [`AccessRequest`](../../sharing/access/classes/AccessRequest.md)\n- [`Team`](../../teams/team/classes/Team.md)\n- [`Webhook`](../../webhooks/webhook/classes/Webhook.md)\n- [`WhatsAppAccount`](../../whatsapp/account/classes/WhatsAppAccount.md)\n- [`WhatsAppMessage`](../../whatsapp/message/classes/WhatsAppMessage.md)\n- [`WhatsAppRemoteGroup`](../../whatsapp/remote-group/classes/WhatsAppRemoteGroup.md)\n- [`WhatsAppSend`](../../whatsapp/send/classes/WhatsAppSend.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `id` | `public readonly` | `string` |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n\n\n# Abstract Class: PropertiedEntity\\\n\nA favoritable entity that also carries user-defined properties.\n\n## Extends\n\n- [`FavoritableEntity`](FavoritableEntity.md)\\<`Detail`\\>\n\n## Extended by\n\n- [`Channel`](../../channels/channel/classes/Channel.md)\n- [`Chat`](../../chats/chat/classes/Chat.md)\n- [`Company`](../../crm/company/classes/Company.md)\n- [`Document`](../../documents/document/classes/Document.md)\n- [`EmailThread`](../../email/thread/classes/EmailThread.md)\n- [`Project`](../../projects/project/classes/Project.md)\n- [`User`](../../users/user/classes/User.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Implements\n\n- [`Propertied`](../interfaces/Propertied.md)\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `abstract readonly` | `\"project\"` \\| `\"user\"` \\| `\"team\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | How the entity-addressed APIs (favorites) identify this entity's type. | [`FavoritableEntity`](FavoritableEntity.md).[`entityType`](FavoritableEntity.md#property-entitytype) |\n| `id` | `public readonly` | `string` | - | [`FavoritableEntity`](FavoritableEntity.md).[`id`](FavoritableEntity.md#property-id) |\n\n## Methods\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\nRemove a property from this entity, given its [properties](#properties) entry.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`deleteProperty`](../interfaces/Propertied.md#deleteproperty)\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`favorite`](../interfaces/Propertied.md#favorite)\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`favorite`](FavoritableEntity.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`permission`](FavoritableEntity.md#permission)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\nThe properties set on this entity, each with its definition, value, and options.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`properties`](../interfaces/Propertied.md#properties)\n\n***\n\n### propertyReference()\n\n> **propertyReference**(): [`PropertyTargetReference`](../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\nThis entity's reference for bulk property operations.\n\n#### Returns\n\n[`PropertyTargetReference`](../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\nSet a property value on this entity, or attach the property without a\nvalue when `value` is omitted.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`setProperty`](../interfaces/Propertied.md#setproperty)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`toJSON`](FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`unfavorite`](../interfaces/Propertied.md#unfavorite)\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`unfavorite`](FavoritableEntity.md#unfavorite)\n\n***\n\n### updatePropertyOptions()\n\n> **updatePropertyOptions**(`changes`): `Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\nApply multi-select option deltas atomically across this entity's properties.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `changes` | [`PropertyOptionDelta`](../interfaces/PropertyOptionDelta.md)[] |\n\n#### Returns\n\n`Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\n\n\n# Interface: Favoritable\n\nAn entity that can be added to and removed from the user's favorites.\n\n## Extended by\n\n- [`Propertied`](Propertied.md)\n\n## Methods\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Favoritable`\\>\n\n#### Returns\n\n`Promise`\\<`Favoritable`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Favoritable`\\>\n\n#### Returns\n\n`Promise`\\<`Favoritable`\\>\n\n\n\n# Interface: Propertied\n\nA favoritable entity that also carries user-defined properties.\n\n## Extends\n\n- [`Favoritable`](Favoritable.md)\n\n## Methods\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Propertied`\\>\n\n#### Returns\n\n`Promise`\\<`Propertied`\\>\n\n#### Inherited from\n\n[`Favoritable`](Favoritable.md).[`favorite`](Favoritable.md#favorite)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Propertied`\\>\n\n#### Returns\n\n`Promise`\\<`Propertied`\\>\n\n#### Inherited from\n\n[`Favoritable`](Favoritable.md).[`unfavorite`](Favoritable.md#unfavorite)\n\n\n\n# Interface: PropertyOptionDelta\n\nA delta to apply to one multi-select property.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `add?` | [`PropertyOption`](../../properties/property-option/classes/PropertyOption.md)[] | Options to add to the property's current selection. |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) | The multi-select property definition to update. |\n| `remove?` | [`PropertyOption`](../../properties/property-option/classes/PropertyOption.md)[] | Options to remove from the property's current selection. |\n\n\n\n# Type Alias: MacroEntityType\n\n> **MacroEntityType** = [`FavoriteEntityRef`](../../../../generated/storage/types.gen/type-aliases/FavoriteEntityRef.md)\\[`\"entityType\"`\\]\n\nHow the entity-addressed APIs (favorites) identify an entity's type.\n\n\n\n# Class: MessageThread\n\nA shared message thread with resolution and deletion operations.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `parent` | `readonly` | [`MessageParent`](../type-aliases/MessageParent.md) | The entity containing this thread. | - |\n| `resolved` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether the thread is resolved. | - |\n\n## Methods\n\n### delete()\n\n> **delete**(`nonce?`): `Promise`\\<`void`\\>\n\nDelete the entire thread, including replies.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `nonce?` | `string` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md); `id`: `string`; `parentId`: `string`; `parentType`: `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"`; \\}\n\nSerialize identity with its owning resource.\n\n#### Returns\n\n\\{ `detail?`: [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md); `id`: `string`; `parentId`: `string`; `parentType`: `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md) |\n| `id` | `string` |\n| `parentId` | `string` |\n| `parentType` | `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` |\n\n#### Overrides\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### update()\n\n> **update**(`options`): `Promise`\\<`void`\\>\n\nResolve the thread or detach its annotation anchor.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options` | \\{ `detachAnchor?`: `boolean`; `nonce?`: `string`; `resolved?`: `boolean`; \\} |\n| `options.detachAnchor?` | `boolean` |\n| `options.nonce?` | `string` |\n| `options.resolved?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `parent`, `id`): `MessageThread`\n\nConstruct a scoped thread handle.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `parent` | [`MessageParent`](../type-aliases/MessageParent.md) |\n| `id` | `string` |\n\n#### Returns\n\n`MessageThread`\n\n\n\n# Function: timeline()\n\n> **timeline**\\<`TMessage`\\>(`client`, `parent`, `map`, `selection?`): `Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: `TMessage`; `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\nA bounded mixed message/activity page with typed message handles.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `TMessage` *extends* [`TimelineMessage`](../type-aliases/TimelineMessage.md) |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `parent` | [`MessageParent`](../type-aliases/MessageParent.md) |\n| `map` | (`record`) => `TMessage` |\n| `selection?` | [`TimelineOptions`](../interfaces/TimelineOptions.md)\\<`TMessage`\\> |\n\n## Returns\n\n`Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: `TMessage`; `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\n\n\n# Interface: TimelineOptions\\\n\nTimeline selection with typed message references and camel case options.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `TMessage` *extends* [`TimelineMessage`](../type-aliases/TimelineMessage.md) | [`TimelineMessage`](../type-aliases/TimelineMessage.md) |\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `activityAfter?` | `string` | Inclusive activity lower bound. |\n| `activityBefore?` | `string` | Exclusive activity upper bound. |\n| `anchored?` | `boolean` | Select anchored threads. |\n| `around?` | `TMessage` | Fetch around this message. |\n| `cursor?` | [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `null` | Opaque continuation cursor from a previous page. |\n| `direction?` | [`MessageDirection`](../../../../../generated/storage/types.gen/type-aliases/MessageDirection.md) | Page direction. |\n| `includeDeletedThreads?` | `boolean` | Include deleted threads. |\n| `limit?` | `number` | Page size. |\n| `messages?` | `TMessage`[] | Restrict selection to these messages. |\n\n\n\n# Type Alias: MessageParent\n\n> **MessageParent** = \\{ `entity`: [`Channel`](../../../channels/channel/classes/Channel.md); `type`: `\"channel\"`; \\} \\| \\{ `entity`: [`Document`](../../../documents/document/classes/Document.md); `type`: `\"document\"`; \\} \\| \\{ `entity`: [`Company`](../../../crm/company/classes/Company.md); `type`: `\"crm_company\"`; \\} \\| \\{ `entity`: [`Contact`](../../../crm/contact/classes/Contact.md); `type`: `\"crm_contact\"`; \\} \\| \\{ `entity`: [`CallRecord`](../../../calls/call-record/classes/CallRecord.md); `type`: `\"call\"`; \\}\n\nThe typed parent of a shared message thread.\n\n\n\n# Type Alias: TimelineMessage\n\n> **TimelineMessage** = [`Message`](../../../channels/message/classes/Message.md) \\| [`Comment`](../../../documents/comment/classes/Comment.md) \\| [`CrmComment`](../../../crm/comment/classes/CrmComment.md) \\| [`CallMessage`](../../../calls/message/classes/CallMessage.md)\n\nA message handle accepted by a mixed timeline selector.\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity`: [`User`](../../users/user/classes/User.md); `type`: `\"user\"`; \\} \\| \\{ `entity`: [`Team`](../../teams/team/classes/Team.md); `type`: `\"team\"`; \\} \\| \\{ `entity`: [`Document`](../../documents/document/classes/Document.md); `type`: `\"document\"`; \\} \\| \\{ `entity`: [`Chat`](../../chats/chat/classes/Chat.md); `type`: `\"chat\"`; \\} \\| \\{ `entity`: [`Channel`](../../channels/channel/classes/Channel.md); `type`: `\"channel\"`; \\} \\| \\{ `entity`: [`Message`](../../channels/message/classes/Message.md); `type`: `\"channel_message\"`; \\} \\| \\{ `entity`: [`Project`](../../projects/project/classes/Project.md); `type`: `\"project\"`; \\} \\| \\{ `entity`: [`EmailThread`](../../email/thread/classes/EmailThread.md); `type`: `\"email_thread\"`; \\} \\| \\{ `entity`: [`CalendarEvent`](../../calendar/event/classes/CalendarEvent.md); `type`: `\"calendar_event\"`; \\} \\| \\{ `entity`: [`CallRecord`](../../calls/call-record/classes/CallRecord.md); `type`: `\"call\"`; \\} \\| \\{ `entity`: [`ForeignEntity`](../../foreign/foreign-entity/classes/ForeignEntity.md); `type`: `\"foreign_entity\"`; \\} \\| \\{ `entity`: [`Company`](../../crm/company/classes/Company.md); `type`: `\"crm_company\"`; \\} \\| \\{ `entity`: [`Contact`](../../crm/contact/classes/Contact.md); `type`: `\"crm_contact\"`; \\} \\| \\{ `entity`: [`CrmPipeline`](../../crm/pipeline/classes/CrmPipeline.md); `type`: `\"crm_pipeline\"`; \\} \\| \\{ `entity`: [`AgentSession`](../../agent-sessions/agent-session/classes/AgentSession.md); `type`: `\"agent_session\"`; \\} \\| \\{ `entity`: [`Routine`](../../routines/routine/classes/Routine.md); `type`: `\"scheduled_action\"`; \\} \\| \\{ `entity`: [`Initiative`](../../initiatives/initiative/classes/Initiative.md); `type`: `\"initiative\"`; \\} \\| \\{ `entity`: [`Database`](../../databases/database/classes/Database.md); `type`: `\"database\"`; \\} \\| \\{ `entity`: [`DatabaseRow`](../../databases/row/classes/DatabaseRow.md); `type`: `\"database_row\"`; \\} \\| \\{ `entity`: [`Form`](../../forms/form/classes/Form.md); `type`: `\"form\"`; \\}\n\nTyped entity references accepted by cross-resource APIs.\n\n\n\n# Function: entitySearch()\n\n> **entitySearch**\\<`T`, `K`\\>(`opts`): (`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`T`\\>\n\nBuild a `search(client, query, opts?)` function for one entity type: unified\nsearch hits narrowed to `type`, each mapped through `make`.\nMost relevant first, auto-paginated.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `T` |\n| `K` *extends* `\"email\"` \\| `\"project\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"company\"` \\| `\"calendarEvent\"` \\| `\"agentSession\"` \\| `\"channelMessage\"` |\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `filters?`: [`EntityFilters`](../../../../generated/search/types.gen/type-aliases/EntityFilters.md); `includeCrm?`: `boolean`; `make`: (`client`, `hit`) => `T`; `type`: `K`; \\} | - |\n| `opts.filters?` | [`EntityFilters`](../../../../generated/search/types.gen/type-aliases/EntityFilters.md) | - |\n| `opts.includeCrm?` | `boolean` | Opt in to CRM results (off by default server-side; required for company hits). |\n| `opts.make` | (`client`, `hit`) => `T` | - |\n| `opts.type` | `K` | - |\n\n## Returns\n\n(`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`T`\\>\n\n\n\n# Interface: SearchOpts\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `pageSize?` | `number` |\n| `searchOn?` | [`SearchOn`](../type-aliases/SearchOn.md) |\n\n\n\n# Type Alias: SearchOn\n\n> **SearchOn** = `\"name\"` \\| `\"content\"` \\| `\"name_content\"`\n\n\n\n# Class: AccessRequest\n\nOne access request; resolutions preserve optimistic concurrency.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `access` | `readonly` | [`EntityAccess`](EntityAccess.md) | Entity access surface owning the request. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `requestedLevel` | `readonly` | () => `Promise`\\<[`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)\\> | Requested access. | - |\n| `requester` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | Requesting user. | - |\n| `revision` | `readonly` | () => `Promise`\\<`number`\\> | Request revision. | - |\n| `status` | `readonly` | () => `Promise`\\<[`RequestStatus`](../../../../../generated/storage/types.gen/type-aliases/RequestStatus.md)\\> | Current request state. | - |\n\n## Methods\n\n### resolve()\n\n> **resolve**(`grantedLevel?`): `Promise`\\<`void`\\>\n\nApprove with an access level, or decline by omitting it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `grantedLevel?` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### from()\n\n> `static` **from**(`client`, `access`, `record`): `AccessRequest`\n\nSeed a request from a state or submission response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `access` | [`EntityAccess`](EntityAccess.md) |\n| `record` | [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md) |\n\n#### Returns\n\n`AccessRequest`\n\n\n\n# Class: EntityAccess\n\nAccess requests and direct grants scoped to a shareable entity.\n\n## Constructors\n\n### Constructor\n\n> **new EntityAccess**(`client`, `entityType`, `entity`): `EntityAccess`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `entityType` | [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md) |\n| `entity` | \\{ `id`: `string`; \\} |\n| `entity.id` | `string` |\n\n#### Returns\n\n`EntityAccess`\n\n## Methods\n\n### cancel()\n\n> **cancel**(`revision`): `Promise`\\<`void`\\>\n\nCancel the caller's own request at its observed revision.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `revision` | `number` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### direct()\n\n> **direct**(): `Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `user`: [`User`](../../../users/user/classes/User.md); \\}[]\\>\n\nDirect grants expressed as user handles.\n\n#### Returns\n\n`Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `user`: [`User`](../../../users/user/classes/User.md); \\}[]\\>\n\n***\n\n### grant()\n\n> **grant**(`user`, `accessLevel?`): `Promise`\\<`void`\\>\n\nGrant direct access, or remove it by omitting the access level.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../../users/user/classes/User.md) |\n| `accessLevel?` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### remove()\n\n> **remove**(`user`): `Promise`\\<`void`\\>\n\nRemove one user's direct grant.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### resolve()\n\n> **resolve**(`request`, `resolution`): `Promise`\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\nResolve a request belonging to this entity at an observed revision.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `request` | [`AccessRequest`](AccessRequest.md) |\n| `resolution` | [`ResolveRequest`](../../../../../generated/storage/types.gen/type-aliases/ResolveRequest.md) |\n\n#### Returns\n\n`Promise`\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\n***\n\n### state()\n\n> **state**(`offset?`): `Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) \\| `undefined`; `canReview`: `boolean`; `mine`: [`AccessRequest`](AccessRequest.md) \\| `undefined`; `nextOffset`: `number` \\| `undefined`; `owner`: [`User`](../../../users/user/classes/User.md) \\| `undefined`; `pendingCount`: `number`; `requests`: [`AccessRequest`](AccessRequest.md)[]; `supportedLevels`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)[]; \\}\\>\n\nA page of access requests, including the caller's own request and review rights.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `offset?` | `number` |\n\n#### Returns\n\n`Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) \\| `undefined`; `canReview`: `boolean`; `mine`: [`AccessRequest`](AccessRequest.md) \\| `undefined`; `nextOffset`: `number` \\| `undefined`; `owner`: [`User`](../../../users/user/classes/User.md) \\| `undefined`; `pendingCount`: `number`; `requests`: [`AccessRequest`](AccessRequest.md)[]; `supportedLevels`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)[]; \\}\\>\n\n***\n\n### submit()\n\n> **submit**(`requestedLevel`, `revision?`): `Promise`\\<[`AccessRequest`](AccessRequest.md)\\>\n\nRequest access, optionally naming the revision of an earlier request.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `requestedLevel` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n| `revision?` | `number` |\n\n#### Returns\n\n`Promise`\\<[`AccessRequest`](AccessRequest.md)\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `entity_id`: `string`; `entity_type`: [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md); \\}\n\nSerialize the entity reference without credentials.\n\n#### Returns\n\n\\{ `entity_id`: `string`; `entity_type`: [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md); \\}\n\n| Name | Type |\n| ------ | ------ |\n| `entity_id` | `string` |\n| `entity_type` | [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md) |\n\n\n\n# Function: sharePermissionBody()\n\n> **sharePermissionBody**(`options`): [`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md)\n\nConvert sharing options into the generated backend contract.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options` | [`SharePermissionOptions`](../type-aliases/SharePermissionOptions.md) |\n\n## Returns\n\n[`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md)\n\n\n\n# Type Alias: SharePermissionOptions\n\n> **SharePermissionOptions** = `Omit`\\<[`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md), `\"channelSharePermissions\"`\\> & \\{ `channelSharePermissions?`: \\{ `accessLevel?`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `channel`: [`Channel`](../../../channels/channel/classes/Channel.md); `operation`: [`UpdateChannelSharePermission`](../../../../../generated/storage/types.gen/type-aliases/UpdateChannelSharePermission.md)\\[`\"operation\"`\\]; \\}[] \\| `null`; \\}\n\nSharing updates reference channels by handle. Null clears the corresponding grant collection.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | \\{ `accessLevel?`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `channel`: [`Channel`](../../../channels/channel/classes/Channel.md); `operation`: [`UpdateChannelSharePermission`](../../../../../generated/storage/types.gen/type-aliases/UpdateChannelSharePermission.md)\\[`\"operation\"`\\]; \\}[] \\| `null` | Channel grants to create or replace. |\n\n\n\n# Class: MacroEvents\n\nPer-instance event receiver. Subscribe with [MacroEvents.on](#on), then\neither [MacroEvents.listen](#listen) (SSE, the default) or mount\n[MacroEvents.webhook](#webhook) at a persisted webhook URL.\n\nObtain via `macro.events` — do not construct directly.\n\n## Constructors\n\n### Constructor\n\n> **new MacroEvents**(`client`, `secret?`): `MacroEvents`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `secret?` | `string` |\n\n#### Returns\n\n`MacroEvents`\n\n## Methods\n\n### handle()\n\n> **handle**(`rawBody`, `headers`): `Promise`\\<`void`\\>\n\nFeed a raw webhook delivery in: verifies the signature, parses, and\ndispatches to matching handlers.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `rawBody` | `string` |\n| `headers` | `DeliveryHeaders` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Throws\n\nif no signing secret was configured, or if the\n signature is missing or invalid.\n\n***\n\n### listen()\n\n> **listen**(`opts?`): `Promise`\\<() => `void`\\>\n\nOpen a live Server-Sent Events stream of matching broker events. This is\nthe default way to receive events — no public URL or signing secret\nrequired. Delivery is best-effort: events published before the\nconnection, while disconnected, or dropped for a slow subscriber are\nmissed; there is no replay.\n\nFilters default to the event names currently registered with [on](#on).\nThe stream uses those filters for its lifetime; later `.on` / unsubscribe\ncalls do not change what the server sends.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | [`ListenOptions`](../interfaces/ListenOptions.md) |\n\n#### Returns\n\n`Promise`\\<() => `void`\\>\n\nA function that closes the stream.\n\n***\n\n### on()\n\n> **on**\\<`E`\\>(`event`, `handler`): () => `void`\n\nSubscribe to an event across all entities.\n\n#### Type Parameters\n\n| Type Parameter |\n| ------ |\n| `E` *extends* `\"agent_session.opened\"` \\| `\"agent_session.turn_started\"` \\| `\"agent_session.turn_ended\"` \\| `\"agent_session.command_rejected\"` \\| `\"agent_session.settled\"` \\| `\"agent_session.waiting_for_input\"` \\| `\"agent_session.input_received\"` \\| `\"agent_session.mentioned\"` \\| `\"agent_session.stopped\"` \\| `\"agent_session.renamed\"` \\| `\"agent_session.deleted\"` \\| `\"channel.picture_changed\"` \\| `\"channel.created\"` \\| `\"channel.updated\"` \\| `\"channel.deleted\"` \\| `\"channel.participant_added\"` \\| `\"channel.participant_removed\"` \\| `\"document.created\"` \\| `\"document.updated\"` \\| `\"document.deleted\"` \\| `\"document.content_uploaded\"` \\| `\"document.sync_content_updated\"` \\| `\"document.purged\"` \\| `\"document.copied\"` \\| `\"document.interaction\"` \\| `\"message.posted\"` \\| `\"message.patched\"` \\| `\"message.deleted\"` \\| `\"message.mentioned\"` \\| `\"message.attachment_created\"` \\| `\"message.attachment_removed\"` |\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `event` | `E` |\n| `handler` | `EventHandler`\\<`E`\\> |\n\n#### Returns\n\nAn unsubscribe function.\n\n() => `void`\n\n***\n\n### onSelfMention()\n\n> **onSelfMention**(`handler`): () => `void`\n\nSubscribe to @-mentions of the authenticated caller: `message.mentioned`\ndeliveries whose mentioned entity is this bot (bot auth) or this user\n(user auth), in channels and in document comments alike.\n\n`message.mentioned` deliveries cover every mention the stream's (or\nwebhook's) workspace can access (its `ids` filter holds channel or\ndocument ids); picking out \"me\" happens here, client-side. The caller's\nidentity is resolved lazily (once) on the first delivery.\n\nFor SSE, register this handler before [listen](#listen) so the derived\nfilters include `message.mentioned`. For persisted webhooks, register the\nwebhook separately, e.g. `macro.webhooks.create({ filters: [{ events:\n['message.mentioned'] }], … })`.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `handler` | `EventHandler`\\<`\"message.mentioned\"`\\> |\n\n#### Returns\n\nAn unsubscribe function.\n\n() => `void`\n\n***\n\n### webhook()\n\n> **webhook**(): (`req`) => `Promise`\\<`Response`\\>\n\nA Fetch-style handler to mount at your persisted webhook route.\n\nRequires `webhookSecret` (or `MACRO_WEBHOOK_SECRET`).\n\n#### Returns\n\n(`req`) => `Promise`\\<`Response`\\>\n\n#### Example\n\n```ts\napp.post('/webhook', macro.events.webhook()); // Hono\n```\n\n\n\n# Interface: ListenOptions\n\nOptions for [MacroEvents.listen](../classes/MacroEvents.md#listen).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `filters?` | [`WebhookFilter`](../../../../generated/storage/types.gen/type-aliases/WebhookFilter.md)[] | Event/entity-id filters, identical to persisted webhook `filters`. Defaults to one filter covering every event currently registered with [MacroEvents.on](../classes/MacroEvents.md#on). |\n| `scope?` | [`WebhookScope`](../../../../generated/storage/types.gen/type-aliases/WebhookScope.md) | Personal or team workspace whose webhook lifecycle events are delivered. Defaults to `'user'`. |\n| `signal?` | `AbortSignal` | Abort the stream. |\n\n\n\n# Class: Macro\\\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` *extends* [`MacroOpts`](../../config/interfaces/MacroOpts.md) | [`MacroOpts`](../../config/interfaces/MacroOpts.md) |\n\n## Constructors\n\n### Constructor\n\n> **new Macro**\\<`T`\\>(`opts`): `Macro`\\<`T`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts` | `T` |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `_client` | `readonly` | `MacroClient` | Direct access to the underlying hey-api service clients. |\n| `agents` | `readonly` | [`AgentNamespace`](../../entities/agents/namespace/classes/AgentNamespace.md) | agents resources and operations. |\n| `agentSessions` | `readonly` | [`AgentSessionNamespace`](../../entities/agent-sessions/namespace/classes/AgentSessionNamespace.md) | - |\n| `ai` | `readonly` | [`AiNamespace`](../../entities/ai/namespace/classes/AiNamespace.md) | - |\n| `apiKeys` | `readonly` | [`ApiKeyNamespace`](../../entities/api-keys/namespace/classes/ApiKeyNamespace.md) | apiKeys resources and operations. |\n| `bots` | `readonly` | [`BotsNamespace`](../../entities/bots/namespace/classes/BotsNamespace.md) | - |\n| `calendar` | `readonly` | [`CalendarNamespace`](../../entities/calendar/namespace/classes/CalendarNamespace.md) | - |\n| `calls` | `readonly` | [`CallRecordNamespace`](../../entities/calls/namespace/classes/CallRecordNamespace.md) | - |\n| `channels` | `readonly` | [`ChannelNamespace`](../../entities/channels/namespace/classes/ChannelNamespace.md) | - |\n| `crm` | `readonly` | [`CrmNamespace`](../../entities/crm/namespace/classes/CrmNamespace.md) | - |\n| `databases` | `readonly` | [`DatabaseNamespace`](../../entities/databases/namespace/classes/DatabaseNamespace.md) | - |\n| `documents` | `readonly` | [`DocumentNamespace`](../../entities/documents/namespace/classes/DocumentNamespace.md) | - |\n| `email` | `readonly` | [`EmailNamespace`](../../entities/email/namespace/classes/EmailNamespace.md) | - |\n| `entityMentions` | `readonly` | [`EntityMentionNamespace`](../../entities/entity-mentions/namespace/classes/EntityMentionNamespace.md) | entityMentions resources and operations. |\n| `events` | `readonly` | [`MacroEvents`](../../events/receiver/classes/MacroEvents.md) | - |\n| `favorites` | `readonly` | [`FavoritesNamespace`](../../entities/favorites/namespace/classes/FavoritesNamespace.md) | - |\n| `foreignEntities` | `readonly` | [`ForeignEntityNamespace`](../../entities/foreign/namespace/classes/ForeignEntityNamespace.md) | - |\n| `forms` | `readonly` | [`FormNamespace`](../../entities/forms/namespace/classes/FormNamespace.md) | Build forms and submit answers without granting respondents database access. |\n| `githubPullRequests` | `readonly` | [`GithubPullRequestNamespace`](../../entities/github-pull-requests/namespace/classes/GithubPullRequestNamespace.md) | githubPullRequests resources and operations. |\n| `harnesses` | `readonly` | [`HarnessNamespace`](../../entities/harnesses/namespace/classes/HarnessNamespace.md) | harnesses resources and operations. |\n| `initiatives` | `readonly` | [`InitiativeNamespace`](../../entities/initiatives/namespace/classes/InitiativeNamespace.md) | initiatives resources and operations. |\n| `meetings` | `readonly` | [`MeetingNamespace`](../../entities/meetings/namespace/classes/MeetingNamespace.md) | meetings resources and operations. |\n| `notifications` | `readonly` | [`NotificationNamespace`](../../entities/notifications/namespace/classes/NotificationNamespace.md) | - |\n| `pins` | `readonly` | [`PinsNamespace`](../../entities/pins/namespace/classes/PinsNamespace.md) | - |\n| `projects` | `readonly` | [`ProjectNamespace`](../../entities/projects/namespace/classes/ProjectNamespace.md) | - |\n| `properties` | `readonly` | [`PropertiesNamespace`](../../entities/properties/namespace/classes/PropertiesNamespace.md) | - |\n| `routines` | `readonly` | [`RoutineNamespace`](../../entities/routines/namespace/classes/RoutineNamespace.md) | routines resources and operations. |\n| `tasks` | `readonly` | [`TaskNamespace`](../../entities/tasks/namespace/classes/TaskNamespace.md) | - |\n| `teams` | `readonly` | [`TeamNamespace`](../../entities/teams/namespace/classes/TeamNamespace.md) | - |\n| `unfurls` | `readonly` | [`UnfurlNamespace`](../../entities/unfurls/namespace/classes/UnfurlNamespace.md) | unfurls resources and operations. |\n| `users` | `readonly` | [`UserNamespace`](../../entities/users/namespace/classes/UserNamespace.md) | - |\n| `webAppUrl` | `readonly` | `string` | Base URL of the Macro web app, used to build entity URLs. |\n| `webhooks` | `readonly` | [`WebhooksNamespace`](../../entities/webhooks/namespace/classes/WebhooksNamespace.md) | - |\n| `whatsapp` | `readonly` | [`WhatsAppNamespace`](../../entities/whatsapp/namespace/classes/WhatsAppNamespace.md) | Personal WhatsApp groups and shared group operations. |\n\n## Methods\n\n### myPrincipalId()\n\n> **myPrincipalId**(): `Promise`\\<`string`\\>\n\nThe authenticated caller's mentionable principal — `bot|` for bot\nauth, `macro|` for user auth — fetched once and cached.\n\n#### Returns\n\n`Promise`\\<`string`\\>\n\n***\n\n### requestedAs()\n\n> **requestedAs**(`user`): `Macro`\\<`T`\\>\n\nClone of this SDK acting on behalf of `user` (sent as\n`x-macro-bot-for-macro-user-id`). Bot auth only — throws for user auth,\nsince a user token always acts as its own user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../entities/users/user/classes/User.md) |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n\n\n# Type Alias: RequestActivity\n\n> **RequestActivity** = \\{ `id`: `number`; `operation`: `string`; `service`: `string`; `status`: `\"started\"` \\| `\"completed\"` \\| `\"failed\"`; \\}\n\nA generated SDK operation lifecycle. Contains no arguments, URLs or response data.\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `id` | `number` |\n| `operation` | `string` |\n| `service` | `string` |\n| `status` | `\"started\"` \\| `\"completed\"` \\| `\"failed\"` |\n\n\n\n# Function: msg()\n\n> **msg**(`strings`, ...`values`): [`RichMessage`](../interfaces/RichMessage.md)\n\nCompose a rich message. Interpolate mentions (a User, Document,\n[here](../variables/here.md), …) or plain strings. Each mention writes its `` tag into the\ncontent *and* adds itself to `mentions[]`, so the two can never drift; strings\nare inserted as-is, so markdown like `**bold**` passes through untouched.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `strings` | `TemplateStringsArray` |\n| ...`values` | [`Interpolation`](../type-aliases/Interpolation.md)[] |\n\n## Returns\n\n[`RichMessage`](../interfaces/RichMessage.md)\n\n## Example\n\n```ts\nchannel.send(msg`Hey ${user}, see ${doc}. cc ${here}`);\nchannel.send(msg`Status: ${status} — see ${doc}`);\n```\n\n\n\n# Function: toBody()\n\n> **toBody**(`body`): [`RichMessage`](../interfaces/RichMessage.md)\n\nNormalize a plain string or a [RichMessage](../interfaces/RichMessage.md) to the wire shape.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../interfaces/RichMessage.md) |\n\n## Returns\n\n[`RichMessage`](../interfaces/RichMessage.md)\n\n\n\n# Function: wrapXml()\n\n> **wrapXml**(`tag`, `data`): `string`\n\nSerialize a mention node to its `{json} ` wire form. Readers take\neverything up to the first closing tag, so `<`, `>` and `&` in the JSON are\nwritten as `\\u` escapes: a document named `` would\notherwise end the tag early. Decoding the JSON restores the original text.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `tag` | `string` |\n| `data` | `unknown` |\n\n## Returns\n\n`string`\n\n\n\n# Interface: MentionPart\n\nThe two things a mentionable entity contributes to a message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `mention` | [`SimpleMention`](../../../generated/storage/types.gen/type-aliases/SimpleMention.md) | The parallel entry the backend uses for notifications and permissions. |\n| `tag` | `string` | The `` tag written into the message content. |\n\n\n\n# Interface: Mentionable\n\nAnything that can be dropped into a [msg](../functions/msg.md) template as a mention.\n\n## Methods\n\n### toMention()\n\n> **toMention**(): [`MentionPart`](MentionPart.md)\n\n#### Returns\n\n[`MentionPart`](MentionPart.md)\n\n\n\n# Interface: RichMessage\n\nA composed message body: content with embedded tags, and the matching mentions.\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `content` | `string` |\n| `mentions` | [`SimpleMention`](../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] |\n\n\n\n# Type Alias: Interpolation\n\n> **Interpolation** = [`Mentionable`](../interfaces/Mentionable.md) \\| `string` \\| `number`\n\nWhat may be interpolated into a [msg](../functions/msg.md) template: a mention, or plain text.\n\n\n\n# Variable: here\n\n> `const` **here**: [`Mentionable`](../interfaces/Mentionable.md)\n\nThe `@here` group mention.\n\n\n\n# Class: Lazy\\\n\nA value fetched on first access and cached thereafter. Powers thin entity\nhandles: construction is free, the record is loaded lazily the first time a\nfield is read, and concurrent reads share one in-flight request. Pass a\n`seed` when the record is already known (from a list or an event) to skip the\nfetch entirely.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `T` |\n\n## Constructors\n\n### Constructor\n\n> **new Lazy**\\<`T`\\>(`loader`, `seed?`): `Lazy`\\<`T`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `loader` | () => `Promise`\\<`T`\\> |\n| `seed?` | `T` |\n\n#### Returns\n\n`Lazy`\\<`T`\\>\n\n## Methods\n\n### clear()\n\n> **clear**(): `void`\n\nDrop the cached value so the next read refetches.\n\n#### Returns\n\n`void`\n\n***\n\n### get()\n\n> **get**(): `Promise`\\<`T`\\>\n\n#### Returns\n\n`Promise`\\<`T`\\>\n\n***\n\n### peek()\n\n> **peek**(): `T` \\| `undefined`\n\nThe cached value, if already loaded — never triggers a fetch.\n\n#### Returns\n\n`T` \\| `undefined`\n\n\n\n# Function: paginate()\n\n> **paginate**\\<`T`, `Cursor`\\>(`fetchPage`): `AsyncGenerator`\\<`T`\\>\n\nAsync generator over a cursor-paginated API. Iterate with `for await`.\nCursors are plain JSON values (strings or small objects), so a page whose\nnext cursor serialises identically to the one it was fetched with means the\nserver is not advancing; the generator throws instead of looping forever.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` | - |\n| `Cursor` | `string` |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `fetchPage` | (`cursor?`) => `Promise`\\<[`Page`](../interfaces/Page.md)\\<`T`, `Cursor`\\>\\> |\n\n## Returns\n\n`AsyncGenerator`\\<`T`\\>\n\n\n\n# Interface: Page\\\n\nOne page of a cursor-paginated list.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` | - |\n| `Cursor` | `string` |\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `items` | `T`[] |\n| `nextCursor?` | `Cursor` \\| `null` |\n\n\n\n# Class: MacroApiError\n\nA non-2xx HTTP response (Macro API, or a raw fetch like presigned downloads).\n\n## Extends\n\n- [`MacroError`](MacroError.md)\n\n## Extended by\n\n- [`MacroOpRefusedError`](../../../entities/databases/database/classes/MacroOpRefusedError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroApiError**(`status`, `data`): `MacroApiError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `status` | `number` |\n| `data` | `unknown` |\n\n#### Returns\n\n`MacroApiError`\n\n#### Overrides\n\n[`MacroError`](MacroError.md).[`constructor`](MacroError.md#constructor)\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `data` | `readonly` | `unknown` |\n| `status` | `readonly` | `number` |\n\n\n\n# Class: MacroError\n\nBase for every error the SDK throws.\n\n## Extends\n\n- `Error`\n\n## Extended by\n\n- [`MacroApiError`](MacroApiError.md)\n- [`MacroNotFoundError`](MacroNotFoundError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroError**(`message`): `MacroError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | `string` |\n\n#### Returns\n\n`MacroError`\n\n#### Overrides\n\n`Error.constructor`\n\n\n\n# Class: MacroNotFoundError\n\nThe API succeeded but the addressed entity doesn't exist in the result.\n\n## Extends\n\n- [`MacroError`](MacroError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroNotFoundError**(`message`): `MacroNotFoundError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | `string` |\n\n#### Returns\n\n`MacroNotFoundError`\n\n#### Overrides\n\n[`MacroError`](MacroError.md).[`constructor`](MacroError.md#constructor)\n\n\n\n# Function: unwrap()\n\n> **unwrap**\\<`TData`, `TError`\\>(`res`): `TData`\n\nTurn a hey-api `{ data, error, response? }` result into either the success\npayload or a thrown MacroApiError.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `TData` |\n| `TError` |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `res` | \\{ `data?`: `TData`; `error?`: `TError`; `response?`: `Response`; \\} |\n| `res.data?` | `TData` |\n| `res.error?` | `TError` |\n| `res.response?` | `Response` |\n\n## Returns\n\n`TData`\n"
+ "documentation": "# Macro SDK: core\n\nGenerated by TypeDoc. Paths below refer to the canonical Markdown hierarchy. Other entity handles are documented in their named section; request core for shared SDK helpers.\n\n\n# Type Alias: BulkUpdateEntityPropertyOptionsResponse\n\n> **BulkUpdateEntityPropertyOptionsResponse** = \\{ `properties`: [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[]; \\}\n\nResponse for a bulk option update: each property's reconciled final ids.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `properties` | [`EntityPropertyOptionSelectionResponse`](EntityPropertyOptionSelectionResponse.md)[] | The final option ids per updated property. |\n\n\n\n# Type Alias: DataType\n\n> **DataType** = `\"BOOLEAN\"` \\| `\"DATE\"` \\| `\"NUMBER\"` \\| `\"STRING\"` \\| `\"SELECT_NUMBER\"` \\| `\"SELECT_STRING\"` \\| `\"TAG\"` \\| `\"ENTITY\"` \\| `\"LINK\"`\n\nData type for property values, determining storage and validation.\n\n\n\n# Type Alias: EntityProperty\n\n> **EntityProperty** = \\{ `created_at`: `string`; `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; \\}\n\nAssignment of a property definition to a specific entity (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `created_at` | `string` |\n| `entity_id` | `string` |\n| `entity_type` | [`EntityType`](EntityType.md) |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n\n\n\n# Type Alias: EntityPropertyOptionSelectionResponse\n\n> **EntityPropertyOptionSelectionResponse** = \\{ `option_ids`: `string`[]; `property_id`: `string`; \\}\n\nThe reconciled final option ids stored for one property after a bulk update.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `option_ids` | `string`[] | The final option ids the server persisted, in stored order. |\n| `property_id` | `string` | The property definition the options belong to. |\n\n\n\n# Type Alias: EntityPropertyWithDefinition\n\n> **EntityPropertyWithDefinition** = \\{ `definition`: [`PropertyDefinition`](PropertyDefinition.md); `options?`: [`PropertyOption`](PropertyOption.md)[] \\| `null`; `property`: [`EntityProperty`](EntityProperty.md); `value?`: `null` \\| [`PropertyValue`](PropertyValue.md); \\}\n\nEntity property with its definition, value, and options (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `definition` | [`PropertyDefinition`](PropertyDefinition.md) |\n| `options?` | [`PropertyOption`](PropertyOption.md)[] \\| `null` |\n| `property` | [`EntityProperty`](EntityProperty.md) |\n| `value?` | `null` \\| [`PropertyValue`](PropertyValue.md) |\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity_id`: `string`; `entity_type`: [`EntityType`](EntityType.md); `specific_message_id?`: `string` \\| `null`; \\}\n\nEntity reference for entity-type property values.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | - |\n| `entity_type` | [`EntityType`](EntityType.md) | - |\n| `specific_message_id?` | `string` \\| `null` | For CHANNEL, CHAT, THREAD entity types - optional specific message ID. This allows referencing a specific message within a thread/channel/chat. |\n\n\n\n# Type Alias: EntityType\n\n> **EntityType** = `\"CALENDAR_EVENT\"` \\| `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"CONTACT\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"TASK\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nType of entity that can be referenced by entity properties.\n\n\n\n# Type Alias: PropertyDefinition\n\n> **PropertyDefinition** = \\{ `created_at`: `string`; `data_type`: [`DataType`](DataType.md); `display_name`: `string`; `id`: `string`; `is_metadata`: `boolean`; `is_multi_select`: `boolean`; `is_system`: `boolean`; `owner`: [`PropertyOwner`](PropertyOwner.md); `specific_entity_type`: `null` \\| [`EntityType`](EntityType.md); `updated_at`: `string`; \\}\n\nProperty definition model (service representation).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | - |\n| `data_type` | [`DataType`](DataType.md) | - |\n| `display_name` | `string` | - |\n| `id` | `string` | - |\n| `is_metadata` | `boolean` | Flag to indicate if this is a system-generated metadata property. Not stored in database - computed at service layer. |\n| `is_multi_select` | `boolean` | - |\n| `is_system` | `boolean` | Flag to indicate if this is a system property (stored in DB). |\n| `owner` | [`PropertyOwner`](PropertyOwner.md) | - |\n| `specific_entity_type` | `null` \\| [`EntityType`](EntityType.md) | - |\n| `updated_at` | `string` | - |\n\n\n\n# Type Alias: PropertyOption\n\n> **PropertyOption** = \\{ `color`: `string` \\| `null`; `created_at`: `string`; `display_order`: `number`; `id`: `string`; `property_definition_id`: `string`; `updated_at`: `string`; `value`: [`PropertyOptionValue`](PropertyOptionValue.md); \\}\n\nA selectable option for select-type properties (service representation).\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `color` | `string` \\| `null` |\n| `created_at` | `string` |\n| `display_order` | `number` |\n| `id` | `string` |\n| `property_definition_id` | `string` |\n| `updated_at` | `string` |\n| `value` | [`PropertyOptionValue`](PropertyOptionValue.md) |\n\n\n\n# Type Alias: PropertyOptionValue\n\n> **PropertyOptionValue** = \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\}\n\nThe value of a property option - either a string or a number.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"string\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"string\"` | - |\n| `value` | `string` | String value for SelectString properties |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"number\"` | - |\n| `value` | `number` | Number value for SelectNumber properties |\n\n\n\n# Type Alias: PropertyOwner\n\n> **PropertyOwner** = \\{ `scope`: `\"user\"`; `user_id`: `string`; \\} \\| \\{ `scope`: `\"team\"`; `team_id`: `string`; \\} \\| \\{ `database_id`: `string`; `scope`: `\"database\"`; \\} \\| \\{ `scope`: `\"system\"`; \\}\n\nDefines who owns a property - user-scoped, team-scoped, database-scoped, or system.\n\n\n\n# Type Alias: PropertyTargetEntityType\n\n> **PropertyTargetEntityType** = `\"CALL_RECORD\"` \\| `\"CHANNEL\"` \\| `\"CHAT\"` \\| `\"COMPANY\"` \\| `\"DATABASE_ROW\"` \\| `\"DOCUMENT\"` \\| `\"INITIATIVE\"` \\| `\"PROJECT\"` \\| `\"THREAD\"` \\| `\"USER\"`\n\nCanonical type of an entity receiving properties.\n\nTasks are documents at API boundaries. `Task` intentionally does not exist\nhere; task classification is resolved by the properties domain from the\ndocument subtype.\n\n\n\n# Type Alias: PropertyTargetReference\n\n> **PropertyTargetReference** = \\{ `entity_id`: `string`; `entity_type`: [`PropertyTargetEntityType`](PropertyTargetEntityType.md); \\}\n\nCanonical reference to an entity receiving properties.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Entity identifier. |\n| `entity_type` | [`PropertyTargetEntityType`](PropertyTargetEntityType.md) | Canonical entity type. |\n\n\n\n# Type Alias: PropertyValue\n\n> **PropertyValue** = \\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"Number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"String\"`; `value`: `string`; \\} \\| \\{ `type`: `\"Date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\} \\| \\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\} \\| \\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\nProperty value (service representation).\n\nRepresents the actual value stored for an entity property.\nThis is serialized to/from JSONB in the database.\n\n## Union Members\n\n### Type Literal\n\n\\{ `type`: `\"Boolean\"`; `value`: `boolean`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Boolean\"` | - |\n| `value` | `boolean` | Boolean value Serializes as: {\"type\": \"Boolean\", \"value\": true} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Number\"`; `value`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Number\"` | - |\n| `value` | `number` | Numeric value Serializes as: {\"type\": \"Number\", \"value\": 42.5} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"String\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"String\"` | - |\n| `value` | `string` | String value Serializes as: {\"type\": \"String\", \"value\": \"text\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Date\"`; `value`: `string`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Date\"` | - |\n| `value` | `string` | Date/timestamp value Serializes as: {\"type\": \"Date\", \"value\": \"2025-01-01T00:00:00Z\"} |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"SelectOption\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"SelectOption\"` | - |\n| `value` | `string`[] | Select option(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"SelectOption\", \"value\": [\"uuid\"]} (length 0 or 1) Multi-select: {\"type\": \"SelectOption\", \"value\": [\"uuid1\", \"uuid2\", ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"EntityReference\"`; `value`: [`EntityReference`](EntityReference.md)[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"EntityReference\"` | - |\n| `value` | [`EntityReference`](EntityReference.md)[] | Entity reference(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"EntityReference\", \"value\": [{...}]} (length 0 or 1) Multi-select: {\"type\": \"EntityReference\", \"value\": [{...}, {...}, ...]} (length 0+) |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"Link\"`; `value`: `string`[]; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `type` | `\"Link\"` | - |\n| `value` | `string`[] | Link value(s) - always an array (check is_multi_select to determine if single or multi) Single-select: {\"type\": \"Link\", \"value\": [\"https://example.com\"]} (length 0 or 1) Multi-select: {\"type\": \"Link\", \"value\": [\"https://example.com\", \"https://other.com\"]} (length 0+) |\n\n\n\n# Type Alias: SetPropertyValue\n\n> **SetPropertyValue** = \\{ `type`: `\"boolean\"`; `value`: `boolean`; \\} \\| \\{ `type`: `\"date\"`; `value`: `string`; \\} \\| \\{ `type`: `\"number\"`; `value`: `number`; \\} \\| \\{ `type`: `\"string\"`; `value`: `string`; \\} \\| \\{ `option_id`: `string`; `type`: `\"select_option\"`; \\} \\| \\{ `option_ids`: `string`[]; `type`: `\"multi_select_option\"`; \\} \\| \\{ `reference`: [`EntityReference`](EntityReference.md); `type`: `\"entity_reference\"`; \\} \\| \\{ `references`: [`EntityReference`](EntityReference.md)[]; `type`: `\"multi_entity_reference\"`; \\} \\| \\{ `type`: `\"link\"`; `url`: `string`; \\} \\| \\{ `type`: `\"multi_link\"`; `urls`: `string`[]; \\}\n\nType-safe enum for setting entity property values - provides compile-time validation.\n\n\n\n# Type Alias: AgentSessionFilters\n\n> **AgentSessionFilters** = \\{ `ids?`: `string`[]; `include?`: `boolean`; `owners?`: `string`[]; \\}\n\nFilters for agent sessions.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `ids?` | `string`[] | Agent session ids to filter by. Empty to include all accessible sessions. |\n| `include?` | `boolean` | Opt this query into agent sessions at all. Agent sessions are off by default — see [`crate::ast::agent_session::AgentSessionLiteral::Include`]. Asking for specific `ids` or `owners` also opts in. |\n| `owners?` | `string`[] | Filter by session owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Empty to include every owner. |\n\n\n\n# Type Alias: CalendarEventFilters\n\n> **CalendarEventFilters** = \\{ `attendees?`: `string`[]; `calendar_event_ids?`: `string`[]; `ends_after?`: `string` \\| `null`; `organizers?`: `string`[]; `starts_before?`: `string` \\| `null`; `statuses?`: `string`[]; \\}\n\nFilters for canonical calendar-event entities.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attendees?` | `string`[] | Attendee email addresses. |\n| `calendar_event_ids?` | `string`[] | Canonical event ids. |\n| `ends_after?` | `string` \\| `null` | Include master events ending after this instant. |\n| `organizers?` | `string`[] | Organizer email addresses. |\n| `starts_before?` | `string` \\| `null` | Include master events starting before this instant. |\n| `statuses?` | `string`[] | Event statuses such as `confirmed`, `tentative`, or `cancelled`. |\n\n\n\n# Type Alias: CallFilters\n\n> **CallFilters** = \\{ `attended?`: `boolean` \\| `null`; `call_ids?`: `string`[]; `channel_ids?`: `string`[]; `speaker_ids?`: `string`[]; `status?`: `null` \\| [`CallStatus`](CallStatus.md); \\}\n\nFilters for call records.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `attended?` | `boolean` \\| `null` | Legacy filter by whether the requesting user attended the call. Prefer [`CallFilters::status`] for new callers. `None` = no filter, `Some(true)` = only calls the user joined, `Some(false)` = only calls the user did not join. |\n| `call_ids?` | `string`[] | Call record IDs to filter by. Empty to include all calls. |\n| `channel_ids?` | `string`[] | Channel IDs to filter calls by. Empty to include all calls. |\n| `speaker_ids?` | `string`[] | Speaker macro user ids. Empty to include all. |\n| `status?` | `null` \\| [`CallStatus`](CallStatus.md) | - |\n\n\n\n# Type Alias: CallStatus\n\n> **CallStatus** = `\"ATTENDED\"` \\| `\"MISSED\"` \\| `\"UNATTENDED\"`\n\nViewer-relative attendance status for a call record.\nSerializes as `ATTENDED`, `MISSED`, or `UNATTENDED`.\n\n\n\n# Type Alias: ChannelFilters\n\n> **ChannelFilters** = \\{ `channel_ids?`: `string`[]; `channel_types?`: `string`[]; `importance?`: `boolean` \\| `null`; `is_participant?`: `boolean` \\| `null`; `mentions?`: `string`[]; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `org_id?`: `number` \\| `null`; `sender_ids?`: `string`[]; `team_id?`: `string` \\| `null`; `thread_ids?`: `string`[]; \\}\n\nThe channel message filters used to filter down what channel messages you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_ids?` | `string`[] | Channel IDs to search within. Examples: ['general']. Empty to search all accessible channels. |\n| `channel_types?` | `string`[] | Channel types to filter by. Examples: ['public'], ['direct_message', 'private']. Empty to search all channel types. |\n| `importance?` | `boolean` \\| `null` | Filter by channel importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `is_participant?` | `boolean` \\| `null` | Filter by whether the requesting user is an active participant of the channel. Presence of this filter also widens the candidate set to team channels of the user's teams that they have not joined, so `false` matches those channels. None to ignore (participant channels only, today's default). |\n| `mentions?` | `string`[] | Channel user mentions to search for. Examples: ['@username']. Empty if not filtering by mentions. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by channel notification state. |\n| `org_id?` | `number` \\| `null` | Channel organization ID to search within. Empty to ignore organization filtering. |\n| `sender_ids?` | `string`[] | Sender IDs to search within. Examples: ['user1']. Empty to search all accessible senders. |\n| `team_id?` | `string` \\| `null` | Channel team ID to search within. Empty to ignore team filtering. |\n| `thread_ids?` | `string`[] | Channel thread IDs to search within. Examples: ['thread123']. Empty to search all threads. |\n\n\n\n# Type Alias: ChannelThreadFilters\n\n> **ChannelThreadFilters** = \\{ `channel_ids?`: `string`[]; `participant_ids?`: `string`[]; `root_sender_ids?`: `string`[]; `thread_ids?`: `string`[]; \\}\n\nThe channel thread filters used to filter down channel-thread entities.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channel_ids?` | `string`[] | Channel IDs containing the thread. Empty to include threads from all accessible channels. |\n| `participant_ids?` | `string`[] | Thread participant user IDs. A participant is the root message sender, anyone who replied in the thread, or anyone @-mentioned in the thread (group mentions like **Here** count through their per-user expansion at send time). Empty to include threads regardless of participants. |\n| `root_sender_ids?` | `string`[] | Sender IDs for the root thread message. Empty to include all root senders. |\n| `thread_ids?` | `string`[] | Channel thread parent message IDs to include. Empty to include all accessible threads. |\n\n\n\n# Type Alias: ChatFilters\n\n> **ChatFilters** = \\{ `chat_ids?`: `string`[]; `importance?`: `boolean` \\| `null`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; `role?`: `string`[]; \\}\n\nThe chat filters used to filter down what chats you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `chat_ids?` | `string`[] | Chat ids to search over. Examples: ['chat1'], ['chat1', 'chat2']. When provided, chat search will only match results on these chats. Empty to search all accessible chats. |\n| `importance?` | `boolean` \\| `null` | Filter by chat importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by chat notification state. |\n| `owners?` | `string`[] | Filter by chat owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Examples: ['project1']. Empty to ignore project filtering. |\n| `role?` | `string`[] | Chat message roles to search. Examples: ['user'], ['assistant']. Empty to search all roles. |\n\n\n\n# Type Alias: CrmCompanyFilters\n\n> **CrmCompanyFilters** = \\{ `company_ids?`: `string`[]; `hidden?`: `boolean` \\| `null`; \\}\n\nThe crm company filters used to narrow which CRM companies appear in soup.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `company_ids?` | `string`[] | CRM company ids to filter by. Examples: ['11111111-...']. Empty to include all of the team's visible CRM companies. |\n| `hidden?` | `boolean` \\| `null` | Optional `crm_companies.hidden` filter. `None` = visible only (default for back-compat with non-admin callers). `Some(false)` = visible only (explicit). `Some(true)` = hidden only — requires admin/owner team role; enforced by the CRM service from the caller's team receipt. |\n\n\n\n# Type Alias: DocumentFilters\n\n> **DocumentFilters** = \\{ `document_ids?`: `string`[]; `file_types?`: `string`[]; `importance?`: `boolean` \\| `null`; `is_email_attachment?`: `boolean` \\| `null`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; `sub_types?`: `string`[]; `task_filters?`: [`TaskFilters`](TaskFilters.md); \\}\n\nThe document filters used to filter down what documents you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `document_ids?` | `string`[] | Document ids to search over. Examples: ['doc1'], ['doc1', 'doc2']. Empty to search all accessible documents. |\n| `file_types?` | `string`[] | Document file types to search. Examples: ['pdf'], ['md', 'txt']. Empty to search all file types. |\n| `importance?` | `boolean` \\| `null` | Filter by document importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `is_email_attachment?` | `boolean` \\| `null` | Filter by email attachment status. true = only email attachments, false = only non-email attachments, None = both. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by document notification state. |\n| `owners?` | `string`[] | Filter by document owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Examples: ['project1']. filtering. Empty to ignore project filtering. |\n| `sub_types?` | `string`[] | Filter by document sub type. Examples: ['task']. Empty to search all sub types. |\n| `task_filters?` | [`TaskFilters`](TaskFilters.md) | Task-specific filters that only apply to task subtype documents. |\n\n\n\n# Type Alias: EmailFilters\n\n> **EmailFilters** = \\{ `bcc?`: `string`[]; `calendar_only?`: `boolean` \\| `null`; `cc?`: `string`[]; `crm_addresses?`: `string`[]; `crm_domains?`: `string`[]; `email_thread_ids?`: `string`[]; `exclude_labels?`: `string`[]; `importance?`: `boolean` \\| `null`; `include_labels?`: `string`[]; `is_read?`: `boolean` \\| `null`; `link_ids?`: `string`[]; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `project_ids?`: `string`[]; `recipients?`: `string`[]; `senders?`: `string`[]; `shared?`: [`SharedEmailFilter`](SharedEmailFilter.md); \\}\n\nThe email filters used to filter down what emails you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `bcc?` | `string`[] | Email BCC addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by BCC. |\n| `calendar_only?` | `boolean` \\| `null` | When `Some(true)`, only include threads that have at least one message with an iCalendar attachment (`.ics` filename or `application/ics` mime type). `Some(false)` and `None` apply no constraint. |\n| `cc?` | `string`[] | Email CC addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by CC. |\n| `crm_addresses?` | `string`[] | CRM-scoped address filter. When non-empty, expands visibility to every teammate's mailbox and restricts to threads involving any of these fully-qualified addresses. Each address is authorized against `crm_contacts` + `crm_companies` (contact must not be hidden, company must not be hidden, `email_sync` must be true). Mutually exclusive with `crm_domains`. |\n| `crm_domains?` | `string`[] | CRM-scoped domain filter. When non-empty, expands visibility to every teammate's mailbox and restricts to threads involving any of these domains (in any of sender/cc/bcc/recipient). Each domain is authorized against `crm_domains` + `crm_companies` (must exist for the caller's team, company must not be hidden, `email_sync` must be true). Mutually exclusive with `crm_addresses`. |\n| `email_thread_ids?` | `string`[] | Email thread IDs to filter by. Examples: ['thread-uuid-1']. Empty to search all threads. |\n| `exclude_labels?` | `string`[] | Exclude emails that have any of these labels. Supports both Gmail system labels (e.g. \"CATEGORY_PROMOTIONS\") and user-created labels. Empty to not exclude any labels. Note: SPAM and TRASH emails are not indexed in OpenSearch, so they are already excluded by default. |\n| `importance?` | `boolean` \\| `null` | Filter by email importance. None to not filter. True to show only important emails (drafts, personal, sent, or uncategorized). False to show only unimportant emails (those categorized as promotions, social, updates, or forums). |\n| `include_labels?` | `string`[] | Only include emails that have at least one of these labels. Supports both Gmail system labels (e.g. \"INBOX\", \"CATEGORY_PROMOTIONS\") and user-created labels (e.g. \"github\"). Empty to not filter by included labels. Note: SPAM and TRASH emails are not indexed in OpenSearch, so they will never appear in results regardless of this filter. |\n| `is_read?` | `boolean` \\| `null` | Filter by the email thread's read flag, independently of notification state. |\n| `link_ids?` | `string`[] | Restrict to specific inboxes by email_links.id. Empty means \"any inbox the caller can access\" (soup expands to the full set at the router edge). |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by email notification state. |\n| `project_ids?` | `string`[] | A list of project ids to search within. Empty to ignore project filtering. |\n| `recipients?` | `string`[] | Email Recipient addresses to filter by. Examples: ['user@example.com']. Empty if not filtering by Recipient. |\n| `senders?` | `string`[] | Email sender addresses to filter by. Examples: ['user@example.com']. Empty to search all senders. |\n| `shared?` | [`SharedEmailFilter`](SharedEmailFilter.md) | Controls whether shared email threads are included in results. Defaults to \"exclude\" (only the user's own threads). |\n\n\n\n# Type Alias: EntityFilters\n\n> **EntityFilters** = \\{ `agent_session_filters?`: [`AgentSessionFilters`](AgentSessionFilters.md); `calendar_event_filters?`: [`CalendarEventFilters`](CalendarEventFilters.md); `call_filters?`: [`CallFilters`](CallFilters.md); `channel_filters?`: [`ChannelFilters`](ChannelFilters.md); `channel_thread_filters?`: [`ChannelThreadFilters`](ChannelThreadFilters.md); `chat_filters?`: [`ChatFilters`](ChatFilters.md); `crm_company_filters?`: [`CrmCompanyFilters`](CrmCompanyFilters.md); `document_filters?`: [`DocumentFilters`](DocumentFilters.md); `email_filters?`: [`EmailFilters`](EmailFilters.md); `favorites_only?`: `boolean` \\| `null`; `foreign_entity_filters?`: [`ForeignEntityFilters`](ForeignEntityFilters.md); `initiative_filters?`: [`InitiativeFilters`](InitiativeFilters.md); `project_filters?`: [`ProjectFilters`](ProjectFilters.md); `property_filters?`: [`PropertyFilter`](PropertyFilter.md)[]; `tag_filter_mode?`: [`TagFilterMode`](TagFilterMode.md); `tag_option_ids?`: `string`[]; \\}\n\na bundle of all of the filters for each entity type\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `agent_session_filters?` | [`AgentSessionFilters`](AgentSessionFilters.md) | the bundled [AgentSessionFilters] |\n| `calendar_event_filters?` | [`CalendarEventFilters`](CalendarEventFilters.md) | the bundled [CalendarEventFilters] |\n| `call_filters?` | [`CallFilters`](CallFilters.md) | the bundled [CallFilters] |\n| `channel_filters?` | [`ChannelFilters`](ChannelFilters.md) | the bundled [ChannelFilters] |\n| `channel_thread_filters?` | [`ChannelThreadFilters`](ChannelThreadFilters.md) | the bundled [ChannelThreadFilters] |\n| `chat_filters?` | [`ChatFilters`](ChatFilters.md) | the bundled [ChatFilters] |\n| `crm_company_filters?` | [`CrmCompanyFilters`](CrmCompanyFilters.md) | the bundled [CrmCompanyFilters] |\n| `document_filters?` | [`DocumentFilters`](DocumentFilters.md) | the bundled [DocumentFilters] |\n| `email_filters?` | [`EmailFilters`](EmailFilters.md) | the bundled [EmailFilters] |\n| `favorites_only?` | `boolean` \\| `null` | Restrict results to the authenticated viewer's favorites when true. |\n| `foreign_entity_filters?` | [`ForeignEntityFilters`](ForeignEntityFilters.md) | the bundled [ForeignEntityFilters] |\n| `initiative_filters?` | [`InitiativeFilters`](InitiativeFilters.md) | Initiative filters. Initiatives are opt-in. |\n| `project_filters?` | [`ProjectFilters`](ProjectFilters.md) | the bundled [ProjectFilters] |\n| `property_filters?` | [`PropertyFilter`](PropertyFilter.md)[] | property-based filters applied across entity types |\n| `tag_filter_mode?` | [`TagFilterMode`](TagFilterMode.md) | How the `tag_option_ids` combine: `any` (default) matches entities holding at least one selected tag, `all` requires every selected tag. |\n| `tag_option_ids?` | `string`[] | tag option ids matched against `properties.values`, OR'd together across all tag definitions. Option ids are globally unique, so the match ignores the owning definition id (personal and team tags combine into one OR). |\n\n\n\n# Type Alias: ForeignEntityFilters\n\n> **ForeignEntityFilters** = \\{ `foreign_entity_ids?`: `string`[]; `foreign_entity_sources?`: `string`[]; `ids?`: `string`[]; `includes_me?`: `boolean`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); \\}\n\nFilters for foreign entity records.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `foreign_entity_ids?` | `string`[] | External entity identifiers to filter by. Empty to include all external IDs. |\n| `foreign_entity_sources?` | `string`[] | External source names to filter by. Empty to include all sources. |\n| `ids?` | `string`[] | Internal foreign entity record IDs to filter by. Empty to include all records. |\n| `includes_me?` | `boolean` | When true, only return foreign entities whose metadata lists the requesting user as a participant (GitHub `involves:me` semantics for `github_pull_request` records). False or absent applies no filter. Serialized in filter ASTs as the `\"me\"` literal. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by the notification state of the foreign entity (e.g. whether the requesting user's GitHub PR notification is done/seen). |\n\n\n\n# Type Alias: InitiativeFilters\n\n> **InitiativeFilters** = \\{ `due_after?`: `string` \\| `null`; `due_before?`: `string` \\| `null`; `include?`: `boolean`; `initiative_ids?`: `string`[]; `name?`: `string` \\| `null`; `owners?`: `string`[]; \\}\n\nFilters for initiatives.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `due_after?` | `string` \\| `null` | Inclusive lower due-date bound. |\n| `due_before?` | `string` \\| `null` | Inclusive upper due-date bound. |\n| `include?` | `boolean` | Opt this query into initiatives at all. Initiatives are off by default — see [`crate::ast::initiative::InitiativeLiteral::Include`]. Asking for specific `initiative_ids` or `owners` also opts in. |\n| `initiative_ids?` | `string`[] | Initiative ids to filter by. Empty to include all accessible initiatives. |\n| `name?` | `string` \\| `null` | Case-insensitive name substring. |\n| `owners?` | `string`[] | Filter by initiative owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Empty to include every owner. |\n\n\n\n# Type Alias: NotificationFilters\n\n> **NotificationFilters** = \\{ `states?`: [`NotificationState`](NotificationState.md)[]; \\}\n\nNotification-level filters that apply to an entity type.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `states?` | [`NotificationState`](NotificationState.md)[] | Include entities with a non-deleted notification in any of these exact states. Empty means no notification restriction. Active means `[unseen, seen]`. |\n\n\n\n# Type Alias: NotificationState\n\n> **NotificationState** = `\"unseen\"` \\| `\"seen\"` \\| `\"done\"`\n\nThe mutually exclusive lifecycle states of a user's notification.\n\n\n\n# Type Alias: ProjectFilters\n\n> **ProjectFilters** = \\{ `importance?`: `boolean` \\| `null`; `include_root?`: `boolean`; `notification_filters?`: [`NotificationFilters`](NotificationFilters.md); `owners?`: `string`[]; `project_ids?`: `string`[]; \\}\n\nThe project filters used to filter down what projects you search over.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `importance?` | `boolean` \\| `null` | Filter by project importance. None to ignore, true to pass through (no clause), false to short-circuit and return nothing. |\n| `include_root?` | `boolean` | When true, `project_ids` also matches the projects themselves in addition to their children. |\n| `notification_filters?` | [`NotificationFilters`](NotificationFilters.md) | Filter by project notification state. |\n| `owners?` | `string`[] | Filter by project owner principal — a user ('macro\\|user1@user.com'), a bot ('bot\\|'), or a team (a bare hyphenated uuid). Examples: ['macro\\|user1@user.com'], ['macro\\|user1@user.com', 'bot\\|0199...']. Empty to search all owners. |\n| `project_ids?` | `string`[] | Project IDs to search within. Examples: ['project1']. Empty to search all accessible projects. By default matches children of these projects; set `include_root` to also match the projects themselves. |\n\n\n\n# Type Alias: PropertyFilter\n\n> **PropertyFilter** = \\{ `entity_ids?`: `string`[]; `entity_type?`: `string` \\| `null`; `option_ids?`: `string`[]; `property_definition_id`: `string`; \\}\n\nA single property-based filter condition.\n\nEach filter targets a specific property definition on entities of a given type,\nmatching against select option UUIDs or entity reference IDs.\nMultiple values within a single filter are OR'd together.\nMultiple filters are AND'd together.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_ids?` | `string`[] | Entity reference IDs to match. Multiple values are OR'd together. |\n| `entity_type?` | `string` \\| `null` | The entity type for the property lookup (e.g., \"TASK\", \"DOCUMENT\", \"PROJECT\"). When None, matches across all entity types. |\n| `option_ids?` | `string`[] | Select option UUIDs to match. Multiple values are OR'd together. |\n| `property_definition_id` | `string` | The UUID of the property definition to filter on. |\n\n\n\n# Type Alias: SharedEmailFilter\n\n> **SharedEmailFilter** = `\"exclude\"` \\| `\"include\"` \\| `\"only\"`\n\nControls whether shared email threads are included in results.\n\n\n\n# Type Alias: TagFilterMode\n\n> **TagFilterMode** = `\"any\"` \\| `\"all\"`\n\nHow multiple `tag_option_ids` combine when filtering.\n\n\n\n# Type Alias: TaskFilters\n\n> **TaskFilters** = \\{ `include_cbm_atm_nc?`: `boolean` \\| `null`; \\}\n\nTask-only filters nested under document filters.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `include_cbm_atm_nc?` | `boolean` \\| `null` | Include tasks that are created by me, assigned to me, and not completed, even when they do not match other document filters. |\n\n\n\n# Type Alias: AccessLevel\n\n> **AccessLevel** = `\"view\"` \\| `\"comment\"` \\| `\"edit\"` \\| `\"owner\"`\n\nOrdered from least to most access top -> bottom\n\n\n\n# Type Alias: AccessRequest\n\n> **AccessRequest** = \\{ `createdAt`: `string`; `grantedLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `id`: `string`; `requestedLevel`: [`AccessLevel`](AccessLevel.md); `requesterId`: `string`; `resolvedAt?`: `string` \\| `null`; `retryAfter?`: `string` \\| `null`; `revision`: `number`; `status`: [`RequestStatus`](RequestStatus.md); `updatedAt`: `string`; \\}\n\nLatest request for one person and one entity.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `createdAt` | `string` | Start of this request attempt. |\n| `grantedLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `id` | `string` | Stable request identity across revisions. |\n| `requestedLevel` | [`AccessLevel`](AccessLevel.md) | Requested upgrade. |\n| `requesterId` | `string` | Person requesting access. |\n| `resolvedAt?` | `string` \\| `null` | When the request stopped being pending. |\n| `retryAfter?` | `string` \\| `null` | Earliest next submission or level change; cancellation preserves this deadline. Submissions wait one minute, denials wait 24 hours, and approval clears it. |\n| `revision` | `number` | Optimistic concurrency token. |\n| `status` | [`RequestStatus`](RequestStatus.md) | Current outcome. |\n| `updatedAt` | `string` | Most recent change. |\n\n\n\n# Type Alias: EntityPermission\n\n> **EntityPermission** = \\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\} \\| \\{ `type`: `\"channel_view_only\"`; \\} \\| \\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\} \\| \\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\nA user's permission for an entity, discriminated by entity kind.\n\nItems (documents, chats, projects, threads) use access levels.\nChannels use view-only permission or participant roles.\n\n## Union Members\n\n### Type Literal\n\n\\{ `access_level`: [`AccessLevel`](AccessLevel.md); `type`: `\"access_level\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `access_level` | [`AccessLevel`](AccessLevel.md) | The access level the user has. |\n| `type` | `\"access_level\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `type`: `\"channel_view_only\"`; \\}\n\n***\n\n### Type Literal\n\n\\{ `role`: [`ParticipantRole`](ParticipantRole.md); `type`: `\"channel_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`ParticipantRole`](ParticipantRole.md) | The role the user has in the channel. |\n| `type` | `\"channel_role\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `role`: [`TeamRole`](TeamRole.md); `type`: `\"team_role\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `role` | [`TeamRole`](TeamRole.md) | The role the user has in the team. |\n| `type` | `\"team_role\"` | - |\n\n\n\n# Type Alias: FavoriteEntityRef\n\n> **FavoriteEntityRef** = \\{ `entityId`: `string`; `entityType`: `\"user\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"project\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"team\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"`; \\}\n\nA reference to a favorited entity.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entityId` | `string` | The id of the favorited entity. |\n| `entityType` | `\"user\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"project\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"team\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | The type of the favorited entity. |\n\n\n\n# Type Alias: LinkShare\n\n> **LinkShare** = `\"PUBLIC\"` \\| `\"TEAM\"`\n\nDefines who can access an item through its share link.\n\n\n\n# Type Alias: MessageCursor\n\n> **MessageCursor** = \\{ `created_at`: `string`; `id`: `string`; \\}\n\nCursor for a chronological parent timeline.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `created_at` | `string` | Last message creation time or activity occurrence time. |\n| `id` | `string` | Last entry UUID, used to break timestamp ties across both sources. |\n\n\n\n# Type Alias: MessageDirection\n\n> **MessageDirection** = `\"older\"` \\| `\"newer\"`\n\nDirection through a parent timeline, retaining channel cursor semantics.\n\n\n\n# Type Alias: ParticipantRole\n\n> **ParticipantRole** = `\"owner\"` \\| `\"admin\"` \\| `\"member\"`\n\nThe role a user has within a channel.\n\n\n\n# Type Alias: RequestStatus\n\n> **RequestStatus** = `\"pending\"` \\| `\"granted\"` \\| `\"denied\"` \\| `\"cancelled\"`\n\nDurable outcome; reading a notification never changes it.\n\n\n\n# Type Alias: ResolveRequest\n\n> **ResolveRequest** = \\{ `grantedLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `revision`: `number`; \\}\n\nOwner's decision; omission of a granted level means deny.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `grantedLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `revision` | `number` | Request revision being reviewed. |\n\n\n\n# Type Alias: ShareEntityType\n\n> **ShareEntityType** = `\"document\"` \\| `\"chat\"` \\| `\"project\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"call\"` \\| `\"email_thread\"` \\| `\"agent_session\"` \\| `\"whatsapp_group\"`\n\nAn entity type with an existing Share surface.\n\n\n\n# Type Alias: SimpleMention\n\n> **SimpleMention** = \\{ `entity_id`: `string`; `entity_type`: `string`; \\}\n\nA mention tracked in a message body.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `entity_id` | `string` | Mentioned entity identifier. |\n| `entity_type` | `string` | Mentioned entity type. |\n\n\n\n# Type Alias: TeamRole\n\n> **TeamRole** = `\"member\"` \\| `\"admin\"` \\| `\"owner\"`\n\nThe role a user has within a team.\n\nOrdered least to most privileged so comparisons reflect access strength.\n\n\n\n# Type Alias: ThreadAnchor\n\n> **ThreadAnchor** = \\{ `mark_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"markdown\"`; \\} \\| \\{ `anchor_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"pdf_highlight\"`; \\} \\| \\{ `anchor_id`: `string`; `type`: `\"pdf_placeable\"`; \\} \\| \\{ `range`: `string`; `sheetId`: `string`; `sheetName`: `string`; `type`: `\"spreadsheet\"`; \\} \\| \\{ `nodeId?`: `string` \\| `null`; `pageId`: `string`; `type`: `\"fig\"`; `x`: `number`; `y`: `number`; \\}\n\nA thread's location within its document. PDF geometry remains annotation-owned.\n\n## Union Members\n\n### Type Literal\n\n\\{ `mark_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"markdown\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `mark_id` | `string` | Mark UUID serialized in the document. |\n| `marked_text?` | `string` \\| `null` | The marked text as it read when the discussion was created, already trimmed and bounded. Absent on threads created or imported before snapshots were captured: the text a mark covers cannot be recovered from the mark id alone. |\n| `type` | `\"markdown\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `anchor_id`: `string`; `marked_text?`: `string` \\| `null`; `type`: `\"pdf_highlight\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `anchor_id` | `string` | Highlight annotation UUID. |\n| `marked_text?` | `string` \\| `null` | The text the highlight covers, trimmed and bounded like a markdown snapshot. The highlight owns it and it can be edited there, so it is read from the highlight whenever the thread is, never stored on the thread. Absent when the highlight carries no text. |\n| `type` | `\"pdf_highlight\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `anchor_id`: `string`; `type`: `\"pdf_placeable\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `anchor_id` | `string` | Placeable annotation UUID. |\n| `type` | `\"pdf_placeable\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `range`: `string`; `sheetId`: `string`; `sheetName`: `string`; `type`: `\"spreadsheet\"`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `range` | `string` | A1 cell or range, such as B4 or B4:C9. |\n| `sheetId` | `string` | Stable sheet identity within the workbook. |\n| `sheetName` | `string` | Sheet name when the discussion was created. |\n| `type` | `\"spreadsheet\"` | - |\n\n***\n\n### Type Literal\n\n\\{ `nodeId?`: `string` \\| `null`; `pageId`: `string`; `type`: `\"fig\"`; `x`: `number`; `y`: `number`; \\}\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `nodeId?` | `string` \\| `null` | Layer the pin follows; absent for a pin on the bare canvas. |\n| `pageId` | `string` | Page (canvas) the pin is on. |\n| `type` | `\"fig\"` | - |\n| `x` | `number` | Horizontal offset from the layer's origin, or the page's when the pin is on no layer, in design units. |\n| `y` | `number` | Vertical offset, measured like `x`. |\n\n\n\n# Type Alias: ThreadState\n\n> **ThreadState** = \\{ `anchor?`: `null` \\| [`ThreadAnchor`](ThreadAnchor.md); `created_at`: `string`; `deleted_at?`: `string` \\| `null`; `resolved`: `boolean`; `root_id`: `string`; `updated_at`: `string`; `user_id`: `string`; \\}\n\nState belonging to a whole thread, keyed by its root message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `anchor?` | `null` \\| [`ThreadAnchor`](ThreadAnchor.md) | - |\n| `created_at` | `string` | Creation time of the discussion. |\n| `deleted_at?` | `string` \\| `null` | Explicit deletion of the entire thread, distinct from root deletion. |\n| `resolved` | `boolean` | Whether this discussion has been resolved. |\n| `root_id` | `string` | Root message UUID; there is no separate thread identity. |\n| `updated_at` | `string` | Last state change. |\n| `user_id` | `string` | User who owns this discussion, including imported discussions. |\n\n\n\n# Type Alias: UpdateChannelSharePermission\n\n> **UpdateChannelSharePermission** = \\{ `accessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `channelId`: `string`; `operation`: [`UpdateOperation`](UpdateOperation.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `accessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `channelId` | `string` | The channel id |\n| `operation` | [`UpdateOperation`](UpdateOperation.md) | The type of operation to be performed on the chanel share permission You can add, remove or replace and existing permission |\n\n\n\n# Type Alias: UpdateOperation\n\n> **UpdateOperation** = `\"add\"` \\| `\"remove\"` \\| `\"replace\"`\n\n\n\n# Type Alias: UpdateSharePermissionRequestV2\n\n> **UpdateSharePermissionRequestV2** = \\{ `channelSharePermissions?`: [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null`; `linkShare?`: `null` \\| [`LinkShare`](LinkShare.md); `linkShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); `teamShareAccessLevel?`: `null` \\| [`AccessLevel`](AccessLevel.md); \\}\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | [`UpdateChannelSharePermission`](UpdateChannelSharePermission.md)[] \\| `null` | Any channel share permissions to be created/updated/removed |\n| `linkShare?` | `null` \\| [`LinkShare`](LinkShare.md) | - |\n| `linkShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n| `teamShareAccessLevel?` | `null` \\| [`AccessLevel`](AccessLevel.md) | - |\n\n\n\n# Type Alias: WebhookFilter\n\n> **WebhookFilter** = \\{ `events`: `string`[]; `ids?`: `string`[] \\| `null`; \\}\n\nEvent and optional entity-id constraints used to match webhook deliveries.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `events` | `string`[] | Event names matched by this filter. |\n| `ids?` | `string`[] \\| `null` | Entity ids matched by this filter. When absent, the filter matches all entity ids. |\n\n\n\n# Type Alias: WebhookScope\n\n> **WebhookScope** = `\"user\"` \\| `\"team\"`\n\nScope that owns a newly-created webhook.\n\nClients serialize this, so both derives are used. `Display`/`FromStr`\nspell the same names as serde, for query strings and config values.\n\n\n\n# Interface: MacroOpts\n\nOptions passed to `new Macro(opts)` and stored on `MacroClient`.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `auth?` | [`MacroAuth`](../type-aliases/MacroAuth.md) | How to authenticate. Takes precedence over `token`. Falls back to `MACRO_API_KEY` (a user API key or bearer token) or `MACRO_BOT_TOKEN` (bot). |\n| `env?` | [`Env`](../type-aliases/Env.md) | Which Macro environment to talk to. Falls back to the MACRO_ENV env var, then `'prod'`. |\n| `hosts?` | `Partial`\\<`Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\> | Override individual service hosts (e.g. point one at localhost). |\n| `onRequest?` | (`event`) => `void` | Optional generated API operation events; excludes arguments, URLs and response data. |\n| `requestedAs?` | `string` | User id the bot acts for, sent as `x-macro-bot-for-macro-user-id` on every request. Bot auth only. Set via `macro.requestedAs(user)` rather than directly. |\n| `token?` | [`TokenSource`](../type-aliases/TokenSource.md) | Shorthand for `auth: { type: 'user', token }`. Accepts a Settings API key (`mak_…`) or a bearer token. |\n| `webAppUrl?` | `string` | Override the web app base URL (e.g. for local frontend dev). Also reads MACRO_WEB_URL. |\n| `webhookSecret?` | `string` | Signing secret for verifying incoming persisted-webhook deliveries. Required only for `macro.events.webhook()` / `macro.events.handle()`. SSE via `macro.events.listen()` uses the API token and does not need this. Falls back to MACRO_WEBHOOK_SECRET. |\n| `wsVerify?` | `string` | - |\n\n\n\n# Type Alias: BotScope\n\n> **BotScope** = `\"user\"` \\| `\"team\"`\n\nAccess scope for bot-authenticated requests. `user` acts with the\nrequested-as user's access (requires `requestedAs`); `team` acts with the\nbot's owning team's access (team-owned bots only).\n\n\n\n# Type Alias: Env\n\n> **Env** = `\"dev\"` \\| `\"prod\"` \\| `\"local\"`\n\n\n\n# Type Alias: MacroAuth\n\n> **MacroAuth** = \\{ `apiKey?`: `never`; `token`: [`TokenSource`](TokenSource.md); `type`: `\"user\"`; \\} \\| \\{ `apiKey`: `string`; `token?`: `never`; `type`: `\"user\"`; \\} \\| \\{ `scope?`: [`BotScope`](BotScope.md); `token`: [`TokenSource`](TokenSource.md); `type`: `\"bot\"`; \\}\n\nHow the SDK authenticates with Macro.\n\nA user has exactly one of two credential fields.\n\n- `token`: a bearer token, or a `mak_` API key. The SDK picks the header\n from the prefix at send time.\n- `apiKey`: a Settings → API Keys key, always sent as\n `x-macro-user-api-key`. Not prefix-checked, so keys that predate the\n `mak_` prefix work here.\n\nA bot uses an `mbot_` token as `x-macro-bot-token` plus\n`x-macro-bot-scope`, defaulting to `user` when `requestedAs` is set and\n`team` otherwise.\n\n\n\n# Type Alias: ServiceName\n\n> **ServiceName** = `\"agent-harness\"` \\| `\"storage\"` \\| `\"auth\"` \\| `\"email\"` \\| `\"calendar\"` \\| `\"cognition\"` \\| `\"notification\"` \\| `\"properties\"` \\| `\"search\"` \\| `\"scheduled-action\"` \\| `\"static-files\"` \\| `\"connection\"` \\| `\"contacts\"` \\| `\"unfurl\"`\n\nThe backend services the SDK talks to. Note `search` and `properties` are\nserved on the storage host, so they point there.\n\n\n\n# Type Alias: TokenSource\n\n> **TokenSource** = `string` \\| (() => `string` \\| `Promise`\\<`string`\\>)\n\nA credential string, or a (possibly async) function that returns one.\n\n\n\n# Variable: HOSTS\n\n> `const` **HOSTS**: `Record`\\<[`Env`](../type-aliases/Env.md), `Record`\\<[`ServiceName`](../type-aliases/ServiceName.md), `string`\\>\\>\n\n\n\n# Variable: WEB\\_APP\\_URLS\n\n> `const` **WEB\\_APP\\_URLS**: `Record`\\<[`Env`](../type-aliases/Env.md), `string`\\>\n\n\n\n# Abstract Class: FavoritableEntity\\\n\nAn entity the favorites API can address, and so can be (un)favorited.\n\n## Extends\n\n- [`MacroEntity`](MacroEntity.md)\\<`Detail`\\>\n\n## Extended by\n\n- [`CallRecord`](../../calls/call-record/classes/CallRecord.md)\n- [`Message`](../../channels/message/classes/Message.md)\n- [`Contact`](../../crm/contact/classes/Contact.md)\n- [`PropertiedEntity`](PropertiedEntity.md)\n- [`ForeignEntity`](../../foreign/foreign-entity/classes/ForeignEntity.md)\n- [`WhatsAppGroup`](../../whatsapp/group/classes/WhatsAppGroup.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Implements\n\n- [`Favoritable`](../interfaces/Favoritable.md)\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `abstract readonly` | `\"project\"` \\| `\"user\"` \\| `\"team\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | How the entity-addressed APIs (favorites) identify this entity's type. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](MacroEntity.md).[`id`](MacroEntity.md#property-id) |\n\n## Methods\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Favoritable`](../interfaces/Favoritable.md).[`favorite`](../interfaces/Favoritable.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](MacroEntity.md).[`toJSON`](MacroEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`FavoritableEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Favoritable`](../interfaces/Favoritable.md).[`unfavorite`](../interfaces/Favoritable.md#unfavorite)\n\n\n\n# Abstract Class: MacroEntity\\\n\nBase for entity handles: a free-to-construct `(client, id)` pair whose\ndetail record loads lazily on first field access and is dropped after any\nmutation. Subclasses implement fetch and build their surface from\nfield and mutate.\n\n## Extended by\n\n- [`AgentSession`](../../agent-sessions/agent-session/classes/AgentSession.md)\n- [`CodeExecution`](../../agent-sessions/code-execution/classes/CodeExecution.md)\n- [`SessionReview`](../../agent-sessions/review/classes/SessionReview.md)\n- [`Agent`](../../agents/agent/classes/Agent.md)\n- [`UserApiKey`](../../api-keys/api-key/classes/UserApiKey.md)\n- [`Calendar`](../../calendar/calendar/classes/Calendar.md)\n- [`CalendarEvent`](../../calendar/event/classes/CalendarEvent.md)\n- [`CalendarNote`](../../calendar/note/classes/CalendarNote.md)\n- [`CallMessage`](../../calls/message/classes/CallMessage.md)\n- [`ChatMessage`](../../chats/generation/classes/ChatMessage.md)\n- [`CrmComment`](../../crm/comment/classes/CrmComment.md)\n- [`CrmPipeline`](../../crm/pipeline/classes/CrmPipeline.md)\n- [`PipelineTable`](../../crm/pipeline/classes/PipelineTable.md)\n- [`PipelineRow`](../../crm/pipeline/classes/PipelineRow.md)\n- [`PipelineColumn`](../../crm/pipeline/classes/PipelineColumn.md)\n- [`Database`](../../databases/database/classes/Database.md)\n- [`DocumentAnchor`](../../documents/anchor/classes/DocumentAnchor.md)\n- [`Comment`](../../documents/comment/classes/Comment.md)\n- [`EmailAttachment`](../../email/attachment/classes/EmailAttachment.md)\n- [`EmailFilter`](../../email/filter/classes/EmailFilter.md)\n- [`Label`](../../email/label/classes/Label.md)\n- [`Link`](../../email/link/classes/Link.md)\n- [`EmailMessage`](../../email/message/classes/EmailMessage.md)\n- [`FavoritableEntity`](FavoritableEntity.md)\n- [`Form`](../../forms/form/classes/Form.md)\n- [`GithubPullRequest`](../../github-pull-requests/pull-request/classes/GithubPullRequest.md)\n- [`Harness`](../../harnesses/harness/classes/Harness.md)\n- [`HarnessPairing`](../../harnesses/pairing/classes/HarnessPairing.md)\n- [`Initiative`](../../initiatives/initiative/classes/Initiative.md)\n- [`Meeting`](../../meetings/meeting/classes/Meeting.md)\n- [`MessageThread`](../../messages/thread/classes/MessageThread.md)\n- [`Notification`](../../notifications/notification/classes/Notification.md)\n- [`Routine`](../../routines/routine/classes/Routine.md)\n- [`AccessRequest`](../../sharing/access/classes/AccessRequest.md)\n- [`Team`](../../teams/team/classes/Team.md)\n- [`Webhook`](../../webhooks/webhook/classes/Webhook.md)\n- [`WhatsAppAccount`](../../whatsapp/account/classes/WhatsAppAccount.md)\n- [`WhatsAppChat`](../../whatsapp/chat/classes/WhatsAppChat.md)\n- [`WhatsAppMessage`](../../whatsapp/message/classes/WhatsAppMessage.md)\n- [`WhatsAppSend`](../../whatsapp/send/classes/WhatsAppSend.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `id` | `public readonly` | `string` |\n\n## Methods\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n\n\n# Abstract Class: PropertiedEntity\\\n\nA favoritable entity that also carries user-defined properties.\n\n## Extends\n\n- [`FavoritableEntity`](FavoritableEntity.md)\\<`Detail`\\>\n\n## Extended by\n\n- [`Channel`](../../channels/channel/classes/Channel.md)\n- [`Chat`](../../chats/chat/classes/Chat.md)\n- [`Company`](../../crm/company/classes/Company.md)\n- [`Document`](../../documents/document/classes/Document.md)\n- [`EmailThread`](../../email/thread/classes/EmailThread.md)\n- [`Project`](../../projects/project/classes/Project.md)\n- [`User`](../../users/user/classes/User.md)\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `Detail` |\n\n## Implements\n\n- [`Propertied`](../interfaces/Propertied.md)\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `entityType` | `abstract readonly` | `\"project\"` \\| `\"user\"` \\| `\"team\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"channel_message\"` \\| `\"document\"` \\| `\"email_thread\"` \\| `\"calendar_event\"` \\| `\"call\"` \\| `\"foreign_entity\"` \\| `\"static_file\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` \\| `\"crm_pipeline\"` \\| `\"reminder\"` \\| `\"skill\"` \\| `\"agent_session\"` \\| `\"scheduled_action\"` \\| `\"initiative\"` \\| `\"database\"` \\| `\"database_row\"` \\| `\"form\"` \\| `\"whatsapp_group\"` | How the entity-addressed APIs (favorites) identify this entity's type. | [`FavoritableEntity`](FavoritableEntity.md).[`entityType`](FavoritableEntity.md#property-entitytype) |\n| `id` | `public readonly` | `string` | - | [`FavoritableEntity`](FavoritableEntity.md).[`id`](FavoritableEntity.md#property-id) |\n\n## Methods\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\nRemove a property from this entity, given its [properties](#properties) entry.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`deleteProperty`](../interfaces/Propertied.md#deleteproperty)\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\nAdd this entity to the user's favorites. Returns this handle for chaining.\nPlain unwrap: favoriting alters the user's favorites collection, not this\nentity's own detail, so there's nothing cached to invalidate.\n\n#### Returns\n\n`Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`favorite`](../interfaces/Propertied.md#favorite)\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`favorite`](FavoritableEntity.md#favorite)\n\n***\n\n### permission()\n\n> **permission**(): `Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\nRead the caller's effective permission on this entity.\n\n#### Returns\n\n`Promise`\\<\\{ `permission`: [`EntityPermission`](../../../../generated/storage/types.gen/type-aliases/EntityPermission.md); `status`: `\"access\"`; \\} \\| \\{ `status`: `\"no_access\"`; \\}\\>\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`permission`](FavoritableEntity.md#permission)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\nThe properties set on this entity, each with its definition, value, and options.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`properties`](../interfaces/Propertied.md#properties)\n\n***\n\n### propertyReference()\n\n> **propertyReference**(): [`PropertyTargetReference`](../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\nThis entity's reference for bulk property operations.\n\n#### Returns\n\n[`PropertyTargetReference`](../../../../generated/properties/types.gen/type-aliases/PropertyTargetReference.md)\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\nSet a property value on this entity, or attach the property without a\nvalue when `value` is omitted.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`setProperty`](../interfaces/Propertied.md#setproperty)\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: `Detail`; `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | `Detail` |\n| `id` | `string` |\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`toJSON`](FavoritableEntity.md#tojson)\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\nRemove this entity from the user's favorites. Returns this handle for chaining.\n\n#### Returns\n\n`Promise`\\<`PropertiedEntity`\\<`Detail`\\>\\>\n\n#### Implementation of\n\n[`Propertied`](../interfaces/Propertied.md).[`unfavorite`](../interfaces/Propertied.md#unfavorite)\n\n#### Inherited from\n\n[`FavoritableEntity`](FavoritableEntity.md).[`unfavorite`](FavoritableEntity.md#unfavorite)\n\n***\n\n### updatePropertyOptions()\n\n> **updatePropertyOptions**(`changes`): `Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\nApply multi-select option deltas atomically across this entity's properties.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `changes` | [`PropertyOptionDelta`](../interfaces/PropertyOptionDelta.md)[] |\n\n#### Returns\n\n`Promise`\\<[`BulkUpdateEntityPropertyOptionsResponse`](../../../../generated/properties/types.gen/type-aliases/BulkUpdateEntityPropertyOptionsResponse.md)\\>\n\n\n\n# Interface: Favoritable\n\nAn entity that can be added to and removed from the user's favorites.\n\n## Extended by\n\n- [`Propertied`](Propertied.md)\n\n## Methods\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Favoritable`\\>\n\n#### Returns\n\n`Promise`\\<`Favoritable`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Favoritable`\\>\n\n#### Returns\n\n`Promise`\\<`Favoritable`\\>\n\n\n\n# Interface: Propertied\n\nA favoritable entity that also carries user-defined properties.\n\n## Extends\n\n- [`Favoritable`](Favoritable.md)\n\n## Methods\n\n### deleteProperty()\n\n> **deleteProperty**(`assignment`): `Promise`\\<`void`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `assignment` | [`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### favorite()\n\n> **favorite**(): `Promise`\\<`Propertied`\\>\n\n#### Returns\n\n`Promise`\\<`Propertied`\\>\n\n#### Inherited from\n\n[`Favoritable`](Favoritable.md).[`favorite`](Favoritable.md#favorite)\n\n***\n\n### properties()\n\n> **properties**(`opts?`): `Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | \\{ `includeMetadata?`: `boolean`; \\} |\n| `opts.includeMetadata?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<[`EntityPropertyWithDefinition`](../../../../generated/properties/types.gen/type-aliases/EntityPropertyWithDefinition.md)[]\\>\n\n***\n\n### setProperty()\n\n> **setProperty**(`property`, `value?`): `Promise`\\<`void`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) |\n| `value?` | [`SetPropertyValue`](../../../../generated/properties/types.gen/type-aliases/SetPropertyValue.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### unfavorite()\n\n> **unfavorite**(): `Promise`\\<`Propertied`\\>\n\n#### Returns\n\n`Promise`\\<`Propertied`\\>\n\n#### Inherited from\n\n[`Favoritable`](Favoritable.md).[`unfavorite`](Favoritable.md#unfavorite)\n\n\n\n# Interface: PropertyOptionDelta\n\nA delta to apply to one multi-select property.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `add?` | [`PropertyOption`](../../properties/property-option/classes/PropertyOption.md)[] | Options to add to the property's current selection. |\n| `property` | [`PropertyDefinition`](../../properties/property-definition/classes/PropertyDefinition.md) | The multi-select property definition to update. |\n| `remove?` | [`PropertyOption`](../../properties/property-option/classes/PropertyOption.md)[] | Options to remove from the property's current selection. |\n\n\n\n# Type Alias: MacroEntityType\n\n> **MacroEntityType** = [`FavoriteEntityRef`](../../../../generated/storage/types.gen/type-aliases/FavoriteEntityRef.md)\\[`\"entityType\"`\\]\n\nHow the entity-addressed APIs (favorites) identify an entity's type.\n\n\n\n# Class: MessageThread\n\nA shared message thread with resolution and deletion operations.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `parent` | `readonly` | [`MessageParent`](../type-aliases/MessageParent.md) | The entity containing this thread. | - |\n| `resolved` | `readonly` | () => `Promise`\\<`boolean`\\> | Whether the thread is resolved. | - |\n\n## Methods\n\n### delete()\n\n> **delete**(`nonce?`): `Promise`\\<`void`\\>\n\nDelete the entire thread, including replies.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `nonce?` | `string` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md); `id`: `string`; `parentId`: `string`; `parentType`: `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"`; \\}\n\nSerialize identity with its owning resource.\n\n#### Returns\n\n\\{ `detail?`: [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md); `id`: `string`; `parentId`: `string`; `parentType`: `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`ThreadState`](../../../../../generated/storage/types.gen/type-aliases/ThreadState.md) |\n| `id` | `string` |\n| `parentId` | `string` |\n| `parentType` | `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"crm_company\"` \\| `\"crm_contact\"` |\n\n#### Overrides\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### update()\n\n> **update**(`options`): `Promise`\\<`void`\\>\n\nResolve the thread or detach its annotation anchor.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options` | \\{ `detachAnchor?`: `boolean`; `nonce?`: `string`; `resolved?`: `boolean`; \\} |\n| `options.detachAnchor?` | `boolean` |\n| `options.nonce?` | `string` |\n| `options.resolved?` | `boolean` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### byId()\n\n> `static` **byId**(`client`, `parent`, `id`): `MessageThread`\n\nConstruct a scoped thread handle.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `parent` | [`MessageParent`](../type-aliases/MessageParent.md) |\n| `id` | `string` |\n\n#### Returns\n\n`MessageThread`\n\n\n\n# Function: timeline()\n\n> **timeline**\\<`TMessage`\\>(`client`, `parent`, `map`, `selection?`): `Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: `TMessage`; `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\nA bounded mixed message/activity page with typed message handles.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `TMessage` *extends* [`TimelineMessage`](../type-aliases/TimelineMessage.md) |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `parent` | [`MessageParent`](../type-aliases/MessageParent.md) |\n| `map` | (`record`) => `TMessage` |\n| `selection?` | [`TimelineOptions`](../interfaces/TimelineOptions.md)\\<`TMessage`\\> |\n\n## Returns\n\n`Promise`\\<\\{ `entries`: (\\{ `activity`: \\{ `action`: `string`; `actor`: [`User`](../../../users/user/classes/User.md); `actor_id`: `string`; `id`: `string`; `occurred_at`: `string`; `payload?`: `unknown`; \\}; `message?`: `undefined`; `type`: `\"activity\"`; \\} \\| \\{ `activity?`: `undefined`; `message`: `TMessage`; `type`: `\"message\"`; \\})[]; `nextCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; `previousCursor`: [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `undefined`; \\}\\>\n\n\n\n# Interface: TimelineOptions\\\n\nTimeline selection with typed message references and camel case options.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `TMessage` *extends* [`TimelineMessage`](../type-aliases/TimelineMessage.md) | [`TimelineMessage`](../type-aliases/TimelineMessage.md) |\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `activityAfter?` | `string` | Inclusive activity lower bound. |\n| `activityBefore?` | `string` | Exclusive activity upper bound. |\n| `anchored?` | `boolean` | Select anchored threads. |\n| `around?` | `TMessage` | Fetch around this message. |\n| `cursor?` | [`MessageCursor`](../../../../../generated/storage/types.gen/type-aliases/MessageCursor.md) \\| `null` | Opaque continuation cursor from a previous page. |\n| `direction?` | [`MessageDirection`](../../../../../generated/storage/types.gen/type-aliases/MessageDirection.md) | Page direction. |\n| `includeDeletedThreads?` | `boolean` | Include deleted threads. |\n| `limit?` | `number` | Page size. |\n| `messages?` | `TMessage`[] | Restrict selection to these messages. |\n\n\n\n# Type Alias: MessageParent\n\n> **MessageParent** = \\{ `entity`: [`Channel`](../../../channels/channel/classes/Channel.md); `type`: `\"channel\"`; \\} \\| \\{ `entity`: [`Document`](../../../documents/document/classes/Document.md); `type`: `\"document\"`; \\} \\| \\{ `entity`: [`Company`](../../../crm/company/classes/Company.md); `type`: `\"crm_company\"`; \\} \\| \\{ `entity`: [`Contact`](../../../crm/contact/classes/Contact.md); `type`: `\"crm_contact\"`; \\} \\| \\{ `entity`: [`CallRecord`](../../../calls/call-record/classes/CallRecord.md); `type`: `\"call\"`; \\}\n\nThe typed parent of a shared message thread.\n\n\n\n# Type Alias: TimelineMessage\n\n> **TimelineMessage** = [`Message`](../../../channels/message/classes/Message.md) \\| [`Comment`](../../../documents/comment/classes/Comment.md) \\| [`CrmComment`](../../../crm/comment/classes/CrmComment.md) \\| [`CallMessage`](../../../calls/message/classes/CallMessage.md)\n\nA message handle accepted by a mixed timeline selector.\n\n\n\n# Type Alias: EntityReference\n\n> **EntityReference** = \\{ `entity`: [`User`](../../users/user/classes/User.md); `type`: `\"user\"`; \\} \\| \\{ `entity`: [`Team`](../../teams/team/classes/Team.md); `type`: `\"team\"`; \\} \\| \\{ `entity`: [`Document`](../../documents/document/classes/Document.md); `type`: `\"document\"`; \\} \\| \\{ `entity`: [`Chat`](../../chats/chat/classes/Chat.md); `type`: `\"chat\"`; \\} \\| \\{ `entity`: [`Channel`](../../channels/channel/classes/Channel.md); `type`: `\"channel\"`; \\} \\| \\{ `entity`: [`Message`](../../channels/message/classes/Message.md); `type`: `\"channel_message\"`; \\} \\| \\{ `entity`: [`Project`](../../projects/project/classes/Project.md); `type`: `\"project\"`; \\} \\| \\{ `entity`: [`EmailThread`](../../email/thread/classes/EmailThread.md); `type`: `\"email_thread\"`; \\} \\| \\{ `entity`: [`CalendarEvent`](../../calendar/event/classes/CalendarEvent.md); `type`: `\"calendar_event\"`; \\} \\| \\{ `entity`: [`CallRecord`](../../calls/call-record/classes/CallRecord.md); `type`: `\"call\"`; \\} \\| \\{ `entity`: [`ForeignEntity`](../../foreign/foreign-entity/classes/ForeignEntity.md); `type`: `\"foreign_entity\"`; \\} \\| \\{ `entity`: [`Company`](../../crm/company/classes/Company.md); `type`: `\"crm_company\"`; \\} \\| \\{ `entity`: [`Contact`](../../crm/contact/classes/Contact.md); `type`: `\"crm_contact\"`; \\} \\| \\{ `entity`: [`CrmPipeline`](../../crm/pipeline/classes/CrmPipeline.md); `type`: `\"crm_pipeline\"`; \\} \\| \\{ `entity`: [`AgentSession`](../../agent-sessions/agent-session/classes/AgentSession.md); `type`: `\"agent_session\"`; \\} \\| \\{ `entity`: [`Routine`](../../routines/routine/classes/Routine.md); `type`: `\"scheduled_action\"`; \\} \\| \\{ `entity`: [`Initiative`](../../initiatives/initiative/classes/Initiative.md); `type`: `\"initiative\"`; \\} \\| \\{ `entity`: [`Database`](../../databases/database/classes/Database.md); `type`: `\"database\"`; \\} \\| \\{ `entity`: [`DatabaseRow`](../../databases/row/classes/DatabaseRow.md); `type`: `\"database_row\"`; \\} \\| \\{ `entity`: [`Form`](../../forms/form/classes/Form.md); `type`: `\"form\"`; \\}\n\nTyped entity references accepted by cross-resource APIs.\n\n\n\n# Function: entitySearch()\n\n> **entitySearch**\\<`T`, `K`\\>(`opts`): (`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`T`\\>\n\nBuild a `search(client, query, opts?)` function for one entity type: unified\nsearch hits narrowed to `type`, each mapped through `make`.\nMost relevant first, auto-paginated.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `T` |\n| `K` *extends* `\"email\"` \\| `\"project\"` \\| `\"chat\"` \\| `\"channel\"` \\| `\"document\"` \\| `\"call\"` \\| `\"company\"` \\| `\"calendarEvent\"` \\| `\"agentSession\"` \\| `\"channelMessage\"` |\n\n## Parameters\n\n| Parameter | Type | Description |\n| ------ | ------ | ------ |\n| `opts` | \\{ `filters?`: [`EntityFilters`](../../../../generated/search/types.gen/type-aliases/EntityFilters.md); `includeCrm?`: `boolean`; `make`: (`client`, `hit`) => `T`; `type`: `K`; \\} | - |\n| `opts.filters?` | [`EntityFilters`](../../../../generated/search/types.gen/type-aliases/EntityFilters.md) | - |\n| `opts.includeCrm?` | `boolean` | Opt in to CRM results (off by default server-side; required for company hits). |\n| `opts.make` | (`client`, `hit`) => `T` | - |\n| `opts.type` | `K` | - |\n\n## Returns\n\n(`client`, `query`, `searchOpts?`) => `AsyncGenerator`\\<`T`\\>\n\n\n\n# Interface: SearchOpts\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `pageSize?` | `number` |\n| `searchOn?` | [`SearchOn`](../type-aliases/SearchOn.md) |\n\n\n\n# Type Alias: SearchOn\n\n> **SearchOn** = `\"name\"` \\| `\"content\"` \\| `\"name_content\"`\n\n\n\n# Class: AccessRequest\n\nOne access request; resolutions preserve optimistic concurrency.\n\n## Extends\n\n- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\n## Properties\n\n| Property | Modifier | Type | Description | Inherited from |\n| ------ | ------ | ------ | ------ | ------ |\n| `access` | `readonly` | [`EntityAccess`](EntityAccess.md) | Entity access surface owning the request. | - |\n| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |\n| `requestedLevel` | `readonly` | () => `Promise`\\<[`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)\\> | Requested access. | - |\n| `requester` | `readonly` | () => `Promise`\\<[`User`](../../../users/user/classes/User.md)\\> | Requesting user. | - |\n| `revision` | `readonly` | () => `Promise`\\<`number`\\> | Request revision. | - |\n| `status` | `readonly` | () => `Promise`\\<[`RequestStatus`](../../../../../generated/storage/types.gen/type-aliases/RequestStatus.md)\\> | Current request state. | - |\n\n## Methods\n\n### resolve()\n\n> **resolve**(`grantedLevel?`): `Promise`\\<`void`\\>\n\nApprove with an access level, or decline by omitting it.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `grantedLevel?` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `detail?`: [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md); `id`: `string`; \\}\n\n#### Returns\n\n\\{ `detail?`: [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md); `id`: `string`; \\}\n\n| Name | Type |\n| ------ | ------ |\n| `detail?` | [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md) |\n| `id` | `string` |\n\n#### Inherited from\n\n[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)\n\n***\n\n### from()\n\n> `static` **from**(`client`, `access`, `record`): `AccessRequest`\n\nSeed a request from a state or submission response.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `access` | [`EntityAccess`](EntityAccess.md) |\n| `record` | [`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md) |\n\n#### Returns\n\n`AccessRequest`\n\n\n\n# Class: EntityAccess\n\nAccess requests and direct grants scoped to a shareable entity.\n\n## Constructors\n\n### Constructor\n\n> **new EntityAccess**(`client`, `entityType`, `entity`): `EntityAccess`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `entityType` | [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md) |\n| `entity` | \\{ `id`: `string`; \\} |\n| `entity.id` | `string` |\n\n#### Returns\n\n`EntityAccess`\n\n## Methods\n\n### cancel()\n\n> **cancel**(`revision`): `Promise`\\<`void`\\>\n\nCancel the caller's own request at its observed revision.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `revision` | `number` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### direct()\n\n> **direct**(): `Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `user`: [`User`](../../../users/user/classes/User.md); \\}[]\\>\n\nDirect grants expressed as user handles.\n\n#### Returns\n\n`Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `user`: [`User`](../../../users/user/classes/User.md); \\}[]\\>\n\n***\n\n### grant()\n\n> **grant**(`user`, `accessLevel?`): `Promise`\\<`void`\\>\n\nGrant direct access, or remove it by omitting the access level.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../../users/user/classes/User.md) |\n| `accessLevel?` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### remove()\n\n> **remove**(`user`): `Promise`\\<`void`\\>\n\nRemove one user's direct grant.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../../users/user/classes/User.md) |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n***\n\n### resolve()\n\n> **resolve**(`request`, `resolution`): `Promise`\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\nResolve a request belonging to this entity at an observed revision.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `request` | [`AccessRequest`](AccessRequest.md) |\n| `resolution` | [`ResolveRequest`](../../../../../generated/storage/types.gen/type-aliases/ResolveRequest.md) |\n\n#### Returns\n\n`Promise`\\<[`AccessRequest`](../../../../../generated/storage/types.gen/type-aliases/AccessRequest.md)\\>\n\n***\n\n### state()\n\n> **state**(`offset?`): `Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) \\| `undefined`; `canReview`: `boolean`; `mine`: [`AccessRequest`](AccessRequest.md) \\| `undefined`; `nextOffset`: `number` \\| `undefined`; `owner`: [`User`](../../../users/user/classes/User.md) \\| `undefined`; `pendingCount`: `number`; `requests`: [`AccessRequest`](AccessRequest.md)[]; `supportedLevels`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)[]; \\}\\>\n\nA page of access requests, including the caller's own request and review rights.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `offset?` | `number` |\n\n#### Returns\n\n`Promise`\\<\\{ `accessLevel`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) \\| `undefined`; `canReview`: `boolean`; `mine`: [`AccessRequest`](AccessRequest.md) \\| `undefined`; `nextOffset`: `number` \\| `undefined`; `owner`: [`User`](../../../users/user/classes/User.md) \\| `undefined`; `pendingCount`: `number`; `requests`: [`AccessRequest`](AccessRequest.md)[]; `supportedLevels`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md)[]; \\}\\>\n\n***\n\n### submit()\n\n> **submit**(`requestedLevel`, `revision?`): `Promise`\\<[`AccessRequest`](AccessRequest.md)\\>\n\nRequest access, optionally naming the revision of an earlier request.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `requestedLevel` | [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md) |\n| `revision?` | `number` |\n\n#### Returns\n\n`Promise`\\<[`AccessRequest`](AccessRequest.md)\\>\n\n***\n\n### toJSON()\n\n> **toJSON**(): \\{ `entity_id`: `string`; `entity_type`: [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md); \\}\n\nSerialize the entity reference without credentials.\n\n#### Returns\n\n\\{ `entity_id`: `string`; `entity_type`: [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md); \\}\n\n| Name | Type |\n| ------ | ------ |\n| `entity_id` | `string` |\n| `entity_type` | [`ShareEntityType`](../../../../../generated/storage/types.gen/type-aliases/ShareEntityType.md) |\n\n\n\n# Function: sharePermissionBody()\n\n> **sharePermissionBody**(`options`): [`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md)\n\nConvert sharing options into the generated backend contract.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `options` | [`SharePermissionOptions`](../type-aliases/SharePermissionOptions.md) |\n\n## Returns\n\n[`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md)\n\n\n\n# Type Alias: SharePermissionOptions\n\n> **SharePermissionOptions** = `Omit`\\<[`UpdateSharePermissionRequestV2`](../../../../../generated/storage/types.gen/type-aliases/UpdateSharePermissionRequestV2.md), `\"channelSharePermissions\"`\\> & \\{ `channelSharePermissions?`: \\{ `accessLevel?`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `channel`: [`Channel`](../../../channels/channel/classes/Channel.md); `operation`: [`UpdateChannelSharePermission`](../../../../../generated/storage/types.gen/type-aliases/UpdateChannelSharePermission.md)\\[`\"operation\"`\\]; \\}[] \\| `null`; \\}\n\nSharing updates reference channels by handle. Null clears the corresponding grant collection.\n\n## Type Declaration\n\n| Name | Type | Description |\n| ------ | ------ | ------ |\n| `channelSharePermissions?` | \\{ `accessLevel?`: [`AccessLevel`](../../../../../generated/storage/types.gen/type-aliases/AccessLevel.md); `channel`: [`Channel`](../../../channels/channel/classes/Channel.md); `operation`: [`UpdateChannelSharePermission`](../../../../../generated/storage/types.gen/type-aliases/UpdateChannelSharePermission.md)\\[`\"operation\"`\\]; \\}[] \\| `null` | Channel grants to create or replace. |\n\n\n\n# Class: MacroEvents\n\nPer-instance event receiver. Subscribe with [MacroEvents.on](#on), then\neither [MacroEvents.listen](#listen) (SSE, the default) or mount\n[MacroEvents.webhook](#webhook) at a persisted webhook URL.\n\nObtain via `macro.events` — do not construct directly.\n\n## Constructors\n\n### Constructor\n\n> **new MacroEvents**(`client`, `secret?`): `MacroEvents`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `client` | `MacroClient` |\n| `secret?` | `string` |\n\n#### Returns\n\n`MacroEvents`\n\n## Methods\n\n### handle()\n\n> **handle**(`rawBody`, `headers`): `Promise`\\<`void`\\>\n\nFeed a raw webhook delivery in: verifies the signature, parses, and\ndispatches to matching handlers.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `rawBody` | `string` |\n| `headers` | `DeliveryHeaders` |\n\n#### Returns\n\n`Promise`\\<`void`\\>\n\n#### Throws\n\nif no signing secret was configured, or if the\n signature is missing or invalid.\n\n***\n\n### listen()\n\n> **listen**(`opts?`): `Promise`\\<() => `void`\\>\n\nOpen a live Server-Sent Events stream of matching broker events. This is\nthe default way to receive events — no public URL or signing secret\nrequired. Delivery is best-effort: events published before the\nconnection, while disconnected, or dropped for a slow subscriber are\nmissed; there is no replay.\n\nFilters default to the event names currently registered with [on](#on).\nThe stream uses those filters for its lifetime; later `.on` / unsubscribe\ncalls do not change what the server sends.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts?` | [`ListenOptions`](../interfaces/ListenOptions.md) |\n\n#### Returns\n\n`Promise`\\<() => `void`\\>\n\nA function that closes the stream.\n\n***\n\n### on()\n\n> **on**\\<`E`\\>(`event`, `handler`): () => `void`\n\nSubscribe to an event across all entities.\n\n#### Type Parameters\n\n| Type Parameter |\n| ------ |\n| `E` *extends* `\"agent_session.opened\"` \\| `\"agent_session.turn_started\"` \\| `\"agent_session.turn_ended\"` \\| `\"agent_session.command_rejected\"` \\| `\"agent_session.settled\"` \\| `\"agent_session.waiting_for_input\"` \\| `\"agent_session.input_received\"` \\| `\"agent_session.mentioned\"` \\| `\"agent_session.stopped\"` \\| `\"agent_session.renamed\"` \\| `\"agent_session.deleted\"` \\| `\"channel.picture_changed\"` \\| `\"channel.created\"` \\| `\"channel.updated\"` \\| `\"channel.deleted\"` \\| `\"channel.participant_added\"` \\| `\"channel.participant_removed\"` \\| `\"document.created\"` \\| `\"document.updated\"` \\| `\"document.deleted\"` \\| `\"document.content_uploaded\"` \\| `\"document.sync_content_updated\"` \\| `\"document.purged\"` \\| `\"document.copied\"` \\| `\"document.interaction\"` \\| `\"message.posted\"` \\| `\"message.patched\"` \\| `\"message.deleted\"` \\| `\"message.mentioned\"` \\| `\"message.attachment_created\"` \\| `\"message.attachment_removed\"` |\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `event` | `E` |\n| `handler` | `EventHandler`\\<`E`\\> |\n\n#### Returns\n\nAn unsubscribe function.\n\n() => `void`\n\n***\n\n### onSelfMention()\n\n> **onSelfMention**(`handler`): () => `void`\n\nSubscribe to @-mentions of the authenticated caller: `message.mentioned`\ndeliveries whose mentioned entity is this bot (bot auth) or this user\n(user auth), in channels and in document comments alike.\n\n`message.mentioned` deliveries cover every mention the stream's (or\nwebhook's) workspace can access (its `ids` filter holds channel or\ndocument ids); picking out \"me\" happens here, client-side. The caller's\nidentity is resolved lazily (once) on the first delivery.\n\nFor SSE, register this handler before [listen](#listen) so the derived\nfilters include `message.mentioned`. For persisted webhooks, register the\nwebhook separately, e.g. `macro.webhooks.create({ filters: [{ events:\n['message.mentioned'] }], … })`.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `handler` | `EventHandler`\\<`\"message.mentioned\"`\\> |\n\n#### Returns\n\nAn unsubscribe function.\n\n() => `void`\n\n***\n\n### webhook()\n\n> **webhook**(): (`req`) => `Promise`\\<`Response`\\>\n\nA Fetch-style handler to mount at your persisted webhook route.\n\nRequires `webhookSecret` (or `MACRO_WEBHOOK_SECRET`).\n\n#### Returns\n\n(`req`) => `Promise`\\<`Response`\\>\n\n#### Example\n\n```ts\napp.post('/webhook', macro.events.webhook()); // Hono\n```\n\n\n\n# Interface: ListenOptions\n\nOptions for [MacroEvents.listen](../classes/MacroEvents.md#listen).\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `filters?` | [`WebhookFilter`](../../../../generated/storage/types.gen/type-aliases/WebhookFilter.md)[] | Event/entity-id filters, identical to persisted webhook `filters`. Defaults to one filter covering every event currently registered with [MacroEvents.on](../classes/MacroEvents.md#on). |\n| `scope?` | [`WebhookScope`](../../../../generated/storage/types.gen/type-aliases/WebhookScope.md) | Personal or team workspace whose webhook lifecycle events are delivered. Defaults to `'user'`. |\n| `signal?` | `AbortSignal` | Abort the stream. |\n\n\n\n# Class: Macro\\\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` *extends* [`MacroOpts`](../../config/interfaces/MacroOpts.md) | [`MacroOpts`](../../config/interfaces/MacroOpts.md) |\n\n## Constructors\n\n### Constructor\n\n> **new Macro**\\<`T`\\>(`opts`): `Macro`\\<`T`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `opts` | `T` |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n## Properties\n\n| Property | Modifier | Type | Description |\n| ------ | ------ | ------ | ------ |\n| `_client` | `readonly` | `MacroClient` | Direct access to the underlying hey-api service clients. |\n| `agents` | `readonly` | [`AgentNamespace`](../../entities/agents/namespace/classes/AgentNamespace.md) | agents resources and operations. |\n| `agentSessions` | `readonly` | [`AgentSessionNamespace`](../../entities/agent-sessions/namespace/classes/AgentSessionNamespace.md) | - |\n| `ai` | `readonly` | [`AiNamespace`](../../entities/ai/namespace/classes/AiNamespace.md) | - |\n| `apiKeys` | `readonly` | [`ApiKeyNamespace`](../../entities/api-keys/namespace/classes/ApiKeyNamespace.md) | apiKeys resources and operations. |\n| `bots` | `readonly` | [`BotsNamespace`](../../entities/bots/namespace/classes/BotsNamespace.md) | - |\n| `calendar` | `readonly` | [`CalendarNamespace`](../../entities/calendar/namespace/classes/CalendarNamespace.md) | - |\n| `calls` | `readonly` | [`CallRecordNamespace`](../../entities/calls/namespace/classes/CallRecordNamespace.md) | - |\n| `channels` | `readonly` | [`ChannelNamespace`](../../entities/channels/namespace/classes/ChannelNamespace.md) | - |\n| `crm` | `readonly` | [`CrmNamespace`](../../entities/crm/namespace/classes/CrmNamespace.md) | - |\n| `databases` | `readonly` | [`DatabaseNamespace`](../../entities/databases/namespace/classes/DatabaseNamespace.md) | - |\n| `documents` | `readonly` | [`DocumentNamespace`](../../entities/documents/namespace/classes/DocumentNamespace.md) | - |\n| `email` | `readonly` | [`EmailNamespace`](../../entities/email/namespace/classes/EmailNamespace.md) | - |\n| `entityMentions` | `readonly` | [`EntityMentionNamespace`](../../entities/entity-mentions/namespace/classes/EntityMentionNamespace.md) | entityMentions resources and operations. |\n| `events` | `readonly` | [`MacroEvents`](../../events/receiver/classes/MacroEvents.md) | - |\n| `favorites` | `readonly` | [`FavoritesNamespace`](../../entities/favorites/namespace/classes/FavoritesNamespace.md) | - |\n| `foreignEntities` | `readonly` | [`ForeignEntityNamespace`](../../entities/foreign/namespace/classes/ForeignEntityNamespace.md) | - |\n| `forms` | `readonly` | [`FormNamespace`](../../entities/forms/namespace/classes/FormNamespace.md) | Build forms and submit answers without granting respondents database access. |\n| `githubPullRequests` | `readonly` | [`GithubPullRequestNamespace`](../../entities/github-pull-requests/namespace/classes/GithubPullRequestNamespace.md) | githubPullRequests resources and operations. |\n| `harnesses` | `readonly` | [`HarnessNamespace`](../../entities/harnesses/namespace/classes/HarnessNamespace.md) | harnesses resources and operations. |\n| `initiatives` | `readonly` | [`InitiativeNamespace`](../../entities/initiatives/namespace/classes/InitiativeNamespace.md) | initiatives resources and operations. |\n| `meetings` | `readonly` | [`MeetingNamespace`](../../entities/meetings/namespace/classes/MeetingNamespace.md) | meetings resources and operations. |\n| `notifications` | `readonly` | [`NotificationNamespace`](../../entities/notifications/namespace/classes/NotificationNamespace.md) | - |\n| `pins` | `readonly` | [`PinsNamespace`](../../entities/pins/namespace/classes/PinsNamespace.md) | - |\n| `projects` | `readonly` | [`ProjectNamespace`](../../entities/projects/namespace/classes/ProjectNamespace.md) | - |\n| `properties` | `readonly` | [`PropertiesNamespace`](../../entities/properties/namespace/classes/PropertiesNamespace.md) | - |\n| `routines` | `readonly` | [`RoutineNamespace`](../../entities/routines/namespace/classes/RoutineNamespace.md) | routines resources and operations. |\n| `tasks` | `readonly` | [`TaskNamespace`](../../entities/tasks/namespace/classes/TaskNamespace.md) | - |\n| `teams` | `readonly` | [`TeamNamespace`](../../entities/teams/namespace/classes/TeamNamespace.md) | - |\n| `unfurls` | `readonly` | [`UnfurlNamespace`](../../entities/unfurls/namespace/classes/UnfurlNamespace.md) | unfurls resources and operations. |\n| `users` | `readonly` | [`UserNamespace`](../../entities/users/namespace/classes/UserNamespace.md) | - |\n| `webAppUrl` | `readonly` | `string` | Base URL of the Macro web app, used to build entity URLs. |\n| `webhooks` | `readonly` | [`WebhooksNamespace`](../../entities/webhooks/namespace/classes/WebhooksNamespace.md) | - |\n| `whatsapp` | `readonly` | [`WhatsAppNamespace`](../../entities/whatsapp/namespace/classes/WhatsAppNamespace.md) | Personal WhatsApp groups and shared group operations. |\n\n## Methods\n\n### myPrincipalId()\n\n> **myPrincipalId**(): `Promise`\\<`string`\\>\n\nThe authenticated caller's mentionable principal — `bot|` for bot\nauth, `macro|` for user auth — fetched once and cached.\n\n#### Returns\n\n`Promise`\\<`string`\\>\n\n***\n\n### requestedAs()\n\n> **requestedAs**(`user`): `Macro`\\<`T`\\>\n\nClone of this SDK acting on behalf of `user` (sent as\n`x-macro-bot-for-macro-user-id`). Bot auth only — throws for user auth,\nsince a user token always acts as its own user.\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `user` | [`User`](../../entities/users/user/classes/User.md) |\n\n#### Returns\n\n`Macro`\\<`T`\\>\n\n\n\n# Type Alias: RequestActivity\n\n> **RequestActivity** = \\{ `id`: `number`; `operation`: `string`; `service`: `string`; `status`: `\"started\"` \\| `\"completed\"` \\| `\"failed\"`; \\}\n\nA generated SDK operation lifecycle. Contains no arguments, URLs or response data.\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `id` | `number` |\n| `operation` | `string` |\n| `service` | `string` |\n| `status` | `\"started\"` \\| `\"completed\"` \\| `\"failed\"` |\n\n\n\n# Function: msg()\n\n> **msg**(`strings`, ...`values`): [`RichMessage`](../interfaces/RichMessage.md)\n\nCompose a rich message. Interpolate mentions (a User, Document,\n[here](../variables/here.md), …) or plain strings. Each mention writes its `` tag into the\ncontent *and* adds itself to `mentions[]`, so the two can never drift; strings\nare inserted as-is, so markdown like `**bold**` passes through untouched.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `strings` | `TemplateStringsArray` |\n| ...`values` | [`Interpolation`](../type-aliases/Interpolation.md)[] |\n\n## Returns\n\n[`RichMessage`](../interfaces/RichMessage.md)\n\n## Example\n\n```ts\nchannel.send(msg`Hey ${user}, see ${doc}. cc ${here}`);\nchannel.send(msg`Status: ${status} — see ${doc}`);\n```\n\n\n\n# Function: toBody()\n\n> **toBody**(`body`): [`RichMessage`](../interfaces/RichMessage.md)\n\nNormalize a plain string or a [RichMessage](../interfaces/RichMessage.md) to the wire shape.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `body` | `string` \\| [`RichMessage`](../interfaces/RichMessage.md) |\n\n## Returns\n\n[`RichMessage`](../interfaces/RichMessage.md)\n\n\n\n# Function: wrapXml()\n\n> **wrapXml**(`tag`, `data`): `string`\n\nSerialize a mention node to its `{json} ` wire form. Readers take\neverything up to the first closing tag, so `<`, `>` and `&` in the JSON are\nwritten as `\\u` escapes: a document named `` would\notherwise end the tag early. Decoding the JSON restores the original text.\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `tag` | `string` |\n| `data` | `unknown` |\n\n## Returns\n\n`string`\n\n\n\n# Interface: MentionPart\n\nThe two things a mentionable entity contributes to a message.\n\n## Properties\n\n| Property | Type | Description |\n| ------ | ------ | ------ |\n| `mention` | [`SimpleMention`](../../../generated/storage/types.gen/type-aliases/SimpleMention.md) | The parallel entry the backend uses for notifications and permissions. |\n| `tag` | `string` | The `` tag written into the message content. |\n\n\n\n# Interface: Mentionable\n\nAnything that can be dropped into a [msg](../functions/msg.md) template as a mention.\n\n## Methods\n\n### toMention()\n\n> **toMention**(): [`MentionPart`](MentionPart.md)\n\n#### Returns\n\n[`MentionPart`](MentionPart.md)\n\n\n\n# Interface: RichMessage\n\nA composed message body: content with embedded tags, and the matching mentions.\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `content` | `string` |\n| `mentions` | [`SimpleMention`](../../../generated/storage/types.gen/type-aliases/SimpleMention.md)[] |\n\n\n\n# Type Alias: Interpolation\n\n> **Interpolation** = [`Mentionable`](../interfaces/Mentionable.md) \\| `string` \\| `number`\n\nWhat may be interpolated into a [msg](../functions/msg.md) template: a mention, or plain text.\n\n\n\n# Variable: here\n\n> `const` **here**: [`Mentionable`](../interfaces/Mentionable.md)\n\nThe `@here` group mention.\n\n\n\n# Class: Lazy\\\n\nA value fetched on first access and cached thereafter. Powers thin entity\nhandles: construction is free, the record is loaded lazily the first time a\nfield is read, and concurrent reads share one in-flight request. Pass a\n`seed` when the record is already known (from a list or an event) to skip the\nfetch entirely.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `T` |\n\n## Constructors\n\n### Constructor\n\n> **new Lazy**\\<`T`\\>(`loader`, `seed?`): `Lazy`\\<`T`\\>\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `loader` | () => `Promise`\\<`T`\\> |\n| `seed?` | `T` |\n\n#### Returns\n\n`Lazy`\\<`T`\\>\n\n## Methods\n\n### clear()\n\n> **clear**(): `void`\n\nDrop the cached value so the next read refetches.\n\n#### Returns\n\n`void`\n\n***\n\n### get()\n\n> **get**(): `Promise`\\<`T`\\>\n\n#### Returns\n\n`Promise`\\<`T`\\>\n\n***\n\n### peek()\n\n> **peek**(): `T` \\| `undefined`\n\nThe cached value, if already loaded — never triggers a fetch.\n\n#### Returns\n\n`T` \\| `undefined`\n\n\n\n# Function: paginate()\n\n> **paginate**\\<`T`, `Cursor`\\>(`fetchPage`): `AsyncGenerator`\\<`T`\\>\n\nAsync generator over a cursor-paginated API. Iterate with `for await`.\nCursors are plain JSON values (strings or small objects), so a page whose\nnext cursor serialises identically to the one it was fetched with means the\nserver is not advancing; the generator throws instead of looping forever.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` | - |\n| `Cursor` | `string` |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `fetchPage` | (`cursor?`) => `Promise`\\<[`Page`](../interfaces/Page.md)\\<`T`, `Cursor`\\>\\> |\n\n## Returns\n\n`AsyncGenerator`\\<`T`\\>\n\n\n\n# Interface: Page\\\n\nOne page of a cursor-paginated list.\n\n## Type Parameters\n\n| Type Parameter | Default type |\n| ------ | ------ |\n| `T` | - |\n| `Cursor` | `string` |\n\n## Properties\n\n| Property | Type |\n| ------ | ------ |\n| `items` | `T`[] |\n| `nextCursor?` | `Cursor` \\| `null` |\n\n\n\n# Class: MacroApiError\n\nA non-2xx HTTP response (Macro API, or a raw fetch like presigned downloads).\n\n## Extends\n\n- [`MacroError`](MacroError.md)\n\n## Extended by\n\n- [`MacroOpRefusedError`](../../../entities/databases/database/classes/MacroOpRefusedError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroApiError**(`status`, `data`): `MacroApiError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `status` | `number` |\n| `data` | `unknown` |\n\n#### Returns\n\n`MacroApiError`\n\n#### Overrides\n\n[`MacroError`](MacroError.md).[`constructor`](MacroError.md#constructor)\n\n## Properties\n\n| Property | Modifier | Type |\n| ------ | ------ | ------ |\n| `data` | `readonly` | `unknown` |\n| `status` | `readonly` | `number` |\n\n\n\n# Class: MacroError\n\nBase for every error the SDK throws.\n\n## Extends\n\n- `Error`\n\n## Extended by\n\n- [`MacroApiError`](MacroApiError.md)\n- [`MacroNotFoundError`](MacroNotFoundError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroError**(`message`): `MacroError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | `string` |\n\n#### Returns\n\n`MacroError`\n\n#### Overrides\n\n`Error.constructor`\n\n\n\n# Class: MacroNotFoundError\n\nThe API succeeded but the addressed entity doesn't exist in the result.\n\n## Extends\n\n- [`MacroError`](MacroError.md)\n\n## Constructors\n\n### Constructor\n\n> **new MacroNotFoundError**(`message`): `MacroNotFoundError`\n\n#### Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `message` | `string` |\n\n#### Returns\n\n`MacroNotFoundError`\n\n#### Overrides\n\n[`MacroError`](MacroError.md).[`constructor`](MacroError.md#constructor)\n\n\n\n# Function: unwrap()\n\n> **unwrap**\\<`TData`, `TError`\\>(`res`): `TData`\n\nTurn a hey-api `{ data, error, response? }` result into either the success\npayload or a thrown MacroApiError.\n\n## Type Parameters\n\n| Type Parameter |\n| ------ |\n| `TData` |\n| `TError` |\n\n## Parameters\n\n| Parameter | Type |\n| ------ | ------ |\n| `res` | \\{ `data?`: `TData`; `error?`: `TError`; `response?`: `Response`; \\} |\n| `res.data?` | `TData` |\n| `res.error?` | `TError` |\n| `res.response?` | `Response` |\n\n## Returns\n\n`TData`\n"
}
]
diff --git a/crates/agent_code_mode/src/domain/operations.json b/crates/agent_code_mode/src/domain/operations.json
index 0ec99529621..eddbdc3bcd3 100644
--- a/crates/agent_code_mode/src/domain/operations.json
+++ b/crates/agent_code_mode/src/domain/operations.json
@@ -575,6 +575,7 @@
"storage.messageTimelineEntries": "Message Timeline Entries",
"storage.entityMessageTyping": "Entity Message Typing",
"storage.linkedAccount": "Linked Account",
+ "storage.linkedChats": "Linked Chats",
"storage.linkedConfiguration": "Linked Configuration",
"storage.linkedConnect": "Linked Connect",
"storage.linkedDisconnect": "Linked Disconnect",
diff --git a/crates/code_execution/src/outbound/deno/sdk.mjs b/crates/code_execution/src/outbound/deno/sdk.mjs
index e278f948a64..40276b75ba6 100644
--- a/crates/code_execution/src/outbound/deno/sdk.mjs
+++ b/crates/code_execution/src/outbound/deno/sdk.mjs
@@ -1,62 +1,62 @@
// Generated by packages/code-mode-sdk/scripts/generate.ts.
-async function cO($,O,j){if(!Number.isInteger(O)||O<1)throw RangeError(`concurrency limit must be a positive integer, got ${O}`);let x=Array($.length),S=0,K=async()=>{while(S<$.length){let X=S;S+=1,x[X]=await j($[X])}},Z=Array.from({length:Math.min(O,$.length)},K);return await Promise.all(Z),x}class W${loader;value;inflight;constructor($,O){this.loader=$;this.value=O}get(){if(this.value!==void 0)return Promise.resolve(this.value);return this.inflight??=this.loader().then(($)=>{return this.value=$,$}),this.inflight}peek(){return this.value}clear(){this.value=void 0,this.inflight=void 0}}async function*u($){let O;do{let j=await $(O),x=j.nextCursor??void 0;if(O!==void 0&&x!==void 0&&JSON.stringify(x)===JSON.stringify(O))throw Error("Pagination cursor did not advance");yield*j.items,O=x}while(O!==void 0)}class f extends Error{constructor($){super($);this.name="MacroError"}}class QO extends f{status;data;constructor($,O){super(`Macro API error ${$}`);this.status=$;this.data=O;this.name="MacroApiError"}}class E extends f{constructor($){super($);this.name="MacroNotFoundError"}}function Q($){if($.error!==void 0)throw new QO($.response?.status??0,$.error);return $.data}class M{client;id;detail;constructor($,O,j){this.client=$;this.id=O;this.detail=new W$(()=>this.fetch(),j)}field($){return async()=>(await this.detail.get())[$]??void 0}mappedField($,O){return async()=>O((await this.detail.get())[$]??void 0)}toJSON(){let $=this.detail.peek();return $===void 0?{id:this.id}:{id:this.id,detail:$}}async mutate($){let O=Q(await $(this.client));return this.detail.clear(),O}}class z$ extends M{async permission(){return Q(await this.client.storage.getEntityPermission({path:{entity_type:this.entityType,entity_id:this.id}}))}async favorite(){return Q(await this.client.storage.addFavorite({body:{entityId:this.id,entityType:this.entityType}})),this}async unfavorite(){return Q(await this.client.storage.removeFavoriteByEntity({path:{entity_type:this.entityType,entity_id:this.id}})),this}}class X$ extends z${propertyReference(){return{entity_type:this.propertyEntityType,entity_id:this.id}}async properties($){let{properties:O}=Q(await this.client.properties.getEntityProperties({path:{entity_type:this.propertyEntityType,entity_id:this.id},query:$?.includeMetadata!==void 0?{include_metadata:$.includeMetadata}:void 0}));return O}async setProperty($,O){Q(await this.client.properties.setEntityProperty({path:{...this.propertyReference(),property_id:$.id},body:{value:O??null}}))}async updatePropertyOptions($){return Q(await this.client.properties.bulkUpdateEntityPropertyOptions({path:this.propertyReference(),body:{properties:$.map((O)=>({property_id:O.property.id,...O.add?{add_option_ids:O.add.map((j)=>j.id)}:{},...O.remove?{remove_option_ids:O.remove.map((j)=>j.id)}:{}}))}}))}async deleteProperty($){Q(await this.client.properties.deleteEntityProperty({path:{entity_property_id:$.property.id}}))}}var w6={"<":"\\u003c",">":"\\u003e","&":"\\u0026"};function i$($,O){let j=JSON.stringify(O).replace(/[<>&]/g,(x)=>w6[x]??x);return`<${$}>${j}${$}>`}function q6($){return typeof $==="object"&&$!==null&&typeof $.toMention==="function"}var f6={toMention:()=>({tag:i$("m-group-mention",{groupAlias:"here"}),mention:{entity_type:"group",entity_id:"here"}})};function b6($,...O){let j="",x=[];for(let[S,K]of $.entries()){j+=K;let Z=O[S];if(Z===void 0)continue;if(q6(Z)){let X=Z.toMention();j+=X.tag,x.push(X.mention)}else j+=String(Z)}return{content:j,mentions:k6(x)}}function k6($){let O=new Set;return $.filter((j)=>{let x=`${j.entity_type}:${j.entity_id}`;if(O.has(x))return!1;return O.add(x),!0})}function O$($){return typeof $==="string"?{content:$,mentions:[]}:$}class B$ extends M{static byId($,O){return new B$($,O)}static from($,O){return new B$($,O.id,O)}async fetch(){let $=Q(await this.client.storage.listHarnesses()).find((O)=>O.id===this.id);if(!$)throw new E(`Harness ${this.id} is unavailable`);return $}name=this.field("name");connected=this.field("connected");kind=this.field("kind");async delete(){await this.mutate(($)=>$.storage.deleteHarness({path:{harness_id:this.id}}))}}class I$ extends M{static byId($,O){return new I$($,O)}static from($,O){return new I$($,O.bot.id,O)}async fetch(){let $=Q(await this.client.storage.listAgents()).find((O)=>O.bot.id===this.id);if(!$)throw new E(`Agent ${this.id} is unavailable`);return $}name=this.mappedField("bot",($)=>$.name);instructions=this.field("instructions");defaultModel=this.field("default_model");channels=this.mappedField("channel_ids",($)=>$.map((O)=>b.byId(this.client,O)));host=this.mappedField("harness_id",($)=>$?B$.byId(this.client,$):void 0);async update($){await this.mutate((O)=>O.storage.updateAgent({path:{agent_id:this.id},body:gx($)}))}}function gx($){let{channels:O,team:j,host:x,autoAcceptPermissions:S,avatarUrl:K,channelScope:Z,defaultModel:X,isCoding:Y,...L}=$;return{...L,channel_ids:O?.map((G)=>G.id),team_id:j?.id,harness_id:x?.id,auto_accept_permissions:S,avatar_url:K,channel_scope:Z,default_model:X,is_coding:Y}}async function Wj($,O,j){let{channelId:x,thread:S}=g6(O);if(await y6($)){let{id:Z}=Q(await $.storage.entityMessageCreate({path:{parent_type:"channel",parent_id:x},body:{content:j.content,mentions:j.mentions,attachments:[],thread_id:S?.rootId??null,nonce:crypto.randomUUID()}}));return Z}if(S)throw new f("a user-owned bot can only post via the channel webhook endpoint, which "+"does not support threads — use a team-owned bot, or requestedAs(user), "+"to reply in a thread");let{message_id:K}=Q(await $.storage.postChannelBotWebhook({path:{channel_id:x},body:{content:j.content},headers:{"x-macro-bot-scope":"user"}}));return K}function g6($){return"rootId"in $?{channelId:$.channelId,thread:$}:{channelId:$.id}}async function y6($){if($.authConfig.type!=="bot"||$.hasActingUser())return!0;let{owner:O}=await $.selfBot();return O?.type==="team"}class h${client;channelId;rootId;constructor($,O,j){this.client=$;this.channelId=O;this.rootId=j}toJSON(){return{channelId:this.channelId,rootId:this.rootId}}channel(){return b.byId(this.client,this.channelId)}root(){return e.byId(this.client,this.channelId,this.rootId)}async replies(){let{replies:$}=Q(await this.client.storage.entityMessageGetThread({path:{parent_type:"channel",parent_id:this.channelId,id:this.rootId}}));return $.map((O)=>e.from(this.client,this.channelId,O))}async reply($){let O=await Wj(this.client,this,O$($));return e.byId(this.client,this.channelId,O)}}class e extends z${channelId;mentions;entityType="channel_message";constructor($,O,j,x=[],S){super($,j,S);this.channelId=O;this.mentions=x}get path(){return{parent_type:"channel",parent_id:this.channelId,id:this.id}}async fetch(){return Q(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j,x=[]){return new e($,O,j,x)}static from($,O,j){return new e($,O,j.id,j.mentions,j)}content=this.field("content");createdAt=this.field("created_at");editedAt=this.field("edited_at");updatedAt=this.field("updated_at");async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}channel(){return b.byId(this.client,this.channelId)}thread(){return new h$(this.client,this.channelId,this.id)}async react($){return await this.mutate((O)=>O.storage.entityMessageReact({path:this.path,body:{add:!0,emoji:$}})),this}async unreact($){return await this.mutate((O)=>O.storage.entityMessageReact({path:this.path,body:{add:!1,emoji:$}})),this}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}async reply($){return this.thread().reply($)}}class Bj{client;channel;record;constructor($,O,j){this.client=$;this.channel=O;this.record=j}agent(){return I$.byId(this.client,this.record.botId)}sessions(){return this.record.sessions.map(($)=>({session:i.byId(this.client,$.sessionId),isCurrent:$.isCurrent,createdAt:$.createdAt}))}turns(){return this.record.turns.map(($)=>new yx(this.client,this,$))}async startFresh($){Q(await this.client.agentHarness.startFreshAgentConversation({path:{channel_id:this.channel.id,bot_id:this.record.botId},body:{sessionId:$.id}}))}toJSON(){return{channelId:this.channel.id,agentId:this.record.botId}}}class yx{client;conversation;record;constructor($,O,j){this.client=$;this.conversation=O;this.record=j}source(){return e.byId(this.client,this.conversation.channel.id,this.record.sourceMessageId)}session(){return i.byId(this.client,this.record.sessionId)}async retry($){Q(await this.client.agentHarness.retryAgentConversationTurn({path:{channel_id:this.conversation.channel.id,bot_id:this.conversation.agent().id,source:this.record.sourceMessageId},body:{actionId:$}}))}toJSON(){return{channelId:this.conversation.channel.id,sourceMessageId:this.record.sourceMessageId}}}class L$ extends M{parent;toJSON(){return{...super.toJSON(),parentType:this.parent.type,parentId:this.parent.entity.id}}constructor($,O,j){super($,j);this.parent=O}static byId($,O,j){return new L$($,O,j)}get path(){return{parent_type:this.parent.type,parent_id:this.parent.entity.id,id:this.id}}async fetch(){return Q(await this.client.storage.entityMessageGetThread({path:this.path})).state}resolved=this.field("resolved");async update($){let O={resolved:$.resolved,detach_anchor:$.detachAnchor,nonce:$.nonce};await this.mutate((j)=>j.storage.entityMessagePatchThread({path:this.path,body:O}))}async delete($){await this.mutate((O)=>O.storage.entityMessageDeleteThread({path:this.path,query:{nonce:$}}))}}async function w$($,O,j,x){for(let K of[...x?.messages??[],...x?.around?[x.around]:[]]){let Z="channelId"in K?{type:"channel",id:K.channelId}:("documentId"in K)?{type:"document",id:K.documentId}:("callId"in K)?{type:"call",id:K.callId}:K.parent;if(Z.type!==O.type||Z.id!==O.entity.id)throw Error("Timeline message belongs to another resource")}let S=Q(await $.storage.messageTimelineEntries({path:{parent_type:O.type,parent_id:O.entity.id},query:{selection:x?JSON.stringify({cursor:x.cursor,around:x.around?.id,ids:x.messages?.map((K)=>K.id),activity_after:x.activityAfter,activity_before:x.activityBefore,anchored:x.anchored,direction:x.direction,include_deleted_threads:x.includeDeletedThreads,limit:x.limit}):void 0}}));return{entries:S.entries.map((K)=>{if(K.type==="activity")return{type:"activity",activity:{...K.activity,actor:P.byId($,K.activity.actor_id)}};return{type:"message",message:j(K.message)}}),nextCursor:S.next_cursor??void 0,previousCursor:S.previous_cursor??void 0}}var v6=50;function x$($){let{filters:O,type:j,make:x,includeCrm:S}=$;return(K,Z,X)=>{let Y=X?.searchOn??"name_content",L=X?.pageSize??v6;return u(async(G)=>{let{results:J,next_cursor:I}=Q(await K.search.unifiedSearch({body:{query:Z,match_type:"partial",search_on:Y,...O?{filters:O}:{},...S?{include_crm:!0}:{}},query:{page_size:L,...G?{cursor:G}:{}}}));return{items:J.filter((W)=>W.type===j).map((W)=>x(K,W)),nextCursor:I}})}}class GO{client;channel;record;constructor($,O,j){this.client=$;this.channel=O;this.record=j}get id(){return this.record.id}user(){return P.byId(this.client,this.record.user_id)}createdAt(){return this.record.created_at}async recordInteraction($){return new GO(this.client,this.channel,Q(await this.client.storage.postActivity({body:{activity_type:$,channel_id:this.channel.id}})))}toJSON(){return this.record}}class b extends X${async recordActivity($){return new GO(this.client,this,Q(await this.client.storage.postActivity({body:{activity_type:$,channel_id:this.id}})))}async setPicture($){await this.mutate((O)=>O.storage.setChannelPicture({path:{channel_id:this.id},body:{profile_picture_id:$?.id??null}}))}messageThreadById($){return L$.byId(this.client,{type:"channel",entity:this},$)}timelinePage($){return w$(this.client,{type:"channel",entity:this},(O)=>e.from(this.client,this.id,O),$)}async agentConversations(){return Q(await this.client.agentHarness.listAgentConversations({path:{channel_id:this.id}})).conversations.map(($)=>new Bj(this.client,this,$))}entityType="channel";propertyEntityType="CHANNEL";async fetch(){return Q(await this.client.storage.getChannel({path:{channel_id:this.id}}))}static byId($,O){return new b($,O)}static async dm($,O){let{channel_id:j}=Q(await $.storage.getOrCreateDm({body:{recipient_id:O.id}}));return new b($,j)}static async private($,O){let{channel_id:j}=Q(await $.storage.getOrCreatePrivate({body:{recipients:O.map((x)=>x.id)}}));return new b($,j)}static async create($,O){let{id:j}=Q(await $.storage.createChannel({body:{channel_type:O.type,name:O.name??null,participants:(O.participants??[]).map((x)=>x.id),team_id:O.team?.id??null}}));return new b($,j)}name=this.field("channel_name");type=this.field("channel_type");async send($,O){let j=await Wj(this.client,O?.thread??this,O$($));return e.byId(this.client,this.id,j)}messages($){return this.timeline({limit:$?.pageSize})}messagesAfter($,O){return this.timeline({activity_after:$ instanceof Date?$.toISOString():$,limit:O?.pageSize})}timeline($){return u(async(O)=>{let j=Q(await this.client.storage.messageTimeline({path:{parent_type:"channel",parent_id:this.id},query:{selection:JSON.stringify({...$,cursor:O})}}));return{items:j.items.map((x)=>e.from(this.client,this.id,x)),nextCursor:j.next_cursor}})}message($){return e.byId(this.client,this.id,$)}async rename($){await this.mutate((O)=>O.storage.patchChannel({path:{channel_id:this.id},body:{channel_name:$}}))}async delete(){await this.mutate(($)=>$.storage.deleteChannel({path:{channel_id:this.id}}))}async join(){await this.mutate(($)=>$.storage.joinChannel({path:{channel_id:this.id}}))}async joinCode(){let{join_code:$}=Q(await this.client.storage.getChannelJoinLink({path:{channel_id:this.id}}));return $}async leave(){await this.mutate(($)=>$.storage.leaveChannel({path:{channel_id:this.id}}))}async participants(){return Q(await this.client.storage.getChannelParticipants({path:{channel_id:this.id}}))}async addParticipants($){await this.mutate((O)=>O.storage.addParticipants({path:{channel_id:this.id},body:{participants:$.map((j)=>j.id)}}))}async removeParticipants($){await this.mutate((O)=>O.storage.removeParticipants({path:{channel_id:this.id},body:{participants:$.map((j)=>j.id)}}))}async typing($,O){Q(await this.client.storage.entityMessageTyping({path:{parent_type:"channel",parent_id:this.id},body:{active:$==="start",thread_id:O?.thread?.rootId??null}}))}attachments($){return u(async(O)=>{let j=Q(await this.client.storage.getChannelAttachments({path:{channel_id:this.id},query:{...$?.pageSize?{limit:$.pageSize}:{},...$?.type?{attachment_type:$.type}:{},...O?{cursor:O}:{}}}));return{items:j.items,nextCursor:j.next_cursor}})}webUrl(){return`${this.client.webAppUrl}/app/channel/${this.id}`}static search=x$({type:"channel",make:($,O)=>new b($,O.channel_id)})}class P extends X${entityType="user";propertyEntityType="USER";async fetch(){let{names:$}=Q(await this.client.auth.getUserNamesWithEmail({body:{user_ids:[this.id]}})),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`user ${this.id} not found`);return O}static byId($,O){return new P($,O)}static fromName($,O){return new P($,O.id,O)}static async me($){let{user_id:O}=Q(await $.auth.getUserInfo());return new P($,O)}async name(){let $=await this.detail.get();return[$.first_name,$.last_name].filter(Boolean).join(" ")||void 0}email(){let $=this.id.startsWith("macro|")?this.id.slice(6):void 0;return $?.includes("@")?$:void 0}dm(){return b.dm(this.client,this)}toMention(){return{tag:i$("m-user-mention",{userId:this.id}),mention:{entity_type:"user",entity_id:this.id}}}}class o{client;entityType;entity;constructor($,O,j){this.client=$;this.entityType=O;this.entity=j}get path(){return{entity_type:this.entityType,entity_id:this.entity.id}}async state($){let O=Q(await this.client.storage.accessRequestsState({path:this.path,query:{offset:$}}));return{accessLevel:O.accessLevel??void 0,canReview:O.canReview,owner:O.owner?P.byId(this.client,O.owner):void 0,pendingCount:O.pendingCount,supportedLevels:O.supportedLevels,nextOffset:O.nextOffset??void 0,mine:O.mine?zO.from(this.client,this,O.mine):void 0,requests:O.requests.map((j)=>zO.from(this.client,this,j))}}async submit($,O){return zO.from(this.client,this,Q(await this.client.storage.accessRequestsSubmit({path:this.path,body:{requestedLevel:$,revision:O}})))}async cancel($){Q(await this.client.storage.accessRequestsCancel({path:this.path,query:{revision:$}}))}async direct(){return Q(await this.client.storage.accessRequestsDirect({path:this.path})).map(($)=>({user:P.byId(this.client,$.userId),accessLevel:$.accessLevel}))}async grant($,O){Q(await this.client.storage.accessRequestsSetDirect({path:{...this.path,user_id:$.id},body:{accessLevel:O}}))}async remove($){Q(await this.client.storage.accessRequestsRemoveDirect({path:{...this.path,user_id:$.id}}))}async resolve($,O){let j=$.access.toJSON();if(j.entity_type!==this.entityType||j.entity_id!==this.entity.id)throw Error("Access request belongs to another entity");return Q(await this.client.storage.accessRequestsResolve({path:{...this.path,request_id:$.id},body:O}))}toJSON(){return this.path}}class zO extends M{access;resolvedRecord;constructor($,O,j){super($,j.id,j);this.access=O}static from($,O,j){return new zO($,O,j)}async fetch(){if(this.resolvedRecord)return this.resolvedRecord;let $;do{let O=await this.access.state($),j=[O.mine,...O.requests].find((x)=>x?.id===this.id);if(j)return j.detail.get();$=O.nextOffset}while($!==void 0);throw new E(`Access request ${this.id} is unavailable`)}revision=this.field("revision");status=this.field("status");requestedLevel=this.field("requestedLevel");requester=this.mappedField("requesterId",($)=>P.byId(this.client,$));async resolve($){this.resolvedRecord=await this.access.resolve(this,{revision:await this.revision(),grantedLevel:$}),this.detail.clear()}}function n$($){return{...$,channelSharePermissions:$.channelSharePermissions===void 0||$.channelSharePermissions===null?$.channelSharePermissions:$.channelSharePermissions.map((O)=>({channelId:O.channel.id,accessLevel:O.accessLevel,operation:O.operation}))}}class N$ extends M{parent;constructor($,O,j,x){super($,j,x);this.parent=O}static byId($,O,j){return new N$($,O,j)}static fromRecord($,O,j){return new N$($,O,j.id,j)}static async create($,O,j){return N$.createForSession($,O.session(),j,O)}static async createForSession($,O,j,x){let S=Q(await $.agentHarness.createSessionReview({path:{session_id:O.id},body:{...j,executionId:x?.id??null}}));return N$.fromRecord($,O,S)}static async list($,O){return Q(await $.agentHarness.listExecutionReviews({path:{session_id:O.session().id,execution_id:O.id}})).map((x)=>N$.fromRecord($,O.session(),x))}async fetch(){return Q(await this.client.agentHarness.getSessionReview({path:{session_id:this.parent.id,review_id:this.id}}))}title=this.field("title");kind=this.field("kind");session(){return this.parent}async reference(){return{kind:await this.kind(),id:this.id}}async items(){return(await this.detail.get()).items.map(($)=>new vx($,{edit:(O)=>this.decide({action:"edit",item:$.id,draft:O}),submit:()=>this.decide({action:"submit",items:[$.id]}),dismiss:()=>this.decide({action:"dismiss",items:[$.id]})}))}async refresh(){return this.detail.clear(),await this.detail.get(),this}async submitAll(){await this.decide({action:"submit",items:[]})}async dismissAll(){await this.decide({action:"dismiss",items:[]})}async decide($){let O=(await this.detail.get()).revision;await this.mutate((j)=>j.agentHarness.decideSessionReview({path:{session_id:this.parent.id,review_id:this.id},body:{...$,revision:O}}))}}class vx{snapshot;actions;constructor($,O){this.snapshot=$;this.actions=O}get id(){return this.snapshot.id}get status(){return this.snapshot.status}get draft(){return this.snapshot.draft}get result(){return this.snapshot.result}async edit($){await this.actions.edit($)}async submit(){await this.actions.submit()}async dismiss(){await this.actions.dismiss()}}class uO extends M{parent;constructor($,O,j){super($,O);this.parent=j}static byId($,O,j){return new uO($,j,O)}async fetch(){return Q(await this.client.agentHarness.getCodeExecution({path:{session_id:this.parent.id,execution_id:this.id}}))}reviews={create:($)=>N$.create(this.client,this,$),list:()=>N$.list(this.client,this)};session(){return this.parent}status=this.field("status");source=this.field("source");calls=this.field("calls");error=this.field("error");async result(){return(await this.detail.get()).result}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class Lj{client;sessionId;dto;constructor($,O,j){this.client=$;this.sessionId=O;this.dto=j}static from($,O,j){return new Lj($,O,j)}get actionId(){return this.dto.actionId}get kind(){return this.dto.kind}get prompt(){return this.dto.prompt??void 0}get attachments(){return this.dto.attachments??[]}get actorUserId(){return this.dto.actorUserId??void 0}get createdAt(){return this.dto.createdAt}async edit($){return Q(await this.client.agentHarness.editQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId},body:{prompt:$}})),this.dto={...this.dto,prompt:$},this}async steer(){Q(await this.client.agentHarness.steerQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId}}))}async remove(){Q(await this.client.agentHarness.removeQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId}}))}}class dO{client;session;id;constructor($,O,j){this.client=$;this.session=O;this.id=j}static byId($,O,j){return new dO($,O,j)}async answer($){return Q(await this.client.agentHarness.answerAgentSessionToolApproval({path:{session_id:this.session.id,approval_id:this.id},body:{answer:$}}))}toJSON(){return{id:this.id,sessionId:this.session.id}}}class i extends M{access=new o(this.client,"agent_session",this);toolApprovalById($){return dO.byId(this.client,this,$)}async sharePermissions(){return Q(await this.client.agentHarness.getAgentSessionPermissions({path:{session_id:this.id}}))}async updateSharePermissions($){return this.mutate((O)=>O.agentHarness.updateAgentSessionPermissions({path:{session_id:this.id},body:n$($)}))}static byId($,O){return new i($,O)}static async createManaged($,O){let{session:j}=Q(await $.agentHarness.createAgentSession({body:{prompt:O?.prompt,instructions:O?.instructions,model:O?.model,repoUrl:O?.repoUrl,repoBranch:O?.repoBranch}}));return new i($,j.id,j)}static async repositories($){let{repositories:O}=Q(await $.agentHarness.listAgentRepositories());return O.map((j)=>({url:j.url,defaultBranch:j.defaultBranch??void 0}))}static async repositoryBranches($,O){let{branches:j}=Q(await $.agentHarness.listAgentRepositoryBranches({query:{repoUrl:O}}));return j}async fetch(){return Q(await this.client.agentHarness.getAgentSession({path:{session_id:this.id}}))}name=this.field("name");isArchived=this.field("isArchived");model=this.field("model");harness=this.field("harness");repoUrl=this.field("repoUrl");workspace=this.field("workspace");instructions=this.field("instructions");status=this.field("status");sandboxSize=this.field("sandboxSize");createdAt=this.field("createdAt");modifiedAt=this.field("modifiedAt");static async forPullRequest($,O){let{sessionIds:j}=Q(await $.agentHarness.agentSessionsForPullRequest({body:{url:O}}));return j.map((x)=>i.byId($,x))}async pullRequests(){let{pullRequests:$}=Q(await this.client.agentHarness.listAgentSessionPullRequests({path:{session_id:this.id}}));return $.map((O)=>({githubKey:O.githubKey,url:O.url,source:O.source,linkedBy:O.linkedBy?P.byId(this.client,O.linkedBy):void 0,createdAt:O.createdAt}))}async linkPullRequest($){Q(await this.client.agentHarness.linkAgentSessionPullRequest({path:{session_id:this.id},body:{url:$}}))}async unlinkPullRequest($){Q(await this.client.agentHarness.unlinkAgentSessionPullRequest({path:{session_id:this.id},query:{url:$}}))}async rename($){await this.mutate((O)=>O.agentHarness.renameAgentSession({path:{session_id:this.id},body:{name:$}}))}async archive(){await this.setArchived(!0)}async unarchive(){await this.setArchived(!1)}async setArchived($){await this.mutate((O)=>O.agentHarness.setAgentSessionArchived({path:{session_id:this.id},body:{isArchived:$}}))}async setSandboxSize($){let{size:O}=await this.mutate((j)=>j.agentHarness.putAgentSessionSandboxSize({path:{session_id:this.id},body:{size:$}}));return O}static async defaultSandboxSize($){return Q(await $.agentHarness.getAgentSandboxSize()).size}static async setDefaultSandboxSize($,O){return Q(await $.agentHarness.putAgentSandboxSize({body:{size:O}})).size}static async codingPreferences($){return Q(await $.agentHarness.getAgentCodingPreferences())}static async setCodingPreferences($,O){return Q(await $.agentHarness.putAgentCodingPreferences({body:O}))}async control($){return this.mutate((O)=>O.agentHarness.controlAgentSession({path:{session_id:this.id},body:$}))}prompt($,O){return this.control({type:"prompt",prompt:$,...O&&O.length>0?{attachments:O}:{}})}async queue(){let{entries:$}=Q(await this.client.agentHarness.getAgentSessionQueue({path:{session_id:this.id}}));return $.map((O)=>Lj.from(this.client,this.id,O))}async changes(){return Q(await this.client.agentHarness.getAgentSessionChanges({path:{session_id:this.id}}))}async changesPatch(){return Q(await this.client.agentHarness.getAgentSessionChangesPatch({path:{session_id:this.id}})).patch}async refreshChanges(){return this.mutate(($)=>$.agentHarness.refreshAgentSessionChanges({path:{session_id:this.id}}))}async foldedLog(){let{bot:$,messages:O}=Q(await this.client.agentHarness.getAgentSessionFoldedLog({path:{session_id:this.id}}));return{bot:$,messages:O}}async log(){return Q(await this.client.agentHarness.getAgentSessionLog({path:{session_id:this.id}}))}reviews={create:($)=>N$.createForSession(this.client,this,$),byId:($)=>N$.byId(this.client,this,$)};codeExecutions={byId:($)=>uO.byId(this.client,this,$)};async delete(){await this.mutate(($)=>$.agentHarness.deleteAgentSession({path:{session_id:this.id}}))}}class hx{client;constructor($){this.client=$}byId($){return i.byId(this.client,$)}createManaged($){return i.createManaged(this.client,$)}repositories(){return i.repositories(this.client)}repositoryBranches($){return i.repositoryBranches(this.client,$)}forPullRequest($){return i.forPullRequest(this.client,$)}defaultSandboxSize(){return i.defaultSandboxSize(this.client)}setDefaultSandboxSize($){return i.setDefaultSandboxSize(this.client,$)}codingPreferences(){return i.codingPreferences(this.client)}setCodingPreferences($){return i.setCodingPreferences(this.client,$)}}class mx{client;constructor($){this.client=$}byId($){return I$.byId(this.client,$)}async list(){return Q(await this.client.storage.listAgents()).map(($)=>I$.from(this.client,$))}async create($){return I$.from(this.client,Q(await this.client.storage.createAgent({body:gx($)})))}}class cx{client;async usage($={}){let{users:O,...j}=$;return Q(await this.client.cognition.getUsageHandler({body:{...j,include_users:O?.map((x)=>x.id)}}))}constructor($){this.client=$}async structuredCompletion($){return Q(await this.client.cognition.structuredCompletion({body:$}))}async decide($){return Q(await this.client.cognition.decisions({body:$}))}}class s$ extends M{static byId($,O){return new s$($,O)}static from($,O){return new s$($,O.id,{id:O.id,name:O.name,createdAt:O.createdAt})}async fetch(){let $=Q(await this.client.storage.listUserApiKeys()).keys.find((O)=>O.id===this.id);if(!$)throw new E(`API key ${this.id} is unavailable`);return $}name=this.field("name");createdAt=this.field("createdAt");async delete(){await this.mutate(($)=>$.storage.deleteUserApiKey({path:{id:this.id}}))}}class ux{client;constructor($){this.client=$}byId($){return s$.byId(this.client,$)}async list(){return Q(await this.client.storage.listUserApiKeys()).keys.map(($)=>s$.from(this.client,$))}async create($){let O=Q(await this.client.storage.createUserApiKey({body:{name:$}}));return{key:s$.from(this.client,O),secret:O.key}}async tokenForEmail($){return Q(await this.client.auth.macroApiToken({query:{email:$}}))}}class lO{client;constructor($){this.client=$}async me(){if(this.client.authConfig.type!=="bot")throw new f("bots.me() requires bot auth — a user API key has no bot identity");return Q(await this.client.storage.getSelfBot())}async channels(){if(this.client.authConfig.type!=="bot")throw new f("bots.channels() requires bot auth — a user API key has no bot identity");let $=await this.me();return Q(await this.client.storage.listBotChannels({path:{bot_id:$.id}}))}async myPrincipalId(){if(this.client.authConfig.type!=="bot")throw new f("bots.myPrincipalId() requires bot auth — a user API key has no bot identity");return this.client.myPrincipalId()}}class S$ extends M{async fetch(){let O=Q(await this.client.auth.getUserTeams()).find((j)=>j.id===this.id);if(!O)throw new E(`team ${this.id} not found`);return O}static byId($,O){return new S$($,O)}static async current($){let O=Q(await $.auth.getTeam());if(!O)throw new E("caller has no current team");return new S$($,O.team.id,O.team)}static async list($){return Q(await $.auth.getUserTeams()).map((j)=>new S$($,j.id,j))}name=this.field("name");slug=this.field("slug");defaultLinkShare=this.field("default_link_share");owner=this.mappedField("owner_id",($)=>P.byId(this.client,$));async members(){let $=Q(await this.client.auth.getTeam());if(!$||$.team.id!==this.id)throw new f("members are only available for the current team (see Team.current)");return $.members.map((O)=>({user:P.byId(this.client,O.user_id),role:O.role}))}}class T$ extends M{async fetch(){let{links:$}=Q(await this.client.email.listLinks()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`email link ${this.id} not found`);return O}static byId($,O){return new T$($,O)}static async list($){let{links:O}=Q(await $.email.listLinks());return O.map((j)=>new T$($,j.id,j))}emailAddress=this.field("email_address");provider=this.field("provider");isPrimary=this.field("is_primary");isSyncActive=this.field("is_sync_active");syncStatus=this.field("sync_status");needsReauth=this.field("needs_reauth");photoUrl=this.field("photo_url");async settingsOperations(){return Q(await this.client.email.mailboxSettingsOperations({headers:{"X-Email-Link-Id":this.id}}))}}class m$ extends M{async setContributesToAvailability($){await this.mutate((O)=>O.calendar.setAvailabilityCalendar({path:{calendar_id:this.id},body:{contributesToAvailability:$}}))}async fetch(){let{calendars:$}=Q(await this.client.calendar.listCalendars()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`calendar ${this.id} not found`);return O}static byId($,O){return new m$($,O)}static async list($){let{calendars:O}=Q(await $.calendar.listCalendars());return O.map((j)=>new m$($,j.id,j))}name=this.field("name");emailAddress=this.field("emailAddress");isPrimary=this.field("isPrimary");isWritable=this.field("isWritable");isSubscription=this.field("isSubscription");color=this.field("color");syncError=this.field("syncError");emailLink=this.mappedField("emailLinkId",($)=>T$.byId(this.client,$))}class rO{client;id;constructor($,O){this.client=$;this.id=O}async status(){return Q(await this.client.calendar.calendarReplacementStatus({path:{operation_id:this.id}}))}async confirm(){return Q(await this.client.calendar.confirmCalendarReplacement({path:{operation_id:this.id}}))}async discard(){Q(await this.client.calendar.discardCalendarReplacement({path:{operation_id:this.id}}))}}class $$ extends M{async notes($){return this.requireOwnOccurrence($),Q(await this.client.calendar.eventNotes({path:{event_id:this.id},query:{occurrenceKey:$.occurrenceKey}})).map((j)=>q$.fromRecord(this.client,this,$,j))}async linkNote($,O,j={}){return this.requireOwnOccurrence(O),Q(await this.client.calendar.linkEventNote({path:{event_id:this.id,document_id:$.id},query:{occurrenceKey:O.occurrenceKey},body:{teamId:j.team?.id??null}})),q$.forDocument(this.client,this,O,$)}requireOwnOccurrence($){if($.eventId!==this.id)throw new f("The occurrence belongs to a different event")}async fetch(){throw new f(`calendar event ${this.id} has no fetch-by-id endpoint; read the record returned by calendar.createEvent / event.update / event.rsvp instead`)}static byId($,O){return new $$($,O)}static fromRecord($,O){return new $$($,O.id,O)}title=this.field("title");description=this.field("description");location=this.field("location");time=this.field("time");status=this.field("status");attendees=this.field("attendees");transparency=this.field("transparency");isReadOnly=this.field("isReadOnly");recurrenceLines=this.field("recurrenceLines");guestPolicy=this.field("guestPolicy");viewerCan=this.field("viewerCan");calendar=this.mappedField("calendarId",($)=>$?m$.byId(this.client,$):void 0);record(){return this.detail.get()}async update($){let O=await this.mutate((j)=>j.calendar.updateCalendarEvent({path:{event_id:this.id},body:h6($)}));return $$.fromRecord(this.client,O)}async delete($={}){await this.mutate((O)=>O.calendar.deleteCalendarEvent({path:{event_id:this.id},query:{calendarId:$.calendar?.id,scope:$.scope,recurrenceId:$.recurrenceId,inbox:$.inbox}}))}async prepareReplacement($){let O=Q(await this.client.calendar.prepareCalendarReplacement({path:{event_id:this.id},body:{removeConference:$.removeConference,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}}));return new rO(this.client,O.operationId)}async providerUrl($={}){return Q(await this.client.calendar.calendarEventProviderUrl({path:{event_id:this.id},query:{recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}})).url??void 0}async inviteGuests($){let O=await this.mutate((j)=>j.calendar.inviteCalendarEventGuests({path:{event_id:this.id},body:{guests:$.guests,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id,inbox:$.inbox}}));return $$.fromRecord(this.client,O)}async addToCalendar($={}){let O=await this.mutate((j)=>j.calendar.copyCalendarEvent({path:{event_id:this.id},body:{calendarId:$.calendar?.id}}));return $$.fromRecord(this.client,O)}async ics(){return Q(await this.client.storage.eventIcs({path:{event_id:this.id}}))}async rsvp($){let O=await this.mutate((j)=>j.calendar.rsvpCalendarEvent({path:{event_id:this.id},body:{response:$.response,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}}));return $$.fromRecord(this.client,O)}}function h6($){return{title:$.title,description:$.description,location:$.location,time:$.time,attendees:$.attendees,recurrenceLines:$.recurrenceLines,visibility:$.visibility,transparency:$.transparency,reminders:$.reminders,conference:$.conference,outOfOffice:$.outOfOffice,guestPolicy:$.guestPolicy,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id,inbox:$.inbox}}class q$ extends M{event;occurrence;fromDocument;constructor($,O,j,x,S,K=!1){super($,x.id,S);this.event=O;this.occurrence=j;this.fromDocument=K;if(j.eventId!==O.id)throw new f("Choose an occurrence belonging to this event")}static fromDocumentLink($,O,j){return new q$($,$$.byId($,j.eventId),j,O,{documentId:O.id,name:j.documentName,team:j.team,canManage:!0},!0)}static forDocument($,O,j,x){return new q$($,O,j,x)}static fromRecord($,O,j,x){return new q$($,O,j,w.byId($,x.documentId),x)}async fetch(){if(this.fromDocument){let x=Q(await this.client.calendar.documentNoteLinks({path:{document_id:this.id}})).find((S)=>S.eventId===this.event.id&&S.occurrenceKey===this.occurrence.occurrenceKey);if(!x)throw new E("This meeting link has been removed");return{documentId:this.id,name:x.documentName,team:x.team,canManage:!0}}let O=Q(await this.client.calendar.eventNotes({path:{event_id:this.event.id},query:{occurrenceKey:this.occurrence.occurrenceKey}})).find((j)=>j.documentId===this.id);if(!O)throw new E("This document is no longer linked to the meeting");return O}document=this.mappedField("documentId",($)=>w.byId(this.client,$));name=this.field("name");team=this.mappedField("team",($)=>$?S$.byId(this.client,$.id):void 0);canManage=this.field("canManage");async setTeam($){await this.mutate((O)=>O.calendar.linkEventNote({path:{event_id:this.event.id,document_id:this.id},query:{occurrenceKey:this.occurrence.occurrenceKey},body:{teamId:$?.id??null}}))}async unlink(){await this.mutate(($)=>$.calendar.unlinkEventNote({path:{event_id:this.event.id,document_id:this.id},query:{occurrenceKey:this.occurrence.occurrenceKey}}))}}class n extends X${async sharePermissions(){return Q(await this.client.storage.getProjectPermissionsV2({path:{id:this.id}}))}async accessLevel(){return Q(await this.client.storage.getProjectUserAccessLevel({path:{id:this.id}}))}access=new o(this.client,"project",this);entityType="project";propertyEntityType="PROJECT";async fetch(){let{data:$}=Q(await this.client.storage.getProjectHandler({path:{id:this.id}}));return $.projectMetadata}static byId($,O){return new n($,O)}static async create($,O){let{data:j}=Q(await $.storage.createProjectHandler({body:{name:O.name,projectParentId:O.parent?.id??null}}));return new n($,j.id,j)}name=this.field("name");parent=this.mappedField("parentId",($)=>$?n.byId(this.client,$):void 0);createdAt=this.field("createdAt");async items(){let{data:$}=Q(await this.client.storage.getProjectContentHandler({path:{id:this.id}}));return $.map((O)=>O.item)}async rename($){await this.mutate((O)=>O.storage.editProjectV2({path:{id:this.id},body:{name:$}}))}async delete($){await this.mutate((O)=>$?.permanent?O.storage.permanentlyDeleteProject({path:{id:this.id}}):O.storage.deleteProjectHandler({path:{id:this.id}}))}async restore(){await this.mutate(($)=>$.storage.revertDeleteProject({path:{id:this.id}}))}static search=x$({filters:{project_filters:{}},type:"project",make:($,O)=>new n($,O.id)})}class JO extends M{document;toJSON(){return{...super.toJSON(),documentId:this.document.id}}constructor($,O,j,x){super($,j,x);this.document=O}static byId($,O,j){return new JO($,O,j)}static from($,O,j){return new JO($,O,j.uuid,j)}async fetch(){let $=Q(await this.client.storage.getDocumentAnchors({path:{document_id:this.document.id}})).data.find((O)=>O.uuid===this.id);if(!$)throw new E(`Annotation ${this.id} is unavailable`);return $}kind=this.field("anchorType");page=this.field("page");async edit($){if(await this.kind()!=="placeable")throw Error("Only placeable comment annotations can be edited");await this.mutate((O)=>O.storage.editAnchor({body:{...$,uuid:this.id,anchorType:"free-comment",fileType:"pdf"}}))}async delete(){if(await this.kind()!=="highlight")throw Error("Only standalone highlights can be deleted with this endpoint");await this.mutate(($)=>$.storage.deleteAnchor({body:{uuid:this.id,anchorType:"highlight",fileType:"pdf"}}))}}class c$ extends M{documentId;constructor($,O,j,x){super($,j,x);this.documentId=O}get path(){return{parent_type:"document",parent_id:this.documentId,id:this.id}}async fetch(){return Q(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new c$($,O,j)}static from($,O,j){return new c$($,O,j.id,j)}text=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");async threadId(){return(await this.detail.get()).thread_id??this.id}document(){return w.byId(this.client,this.documentId)}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){return this.document().comment($,{threadId:await this.threadId()})}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}class pO{client;document;id;detail;constructor($,O,j){this.client=$;this.document=O;this.id=j;this.detail=new W$(async()=>Q(await this.client.storage.getDocumentVersion({path:{document_id:O.id,document_version_id:j}})).data)}static byId($,O,j){return new pO($,O,j)}read(){return this.detail.get()}toJSON(){return{id:this.id,documentId:this.document.id}}}var m6=8;class w extends X${async meetingNotes(){return Q(await this.client.calendar.documentNoteLinks({path:{document_id:this.id}})).map((O)=>({note:q$.fromDocumentLink(this.client,this,O),eventTitle:O.eventTitle}))}async anchors(){return Q(await this.client.storage.getDocumentAnchors({path:{document_id:this.id}})).data.map(($)=>JO.from(this.client,this,$))}async createHighlight($){return JO.from(this.client,this,Q(await this.client.storage.createAnchor({path:{document_id:this.id},body:{...$,fileType:"pdf",anchorType:"highlight"}})))}version($){return pO.byId(this.client,this,$)}async sharePermissions(){return Q(await this.client.storage.getDocumentPermissionsV2({path:{document_id:this.id}})).documentPermissions}async permissionsToken(){return Q(await this.client.storage.getDocumentPermissionsToken({path:{document_id:this.id}})).token}async prepareSave($){return Q(await this.client.storage.presaveDocumentHandler({path:{document_id:this.id},body:{newBom:$}})).data}async save($){return(await this.mutate((O)=>O.storage.saveDocumentHandler({path:{document_id:this.id},body:$}))).data}async simpleSave(){return(await this.mutate(($)=>$.storage.simpleSave({path:{document_id:this.id}}))).data}messageThreadById($){return L$.byId(this.client,{type:"document",entity:this},$)}timelinePage($){return w$(this.client,{type:"document",entity:this},(O)=>c$.from(this.client,this.id,O),$)}access=new o(this.client,"document",this);async fetch(){let{data:$}=Q(await this.client.storage.getDocument({path:{document_id:this.id}}));return $.documentMetadata}static byId($,O){return new w($,O)}static async create($,O){let{documentId:j}=Q(await $.storage.createMarkdownHandler({body:{documentName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static async createSnippet($,O){let{documentId:j}=Q(await $.storage.createSnippetHandler({body:{snippetName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static async createSkill($,O){let{documentId:j}=Q(await $.storage.createSkillHandler({body:{skillName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static recent($,O){let j=O?.pageSize??50;return u(async(x)=>{let S=Q(await $.storage.getUserDocumentsHandler({query:{limit:j,offset:x?Number(x):0,...O?.fileType!==void 0?{file_type:O.fileType}:{}}})),K=S.data?.next_offset;return{items:(S.data?.documents??[]).map((Z)=>new w($,Z.documentId)),nextCursor:K!=null?String(K):null}})}static async recentlyDeleted($){let{data:O}=Q(await $.storage.recentlyDeleted({}));return O.items.filter((j)=>j.type==="document").map((j)=>new w($,j.id))}entityType="document";propertyEntityType="DOCUMENT";name=this.field("documentName");fileType=this.field("fileType");project=this.mappedField("projectId",($)=>$?n.byId(this.client,$):void 0);owner=this.mappedField("owner",($)=>P.byId(this.client,$));branchedFrom=this.mappedField("branchedFromId",($)=>$?w.byId(this.client,$):void 0);createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");deletedAt=this.field("deletedAt");async content(){let{text:$}=Q(await this.client.storage.getDocumentTextContent({path:{document_id:this.id}}));if($!==null)return $;let{presigned_url:O}=Q(await this.client.storage.exportDocument({path:{document_id:this.id}})),j=await fetch(O);if(!j.ok)throw new QO(j.status,{message:"failed to download document content"});return j.text()}async rename($){await this.mutate((O)=>O.storage.editDocument({path:{document_id:this.id},body:{documentName:$}}))}async move($){await this.mutate((O)=>O.storage.editDocument({path:{document_id:this.id},body:{projectId:$?.id??""}}))}async delete($){await this.mutate((O)=>$?.permanent?O.storage.permanentlyDeleteDocument({path:{document_id:this.id}}):O.storage.deleteDocument({path:{document_id:this.id}}))}async restore(){await this.mutate(($)=>$.storage.revertDeleteDocument({path:{document_id:this.id}}))}async copy($){let{data:O}=Q(await this.client.storage.copyDocument({path:{document_id:this.id},query:$.versionId!==void 0?{version_id:$.versionId}:void 0,body:{documentName:$.name}}));return new w(this.client,O.documentMetadata.documentId)}async comments(){let $={parent_type:"document",parent_id:this.id},O=u(async(x)=>{let S=Q(await this.client.storage.messageTimeline({path:$,query:{selection:JSON.stringify({limit:100,cursor:x})}}));return{items:S.items,nextCursor:S.next_cursor}}),j=[];for await(let x of O)j.push(x);return cO(j,m6,async(x)=>{let{state:S,root:K,replies:Z}=Q(await this.client.storage.entityMessageGetThread({path:{...$,id:x.id}}));return{thread:S,comments:[K,...Z].map((X)=>c$.from(this.client,this.id,X))}})}async comment($,O){let j=await this.mutate((x)=>x.storage.entityMessageCreate({path:{parent_type:"document",parent_id:this.id},body:{...O$($),thread_id:O?.threadId??null}}));return c$.from(this.client,this.id,j)}async shortId(){return Q(await this.client.storage.getDocumentShortId({path:{document_id:this.id}}))}async teamShare(){return Q(await this.client.storage.getDocumentTeamShare({path:{document_id:this.id}}))}async setTeamShare($){await this.mutate((O)=>O.storage.setDocumentTeamShare({path:{document_id:this.id},body:{shareWithTeam:$}}))}async githubPullRequests(){let{pullRequests:$}=Q(await this.client.storage.getDocumentGithubPullRequests({path:{document_id:this.id}}));return $}async branchName(){let{branchName:$}=Q(await this.client.storage.getDocumentBranchName({path:{document_id:this.id}}));return $}webUrl(){return`${this.client.webAppUrl}/app/md/${this.id}`}static search=x$({filters:{document_filters:{}},type:"document",make:($,O)=>new w($,O.document_id)});toMention(){let $=this.detail.peek();return{tag:i$("m-document-mention",{documentId:this.id,documentName:$?.documentName??"",blockName:$?.fileType??"md"}),mention:{entity_type:"document",entity_id:this.id}}}}class dx{client;async noteDocuments($=""){let O=Q(await this.client.calendar.noteDocuments({query:{query:$}}));return{documents:O.documents.map((j)=>({document:w.byId(this.client,j.documentId),name:j.name})),teams:O.teams.map((j)=>({team:S$.byId(this.client,j.id),name:j.name}))}}async availabilityCalendars(){return Q(await this.client.calendar.getAvailabilityCalendars()).calendars.map(($)=>({calendar:m$.byId(this.client,$.calendarId),name:$.name,isPrimary:$.isPrimary,contributesToAvailability:$.contributesToAvailability}))}async teamSharing(){return Q(await this.client.calendar.getTeamSharing()).sharing}async setTeamSharing($){return Q(await this.client.calendar.setTeamSharing({body:{sharing:$}})).sharing}occurrences($){let O;return u(async(j)=>{let x=Q(await this.client.storage.listOccurrences({query:{...$,cursor:j}}));O??=u6(this.client);let S=await O;return{items:x.items.map((K)=>({event:$$.fromRecord(this.client,K.event),occurrence:K.occurrence,inbox:K.event.calendarId?S.get(K.event.calendarId):void 0,role:d6(K.event)})),nextCursor:x.nextCursor}})}async teamPage($){let O=Q(await this.client.storage.listTeamCalendar({query:$}));return{items:O.items.map(({ownerId:j,...x})=>({...x,owner:P.byId(this.client,j)})),members:O.members.map((j)=>({user:P.byId(this.client,j.userId),sharing:j.sharing,coverage:j.coverage})),nextCursor:O.nextCursor??void 0}}async teamOutOfOffice($){let O=Q(await this.client.storage.listTeamOutOfOffice({query:$}));return{items:O.items.map((j)=>({event:$$.byId(this.client,j.eventId),owner:P.byId(this.client,j.ownerId),occurrenceKey:j.occurrenceKey,time:j.time,title:j.title??void 0})),hasMore:O.hasMore}}constructor($){this.client=$}calendars(){return m$.list(this.client)}calendar($){return m$.byId(this.client,$)}event($){return $$.byId(this.client,$)}replacement($){return new rO(this.client,$)}async createEvent($){let O=Q(await this.client.calendar.createCalendarEvent({body:c6($)}));return $$.fromRecord(this.client,O)}}function c6($){return{title:$.title,time:$.time,description:$.description,location:$.location,attendees:$.attendees,recurrenceLines:$.recurrenceLines,visibility:$.visibility,transparency:$.transparency,reminders:$.reminders,conference:$.conference,macroCall:$.macroCall,outOfOffice:$.outOfOffice,guestPolicy:$.guestPolicy,calendarId:$.calendar?.id,emailLinkId:$.emailLink?.id}}async function u6($){let{calendars:O}=Q(await $.calendar.listCalendars());return new Map(O.map((j)=>[j.id,j.emailAddress]))}function d6($){let O=$.attendees.find((j)=>j.isSelf);if($.viewerCan.organize||O?.isOrganizer)return"organizer";return O?"guest":void 0}class H$ extends M{lookupToken;constructor($,O,j){super($,O,j);this.lookupToken=j?.shareToken}static byId($,O){return new H$($,O)}static from($,O){return new H$($,O.id,O)}async fetch(){if(this.lookupToken)return Q(await this.client.storage.meetingLookup({path:{token:this.lookupToken}}));let $=Q(await this.client.storage.meetingList()).meetings.find((O)=>O.id===this.id);if(!$)throw new E(`Meeting ${this.id} is unavailable`);return this.lookupToken=$.shareToken,$}title=this.field("title");scheduledStart=this.field("scheduledStart");scheduledEnd=this.field("scheduledEnd");channel=this.mappedField("channelId",($)=>$?b.byId(this.client,$):void 0);call=this.mappedField("callId",($)=>$?G$.byId(this.client,$):void 0);async update($){await this.mutate((O)=>O.storage.meetingUpdate({path:{meeting_id:this.id},body:$}))}async cancel(){await this.mutate(($)=>$.storage.meetingCancel({path:{meeting_id:this.id}}))}async invitePermissions(){return Q(await this.client.storage.meetingInvitePermissions({path:{token:(await this.detail.get()).shareToken}}))}async invite($){Q(await this.client.storage.meetingInvite({path:{token:(await this.detail.get()).shareToken},body:{email:$}}))}async inviteUsers($){Q(await this.client.storage.meetingInviteUsers({path:{token:(await this.detail.get()).shareToken},body:{userIds:$.map((O)=>O.id)}}))}async webUrl(){return`${this.client.webAppUrl}/app/meet/join/${encodeURIComponent((await this.detail.get()).shareToken)}`}}class u$ extends M{callId;constructor($,O,j,x){super($,j,x);this.callId=O}get path(){return{parent_type:"call",parent_id:this.callId,id:this.id}}async fetch(){return Q(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new u$($,O,j)}static from($,O,j){return new u$($,O,j.id,j)}content=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");call(){return G$.byId(this.client,this.callId)}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){let O=Q(await this.client.storage.entityMessageCreate({path:{parent_type:"call",parent_id:this.callId},body:{...O$($),thread_id:this.callId}}));return u$.from(this.client,this.callId,O)}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}class G$ extends z${messageThreadById($){return L$.byId(this.client,{type:"call",entity:this},$)}timelinePage($){return w$(this.client,{type:"call",entity:this},(O)=>u$.from(this.client,this.id,O),$)}access=new o(this.client,"call",this);async meeting(){return H$.from(this.client,Q(await this.client.storage.meetingShare({path:{call_id:this.id}})))}async editTranscript($){await this.mutate((O)=>O.storage.editCallTranscript({path:{call_id:this.id},body:{assignments:$}}))}async toggleTeamShare(){return this.mutate(($)=>$.storage.toggleShareWithTeam({path:{call_id:this.id}}))}entityType="call";async fetch(){return Q(await this.client.storage.getCallRecord({path:{call_id:this.id}}))}static byId($,O){return new G$($,O)}message($){return u$.byId(this.client,this.id,$)}name=this.field("customName");channel=this.mappedField("channelId",($)=>$?b.byId(this.client,$):void 0);channelName=this.field("channelName");creator=this.mappedField("createdBy",($)=>P.byId(this.client,$));isActive=this.field("isActive");status=this.field("status");roomName=this.field("roomName");startedAt=this.field("startedAt");endedAt=this.field("endedAt");durationMs=this.field("durationMs");summary=this.field("summary");transcript=this.field("transcript");participants=this.field("participants");guests=this.field("guests");teamShareAccessLevel=this.field("teamShareAccessLevel");shareWithTeam=this.field("shareWithTeam");recordingUrl=this.field("recordingUrl");recordingPreviewUrl=this.field("recordingPreviewUrl");recordingStartedAt=this.field("recordingStartedAt");async rename($){await this.mutate((O)=>O.storage.editCallRecord({path:{call_id:this.id},body:{customName:$??""}}))}async setTeamShare($){await this.mutate((O)=>O.storage.editCallRecord({path:{call_id:this.id},body:{sharePermission:{teamShareAccessLevel:$?"view":null}}}))}async delete(){await this.mutate(($)=>$.storage.deleteCallRecord({path:{call_id:this.id}}))}static search=x$({filters:{call_filters:{}},type:"call",make:($,O)=>new G$($,O.call_id)})}class lx{client;constructor($){this.client=$}byId($){return G$.byId(this.client,$)}search($,O){return G$.search(this.client,$,O)}}class rx{client;constructor($){this.client=$}async list(){let{labels:$}=Q(await this.client.storage.listChannelLabels());return $}async create($,O=[]){return Q(await this.client.storage.createChannelLabel({body:{name:$,channelIds:O.map((j)=>j.id)}}))}async createSmartTag($,O){return Q(await this.client.storage.createChannelLabel({body:{name:$,rule:O}}))}async previewSmartTag($){return Q(await this.client.storage.previewSmartTag({body:$}))}async updateSmartTag($,O,j){return Q(await this.client.storage.renameChannelLabel({path:{label_id:$.id},body:{name:O,rule:j}}))}async rename($,O){return Q(await this.client.storage.renameChannelLabel({path:{label_id:$.id},body:{name:O}}))}async delete($){Q(await this.client.storage.deleteChannelLabel({path:{label_id:$.id}}))}async setLabel($,O){Q(await this.client.storage.setChannelLabel({path:{channel_id:$.id},body:{labelId:O?.id??null}}))}}class px{client;async activity(){return Q(await this.client.storage.getActivity()).map(($)=>new GO(this.client,b.byId(this.client,$.channel_id),$))}labels;constructor($){this.client=$;this.labels=new rx($)}byId($){return b.byId(this.client,$)}async dm($){return b.dm(this.client,$)}async private($){return b.private(this.client,$)}async create($){return b.create(this.client,$)}async list(){let{items:$}=Q(await this.client.storage.getChannels());return $.map((O)=>b.byId(this.client,O.id.toString()))}async*search($,O){if(!O?.searchOn||O.searchOn==="name"){let{items:j}=Q(await this.client.storage.getChannels()),x=$.toLowerCase();for(let S of j)if(S.name?.toLowerCase().includes(x))yield b.byId(this.client,S.id.toString())}else yield*b.search(this.client,$,O)}}class aO{client;chat;id;message;constructor($,O,j,x){this.client=$;this.chat=O;this.id=j;this.message=x}static byId($,O,j,x){return new aO($,O,j,x)}async stop(){Q(await this.client.cognition.stopChatStream({body:{chat_id:this.chat.id,stream_id:this.id}}))}toJSON(){return{id:this.id,chatId:this.chat.id,messageId:this.message.id}}}class iO extends M{chat;constructor($,O,j){super($,j);this.chat=O}static byId($,O,j){return new iO($,O,j)}async fetch(){let $=Q(await this.client.cognition.getChat({path:{chat_id:this.chat.id}})).chat.messages.find((O)=>O.id===this.id);if(!$)throw new E(`Chat message ${this.id} is not yet available`);return $}content=this.field("content");role=this.field("role");async refresh(){this.detail.clear(),await this.detail.get()}toJSON(){return{...super.toJSON(),chatId:this.chat.id}}}class K$ extends X${async send($){let{attachments:O,additionalInstructions:j,...x}=$,S=await this.mutate((Z)=>Z.cognition.sendChatMessage({body:{...x,chat_id:this.id,additional_instructions:j,attachments:O?.map((X)=>({entity_id:X.entity.id,entity_type:X.type}))}})),K=K$.byId(this.client,S.chat_id);return aO.byId(this.client,K,S.stream_id,iO.byId(this.client,K,S.message_id))}access=new o(this.client,"chat",this);entityType="chat";propertyEntityType="CHAT";async fetch(){let{chat:$}=Q(await this.client.cognition.getChat({path:{chat_id:this.id}}));return $}static byId($,O){return new K$($,O)}static async create($,O){let{id:j}=Q(await $.cognition.createChat({body:{name:O?.name??null,projectId:O?.project?.id??null}}));return new K$($,j)}name=this.field("name");model=this.field("model");project=this.mappedField("projectId",($)=>$?n.byId(this.client,$):void 0);createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");messages=this.field("messages");async rename($){await this.mutate((O)=>O.cognition.patchChat({path:{chat_id:this.id},body:{name:$}}))}async delete($){await this.mutate((O)=>$?.permanent?O.cognition.permanentlyDeleteChat({path:{chat_id:this.id}}):O.cognition.deleteChat({path:{chat_id:this.id}}))}async copy(){let{id:$}=await this.mutate((O)=>O.cognition.copyChat({path:{chat_id:this.id}}));return new K$(this.client,$)}async restore(){await this.mutate(($)=>$.cognition.revertDeleteChat({path:{chat_id:this.id}}))}async history(){let{conversation:$}=Q(await this.client.cognition.getChatHistoryHandler({path:{chat_id:this.id}}));return $}webUrl(){return`${this.client.webAppUrl}/app/chat/${this.id}`}static search=x$({filters:{chat_filters:{}},type:"chat",make:($,O)=>new K$($,O.chat_id)});toMention(){return{tag:i$("m-document-mention",{documentId:this.id,documentName:this.detail.peek()?.name??"",blockName:"chat",blockParams:{}}),mention:{entity_type:"chat",entity_id:this.id}}}}class ax{client;constructor($){this.client=$}byId($){return K$.byId(this.client,$)}create($){return K$.create(this.client,$)}search($,O){return K$.search(this.client,$,O)}}var l6=8;class M$ extends M{parent;constructor($,O,j,x){super($,j,x);this.parent=O}get path(){return{parent_type:this.parent.type,parent_id:this.parent.id,id:this.id}}async fetch(){return Q(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new M$($,O,j)}static from($,O,j){return new M$($,O,j.id,j)}text=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");deletedAt=this.field("deleted_at");async threadId(){return(await this.detail.get()).thread_id??this.id}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){return nO(this.client,this.parent,$,{threadId:await this.threadId()})}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}async function Nj($,O){let j={parent_type:O.type,parent_id:O.id},x=u(async(K)=>{let Z=Q(await $.storage.messageTimeline({path:j,query:{selection:JSON.stringify({limit:100,cursor:K})}}));return{items:Z.items,nextCursor:Z.next_cursor}}),S=[];for await(let K of x)S.push(K);return cO(S,l6,async(K)=>{let{state:Z,root:X,replies:Y}=Q(await $.storage.entityMessageGetThread({path:{...j,id:K.id}}));return{thread:Z,comments:[X,...Y].map((L)=>M$.from($,O,L))}})}async function nO($,O,j,x){let S=Q(await $.storage.entityMessageCreate({path:{parent_type:O.type,parent_id:O.id},body:{...O$(j),thread_id:x?.threadId??null}}));return M$.from($,O,S)}class f$ extends z${messageThreadById($){return L$.byId(this.client,{type:"crm_contact",entity:this},$)}timelinePage($){return w$(this.client,{type:"crm_contact",entity:this},(O)=>M$.from(this.client,{type:"crm_contact",id:this.id},O),$)}entityType="crm_contact";async fetch(){return Q(await this.client.storage.getContact({path:{contact_id:this.id}}))}static byId($,O){return new f$($,O)}static from($,O){return new f$($,O.id,O)}name=this.field("name");email=this.field("email");company=this.mappedField("companyId",($)=>b$.byId(this.client,$));hidden=this.field("hidden");createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");firstInteraction=this.field("firstInteraction");lastInteraction=this.field("lastInteraction");async hide(){await this.setHidden(!0)}async unhide(){await this.setHidden(!1)}async setHidden($){await this.mutate((O)=>O.storage.setContactHidden({path:{contact_id:this.id},body:{hidden:$}}))}async rename($){await this.mutate((O)=>O.storage.setCrmContactName({path:{contact_id:this.id},body:{name:$}}))}get commentParent(){return{type:"crm_contact",id:this.id}}async comments(){return Nj(this.client,this.commentParent)}async comment($,O){return nO(this.client,this.commentParent,$,O)}commentById($){return M$.byId(this.client,this.commentParent,$)}}class b$ extends X${messageThreadById($){return L$.byId(this.client,{type:"crm_company",entity:this},$)}timelinePage($){return w$(this.client,{type:"crm_company",entity:this},(O)=>M$.from(this.client,{type:"crm_company",id:this.id},O),$)}entityType="crm_company";propertyEntityType="COMPANY";async fetch(){return Q(await this.client.storage.getCompany({path:{company_id:this.id}}))}static byId($,O){return new b$($,O)}static from($,O){return new b$($,O.id,O)}name=this.field("name");description=this.field("description");hidden=this.field("hidden");emailSync=this.field("emailSync");team=this.mappedField("teamId",($)=>S$.byId(this.client,$));createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");async domain(){let{domains:$}=await this.detail.get();return $[0]?.domain}async domains(){let{domains:$}=await this.detail.get();return $.map((O)=>O.domain)}async contacts(){return Q(await this.client.storage.listCompanyContacts({path:{company_id:this.id}})).map((O)=>f$.from(this.client,O))}static search=x$({filters:{crm_company_filters:{}},type:"company",includeCrm:!0,make:($,O)=>new b$($,O.id)});async hide(){await this.setHidden(!0)}async unhide(){await this.setHidden(!1)}async setHidden($){await this.mutate((O)=>O.storage.setCompanyHidden({path:{company_id:this.id},body:{hidden:$}}))}async setEmailSync($){await this.mutate((O)=>O.storage.setEmailSync({path:{company_id:this.id},body:{email_sync:$}}))}async rename($){await this.mutate((O)=>O.storage.setCrmCompanyName({path:{company_id:this.id},body:{name:$}}))}async createContact($){let O=await this.mutate((j)=>j.storage.createCrmContact({path:{company_id:this.id},body:$}));return f$.from(this.client,O)}get commentParent(){return{type:"crm_company",id:this.id}}async comments(){return Nj(this.client,this.commentParent)}async comment($,O){return nO(this.client,this.commentParent,$,O)}commentById($){return M$.byId(this.client,this.commentParent,$)}}class t$ extends M{tableDetail=new W$(async()=>Q(await this.client.storage.getCrmPipelineTable({path:{id:this.id}})));static byId($,O){return new t$($,O)}static from($,O){return new t$($,O.id,O)}async fetch(){return Q(await this.client.storage.getCrmPipeline({path:{id:this.id}}))}name=this.field("name");recordType=this.field("recordType");accessLevel=this.field("grant");sharing=this.field("sharing");owner=this.mappedField("userId",($)=>P.byId(this.client,$));team=this.mappedField("teamId",($)=>S$.byId(this.client,$));async rename($){await this.mutate((O)=>O.storage.renameCrmPipeline({path:{id:this.id},body:{name:$}}))}async setSharing($){if($===void 0)throw Error("Sharing is required");await this.mutate((O)=>O.storage.shareCrmPipeline({path:{id:this.id},body:{sharing:$}}))}async setTrashed($){await this.mutate((O)=>O.storage.trashCrmPipeline({path:{id:this.id},body:{trashed:$}}))}async sharePermissions(){return Q(await this.client.storage.getCrmPipelinePermissions({path:{id:this.id}}))}async updateSharePermissions($){return this.mutate((O)=>O.storage.updateCrmPipelinePermissions({path:{id:this.id},body:n$($)}))}async table(){return Uj.from(this.client,this,await this.tableRecord())}tableRecord(){return this.tableDetail.get()}rows(){return u(async($)=>{let O=Q(await this.client.storage.getCrmPipelineRows({path:{id:this.id},query:{after:$}}));return{items:O.rows.map((j)=>VO.from(this.client,this,j)),nextCursor:O.next}})}queryRows($={}){if($.rows?.some((O)=>O.pipeline.id!==this.id))throw Error("Rows belong to another pipeline");return u(async(O)=>{let j=Q(await this.client.storage.queryCrmPipelineRows({path:{id:this.id},body:{after:O,query:$.query,rowIds:$.rows?.map((x)=>x.id)}}));return{items:j.rows.map((x)=>VO.from(this.client,this,x)),nextCursor:j.next}})}async applyOps($,O){if(O?.baseVersions?.some((S)=>S.table.pipeline.id!==this.id))throw Error("Table belongs to another pipeline");let j={ops:$,baseVersions:O?.baseVersions?Object.fromEntries(O.baseVersions.map((S)=>[S.table.id,S.version])):void 0},x=await this.mutate((S)=>S.storage.applyCrmPipelineOps({path:{id:this.id},body:j}));return this.tableDetail.clear(),x}}class Uj extends M{pipeline;toJSON(){return{...super.toJSON(),pipelineId:this.pipeline.id}}constructor($,O,j){super($,j.table.id,j);this.pipeline=O}static from($,O,j){return new Uj($,O,j)}fetch(){return this.pipeline.tableRecord()}async columns(){return(await this.pipeline.tableRecord()).columns.map(($)=>zj.from(this.client,this,$))}async version(){return(await this.pipeline.tableRecord()).table.version}rowById($){return VO.byId(this.client,this.pipeline,$)}rows(){return this.pipeline.rows()}}class VO extends M{pipeline;toJSON(){return{...super.toJSON(),pipelineId:this.pipeline.id}}constructor($,O,j,x){super($,j,x);this.pipeline=O}static byId($,O,j){return new VO($,O,j)}static from($,O,j){return new VO($,O,j.rowId,j)}async fetch(){for await(let $ of this.pipeline.queryRows({rows:[this]}))if($.id===this.id)return $.detail.get();throw new E(`Pipeline row ${this.id} is unavailable`)}cells=this.field("cells");async refresh(){this.detail.clear(),await this.detail.get()}}class zj extends M{table;toJSON(){return{...super.toJSON(),pipelineId:this.table.pipeline.id,tableId:this.table.id}}constructor($,O,j){super($,j.column.id,j);this.table=O}static from($,O,j){return new zj($,O,j)}async fetch(){let $=(await this.table.pipeline.tableRecord()).columns.find((O)=>O.column.id===this.id);if(!$)throw new E(`Pipeline column ${this.id} is unavailable`);return $}async writable(){return(await this.fetch()).writable}async name(){return(await this.fetch()).column.display_name??(await this.fetch()).definition.definition.display_name}}class ix{client;constructor($){this.client=$}byId($){return t$.byId(this.client,$)}async list(){return Q(await this.client.storage.listCrmPipelines()).map(($)=>t$.from(this.client,$))}async create($){return t$.from(this.client,Q(await this.client.storage.createCrmPipeline({body:$})))}}class nx{client;pipelines;constructor($){this.client=$;this.pipelines=new ix($)}companyById($){return b$.byId(this.client,$)}contactById($){return f$.byId(this.client,$)}async contactByEmail($){let{contact:O}=Q(await this.client.storage.getContactByEmail({query:{email:$}}));return O?f$.from(this.client,O):void 0}async searchContacts($,O={}){let{contacts:j}=Q(await this.client.storage.searchContacts({query:{query:$,limit:O.limit}}));return j.map((x)=>f$.from(this.client,x))}async createCompany($){return b$.from(this.client,Q(await this.client.storage.createCrmCompany({body:$})))}async settings(){return Q(await this.client.storage.getCrmTeamSettings())}async updateSettings($){return Q(await this.client.storage.putCrmTeamSettings({body:$}))}async setStages($){return Q(await this.client.storage.putCrmTeamStages({body:$}))}async resetStages(){Q(await this.client.storage.resetCrmTeamStages())}searchCompanies($){return b$.search(this.client,$)}}var Q$=Symbol.for("@ts-pattern/matcher"),v1=Symbol.for("@ts-pattern/isVariadic");var sx=($)=>Boolean($&&typeof $=="object"),Ij=($)=>$&&!!$[Q$],s=($,O,j)=>{if(Ij($)){let x=$[Q$](),{matched:S,selections:K}=x.match(O);return S&&K&&Object.keys(K).forEach((Z)=>j(Z,K[Z])),S}if(sx($)){if(!sx(O))return!1;if(Array.isArray($)){if(!Array.isArray(O))return!1;let x=[],S=[],K=[];for(let Z of $.keys()){let X=$[Z];Ij(X)&&X[v1]?K.push(X):K.length?S.push(X):x.push(X)}if(K.length){if(K.length>1)throw Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(O.lengths(L,Z[G],j))&&S.every((L,G)=>s(L,X[G],j))&&(K.length===0||s(K[0],Y,j))}return $.length===O.length&&$.every((Z,X)=>s(Z,O[X],j))}return Reflect.ownKeys($).every((x)=>{let S=$[x];return((x in O)||Ij(K=S)&&K[Q$]().matcherType==="optional")&&s(S,O[x],j);var K})}return Object.is(O,$)},Y$=($)=>{var O,j,x;return sx($)?Ij($)?(O=(j=(x=$[Q$]()).getSelectionKeys)==null?void 0:j.call(x))!=null?O:[]:Array.isArray($)?sO($,Y$):sO(Object.values($),Y$):[]},sO=($,O)=>$.reduce((j,x)=>j.concat(O(x)),[]);function r6(...$){if($.length===1){let[O]=$;return(j)=>s(O,j,()=>{})}if($.length===2){let[O,j]=$;return s(O,j,()=>{})}throw Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${$.length}.`)}function t($){return Object.assign($,{optional:()=>ox($),and:(O)=>d($,O),or:(O)=>h1($,O),select:(O)=>O===void 0?tO($):tO(O,$)})}function tx($){return Object.assign(((O)=>Object.assign(O,{[Symbol.iterator](){let j=0,x=[{value:Object.assign(O,{[v1]:!0}),done:!1},{done:!0,value:void 0}];return{next:()=>{var S;return(S=x[j++])!=null?S:x.at(-1)}}}}))($),{optional:()=>tx(ox($)),select:(O)=>tx(O===void 0?tO($):tO(O,$))})}function ox($){return t({[Q$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return O===void 0?(Y$($).forEach((S)=>x(S,void 0)),{matched:!0,selections:j}):{matched:s($,O,x),selections:j}},getSelectionKeys:()=>Y$($),matcherType:"optional"})})}var p6=($,O)=>{for(let j of $)if(!O(j))return!1;return!0},a6=($,O)=>{for(let[j,x]of $.entries())if(!O(x,j))return!1;return!0},i6=($,O)=>{let j=Reflect.ownKeys($);for(let x of j)if(!O(x,$[x]))return!1;return!0};function d(...$){return t({[Q$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return{matched:$.every((S)=>s(S,O,x)),selections:j}},getSelectionKeys:()=>sO($,Y$),matcherType:"and"})})}function h1(...$){return t({[Q$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return sO($,Y$).forEach((S)=>x(S,void 0)),{matched:$.some((S)=>s(S,O,x)),selections:j}},getSelectionKeys:()=>sO($,Y$),matcherType:"or"})})}function m($){return{[Q$]:()=>({match:(O)=>({matched:Boolean($(O))})})}}function tO(...$){let O=typeof $[0]=="string"?$[0]:void 0,j=$.length===2?$[1]:typeof $[0]=="string"?void 0:$[0];return t({[Q$]:()=>({match:(x)=>{let S={[O!=null?O:"@ts-pattern/anonymous-select-key"]:x};return{matched:j===void 0||s(j,x,(K,Z)=>{S[K]=Z}),selections:S}},getSelectionKeys:()=>[O!=null?O:"@ts-pattern/anonymous-select-key"].concat(j===void 0?[]:Y$(j))})})}function m1($){return!0}function k$($){return typeof $=="number"}function e$($){return typeof $=="string"}function o$($){return typeof $=="bigint"}var c1=t(m(m1)),n6=t(m(m1)),s6=c1,$O=($)=>Object.assign(t($),{startsWith:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.startsWith(j)))));var j},endsWith:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.endsWith(j)))));var j},minLength:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length>=j))(O))),length:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length===j))(O))),maxLength:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length<=j))(O))),includes:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.includes(j)))));var j},regex:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&Boolean(x.match(j))))));var j}}),y1=$O(m(e$)),g$=($)=>Object.assign(t($),{between:(O,j)=>g$(d($,((x,S)=>m((K)=>k$(K)&&x<=K&&S>=K))(O,j))),lt:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&xg$(d($,((j)=>m((x)=>k$(x)&&x>j))(O))),lte:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&x<=j))(O))),gte:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&x>=j))(O))),int:()=>g$(d($,m((O)=>k$(O)&&Number.isInteger(O)))),finite:()=>g$(d($,m((O)=>k$(O)&&Number.isFinite(O)))),positive:()=>g$(d($,m((O)=>k$(O)&&O>0))),negative:()=>g$(d($,m((O)=>k$(O)&&O<0)))}),t6=g$(m(k$)),OO=($)=>Object.assign(t($),{between:(O,j)=>OO(d($,((x,S)=>m((K)=>o$(K)&&x<=K&&S>=K))(O,j))),lt:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&xOO(d($,((j)=>m((x)=>o$(x)&&x>j))(O))),lte:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&x<=j))(O))),gte:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&x>=j))(O))),positive:()=>OO(d($,m((O)=>o$(O)&&O>0))),negative:()=>OO(d($,m((O)=>o$(O)&&O<0)))}),e6=OO(m(o$)),o6=t(m(function($){return typeof $=="boolean"})),$7=t(m(function($){return typeof $=="symbol"})),O7=t(m(function($){return $==null})),j7=t(m(function($){return $!=null})),Z$={__proto__:null,matcher:Q$,optional:ox,array:function(...$){return tx({[Q$]:()=>({match:(O)=>{if(!Array.isArray(O))return{matched:!1};if($.length===0)return{matched:!0};let j=$[0],x={};if(O.length===0)return Y$(j).forEach((K)=>{x[K]=[]}),{matched:!0,selections:x};let S=(K,Z)=>{x[K]=(x[K]||[]).concat([Z])};return{matched:O.every((K)=>s(j,K,S)),selections:x}},getSelectionKeys:()=>$.length===0?[]:Y$($[0])})})},set:function(...$){return t({[Q$]:()=>({match:(O)=>{if(!(O instanceof Set))return{matched:!1};let j={};if(O.size===0)return{matched:!0,selections:j};if($.length===0)return{matched:!0};let x=(K,Z)=>{j[K]=(j[K]||[]).concat([Z])},S=$[0];return{matched:p6(O,(K)=>s(S,K,x)),selections:j}},getSelectionKeys:()=>$.length===0?[]:Y$($[0])})})},map:function(...$){return t({[Q$]:()=>({match:(O)=>{if(!(O instanceof Map))return{matched:!1};let j={};if(O.size===0)return{matched:!0,selections:j};let x=(X,Y)=>{j[X]=(j[X]||[]).concat([Y])};if($.length===0)return{matched:!0};var S;if($.length===1)throw Error(`\`P.map\` wasn't given enough arguments. Expected (key, value), received ${(S=$[0])==null?void 0:S.toString()}`);let[K,Z]=$;return{matched:a6(O,(X,Y)=>{let L=s(K,Y,x),G=s(Z,X,x);return L&&G}),selections:j}},getSelectionKeys:()=>$.length===0?[]:[...Y$($[0]),...Y$($[1])]})})},record:function(...$){return t({[Q$]:()=>({match:(O)=>{if(O===null||typeof O!="object"||Array.isArray(O))return{matched:!1};var j;if($.length===0)throw Error(`\`P.record\` wasn't given enough arguments. Expected (value) or (key, value), received ${(j=$[0])==null?void 0:j.toString()}`);let x={},S=(X,Y)=>{x[X]=(x[X]||[]).concat([Y])},[K,Z]=$.length===1?[y1,$[0]]:$;return{matched:i6(O,(X,Y)=>{let L=typeof X!="string"||Number.isNaN(Number(X))?null:Number(X),G=L!==null&&s(K,L,S),J=s(K,X,S),I=s(Z,Y,S);return(J||G)&&I}),selections:x}},getSelectionKeys:()=>$.length===0?[]:[...Y$($[0]),...Y$($[1])]})})},intersection:d,union:h1,not:function($){return t({[Q$]:()=>({match:(O)=>({matched:!s($,O,()=>{})}),getSelectionKeys:()=>[],matcherType:"not"})})},when:m,select:tO,any:c1,unknown:n6,_:s6,string:y1,number:t6,bigint:e6,boolean:o6,symbol:$7,nullish:O7,nonNullable:j7,instanceOf:function($){return t(m(function(O){return(j)=>j instanceof O}($)))},shape:function($){return t(m(r6($)))}};class u1 extends Error{constructor($){let O;try{O=JSON.stringify($)}catch(j){O=$}super(`Pattern matching error: no pattern matches value ${O}`),this.input=void 0,this.input=$}}var ex={matched:!1,value:void 0};function c($){return new Tj($,ex)}class Tj{constructor($,O){this.input=void 0,this.state=void 0,this.input=$,this.state=O}with(...$){if(this.state.matched)return this;let O=$[$.length-1],j=[$[0]],x;$.length===3&&typeof $[1]=="function"?x=$[1]:$.length>2&&j.push(...$.slice(1,$.length-1));let S=!1,K={},Z=(Y,L)=>{S=!0,K[Y]=L},X=!j.some((Y)=>s(Y,this.input,Z))||x&&!Boolean(x(this.input))?ex:{matched:!0,value:O(S?"@ts-pattern/anonymous-select-key"in K?K["@ts-pattern/anonymous-select-key"]:K:this.input,this.input)};return new Tj(this.input,X)}when($,O){if(this.state.matched)return this;let j=Boolean($(this.input));return new Tj(this.input,j?{matched:!0,value:O(this.input,this.input)}:ex)}otherwise($){return this.state.matched?this.state.value:$(this.input)}exhaustive($=x7){return this.state.matched?this.state.value:$(this.input)}run(){return this.exhaustive()}returnType(){return this}narrow(){return this}}function x7($){throw new u1($)}var $0,S7=new Uint8Array(16);function Hj(){if(!$0){if(typeof crypto>"u"||!crypto.getRandomValues)throw Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");$0=crypto.getRandomValues.bind(crypto)}return $0(S7)}var j$=[];for(let $=0;$<256;++$)j$.push(($+256).toString(16).slice(1));function d1($,O=0){return(j$[$[O+0]]+j$[$[O+1]]+j$[$[O+2]]+j$[$[O+3]]+"-"+j$[$[O+4]]+j$[$[O+5]]+"-"+j$[$[O+6]]+j$[$[O+7]]+"-"+j$[$[O+8]]+j$[$[O+9]]+"-"+j$[$[O+10]]+j$[$[O+11]]+j$[$[O+12]]+j$[$[O+13]]+j$[$[O+14]]+j$[$[O+15]]).toLowerCase()}var O0={};function Z7($,O,j){let x;if($)x=l1($.random??$.rng?.()??Hj(),$.msecs,$.seq,O,j);else{let S=Date.now(),K=Hj();X7(O0,S,K),x=l1(K,O0.msecs,O0.seq,O,j)}return O??d1(x)}function X7($,O,j){if($.msecs??=-1/0,$.seq??=0,O>$.msecs)$.seq=j[6]<<23|j[7]<<16|j[8]<<8|j[9],$.msecs=O;else if($.seq=$.seq+1|0,$.seq===0)$.msecs++;return $}function l1($,O,j,x,S=0){if($.length<16)throw Error("Random bytes length must be >= 16");if(!x)x=new Uint8Array(16),S=0;else if(S<0||S+16>x.length)throw RangeError(`UUID byte range ${S}:${S+15} is out of buffer bounds`);return O??=Date.now(),j??=$[6]*127<<24|$[7]<<16|$[8]<<8|$[9],x[S++]=O/1099511627776&255,x[S++]=O/4294967296&255,x[S++]=O/16777216&255,x[S++]=O/65536&255,x[S++]=O/256&255,x[S++]=O&255,x[S++]=112|j>>>28&15,x[S++]=j>>>20&255,x[S++]=128|j>>>14&63,x[S++]=j>>>6&255,x[S++]=j<<2&255|$[10]&3,x[S++]=$[11],x[S++]=$[12],x[S++]=$[13],x[S++]=$[14],x[S++]=$[15],x}var d$=Z7;class A${table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new A$($,O)}async detail(){let{columns:$}=await this.table.detail(),O=$.find((j)=>j.column.id===this.id);if(!O)throw new E(`column ${this.id} is not on table ${this.table.id}`);return O}async name(){let $=await this.detail();return $.column.display_name??$.definition.definition.display_name}async rename($){return await this.table.database.renameColumn(this,$),this}async inferType($){return await this.table.database.inferColumnType(this,$),this}changeType($){return this.table.database.changeColumnType(this,$)}convertIntoNewColumn($){return this.table.database.convertColumnIntoNewColumn(this,$)}casts(){return this.table.database.columnCasts(this)}async delete(){await this.table.database.deleteColumn(this)}async dataType(){return(await this.detail()).definition.definition.data_type}async isMultiSelect(){return(await this.detail()).definition.definition.is_multi_select}async position(){return(await this.detail()).column.position}async definition(){return(await this.detail()).definition}async config(){return(await this.detail()).column.config??void 0}async addOptions($){return await this.table.database.addColumnOptions(this,$),this}toJSON(){return{id:this.id,tableId:this.table.id}}}class F${table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new F$($,O)}history(){return this.table.database.rowHistory(this)}toJSON(){return{id:this.id,tableId:this.table.id}}}class Rj{table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new Rj($,O)}async detail(){let{views:$}=await this.table.detail(),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`view ${this.id} is not on table ${this.table.id}`);return O}async name(){return(await this.detail()).name}async position(){return(await this.detail()).position}async layout(){return(await this.detail()).layout}async query(){return(await this.detail()).query}positions(){return this.table.database.viewPositions(this)}toJSON(){return{id:this.id,tableId:this.table.id}}}class J${database;id;constructor($,O){this.database=$;this.id=O}static byId($,O){return new J$($,O)}async detail(){let{tables:$}=await this.database.schema(),O=$.find((j)=>j.table.id===this.id);if(!O)throw new E(`table ${this.id} is not in database ${this.database.id}`);return O}async name(){return(await this.detail()).table.name}async rename($){return await this.database.renameTable(this,$),this}async version(){return(await this.detail()).table.version}async position(){return(await this.detail()).table.position}async columns(){let{columns:$}=await this.detail();return $.map((O)=>A$.byId(this,O.column.id))}addColumn($){return this.database.addColumn(this,$)}async reorderColumns($){return await this.database.reorderColumns(this,$),this}row($){return F$.byId(this,$)}async views(){let{views:$}=await this.detail();return $.map((O)=>Rj.byId(this,O.id))}createWebhook(){return this.database.createWebhook(this)}async delete(){await this.database.deleteTable(this)}toJSON(){return{id:this.id,databaseId:this.database.id}}}async function Dj($,O,j,x={}){let S=Q(await $.storage.queryDatabases({body:{sql:j,databaseId:x.database?.id,baseVersions:Object.fromEntries((x.baseVersions??[]).map(({table:G,version:J})=>[G.id,J]))}})),K=new Map;for(let G of[x.database,...(x.baseVersions??[]).map(({table:J})=>J.database)]){if(!G)continue;let J=K.get(G.id);if(J)J.add(G);else K.set(G.id,new Set([G]))}let Z=(G)=>{let J=K.get(G)?.values().next().value;if(J)return J;let I=O($,G);return K.set(G,new Set([I])),I},X=(G)=>{let J=S.tableDatabases[G];if(!J)throw Error(`SQL response is missing the owner of table ${G}`);return J$.byId(Z(J),G)},Y=new Set(Object.keys(S.newVersions).map((G)=>X(G).database.id));if(S.statement.kind==="schema")Y.add(S.statement.databaseId);for(let G of Y)for(let J of K.get(G)??[])J.invalidateSchema();let L=c(S.statement).with({kind:"select"},(G)=>G).with({kind:"schema"},({databaseId:G,summary:J})=>({kind:"schema",database:Z(G),summary:J})).with({kind:"insert"},{kind:"update"},{kind:"delete"},({kind:G,tableId:J,tableName:I})=>({kind:G,table:X(J),tableName:I})).with({kind:"alterColumnType"},({tableId:G,tableName:J,columnId:I,columnName:z,to:W})=>{let V=X(G);return{kind:"alterColumnType",table:V,tableName:J,column:A$.byId(V,I),columnName:z,to:W}}).exhaustive();return{result:S.result?K7(S.result,X,S.tableDatabases):void 0,changesApplied:S.changesApplied,insertedRows:L.kind==="insert"?S.insertedRowIds.map((G)=>F$.byId(L.table,G)):[],newVersions:Object.entries(S.newVersions).map(([G,J])=>({table:X(G),version:J})),readVersions:Object.entries(S.readVersions).map(([G,J])=>({table:X(G),version:J})),truncatedTables:S.truncatedTables,statement:L}}function K7($,O,j){let x=$.sourceTable&&j[$.sourceTable]?O($.sourceTable):void 0;return{columns:$.columns.map(({relatedTable:S,...K})=>({...K,relatedTable:S&&j[S]?O(S):void 0})),rows:$.rows,sourceTable:x,rowHandles:x?$.rowIds.map((S)=>F$.byId(x,S)):[]}}class Cj{table;id;createdBy;record;constructor($,O,j,x){this.table=$;this.id=O;this.createdBy=j;this.record=x}static fromRecord($,O,j){return new Cj($,j.id,O,j)}get tokenPrefix(){return this.record.tokenPrefix}get createdAt(){return this.record.createdAt}delete(){return this.table.database.deleteWebhook(this)}toJSON(){return{id:this.id,tableId:this.table.id,tokenPrefix:this.tokenPrefix}}}class S0 extends QO{op;row;column;taken;constructor($,O){super($,O);this.name="MacroOpRefusedError",this.message=O.message,this.op=O.op,this.row=O.row,this.column=O.column,this.taken=O.taken}}function _j($){return c($).with({type:"relation"},({table:O})=>({type:"relation",database:O.database.id,table:O.id})).with({type:Z$.not("relation")},(O)=>O).exhaustive()}var Y7={USER:"People",DOCUMENT:"Documents",TASK:"Tasks",COMPANY:"Companies",CONTACT:"Contacts",CALL_RECORD:"Calls",CHANNEL:"Channels",CHAT:"Chats",PROJECT:"Projects",THREAD:"Emails",CALENDAR_EVENT:"Events",INITIATIVE:"Initiatives"};function Q7($){return c($).with({type:"text"},()=>"Text").with({type:"number"},()=>"Number").with({type:"boolean"},()=>"Checkbox").with({type:"date"},()=>"Date").with({type:"link"},()=>"URL").with({type:"select",multi:!0},()=>"Multi-select").with({type:"select",multi:!1},()=>"Select").with({type:"select_number",multi:!0},()=>"Multi-number select").with({type:"select_number",multi:!1},()=>"Number select").with({type:"tag"},()=>"Tag").with({type:"entity"},({target:O})=>Y7[O]).with({type:"relation"},()=>"Relation").exhaustive(()=>"Column")}function j0($){return $.map((O)=>({id:d$(),label:O}))}function r1($,O,j){return $?.kind===O&&"change"in $&&$.change.kind===j}function x0($){return c($).with({kind:"reorder_tables"},({kind:O})=>O).with({kind:Z$.union("table","column","rows","view")},({kind:O,change:j})=>`${O}.${j.kind}`).exhaustive(()=>"unknown")}function l$($,O,j){let[x]=$;if($.length!==1||!r1(x,O,j))throw new f(`expected one ${O}.${j} result, got ${$.map(x0).join(", ")||"none"}`);return x}class V$ extends M{access=new o(this.client,"database",this);async fetch(){return Q(await this.client.storage.getDatabase({path:{id:this.id}}))}assertOwns($,O){if(O.id!==this.id)throw new f(`${$} does not belong to database ${this.id}`)}static byId($,O){return new V$($,O)}static async create($,O){let j=Q(await $.storage.createDatabase({body:{name:O.name}}));return new V$($,j.id)}static async list($){return Q(await $.storage.listDatabases()).map((j)=>new V$($,j.database.id))}query($,O){return Dj(this.client,V$.byId,$,{...O,database:this})}invalidateSchema(){this.detail.clear()}schema(){return this.detail.get()}name=this.mappedField("database",($)=>$.name);owner=this.mappedField("database",($)=>P.byId(this.client,$.owner_id));createdAt=this.mappedField("database",($)=>$.created_at);trashedAt=this.mappedField("database",($)=>$.trashed_at??void 0);grant=this.field("grant");tables=this.mappedField("tables",($)=>$.map((O)=>J$.byId(this,O.table.id)));async table($){let{tables:O}=await this.schema(),j=O.find((x)=>x.table.name===$);return j?J$.byId(this,j.table.id):void 0}async createTable($){let{table:O}=l$(await this.applyOps([{kind:"table",table:d$(),change:{kind:"create",name:$.name}}]),"table","created");return J$.byId(this,O)}async applyOps($,O={}){let j={ops:$};if(O.baseVersions!==void 0){for(let{table:S}of O.baseVersions)this.assertOwns(`table ${S.id}`,S.database);j.baseVersions=Object.fromEntries(O.baseVersions.map(({table:S,version:K})=>[S.id,K]))}let{results:x}=await this.mutate(async(S)=>{let K=await S.storage.applyDatabaseOps({path:{id:this.id},body:j});if(K.error!==void 0&&"op"in K.error)throw new S0(K.response?.status??0,K.error);return K});return x}async reorderTables($){for(let x of $)this.assertOwns(`table ${x.id}`,x.database);let O=await this.applyOps([{kind:"reorder_tables",order:$.map((x)=>x.id)}]),[j]=O;if(O.length!==1||j?.kind!=="reorder_tables")throw new f(`expected one reorder_tables result, got ${O.map(x0).join(", ")||"none"}`);return j.tables.map(({table:x})=>J$.byId(this,x))}async deleteTable($){this.assertOwns(`table ${$.id}`,$.database),l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"delete"}}]),"table","deleted")}async columnCasts($){return this.assertOwns(`column ${$.id}`,$.table.database),Q(await this.client.storage.listDatabaseColumnCasts({path:{id:this.id,table_id:$.table.id,column_id:$.id}}))}async viewPositions($){this.assertOwns(`view ${$.id}`,$.table.database);let{positions:O}=Q(await this.client.storage.getDatabaseViewPositions({path:{id:this.id,view_id:$.id}}));return O}async rowHistory($){this.assertOwns(`row ${$.id}`,$.table.database);let{changes:O}=Q(await this.client.storage.getDatabaseRowHistory({path:{id:this.id,table_id:$.table.id,row_id:$.id}}));return O}async importTable($){let O=await this.mutate((j)=>j.storage.importDatabaseTable({path:{id:this.id},body:$}));return J$.byId(this,O.id)}webhookOf($){return Cj.fromRecord(J$.byId(this,$.tableId),P.byId(this.client,$.createdBy),$)}async webhooks(){let{webhooks:$}=Q(await this.client.storage.listDatabaseWebhooks({path:{id:this.id}}));return $.map((O)=>this.webhookOf(O))}async createWebhook($){this.assertOwns("table",$.database);let O=Q(await this.client.storage.createDatabaseWebhook({path:{id:this.id},body:{tableId:$.id}}));return{webhook:this.webhookOf(O.webhook),token:O.token}}async deleteWebhook($){this.assertOwns("webhook",$.table.database),Q(await this.client.storage.deleteDatabaseWebhook({path:{id:this.id,webhook_id:$.id}}))}async sharePermissions(){return Q(await this.client.storage.getDatabasePermissions({path:{id:this.id}}))}updateSharePermissions($){return this.mutate((O)=>O.storage.updateDatabasePermissions({path:{id:this.id},body:$}))}async changeColumnType($,O){this.assertOwns(`column ${$.id}`,$.table.database);let j=await $.table.version();return l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"change_type",to:_j(O.to)}}],{baseVersions:[{table:$.table,version:j}]}),"column","type_changed")}async columnConversion($,O){return this.assertOwns(`column ${$.id}`,$.table.database),Q(await this.client.storage.convertDatabaseColumn({path:{id:this.id,table_id:$.table.id,column_id:$.id},body:{to:_j(O)}}))}async convertColumnIntoNewColumn($,O){let j=await this.columnConversion($,O.to),x=O.name??`${await $.name()} (${Q7(O.to)})`,S=d$(),K=[{kind:"column",table:$.table.id,column:S,change:{kind:"create",definition:{source:"new",name:x,type:_j(O.to),options:j0(j.options)},after:$.id}}];if(j.cells.length>0)K.push({kind:"rows",table:$.table.id,change:{kind:"update",changes:{kind:"per_row",rows:j.cells.map(({row:X,value:Y})=>({row:X,cells:[{column:S,value:Y}]}))}}});let[Z]=await this.applyOps(K,{baseVersions:[{table:$.table,version:j.tableVersion}]});if(!r1(Z,"column","created"))throw new f(`expected a column.created result, got ${Z?x0(Z):"none"}`);return A$.byId($.table,Z.column)}async deleteColumn($){this.assertOwns(`column ${$.id}`,$.table.database);let O=await $.table.version(),{tableVersion:j}=l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"delete"}}],{baseVersions:[{table:$.table,version:O}]}),"column","deleted");return j}async reorderColumns($,O){this.assertOwns(`table ${$.id}`,$.database);for(let S of O)if(S.table.id!==$.id)throw new f(`column ${S.id} does not belong to table ${$.id}`);let j=await $.version(),{tableVersion:x}=l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"reorder_columns",order:O.map((S)=>S.id)}}],{baseVersions:[{table:$,version:j}]}),"table","columns_reordered");if(x===void 0)throw new f(`table ${$.id} reordered its columns without a version`);return x}async renameTable($,O){this.assertOwns(`table ${$.id}`,$.database);let j=await $.name(),{tableVersion:x}=l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"rename",name:O,previousName:j}}]),"table","renamed");if(x===void 0)throw new f(`table ${$.id} was renamed without a version`);return x}async renameColumn($,O){this.assertOwns(`column ${$.id}`,$.table.database);let j=await $.name(),{tableVersion:x}=l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"rename",name:O,previousName:j}}]),"column","renamed");return x}async inferColumnType($,O){return this.assertOwns(`column ${$.id}`,$.table.database),this.mutate((j)=>j.storage.inferDatabaseColumnType({path:{id:this.id,table_id:$.table.id,column_id:$.id},body:{dataType:O.dataType,baseVersion:O.baseVersion,...O.specificEntityType!==void 0?{specificEntityType:O.specificEntityType}:{}}}))}async addColumn($,O){if(this.assertOwns(`table ${$.id}`,$.database),O.after!==void 0&&O.after.table.id!==$.id)throw new f(`column ${O.after.id} does not belong to table ${$.id}`);let j="property"in O?{source:"existing",property:O.property.id}:{source:"new",name:O.name,type:_j(O.type),...O.options!==void 0?{options:j0(O.options)}:{},...O.inferType!==void 0?{inferType:O.inferType}:{}},{column:x}=l$(await this.applyOps([{kind:"column",table:$.id,column:d$(),change:{kind:"create",definition:j,...O.after!==void 0?{after:O.after.id}:{}}}]),"column","created");return A$.byId($,x)}async addColumnOptions($,O){return this.assertOwns(`column ${$.id}`,$.table.database),l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"add_options",options:j0(O)}}]),"column","options_added")}}class Z0{client;constructor($){this.client=$}query($,O){return Dj(this.client,V$.byId,$,O)}byId($){return V$.byId(this.client,$)}create($){return V$.create(this.client,$)}list(){return V$.list(this.client)}}class Pj{id;name;constructor($,O){this.id=$;this.name=O}static async list($){let{skills:O}=Q(await $.storage.getSystemSkillsHandler());return O.map((j)=>new Pj(j.id,j.name))}}class X0{client;async byTeamSlug($){let O=Q(await this.client.storage.getDocumentByTeamSlug({path:{slug:$}}));if(typeof O!=="object"||O===null||!("data"in O)||typeof O.data!=="object"||O.data===null||!("documentMetadata"in O.data)||typeof O.data.documentMetadata!=="object"||O.data.documentMetadata===null||!("documentId"in O.data.documentMetadata)||typeof O.data.documentMetadata.documentId!=="string")throw Error("Invalid team task document response");return w.byId(this.client,O.data.documentMetadata.documentId)}async validatePermissionsToken($){let O=Q(await this.client.storage.validateDocumentPermissionsToken({body:{token:$}}));return{document:w.byId(this.client,O.document_id),user:O.user_id?P.byId(this.client,O.user_id):void 0,accessLevel:O.access_level,expiresAt:O.exp,issuer:O.iss}}async createUpload($){let O={documentName:$.name,sha:$.sha,fileType:$.fileType,mimeType:$.mimeType,projectId:$.project?.id,teamId:$.team?.id,branchedFromId:$.branchedFrom?.id,emailAttachmentId:$.attachment?.id,isTask:$.isTask},j=Q(await this.client.storage.createDocument({body:O})).data;return{document:w.byId(this.client,j.documentMetadata.documentId),uploadUrl:j.presignedUrl??void 0,contentType:j.contentType,content:j.documentMetadata.content}}constructor($){this.client=$}byId($){return w.byId(this.client,$)}create($){return w.create(this.client,$)}async createCanvas($){let O=Q(await this.client.storage.createCanvasHandler({body:{documentName:$.name,projectId:$.project?.id}}));return w.byId(this.client,O.documentId)}createSnippet($){return w.createSnippet(this.client,$)}createSkill($){return w.createSkill(this.client,$)}systemSkills(){return Pj.list(this.client)}search($,O){return w.search(this.client,$,O)}recent($){return w.recent(this.client,$)}recentlyDeleted(){return w.recentlyDeleted(this.client)}}class WO extends M{async fetch(){let{attachment:$}=Q(await this.client.email.getAttachment({path:{id:this.id}}));return $}static byId($,O){return new WO($,O)}static from($,O){return new WO($,O.db_id,O)}filename=this.field("filename");mimeType=this.field("mime_type");size=this.field("size_bytes");dataUrl=this.field("data_url");sfsId=this.field("sfs_id");contentId=this.field("content_id");async toDocument(){let{document_id:$}=Q(await this.client.email.getAttachmentDocumentId({path:{id:this.id}}));return w.byId(this.client,$)}}class R$ extends X${access=new o(this.client,"email_thread",this);async followup(){return Q(await this.client.storage.getEmailFollowup({path:{thread_id:this.id}}))}async setFollowup($){return Q(await this.client.storage.setEmailFollowup({path:{thread_id:this.id},body:$}))}async calendarInvitations(){return Q(await this.client.email.getThreadCalendarInvitations({path:{thread_id:this.id}}))}async addEventToCalendar($,O,j={}){let x=Q(await this.client.email.copyThreadCalendarInvitation({path:{thread_id:this.id,message_id:$.id,invitation_id:O.id},body:{calendarId:j.calendar?.id}}));return $$.fromRecord(this.client,x)}async update($){await this.mutate((O)=>O.storage.editThreadV2({path:{thread_id:this.id},body:{projectId:$.project===void 0?void 0:$.project?.id??null,sharePermission:$.sharePermission?n$($.sharePermission):void 0}}))}entityType="email_thread";propertyEntityType="THREAD";async fetch(){let{thread:$}=Q(await this.client.email.getThread({path:{thread_id:this.id},query:{limit:100}}));return $}static byId($,O){return new R$($,O)}createdAt=this.field("created_at");updatedAt=this.field("updated_at");isRead=this.field("is_read");inboxVisible=this.field("inbox_visible");accessLevel=this.field("access_level");providerId=this.field("provider_id");link=this.mappedField("link_id",($)=>T$.byId(this.client,$));project=this.mappedField("project_id",($)=>$?n.byId(this.client,$):void 0);latestInboundAt=this.field("latest_inbound_message_ts");latestOutboundAt=this.field("latest_outbound_message_ts");latestNonSpamAt=this.field("latest_non_spam_message_ts");async subject(){let{messages:$}=await this.detail.get();for(let O of $)if(O.subject)return O.subject;return}async participants(){let{messages:$}=await this.detail.get(),O=new Map;for(let j of $)for(let x of[j.from,...j.to,...j.cc,...j.bcc])if(x&&!O.has(x.email))O.set(x.email,x);return[...O.values()]}async messages($){return Q(await this.client.email.getThreadMessagesHandler({path:{id:this.id},query:{...$?.since?{since:$.since}:{},...$?.limit?{limit:$.limit}:{}}})).map((j)=>D$.from(this.client,j))}async attachments(){let{messages:$}=await this.detail.get();return $.flatMap((O)=>O.attachments.map((j)=>WO.from(this.client,j)))}async reply($){let O=$.subject??await this.subject()??"",{message:j}=await this.mutate((x)=>x.email.sendMessage({body:{message:{thread_db_id:this.id,replying_to_id:$.replyingTo?.id??null,to:$.to,cc:$.cc??null,bcc:$.bcc??null,subject:O,body_text:$.bodyText}}}));return j.db_id?D$.byId(this.client,j.db_id):void 0}async archive($=!0){await this.mutate((O)=>O.email.archiveThread({path:{id:this.id},body:{value:$}}))}async updateState($){await this.mutate((O)=>O.email.updateThreadState({path:{id:this.id},body:$}))}async operations(){return Q(await this.client.email.threadOperations({path:{id:this.id}}))}async markSeen(){await this.mutate(($)=>$.email.threadSeen({path:{id:this.id}}))}async addLabel($){await this.mutate((O)=>O.email.addRemoveThreadLabel({path:{id:this.id},body:{label_id:$.id,value:!0}}))}async removeLabel($){await this.mutate((O)=>O.email.addRemoveThreadLabel({path:{id:this.id},body:{label_id:$.id,value:!1}}))}async moveToProject($){await this.mutate((O)=>O.email.updateThreadProject({path:{thread_id:this.id},body:{projectId:$?.id??null}}))}static search=x$({filters:{email_filters:{}},type:"email",make:($,O)=>new R$($,O.thread_id)})}class D$ extends M{async fetch(){return Q(await this.client.email.getMessage({path:{id:this.id}}))}static byId($,O){return new D$($,O)}static from($,O){return new D$($,O.db_id,O)}static async send($,O){let{message:j}=Q(await $.email.sendMessage({body:{message:{to:O.to,cc:O.cc??null,bcc:O.bcc??null,subject:O.subject,body_text:O.bodyText}}}));return j.db_id?D$.byId($,j.db_id):void 0}subject=this.field("subject");from=this.field("from");to=this.field("to");cc=this.field("cc");bcc=this.field("bcc");body=this.field("body_parsed");sentAt=this.field("internal_date_ts");labels=this.field("labels");link=this.mappedField("link_id",($)=>T$.byId(this.client,$));async operationStatus(){return Q(await this.client.email.messageOperationStatus({path:{id:this.id}}))}async resolveOperation($){await this.mutate((O)=>O.email.resolveMessageOperation({path:{id:this.id},body:$}))}async completeDraftAttachment($,O=0){let j=await this.link();await this.mutate((x)=>x.email.completeDraftAttachment({path:{id:this.id,attachment_id:$},query:{draft_generation:O},headers:{"X-Email-Link-Id":j.id}}))}async transferDraft($){let O=await this.detail.get();return this.mutate((j)=>j.email.transferDraft({path:{id:this.id},body:{...$,draft_generation:$.draft_generation??O.draft_generation??0},headers:{"X-Email-Link-Id":O.link_id}}))}async addLabel($){await this.mutate((O)=>O.email.addRemoveLabel({body:{label_id:$.id,message_ids:[this.id],value:!0}}))}async removeLabel($){await this.mutate((O)=>O.email.addRemoveLabel({body:{label_id:$.id,message_ids:[this.id],value:!1}}))}async thread(){return R$.byId(this.client,(await this.detail.get()).thread_db_id)}}class BO extends D${async draftContext(){let $=await this.detail.get();return{headers:{"X-Email-Link-Id":$.link_id},query:{draft_generation:$.draft_generation??0}}}static byId($,O){return new BO($,O)}draftGeneration=this.field("draft_generation");async update($){let{headers:O,query:j}=await this.draftContext();await this.mutate((x)=>x.email.createDraft({headers:O,body:{draft:{...K0($),db_id:this.id,draft_generation:$.draftGeneration??j.draft_generation}}}))}async delete(){let{headers:$,query:O}=await this.draftContext();await this.mutate((j)=>j.email.deleteDraft({path:{id:this.id},headers:$,query:O}))}async schedule($,O){let{headers:j,query:x}=await this.draftContext();await this.mutate((S)=>S.email.upsertScheduledMessage({path:{id:this.id},headers:j,query:x,body:{send_time:$,include_signature:O?.includeSignature}}))}async unschedule(){let{headers:$,query:O}=await this.draftContext();await this.mutate((j)=>j.email.deleteScheduledDraft({path:{message_id:this.id},headers:$,query:O}))}async addAttachment($){let O={file_name:$.fileName,sha:$.sha,size:$.size,upload_id:$.uploadId},{headers:j,query:x}=await this.draftContext(),S=await this.mutate((K)=>K.email.addDraftAttachment({path:{id:this.id},headers:j,query:x,body:O}));return{attachment:eO.byId(this.client,this,S.attachment_id,!1,x.draft_generation),uploadUrl:S.upload_url,contentType:S.content_type}}async forwardAttachment($){let{headers:O,query:j}=await this.draftContext(),x=await this.mutate((S)=>S.email.addForwardedAttachment({path:{id:this.id},headers:O,query:j,body:{attachment_id:$.id}}));return eO.byId(this.client,this,x.attachment_id,!0,j.draft_generation)}async removeAttachment($){if($.draft.id!==this.id)throw Error("Attachment belongs to another draft");let{headers:O}=await this.draftContext(),j={draft_generation:$.draftGeneration};if($.forwarded)await this.mutate((x)=>x.email.removeForwardedAttachment({path:{id:this.id,attachment_id:$.id},headers:O,query:j}));else await this.mutate((x)=>x.email.removeDraftAttachment({path:{id:this.id,attachment_id:$.id},headers:O,query:j}))}async verifyAttachment($){if($.draft.id!==this.id||$.forwarded)throw Error("Expected an uploaded attachment on this draft");await this.completeDraftAttachment($.id,$.draftGeneration)}}class eO{draft;id;forwarded;draftGeneration;constructor($,O,j,x){this.draft=$;this.id=O;this.forwarded=j;this.draftGeneration=x}static byId($,O,j,x=!1,S=0){return new eO(O,j,x,S)}complete(){return this.draft.verifyAttachment(this)}remove(){return this.draft.removeAttachment(this)}toJSON(){return{id:this.id,draftId:this.draft.id,forwarded:this.forwarded,draftGeneration:this.draftGeneration}}}function K0($){let{bodyText:O,bodyHtml:j,bodyMacro:x,headers:S,includeSignature:K,draftGeneration:Z,thread:X,replyingTo:Y,...L}=$;return{...L,body_text:O,body_html:j===void 0?void 0:btoa(Array.from(new TextEncoder().encode(j),(G)=>String.fromCharCode(G)).join("")).replaceAll("+","-").replaceAll("/","_").replaceAll("=",""),body_macro:x,headers_json:S,include_signature:K,draft_generation:Z,thread_db_id:X?.id,replying_to_id:Y?.id}}class LO extends M{inbox;constructor($,O,j,x){super($,O,j);this.inbox=x}get headers(){return this.inbox?{"X-Email-Link-Id":this.inbox.id}:void 0}static byId($,O,j){return new LO($,O,void 0,j)}static from($,O,j){return new LO($,O.id,O,j)}async fetch(){let $=Q(await this.client.email.listEmailFilters({headers:this.headers})).filters.find((O)=>O.id===this.id);if(!$)throw new E(`Email filter ${this.id} is unavailable`);return $}emailAddress=this.field("email_address");emailDomain=this.field("email_domain");isImportant=this.field("is_important");async setImportant($){let O=await this.detail.get();await this.mutate((j)=>j.email.upsertEmailFilter({headers:this.headers,body:{email_address:O.email_address,email_domain:O.email_domain,is_important:$}}))}async delete(){await this.mutate(($)=>$.email.deleteEmailFilter({path:{id:this.id},headers:this.headers}))}}class jO extends M{async fetch(){let{labels:$}=Q(await this.client.email.listLabels()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`label ${this.id} not found`);return O}static byId($,O){return new jO($,O)}static async list($){let{labels:O}=Q(await $.email.listLabels());return O.map((j)=>new jO($,j.id,j))}static async create($,O){let{label:j}=Q(await $.email.createLabel({body:{label_name:O}}));if(!j.id)throw new f("created label has no id");return new jO($,j.id)}async delete(){Q(await this.client.email.deleteLabel({path:{id:this.id}}))}name=this.field("name");linkId=this.field("linkId");type=this.field("type");createdAt=this.field("createdAt");labelListVisibility=this.field("labelListVisibility");messageListVisibility=this.field("messageListVisibility")}class Y0{client;async createDraft($,O){let j=Q(await this.client.email.createDraft({body:{draft:K0($)},headers:O?{"X-Email-Link-Id":O.id}:void 0}));if(!j.draft.db_id)throw Error("Draft response has no message id");return BO.byId(this.client,j.draft.db_id)}draftById($){return BO.byId(this.client,$)}async*scheduled($){let O=$?.pageSize??100;if(!Number.isInteger(O)||O<1)throw Error("pageSize must be positive");let j=Math.min(O,1000);for(let x=0;;x+=j){let S=Q(await this.client.email.getScheduledMessages({query:{offset:x,limit:j},headers:$?.inbox?{"X-Email-Link-Id":$.inbox.id}:void 0}));for(let K of S.messages)yield BO.byId(this.client,K.db_id);if(S.messages.lengthLO.from(this.client,O,$))}async upsertFilter($,O){return LO.from(this.client,Q(await this.client.email.upsertEmailFilter({headers:O?{"X-Email-Link-Id":O.id}:void 0,body:{email_address:$.emailAddress,email_domain:$.emailDomain,is_important:$.isImportant}})).filter,O)}async contacts(){return Q(await this.client.email.listContacts()).contacts}reminders($){let{inboxes:O,...j}=$??{};return u(async(x)=>{let S=Q(await this.client.storage.listEmailReminders({query:{...j,inboxIds:O?.map((K)=>K.id),cursor:x}}));return{items:S.items.map(({threadId:K,...Z})=>({...Z,thread:R$.byId(this.client,K)})),nextCursor:S.nextCursor}})}constructor($){this.client=$}byId($){return R$.byId(this.client,$)}message($){return D$.byId(this.client,$)}attachment($){return WO.byId(this.client,$)}link($){return T$.byId(this.client,$)}links(){return T$.list(this.client)}async connectionProviders(){return Q(await this.client.auth.emailConnectionProviders())}async recoverDraftTransfer($){return Q(await this.client.email.recoverDraftTransfer({path:{id:$}}))}send($){return D$.send(this.client,$)}search($,O){return R$.search(this.client,$,O)}inbox($){return u(async(O)=>{let j=Q(await this.client.email.previewsInboxCursor({path:{view:"inbox"},query:{...$?.pageSize?{limit:$.pageSize}:{},...$?.sort?{sort_method:$.sort}:{},...O?{cursor:O}:{}}}));return{items:j.items.map((x)=>R$.byId(this.client,x.id)),nextCursor:j.next_cursor}})}label($){return jO.byId(this.client,$)}labels(){return jO.list(this.client)}createLabel($){return jO.create(this.client,$)}async deleteLabel($){Q(await this.client.email.deleteLabel({path:{id:$.id}}))}async blockSender($){Q(await this.client.email.blockSender({body:{email_address:$}}))}async unblockSender($){Q(await this.client.email.unblockSender({body:{email_address:$}}))}async blockedSenders(){return Q(await this.client.email.listBlockedSenders()).blocked_emails}}class IO{client;id;constructor($,O){this.client=$;this.id=O}static byId($,O){return new IO($,O)}async delete(){Q(await this.client.storage.deleteEntityMention({path:{mention_id:this.id}}))}toJSON(){return{id:this.id}}}class Q0{client;constructor($){this.client=$}byId($){return IO.byId(this.client,$)}async create($,O){let j=Q(await this.client.storage.createEntityMention({body:{source_entity_id:$.entity.id,source_entity_type:$.type,entity_id:O.entity.id,entity_type:O.type}}));return IO.byId(this.client,j.id)}}class G0{client;constructor($){this.client=$}async list($={}){let{favorites:O}=Q(await this.client.storage.listFavorites({query:{entityType:$.entityTypes,entityId:$.entityIds}}));return O}async add($){return Q(await this.client.storage.addFavorite({body:{entityId:$.id,entityType:$.entityType}}))}async remove($){Q(await this.client.storage.removeFavoriteByEntity({path:{entity_type:$.entityType,entity_id:$.id}}))}async reorder($){Q(await this.client.storage.reorderFavorites({body:{favorites:$}}))}}class xO extends z${entityType="foreign_entity";async fetch(){return Q(await this.client.storage.getForeignEntity({path:{id:this.id}}))}static byId($,O){return new xO($,O)}static fromRecord($,O){return new xO($,O.id,O)}foreignEntityId=this.field("foreignEntityId");source=this.field("foreignEntitySource");storedForId=this.field("storedForId");storedForAuthEntity=this.field("storedForAuthEntity");createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");async metadata(){return(await this.detail.get()).metadata}}function p1({login:$,...O}){return{...O,login:$??void 0}}class J0{client;constructor($){this.client=$}byId($){return xO.byId(this.client,$)}async bySource($,O){return xO.fromRecord(this.client,Q(await this.client.storage.getForeignEntityBySource({path:{source:$,foreign_entity_id:O}})))}async githubPullRequestFacets(){let{repositories:$,authors:O,assignees:j,labels:x}=Q(await this.client.storage.getGithubPullRequestFacets());return{repositories:$,authors:O.map(p1),assignees:j.map(p1),labels:x.map(({color:S,...K})=>({...K,color:S??void 0}))}}}class r${form;id;constructor($,O){this.form=$;this.id=O}static byId($,O){return new r$($,O)}async detail(){let O=(await this.form.schema()).sections.flatMap((j)=>j.kind==="questions"?j.questions:[]).find((j)=>j.id===this.id);if(!O)throw new E(`question ${this.id} is not on form ${this.form.id}`);return O}async title(){return(await this.detail()).title}async column(){return A$.byId(await this.form.table(),(await this.detail()).column)}async options(){return(await this.detail()).options.map(($)=>NO.byId(this,$.id))}}class NO{question;id;constructor($,O){this.question=$;this.id=O}static byId($,O){return new NO($,O)}async detail(){let $=(await this.question.detail()).options.find((O)=>O.id===this.id);if(!$)throw new E(`option ${this.id} is not on question ${this.question.id}`);return $}async label(){return(await this.detail()).label}async color(){return(await this.detail()).color??void 0}}class TO{form;id;detail;constructor($,O,j){this.form=$;this.id=O;this.detail=new W$(()=>this.load(),j)}async load(){let $=await this.form.myResponse();if($.response.id!==this.id)throw new E(`response ${this.id} is not your current response`);return $}static byId($,O,j){return new TO($,O,j)}async status(){return(await this.detail.get()).status}async row(){return(await this.detail.get()).row}async answers(){return(await this.detail.get()).answers}async booking(){return(await this.detail.get()).booking}async refresh(){let $=await this.load();return this.detail=new W$(()=>this.load(),$),this}}class p${form;id;constructor($,O){this.form=$;this.id=O}static byId($,O){return new p$($,O)}async detail(){let $=(await this.form.schema()).sections.find((O)=>O.id===this.id);if(!$)throw new E(`section ${this.id} is not on form ${this.form.id}`);return $}async title(){return(await this.detail()).title}async questions(){let $=await this.detail();return $.kind==="questions"?$.questions.map((O)=>r$.byId(this.form,O.id)):[]}}class Mj{entityType;id;constructor($,O){this.entityType=$;this.id=O}static byId($,O){return new Mj($,O)}}class y$ extends M{async fetch(){return Q(await this.client.storage.getForm({path:{id:this.id}}))}static byId($,O){return new y$($,O)}static async create($,O){let j=Q(await $.storage.createForm({body:{name:O.name,source:O.table?{kind:"table",databaseId:O.table.database.id,tableId:O.table.id}:{kind:"new"}}}));return new y$($,j.form.id,j)}static async list($,O){if(!O)return Q(await $.storage.listAccessibleForms()).map(({form:S})=>new y$($,S.id));return Q(await $.storage.listForms({query:{databaseId:O.id}})).map((x)=>new y$($,x.id))}schema(){return this.detail.get()}name=this.mappedField("form",($)=>$.name);description=this.mappedField("form",($)=>$.description);owner=this.mappedField("form",($)=>P.byId(this.client,$.ownerId));database=this.mappedField("form",($)=>V$.byId(this.client,$.databaseId));table=this.mappedField("form",($)=>J$.byId(V$.byId(this.client,$.databaseId),$.tableId));audience=this.mappedField("form",($)=>$.audience);status=this.mappedField("form",($)=>$.status);closesAt=this.mappedField("form",($)=>$.closesAt??void 0);access=this.field("access");async sections(){return(await this.detail.get()).sections.map(($)=>p$.byId(this,$.id))}async questions(){return(await this.detail.get()).sections.flatMap(($)=>$.kind==="questions"?$.questions.map((O)=>r$.byId(this,O.id)):[])}async update($){return await this.mutate((O)=>O.storage.updateForm({path:{id:this.id},body:$})),this}assertOwns($){if($.form.id!==this.id)throw new f(`question or section does not belong to form ${this.id}`)}async replaceLayout($){let O=await this.table(),j=(Z)=>{if(Z.table.id!==O.id||Z.table.database.id!==O.database.id)throw new f(`column does not belong to form ${this.id}'s table`);return Z.id},x=(Z)=>({conjunction:Z.conjunction,conditions:Z.conditions.map((X)=>c(X).with({kind:"group"},(Y)=>({kind:"group",...x(Y)})).with({kind:"condition"},(Y)=>({kind:"condition",column:j(Y.column),test:c(Y.test).with({kind:"options"},(L)=>({...L,options:L.options.map((G)=>G.id)})).with({kind:"entities"},(L)=>({...L,entities:L.entities.map((G)=>G.id)})).with({kind:Z$.union("presence","text","number","date","checkbox")},(L)=>L).exhaustive()})).exhaustive())}),S={sections:$.map((Z)=>{if(Z.section)this.assertOwns(Z.section);let X={id:Z.section?.id??d$(),title:Z.title,description:Z.description??""};return c(Z).with({kind:"booking"},(Y)=>({...X,kind:"booking",target:Y.target})).with({kind:"gate"},(Y)=>({...X,kind:"gate",rules:x(Y.rules),message:Y.message})).with({kind:"questions"},(Y)=>({...X,kind:"questions",questions:Y.questions.map((L)=>{if(L.question)this.assertOwns(L.question);return{id:L.question?.id??d$(),column:j(L.column),helpText:L.helpText??"",required:L.required??!1,widget:L.widget??null}})})).exhaustive()})},K=await this.mutate((Z)=>Z.storage.putFormLayout({path:{id:this.id},body:S}));return{form:this,publicationError:K.publicationError}}wireAnswers($){return $.map(({question:O,value:j})=>{this.assertOwns(O);let x=c(j).with({type:"rows"},(S)=>({type:"rows",value:S.value.map((K)=>K.id)})).with({type:"options"},(S)=>({type:"options",value:S.value.map((K)=>{if(K.question.id!==O.id||K.question.form.id!==this.id)throw new f("option does not belong to the answered question");return{id:K.id}})})).with({type:"entities"},(S)=>({type:"entities",value:S.value.map(({entityType:K,entity:Z})=>({entityType:K,entityId:Z.id}))})).with({type:Z$.union("text","number","boolean","date","link","clear")},(S)=>S).exhaustive();return{question:O.id,value:x}})}unlockedBooking($){return $?{...$,section:p$.byId(this,$.section)}:void 0}async outcome($,O){return c($).with({outcome:"stopped"},(j)=>({...j,section:p$.byId(this,j.section)})).with({outcome:"submitted"},async(j)=>{let x=F$.byId(await this.table(),j.row),S=this.unlockedBooking(j.booking);return{outcome:"submitted",response:TO.byId(this,j.response,{status:"submitted",row:x,answers:O,booking:S}),row:x,...S?{booking:S}:{}}}).exhaustive()}async submit($){let O={answers:this.wireAnswers($)};return this.outcome(Q(await this.client.storage.submitFormResponse({path:{id:this.id},body:O})),$)}async editResponse($){let O={answers:this.wireAnswers($)};return this.outcome(Q(await this.client.storage.editMyFormResponse({path:{id:this.id},body:O})),$)}async myResponse(){let $=Q(await this.client.storage.getMyFormResponse({path:{id:this.id}})),O=await this.table(),j=await Promise.all($.answers.map(async(K)=>{let Z=r$.byId(this,K.question),X=await c(K.value).with({type:"options"},(Y)=>({type:"options",value:Y.value.map((L)=>{if(!("id"in L))throw new f("stored form answers must reference options by id");return NO.byId(Z,L.id)})})).with({type:"entities"},(Y)=>({type:"entities",value:Y.value.map((L)=>({entityType:L.entityType,entity:Mj.byId(L.entityType,L.entityId)}))})).with({type:"rows"},async(Y)=>{let L=await Z.detail();if(L.kind.type!=="relation")throw new f("row answer requires a relation question");let G=J$.byId(V$.byId(this.client,L.kind.database),L.kind.table);return{type:"rows",value:Y.value.map((J)=>F$.byId(G,J))}}).with({type:Z$.union("text","number","boolean","date","link","clear")},(Y)=>Y).exhaustive(()=>{throw new f(`answer to question ${Z.id} has a type this SDK doesn't know`)});return{question:Z,value:X}})),x=$.response.row?F$.byId(O,$.response.row):void 0,S=this.unlockedBooking($.booking);return{...S?{booking:S}:{},response:TO.byId(this,$.response.id,{status:$.response.status,row:x,answers:j,booking:S}),status:$.response.status,stoppedAtSection:$.response.stoppedAtSection?p$.byId(this,$.response.stoppedAtSection):void 0,row:x,submittedAt:$.response.submittedAt,updatedAt:$.response.updatedAt,answers:j}}async responseSummary(){let $=Q(await this.client.storage.getFormResponseSummary({path:{id:this.id}}));return{...$,stoppedBySection:$.stoppedBySection.map((O)=>({section:p$.byId(this,O.section),count:O.count}))}}async tally(){return Q(await this.client.storage.getFormTally({path:{id:this.id}})).questions.map((O)=>{let j=r$.byId(this,O.question);return{question:j,responses:O.responses,buckets:O.buckets.flatMap((x)=>c(x.value).with({kind:"option"},(S)=>[{count:x.count,value:{kind:"option",option:NO.byId(j,S.option)}}]).with({kind:"checkbox"},(S)=>[{count:x.count,value:S}]).exhaustive((S)=>{return console.warn("macro sdk: unknown form tally bucket",S),[]}))}})}async sharePermissions(){return Q(await this.client.storage.getFormPermissions({path:{id:this.id}}))}updateSharePermissions($){return this.mutate((O)=>O.storage.updateFormPermissions({path:{id:this.id},body:$}))}webUrl(){return`${this.client.webAppUrl}/app/form/${this.id}`}respondUrl(){return`${this.client.webAppUrl}/app/form/${this.id}/respond`}}class V0{client;constructor($){this.client=$}byId($){return y$.byId(this.client,$)}create($){return y$.create(this.client,$)}list($){return y$.list(this.client,$)}}class HO extends M{static byId($,O){return new HO($,O)}async fetch(){return Q(await this.client.storage.getGithubPullRequest({path:{id:this.id}}))}title=this.field("title");url=this.field("url");status=this.field("status");async changes(){let $=Q(await this.client.storage.getGithubPullRequestChanges({path:{id:this.id}}));return{changeset:$.changeset?new W0(this.client,this,$.changeset):void 0,error:$.error??void 0}}}class W0{client;pullRequest;record;constructor($,O,j){this.client=$;this.pullRequest=O;this.record=j}get id(){return this.record.id}async patch(){return Q(await this.client.storage.getGithubPullRequestChangesPatch({path:{id:this.pullRequest.id},query:{changeset:this.id}})).patch}toJSON(){return{pullRequestId:this.pullRequest.id,...this.record}}}class B0{client;constructor($){this.client=$}byId($){return HO.byId(this.client,$)}forEntity($){return HO.byId(this.client,$.id)}}class RO extends M{static byId($,O){return new RO($,O)}async fetch(){return Q(await this.client.storage.getHarnessPairing({path:{code:this.id}}))}name=this.field("requested_name");expiresAt=this.field("expires_at");async approve($){let O={name:$?.name,team_id:$?.team?.id,allow_permission_bypass:$?.allowPermissionBypass};return B$.from(this.client,await this.mutate((j)=>j.storage.approveHarnessPairing({path:{code:this.id},body:O})))}}class oO{client;id;constructor($,O){this.client=$;this.id=O}static byId($,O){return new oO($,O)}async claim($){let O=Q(await this.client.storage.claimHarnessPairing({path:{pairing_id:this.id},body:{device_secret:$}}));return"harness"in O?{harness:B$.from(this.client,O.harness),token:O.token}:void 0}toJSON(){return{id:this.id}}}class L0{client;constructor($){this.client=$}byId($){return B$.byId(this.client,$)}async list(){return Q(await this.client.storage.listHarnesses()).map(($)=>B$.from(this.client,$))}async me(){return B$.from(this.client,Q(await this.client.storage.getSelfHarness()))}async deleteSelf(){Q(await this.client.storage.deleteSelfHarness())}async agents(){return Q(await this.client.storage.listHarnessAgents()).map(($)=>I$.byId(this.client,$.bot_id))}async sessions(){return Q(await this.client.storage.listHarnessSessions()).map(($)=>i.byId(this.client,$.session_id))}pairing($){return RO.byId(this.client,$)}async createPairing($){let O=Q(await this.client.storage.createHarnessPairing({body:$}));return{pairing:RO.byId(this.client,O.code),device:oO.byId(this.client,O.pairing_id),deviceSecret:O.device_secret,expiresAt:O.expires_at,pollIntervalSeconds:O.poll_interval_seconds}}}var G7="00000001-0000-0000-0000-000000000002",J7="00000001-0000-0000-0002-000000000004";function V7($){let O=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/([1-9][0-9]*)\/?(?:[?#].*)?$/i);if(!O)throw Error(`Expected a GitHub pull request URL like https://github.com/owner/repo/pull/1, got ${$}`);return`${O[1]}/${O[2]}/pull/${O[3]}`}class C$ extends w{static byId($,O){return new C$($,O)}static async create($,O){let{documentId:j}=Q(await $.storage.createTaskHandler({body:{taskName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null,teamId:O.team?.id??null,shareWithTeam:O.shareWithTeam??!0}}));return new C$($,j)}static async forPullRequest($,O){let j=V7(O),{pullRequests:x}=Q(await $.storage.getGithubPullRequestTasks({body:{githubKeys:[j]}}));return(x[0]?.taskIds??[]).map((S)=>new C$($,S))}async completed(){let{subType:$}=await this.detail.get();if($!=="task")return;let j=(await this.properties()).find((x)=>x.definition.id===G7)?.value;return j?.type==="SelectOption"&&j.value.includes(J7)}webUrl(){return`${this.client.webAppUrl}/app/task/${this.id}`}static search=x$({filters:{document_filters:{sub_types:["task"],task_filters:{}}},type:"document",make:($,O)=>new C$($,O.document_id)})}class SO extends M{access=new o(this.client,"initiative",this);static byId($,O){return new SO($,O)}static from($,O){return new SO($,O.id,O)}async fetch(){return Q(await this.client.storage.getInitiative({path:{initiative_id:this.id}}))}name=this.field("name");owner=this.mappedField("ownerId",($)=>P.byId(this.client,$));members=this.mappedField("memberIds",($)=>$.map((O)=>P.byId(this.client,O)));tasks=this.mappedField("taskIds",($)=>$.map((O)=>C$.byId(this.client,O)));accessLevel=this.field("userAccessLevel");sharePermissions=this.field("sharePermission");async update($){await this.mutate((O)=>O.storage.updateInitiative({path:{initiative_id:this.id},body:{name:$.name,memberIds:$.members?.map((j)=>j.id),sharePermission:$.sharePermission?n$($.sharePermission):void 0}}))}async delete(){await this.mutate(($)=>$.storage.deleteInitiative({path:{initiative_id:this.id}}))}}class N0{client;constructor($){this.client=$}byId($){return SO.byId(this.client,$)}async list(){return Q(await this.client.storage.listInitiatives()).initiatives.map(($)=>SO.byId(this.client,$.id))}async create($){return SO.from(this.client,Q(await this.client.storage.createInitiative({body:{name:$.name,description:$.description,memberIds:$.members?.map((O)=>O.id),shareWithTeam:$.shareWithTeam,propertyValues:$.propertyValues}})))}}class U0{client;constructor($){this.client=$}byId($){return H$.byId(this.client,$)}async create($){return H$.from(this.client,Q(await this.client.storage.meetingCreate({body:$})))}async list(){return Q(await this.client.storage.meetingList()).meetings.map(($)=>H$.from(this.client,$))}async active(){return Q(await this.client.storage.meetingListActive()).meetings.map(($)=>H$.from(this.client,$))}async lookup($){return H$.from(this.client,Q(await this.client.storage.meetingLookup({path:{token:$}})))}}class UO extends M{async fetch(){return Q(await this.client.notification.getTypedNotificationById({path:{notification_id:this.id}}))}static byId($,O){return new UO($,O)}static from($,O){return new UO($,O.id,O)}static list($,O){return u(async(j)=>{let x=Q(await $.notification.listTypedNotifications({query:{...O?.pageSize?{limit:O.pageSize}:{},...O?.states!==void 0?{states:O.states.join(",")}:{},...j?{cursor:j}:{}}}));return{items:x.items.map((S)=>UO.from($,S)),nextCursor:x.next_cursor}})}type=this.field("notification_event_type");createdAt=this.field("created_at");updatedAt=this.field("updated_at");state=this.field("state");done=this.mappedField("state",($)=>$==="done");sent=this.field("sent");viewedAt=this.field("viewed_at");deletedAt=this.field("deleted_at");owner=this.mappedField("owner_id",($)=>P.byId(this.client,$));sender=this.mappedField("sender_id",($)=>$?P.byId(this.client,$):void 0);metadata=this.field("notification_metadata");async seen(){return await this.state()!=="unseen"}async markSeen(){await this.mutate(($)=>$.notification.bulkMarkNotificationsSeen({body:{notificationIds:[this.id]}}))}async markDone(){await this.mutate(($)=>$.notification.bulkMarkNotificationsDone({body:{notificationIds:[this.id]}}))}async markUndone(){await this.mutate(($)=>$.notification.bulkMarkNotificationsUndone({body:{notificationIds:[this.id]}}))}async delete(){await this.mutate(($)=>$.notification.deleteUserNotificationV2({path:{notification_id:this.id}}))}}class z0{client;constructor($){this.client=$}byId($){return UO.byId(this.client,$)}list($){return UO.list(this.client,$)}async markSeen($){Q(await this.client.notification.bulkMarkNotificationsSeen({body:{notificationIds:$}}))}async markDone($){Q(await this.client.notification.bulkMarkNotificationsDone({body:{notificationIds:$}}))}async delete($){Q(await this.client.notification.bulkDeleteUserNotificationsV2({body:{notificationIds:$}}))}async preferences(){return Q(await this.client.notification.getNotificationTypePreferences())}async enableType($){Q(await this.client.notification.enableNotificationType({path:{notification_event_type:$}}))}async disableType($){Q(await this.client.notification.disableNotificationType({path:{notification_event_type:$}}))}}class I0{client;constructor($){this.client=$}async list(){let{data:$}=Q(await this.client.storage.getPinsHandler({}));return $?.recent??[]}async add($,O){Q(await this.client.storage.addPinHandler({path:{pinned_item_id:$.id},body:{pinType:$.entityType,pinIndex:O.index}}))}async remove($){Q(await this.client.storage.removePinHandler({path:{pinned_item_id:$.id},body:{pinType:$.entityType}}))}async reorder($){Q(await this.client.storage.reorderPinsHandler({body:$}))}}class T0{client;constructor($){this.client=$}byId($){return n.byId(this.client,$)}create($){return n.create(this.client,$)}search($,O){return n.search(this.client,$,O)}}class DO{client;definitionId;id;record;constructor($,O,j,x){this.client=$;this.definitionId=O;this.id=j;this.record=x}static from($,O,j){return new DO($,O,j.id,j)}get value(){return this.record.value}get color(){return this.record.color??void 0}get displayOrder(){return this.record.display_order}get createdAt(){return this.record.created_at}get updatedAt(){return this.record.updated_at}async update($){return this.record=Q(await this.client.properties.updatePropertyOption({path:{definition_id:this.definitionId,option_id:this.id},body:$})),this}async delete(){Q(await this.client.properties.deletePropertyOption({path:{definition_id:this.definitionId,option_id:this.id}}))}}class ZO{client;id;detail;constructor($,O,j){this.client=$;this.id=O;this.detail=new W$(()=>this.fetch(),j)}async fetch(){return Q(await this.client.properties.getPropertyDefinition({path:{definition_id:this.id}}))}static async create($,O){let j=Q(await $.properties.createPropertyDefinition({body:{display_name:O.displayName,scope:O.scope,data_type:O.dataType}}));return new ZO($,j.id,j)}static byId($,O){return new ZO($,O)}static fromRecord($,O){return new ZO($,O.id,O)}get displayName(){return this.detail.get().then(($)=>$.display_name)}get dataType(){return this.detail.get().then(($)=>$.data_type)}get owner(){return this.detail.get().then(($)=>$.owner)}get isSystem(){return this.detail.get().then(($)=>$.is_system)}get isMultiSelect(){return this.detail.get().then(($)=>$.is_multi_select)}get createdAt(){return this.detail.get().then(($)=>$.created_at)}get updatedAt(){return this.detail.get().then(($)=>$.updated_at)}async delete(){return Q(await this.client.properties.deletePropertyDefinition({path:{definition_id:this.id}}))}async options(){return Q(await this.client.properties.getPropertyOptions({path:{definition_id:this.id}})).map((O)=>DO.from(this.client,this.id,O))}async addOption($){let O=Q(await this.client.properties.addPropertyOption({path:{definition_id:this.id},body:$}));return DO.from(this.client,this.id,O)}async updateOption($,O){let j=Q(await this.client.properties.updatePropertyOption({path:{definition_id:this.id,option_id:$.id},body:O}));return DO.from(this.client,this.id,j)}async deleteOption($){return Q(await this.client.properties.deletePropertyOption({path:{definition_id:this.id,option_id:$.id}}))}}class H0{client;constructor($){this.client=$}async list($){return Q(await this.client.properties.listProperties({query:{scope:$?.scope??"all",...$?.forEntityType!==void 0?{for_entity_type:$.forEntityType}:{}}})).map((j)=>{let x="definition"in j?j.definition:j;return ZO.fromRecord(this.client,x)})}create($){return ZO.create(this.client,$)}definition($){return ZO.byId(this.client,$)}async bulkEntityProperties($){return Q(await this.client.properties.getBulkEntityProperties({body:$}))}async updateEntityPropertyOptions($,O){return Q(await this.client.properties.bulkUpdateEntitiesPropertyOptions({body:{entities:$.map((x)=>x.propertyReference()),property_id:O.property.id,...O.add?{add_option_ids:O.add.map((x)=>x.id)}:{},...O.remove?{remove_option_ids:O.remove.map((x)=>x.id)}:{}}})).results}async addEntityPropertyOption($){return Q(await this.client.properties.addEntityPropertyOption({path:{...$.entity.propertyReference(),property_id:$.property.id,option_id:$.option.id}}))}async removeEntityPropertyOption($){return Q(await this.client.properties.removeEntityPropertyOption({path:{...$.entity.propertyReference(),property_id:$.property.id,option_id:$.option.id}}))}async tags(){return Q(await this.client.properties.listTags({}))}}function R0($){return c($).with({type:"cron"},(O)=>O).with({type:"events"},(O)=>({type:"events",filters:O.filters.map(({entities:j,...x})=>({...x,ids:j?.map((S)=>S.entity.id)}))})).exhaustive()}function W7($){return c($).with({type:"multiple"},(O)=>({type:"multiple",triggers:O.triggers.map(R0)})).with({type:"cron"},R0).with({type:"events"},R0).exhaustive()}class XO extends M{static byId($,O){return new XO($,O)}static from($,O){if(!O.id)throw Error("Routine response has no id");return new XO($,O.id,O)}async fetch(){return Q(await this.client.scheduledAction.getScheduledAction({path:{id:this.id}}))}name=this.field("name");trigger=this.field("trigger");enabled=this.field("enabled");runVisibility=this.field("run_visibility");nextRunAt=this.field("next_run_at");revision=this.field("configuration_revision");owner=this.mappedField("owner",($)=>P.byId(this.client,$));async update($){await this.mutate((O)=>O.scheduledAction.updateScheduledAction({path:{id:this.id},body:C0($)}))}async setEnabled($){await this.mutate((O)=>O.scheduledAction.setScheduledActionEnabled({path:{id:this.id},body:{enabled:$}}))}async execute(){let $=Q(await this.client.scheduledAction.executeScheduledActionNow({path:{id:this.id}}));if($.resource)return c($.resource).with({type:"agent"},(O)=>i.byId(this.client,O.id)).with({type:"chat"},(O)=>K$.byId(this.client,O.id)).exhaustive();return $.chat_id?K$.byId(this.client,$.chat_id):void 0}async history(){return Q(await this.client.scheduledAction.listScheduledActionHistory({path:{id:this.id}})).map(($)=>new D0(this,$))}async delete(){await this.mutate(($)=>$.scheduledAction.deleteScheduledAction({path:{id:this.id}}))}}class D0{routine;record;constructor($,O){this.routine=$;this.record=O}get id(){return this.record.id??void 0}toJSON(){return{routine:this.routine.id,...this.record}}}function C0($){let O={prompt:$.prompt,user_prompt:$.userPrompt,model:$.model,agent:$.agent?{bot_id:$.agent.id}:void 0};return{kind:"Agent",name:$.name,enabled:$.enabled,run_visibility:$.runVisibility,trigger:W7($.trigger),task:{...O}}}class _0{client;constructor($){this.client=$}byId($){return XO.byId(this.client,$)}async create($){return XO.from(this.client,Q(await this.client.scheduledAction.createScheduledAction({body:{...C0($),enabled:$.enabled??!0}})))}async list($){return Q(await this.client.scheduledAction.listScheduledActions({query:{include_events:$?.includeEvents}})).map((O)=>XO.from(this.client,O))}}class P0{client;constructor($){this.client=$}byId($){return C$.byId(this.client,$)}create($){return C$.create(this.client,$)}forPullRequest($){return C$.forPullRequest(this.client,$)}search($,O){return C$.search(this.client,$,O)}}class M0{client;constructor($){this.client=$}byId($){return S$.byId(this.client,$)}current(){return S$.current(this.client)}list(){return S$.list(this.client)}}class A0{client;constructor($){this.client=$}async get($){return Q(await this.client.unfurl.getUnfurl({query:{url:$}}))}async bulk($){return Q(await this.client.unfurl.getUnfurlBulk({body:{url_list:$}}))}}class F0{client;constructor($){this.client=$}byId($){return P.byId(this.client,$)}me(){return P.me(this.client)}async search($){let O=$.trim().toLocaleLowerCase();if(!O)throw Error("A person search needs a name or email.");let j=await this.client.contacts.getContacts();if(j.response?.status===404)return[];let{contacts:x}=Q(j),S=[...new Set(x)],K=[];for(let Z=0;Z[G.id,G]));for(let G of X){let J=L.get(G)??{id:G};if(`${[J.first_name,J.last_name].filter(Boolean).join(" ")} ${G}`.toLocaleLowerCase().includes(O))K.push(P.fromName(this.client,J))}}return K}}class KO extends M{signingSecret;constructor($,O,j,x){super($,O,j);this.signingSecret=x}async fetch(){return Q(await this.client.storage.getWebhook({path:{webhook_id:this.id}}))}static async create($,O){let j=Q(await $.storage.createWebhook({body:{endpoint_url:O.url,namespace:O.namespace,name:O.name,filters:O.filters,scope:O.scope??"user",...O.headers!==void 0?{headers:O.headers}:{}}}));return new KO($,j.id,j,j.signing_secret)}static byId($,O){return new KO($,O)}static fromRecord($,O){return new KO($,O.id,O)}name=this.field("name");namespace=this.field("namespace");endpointUrl=this.field("endpoint_url");status=this.field("status");isValid=this.field("is_valid");filters=this.field("filters");createdAt=this.field("created_at");workspaceId=this.field("workspace_id");createdBy=this.mappedField("created_by_user_id",($)=>P.byId(this.client,$));async scope(){let $=await this.detail.get();return $.workspace_id===$.created_by_user_id?"user":"team"}async update($){await this.mutate((O)=>O.storage.patchWebhook({path:{webhook_id:this.id},body:$}))}async rename($){await this.update({name:$})}async setUrl($){await this.update({endpoint_url:$})}async setFilters($){await this.update({filters:$})}async pause(){await this.update({status:"paused"})}async resume(){await this.update({status:"active"})}async delete(){await this.mutate(($)=>$.storage.deleteWebhook({path:{webhook_id:this.id}}))}async validate(){return this.mutate(($)=>$.storage.validateWebhook({path:{webhook_id:this.id}}))}}class E0{client;constructor($){this.client=$}create($){return KO.create(this.client,$)}byId($){return KO.byId(this.client,$)}async list(){let{webhooks:$}=Q(await this.client.storage.listWebhooks());return $.map((O)=>KO.fromRecord(this.client,O))}}class CO extends M{static byId($,O){return new CO($,O)}static from($,O){return new CO($,O.id,O)}async fetch(){let{account:$}=Q(await this.client.storage.linkedAccount());if($?.id!==this.id)throw new E("WhatsApp account is not available");return $}state=this.field("state");identity=this.field("identity_jid");owner=this.mappedField("user_id",($)=>P.byId(this.client,$));async refresh(){return this.detail.clear(),await this.detail.get(),this}}class _$ extends M{group;constructor($,O,j,x){super($,j,x);this.group=O}static byId($,O,j){return new _$($,O,j)}static from($,O,j){return new _$($,O,j.id,j)}get groupId(){return this.group.id}async fetch(){for await(let $ of this.group.messages({limit:100}))if($.id===this.id)return $.detail.get();throw new E("WhatsApp message is not available")}body=this.field("body");sender=this.field("sender");sentAt=this.field("sent_at");editedAt=this.field("edited_at");deleted=this.field("deleted");reactions=this.field("reactions");deliveryState=this.field("delivery_state");replyTo=this.mappedField("reply_to",($)=>$?_$.byId(this.client,this.group,$):void 0);attachments=this.mappedField("attachments",($)=>$.map((O)=>({ordinal:O.ordinal,state:O.state,fileName:O.file_name,mime:O.mime,size:O.size,document:O.document_id?w.byId(this.client,O.document_id):void 0})))}class YO{id;groupId;filename;kind;constructor($,O,j,x){this.id=$;this.groupId=O;this.filename=j;this.kind=x}static byId($,O){return new YO(O,$.id)}static from($,O){return new YO(O.upload_id,$.id,O.filename,O.kind)}toJSON(){return{id:this.id,groupId:this.groupId,filename:this.filename,kind:this.kind}}}class a$ extends M{group;constructor($,O,j,x){super($,j,x);this.group=O}static byId($,O,j){return new a$($,O,j)}static from($,O,j){return new a$($,O,j.id,j)}async fetch(){let O=Q(await this.client.storage.linkedDelivery({path:{group_id:this.group.id},body:[this.id]})).find((j)=>j.id===this.id);if(!O)throw new E("WhatsApp send is not available");return O}state=this.field("state");errorCode=this.field("error_code");createdAt=this.field("created_at");message=this.mappedField("message_id",($)=>$?_$.byId(this.client,this.group,$):void 0);async request(){let{payload:$}=await this.detail.get(),O=$.message,j=c(O).returnType().with({type:"media"},(x)=>({type:"media",upload:YO.byId(this.group,x.upload_id),caption:x.caption??void 0})).with({type:"mutation"},(x)=>({type:"mutation",message:_$.byId(this.client,this.group,x.message_id),operation:x.operation,text:x.text??void 0})).with({type:"text"},(x)=>x).exhaustive();return{idempotencyKey:$.idempotency_key,message:j,replyTo:$.reply_to?_$.byId(this.client,this.group,$.reply_to):void 0}}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class v$ extends z${entityType="whatsapp_group";static byId($,O){return new v$($,O)}async fetch(){return Q(await this.client.storage.whatsappGroup({path:{group_id:this.id}}))}name=this.field("name");canSend=this.field("can_send");sendReason=this.field("send_reason");sendingIdentity=this.field("sending_identity");unreadCount=this.field("unread_count");limits=this.field("limits");roster=this.field("roster");owner=this.mappedField("user_id",($)=>P.byId(this.client,$));async*messages($={}){yield*u(async(O)=>{let j=Q(await this.client.storage.whatsappGroupMessages({path:{group_id:this.id},query:{before:O,limit:$.limit}}));return{items:j.messages.map((x)=>_$.from(this.client,this,x)),nextCursor:j.next_cursor}})}async markRead($){this.assertGroup($.groupId),await this.mutate((O)=>O.storage.whatsappGroupRead({path:{group_id:this.id},body:{message_id:$.id}}))}async permissions(){return Q(await this.client.storage.whatsappGroupPermissions({path:{group_id:this.id}}))}async updatePermissions($){await this.mutate((O)=>O.storage.whatsappGroupUpdatePermissions({path:{group_id:this.id},body:$}))}async detach(){await this.mutate(($)=>$.storage.linkedDetach({path:{group_id:this.id}}))}async upload($){let O=Q(await this.client.storage.linkedUpload({path:{group_id:this.id},body:{file:$}}));return YO.from(this,O)}async reply($,O){if(O.replyTo)this.assertGroup(O.replyTo.groupId);let j=c($).returnType().with({type:"text"},(S)=>S).with({type:"media"},(S)=>{return this.assertGroup(S.upload.groupId),{type:"media",upload_id:S.upload.id,caption:S.caption}}).with({type:"mutation"},(S)=>{return this.assertGroup(S.message.groupId),{type:"mutation",message_id:S.message.id,operation:S.operation,text:S.text}}).exhaustive(),x=await this.mutate((S)=>S.storage.linkedReply({path:{group_id:this.id},body:{idempotency_key:O.idempotencyKey,message:j,reply_to:O.replyTo?.id}}));return a$.from(this.client,this,x)}async sends(){return Q(await this.client.storage.whatsappGroupSends({path:{group_id:this.id}})).map(($)=>a$.from(this.client,this,$))}async delivery($){for(let O of $)this.assertGroup(O instanceof a$?O.group.id:O.groupId);return Q(await this.client.storage.linkedDelivery({path:{group_id:this.id},body:$.map((O)=>O.id)})).map((O)=>a$.from(this.client,this,O))}async messageAttachments($){for(let O of $)this.assertGroup(O.groupId);return Q(await this.client.storage.linkedMessageAttachments({path:{group_id:this.id},body:$.map((O)=>O.id)})).map((O)=>({message:_$.byId(this.client,this,O.message_id),attachments:O.linked_attachments.map((j)=>({ordinal:j.ordinal,state:j.state,fileName:j.file_name,mime:j.mime,size:j.size,document:j.document_id?w.byId(this.client,j.document_id):void 0}))}))}async refresh(){return this.detail.clear(),await this.detail.get(),this}assertGroup($){if($!==this.id)throw Error("WhatsApp reference belongs to another group")}}class _O extends M{static byId($,O){return new _O($,O)}static from($,O){return new _O($,O.jid,O)}async fetch(){let O=Q(await this.client.storage.linkedGroups()).find((j)=>j.jid===this.id);if(!O)throw new E("WhatsApp group is not available");return O}name=this.field("name");observedAt=this.field("observedAt");participants=this.field("participants");disappearing=this.field("disappearing");announce=this.field("announce");community=this.field("community");group=this.mappedField("group",($)=>$?v$.byId(this.client,$.id):void 0);shared=this.mappedField("shared",($)=>$?v$.byId(this.client,$.id):void 0);async adopt(){let $=await this.mutate((O)=>O.storage.linkedAdopt({body:{group_jid:this.id}}));return v$.byId(this.client,$.group_id)}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class w0{client;constructor($){this.client=$}async account(){let{account:$}=Q(await this.client.storage.linkedAccount());return $?CO.from(this.client,$):void 0}async groups(){return Q(await this.client.storage.whatsappGroups()).map(($)=>v$.byId(this.client,$.id))}async remoteGroups(){return Q(await this.client.storage.linkedGroups()).map(($)=>_O.from(this.client,$))}byId($){return v$.byId(this.client,$)}}function q0($){if("properties"in $.data)return $.data.properties;if($.tag==="calendarEvent")return $.data.extra.properties;return[]}function a1($,O,j){let x=[];for(let S of q0(O)){if(S.definition.data_type!=="TAG"||S.value?.type!=="SelectOption")continue;for(let K of S.value.value){let Z=j.get(K);if(Z&&!x.some((X)=>X.label===Z.label&&X.scope===Z.scope))x.push(Z)}}switch(O.tag){case"document":return{type:"document",id:O.data.id,entity:w.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name,fileType:O.data.fileType,subType:O.data.subType?.type};case"chat":return{type:"ai_chat",id:O.data.id,entity:K$.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name};case"project":return{type:"project",id:O.data.id,entity:n.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name};case"emailThread":return{type:"email",id:O.data.id,entity:R$.byId($,O.data.id),snapshot:O,tags:x,subject:O.data.name,snippet:O.data.snippet,senderName:O.data.senderName,senderEmail:O.data.senderEmail,inboxVisible:O.data.inboxVisible,isRead:O.data.isRead,isDraft:O.data.isDraft};case"channel":return{type:"channel",id:O.data.channel.id,entity:b.byId($,O.data.channel.id),snapshot:O,tags:x,name:O.data.channel.name};case"channelThread":return{type:"channel_thread",id:O.data.id,entity:new h$($,O.data.channel_id,O.data.id),snapshot:O,tags:x,channelId:O.data.channel_id};case"call":return{type:"call",id:O.data.callId,entity:G$.byId($,O.data.callId),snapshot:O,tags:x,createdBy:O.data.createdBy};case"calendarEvent":return{type:"calendar_event",id:O.data.id,entity:$$.byId($,O.data.id),snapshot:O,tags:x,title:O.data.title,status:O.data.status,location:O.data.location,conferenceUrl:O.data.conferenceUrl,conferenceProvider:O.data.conferenceProvider,time:O.data.time};case"foreignEntity":return{type:"foreign_entity",id:O.data.id,entity:xO.byId($,O.data.id),snapshot:O,tags:x,foreignEntityId:O.data.foreignEntityId,foreignEntitySource:O.data.foreignEntitySource,metadata:O.data.metadata};default:throw Error(`Unexpected workspace entity type: ${O.tag}`)}}var i1="00000000-0000-0000-0000-000000000000",f0={document:["df","id"],project:["pf","pid"],ai_chat:["cf","cid"],email:["ef","ThreadId"],channel:["chanf","ChannelId"],channel_thread:["cthf","ThreadId"],call:["callf","CallId"],calendar_event:["calf","id"],foreign_entity:["fef","id"]},Aj=($)=>$.replace(/[A-Z]/g,(O)=>O.toLowerCase()),n1=($,O)=>$==null?O:{"&":[$,O]};function b0($,O){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`Invalid workspace ${O}: expected a filter expression.`);let j=Object.entries($),x=j[0];if(j.length!==1||x===void 0)throw Error(`Invalid workspace ${O}: use exactly one of l, &, |, !.`);let[S,K]=x;if(S==="l")return;if(S==="!"){b0(K,`${O}.!`);return}if(S!=="&"&&S!=="|")throw Error(`Invalid workspace ${O}: use l, &, | or !.`);if(!Array.isArray(K)||K.length!==2)throw Error(`Invalid workspace ${O}.${S}: expected exactly two expressions. Use {l: {...}} for a single condition; nest binary operators for three or more.`);K.forEach((Z,X)=>{b0(Z,`${O}.${S}[${X}]`)})}class Fj{client;tagSets;constructor($){this.client=$}sets(){return this.tagSets??=this.client.properties.listTags({}).then(Q),this.tagSets}async tagMap(){let $=new Map;for(let O of await this.sets())for(let j of O.options)if(j.value.type==="string")$.set(j.id,{label:j.value.value,scope:O.scope==="user"?"personal":"team"});return $}async body($){for(let[S,K,Z]of[["sortBy",$.sortBy,["recently_viewed","recently_updated","recently_created"]],["emailPreset",$.emailPreset,["signal"]],["tagsMatch",$.tagsMatch,["any","all"]]])if(K!==void 0&&!Z.includes(K))throw Error(`Invalid workspace ${S}: ${K}`);if($.includeTypes!==void 0&&(!Array.isArray($.includeTypes)||$.includeTypes.some((S)=>!Object.hasOwn(f0,S))))throw Error(`Invalid workspace includeTypes. Supported values: ${Object.keys(f0).join(", ")}. Tasks use document with df: {l: {dst: 'task'}}.`);for(let S of["df","pf","cf","ef","chanf","cthf","callf","fef","calf","propf"])if($[S]!=null)b0($[S],S);if($.tags?.some((S)=>S.scope!==void 0&&S.scope!=="personal"&&S.scope!=="team"))throw Error("Invalid workspace tag scope");if($.limit!==void 0&&!Number.isFinite($.limit))throw Error("Workspace limit must be finite");let O={df:$.df,pf:$.pf,cf:$.cf,ef:$.ef,chanf:$.chanf,cthf:$.cthf,callf:$.callf,fef:$.fef,calf:$.calf,propf:$.propf,ccf:{l:{id:i1}},favorites_only:$.favoritesOnly,expand:!0,limit:Math.max(1,Math.min(500,Math.trunc($.limit??50))),sort_method:$.sortBy==="recently_viewed"?"viewed_at":$.sortBy==="recently_created"?"created_at":"updated_at",sort_direction:"desc",emailView:$.emailView??"inbox"};if($.emailPreset==="signal")O.ef={"&":[{l:{Importance:!0}},{l:{Shared:"exclude"}}]};let j=$.inbox?.trim();if(j){let{links:S}=Q(await this.client.email.listLinks()),K=S.filter((X)=>Aj(X.email_address)===Aj(j)),Z=K[0];if(!Z)throw Error(`No connected inbox matches "${j}". Connected inboxes: ${S.map((X)=>X.email_address).join(", ")}.`);if(K.length>1)throw Error(`Multiple connected inboxes match "${j}"; cannot pick one.`);O.ef=n1(O.ef,{l:{Owner:Z.id}})}let x=$.includeTypes??($.emailPreset==="signal"?["email"]:void 0);if(x?.length){for(let[S,[K,Z]]of Object.entries(f0))if(!x.includes(S))O[K]={l:{[Z]:i1}}}if($.tags?.length){let S=(await this.sets()).flatMap((Y)=>{let L=Y.definition;if(!L)return[];return Y.options.flatMap((G)=>G.value.type==="string"?[{id:G.id,definitionId:L.id,label:G.value.value,scope:Y.scope==="user"?"personal":"team"}]:[])}),K=new Map;for(let Y of $.tags){let L=S.filter((G)=>Aj(G.label)===Aj(Y.label.trim())&&(!Y.scope||G.scope===Y.scope));if(!L.length)throw Error(`Unknown tag "${Y.label}". Available tags: ${S.map((G)=>`${G.label} (${G.scope})`).join(", ")}.`);if($.tagsMatch==="all"&&L.length>1)throw Error(`Tag "${Y.label}" is ambiguous; specify personal or team scope.`);for(let G of L)K.set(G.id,G)}let X=[...K.values()].map((Y)=>({l:{pd:Y.definitionId,v:{so:Y.id}}})).reduce((Y,L)=>Y===void 0?L:{[$.tagsMatch==="all"?"&":"|"]:[Y,L]},void 0);O.propf=n1(O.propf,X)}return O}}class k0{client;constructor($){this.client=$}async page($={}){let O=new Fj(this.client);return this.fetch(O,await O.body($),$.cursor)}async*list($={}){let O=new Fj(this.client),j=await O.body($);yield*u((x)=>this.fetch(O,j,x))}async fetch($,O,j){let x=Q(await this.client.storage.postItemsSoupAst({body:O,query:j?{cursor:j}:void 0})),K=x.items.some((Z)=>q0(Z).some((X)=>X.definition.data_type==="TAG"))?await $.tagMap():new Map;return{items:x.items.map((Z)=>a1(this.client,Z,K)),nextCursor:x.next_cursor,hasMore:x.next_cursor!=null}}}function s1({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+async function cO($,O,j){if(!Number.isInteger(O)||O<1)throw RangeError(`concurrency limit must be a positive integer, got ${O}`);let x=Array($.length),S=0,K=async()=>{while(S<$.length){let X=S;S+=1,x[X]=await j($[X])}},Z=Array.from({length:Math.min(O,$.length)},K);return await Promise.all(Z),x}class W${loader;value;inflight;constructor($,O){this.loader=$;this.value=O}get(){if(this.value!==void 0)return Promise.resolve(this.value);return this.inflight??=this.loader().then(($)=>{return this.value=$,$}),this.inflight}peek(){return this.value}clear(){this.value=void 0,this.inflight=void 0}}async function*u($){let O;do{let j=await $(O),x=j.nextCursor??void 0;if(O!==void 0&&x!==void 0&&JSON.stringify(x)===JSON.stringify(O))throw Error("Pagination cursor did not advance");yield*j.items,O=x}while(O!==void 0)}class f extends Error{constructor($){super($);this.name="MacroError"}}class GO extends f{status;data;constructor($,O){super(`Macro API error ${$}`);this.status=$;this.data=O;this.name="MacroApiError"}}class E extends f{constructor($){super($);this.name="MacroNotFoundError"}}function G($){if($.error!==void 0)throw new GO($.response?.status??0,$.error);return $.data}class M{client;id;detail;constructor($,O,j){this.client=$;this.id=O;this.detail=new W$(()=>this.fetch(),j)}field($){return async()=>(await this.detail.get())[$]??void 0}mappedField($,O){return async()=>O((await this.detail.get())[$]??void 0)}toJSON(){let $=this.detail.peek();return $===void 0?{id:this.id}:{id:this.id,detail:$}}async mutate($){let O=G(await $(this.client));return this.detail.clear(),O}}class z$ extends M{async permission(){return G(await this.client.storage.getEntityPermission({path:{entity_type:this.entityType,entity_id:this.id}}))}async favorite(){return G(await this.client.storage.addFavorite({body:{entityId:this.id,entityType:this.entityType}})),this}async unfavorite(){return G(await this.client.storage.removeFavoriteByEntity({path:{entity_type:this.entityType,entity_id:this.id}})),this}}class X$ extends z${propertyReference(){return{entity_type:this.propertyEntityType,entity_id:this.id}}async properties($){let{properties:O}=G(await this.client.properties.getEntityProperties({path:{entity_type:this.propertyEntityType,entity_id:this.id},query:$?.includeMetadata!==void 0?{include_metadata:$.includeMetadata}:void 0}));return O}async setProperty($,O){G(await this.client.properties.setEntityProperty({path:{...this.propertyReference(),property_id:$.id},body:{value:O??null}}))}async updatePropertyOptions($){return G(await this.client.properties.bulkUpdateEntityPropertyOptions({path:this.propertyReference(),body:{properties:$.map((O)=>({property_id:O.property.id,...O.add?{add_option_ids:O.add.map((j)=>j.id)}:{},...O.remove?{remove_option_ids:O.remove.map((j)=>j.id)}:{}}))}}))}async deleteProperty($){G(await this.client.properties.deleteEntityProperty({path:{entity_property_id:$.property.id}}))}}var w6={"<":"\\u003c",">":"\\u003e","&":"\\u0026"};function i$($,O){let j=JSON.stringify(O).replace(/[<>&]/g,(x)=>w6[x]??x);return`<${$}>${j}${$}>`}function q6($){return typeof $==="object"&&$!==null&&typeof $.toMention==="function"}var f6={toMention:()=>({tag:i$("m-group-mention",{groupAlias:"here"}),mention:{entity_type:"group",entity_id:"here"}})};function b6($,...O){let j="",x=[];for(let[S,K]of $.entries()){j+=K;let Z=O[S];if(Z===void 0)continue;if(q6(Z)){let X=Z.toMention();j+=X.tag,x.push(X.mention)}else j+=String(Z)}return{content:j,mentions:k6(x)}}function k6($){let O=new Set;return $.filter((j)=>{let x=`${j.entity_type}:${j.entity_id}`;if(O.has(x))return!1;return O.add(x),!0})}function O$($){return typeof $==="string"?{content:$,mentions:[]}:$}class B$ extends M{static byId($,O){return new B$($,O)}static from($,O){return new B$($,O.id,O)}async fetch(){let $=G(await this.client.storage.listHarnesses()).find((O)=>O.id===this.id);if(!$)throw new E(`Harness ${this.id} is unavailable`);return $}name=this.field("name");connected=this.field("connected");kind=this.field("kind");async delete(){await this.mutate(($)=>$.storage.deleteHarness({path:{harness_id:this.id}}))}}class I$ extends M{static byId($,O){return new I$($,O)}static from($,O){return new I$($,O.bot.id,O)}async fetch(){let $=G(await this.client.storage.listAgents()).find((O)=>O.bot.id===this.id);if(!$)throw new E(`Agent ${this.id} is unavailable`);return $}name=this.mappedField("bot",($)=>$.name);instructions=this.field("instructions");defaultModel=this.field("default_model");channels=this.mappedField("channel_ids",($)=>$.map((O)=>b.byId(this.client,O)));host=this.mappedField("harness_id",($)=>$?B$.byId(this.client,$):void 0);async update($){await this.mutate((O)=>O.storage.updateAgent({path:{agent_id:this.id},body:gx($)}))}}function gx($){let{channels:O,team:j,host:x,autoAcceptPermissions:S,avatarUrl:K,channelScope:Z,defaultModel:X,isCoding:Y,...L}=$;return{...L,channel_ids:O?.map((Q)=>Q.id),team_id:j?.id,harness_id:x?.id,auto_accept_permissions:S,avatar_url:K,channel_scope:Z,default_model:X,is_coding:Y}}async function Wj($,O,j){let{channelId:x,thread:S}=g6(O);if(await y6($)){let{id:Z}=G(await $.storage.entityMessageCreate({path:{parent_type:"channel",parent_id:x},body:{content:j.content,mentions:j.mentions,attachments:[],thread_id:S?.rootId??null,nonce:crypto.randomUUID()}}));return Z}if(S)throw new f("a user-owned bot can only post via the channel webhook endpoint, which "+"does not support threads — use a team-owned bot, or requestedAs(user), "+"to reply in a thread");let{message_id:K}=G(await $.storage.postChannelBotWebhook({path:{channel_id:x},body:{content:j.content},headers:{"x-macro-bot-scope":"user"}}));return K}function g6($){return"rootId"in $?{channelId:$.channelId,thread:$}:{channelId:$.id}}async function y6($){if($.authConfig.type!=="bot"||$.hasActingUser())return!0;let{owner:O}=await $.selfBot();return O?.type==="team"}class h${client;channelId;rootId;constructor($,O,j){this.client=$;this.channelId=O;this.rootId=j}toJSON(){return{channelId:this.channelId,rootId:this.rootId}}channel(){return b.byId(this.client,this.channelId)}root(){return e.byId(this.client,this.channelId,this.rootId)}async replies(){let{replies:$}=G(await this.client.storage.entityMessageGetThread({path:{parent_type:"channel",parent_id:this.channelId,id:this.rootId}}));return $.map((O)=>e.from(this.client,this.channelId,O))}async reply($){let O=await Wj(this.client,this,O$($));return e.byId(this.client,this.channelId,O)}}class e extends z${channelId;mentions;entityType="channel_message";constructor($,O,j,x=[],S){super($,j,S);this.channelId=O;this.mentions=x}get path(){return{parent_type:"channel",parent_id:this.channelId,id:this.id}}async fetch(){return G(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j,x=[]){return new e($,O,j,x)}static from($,O,j){return new e($,O,j.id,j.mentions,j)}content=this.field("content");createdAt=this.field("created_at");editedAt=this.field("edited_at");updatedAt=this.field("updated_at");async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}channel(){return b.byId(this.client,this.channelId)}thread(){return new h$(this.client,this.channelId,this.id)}async react($){return await this.mutate((O)=>O.storage.entityMessageReact({path:this.path,body:{add:!0,emoji:$}})),this}async unreact($){return await this.mutate((O)=>O.storage.entityMessageReact({path:this.path,body:{add:!1,emoji:$}})),this}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}async reply($){return this.thread().reply($)}}class Bj{client;channel;record;constructor($,O,j){this.client=$;this.channel=O;this.record=j}agent(){return I$.byId(this.client,this.record.botId)}sessions(){return this.record.sessions.map(($)=>({session:i.byId(this.client,$.sessionId),isCurrent:$.isCurrent,createdAt:$.createdAt}))}turns(){return this.record.turns.map(($)=>new yx(this.client,this,$))}async startFresh($){G(await this.client.agentHarness.startFreshAgentConversation({path:{channel_id:this.channel.id,bot_id:this.record.botId},body:{sessionId:$.id}}))}toJSON(){return{channelId:this.channel.id,agentId:this.record.botId}}}class yx{client;conversation;record;constructor($,O,j){this.client=$;this.conversation=O;this.record=j}source(){return e.byId(this.client,this.conversation.channel.id,this.record.sourceMessageId)}session(){return i.byId(this.client,this.record.sessionId)}async retry($){G(await this.client.agentHarness.retryAgentConversationTurn({path:{channel_id:this.conversation.channel.id,bot_id:this.conversation.agent().id,source:this.record.sourceMessageId},body:{actionId:$}}))}toJSON(){return{channelId:this.conversation.channel.id,sourceMessageId:this.record.sourceMessageId}}}class L$ extends M{parent;toJSON(){return{...super.toJSON(),parentType:this.parent.type,parentId:this.parent.entity.id}}constructor($,O,j){super($,j);this.parent=O}static byId($,O,j){return new L$($,O,j)}get path(){return{parent_type:this.parent.type,parent_id:this.parent.entity.id,id:this.id}}async fetch(){return G(await this.client.storage.entityMessageGetThread({path:this.path})).state}resolved=this.field("resolved");async update($){let O={resolved:$.resolved,detach_anchor:$.detachAnchor,nonce:$.nonce};await this.mutate((j)=>j.storage.entityMessagePatchThread({path:this.path,body:O}))}async delete($){await this.mutate((O)=>O.storage.entityMessageDeleteThread({path:this.path,query:{nonce:$}}))}}async function w$($,O,j,x){for(let K of[...x?.messages??[],...x?.around?[x.around]:[]]){let Z="channelId"in K?{type:"channel",id:K.channelId}:("documentId"in K)?{type:"document",id:K.documentId}:("callId"in K)?{type:"call",id:K.callId}:K.parent;if(Z.type!==O.type||Z.id!==O.entity.id)throw Error("Timeline message belongs to another resource")}let S=G(await $.storage.messageTimelineEntries({path:{parent_type:O.type,parent_id:O.entity.id},query:{selection:x?JSON.stringify({cursor:x.cursor,around:x.around?.id,ids:x.messages?.map((K)=>K.id),activity_after:x.activityAfter,activity_before:x.activityBefore,anchored:x.anchored,direction:x.direction,include_deleted_threads:x.includeDeletedThreads,limit:x.limit}):void 0}}));return{entries:S.entries.map((K)=>{if(K.type==="activity")return{type:"activity",activity:{...K.activity,actor:P.byId($,K.activity.actor_id)}};return{type:"message",message:j(K.message)}}),nextCursor:S.next_cursor??void 0,previousCursor:S.previous_cursor??void 0}}var v6=50;function x$($){let{filters:O,type:j,make:x,includeCrm:S}=$;return(K,Z,X)=>{let Y=X?.searchOn??"name_content",L=X?.pageSize??v6;return u(async(Q)=>{let{results:J,next_cursor:I}=G(await K.search.unifiedSearch({body:{query:Z,match_type:"partial",search_on:Y,...O?{filters:O}:{},...S?{include_crm:!0}:{}},query:{page_size:L,...Q?{cursor:Q}:{}}}));return{items:J.filter((W)=>W.type===j).map((W)=>x(K,W)),nextCursor:I}})}}class QO{client;channel;record;constructor($,O,j){this.client=$;this.channel=O;this.record=j}get id(){return this.record.id}user(){return P.byId(this.client,this.record.user_id)}createdAt(){return this.record.created_at}async recordInteraction($){return new QO(this.client,this.channel,G(await this.client.storage.postActivity({body:{activity_type:$,channel_id:this.channel.id}})))}toJSON(){return this.record}}class b extends X${async recordActivity($){return new QO(this.client,this,G(await this.client.storage.postActivity({body:{activity_type:$,channel_id:this.id}})))}async setPicture($){await this.mutate((O)=>O.storage.setChannelPicture({path:{channel_id:this.id},body:{profile_picture_id:$?.id??null}}))}messageThreadById($){return L$.byId(this.client,{type:"channel",entity:this},$)}timelinePage($){return w$(this.client,{type:"channel",entity:this},(O)=>e.from(this.client,this.id,O),$)}async agentConversations(){return G(await this.client.agentHarness.listAgentConversations({path:{channel_id:this.id}})).conversations.map(($)=>new Bj(this.client,this,$))}entityType="channel";propertyEntityType="CHANNEL";async fetch(){return G(await this.client.storage.getChannel({path:{channel_id:this.id}}))}static byId($,O){return new b($,O)}static async dm($,O){let{channel_id:j}=G(await $.storage.getOrCreateDm({body:{recipient_id:O.id}}));return new b($,j)}static async private($,O){let{channel_id:j}=G(await $.storage.getOrCreatePrivate({body:{recipients:O.map((x)=>x.id)}}));return new b($,j)}static async create($,O){let{id:j}=G(await $.storage.createChannel({body:{channel_type:O.type,name:O.name??null,participants:(O.participants??[]).map((x)=>x.id),team_id:O.team?.id??null}}));return new b($,j)}name=this.field("channel_name");type=this.field("channel_type");async send($,O){let j=await Wj(this.client,O?.thread??this,O$($));return e.byId(this.client,this.id,j)}messages($){return this.timeline({limit:$?.pageSize})}messagesAfter($,O){return this.timeline({activity_after:$ instanceof Date?$.toISOString():$,limit:O?.pageSize})}timeline($){return u(async(O)=>{let j=G(await this.client.storage.messageTimeline({path:{parent_type:"channel",parent_id:this.id},query:{selection:JSON.stringify({...$,cursor:O})}}));return{items:j.items.map((x)=>e.from(this.client,this.id,x)),nextCursor:j.next_cursor}})}message($){return e.byId(this.client,this.id,$)}async rename($){await this.mutate((O)=>O.storage.patchChannel({path:{channel_id:this.id},body:{channel_name:$}}))}async delete(){await this.mutate(($)=>$.storage.deleteChannel({path:{channel_id:this.id}}))}async join(){await this.mutate(($)=>$.storage.joinChannel({path:{channel_id:this.id}}))}async joinCode(){let{join_code:$}=G(await this.client.storage.getChannelJoinLink({path:{channel_id:this.id}}));return $}async leave(){await this.mutate(($)=>$.storage.leaveChannel({path:{channel_id:this.id}}))}async participants(){return G(await this.client.storage.getChannelParticipants({path:{channel_id:this.id}}))}async addParticipants($){await this.mutate((O)=>O.storage.addParticipants({path:{channel_id:this.id},body:{participants:$.map((j)=>j.id)}}))}async removeParticipants($){await this.mutate((O)=>O.storage.removeParticipants({path:{channel_id:this.id},body:{participants:$.map((j)=>j.id)}}))}async typing($,O){G(await this.client.storage.entityMessageTyping({path:{parent_type:"channel",parent_id:this.id},body:{active:$==="start",thread_id:O?.thread?.rootId??null}}))}attachments($){return u(async(O)=>{let j=G(await this.client.storage.getChannelAttachments({path:{channel_id:this.id},query:{...$?.pageSize?{limit:$.pageSize}:{},...$?.type?{attachment_type:$.type}:{},...O?{cursor:O}:{}}}));return{items:j.items,nextCursor:j.next_cursor}})}webUrl(){return`${this.client.webAppUrl}/app/channel/${this.id}`}static search=x$({type:"channel",make:($,O)=>new b($,O.channel_id)})}class P extends X${entityType="user";propertyEntityType="USER";async fetch(){let{names:$}=G(await this.client.auth.getUserNamesWithEmail({body:{user_ids:[this.id]}})),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`user ${this.id} not found`);return O}static byId($,O){return new P($,O)}static fromName($,O){return new P($,O.id,O)}static async me($){let{user_id:O}=G(await $.auth.getUserInfo());return new P($,O)}async name(){let $=await this.detail.get();return[$.first_name,$.last_name].filter(Boolean).join(" ")||void 0}email(){let $=this.id.startsWith("macro|")?this.id.slice(6):void 0;return $?.includes("@")?$:void 0}dm(){return b.dm(this.client,this)}toMention(){return{tag:i$("m-user-mention",{userId:this.id}),mention:{entity_type:"user",entity_id:this.id}}}}class o{client;entityType;entity;constructor($,O,j){this.client=$;this.entityType=O;this.entity=j}get path(){return{entity_type:this.entityType,entity_id:this.entity.id}}async state($){let O=G(await this.client.storage.accessRequestsState({path:this.path,query:{offset:$}}));return{accessLevel:O.accessLevel??void 0,canReview:O.canReview,owner:O.owner?P.byId(this.client,O.owner):void 0,pendingCount:O.pendingCount,supportedLevels:O.supportedLevels,nextOffset:O.nextOffset??void 0,mine:O.mine?zO.from(this.client,this,O.mine):void 0,requests:O.requests.map((j)=>zO.from(this.client,this,j))}}async submit($,O){return zO.from(this.client,this,G(await this.client.storage.accessRequestsSubmit({path:this.path,body:{requestedLevel:$,revision:O}})))}async cancel($){G(await this.client.storage.accessRequestsCancel({path:this.path,query:{revision:$}}))}async direct(){return G(await this.client.storage.accessRequestsDirect({path:this.path})).map(($)=>({user:P.byId(this.client,$.userId),accessLevel:$.accessLevel}))}async grant($,O){G(await this.client.storage.accessRequestsSetDirect({path:{...this.path,user_id:$.id},body:{accessLevel:O}}))}async remove($){G(await this.client.storage.accessRequestsRemoveDirect({path:{...this.path,user_id:$.id}}))}async resolve($,O){let j=$.access.toJSON();if(j.entity_type!==this.entityType||j.entity_id!==this.entity.id)throw Error("Access request belongs to another entity");return G(await this.client.storage.accessRequestsResolve({path:{...this.path,request_id:$.id},body:O}))}toJSON(){return this.path}}class zO extends M{access;resolvedRecord;constructor($,O,j){super($,j.id,j);this.access=O}static from($,O,j){return new zO($,O,j)}async fetch(){if(this.resolvedRecord)return this.resolvedRecord;let $;do{let O=await this.access.state($),j=[O.mine,...O.requests].find((x)=>x?.id===this.id);if(j)return j.detail.get();$=O.nextOffset}while($!==void 0);throw new E(`Access request ${this.id} is unavailable`)}revision=this.field("revision");status=this.field("status");requestedLevel=this.field("requestedLevel");requester=this.mappedField("requesterId",($)=>P.byId(this.client,$));async resolve($){this.resolvedRecord=await this.access.resolve(this,{revision:await this.revision(),grantedLevel:$}),this.detail.clear()}}function n$($){return{...$,channelSharePermissions:$.channelSharePermissions===void 0||$.channelSharePermissions===null?$.channelSharePermissions:$.channelSharePermissions.map((O)=>({channelId:O.channel.id,accessLevel:O.accessLevel,operation:O.operation}))}}class N$ extends M{parent;constructor($,O,j,x){super($,j,x);this.parent=O}static byId($,O,j){return new N$($,O,j)}static fromRecord($,O,j){return new N$($,O,j.id,j)}static async create($,O,j){return N$.createForSession($,O.session(),j,O)}static async createForSession($,O,j,x){let S=G(await $.agentHarness.createSessionReview({path:{session_id:O.id},body:{...j,executionId:x?.id??null}}));return N$.fromRecord($,O,S)}static async list($,O){return G(await $.agentHarness.listExecutionReviews({path:{session_id:O.session().id,execution_id:O.id}})).map((x)=>N$.fromRecord($,O.session(),x))}async fetch(){return G(await this.client.agentHarness.getSessionReview({path:{session_id:this.parent.id,review_id:this.id}}))}title=this.field("title");kind=this.field("kind");session(){return this.parent}async reference(){return{kind:await this.kind(),id:this.id}}async items(){return(await this.detail.get()).items.map(($)=>new vx($,{edit:(O)=>this.decide({action:"edit",item:$.id,draft:O}),submit:()=>this.decide({action:"submit",items:[$.id]}),dismiss:()=>this.decide({action:"dismiss",items:[$.id]})}))}async refresh(){return this.detail.clear(),await this.detail.get(),this}async submitAll(){await this.decide({action:"submit",items:[]})}async dismissAll(){await this.decide({action:"dismiss",items:[]})}async decide($){let O=(await this.detail.get()).revision;await this.mutate((j)=>j.agentHarness.decideSessionReview({path:{session_id:this.parent.id,review_id:this.id},body:{...$,revision:O}}))}}class vx{snapshot;actions;constructor($,O){this.snapshot=$;this.actions=O}get id(){return this.snapshot.id}get status(){return this.snapshot.status}get draft(){return this.snapshot.draft}get result(){return this.snapshot.result}async edit($){await this.actions.edit($)}async submit(){await this.actions.submit()}async dismiss(){await this.actions.dismiss()}}class uO extends M{parent;constructor($,O,j){super($,O);this.parent=j}static byId($,O,j){return new uO($,j,O)}async fetch(){return G(await this.client.agentHarness.getCodeExecution({path:{session_id:this.parent.id,execution_id:this.id}}))}reviews={create:($)=>N$.create(this.client,this,$),list:()=>N$.list(this.client,this)};session(){return this.parent}status=this.field("status");source=this.field("source");calls=this.field("calls");error=this.field("error");async result(){return(await this.detail.get()).result}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class Lj{client;sessionId;dto;constructor($,O,j){this.client=$;this.sessionId=O;this.dto=j}static from($,O,j){return new Lj($,O,j)}get actionId(){return this.dto.actionId}get kind(){return this.dto.kind}get prompt(){return this.dto.prompt??void 0}get attachments(){return this.dto.attachments??[]}get actorUserId(){return this.dto.actorUserId??void 0}get createdAt(){return this.dto.createdAt}async edit($){return G(await this.client.agentHarness.editQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId},body:{prompt:$}})),this.dto={...this.dto,prompt:$},this}async steer(){G(await this.client.agentHarness.steerQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId}}))}async remove(){G(await this.client.agentHarness.removeQueuedAction({path:{session_id:this.sessionId,action_id:this.actionId}}))}}class dO{client;session;id;constructor($,O,j){this.client=$;this.session=O;this.id=j}static byId($,O,j){return new dO($,O,j)}async answer($){return G(await this.client.agentHarness.answerAgentSessionToolApproval({path:{session_id:this.session.id,approval_id:this.id},body:{answer:$}}))}toJSON(){return{id:this.id,sessionId:this.session.id}}}class i extends M{access=new o(this.client,"agent_session",this);toolApprovalById($){return dO.byId(this.client,this,$)}async sharePermissions(){return G(await this.client.agentHarness.getAgentSessionPermissions({path:{session_id:this.id}}))}async updateSharePermissions($){return this.mutate((O)=>O.agentHarness.updateAgentSessionPermissions({path:{session_id:this.id},body:n$($)}))}static byId($,O){return new i($,O)}static async createManaged($,O){let{session:j}=G(await $.agentHarness.createAgentSession({body:{prompt:O?.prompt,instructions:O?.instructions,model:O?.model,repoUrl:O?.repoUrl,repoBranch:O?.repoBranch}}));return new i($,j.id,j)}static async repositories($){let{repositories:O}=G(await $.agentHarness.listAgentRepositories());return O.map((j)=>({url:j.url,defaultBranch:j.defaultBranch??void 0}))}static async repositoryBranches($,O){let{branches:j}=G(await $.agentHarness.listAgentRepositoryBranches({query:{repoUrl:O}}));return j}async fetch(){return G(await this.client.agentHarness.getAgentSession({path:{session_id:this.id}}))}name=this.field("name");isArchived=this.field("isArchived");model=this.field("model");harness=this.field("harness");repoUrl=this.field("repoUrl");workspace=this.field("workspace");instructions=this.field("instructions");status=this.field("status");sandboxSize=this.field("sandboxSize");createdAt=this.field("createdAt");modifiedAt=this.field("modifiedAt");static async forPullRequest($,O){let{sessionIds:j}=G(await $.agentHarness.agentSessionsForPullRequest({body:{url:O}}));return j.map((x)=>i.byId($,x))}async pullRequests(){let{pullRequests:$}=G(await this.client.agentHarness.listAgentSessionPullRequests({path:{session_id:this.id}}));return $.map((O)=>({githubKey:O.githubKey,url:O.url,source:O.source,linkedBy:O.linkedBy?P.byId(this.client,O.linkedBy):void 0,createdAt:O.createdAt}))}async linkPullRequest($){G(await this.client.agentHarness.linkAgentSessionPullRequest({path:{session_id:this.id},body:{url:$}}))}async unlinkPullRequest($){G(await this.client.agentHarness.unlinkAgentSessionPullRequest({path:{session_id:this.id},query:{url:$}}))}async rename($){await this.mutate((O)=>O.agentHarness.renameAgentSession({path:{session_id:this.id},body:{name:$}}))}async archive(){await this.setArchived(!0)}async unarchive(){await this.setArchived(!1)}async setArchived($){await this.mutate((O)=>O.agentHarness.setAgentSessionArchived({path:{session_id:this.id},body:{isArchived:$}}))}async setSandboxSize($){let{size:O}=await this.mutate((j)=>j.agentHarness.putAgentSessionSandboxSize({path:{session_id:this.id},body:{size:$}}));return O}static async defaultSandboxSize($){return G(await $.agentHarness.getAgentSandboxSize()).size}static async setDefaultSandboxSize($,O){return G(await $.agentHarness.putAgentSandboxSize({body:{size:O}})).size}static async codingPreferences($){return G(await $.agentHarness.getAgentCodingPreferences())}static async setCodingPreferences($,O){return G(await $.agentHarness.putAgentCodingPreferences({body:O}))}async control($){return this.mutate((O)=>O.agentHarness.controlAgentSession({path:{session_id:this.id},body:$}))}prompt($,O){return this.control({type:"prompt",prompt:$,...O&&O.length>0?{attachments:O}:{}})}async queue(){let{entries:$}=G(await this.client.agentHarness.getAgentSessionQueue({path:{session_id:this.id}}));return $.map((O)=>Lj.from(this.client,this.id,O))}async changes(){return G(await this.client.agentHarness.getAgentSessionChanges({path:{session_id:this.id}}))}async changesPatch(){return G(await this.client.agentHarness.getAgentSessionChangesPatch({path:{session_id:this.id}})).patch}async refreshChanges(){return this.mutate(($)=>$.agentHarness.refreshAgentSessionChanges({path:{session_id:this.id}}))}async foldedLog(){let{bot:$,messages:O}=G(await this.client.agentHarness.getAgentSessionFoldedLog({path:{session_id:this.id}}));return{bot:$,messages:O}}async log(){return G(await this.client.agentHarness.getAgentSessionLog({path:{session_id:this.id}}))}reviews={create:($)=>N$.createForSession(this.client,this,$),byId:($)=>N$.byId(this.client,this,$)};codeExecutions={byId:($)=>uO.byId(this.client,this,$)};async delete(){await this.mutate(($)=>$.agentHarness.deleteAgentSession({path:{session_id:this.id}}))}}class hx{client;constructor($){this.client=$}byId($){return i.byId(this.client,$)}createManaged($){return i.createManaged(this.client,$)}repositories(){return i.repositories(this.client)}repositoryBranches($){return i.repositoryBranches(this.client,$)}forPullRequest($){return i.forPullRequest(this.client,$)}defaultSandboxSize(){return i.defaultSandboxSize(this.client)}setDefaultSandboxSize($){return i.setDefaultSandboxSize(this.client,$)}codingPreferences(){return i.codingPreferences(this.client)}setCodingPreferences($){return i.setCodingPreferences(this.client,$)}}class mx{client;constructor($){this.client=$}byId($){return I$.byId(this.client,$)}async list(){return G(await this.client.storage.listAgents()).map(($)=>I$.from(this.client,$))}async create($){return I$.from(this.client,G(await this.client.storage.createAgent({body:gx($)})))}}class cx{client;async usage($={}){let{users:O,...j}=$;return G(await this.client.cognition.getUsageHandler({body:{...j,include_users:O?.map((x)=>x.id)}}))}constructor($){this.client=$}async structuredCompletion($){return G(await this.client.cognition.structuredCompletion({body:$}))}async decide($){return G(await this.client.cognition.decisions({body:$}))}}class s$ extends M{static byId($,O){return new s$($,O)}static from($,O){return new s$($,O.id,{id:O.id,name:O.name,createdAt:O.createdAt})}async fetch(){let $=G(await this.client.storage.listUserApiKeys()).keys.find((O)=>O.id===this.id);if(!$)throw new E(`API key ${this.id} is unavailable`);return $}name=this.field("name");createdAt=this.field("createdAt");async delete(){await this.mutate(($)=>$.storage.deleteUserApiKey({path:{id:this.id}}))}}class ux{client;constructor($){this.client=$}byId($){return s$.byId(this.client,$)}async list(){return G(await this.client.storage.listUserApiKeys()).keys.map(($)=>s$.from(this.client,$))}async create($){let O=G(await this.client.storage.createUserApiKey({body:{name:$}}));return{key:s$.from(this.client,O),secret:O.key}}async tokenForEmail($){return G(await this.client.auth.macroApiToken({query:{email:$}}))}}class lO{client;constructor($){this.client=$}async me(){if(this.client.authConfig.type!=="bot")throw new f("bots.me() requires bot auth — a user API key has no bot identity");return G(await this.client.storage.getSelfBot())}async channels(){if(this.client.authConfig.type!=="bot")throw new f("bots.channels() requires bot auth — a user API key has no bot identity");let $=await this.me();return G(await this.client.storage.listBotChannels({path:{bot_id:$.id}}))}async myPrincipalId(){if(this.client.authConfig.type!=="bot")throw new f("bots.myPrincipalId() requires bot auth — a user API key has no bot identity");return this.client.myPrincipalId()}}class S$ extends M{async fetch(){let O=G(await this.client.auth.getUserTeams()).find((j)=>j.id===this.id);if(!O)throw new E(`team ${this.id} not found`);return O}static byId($,O){return new S$($,O)}static async current($){let O=G(await $.auth.getTeam());if(!O)throw new E("caller has no current team");return new S$($,O.team.id,O.team)}static async list($){return G(await $.auth.getUserTeams()).map((j)=>new S$($,j.id,j))}name=this.field("name");slug=this.field("slug");defaultLinkShare=this.field("default_link_share");owner=this.mappedField("owner_id",($)=>P.byId(this.client,$));async members(){let $=G(await this.client.auth.getTeam());if(!$||$.team.id!==this.id)throw new f("members are only available for the current team (see Team.current)");return $.members.map((O)=>({user:P.byId(this.client,O.user_id),role:O.role}))}}class T$ extends M{async fetch(){let{links:$}=G(await this.client.email.listLinks()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`email link ${this.id} not found`);return O}static byId($,O){return new T$($,O)}static async list($){let{links:O}=G(await $.email.listLinks());return O.map((j)=>new T$($,j.id,j))}emailAddress=this.field("email_address");provider=this.field("provider");isPrimary=this.field("is_primary");isSyncActive=this.field("is_sync_active");syncStatus=this.field("sync_status");needsReauth=this.field("needs_reauth");photoUrl=this.field("photo_url");async settingsOperations(){return G(await this.client.email.mailboxSettingsOperations({headers:{"X-Email-Link-Id":this.id}}))}}class m$ extends M{async setContributesToAvailability($){await this.mutate((O)=>O.calendar.setAvailabilityCalendar({path:{calendar_id:this.id},body:{contributesToAvailability:$}}))}async fetch(){let{calendars:$}=G(await this.client.calendar.listCalendars()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`calendar ${this.id} not found`);return O}static byId($,O){return new m$($,O)}static async list($){let{calendars:O}=G(await $.calendar.listCalendars());return O.map((j)=>new m$($,j.id,j))}name=this.field("name");emailAddress=this.field("emailAddress");isPrimary=this.field("isPrimary");isWritable=this.field("isWritable");isSubscription=this.field("isSubscription");color=this.field("color");syncError=this.field("syncError");emailLink=this.mappedField("emailLinkId",($)=>T$.byId(this.client,$))}class rO{client;id;constructor($,O){this.client=$;this.id=O}async status(){return G(await this.client.calendar.calendarReplacementStatus({path:{operation_id:this.id}}))}async confirm(){return G(await this.client.calendar.confirmCalendarReplacement({path:{operation_id:this.id}}))}async discard(){G(await this.client.calendar.discardCalendarReplacement({path:{operation_id:this.id}}))}}class $$ extends M{async notes($){return this.requireOwnOccurrence($),G(await this.client.calendar.eventNotes({path:{event_id:this.id},query:{occurrenceKey:$.occurrenceKey}})).map((j)=>q$.fromRecord(this.client,this,$,j))}async linkNote($,O,j={}){return this.requireOwnOccurrence(O),G(await this.client.calendar.linkEventNote({path:{event_id:this.id,document_id:$.id},query:{occurrenceKey:O.occurrenceKey},body:{teamId:j.team?.id??null}})),q$.forDocument(this.client,this,O,$)}requireOwnOccurrence($){if($.eventId!==this.id)throw new f("The occurrence belongs to a different event")}async fetch(){throw new f(`calendar event ${this.id} has no fetch-by-id endpoint; read the record returned by calendar.createEvent / event.update / event.rsvp instead`)}static byId($,O){return new $$($,O)}static fromRecord($,O){return new $$($,O.id,O)}title=this.field("title");description=this.field("description");location=this.field("location");time=this.field("time");status=this.field("status");attendees=this.field("attendees");transparency=this.field("transparency");isReadOnly=this.field("isReadOnly");recurrenceLines=this.field("recurrenceLines");guestPolicy=this.field("guestPolicy");viewerCan=this.field("viewerCan");calendar=this.mappedField("calendarId",($)=>$?m$.byId(this.client,$):void 0);record(){return this.detail.get()}async update($){let O=await this.mutate((j)=>j.calendar.updateCalendarEvent({path:{event_id:this.id},body:h6($)}));return $$.fromRecord(this.client,O)}async delete($={}){await this.mutate((O)=>O.calendar.deleteCalendarEvent({path:{event_id:this.id},query:{calendarId:$.calendar?.id,scope:$.scope,recurrenceId:$.recurrenceId,inbox:$.inbox}}))}async prepareReplacement($){let O=G(await this.client.calendar.prepareCalendarReplacement({path:{event_id:this.id},body:{removeConference:$.removeConference,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}}));return new rO(this.client,O.operationId)}async providerUrl($={}){return G(await this.client.calendar.calendarEventProviderUrl({path:{event_id:this.id},query:{recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}})).url??void 0}async inviteGuests($){let O=await this.mutate((j)=>j.calendar.inviteCalendarEventGuests({path:{event_id:this.id},body:{guests:$.guests,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id,inbox:$.inbox}}));return $$.fromRecord(this.client,O)}async addToCalendar($={}){let O=await this.mutate((j)=>j.calendar.copyCalendarEvent({path:{event_id:this.id},body:{calendarId:$.calendar?.id}}));return $$.fromRecord(this.client,O)}async ics(){return G(await this.client.storage.eventIcs({path:{event_id:this.id}}))}async rsvp($){let O=await this.mutate((j)=>j.calendar.rsvpCalendarEvent({path:{event_id:this.id},body:{response:$.response,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id}}));return $$.fromRecord(this.client,O)}}function h6($){return{title:$.title,description:$.description,location:$.location,time:$.time,attendees:$.attendees,recurrenceLines:$.recurrenceLines,visibility:$.visibility,transparency:$.transparency,reminders:$.reminders,conference:$.conference,outOfOffice:$.outOfOffice,guestPolicy:$.guestPolicy,scope:$.scope,recurrenceId:$.recurrenceId,calendarId:$.calendar?.id,inbox:$.inbox}}class q$ extends M{event;occurrence;fromDocument;constructor($,O,j,x,S,K=!1){super($,x.id,S);this.event=O;this.occurrence=j;this.fromDocument=K;if(j.eventId!==O.id)throw new f("Choose an occurrence belonging to this event")}static fromDocumentLink($,O,j){return new q$($,$$.byId($,j.eventId),j,O,{documentId:O.id,name:j.documentName,team:j.team,canManage:!0},!0)}static forDocument($,O,j,x){return new q$($,O,j,x)}static fromRecord($,O,j,x){return new q$($,O,j,w.byId($,x.documentId),x)}async fetch(){if(this.fromDocument){let x=G(await this.client.calendar.documentNoteLinks({path:{document_id:this.id}})).find((S)=>S.eventId===this.event.id&&S.occurrenceKey===this.occurrence.occurrenceKey);if(!x)throw new E("This meeting link has been removed");return{documentId:this.id,name:x.documentName,team:x.team,canManage:!0}}let O=G(await this.client.calendar.eventNotes({path:{event_id:this.event.id},query:{occurrenceKey:this.occurrence.occurrenceKey}})).find((j)=>j.documentId===this.id);if(!O)throw new E("This document is no longer linked to the meeting");return O}document=this.mappedField("documentId",($)=>w.byId(this.client,$));name=this.field("name");team=this.mappedField("team",($)=>$?S$.byId(this.client,$.id):void 0);canManage=this.field("canManage");async setTeam($){await this.mutate((O)=>O.calendar.linkEventNote({path:{event_id:this.event.id,document_id:this.id},query:{occurrenceKey:this.occurrence.occurrenceKey},body:{teamId:$?.id??null}}))}async unlink(){await this.mutate(($)=>$.calendar.unlinkEventNote({path:{event_id:this.event.id,document_id:this.id},query:{occurrenceKey:this.occurrence.occurrenceKey}}))}}class n extends X${async sharePermissions(){return G(await this.client.storage.getProjectPermissionsV2({path:{id:this.id}}))}async accessLevel(){return G(await this.client.storage.getProjectUserAccessLevel({path:{id:this.id}}))}access=new o(this.client,"project",this);entityType="project";propertyEntityType="PROJECT";async fetch(){let{data:$}=G(await this.client.storage.getProjectHandler({path:{id:this.id}}));return $.projectMetadata}static byId($,O){return new n($,O)}static async create($,O){let{data:j}=G(await $.storage.createProjectHandler({body:{name:O.name,projectParentId:O.parent?.id??null}}));return new n($,j.id,j)}name=this.field("name");parent=this.mappedField("parentId",($)=>$?n.byId(this.client,$):void 0);createdAt=this.field("createdAt");async items(){let{data:$}=G(await this.client.storage.getProjectContentHandler({path:{id:this.id}}));return $.map((O)=>O.item)}async rename($){await this.mutate((O)=>O.storage.editProjectV2({path:{id:this.id},body:{name:$}}))}async delete($){await this.mutate((O)=>$?.permanent?O.storage.permanentlyDeleteProject({path:{id:this.id}}):O.storage.deleteProjectHandler({path:{id:this.id}}))}async restore(){await this.mutate(($)=>$.storage.revertDeleteProject({path:{id:this.id}}))}static search=x$({filters:{project_filters:{}},type:"project",make:($,O)=>new n($,O.id)})}class JO extends M{document;toJSON(){return{...super.toJSON(),documentId:this.document.id}}constructor($,O,j,x){super($,j,x);this.document=O}static byId($,O,j){return new JO($,O,j)}static from($,O,j){return new JO($,O,j.uuid,j)}async fetch(){let $=G(await this.client.storage.getDocumentAnchors({path:{document_id:this.document.id}})).data.find((O)=>O.uuid===this.id);if(!$)throw new E(`Annotation ${this.id} is unavailable`);return $}kind=this.field("anchorType");page=this.field("page");async edit($){if(await this.kind()!=="placeable")throw Error("Only placeable comment annotations can be edited");await this.mutate((O)=>O.storage.editAnchor({body:{...$,uuid:this.id,anchorType:"free-comment",fileType:"pdf"}}))}async delete(){if(await this.kind()!=="highlight")throw Error("Only standalone highlights can be deleted with this endpoint");await this.mutate(($)=>$.storage.deleteAnchor({body:{uuid:this.id,anchorType:"highlight",fileType:"pdf"}}))}}class c$ extends M{documentId;constructor($,O,j,x){super($,j,x);this.documentId=O}get path(){return{parent_type:"document",parent_id:this.documentId,id:this.id}}async fetch(){return G(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new c$($,O,j)}static from($,O,j){return new c$($,O,j.id,j)}text=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");async threadId(){return(await this.detail.get()).thread_id??this.id}document(){return w.byId(this.client,this.documentId)}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){return this.document().comment($,{threadId:await this.threadId()})}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}class pO{client;document;id;detail;constructor($,O,j){this.client=$;this.document=O;this.id=j;this.detail=new W$(async()=>G(await this.client.storage.getDocumentVersion({path:{document_id:O.id,document_version_id:j}})).data)}static byId($,O,j){return new pO($,O,j)}read(){return this.detail.get()}toJSON(){return{id:this.id,documentId:this.document.id}}}var m6=8;class w extends X${async meetingNotes(){return G(await this.client.calendar.documentNoteLinks({path:{document_id:this.id}})).map((O)=>({note:q$.fromDocumentLink(this.client,this,O),eventTitle:O.eventTitle}))}async anchors(){return G(await this.client.storage.getDocumentAnchors({path:{document_id:this.id}})).data.map(($)=>JO.from(this.client,this,$))}async createHighlight($){return JO.from(this.client,this,G(await this.client.storage.createAnchor({path:{document_id:this.id},body:{...$,fileType:"pdf",anchorType:"highlight"}})))}version($){return pO.byId(this.client,this,$)}async sharePermissions(){return G(await this.client.storage.getDocumentPermissionsV2({path:{document_id:this.id}})).documentPermissions}async permissionsToken(){return G(await this.client.storage.getDocumentPermissionsToken({path:{document_id:this.id}})).token}async prepareSave($){return G(await this.client.storage.presaveDocumentHandler({path:{document_id:this.id},body:{newBom:$}})).data}async save($){return(await this.mutate((O)=>O.storage.saveDocumentHandler({path:{document_id:this.id},body:$}))).data}async simpleSave(){return(await this.mutate(($)=>$.storage.simpleSave({path:{document_id:this.id}}))).data}messageThreadById($){return L$.byId(this.client,{type:"document",entity:this},$)}timelinePage($){return w$(this.client,{type:"document",entity:this},(O)=>c$.from(this.client,this.id,O),$)}access=new o(this.client,"document",this);async fetch(){let{data:$}=G(await this.client.storage.getDocument({path:{document_id:this.id}}));return $.documentMetadata}static byId($,O){return new w($,O)}static async create($,O){let{documentId:j}=G(await $.storage.createMarkdownHandler({body:{documentName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static async createSnippet($,O){let{documentId:j}=G(await $.storage.createSnippetHandler({body:{snippetName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static async createSkill($,O){let{documentId:j}=G(await $.storage.createSkillHandler({body:{skillName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null}}));return new w($,j)}static recent($,O){let j=O?.pageSize??50;return u(async(x)=>{let S=G(await $.storage.getUserDocumentsHandler({query:{limit:j,offset:x?Number(x):0,...O?.fileType!==void 0?{file_type:O.fileType}:{}}})),K=S.data?.next_offset;return{items:(S.data?.documents??[]).map((Z)=>new w($,Z.documentId)),nextCursor:K!=null?String(K):null}})}static async recentlyDeleted($){let{data:O}=G(await $.storage.recentlyDeleted({}));return O.items.filter((j)=>j.type==="document").map((j)=>new w($,j.id))}entityType="document";propertyEntityType="DOCUMENT";name=this.field("documentName");fileType=this.field("fileType");project=this.mappedField("projectId",($)=>$?n.byId(this.client,$):void 0);owner=this.mappedField("owner",($)=>P.byId(this.client,$));branchedFrom=this.mappedField("branchedFromId",($)=>$?w.byId(this.client,$):void 0);createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");deletedAt=this.field("deletedAt");async content(){let{text:$}=G(await this.client.storage.getDocumentTextContent({path:{document_id:this.id}}));if($!==null)return $;let{presigned_url:O}=G(await this.client.storage.exportDocument({path:{document_id:this.id}})),j=await fetch(O);if(!j.ok)throw new GO(j.status,{message:"failed to download document content"});return j.text()}async rename($){await this.mutate((O)=>O.storage.editDocument({path:{document_id:this.id},body:{documentName:$}}))}async move($){await this.mutate((O)=>O.storage.editDocument({path:{document_id:this.id},body:{projectId:$?.id??""}}))}async delete($){await this.mutate((O)=>$?.permanent?O.storage.permanentlyDeleteDocument({path:{document_id:this.id}}):O.storage.deleteDocument({path:{document_id:this.id}}))}async restore(){await this.mutate(($)=>$.storage.revertDeleteDocument({path:{document_id:this.id}}))}async copy($){let{data:O}=G(await this.client.storage.copyDocument({path:{document_id:this.id},query:$.versionId!==void 0?{version_id:$.versionId}:void 0,body:{documentName:$.name}}));return new w(this.client,O.documentMetadata.documentId)}async comments(){let $={parent_type:"document",parent_id:this.id},O=u(async(x)=>{let S=G(await this.client.storage.messageTimeline({path:$,query:{selection:JSON.stringify({limit:100,cursor:x})}}));return{items:S.items,nextCursor:S.next_cursor}}),j=[];for await(let x of O)j.push(x);return cO(j,m6,async(x)=>{let{state:S,root:K,replies:Z}=G(await this.client.storage.entityMessageGetThread({path:{...$,id:x.id}}));return{thread:S,comments:[K,...Z].map((X)=>c$.from(this.client,this.id,X))}})}async comment($,O){let j=await this.mutate((x)=>x.storage.entityMessageCreate({path:{parent_type:"document",parent_id:this.id},body:{...O$($),thread_id:O?.threadId??null}}));return c$.from(this.client,this.id,j)}async shortId(){return G(await this.client.storage.getDocumentShortId({path:{document_id:this.id}}))}async teamShare(){return G(await this.client.storage.getDocumentTeamShare({path:{document_id:this.id}}))}async setTeamShare($){await this.mutate((O)=>O.storage.setDocumentTeamShare({path:{document_id:this.id},body:{shareWithTeam:$}}))}async githubPullRequests(){let{pullRequests:$}=G(await this.client.storage.getDocumentGithubPullRequests({path:{document_id:this.id}}));return $}async branchName(){let{branchName:$}=G(await this.client.storage.getDocumentBranchName({path:{document_id:this.id}}));return $}webUrl(){return`${this.client.webAppUrl}/app/md/${this.id}`}static search=x$({filters:{document_filters:{}},type:"document",make:($,O)=>new w($,O.document_id)});toMention(){let $=this.detail.peek();return{tag:i$("m-document-mention",{documentId:this.id,documentName:$?.documentName??"",blockName:$?.fileType??"md"}),mention:{entity_type:"document",entity_id:this.id}}}}class dx{client;async noteDocuments($=""){let O=G(await this.client.calendar.noteDocuments({query:{query:$}}));return{documents:O.documents.map((j)=>({document:w.byId(this.client,j.documentId),name:j.name})),teams:O.teams.map((j)=>({team:S$.byId(this.client,j.id),name:j.name}))}}async availabilityCalendars(){return G(await this.client.calendar.getAvailabilityCalendars()).calendars.map(($)=>({calendar:m$.byId(this.client,$.calendarId),name:$.name,isPrimary:$.isPrimary,contributesToAvailability:$.contributesToAvailability}))}async teamSharing(){return G(await this.client.calendar.getTeamSharing()).sharing}async setTeamSharing($){return G(await this.client.calendar.setTeamSharing({body:{sharing:$}})).sharing}occurrences($){let O;return u(async(j)=>{let x=G(await this.client.storage.listOccurrences({query:{...$,cursor:j}}));O??=u6(this.client);let S=await O;return{items:x.items.map((K)=>({event:$$.fromRecord(this.client,K.event),occurrence:K.occurrence,inbox:K.event.calendarId?S.get(K.event.calendarId):void 0,role:d6(K.event)})),nextCursor:x.nextCursor}})}async teamPage($){let O=G(await this.client.storage.listTeamCalendar({query:$}));return{items:O.items.map(({ownerId:j,...x})=>({...x,owner:P.byId(this.client,j)})),members:O.members.map((j)=>({user:P.byId(this.client,j.userId),sharing:j.sharing,coverage:j.coverage})),nextCursor:O.nextCursor??void 0}}async teamOutOfOffice($){let O=G(await this.client.storage.listTeamOutOfOffice({query:$}));return{items:O.items.map((j)=>({event:$$.byId(this.client,j.eventId),owner:P.byId(this.client,j.ownerId),occurrenceKey:j.occurrenceKey,time:j.time,title:j.title??void 0})),hasMore:O.hasMore}}constructor($){this.client=$}calendars(){return m$.list(this.client)}calendar($){return m$.byId(this.client,$)}event($){return $$.byId(this.client,$)}replacement($){return new rO(this.client,$)}async createEvent($){let O=G(await this.client.calendar.createCalendarEvent({body:c6($)}));return $$.fromRecord(this.client,O)}}function c6($){return{title:$.title,time:$.time,description:$.description,location:$.location,attendees:$.attendees,recurrenceLines:$.recurrenceLines,visibility:$.visibility,transparency:$.transparency,reminders:$.reminders,conference:$.conference,macroCall:$.macroCall,outOfOffice:$.outOfOffice,guestPolicy:$.guestPolicy,calendarId:$.calendar?.id,emailLinkId:$.emailLink?.id}}async function u6($){let{calendars:O}=G(await $.calendar.listCalendars());return new Map(O.map((j)=>[j.id,j.emailAddress]))}function d6($){let O=$.attendees.find((j)=>j.isSelf);if($.viewerCan.organize||O?.isOrganizer)return"organizer";return O?"guest":void 0}class H$ extends M{lookupToken;constructor($,O,j){super($,O,j);this.lookupToken=j?.shareToken}static byId($,O){return new H$($,O)}static from($,O){return new H$($,O.id,O)}async fetch(){if(this.lookupToken)return G(await this.client.storage.meetingLookup({path:{token:this.lookupToken}}));let $=G(await this.client.storage.meetingList()).meetings.find((O)=>O.id===this.id);if(!$)throw new E(`Meeting ${this.id} is unavailable`);return this.lookupToken=$.shareToken,$}title=this.field("title");scheduledStart=this.field("scheduledStart");scheduledEnd=this.field("scheduledEnd");channel=this.mappedField("channelId",($)=>$?b.byId(this.client,$):void 0);call=this.mappedField("callId",($)=>$?Q$.byId(this.client,$):void 0);async update($){await this.mutate((O)=>O.storage.meetingUpdate({path:{meeting_id:this.id},body:$}))}async cancel(){await this.mutate(($)=>$.storage.meetingCancel({path:{meeting_id:this.id}}))}async invitePermissions(){return G(await this.client.storage.meetingInvitePermissions({path:{token:(await this.detail.get()).shareToken}}))}async invite($){G(await this.client.storage.meetingInvite({path:{token:(await this.detail.get()).shareToken},body:{email:$}}))}async inviteUsers($){G(await this.client.storage.meetingInviteUsers({path:{token:(await this.detail.get()).shareToken},body:{userIds:$.map((O)=>O.id)}}))}async webUrl(){return`${this.client.webAppUrl}/app/meet/join/${encodeURIComponent((await this.detail.get()).shareToken)}`}}class u$ extends M{callId;constructor($,O,j,x){super($,j,x);this.callId=O}get path(){return{parent_type:"call",parent_id:this.callId,id:this.id}}async fetch(){return G(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new u$($,O,j)}static from($,O,j){return new u$($,O,j.id,j)}content=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");call(){return Q$.byId(this.client,this.callId)}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){let O=G(await this.client.storage.entityMessageCreate({path:{parent_type:"call",parent_id:this.callId},body:{...O$($),thread_id:this.callId}}));return u$.from(this.client,this.callId,O)}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}class Q$ extends z${messageThreadById($){return L$.byId(this.client,{type:"call",entity:this},$)}timelinePage($){return w$(this.client,{type:"call",entity:this},(O)=>u$.from(this.client,this.id,O),$)}access=new o(this.client,"call",this);async meeting(){return H$.from(this.client,G(await this.client.storage.meetingShare({path:{call_id:this.id}})))}async editTranscript($){await this.mutate((O)=>O.storage.editCallTranscript({path:{call_id:this.id},body:{assignments:$}}))}async toggleTeamShare(){return this.mutate(($)=>$.storage.toggleShareWithTeam({path:{call_id:this.id}}))}entityType="call";async fetch(){return G(await this.client.storage.getCallRecord({path:{call_id:this.id}}))}static byId($,O){return new Q$($,O)}message($){return u$.byId(this.client,this.id,$)}name=this.field("customName");channel=this.mappedField("channelId",($)=>$?b.byId(this.client,$):void 0);channelName=this.field("channelName");creator=this.mappedField("createdBy",($)=>P.byId(this.client,$));isActive=this.field("isActive");status=this.field("status");roomName=this.field("roomName");startedAt=this.field("startedAt");endedAt=this.field("endedAt");durationMs=this.field("durationMs");summary=this.field("summary");transcript=this.field("transcript");participants=this.field("participants");guests=this.field("guests");teamShareAccessLevel=this.field("teamShareAccessLevel");shareWithTeam=this.field("shareWithTeam");recordingUrl=this.field("recordingUrl");recordingPreviewUrl=this.field("recordingPreviewUrl");recordingStartedAt=this.field("recordingStartedAt");async rename($){await this.mutate((O)=>O.storage.editCallRecord({path:{call_id:this.id},body:{customName:$??""}}))}async setTeamShare($){await this.mutate((O)=>O.storage.editCallRecord({path:{call_id:this.id},body:{sharePermission:{teamShareAccessLevel:$?"view":null}}}))}async delete(){await this.mutate(($)=>$.storage.deleteCallRecord({path:{call_id:this.id}}))}static search=x$({filters:{call_filters:{}},type:"call",make:($,O)=>new Q$($,O.call_id)})}class lx{client;constructor($){this.client=$}byId($){return Q$.byId(this.client,$)}search($,O){return Q$.search(this.client,$,O)}}class rx{client;constructor($){this.client=$}async list(){let{labels:$}=G(await this.client.storage.listChannelLabels());return $}async create($,O=[]){return G(await this.client.storage.createChannelLabel({body:{name:$,channelIds:O.map((j)=>j.id)}}))}async createSmartTag($,O){return G(await this.client.storage.createChannelLabel({body:{name:$,rule:O}}))}async previewSmartTag($){return G(await this.client.storage.previewSmartTag({body:$}))}async updateSmartTag($,O,j){return G(await this.client.storage.renameChannelLabel({path:{label_id:$.id},body:{name:O,rule:j}}))}async rename($,O){return G(await this.client.storage.renameChannelLabel({path:{label_id:$.id},body:{name:O}}))}async delete($){G(await this.client.storage.deleteChannelLabel({path:{label_id:$.id}}))}async setLabel($,O){G(await this.client.storage.setChannelLabel({path:{channel_id:$.id},body:{labelId:O?.id??null}}))}}class px{client;async activity(){return G(await this.client.storage.getActivity()).map(($)=>new QO(this.client,b.byId(this.client,$.channel_id),$))}labels;constructor($){this.client=$;this.labels=new rx($)}byId($){return b.byId(this.client,$)}async dm($){return b.dm(this.client,$)}async private($){return b.private(this.client,$)}async create($){return b.create(this.client,$)}async list(){let{items:$}=G(await this.client.storage.getChannels());return $.map((O)=>b.byId(this.client,O.id.toString()))}async*search($,O){if(!O?.searchOn||O.searchOn==="name"){let{items:j}=G(await this.client.storage.getChannels()),x=$.toLowerCase();for(let S of j)if(S.name?.toLowerCase().includes(x))yield b.byId(this.client,S.id.toString())}else yield*b.search(this.client,$,O)}}class aO{client;chat;id;message;constructor($,O,j,x){this.client=$;this.chat=O;this.id=j;this.message=x}static byId($,O,j,x){return new aO($,O,j,x)}async stop(){G(await this.client.cognition.stopChatStream({body:{chat_id:this.chat.id,stream_id:this.id}}))}toJSON(){return{id:this.id,chatId:this.chat.id,messageId:this.message.id}}}class iO extends M{chat;constructor($,O,j){super($,j);this.chat=O}static byId($,O,j){return new iO($,O,j)}async fetch(){let $=G(await this.client.cognition.getChat({path:{chat_id:this.chat.id}})).chat.messages.find((O)=>O.id===this.id);if(!$)throw new E(`Chat message ${this.id} is not yet available`);return $}content=this.field("content");role=this.field("role");async refresh(){this.detail.clear(),await this.detail.get()}toJSON(){return{...super.toJSON(),chatId:this.chat.id}}}class K$ extends X${async send($){let{attachments:O,additionalInstructions:j,...x}=$,S=await this.mutate((Z)=>Z.cognition.sendChatMessage({body:{...x,chat_id:this.id,additional_instructions:j,attachments:O?.map((X)=>({entity_id:X.entity.id,entity_type:X.type}))}})),K=K$.byId(this.client,S.chat_id);return aO.byId(this.client,K,S.stream_id,iO.byId(this.client,K,S.message_id))}access=new o(this.client,"chat",this);entityType="chat";propertyEntityType="CHAT";async fetch(){let{chat:$}=G(await this.client.cognition.getChat({path:{chat_id:this.id}}));return $}static byId($,O){return new K$($,O)}static async create($,O){let{id:j}=G(await $.cognition.createChat({body:{name:O?.name??null,projectId:O?.project?.id??null}}));return new K$($,j)}name=this.field("name");model=this.field("model");project=this.mappedField("projectId",($)=>$?n.byId(this.client,$):void 0);createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");messages=this.field("messages");async rename($){await this.mutate((O)=>O.cognition.patchChat({path:{chat_id:this.id},body:{name:$}}))}async delete($){await this.mutate((O)=>$?.permanent?O.cognition.permanentlyDeleteChat({path:{chat_id:this.id}}):O.cognition.deleteChat({path:{chat_id:this.id}}))}async copy(){let{id:$}=await this.mutate((O)=>O.cognition.copyChat({path:{chat_id:this.id}}));return new K$(this.client,$)}async restore(){await this.mutate(($)=>$.cognition.revertDeleteChat({path:{chat_id:this.id}}))}async history(){let{conversation:$}=G(await this.client.cognition.getChatHistoryHandler({path:{chat_id:this.id}}));return $}webUrl(){return`${this.client.webAppUrl}/app/chat/${this.id}`}static search=x$({filters:{chat_filters:{}},type:"chat",make:($,O)=>new K$($,O.chat_id)});toMention(){return{tag:i$("m-document-mention",{documentId:this.id,documentName:this.detail.peek()?.name??"",blockName:"chat",blockParams:{}}),mention:{entity_type:"chat",entity_id:this.id}}}}class ax{client;constructor($){this.client=$}byId($){return K$.byId(this.client,$)}create($){return K$.create(this.client,$)}search($,O){return K$.search(this.client,$,O)}}var l6=8;class M$ extends M{parent;constructor($,O,j,x){super($,j,x);this.parent=O}get path(){return{parent_type:this.parent.type,parent_id:this.parent.id,id:this.id}}async fetch(){return G(await this.client.storage.entityMessageGetMessage({path:this.path}))}static byId($,O,j){return new M$($,O,j)}static from($,O,j){return new M$($,O,j.id,j)}text=this.field("content");createdAt=this.field("created_at");updatedAt=this.field("updated_at");deletedAt=this.field("deleted_at");async threadId(){return(await this.detail.get()).thread_id??this.id}async author(){return P.byId(this.client,(await this.detail.get()).sender_id)}async reply($){return nO(this.client,this.parent,$,{threadId:await this.threadId()})}async edit($){let{content:O,mentions:j}=O$($);return await this.mutate((x)=>x.storage.entityMessageEdit({path:this.path,body:{content:O,mentions:j}})),this}async delete(){await this.mutate(($)=>$.storage.entityMessageDeleteMessage({path:this.path}))}}async function Nj($,O){let j={parent_type:O.type,parent_id:O.id},x=u(async(K)=>{let Z=G(await $.storage.messageTimeline({path:j,query:{selection:JSON.stringify({limit:100,cursor:K})}}));return{items:Z.items,nextCursor:Z.next_cursor}}),S=[];for await(let K of x)S.push(K);return cO(S,l6,async(K)=>{let{state:Z,root:X,replies:Y}=G(await $.storage.entityMessageGetThread({path:{...j,id:K.id}}));return{thread:Z,comments:[X,...Y].map((L)=>M$.from($,O,L))}})}async function nO($,O,j,x){let S=G(await $.storage.entityMessageCreate({path:{parent_type:O.type,parent_id:O.id},body:{...O$(j),thread_id:x?.threadId??null}}));return M$.from($,O,S)}class f$ extends z${messageThreadById($){return L$.byId(this.client,{type:"crm_contact",entity:this},$)}timelinePage($){return w$(this.client,{type:"crm_contact",entity:this},(O)=>M$.from(this.client,{type:"crm_contact",id:this.id},O),$)}entityType="crm_contact";async fetch(){return G(await this.client.storage.getContact({path:{contact_id:this.id}}))}static byId($,O){return new f$($,O)}static from($,O){return new f$($,O.id,O)}name=this.field("name");email=this.field("email");company=this.mappedField("companyId",($)=>b$.byId(this.client,$));hidden=this.field("hidden");createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");firstInteraction=this.field("firstInteraction");lastInteraction=this.field("lastInteraction");async hide(){await this.setHidden(!0)}async unhide(){await this.setHidden(!1)}async setHidden($){await this.mutate((O)=>O.storage.setContactHidden({path:{contact_id:this.id},body:{hidden:$}}))}async rename($){await this.mutate((O)=>O.storage.setCrmContactName({path:{contact_id:this.id},body:{name:$}}))}get commentParent(){return{type:"crm_contact",id:this.id}}async comments(){return Nj(this.client,this.commentParent)}async comment($,O){return nO(this.client,this.commentParent,$,O)}commentById($){return M$.byId(this.client,this.commentParent,$)}}class b$ extends X${messageThreadById($){return L$.byId(this.client,{type:"crm_company",entity:this},$)}timelinePage($){return w$(this.client,{type:"crm_company",entity:this},(O)=>M$.from(this.client,{type:"crm_company",id:this.id},O),$)}entityType="crm_company";propertyEntityType="COMPANY";async fetch(){return G(await this.client.storage.getCompany({path:{company_id:this.id}}))}static byId($,O){return new b$($,O)}static from($,O){return new b$($,O.id,O)}name=this.field("name");description=this.field("description");hidden=this.field("hidden");emailSync=this.field("emailSync");team=this.mappedField("teamId",($)=>S$.byId(this.client,$));createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");async domain(){let{domains:$}=await this.detail.get();return $[0]?.domain}async domains(){let{domains:$}=await this.detail.get();return $.map((O)=>O.domain)}async contacts(){return G(await this.client.storage.listCompanyContacts({path:{company_id:this.id}})).map((O)=>f$.from(this.client,O))}static search=x$({filters:{crm_company_filters:{}},type:"company",includeCrm:!0,make:($,O)=>new b$($,O.id)});async hide(){await this.setHidden(!0)}async unhide(){await this.setHidden(!1)}async setHidden($){await this.mutate((O)=>O.storage.setCompanyHidden({path:{company_id:this.id},body:{hidden:$}}))}async setEmailSync($){await this.mutate((O)=>O.storage.setEmailSync({path:{company_id:this.id},body:{email_sync:$}}))}async rename($){await this.mutate((O)=>O.storage.setCrmCompanyName({path:{company_id:this.id},body:{name:$}}))}async createContact($){let O=await this.mutate((j)=>j.storage.createCrmContact({path:{company_id:this.id},body:$}));return f$.from(this.client,O)}get commentParent(){return{type:"crm_company",id:this.id}}async comments(){return Nj(this.client,this.commentParent)}async comment($,O){return nO(this.client,this.commentParent,$,O)}commentById($){return M$.byId(this.client,this.commentParent,$)}}class t$ extends M{tableDetail=new W$(async()=>G(await this.client.storage.getCrmPipelineTable({path:{id:this.id}})));static byId($,O){return new t$($,O)}static from($,O){return new t$($,O.id,O)}async fetch(){return G(await this.client.storage.getCrmPipeline({path:{id:this.id}}))}name=this.field("name");recordType=this.field("recordType");accessLevel=this.field("grant");sharing=this.field("sharing");owner=this.mappedField("userId",($)=>P.byId(this.client,$));team=this.mappedField("teamId",($)=>S$.byId(this.client,$));async rename($){await this.mutate((O)=>O.storage.renameCrmPipeline({path:{id:this.id},body:{name:$}}))}async setSharing($){if($===void 0)throw Error("Sharing is required");await this.mutate((O)=>O.storage.shareCrmPipeline({path:{id:this.id},body:{sharing:$}}))}async setTrashed($){await this.mutate((O)=>O.storage.trashCrmPipeline({path:{id:this.id},body:{trashed:$}}))}async sharePermissions(){return G(await this.client.storage.getCrmPipelinePermissions({path:{id:this.id}}))}async updateSharePermissions($){return this.mutate((O)=>O.storage.updateCrmPipelinePermissions({path:{id:this.id},body:n$($)}))}async table(){return Uj.from(this.client,this,await this.tableRecord())}tableRecord(){return this.tableDetail.get()}rows(){return u(async($)=>{let O=G(await this.client.storage.getCrmPipelineRows({path:{id:this.id},query:{after:$}}));return{items:O.rows.map((j)=>VO.from(this.client,this,j)),nextCursor:O.next}})}queryRows($={}){if($.rows?.some((O)=>O.pipeline.id!==this.id))throw Error("Rows belong to another pipeline");return u(async(O)=>{let j=G(await this.client.storage.queryCrmPipelineRows({path:{id:this.id},body:{after:O,query:$.query,rowIds:$.rows?.map((x)=>x.id)}}));return{items:j.rows.map((x)=>VO.from(this.client,this,x)),nextCursor:j.next}})}async applyOps($,O){if(O?.baseVersions?.some((S)=>S.table.pipeline.id!==this.id))throw Error("Table belongs to another pipeline");let j={ops:$,baseVersions:O?.baseVersions?Object.fromEntries(O.baseVersions.map((S)=>[S.table.id,S.version])):void 0},x=await this.mutate((S)=>S.storage.applyCrmPipelineOps({path:{id:this.id},body:j}));return this.tableDetail.clear(),x}}class Uj extends M{pipeline;toJSON(){return{...super.toJSON(),pipelineId:this.pipeline.id}}constructor($,O,j){super($,j.table.id,j);this.pipeline=O}static from($,O,j){return new Uj($,O,j)}fetch(){return this.pipeline.tableRecord()}async columns(){return(await this.pipeline.tableRecord()).columns.map(($)=>zj.from(this.client,this,$))}async version(){return(await this.pipeline.tableRecord()).table.version}rowById($){return VO.byId(this.client,this.pipeline,$)}rows(){return this.pipeline.rows()}}class VO extends M{pipeline;toJSON(){return{...super.toJSON(),pipelineId:this.pipeline.id}}constructor($,O,j,x){super($,j,x);this.pipeline=O}static byId($,O,j){return new VO($,O,j)}static from($,O,j){return new VO($,O,j.rowId,j)}async fetch(){for await(let $ of this.pipeline.queryRows({rows:[this]}))if($.id===this.id)return $.detail.get();throw new E(`Pipeline row ${this.id} is unavailable`)}cells=this.field("cells");async refresh(){this.detail.clear(),await this.detail.get()}}class zj extends M{table;toJSON(){return{...super.toJSON(),pipelineId:this.table.pipeline.id,tableId:this.table.id}}constructor($,O,j){super($,j.column.id,j);this.table=O}static from($,O,j){return new zj($,O,j)}async fetch(){let $=(await this.table.pipeline.tableRecord()).columns.find((O)=>O.column.id===this.id);if(!$)throw new E(`Pipeline column ${this.id} is unavailable`);return $}async writable(){return(await this.fetch()).writable}async name(){return(await this.fetch()).column.display_name??(await this.fetch()).definition.definition.display_name}}class ix{client;constructor($){this.client=$}byId($){return t$.byId(this.client,$)}async list(){return G(await this.client.storage.listCrmPipelines()).map(($)=>t$.from(this.client,$))}async create($){return t$.from(this.client,G(await this.client.storage.createCrmPipeline({body:$})))}}class nx{client;pipelines;constructor($){this.client=$;this.pipelines=new ix($)}companyById($){return b$.byId(this.client,$)}contactById($){return f$.byId(this.client,$)}async contactByEmail($){let{contact:O}=G(await this.client.storage.getContactByEmail({query:{email:$}}));return O?f$.from(this.client,O):void 0}async searchContacts($,O={}){let{contacts:j}=G(await this.client.storage.searchContacts({query:{query:$,limit:O.limit}}));return j.map((x)=>f$.from(this.client,x))}async createCompany($){return b$.from(this.client,G(await this.client.storage.createCrmCompany({body:$})))}async settings(){return G(await this.client.storage.getCrmTeamSettings())}async updateSettings($){return G(await this.client.storage.putCrmTeamSettings({body:$}))}async setStages($){return G(await this.client.storage.putCrmTeamStages({body:$}))}async resetStages(){G(await this.client.storage.resetCrmTeamStages())}searchCompanies($){return b$.search(this.client,$)}}var G$=Symbol.for("@ts-pattern/matcher"),v1=Symbol.for("@ts-pattern/isVariadic");var sx=($)=>Boolean($&&typeof $=="object"),Ij=($)=>$&&!!$[G$],s=($,O,j)=>{if(Ij($)){let x=$[G$](),{matched:S,selections:K}=x.match(O);return S&&K&&Object.keys(K).forEach((Z)=>j(Z,K[Z])),S}if(sx($)){if(!sx(O))return!1;if(Array.isArray($)){if(!Array.isArray(O))return!1;let x=[],S=[],K=[];for(let Z of $.keys()){let X=$[Z];Ij(X)&&X[v1]?K.push(X):K.length?S.push(X):x.push(X)}if(K.length){if(K.length>1)throw Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(O.lengths(L,Z[Q],j))&&S.every((L,Q)=>s(L,X[Q],j))&&(K.length===0||s(K[0],Y,j))}return $.length===O.length&&$.every((Z,X)=>s(Z,O[X],j))}return Reflect.ownKeys($).every((x)=>{let S=$[x];return((x in O)||Ij(K=S)&&K[G$]().matcherType==="optional")&&s(S,O[x],j);var K})}return Object.is(O,$)},Y$=($)=>{var O,j,x;return sx($)?Ij($)?(O=(j=(x=$[G$]()).getSelectionKeys)==null?void 0:j.call(x))!=null?O:[]:Array.isArray($)?sO($,Y$):sO(Object.values($),Y$):[]},sO=($,O)=>$.reduce((j,x)=>j.concat(O(x)),[]);function r6(...$){if($.length===1){let[O]=$;return(j)=>s(O,j,()=>{})}if($.length===2){let[O,j]=$;return s(O,j,()=>{})}throw Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${$.length}.`)}function t($){return Object.assign($,{optional:()=>ox($),and:(O)=>d($,O),or:(O)=>h1($,O),select:(O)=>O===void 0?tO($):tO(O,$)})}function tx($){return Object.assign(((O)=>Object.assign(O,{[Symbol.iterator](){let j=0,x=[{value:Object.assign(O,{[v1]:!0}),done:!1},{done:!0,value:void 0}];return{next:()=>{var S;return(S=x[j++])!=null?S:x.at(-1)}}}}))($),{optional:()=>tx(ox($)),select:(O)=>tx(O===void 0?tO($):tO(O,$))})}function ox($){return t({[G$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return O===void 0?(Y$($).forEach((S)=>x(S,void 0)),{matched:!0,selections:j}):{matched:s($,O,x),selections:j}},getSelectionKeys:()=>Y$($),matcherType:"optional"})})}var p6=($,O)=>{for(let j of $)if(!O(j))return!1;return!0},a6=($,O)=>{for(let[j,x]of $.entries())if(!O(x,j))return!1;return!0},i6=($,O)=>{let j=Reflect.ownKeys($);for(let x of j)if(!O(x,$[x]))return!1;return!0};function d(...$){return t({[G$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return{matched:$.every((S)=>s(S,O,x)),selections:j}},getSelectionKeys:()=>sO($,Y$),matcherType:"and"})})}function h1(...$){return t({[G$]:()=>({match:(O)=>{let j={},x=(S,K)=>{j[S]=K};return sO($,Y$).forEach((S)=>x(S,void 0)),{matched:$.some((S)=>s(S,O,x)),selections:j}},getSelectionKeys:()=>sO($,Y$),matcherType:"or"})})}function m($){return{[G$]:()=>({match:(O)=>({matched:Boolean($(O))})})}}function tO(...$){let O=typeof $[0]=="string"?$[0]:void 0,j=$.length===2?$[1]:typeof $[0]=="string"?void 0:$[0];return t({[G$]:()=>({match:(x)=>{let S={[O!=null?O:"@ts-pattern/anonymous-select-key"]:x};return{matched:j===void 0||s(j,x,(K,Z)=>{S[K]=Z}),selections:S}},getSelectionKeys:()=>[O!=null?O:"@ts-pattern/anonymous-select-key"].concat(j===void 0?[]:Y$(j))})})}function m1($){return!0}function k$($){return typeof $=="number"}function e$($){return typeof $=="string"}function o$($){return typeof $=="bigint"}var c1=t(m(m1)),n6=t(m(m1)),s6=c1,$O=($)=>Object.assign(t($),{startsWith:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.startsWith(j)))));var j},endsWith:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.endsWith(j)))));var j},minLength:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length>=j))(O))),length:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length===j))(O))),maxLength:(O)=>$O(d($,((j)=>m((x)=>e$(x)&&x.length<=j))(O))),includes:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&x.includes(j)))));var j},regex:(O)=>{return $O(d($,(j=O,m((x)=>e$(x)&&Boolean(x.match(j))))));var j}}),y1=$O(m(e$)),g$=($)=>Object.assign(t($),{between:(O,j)=>g$(d($,((x,S)=>m((K)=>k$(K)&&x<=K&&S>=K))(O,j))),lt:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&xg$(d($,((j)=>m((x)=>k$(x)&&x>j))(O))),lte:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&x<=j))(O))),gte:(O)=>g$(d($,((j)=>m((x)=>k$(x)&&x>=j))(O))),int:()=>g$(d($,m((O)=>k$(O)&&Number.isInteger(O)))),finite:()=>g$(d($,m((O)=>k$(O)&&Number.isFinite(O)))),positive:()=>g$(d($,m((O)=>k$(O)&&O>0))),negative:()=>g$(d($,m((O)=>k$(O)&&O<0)))}),t6=g$(m(k$)),OO=($)=>Object.assign(t($),{between:(O,j)=>OO(d($,((x,S)=>m((K)=>o$(K)&&x<=K&&S>=K))(O,j))),lt:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&xOO(d($,((j)=>m((x)=>o$(x)&&x>j))(O))),lte:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&x<=j))(O))),gte:(O)=>OO(d($,((j)=>m((x)=>o$(x)&&x>=j))(O))),positive:()=>OO(d($,m((O)=>o$(O)&&O>0))),negative:()=>OO(d($,m((O)=>o$(O)&&O<0)))}),e6=OO(m(o$)),o6=t(m(function($){return typeof $=="boolean"})),$7=t(m(function($){return typeof $=="symbol"})),O7=t(m(function($){return $==null})),j7=t(m(function($){return $!=null})),Z$={__proto__:null,matcher:G$,optional:ox,array:function(...$){return tx({[G$]:()=>({match:(O)=>{if(!Array.isArray(O))return{matched:!1};if($.length===0)return{matched:!0};let j=$[0],x={};if(O.length===0)return Y$(j).forEach((K)=>{x[K]=[]}),{matched:!0,selections:x};let S=(K,Z)=>{x[K]=(x[K]||[]).concat([Z])};return{matched:O.every((K)=>s(j,K,S)),selections:x}},getSelectionKeys:()=>$.length===0?[]:Y$($[0])})})},set:function(...$){return t({[G$]:()=>({match:(O)=>{if(!(O instanceof Set))return{matched:!1};let j={};if(O.size===0)return{matched:!0,selections:j};if($.length===0)return{matched:!0};let x=(K,Z)=>{j[K]=(j[K]||[]).concat([Z])},S=$[0];return{matched:p6(O,(K)=>s(S,K,x)),selections:j}},getSelectionKeys:()=>$.length===0?[]:Y$($[0])})})},map:function(...$){return t({[G$]:()=>({match:(O)=>{if(!(O instanceof Map))return{matched:!1};let j={};if(O.size===0)return{matched:!0,selections:j};let x=(X,Y)=>{j[X]=(j[X]||[]).concat([Y])};if($.length===0)return{matched:!0};var S;if($.length===1)throw Error(`\`P.map\` wasn't given enough arguments. Expected (key, value), received ${(S=$[0])==null?void 0:S.toString()}`);let[K,Z]=$;return{matched:a6(O,(X,Y)=>{let L=s(K,Y,x),Q=s(Z,X,x);return L&&Q}),selections:j}},getSelectionKeys:()=>$.length===0?[]:[...Y$($[0]),...Y$($[1])]})})},record:function(...$){return t({[G$]:()=>({match:(O)=>{if(O===null||typeof O!="object"||Array.isArray(O))return{matched:!1};var j;if($.length===0)throw Error(`\`P.record\` wasn't given enough arguments. Expected (value) or (key, value), received ${(j=$[0])==null?void 0:j.toString()}`);let x={},S=(X,Y)=>{x[X]=(x[X]||[]).concat([Y])},[K,Z]=$.length===1?[y1,$[0]]:$;return{matched:i6(O,(X,Y)=>{let L=typeof X!="string"||Number.isNaN(Number(X))?null:Number(X),Q=L!==null&&s(K,L,S),J=s(K,X,S),I=s(Z,Y,S);return(J||Q)&&I}),selections:x}},getSelectionKeys:()=>$.length===0?[]:[...Y$($[0]),...Y$($[1])]})})},intersection:d,union:h1,not:function($){return t({[G$]:()=>({match:(O)=>({matched:!s($,O,()=>{})}),getSelectionKeys:()=>[],matcherType:"not"})})},when:m,select:tO,any:c1,unknown:n6,_:s6,string:y1,number:t6,bigint:e6,boolean:o6,symbol:$7,nullish:O7,nonNullable:j7,instanceOf:function($){return t(m(function(O){return(j)=>j instanceof O}($)))},shape:function($){return t(m(r6($)))}};class u1 extends Error{constructor($){let O;try{O=JSON.stringify($)}catch(j){O=$}super(`Pattern matching error: no pattern matches value ${O}`),this.input=void 0,this.input=$}}var ex={matched:!1,value:void 0};function c($){return new Tj($,ex)}class Tj{constructor($,O){this.input=void 0,this.state=void 0,this.input=$,this.state=O}with(...$){if(this.state.matched)return this;let O=$[$.length-1],j=[$[0]],x;$.length===3&&typeof $[1]=="function"?x=$[1]:$.length>2&&j.push(...$.slice(1,$.length-1));let S=!1,K={},Z=(Y,L)=>{S=!0,K[Y]=L},X=!j.some((Y)=>s(Y,this.input,Z))||x&&!Boolean(x(this.input))?ex:{matched:!0,value:O(S?"@ts-pattern/anonymous-select-key"in K?K["@ts-pattern/anonymous-select-key"]:K:this.input,this.input)};return new Tj(this.input,X)}when($,O){if(this.state.matched)return this;let j=Boolean($(this.input));return new Tj(this.input,j?{matched:!0,value:O(this.input,this.input)}:ex)}otherwise($){return this.state.matched?this.state.value:$(this.input)}exhaustive($=x7){return this.state.matched?this.state.value:$(this.input)}run(){return this.exhaustive()}returnType(){return this}narrow(){return this}}function x7($){throw new u1($)}var $0,S7=new Uint8Array(16);function Hj(){if(!$0){if(typeof crypto>"u"||!crypto.getRandomValues)throw Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");$0=crypto.getRandomValues.bind(crypto)}return $0(S7)}var j$=[];for(let $=0;$<256;++$)j$.push(($+256).toString(16).slice(1));function d1($,O=0){return(j$[$[O+0]]+j$[$[O+1]]+j$[$[O+2]]+j$[$[O+3]]+"-"+j$[$[O+4]]+j$[$[O+5]]+"-"+j$[$[O+6]]+j$[$[O+7]]+"-"+j$[$[O+8]]+j$[$[O+9]]+"-"+j$[$[O+10]]+j$[$[O+11]]+j$[$[O+12]]+j$[$[O+13]]+j$[$[O+14]]+j$[$[O+15]]).toLowerCase()}var O0={};function Z7($,O,j){let x;if($)x=l1($.random??$.rng?.()??Hj(),$.msecs,$.seq,O,j);else{let S=Date.now(),K=Hj();X7(O0,S,K),x=l1(K,O0.msecs,O0.seq,O,j)}return O??d1(x)}function X7($,O,j){if($.msecs??=-1/0,$.seq??=0,O>$.msecs)$.seq=j[6]<<23|j[7]<<16|j[8]<<8|j[9],$.msecs=O;else if($.seq=$.seq+1|0,$.seq===0)$.msecs++;return $}function l1($,O,j,x,S=0){if($.length<16)throw Error("Random bytes length must be >= 16");if(!x)x=new Uint8Array(16),S=0;else if(S<0||S+16>x.length)throw RangeError(`UUID byte range ${S}:${S+15} is out of buffer bounds`);return O??=Date.now(),j??=$[6]*127<<24|$[7]<<16|$[8]<<8|$[9],x[S++]=O/1099511627776&255,x[S++]=O/4294967296&255,x[S++]=O/16777216&255,x[S++]=O/65536&255,x[S++]=O/256&255,x[S++]=O&255,x[S++]=112|j>>>28&15,x[S++]=j>>>20&255,x[S++]=128|j>>>14&63,x[S++]=j>>>6&255,x[S++]=j<<2&255|$[10]&3,x[S++]=$[11],x[S++]=$[12],x[S++]=$[13],x[S++]=$[14],x[S++]=$[15],x}var d$=Z7;class A${table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new A$($,O)}async detail(){let{columns:$}=await this.table.detail(),O=$.find((j)=>j.column.id===this.id);if(!O)throw new E(`column ${this.id} is not on table ${this.table.id}`);return O}async name(){let $=await this.detail();return $.column.display_name??$.definition.definition.display_name}async rename($){return await this.table.database.renameColumn(this,$),this}async inferType($){return await this.table.database.inferColumnType(this,$),this}changeType($){return this.table.database.changeColumnType(this,$)}convertIntoNewColumn($){return this.table.database.convertColumnIntoNewColumn(this,$)}casts(){return this.table.database.columnCasts(this)}async delete(){await this.table.database.deleteColumn(this)}async dataType(){return(await this.detail()).definition.definition.data_type}async isMultiSelect(){return(await this.detail()).definition.definition.is_multi_select}async position(){return(await this.detail()).column.position}async definition(){return(await this.detail()).definition}async config(){return(await this.detail()).column.config??void 0}async addOptions($){return await this.table.database.addColumnOptions(this,$),this}toJSON(){return{id:this.id,tableId:this.table.id}}}class F${table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new F$($,O)}history(){return this.table.database.rowHistory(this)}toJSON(){return{id:this.id,tableId:this.table.id}}}class Rj{table;id;constructor($,O){this.table=$;this.id=O}static byId($,O){return new Rj($,O)}async detail(){let{views:$}=await this.table.detail(),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`view ${this.id} is not on table ${this.table.id}`);return O}async name(){return(await this.detail()).name}async position(){return(await this.detail()).position}async layout(){return(await this.detail()).layout}async query(){return(await this.detail()).query}positions(){return this.table.database.viewPositions(this)}toJSON(){return{id:this.id,tableId:this.table.id}}}class J${database;id;constructor($,O){this.database=$;this.id=O}static byId($,O){return new J$($,O)}async detail(){let{tables:$}=await this.database.schema(),O=$.find((j)=>j.table.id===this.id);if(!O)throw new E(`table ${this.id} is not in database ${this.database.id}`);return O}async name(){return(await this.detail()).table.name}async rename($){return await this.database.renameTable(this,$),this}async version(){return(await this.detail()).table.version}async position(){return(await this.detail()).table.position}async columns(){let{columns:$}=await this.detail();return $.map((O)=>A$.byId(this,O.column.id))}addColumn($){return this.database.addColumn(this,$)}async reorderColumns($){return await this.database.reorderColumns(this,$),this}row($){return F$.byId(this,$)}async views(){let{views:$}=await this.detail();return $.map((O)=>Rj.byId(this,O.id))}createWebhook(){return this.database.createWebhook(this)}async delete(){await this.database.deleteTable(this)}toJSON(){return{id:this.id,databaseId:this.database.id}}}async function Dj($,O,j,x={}){let S=G(await $.storage.queryDatabases({body:{sql:j,databaseId:x.database?.id,baseVersions:Object.fromEntries((x.baseVersions??[]).map(({table:Q,version:J})=>[Q.id,J]))}})),K=new Map;for(let Q of[x.database,...(x.baseVersions??[]).map(({table:J})=>J.database)]){if(!Q)continue;let J=K.get(Q.id);if(J)J.add(Q);else K.set(Q.id,new Set([Q]))}let Z=(Q)=>{let J=K.get(Q)?.values().next().value;if(J)return J;let I=O($,Q);return K.set(Q,new Set([I])),I},X=(Q)=>{let J=S.tableDatabases[Q];if(!J)throw Error(`SQL response is missing the owner of table ${Q}`);return J$.byId(Z(J),Q)},Y=new Set(Object.keys(S.newVersions).map((Q)=>X(Q).database.id));if(S.statement.kind==="schema")Y.add(S.statement.databaseId);for(let Q of Y)for(let J of K.get(Q)??[])J.invalidateSchema();let L=c(S.statement).with({kind:"select"},(Q)=>Q).with({kind:"schema"},({databaseId:Q,summary:J})=>({kind:"schema",database:Z(Q),summary:J})).with({kind:"insert"},{kind:"update"},{kind:"delete"},({kind:Q,tableId:J,tableName:I})=>({kind:Q,table:X(J),tableName:I})).with({kind:"alterColumnType"},({tableId:Q,tableName:J,columnId:I,columnName:z,to:W})=>{let V=X(Q);return{kind:"alterColumnType",table:V,tableName:J,column:A$.byId(V,I),columnName:z,to:W}}).exhaustive();return{result:S.result?K7(S.result,X,S.tableDatabases):void 0,changesApplied:S.changesApplied,insertedRows:L.kind==="insert"?S.insertedRowIds.map((Q)=>F$.byId(L.table,Q)):[],newVersions:Object.entries(S.newVersions).map(([Q,J])=>({table:X(Q),version:J})),readVersions:Object.entries(S.readVersions).map(([Q,J])=>({table:X(Q),version:J})),truncatedTables:S.truncatedTables,statement:L}}function K7($,O,j){let x=$.sourceTable&&j[$.sourceTable]?O($.sourceTable):void 0;return{columns:$.columns.map(({relatedTable:S,...K})=>({...K,relatedTable:S&&j[S]?O(S):void 0})),rows:$.rows,sourceTable:x,rowHandles:x?$.rowIds.map((S)=>F$.byId(x,S)):[]}}class _j{table;id;createdBy;record;constructor($,O,j,x){this.table=$;this.id=O;this.createdBy=j;this.record=x}static fromRecord($,O,j){return new _j($,j.id,O,j)}get tokenPrefix(){return this.record.tokenPrefix}get createdAt(){return this.record.createdAt}delete(){return this.table.database.deleteWebhook(this)}toJSON(){return{id:this.id,tableId:this.table.id,tokenPrefix:this.tokenPrefix}}}class S0 extends GO{op;row;column;taken;constructor($,O){super($,O);this.name="MacroOpRefusedError",this.message=O.message,this.op=O.op,this.row=O.row,this.column=O.column,this.taken=O.taken}}function Cj($){return c($).with({type:"relation"},({table:O})=>({type:"relation",database:O.database.id,table:O.id})).with({type:Z$.not("relation")},(O)=>O).exhaustive()}var Y7={USER:"People",DOCUMENT:"Documents",TASK:"Tasks",COMPANY:"Companies",CONTACT:"Contacts",CALL_RECORD:"Calls",CHANNEL:"Channels",CHAT:"Chats",PROJECT:"Projects",THREAD:"Emails",CALENDAR_EVENT:"Events",INITIATIVE:"Initiatives"};function G7($){return c($).with({type:"text"},()=>"Text").with({type:"number"},()=>"Number").with({type:"boolean"},()=>"Checkbox").with({type:"date"},()=>"Date").with({type:"link"},()=>"URL").with({type:"select",multi:!0},()=>"Multi-select").with({type:"select",multi:!1},()=>"Select").with({type:"select_number",multi:!0},()=>"Multi-number select").with({type:"select_number",multi:!1},()=>"Number select").with({type:"tag"},()=>"Tag").with({type:"entity"},({target:O})=>Y7[O]).with({type:"relation"},()=>"Relation").exhaustive(()=>"Column")}function j0($){return $.map((O)=>({id:d$(),label:O}))}function r1($,O,j){return $?.kind===O&&"change"in $&&$.change.kind===j}function x0($){return c($).with({kind:"reorder_tables"},({kind:O})=>O).with({kind:Z$.union("table","column","rows","view")},({kind:O,change:j})=>`${O}.${j.kind}`).exhaustive(()=>"unknown")}function l$($,O,j){let[x]=$;if($.length!==1||!r1(x,O,j))throw new f(`expected one ${O}.${j} result, got ${$.map(x0).join(", ")||"none"}`);return x}class V$ extends M{access=new o(this.client,"database",this);async fetch(){return G(await this.client.storage.getDatabase({path:{id:this.id}}))}assertOwns($,O){if(O.id!==this.id)throw new f(`${$} does not belong to database ${this.id}`)}static byId($,O){return new V$($,O)}static async create($,O){let j=G(await $.storage.createDatabase({body:{name:O.name}}));return new V$($,j.id)}static async list($){return G(await $.storage.listDatabases()).map((j)=>new V$($,j.database.id))}query($,O){return Dj(this.client,V$.byId,$,{...O,database:this})}invalidateSchema(){this.detail.clear()}schema(){return this.detail.get()}name=this.mappedField("database",($)=>$.name);owner=this.mappedField("database",($)=>P.byId(this.client,$.owner_id));createdAt=this.mappedField("database",($)=>$.created_at);trashedAt=this.mappedField("database",($)=>$.trashed_at??void 0);grant=this.field("grant");tables=this.mappedField("tables",($)=>$.map((O)=>J$.byId(this,O.table.id)));async table($){let{tables:O}=await this.schema(),j=O.find((x)=>x.table.name===$);return j?J$.byId(this,j.table.id):void 0}async createTable($){let{table:O}=l$(await this.applyOps([{kind:"table",table:d$(),change:{kind:"create",name:$.name}}]),"table","created");return J$.byId(this,O)}async applyOps($,O={}){let j={ops:$};if(O.baseVersions!==void 0){for(let{table:S}of O.baseVersions)this.assertOwns(`table ${S.id}`,S.database);j.baseVersions=Object.fromEntries(O.baseVersions.map(({table:S,version:K})=>[S.id,K]))}let{results:x}=await this.mutate(async(S)=>{let K=await S.storage.applyDatabaseOps({path:{id:this.id},body:j});if(K.error!==void 0&&"op"in K.error)throw new S0(K.response?.status??0,K.error);return K});return x}async reorderTables($){for(let x of $)this.assertOwns(`table ${x.id}`,x.database);let O=await this.applyOps([{kind:"reorder_tables",order:$.map((x)=>x.id)}]),[j]=O;if(O.length!==1||j?.kind!=="reorder_tables")throw new f(`expected one reorder_tables result, got ${O.map(x0).join(", ")||"none"}`);return j.tables.map(({table:x})=>J$.byId(this,x))}async deleteTable($){this.assertOwns(`table ${$.id}`,$.database),l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"delete"}}]),"table","deleted")}async columnCasts($){return this.assertOwns(`column ${$.id}`,$.table.database),G(await this.client.storage.listDatabaseColumnCasts({path:{id:this.id,table_id:$.table.id,column_id:$.id}}))}async viewPositions($){this.assertOwns(`view ${$.id}`,$.table.database);let{positions:O}=G(await this.client.storage.getDatabaseViewPositions({path:{id:this.id,view_id:$.id}}));return O}async rowHistory($){this.assertOwns(`row ${$.id}`,$.table.database);let{changes:O}=G(await this.client.storage.getDatabaseRowHistory({path:{id:this.id,table_id:$.table.id,row_id:$.id}}));return O}async importTable($){let O=await this.mutate((j)=>j.storage.importDatabaseTable({path:{id:this.id},body:$}));return J$.byId(this,O.id)}webhookOf($){return _j.fromRecord(J$.byId(this,$.tableId),P.byId(this.client,$.createdBy),$)}async webhooks(){let{webhooks:$}=G(await this.client.storage.listDatabaseWebhooks({path:{id:this.id}}));return $.map((O)=>this.webhookOf(O))}async createWebhook($){this.assertOwns("table",$.database);let O=G(await this.client.storage.createDatabaseWebhook({path:{id:this.id},body:{tableId:$.id}}));return{webhook:this.webhookOf(O.webhook),token:O.token}}async deleteWebhook($){this.assertOwns("webhook",$.table.database),G(await this.client.storage.deleteDatabaseWebhook({path:{id:this.id,webhook_id:$.id}}))}async sharePermissions(){return G(await this.client.storage.getDatabasePermissions({path:{id:this.id}}))}updateSharePermissions($){return this.mutate((O)=>O.storage.updateDatabasePermissions({path:{id:this.id},body:$}))}async changeColumnType($,O){this.assertOwns(`column ${$.id}`,$.table.database);let j=await $.table.version();return l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"change_type",to:Cj(O.to)}}],{baseVersions:[{table:$.table,version:j}]}),"column","type_changed")}async columnConversion($,O){return this.assertOwns(`column ${$.id}`,$.table.database),G(await this.client.storage.convertDatabaseColumn({path:{id:this.id,table_id:$.table.id,column_id:$.id},body:{to:Cj(O)}}))}async convertColumnIntoNewColumn($,O){let j=await this.columnConversion($,O.to),x=O.name??`${await $.name()} (${G7(O.to)})`,S=d$(),K=[{kind:"column",table:$.table.id,column:S,change:{kind:"create",definition:{source:"new",name:x,type:Cj(O.to),options:j0(j.options)},after:$.id}}];if(j.cells.length>0)K.push({kind:"rows",table:$.table.id,change:{kind:"update",changes:{kind:"per_row",rows:j.cells.map(({row:X,value:Y})=>({row:X,cells:[{column:S,value:Y}]}))}}});let[Z]=await this.applyOps(K,{baseVersions:[{table:$.table,version:j.tableVersion}]});if(!r1(Z,"column","created"))throw new f(`expected a column.created result, got ${Z?x0(Z):"none"}`);return A$.byId($.table,Z.column)}async deleteColumn($){this.assertOwns(`column ${$.id}`,$.table.database);let O=await $.table.version(),{tableVersion:j}=l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"delete"}}],{baseVersions:[{table:$.table,version:O}]}),"column","deleted");return j}async reorderColumns($,O){this.assertOwns(`table ${$.id}`,$.database);for(let S of O)if(S.table.id!==$.id)throw new f(`column ${S.id} does not belong to table ${$.id}`);let j=await $.version(),{tableVersion:x}=l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"reorder_columns",order:O.map((S)=>S.id)}}],{baseVersions:[{table:$,version:j}]}),"table","columns_reordered");if(x===void 0)throw new f(`table ${$.id} reordered its columns without a version`);return x}async renameTable($,O){this.assertOwns(`table ${$.id}`,$.database);let j=await $.name(),{tableVersion:x}=l$(await this.applyOps([{kind:"table",table:$.id,change:{kind:"rename",name:O,previousName:j}}]),"table","renamed");if(x===void 0)throw new f(`table ${$.id} was renamed without a version`);return x}async renameColumn($,O){this.assertOwns(`column ${$.id}`,$.table.database);let j=await $.name(),{tableVersion:x}=l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"rename",name:O,previousName:j}}]),"column","renamed");return x}async inferColumnType($,O){return this.assertOwns(`column ${$.id}`,$.table.database),this.mutate((j)=>j.storage.inferDatabaseColumnType({path:{id:this.id,table_id:$.table.id,column_id:$.id},body:{dataType:O.dataType,baseVersion:O.baseVersion,...O.specificEntityType!==void 0?{specificEntityType:O.specificEntityType}:{}}}))}async addColumn($,O){if(this.assertOwns(`table ${$.id}`,$.database),O.after!==void 0&&O.after.table.id!==$.id)throw new f(`column ${O.after.id} does not belong to table ${$.id}`);let j="property"in O?{source:"existing",property:O.property.id}:{source:"new",name:O.name,type:Cj(O.type),...O.options!==void 0?{options:j0(O.options)}:{},...O.inferType!==void 0?{inferType:O.inferType}:{}},{column:x}=l$(await this.applyOps([{kind:"column",table:$.id,column:d$(),change:{kind:"create",definition:j,...O.after!==void 0?{after:O.after.id}:{}}}]),"column","created");return A$.byId($,x)}async addColumnOptions($,O){return this.assertOwns(`column ${$.id}`,$.table.database),l$(await this.applyOps([{kind:"column",table:$.table.id,column:$.id,change:{kind:"add_options",options:j0(O)}}]),"column","options_added")}}class Z0{client;constructor($){this.client=$}query($,O){return Dj(this.client,V$.byId,$,O)}byId($){return V$.byId(this.client,$)}create($){return V$.create(this.client,$)}list(){return V$.list(this.client)}}class Pj{id;name;constructor($,O){this.id=$;this.name=O}static async list($){let{skills:O}=G(await $.storage.getSystemSkillsHandler());return O.map((j)=>new Pj(j.id,j.name))}}class X0{client;async byTeamSlug($){let O=G(await this.client.storage.getDocumentByTeamSlug({path:{slug:$}}));if(typeof O!=="object"||O===null||!("data"in O)||typeof O.data!=="object"||O.data===null||!("documentMetadata"in O.data)||typeof O.data.documentMetadata!=="object"||O.data.documentMetadata===null||!("documentId"in O.data.documentMetadata)||typeof O.data.documentMetadata.documentId!=="string")throw Error("Invalid team task document response");return w.byId(this.client,O.data.documentMetadata.documentId)}async validatePermissionsToken($){let O=G(await this.client.storage.validateDocumentPermissionsToken({body:{token:$}}));return{document:w.byId(this.client,O.document_id),user:O.user_id?P.byId(this.client,O.user_id):void 0,accessLevel:O.access_level,expiresAt:O.exp,issuer:O.iss}}async createUpload($){let O={documentName:$.name,sha:$.sha,fileType:$.fileType,mimeType:$.mimeType,projectId:$.project?.id,teamId:$.team?.id,branchedFromId:$.branchedFrom?.id,emailAttachmentId:$.attachment?.id,isTask:$.isTask},j=G(await this.client.storage.createDocument({body:O})).data;return{document:w.byId(this.client,j.documentMetadata.documentId),uploadUrl:j.presignedUrl??void 0,contentType:j.contentType,content:j.documentMetadata.content}}constructor($){this.client=$}byId($){return w.byId(this.client,$)}create($){return w.create(this.client,$)}async createCanvas($){let O=G(await this.client.storage.createCanvasHandler({body:{documentName:$.name,projectId:$.project?.id}}));return w.byId(this.client,O.documentId)}createSnippet($){return w.createSnippet(this.client,$)}createSkill($){return w.createSkill(this.client,$)}systemSkills(){return Pj.list(this.client)}search($,O){return w.search(this.client,$,O)}recent($){return w.recent(this.client,$)}recentlyDeleted(){return w.recentlyDeleted(this.client)}}class WO extends M{async fetch(){let{attachment:$}=G(await this.client.email.getAttachment({path:{id:this.id}}));return $}static byId($,O){return new WO($,O)}static from($,O){return new WO($,O.db_id,O)}filename=this.field("filename");mimeType=this.field("mime_type");size=this.field("size_bytes");dataUrl=this.field("data_url");sfsId=this.field("sfs_id");contentId=this.field("content_id");async toDocument(){let{document_id:$}=G(await this.client.email.getAttachmentDocumentId({path:{id:this.id}}));return w.byId(this.client,$)}}class R$ extends X${access=new o(this.client,"email_thread",this);async followup(){return G(await this.client.storage.getEmailFollowup({path:{thread_id:this.id}}))}async setFollowup($){return G(await this.client.storage.setEmailFollowup({path:{thread_id:this.id},body:$}))}async calendarInvitations(){return G(await this.client.email.getThreadCalendarInvitations({path:{thread_id:this.id}}))}async addEventToCalendar($,O,j={}){let x=G(await this.client.email.copyThreadCalendarInvitation({path:{thread_id:this.id,message_id:$.id,invitation_id:O.id},body:{calendarId:j.calendar?.id}}));return $$.fromRecord(this.client,x)}async update($){await this.mutate((O)=>O.storage.editThreadV2({path:{thread_id:this.id},body:{projectId:$.project===void 0?void 0:$.project?.id??null,sharePermission:$.sharePermission?n$($.sharePermission):void 0}}))}entityType="email_thread";propertyEntityType="THREAD";async fetch(){let{thread:$}=G(await this.client.email.getThread({path:{thread_id:this.id},query:{limit:100}}));return $}static byId($,O){return new R$($,O)}createdAt=this.field("created_at");updatedAt=this.field("updated_at");isRead=this.field("is_read");inboxVisible=this.field("inbox_visible");accessLevel=this.field("access_level");providerId=this.field("provider_id");link=this.mappedField("link_id",($)=>T$.byId(this.client,$));project=this.mappedField("project_id",($)=>$?n.byId(this.client,$):void 0);latestInboundAt=this.field("latest_inbound_message_ts");latestOutboundAt=this.field("latest_outbound_message_ts");latestNonSpamAt=this.field("latest_non_spam_message_ts");async subject(){let{messages:$}=await this.detail.get();for(let O of $)if(O.subject)return O.subject;return}async participants(){let{messages:$}=await this.detail.get(),O=new Map;for(let j of $)for(let x of[j.from,...j.to,...j.cc,...j.bcc])if(x&&!O.has(x.email))O.set(x.email,x);return[...O.values()]}async messages($){return G(await this.client.email.getThreadMessagesHandler({path:{id:this.id},query:{...$?.since?{since:$.since}:{},...$?.limit?{limit:$.limit}:{}}})).map((j)=>D$.from(this.client,j))}async attachments(){let{messages:$}=await this.detail.get();return $.flatMap((O)=>O.attachments.map((j)=>WO.from(this.client,j)))}async reply($){let O=$.subject??await this.subject()??"",{message:j}=await this.mutate((x)=>x.email.sendMessage({body:{message:{thread_db_id:this.id,replying_to_id:$.replyingTo?.id??null,to:$.to,cc:$.cc??null,bcc:$.bcc??null,subject:O,body_text:$.bodyText}}}));return j.db_id?D$.byId(this.client,j.db_id):void 0}async archive($=!0){await this.mutate((O)=>O.email.archiveThread({path:{id:this.id},body:{value:$}}))}async updateState($){await this.mutate((O)=>O.email.updateThreadState({path:{id:this.id},body:$}))}async operations(){return G(await this.client.email.threadOperations({path:{id:this.id}}))}async markSeen(){await this.mutate(($)=>$.email.threadSeen({path:{id:this.id}}))}async addLabel($){await this.mutate((O)=>O.email.addRemoveThreadLabel({path:{id:this.id},body:{label_id:$.id,value:!0}}))}async removeLabel($){await this.mutate((O)=>O.email.addRemoveThreadLabel({path:{id:this.id},body:{label_id:$.id,value:!1}}))}async moveToProject($){await this.mutate((O)=>O.email.updateThreadProject({path:{thread_id:this.id},body:{projectId:$?.id??null}}))}static search=x$({filters:{email_filters:{}},type:"email",make:($,O)=>new R$($,O.thread_id)})}class D$ extends M{async fetch(){return G(await this.client.email.getMessage({path:{id:this.id}}))}static byId($,O){return new D$($,O)}static from($,O){return new D$($,O.db_id,O)}static async send($,O){let{message:j}=G(await $.email.sendMessage({body:{message:{to:O.to,cc:O.cc??null,bcc:O.bcc??null,subject:O.subject,body_text:O.bodyText}}}));return j.db_id?D$.byId($,j.db_id):void 0}subject=this.field("subject");from=this.field("from");to=this.field("to");cc=this.field("cc");bcc=this.field("bcc");body=this.field("body_parsed");sentAt=this.field("internal_date_ts");labels=this.field("labels");link=this.mappedField("link_id",($)=>T$.byId(this.client,$));async operationStatus(){return G(await this.client.email.messageOperationStatus({path:{id:this.id}}))}async resolveOperation($){await this.mutate((O)=>O.email.resolveMessageOperation({path:{id:this.id},body:$}))}async completeDraftAttachment($,O=0){let j=await this.link();await this.mutate((x)=>x.email.completeDraftAttachment({path:{id:this.id,attachment_id:$},query:{draft_generation:O},headers:{"X-Email-Link-Id":j.id}}))}async transferDraft($){let O=await this.detail.get();return this.mutate((j)=>j.email.transferDraft({path:{id:this.id},body:{...$,draft_generation:$.draft_generation??O.draft_generation??0},headers:{"X-Email-Link-Id":O.link_id}}))}async addLabel($){await this.mutate((O)=>O.email.addRemoveLabel({body:{label_id:$.id,message_ids:[this.id],value:!0}}))}async removeLabel($){await this.mutate((O)=>O.email.addRemoveLabel({body:{label_id:$.id,message_ids:[this.id],value:!1}}))}async thread(){return R$.byId(this.client,(await this.detail.get()).thread_db_id)}}class BO extends D${async draftContext(){let $=await this.detail.get();return{headers:{"X-Email-Link-Id":$.link_id},query:{draft_generation:$.draft_generation??0}}}static byId($,O){return new BO($,O)}draftGeneration=this.field("draft_generation");async update($){let{headers:O,query:j}=await this.draftContext();await this.mutate((x)=>x.email.createDraft({headers:O,body:{draft:{...K0($),db_id:this.id,draft_generation:$.draftGeneration??j.draft_generation}}}))}async delete(){let{headers:$,query:O}=await this.draftContext();await this.mutate((j)=>j.email.deleteDraft({path:{id:this.id},headers:$,query:O}))}async schedule($,O){let{headers:j,query:x}=await this.draftContext();await this.mutate((S)=>S.email.upsertScheduledMessage({path:{id:this.id},headers:j,query:x,body:{send_time:$,include_signature:O?.includeSignature}}))}async unschedule(){let{headers:$,query:O}=await this.draftContext();await this.mutate((j)=>j.email.deleteScheduledDraft({path:{message_id:this.id},headers:$,query:O}))}async addAttachment($){let O={file_name:$.fileName,sha:$.sha,size:$.size,upload_id:$.uploadId},{headers:j,query:x}=await this.draftContext(),S=await this.mutate((K)=>K.email.addDraftAttachment({path:{id:this.id},headers:j,query:x,body:O}));return{attachment:eO.byId(this.client,this,S.attachment_id,!1,x.draft_generation),uploadUrl:S.upload_url,contentType:S.content_type}}async forwardAttachment($){let{headers:O,query:j}=await this.draftContext(),x=await this.mutate((S)=>S.email.addForwardedAttachment({path:{id:this.id},headers:O,query:j,body:{attachment_id:$.id}}));return eO.byId(this.client,this,x.attachment_id,!0,j.draft_generation)}async removeAttachment($){if($.draft.id!==this.id)throw Error("Attachment belongs to another draft");let{headers:O}=await this.draftContext(),j={draft_generation:$.draftGeneration};if($.forwarded)await this.mutate((x)=>x.email.removeForwardedAttachment({path:{id:this.id,attachment_id:$.id},headers:O,query:j}));else await this.mutate((x)=>x.email.removeDraftAttachment({path:{id:this.id,attachment_id:$.id},headers:O,query:j}))}async verifyAttachment($){if($.draft.id!==this.id||$.forwarded)throw Error("Expected an uploaded attachment on this draft");await this.completeDraftAttachment($.id,$.draftGeneration)}}class eO{draft;id;forwarded;draftGeneration;constructor($,O,j,x){this.draft=$;this.id=O;this.forwarded=j;this.draftGeneration=x}static byId($,O,j,x=!1,S=0){return new eO(O,j,x,S)}complete(){return this.draft.verifyAttachment(this)}remove(){return this.draft.removeAttachment(this)}toJSON(){return{id:this.id,draftId:this.draft.id,forwarded:this.forwarded,draftGeneration:this.draftGeneration}}}function K0($){let{bodyText:O,bodyHtml:j,bodyMacro:x,headers:S,includeSignature:K,draftGeneration:Z,thread:X,replyingTo:Y,...L}=$;return{...L,body_text:O,body_html:j===void 0?void 0:btoa(Array.from(new TextEncoder().encode(j),(Q)=>String.fromCharCode(Q)).join("")).replaceAll("+","-").replaceAll("/","_").replaceAll("=",""),body_macro:x,headers_json:S,include_signature:K,draft_generation:Z,thread_db_id:X?.id,replying_to_id:Y?.id}}class LO extends M{inbox;constructor($,O,j,x){super($,O,j);this.inbox=x}get headers(){return this.inbox?{"X-Email-Link-Id":this.inbox.id}:void 0}static byId($,O,j){return new LO($,O,void 0,j)}static from($,O,j){return new LO($,O.id,O,j)}async fetch(){let $=G(await this.client.email.listEmailFilters({headers:this.headers})).filters.find((O)=>O.id===this.id);if(!$)throw new E(`Email filter ${this.id} is unavailable`);return $}emailAddress=this.field("email_address");emailDomain=this.field("email_domain");isImportant=this.field("is_important");async setImportant($){let O=await this.detail.get();await this.mutate((j)=>j.email.upsertEmailFilter({headers:this.headers,body:{email_address:O.email_address,email_domain:O.email_domain,is_important:$}}))}async delete(){await this.mutate(($)=>$.email.deleteEmailFilter({path:{id:this.id},headers:this.headers}))}}class jO extends M{async fetch(){let{labels:$}=G(await this.client.email.listLabels()),O=$.find((j)=>j.id===this.id);if(!O)throw new E(`label ${this.id} not found`);return O}static byId($,O){return new jO($,O)}static async list($){let{labels:O}=G(await $.email.listLabels());return O.map((j)=>new jO($,j.id,j))}static async create($,O){let{label:j}=G(await $.email.createLabel({body:{label_name:O}}));if(!j.id)throw new f("created label has no id");return new jO($,j.id)}async delete(){G(await this.client.email.deleteLabel({path:{id:this.id}}))}name=this.field("name");linkId=this.field("linkId");type=this.field("type");createdAt=this.field("createdAt");labelListVisibility=this.field("labelListVisibility");messageListVisibility=this.field("messageListVisibility")}class Y0{client;async createDraft($,O){let j=G(await this.client.email.createDraft({body:{draft:K0($)},headers:O?{"X-Email-Link-Id":O.id}:void 0}));if(!j.draft.db_id)throw Error("Draft response has no message id");return BO.byId(this.client,j.draft.db_id)}draftById($){return BO.byId(this.client,$)}async*scheduled($){let O=$?.pageSize??100;if(!Number.isInteger(O)||O<1)throw Error("pageSize must be positive");let j=Math.min(O,1000);for(let x=0;;x+=j){let S=G(await this.client.email.getScheduledMessages({query:{offset:x,limit:j},headers:$?.inbox?{"X-Email-Link-Id":$.inbox.id}:void 0}));for(let K of S.messages)yield BO.byId(this.client,K.db_id);if(S.messages.lengthLO.from(this.client,O,$))}async upsertFilter($,O){return LO.from(this.client,G(await this.client.email.upsertEmailFilter({headers:O?{"X-Email-Link-Id":O.id}:void 0,body:{email_address:$.emailAddress,email_domain:$.emailDomain,is_important:$.isImportant}})).filter,O)}async contacts(){return G(await this.client.email.listContacts()).contacts}reminders($){let{inboxes:O,...j}=$??{};return u(async(x)=>{let S=G(await this.client.storage.listEmailReminders({query:{...j,inboxIds:O?.map((K)=>K.id),cursor:x}}));return{items:S.items.map(({threadId:K,...Z})=>({...Z,thread:R$.byId(this.client,K)})),nextCursor:S.nextCursor}})}constructor($){this.client=$}byId($){return R$.byId(this.client,$)}message($){return D$.byId(this.client,$)}attachment($){return WO.byId(this.client,$)}link($){return T$.byId(this.client,$)}links(){return T$.list(this.client)}async connectionProviders(){return G(await this.client.auth.emailConnectionProviders())}async recoverDraftTransfer($){return G(await this.client.email.recoverDraftTransfer({path:{id:$}}))}send($){return D$.send(this.client,$)}search($,O){return R$.search(this.client,$,O)}inbox($){return u(async(O)=>{let j=G(await this.client.email.previewsInboxCursor({path:{view:"inbox"},query:{...$?.pageSize?{limit:$.pageSize}:{},...$?.sort?{sort_method:$.sort}:{},...O?{cursor:O}:{}}}));return{items:j.items.map((x)=>R$.byId(this.client,x.id)),nextCursor:j.next_cursor}})}label($){return jO.byId(this.client,$)}labels(){return jO.list(this.client)}createLabel($){return jO.create(this.client,$)}async deleteLabel($){G(await this.client.email.deleteLabel({path:{id:$.id}}))}async blockSender($){G(await this.client.email.blockSender({body:{email_address:$}}))}async unblockSender($){G(await this.client.email.unblockSender({body:{email_address:$}}))}async blockedSenders(){return G(await this.client.email.listBlockedSenders()).blocked_emails}}class IO{client;id;constructor($,O){this.client=$;this.id=O}static byId($,O){return new IO($,O)}async delete(){G(await this.client.storage.deleteEntityMention({path:{mention_id:this.id}}))}toJSON(){return{id:this.id}}}class G0{client;constructor($){this.client=$}byId($){return IO.byId(this.client,$)}async create($,O){let j=G(await this.client.storage.createEntityMention({body:{source_entity_id:$.entity.id,source_entity_type:$.type,entity_id:O.entity.id,entity_type:O.type}}));return IO.byId(this.client,j.id)}}class Q0{client;constructor($){this.client=$}async list($={}){let{favorites:O}=G(await this.client.storage.listFavorites({query:{entityType:$.entityTypes,entityId:$.entityIds}}));return O}async add($){return G(await this.client.storage.addFavorite({body:{entityId:$.id,entityType:$.entityType}}))}async remove($){G(await this.client.storage.removeFavoriteByEntity({path:{entity_type:$.entityType,entity_id:$.id}}))}async reorder($){G(await this.client.storage.reorderFavorites({body:{favorites:$}}))}}class xO extends z${entityType="foreign_entity";async fetch(){return G(await this.client.storage.getForeignEntity({path:{id:this.id}}))}static byId($,O){return new xO($,O)}static fromRecord($,O){return new xO($,O.id,O)}foreignEntityId=this.field("foreignEntityId");source=this.field("foreignEntitySource");storedForId=this.field("storedForId");storedForAuthEntity=this.field("storedForAuthEntity");createdAt=this.field("createdAt");updatedAt=this.field("updatedAt");async metadata(){return(await this.detail.get()).metadata}}function p1({login:$,...O}){return{...O,login:$??void 0}}class J0{client;constructor($){this.client=$}byId($){return xO.byId(this.client,$)}async bySource($,O){return xO.fromRecord(this.client,G(await this.client.storage.getForeignEntityBySource({path:{source:$,foreign_entity_id:O}})))}async githubPullRequestFacets(){let{repositories:$,authors:O,assignees:j,labels:x}=G(await this.client.storage.getGithubPullRequestFacets());return{repositories:$,authors:O.map(p1),assignees:j.map(p1),labels:x.map(({color:S,...K})=>({...K,color:S??void 0}))}}}class r${form;id;constructor($,O){this.form=$;this.id=O}static byId($,O){return new r$($,O)}async detail(){let O=(await this.form.schema()).sections.flatMap((j)=>j.kind==="questions"?j.questions:[]).find((j)=>j.id===this.id);if(!O)throw new E(`question ${this.id} is not on form ${this.form.id}`);return O}async title(){return(await this.detail()).title}async column(){return A$.byId(await this.form.table(),(await this.detail()).column)}async options(){return(await this.detail()).options.map(($)=>NO.byId(this,$.id))}}class NO{question;id;constructor($,O){this.question=$;this.id=O}static byId($,O){return new NO($,O)}async detail(){let $=(await this.question.detail()).options.find((O)=>O.id===this.id);if(!$)throw new E(`option ${this.id} is not on question ${this.question.id}`);return $}async label(){return(await this.detail()).label}async color(){return(await this.detail()).color??void 0}}class TO{form;id;detail;constructor($,O,j){this.form=$;this.id=O;this.detail=new W$(()=>this.load(),j)}async load(){let $=await this.form.myResponse();if($.response.id!==this.id)throw new E(`response ${this.id} is not your current response`);return $}static byId($,O,j){return new TO($,O,j)}async status(){return(await this.detail.get()).status}async row(){return(await this.detail.get()).row}async answers(){return(await this.detail.get()).answers}async booking(){return(await this.detail.get()).booking}async refresh(){let $=await this.load();return this.detail=new W$(()=>this.load(),$),this}}class p${form;id;constructor($,O){this.form=$;this.id=O}static byId($,O){return new p$($,O)}async detail(){let $=(await this.form.schema()).sections.find((O)=>O.id===this.id);if(!$)throw new E(`section ${this.id} is not on form ${this.form.id}`);return $}async title(){return(await this.detail()).title}async questions(){let $=await this.detail();return $.kind==="questions"?$.questions.map((O)=>r$.byId(this.form,O.id)):[]}}class Mj{entityType;id;constructor($,O){this.entityType=$;this.id=O}static byId($,O){return new Mj($,O)}}class y$ extends M{async fetch(){return G(await this.client.storage.getForm({path:{id:this.id}}))}static byId($,O){return new y$($,O)}static async create($,O){let j=G(await $.storage.createForm({body:{name:O.name,source:O.table?{kind:"table",databaseId:O.table.database.id,tableId:O.table.id}:{kind:"new"}}}));return new y$($,j.form.id,j)}static async list($,O){if(!O)return G(await $.storage.listAccessibleForms()).map(({form:S})=>new y$($,S.id));return G(await $.storage.listForms({query:{databaseId:O.id}})).map((x)=>new y$($,x.id))}schema(){return this.detail.get()}name=this.mappedField("form",($)=>$.name);description=this.mappedField("form",($)=>$.description);owner=this.mappedField("form",($)=>P.byId(this.client,$.ownerId));database=this.mappedField("form",($)=>V$.byId(this.client,$.databaseId));table=this.mappedField("form",($)=>J$.byId(V$.byId(this.client,$.databaseId),$.tableId));audience=this.mappedField("form",($)=>$.audience);status=this.mappedField("form",($)=>$.status);closesAt=this.mappedField("form",($)=>$.closesAt??void 0);access=this.field("access");async sections(){return(await this.detail.get()).sections.map(($)=>p$.byId(this,$.id))}async questions(){return(await this.detail.get()).sections.flatMap(($)=>$.kind==="questions"?$.questions.map((O)=>r$.byId(this,O.id)):[])}async update($){return await this.mutate((O)=>O.storage.updateForm({path:{id:this.id},body:$})),this}assertOwns($){if($.form.id!==this.id)throw new f(`question or section does not belong to form ${this.id}`)}async replaceLayout($){let O=await this.table(),j=(Z)=>{if(Z.table.id!==O.id||Z.table.database.id!==O.database.id)throw new f(`column does not belong to form ${this.id}'s table`);return Z.id},x=(Z)=>({conjunction:Z.conjunction,conditions:Z.conditions.map((X)=>c(X).with({kind:"group"},(Y)=>({kind:"group",...x(Y)})).with({kind:"condition"},(Y)=>({kind:"condition",column:j(Y.column),test:c(Y.test).with({kind:"options"},(L)=>({...L,options:L.options.map((Q)=>Q.id)})).with({kind:"entities"},(L)=>({...L,entities:L.entities.map((Q)=>Q.id)})).with({kind:Z$.union("presence","text","number","date","checkbox")},(L)=>L).exhaustive()})).exhaustive())}),S={sections:$.map((Z)=>{if(Z.section)this.assertOwns(Z.section);let X={id:Z.section?.id??d$(),title:Z.title,description:Z.description??""};return c(Z).with({kind:"booking"},(Y)=>({...X,kind:"booking",target:Y.target})).with({kind:"gate"},(Y)=>({...X,kind:"gate",rules:x(Y.rules),message:Y.message})).with({kind:"questions"},(Y)=>({...X,kind:"questions",questions:Y.questions.map((L)=>{if(L.question)this.assertOwns(L.question);return{id:L.question?.id??d$(),column:j(L.column),helpText:L.helpText??"",required:L.required??!1,widget:L.widget??null}})})).exhaustive()})},K=await this.mutate((Z)=>Z.storage.putFormLayout({path:{id:this.id},body:S}));return{form:this,publicationError:K.publicationError}}wireAnswers($){return $.map(({question:O,value:j})=>{this.assertOwns(O);let x=c(j).with({type:"rows"},(S)=>({type:"rows",value:S.value.map((K)=>K.id)})).with({type:"options"},(S)=>({type:"options",value:S.value.map((K)=>{if(K.question.id!==O.id||K.question.form.id!==this.id)throw new f("option does not belong to the answered question");return{id:K.id}})})).with({type:"entities"},(S)=>({type:"entities",value:S.value.map(({entityType:K,entity:Z})=>({entityType:K,entityId:Z.id}))})).with({type:Z$.union("text","number","boolean","date","link","clear")},(S)=>S).exhaustive();return{question:O.id,value:x}})}unlockedBooking($){return $?{...$,section:p$.byId(this,$.section)}:void 0}async outcome($,O){return c($).with({outcome:"stopped"},(j)=>({...j,section:p$.byId(this,j.section)})).with({outcome:"submitted"},async(j)=>{let x=F$.byId(await this.table(),j.row),S=this.unlockedBooking(j.booking);return{outcome:"submitted",response:TO.byId(this,j.response,{status:"submitted",row:x,answers:O,booking:S}),row:x,...S?{booking:S}:{}}}).exhaustive()}async submit($){let O={answers:this.wireAnswers($)};return this.outcome(G(await this.client.storage.submitFormResponse({path:{id:this.id},body:O})),$)}async editResponse($){let O={answers:this.wireAnswers($)};return this.outcome(G(await this.client.storage.editMyFormResponse({path:{id:this.id},body:O})),$)}async myResponse(){let $=G(await this.client.storage.getMyFormResponse({path:{id:this.id}})),O=await this.table(),j=await Promise.all($.answers.map(async(K)=>{let Z=r$.byId(this,K.question),X=await c(K.value).with({type:"options"},(Y)=>({type:"options",value:Y.value.map((L)=>{if(!("id"in L))throw new f("stored form answers must reference options by id");return NO.byId(Z,L.id)})})).with({type:"entities"},(Y)=>({type:"entities",value:Y.value.map((L)=>({entityType:L.entityType,entity:Mj.byId(L.entityType,L.entityId)}))})).with({type:"rows"},async(Y)=>{let L=await Z.detail();if(L.kind.type!=="relation")throw new f("row answer requires a relation question");let Q=J$.byId(V$.byId(this.client,L.kind.database),L.kind.table);return{type:"rows",value:Y.value.map((J)=>F$.byId(Q,J))}}).with({type:Z$.union("text","number","boolean","date","link","clear")},(Y)=>Y).exhaustive(()=>{throw new f(`answer to question ${Z.id} has a type this SDK doesn't know`)});return{question:Z,value:X}})),x=$.response.row?F$.byId(O,$.response.row):void 0,S=this.unlockedBooking($.booking);return{...S?{booking:S}:{},response:TO.byId(this,$.response.id,{status:$.response.status,row:x,answers:j,booking:S}),status:$.response.status,stoppedAtSection:$.response.stoppedAtSection?p$.byId(this,$.response.stoppedAtSection):void 0,row:x,submittedAt:$.response.submittedAt,updatedAt:$.response.updatedAt,answers:j}}async responseSummary(){let $=G(await this.client.storage.getFormResponseSummary({path:{id:this.id}}));return{...$,stoppedBySection:$.stoppedBySection.map((O)=>({section:p$.byId(this,O.section),count:O.count}))}}async tally(){return G(await this.client.storage.getFormTally({path:{id:this.id}})).questions.map((O)=>{let j=r$.byId(this,O.question);return{question:j,responses:O.responses,buckets:O.buckets.flatMap((x)=>c(x.value).with({kind:"option"},(S)=>[{count:x.count,value:{kind:"option",option:NO.byId(j,S.option)}}]).with({kind:"checkbox"},(S)=>[{count:x.count,value:S}]).exhaustive((S)=>{return console.warn("macro sdk: unknown form tally bucket",S),[]}))}})}async sharePermissions(){return G(await this.client.storage.getFormPermissions({path:{id:this.id}}))}updateSharePermissions($){return this.mutate((O)=>O.storage.updateFormPermissions({path:{id:this.id},body:$}))}webUrl(){return`${this.client.webAppUrl}/app/form/${this.id}`}respondUrl(){return`${this.client.webAppUrl}/app/form/${this.id}/respond`}}class V0{client;constructor($){this.client=$}byId($){return y$.byId(this.client,$)}create($){return y$.create(this.client,$)}list($){return y$.list(this.client,$)}}class HO extends M{static byId($,O){return new HO($,O)}async fetch(){return G(await this.client.storage.getGithubPullRequest({path:{id:this.id}}))}title=this.field("title");url=this.field("url");status=this.field("status");async changes(){let $=G(await this.client.storage.getGithubPullRequestChanges({path:{id:this.id}}));return{changeset:$.changeset?new W0(this.client,this,$.changeset):void 0,error:$.error??void 0}}}class W0{client;pullRequest;record;constructor($,O,j){this.client=$;this.pullRequest=O;this.record=j}get id(){return this.record.id}async patch(){return G(await this.client.storage.getGithubPullRequestChangesPatch({path:{id:this.pullRequest.id},query:{changeset:this.id}})).patch}toJSON(){return{pullRequestId:this.pullRequest.id,...this.record}}}class B0{client;constructor($){this.client=$}byId($){return HO.byId(this.client,$)}forEntity($){return HO.byId(this.client,$.id)}}class RO extends M{static byId($,O){return new RO($,O)}async fetch(){return G(await this.client.storage.getHarnessPairing({path:{code:this.id}}))}name=this.field("requested_name");expiresAt=this.field("expires_at");async approve($){let O={name:$?.name,team_id:$?.team?.id,allow_permission_bypass:$?.allowPermissionBypass};return B$.from(this.client,await this.mutate((j)=>j.storage.approveHarnessPairing({path:{code:this.id},body:O})))}}class oO{client;id;constructor($,O){this.client=$;this.id=O}static byId($,O){return new oO($,O)}async claim($){let O=G(await this.client.storage.claimHarnessPairing({path:{pairing_id:this.id},body:{device_secret:$}}));return"harness"in O?{harness:B$.from(this.client,O.harness),token:O.token}:void 0}toJSON(){return{id:this.id}}}class L0{client;constructor($){this.client=$}byId($){return B$.byId(this.client,$)}async list(){return G(await this.client.storage.listHarnesses()).map(($)=>B$.from(this.client,$))}async me(){return B$.from(this.client,G(await this.client.storage.getSelfHarness()))}async deleteSelf(){G(await this.client.storage.deleteSelfHarness())}async agents(){return G(await this.client.storage.listHarnessAgents()).map(($)=>I$.byId(this.client,$.bot_id))}async sessions(){return G(await this.client.storage.listHarnessSessions()).map(($)=>i.byId(this.client,$.session_id))}pairing($){return RO.byId(this.client,$)}async createPairing($){let O=G(await this.client.storage.createHarnessPairing({body:$}));return{pairing:RO.byId(this.client,O.code),device:oO.byId(this.client,O.pairing_id),deviceSecret:O.device_secret,expiresAt:O.expires_at,pollIntervalSeconds:O.poll_interval_seconds}}}var Q7="00000001-0000-0000-0000-000000000002",J7="00000001-0000-0000-0002-000000000004";function V7($){let O=$.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/([1-9][0-9]*)\/?(?:[?#].*)?$/i);if(!O)throw Error(`Expected a GitHub pull request URL like https://github.com/owner/repo/pull/1, got ${$}`);return`${O[1]}/${O[2]}/pull/${O[3]}`}class _$ extends w{static byId($,O){return new _$($,O)}static async create($,O){let{documentId:j}=G(await $.storage.createTaskHandler({body:{taskName:O.name,markdown:O.markdown??null,projectId:O.project?.id??null,teamId:O.team?.id??null,shareWithTeam:O.shareWithTeam??!0}}));return new _$($,j)}static async forPullRequest($,O){let j=V7(O),{pullRequests:x}=G(await $.storage.getGithubPullRequestTasks({body:{githubKeys:[j]}}));return(x[0]?.taskIds??[]).map((S)=>new _$($,S))}async completed(){let{subType:$}=await this.detail.get();if($!=="task")return;let j=(await this.properties()).find((x)=>x.definition.id===Q7)?.value;return j?.type==="SelectOption"&&j.value.includes(J7)}webUrl(){return`${this.client.webAppUrl}/app/task/${this.id}`}static search=x$({filters:{document_filters:{sub_types:["task"],task_filters:{}}},type:"document",make:($,O)=>new _$($,O.document_id)})}class SO extends M{access=new o(this.client,"initiative",this);static byId($,O){return new SO($,O)}static from($,O){return new SO($,O.id,O)}async fetch(){return G(await this.client.storage.getInitiative({path:{initiative_id:this.id}}))}name=this.field("name");owner=this.mappedField("ownerId",($)=>P.byId(this.client,$));members=this.mappedField("memberIds",($)=>$.map((O)=>P.byId(this.client,O)));tasks=this.mappedField("taskIds",($)=>$.map((O)=>_$.byId(this.client,O)));accessLevel=this.field("userAccessLevel");sharePermissions=this.field("sharePermission");async update($){await this.mutate((O)=>O.storage.updateInitiative({path:{initiative_id:this.id},body:{name:$.name,memberIds:$.members?.map((j)=>j.id),sharePermission:$.sharePermission?n$($.sharePermission):void 0}}))}async delete(){await this.mutate(($)=>$.storage.deleteInitiative({path:{initiative_id:this.id}}))}}class N0{client;constructor($){this.client=$}byId($){return SO.byId(this.client,$)}async list(){return G(await this.client.storage.listInitiatives()).initiatives.map(($)=>SO.byId(this.client,$.id))}async create($){return SO.from(this.client,G(await this.client.storage.createInitiative({body:{name:$.name,description:$.description,memberIds:$.members?.map((O)=>O.id),shareWithTeam:$.shareWithTeam,propertyValues:$.propertyValues}})))}}class U0{client;constructor($){this.client=$}byId($){return H$.byId(this.client,$)}async create($){return H$.from(this.client,G(await this.client.storage.meetingCreate({body:$})))}async list(){return G(await this.client.storage.meetingList()).meetings.map(($)=>H$.from(this.client,$))}async active(){return G(await this.client.storage.meetingListActive()).meetings.map(($)=>H$.from(this.client,$))}async lookup($){return H$.from(this.client,G(await this.client.storage.meetingLookup({path:{token:$}})))}}class UO extends M{async fetch(){return G(await this.client.notification.getTypedNotificationById({path:{notification_id:this.id}}))}static byId($,O){return new UO($,O)}static from($,O){return new UO($,O.id,O)}static list($,O){return u(async(j)=>{let x=G(await $.notification.listTypedNotifications({query:{...O?.pageSize?{limit:O.pageSize}:{},...O?.states!==void 0?{states:O.states.join(",")}:{},...j?{cursor:j}:{}}}));return{items:x.items.map((S)=>UO.from($,S)),nextCursor:x.next_cursor}})}type=this.field("notification_event_type");createdAt=this.field("created_at");updatedAt=this.field("updated_at");state=this.field("state");done=this.mappedField("state",($)=>$==="done");sent=this.field("sent");viewedAt=this.field("viewed_at");deletedAt=this.field("deleted_at");owner=this.mappedField("owner_id",($)=>P.byId(this.client,$));sender=this.mappedField("sender_id",($)=>$?P.byId(this.client,$):void 0);metadata=this.field("notification_metadata");async seen(){return await this.state()!=="unseen"}async markSeen(){await this.mutate(($)=>$.notification.bulkMarkNotificationsSeen({body:{notificationIds:[this.id]}}))}async markDone(){await this.mutate(($)=>$.notification.bulkMarkNotificationsDone({body:{notificationIds:[this.id]}}))}async markUndone(){await this.mutate(($)=>$.notification.bulkMarkNotificationsUndone({body:{notificationIds:[this.id]}}))}async delete(){await this.mutate(($)=>$.notification.deleteUserNotificationV2({path:{notification_id:this.id}}))}}class z0{client;constructor($){this.client=$}byId($){return UO.byId(this.client,$)}list($){return UO.list(this.client,$)}async markSeen($){G(await this.client.notification.bulkMarkNotificationsSeen({body:{notificationIds:$}}))}async markDone($){G(await this.client.notification.bulkMarkNotificationsDone({body:{notificationIds:$}}))}async delete($){G(await this.client.notification.bulkDeleteUserNotificationsV2({body:{notificationIds:$}}))}async preferences(){return G(await this.client.notification.getNotificationTypePreferences())}async enableType($){G(await this.client.notification.enableNotificationType({path:{notification_event_type:$}}))}async disableType($){G(await this.client.notification.disableNotificationType({path:{notification_event_type:$}}))}}class I0{client;constructor($){this.client=$}async list(){let{data:$}=G(await this.client.storage.getPinsHandler({}));return $?.recent??[]}async add($,O){G(await this.client.storage.addPinHandler({path:{pinned_item_id:$.id},body:{pinType:$.entityType,pinIndex:O.index}}))}async remove($){G(await this.client.storage.removePinHandler({path:{pinned_item_id:$.id},body:{pinType:$.entityType}}))}async reorder($){G(await this.client.storage.reorderPinsHandler({body:$}))}}class T0{client;constructor($){this.client=$}byId($){return n.byId(this.client,$)}create($){return n.create(this.client,$)}search($,O){return n.search(this.client,$,O)}}class DO{client;definitionId;id;record;constructor($,O,j,x){this.client=$;this.definitionId=O;this.id=j;this.record=x}static from($,O,j){return new DO($,O,j.id,j)}get value(){return this.record.value}get color(){return this.record.color??void 0}get displayOrder(){return this.record.display_order}get createdAt(){return this.record.created_at}get updatedAt(){return this.record.updated_at}async update($){return this.record=G(await this.client.properties.updatePropertyOption({path:{definition_id:this.definitionId,option_id:this.id},body:$})),this}async delete(){G(await this.client.properties.deletePropertyOption({path:{definition_id:this.definitionId,option_id:this.id}}))}}class ZO{client;id;detail;constructor($,O,j){this.client=$;this.id=O;this.detail=new W$(()=>this.fetch(),j)}async fetch(){return G(await this.client.properties.getPropertyDefinition({path:{definition_id:this.id}}))}static async create($,O){let j=G(await $.properties.createPropertyDefinition({body:{display_name:O.displayName,scope:O.scope,data_type:O.dataType}}));return new ZO($,j.id,j)}static byId($,O){return new ZO($,O)}static fromRecord($,O){return new ZO($,O.id,O)}get displayName(){return this.detail.get().then(($)=>$.display_name)}get dataType(){return this.detail.get().then(($)=>$.data_type)}get owner(){return this.detail.get().then(($)=>$.owner)}get isSystem(){return this.detail.get().then(($)=>$.is_system)}get isMultiSelect(){return this.detail.get().then(($)=>$.is_multi_select)}get createdAt(){return this.detail.get().then(($)=>$.created_at)}get updatedAt(){return this.detail.get().then(($)=>$.updated_at)}async delete(){return G(await this.client.properties.deletePropertyDefinition({path:{definition_id:this.id}}))}async options(){return G(await this.client.properties.getPropertyOptions({path:{definition_id:this.id}})).map((O)=>DO.from(this.client,this.id,O))}async addOption($){let O=G(await this.client.properties.addPropertyOption({path:{definition_id:this.id},body:$}));return DO.from(this.client,this.id,O)}async updateOption($,O){let j=G(await this.client.properties.updatePropertyOption({path:{definition_id:this.id,option_id:$.id},body:O}));return DO.from(this.client,this.id,j)}async deleteOption($){return G(await this.client.properties.deletePropertyOption({path:{definition_id:this.id,option_id:$.id}}))}}class H0{client;constructor($){this.client=$}async list($){return G(await this.client.properties.listProperties({query:{scope:$?.scope??"all",...$?.forEntityType!==void 0?{for_entity_type:$.forEntityType}:{}}})).map((j)=>{let x="definition"in j?j.definition:j;return ZO.fromRecord(this.client,x)})}create($){return ZO.create(this.client,$)}definition($){return ZO.byId(this.client,$)}async bulkEntityProperties($){return G(await this.client.properties.getBulkEntityProperties({body:$}))}async updateEntityPropertyOptions($,O){return G(await this.client.properties.bulkUpdateEntitiesPropertyOptions({body:{entities:$.map((x)=>x.propertyReference()),property_id:O.property.id,...O.add?{add_option_ids:O.add.map((x)=>x.id)}:{},...O.remove?{remove_option_ids:O.remove.map((x)=>x.id)}:{}}})).results}async addEntityPropertyOption($){return G(await this.client.properties.addEntityPropertyOption({path:{...$.entity.propertyReference(),property_id:$.property.id,option_id:$.option.id}}))}async removeEntityPropertyOption($){return G(await this.client.properties.removeEntityPropertyOption({path:{...$.entity.propertyReference(),property_id:$.property.id,option_id:$.option.id}}))}async tags(){return G(await this.client.properties.listTags({}))}}function R0($){return c($).with({type:"cron"},(O)=>O).with({type:"events"},(O)=>({type:"events",filters:O.filters.map(({entities:j,...x})=>({...x,ids:j?.map((S)=>S.entity.id)}))})).exhaustive()}function W7($){return c($).with({type:"multiple"},(O)=>({type:"multiple",triggers:O.triggers.map(R0)})).with({type:"cron"},R0).with({type:"events"},R0).exhaustive()}class XO extends M{static byId($,O){return new XO($,O)}static from($,O){if(!O.id)throw Error("Routine response has no id");return new XO($,O.id,O)}async fetch(){return G(await this.client.scheduledAction.getScheduledAction({path:{id:this.id}}))}name=this.field("name");trigger=this.field("trigger");enabled=this.field("enabled");runVisibility=this.field("run_visibility");nextRunAt=this.field("next_run_at");revision=this.field("configuration_revision");owner=this.mappedField("owner",($)=>P.byId(this.client,$));async update($){await this.mutate((O)=>O.scheduledAction.updateScheduledAction({path:{id:this.id},body:_0($)}))}async setEnabled($){await this.mutate((O)=>O.scheduledAction.setScheduledActionEnabled({path:{id:this.id},body:{enabled:$}}))}async execute(){let $=G(await this.client.scheduledAction.executeScheduledActionNow({path:{id:this.id}}));if($.resource)return c($.resource).with({type:"agent"},(O)=>i.byId(this.client,O.id)).with({type:"chat"},(O)=>K$.byId(this.client,O.id)).exhaustive();return $.chat_id?K$.byId(this.client,$.chat_id):void 0}async history(){return G(await this.client.scheduledAction.listScheduledActionHistory({path:{id:this.id}})).map(($)=>new D0(this,$))}async delete(){await this.mutate(($)=>$.scheduledAction.deleteScheduledAction({path:{id:this.id}}))}}class D0{routine;record;constructor($,O){this.routine=$;this.record=O}get id(){return this.record.id??void 0}toJSON(){return{routine:this.routine.id,...this.record}}}function _0($){let O={prompt:$.prompt,user_prompt:$.userPrompt,model:$.model,agent:$.agent?{bot_id:$.agent.id}:void 0};return{kind:"Agent",name:$.name,enabled:$.enabled,run_visibility:$.runVisibility,trigger:W7($.trigger),task:{...O}}}class C0{client;constructor($){this.client=$}byId($){return XO.byId(this.client,$)}async create($){return XO.from(this.client,G(await this.client.scheduledAction.createScheduledAction({body:{..._0($),enabled:$.enabled??!0}})))}async list($){return G(await this.client.scheduledAction.listScheduledActions({query:{include_events:$?.includeEvents}})).map((O)=>XO.from(this.client,O))}}class P0{client;constructor($){this.client=$}byId($){return _$.byId(this.client,$)}create($){return _$.create(this.client,$)}forPullRequest($){return _$.forPullRequest(this.client,$)}search($,O){return _$.search(this.client,$,O)}}class M0{client;constructor($){this.client=$}byId($){return S$.byId(this.client,$)}current(){return S$.current(this.client)}list(){return S$.list(this.client)}}class A0{client;constructor($){this.client=$}async get($){return G(await this.client.unfurl.getUnfurl({query:{url:$}}))}async bulk($){return G(await this.client.unfurl.getUnfurlBulk({body:{url_list:$}}))}}class F0{client;constructor($){this.client=$}byId($){return P.byId(this.client,$)}me(){return P.me(this.client)}async search($){let O=$.trim().toLocaleLowerCase();if(!O)throw Error("A person search needs a name or email.");let j=await this.client.contacts.getContacts();if(j.response?.status===404)return[];let{contacts:x}=G(j),S=[...new Set(x)],K=[];for(let Z=0;Z[Q.id,Q]));for(let Q of X){let J=L.get(Q)??{id:Q};if(`${[J.first_name,J.last_name].filter(Boolean).join(" ")} ${Q}`.toLocaleLowerCase().includes(O))K.push(P.fromName(this.client,J))}}return K}}class KO extends M{signingSecret;constructor($,O,j,x){super($,O,j);this.signingSecret=x}async fetch(){return G(await this.client.storage.getWebhook({path:{webhook_id:this.id}}))}static async create($,O){let j=G(await $.storage.createWebhook({body:{endpoint_url:O.url,namespace:O.namespace,name:O.name,filters:O.filters,scope:O.scope??"user",...O.headers!==void 0?{headers:O.headers}:{}}}));return new KO($,j.id,j,j.signing_secret)}static byId($,O){return new KO($,O)}static fromRecord($,O){return new KO($,O.id,O)}name=this.field("name");namespace=this.field("namespace");endpointUrl=this.field("endpoint_url");status=this.field("status");isValid=this.field("is_valid");filters=this.field("filters");createdAt=this.field("created_at");workspaceId=this.field("workspace_id");createdBy=this.mappedField("created_by_user_id",($)=>P.byId(this.client,$));async scope(){let $=await this.detail.get();return $.workspace_id===$.created_by_user_id?"user":"team"}async update($){await this.mutate((O)=>O.storage.patchWebhook({path:{webhook_id:this.id},body:$}))}async rename($){await this.update({name:$})}async setUrl($){await this.update({endpoint_url:$})}async setFilters($){await this.update({filters:$})}async pause(){await this.update({status:"paused"})}async resume(){await this.update({status:"active"})}async delete(){await this.mutate(($)=>$.storage.deleteWebhook({path:{webhook_id:this.id}}))}async validate(){return this.mutate(($)=>$.storage.validateWebhook({path:{webhook_id:this.id}}))}}class E0{client;constructor($){this.client=$}create($){return KO.create(this.client,$)}byId($){return KO.byId(this.client,$)}async list(){let{webhooks:$}=G(await this.client.storage.listWebhooks());return $.map((O)=>KO.fromRecord(this.client,O))}}class _O extends M{static byId($,O){return new _O($,O)}static from($,O){return new _O($,O.id,O)}async fetch(){let{account:$}=G(await this.client.storage.linkedAccount());if($?.id!==this.id)throw new E("WhatsApp account is not available");return $}state=this.field("state");identity=this.field("identity_jid");owner=this.mappedField("user_id",($)=>P.byId(this.client,$));async refresh(){return this.detail.clear(),await this.detail.get(),this}}class C$ extends M{group;constructor($,O,j,x){super($,j,x);this.group=O}static byId($,O,j){return new C$($,O,j)}static from($,O,j){return new C$($,O,j.id,j)}get groupId(){return this.group.id}async fetch(){for await(let $ of this.group.messages({limit:100}))if($.id===this.id)return $.detail.get();throw new E("WhatsApp message is not available")}body=this.field("body");sender=this.field("sender");sentAt=this.field("sent_at");editedAt=this.field("edited_at");deleted=this.field("deleted");reactions=this.field("reactions");deliveryState=this.field("delivery_state");replyTo=this.mappedField("reply_to",($)=>$?C$.byId(this.client,this.group,$):void 0);attachments=this.mappedField("attachments",($)=>$.map((O)=>({ordinal:O.ordinal,state:O.state,fileName:O.file_name,mime:O.mime,size:O.size,document:O.document_id?w.byId(this.client,O.document_id):void 0})))}class YO{id;groupId;filename;kind;constructor($,O,j,x){this.id=$;this.groupId=O;this.filename=j;this.kind=x}static byId($,O){return new YO(O,$.id)}static from($,O){return new YO(O.upload_id,$.id,O.filename,O.kind)}toJSON(){return{id:this.id,groupId:this.groupId,filename:this.filename,kind:this.kind}}}class a$ extends M{group;constructor($,O,j,x){super($,j,x);this.group=O}static byId($,O,j){return new a$($,O,j)}static from($,O,j){return new a$($,O,j.id,j)}async fetch(){let O=G(await this.client.storage.linkedDelivery({path:{group_id:this.group.id},body:[this.id]})).find((j)=>j.id===this.id);if(!O)throw new E("WhatsApp send is not available");return O}state=this.field("state");errorCode=this.field("error_code");createdAt=this.field("created_at");message=this.mappedField("message_id",($)=>$?C$.byId(this.client,this.group,$):void 0);async request(){let{payload:$}=await this.detail.get(),O=$.message,j=c(O).returnType().with({type:"media"},(x)=>({type:"media",upload:YO.byId(this.group,x.upload_id),caption:x.caption??void 0})).with({type:"mutation"},(x)=>({type:"mutation",message:C$.byId(this.client,this.group,x.message_id),operation:x.operation,text:x.text??void 0})).with({type:"text"},(x)=>x).exhaustive();return{idempotencyKey:$.idempotency_key,message:j,replyTo:$.reply_to?C$.byId(this.client,this.group,$.reply_to):void 0}}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class v$ extends z${entityType="whatsapp_group";static byId($,O){return new v$($,O)}async fetch(){return G(await this.client.storage.whatsappGroup({path:{group_id:this.id}}))}name=this.field("name");canSend=this.field("can_send");sendReason=this.field("send_reason");sendingIdentity=this.field("sending_identity");unreadCount=this.field("unread_count");backfill=this.field("backfill");limits=this.field("limits");roster=this.field("roster");owner=this.mappedField("user_id",($)=>P.byId(this.client,$));async*messages($={}){yield*u(async(O)=>{let j=G(await this.client.storage.whatsappGroupMessages({path:{group_id:this.id},query:{before:O,limit:$.limit}}));return{items:j.messages.map((x)=>C$.from(this.client,this,x)),nextCursor:j.next_cursor}})}async markRead($){this.assertGroup($.groupId),await this.mutate((O)=>O.storage.whatsappGroupRead({path:{group_id:this.id},body:{message_id:$.id}}))}async permissions(){return G(await this.client.storage.whatsappGroupPermissions({path:{group_id:this.id}}))}async updatePermissions($){await this.mutate((O)=>O.storage.whatsappGroupUpdatePermissions({path:{group_id:this.id},body:$}))}async detach(){await this.mutate(($)=>$.storage.linkedDetach({path:{group_id:this.id}}))}async upload($){let O=G(await this.client.storage.linkedUpload({path:{group_id:this.id},body:{file:$}}));return YO.from(this,O)}async reply($,O){if(O.replyTo)this.assertGroup(O.replyTo.groupId);let j=c($).returnType().with({type:"text"},(S)=>S).with({type:"media"},(S)=>{return this.assertGroup(S.upload.groupId),{type:"media",upload_id:S.upload.id,caption:S.caption}}).with({type:"mutation"},(S)=>{return this.assertGroup(S.message.groupId),{type:"mutation",message_id:S.message.id,operation:S.operation,text:S.text}}).exhaustive(),x=await this.mutate((S)=>S.storage.linkedReply({path:{group_id:this.id},body:{idempotency_key:O.idempotencyKey,message:j,reply_to:O.replyTo?.id}}));return a$.from(this.client,this,x)}async sends(){return G(await this.client.storage.whatsappGroupSends({path:{group_id:this.id}})).map(($)=>a$.from(this.client,this,$))}async delivery($){for(let O of $)this.assertGroup(O instanceof a$?O.group.id:O.groupId);return G(await this.client.storage.linkedDelivery({path:{group_id:this.id},body:$.map((O)=>O.id)})).map((O)=>a$.from(this.client,this,O))}async messageAttachments($){for(let O of $)this.assertGroup(O.groupId);return G(await this.client.storage.linkedMessageAttachments({path:{group_id:this.id},body:$.map((O)=>O.id)})).map((O)=>({message:C$.byId(this.client,this,O.message_id),attachments:O.linked_attachments.map((j)=>({ordinal:j.ordinal,state:j.state,fileName:j.file_name,mime:j.mime,size:j.size,document:j.document_id?w.byId(this.client,j.document_id):void 0}))}))}async refresh(){return this.detail.clear(),await this.detail.get(),this}assertGroup($){if($!==this.id)throw Error("WhatsApp reference belongs to another group")}}class CO extends M{static byId($,O){return new CO($,O)}static from($,O){return new CO($,O.jid,O)}async fetch(){let{chats:$}=G(await this.client.storage.linkedChats()),O=$.find((j)=>j.jid===this.id);if(!O)throw new E("WhatsApp chat is not available");return O}kind=this.field("kind");name=this.field("name");lastActivityAt=this.field("lastActivityAt");archived=this.field("archived");pinned=this.field("pinned");canAdd=this.field("canAdd");cannotAddReason=this.field("cannotAddReason");group=this.mappedField("group",($)=>$?v$.byId(this.client,$.id):void 0);shared=this.mappedField("shared",($)=>$?v$.byId(this.client,$.id):void 0);async adopt(){let $=await this.mutate((O)=>O.storage.linkedAdopt({body:{group_jid:this.id}}));return v$.byId(this.client,$.group_id)}async refresh(){return this.detail.clear(),await this.detail.get(),this}}class w0{client;constructor($){this.client=$}async account(){let{account:$}=G(await this.client.storage.linkedAccount());return $?_O.from(this.client,$):void 0}async groups(){return G(await this.client.storage.whatsappGroups()).map(($)=>v$.byId(this.client,$.id))}async chats(){return G(await this.client.storage.linkedChats()).chats.map(($)=>CO.from(this.client,$))}byId($){return v$.byId(this.client,$)}}function q0($){if("properties"in $.data)return $.data.properties;if($.tag==="calendarEvent")return $.data.extra.properties;return[]}function a1($,O,j){let x=[];for(let S of q0(O)){if(S.definition.data_type!=="TAG"||S.value?.type!=="SelectOption")continue;for(let K of S.value.value){let Z=j.get(K);if(Z&&!x.some((X)=>X.label===Z.label&&X.scope===Z.scope))x.push(Z)}}switch(O.tag){case"document":return{type:"document",id:O.data.id,entity:w.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name,fileType:O.data.fileType,subType:O.data.subType?.type};case"chat":return{type:"ai_chat",id:O.data.id,entity:K$.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name};case"project":return{type:"project",id:O.data.id,entity:n.byId($,O.data.id),snapshot:O,tags:x,name:O.data.name};case"emailThread":return{type:"email",id:O.data.id,entity:R$.byId($,O.data.id),snapshot:O,tags:x,subject:O.data.name,snippet:O.data.snippet,senderName:O.data.senderName,senderEmail:O.data.senderEmail,inboxVisible:O.data.inboxVisible,isRead:O.data.isRead,isDraft:O.data.isDraft};case"channel":return{type:"channel",id:O.data.channel.id,entity:b.byId($,O.data.channel.id),snapshot:O,tags:x,name:O.data.channel.name};case"channelThread":return{type:"channel_thread",id:O.data.id,entity:new h$($,O.data.channel_id,O.data.id),snapshot:O,tags:x,channelId:O.data.channel_id};case"call":return{type:"call",id:O.data.callId,entity:Q$.byId($,O.data.callId),snapshot:O,tags:x,createdBy:O.data.createdBy};case"calendarEvent":return{type:"calendar_event",id:O.data.id,entity:$$.byId($,O.data.id),snapshot:O,tags:x,title:O.data.title,status:O.data.status,location:O.data.location,conferenceUrl:O.data.conferenceUrl,conferenceProvider:O.data.conferenceProvider,time:O.data.time};case"foreignEntity":return{type:"foreign_entity",id:O.data.id,entity:xO.byId($,O.data.id),snapshot:O,tags:x,foreignEntityId:O.data.foreignEntityId,foreignEntitySource:O.data.foreignEntitySource,metadata:O.data.metadata};default:throw Error(`Unexpected workspace entity type: ${O.tag}`)}}var i1="00000000-0000-0000-0000-000000000000",f0={document:["df","id"],project:["pf","pid"],ai_chat:["cf","cid"],email:["ef","ThreadId"],channel:["chanf","ChannelId"],channel_thread:["cthf","ThreadId"],call:["callf","CallId"],calendar_event:["calf","id"],foreign_entity:["fef","id"]},Aj=($)=>$.replace(/[A-Z]/g,(O)=>O.toLowerCase()),n1=($,O)=>$==null?O:{"&":[$,O]};function b0($,O){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`Invalid workspace ${O}: expected a filter expression.`);let j=Object.entries($),x=j[0];if(j.length!==1||x===void 0)throw Error(`Invalid workspace ${O}: use exactly one of l, &, |, !.`);let[S,K]=x;if(S==="l")return;if(S==="!"){b0(K,`${O}.!`);return}if(S!=="&"&&S!=="|")throw Error(`Invalid workspace ${O}: use l, &, | or !.`);if(!Array.isArray(K)||K.length!==2)throw Error(`Invalid workspace ${O}.${S}: expected exactly two expressions. Use {l: {...}} for a single condition; nest binary operators for three or more.`);K.forEach((Z,X)=>{b0(Z,`${O}.${S}[${X}]`)})}class Fj{client;tagSets;constructor($){this.client=$}sets(){return this.tagSets??=this.client.properties.listTags({}).then(G),this.tagSets}async tagMap(){let $=new Map;for(let O of await this.sets())for(let j of O.options)if(j.value.type==="string")$.set(j.id,{label:j.value.value,scope:O.scope==="user"?"personal":"team"});return $}async body($){for(let[S,K,Z]of[["sortBy",$.sortBy,["recently_viewed","recently_updated","recently_created"]],["emailPreset",$.emailPreset,["signal"]],["tagsMatch",$.tagsMatch,["any","all"]]])if(K!==void 0&&!Z.includes(K))throw Error(`Invalid workspace ${S}: ${K}`);if($.includeTypes!==void 0&&(!Array.isArray($.includeTypes)||$.includeTypes.some((S)=>!Object.hasOwn(f0,S))))throw Error(`Invalid workspace includeTypes. Supported values: ${Object.keys(f0).join(", ")}. Tasks use document with df: {l: {dst: 'task'}}.`);for(let S of["df","pf","cf","ef","chanf","cthf","callf","fef","calf","propf"])if($[S]!=null)b0($[S],S);if($.tags?.some((S)=>S.scope!==void 0&&S.scope!=="personal"&&S.scope!=="team"))throw Error("Invalid workspace tag scope");if($.limit!==void 0&&!Number.isFinite($.limit))throw Error("Workspace limit must be finite");let O={df:$.df,pf:$.pf,cf:$.cf,ef:$.ef,chanf:$.chanf,cthf:$.cthf,callf:$.callf,fef:$.fef,calf:$.calf,propf:$.propf,ccf:{l:{id:i1}},favorites_only:$.favoritesOnly,expand:!0,limit:Math.max(1,Math.min(500,Math.trunc($.limit??50))),sort_method:$.sortBy==="recently_viewed"?"viewed_at":$.sortBy==="recently_created"?"created_at":"updated_at",sort_direction:"desc",emailView:$.emailView??"inbox"};if($.emailPreset==="signal")O.ef={"&":[{l:{Importance:!0}},{l:{Shared:"exclude"}}]};let j=$.inbox?.trim();if(j){let{links:S}=G(await this.client.email.listLinks()),K=S.filter((X)=>Aj(X.email_address)===Aj(j)),Z=K[0];if(!Z)throw Error(`No connected inbox matches "${j}". Connected inboxes: ${S.map((X)=>X.email_address).join(", ")}.`);if(K.length>1)throw Error(`Multiple connected inboxes match "${j}"; cannot pick one.`);O.ef=n1(O.ef,{l:{Owner:Z.id}})}let x=$.includeTypes??($.emailPreset==="signal"?["email"]:void 0);if(x?.length){for(let[S,[K,Z]]of Object.entries(f0))if(!x.includes(S))O[K]={l:{[Z]:i1}}}if($.tags?.length){let S=(await this.sets()).flatMap((Y)=>{let L=Y.definition;if(!L)return[];return Y.options.flatMap((Q)=>Q.value.type==="string"?[{id:Q.id,definitionId:L.id,label:Q.value.value,scope:Y.scope==="user"?"personal":"team"}]:[])}),K=new Map;for(let Y of $.tags){let L=S.filter((Q)=>Aj(Q.label)===Aj(Y.label.trim())&&(!Y.scope||Q.scope===Y.scope));if(!L.length)throw Error(`Unknown tag "${Y.label}". Available tags: ${S.map((Q)=>`${Q.label} (${Q.scope})`).join(", ")}.`);if($.tagsMatch==="all"&&L.length>1)throw Error(`Tag "${Y.label}" is ambiguous; specify personal or team scope.`);for(let Q of L)K.set(Q.id,Q)}let X=[...K.values()].map((Y)=>({l:{pd:Y.definitionId,v:{so:Y.id}}})).reduce((Y,L)=>Y===void 0?L:{[$.tagsMatch==="all"?"&":"|"]:[Y,L]},void 0);O.propf=n1(O.propf,X)}return O}}class k0{client;constructor($){this.client=$}async page($={}){let O=new Fj(this.client);return this.fetch(O,await O.body($),$.cursor)}async*list($={}){let O=new Fj(this.client),j=await O.body($);yield*u((x)=>this.fetch(O,j,x))}async fetch($,O,j){let x=G(await this.client.storage.postItemsSoupAst({body:O,query:j?{cursor:j}:void 0})),K=x.items.some((Z)=>q0(Z).some((X)=>X.definition.data_type==="TAG"))?await $.tagMap():new Map;return{items:x.items.map((Z)=>a1(this.client,Z,K)),nextCursor:x.next_cursor,hasMore:x.next_cursor!=null}}}function s1({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var B7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},L7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},N7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Ej=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(L7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=B7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return PO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},PO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},wj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=N7(x),X=Object.entries(S).map(([Y,L])=>PO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var U7=/\{[^{}]+\}/g,z7=({path:$,url:O})=>{let j=O,x=O.match(U7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Ej({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,wj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${PO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},t1=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=z7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function g0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var e1=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var o1={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var $2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Ej({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=wj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=PO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},O2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},I7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function j2($){for(let O of $.security??[]){if(I7($,O.name))continue;let j=await e1(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var y0=($)=>t1({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:$2($.querySerializer),url:$.url}),v0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=fj($.headers,O.headers),j},T7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},fj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?T7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class qj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var x2=()=>({error:new qj,request:new qj,response:new qj}),H7=$2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),R7={"Content-Type":"application/json"},$j=($={})=>({...o1,headers:R7,parseAs:"auto",querySerializer:H7,...$});var h0=($={})=>{let O=v0($j(),$),j=()=>({...O}),x=(G)=>{return O=v0(O,G),j()},S=x2(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:fj(O.headers,G.headers),serializedBody:void 0};if(J.security)await j2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=y0(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:g0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?O2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return s1({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:g0(I),url:z})};return{buildUrl:(G)=>y0({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var S2=h0($j());class Z2{client;constructor($){this.client=$?.client??S2}}class X2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class bj extends Z2{static __registry=new X2;constructor($){super($);bj.__registry.set(this,$?.key)}discoverAgentCapabilitiesHandler($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-capabilities/discover",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentCodingPreferences($){return($?.client??this.client).get({url:"/agent-coding-preferences",...$})}putAgentCodingPreferences($){return($.client??this.client).put({url:"/agent-coding-preferences",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAgentConversations($){return($.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}",...$})}startFreshAgentConversation($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}/{bot_id}/start-fresh",...$,headers:{"Content-Type":"application/json",...$.headers}})}retryAgentConversationTurn($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}/{bot_id}/turns/{source}/retry",...$,headers:{"Content-Type":"application/json",...$.headers}})}loadAgentModelsHandler($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-models/load",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAgentRepositories($){return($?.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-repositories",...$})}listAgentRepositoryBranches($){return($.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-repositories/branches",...$})}getAgentSandboxSize($){return($?.client??this.client).get({url:"/agent-sandbox-size",...$})}putAgentSandboxSize($){return($.client??this.client).put({url:"/agent-sandbox-size",...$,headers:{"Content-Type":"application/json",...$.headers}})}createAgentSession($){return($.client??this.client).post({url:"/agent-sessions",...$,headers:{"Content-Type":"application/json",...$.headers}})}agentSessionsForPullRequest($){return($.client??this.client).post({url:"/agent-sessions/by-pull-request",...$,headers:{"Content-Type":"application/json",...$.headers}})}agentSessionsForPullRequests($){return($.client??this.client).post({url:"/agent-sessions/by-pull-requests",...$,headers:{"Content-Type":"application/json",...$.headers}})}previewAgentSessions($){return($.client??this.client).post({url:"/agent-sessions/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}warmAgentSessionHandler($){return($.client??this.client).post({url:"/agent-sessions/warm",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteAgentSession($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}",...$})}getAgentSession($){return($.client??this.client).get({url:"/agent-sessions/{session_id}",...$})}reportAgentSessionAppConnected($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/app-connections",...$,headers:{"Content-Type":"application/json",...$.headers}})}setAgentSessionArchived($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/archived",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionChanges($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/changes",...$})}getAgentSessionChangesPatch($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/changes/patch",...$})}refreshAgentSessionChanges($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/changes/refresh",...$})}getCodeExecution($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/code-executions/{execution_id}",...$})}listExecutionReviews($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/code-executions/{execution_id}/reviews",...$})}controlAgentSession($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/control",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionLog($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/log",...$})}getAgentSessionFoldedLog($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/log/folded",...$})}renameAgentSession($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionPermissions($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/permissions",...$})}updateAgentSessionPermissions($){return($.client??this.client).patch({url:"/agent-sessions/{session_id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}unlinkAgentSessionPullRequest($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}/pull-requests",...$})}listAgentSessionPullRequests($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/pull-requests",...$})}linkAgentSessionPullRequest($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/pull-requests",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionQueue($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/queue",...$})}removeQueuedAction($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}/queue/{action_id}",...$})}editQueuedAction($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/queue/{action_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}steerQueuedAction($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/queue/{action_id}/steer",...$})}createSessionReview($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/reviews",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSessionReview($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/reviews/{review_id}",...$})}decideSessionReview($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/reviews/{review_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}putAgentSessionSandboxSize($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/sandbox-size",...$,headers:{"Content-Type":"application/json",...$.headers}})}answerAgentSessionToolApproval($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/tool-approvals/{approval_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function K2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var B7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},L7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},N7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Ej=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(L7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=B7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return PO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},PO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},wj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=N7(x),X=Object.entries(S).map(([Y,L])=>PO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var U7=/\{[^{}]+\}/g,z7=({path:$,url:O})=>{let j=O,x=O.match(U7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Ej({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,wj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${PO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},t1=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=z7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function g0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var e1=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var o1={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var $2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Ej({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=wj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=PO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},O2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},I7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function j2($){for(let O of $.security??[]){if(I7($,O.name))continue;let j=await e1(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var y0=($)=>t1({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:$2($.querySerializer),url:$.url}),v0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=fj($.headers,O.headers),j},T7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},fj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?T7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class qj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var x2=()=>({error:new qj,request:new qj,response:new qj}),H7=$2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),R7={"Content-Type":"application/json"},$j=($={})=>({...o1,headers:R7,parseAs:"auto",querySerializer:H7,...$});var h0=($={})=>{let O=v0($j(),$),j=()=>({...O}),x=(Q)=>{return O=v0(O,Q),j()},S=x2(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:fj(O.headers,Q.headers),serializedBody:void 0};if(J.security)await j2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=y0(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:g0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?O2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return s1({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:g0(I),url:z})};return{buildUrl:(Q)=>y0({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var S2=h0($j());class Z2{client;constructor($){this.client=$?.client??S2}}class X2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class bj extends Z2{static __registry=new X2;constructor($){super($);bj.__registry.set(this,$?.key)}discoverAgentCapabilitiesHandler($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-capabilities/discover",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentCodingPreferences($){return($?.client??this.client).get({url:"/agent-coding-preferences",...$})}putAgentCodingPreferences($){return($.client??this.client).put({url:"/agent-coding-preferences",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAgentConversations($){return($.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}",...$})}startFreshAgentConversation($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}/{bot_id}/start-fresh",...$,headers:{"Content-Type":"application/json",...$.headers}})}retryAgentConversationTurn($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-conversations/{channel_id}/{bot_id}/turns/{source}/retry",...$,headers:{"Content-Type":"application/json",...$.headers}})}loadAgentModelsHandler($){return($.client??this.client).post({security:[{scheme:"bearer",type:"http"}],url:"/agent-models/load",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAgentRepositories($){return($?.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-repositories",...$})}listAgentRepositoryBranches($){return($.client??this.client).get({security:[{scheme:"bearer",type:"http"}],url:"/agent-repositories/branches",...$})}getAgentSandboxSize($){return($?.client??this.client).get({url:"/agent-sandbox-size",...$})}putAgentSandboxSize($){return($.client??this.client).put({url:"/agent-sandbox-size",...$,headers:{"Content-Type":"application/json",...$.headers}})}createAgentSession($){return($.client??this.client).post({url:"/agent-sessions",...$,headers:{"Content-Type":"application/json",...$.headers}})}agentSessionsForPullRequest($){return($.client??this.client).post({url:"/agent-sessions/by-pull-request",...$,headers:{"Content-Type":"application/json",...$.headers}})}agentSessionsForPullRequests($){return($.client??this.client).post({url:"/agent-sessions/by-pull-requests",...$,headers:{"Content-Type":"application/json",...$.headers}})}previewAgentSessions($){return($.client??this.client).post({url:"/agent-sessions/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}warmAgentSessionHandler($){return($.client??this.client).post({url:"/agent-sessions/warm",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteAgentSession($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}",...$})}getAgentSession($){return($.client??this.client).get({url:"/agent-sessions/{session_id}",...$})}reportAgentSessionAppConnected($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/app-connections",...$,headers:{"Content-Type":"application/json",...$.headers}})}setAgentSessionArchived($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/archived",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionChanges($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/changes",...$})}getAgentSessionChangesPatch($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/changes/patch",...$})}refreshAgentSessionChanges($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/changes/refresh",...$})}getCodeExecution($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/code-executions/{execution_id}",...$})}listExecutionReviews($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/code-executions/{execution_id}/reviews",...$})}controlAgentSession($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/control",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionLog($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/log",...$})}getAgentSessionFoldedLog($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/log/folded",...$})}renameAgentSession($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionPermissions($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/permissions",...$})}updateAgentSessionPermissions($){return($.client??this.client).patch({url:"/agent-sessions/{session_id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}unlinkAgentSessionPullRequest($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}/pull-requests",...$})}listAgentSessionPullRequests($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/pull-requests",...$})}linkAgentSessionPullRequest($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/pull-requests",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAgentSessionQueue($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/queue",...$})}removeQueuedAction($){return($.client??this.client).delete({url:"/agent-sessions/{session_id}/queue/{action_id}",...$})}editQueuedAction($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/queue/{action_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}steerQueuedAction($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/queue/{action_id}/steer",...$})}createSessionReview($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/reviews",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSessionReview($){return($.client??this.client).get({url:"/agent-sessions/{session_id}/reviews/{review_id}",...$})}decideSessionReview($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/reviews/{review_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}putAgentSessionSandboxSize($){return($.client??this.client).put({url:"/agent-sessions/{session_id}/sandbox-size",...$,headers:{"Content-Type":"application/json",...$.headers}})}answerAgentSessionToolApproval($){return($.client??this.client).post({url:"/agent-sessions/{session_id}/tool-approvals/{approval_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function K2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var D7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},C7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},_7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},kj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(C7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=D7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return MO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},MO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},gj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=_7(x),X=Object.entries(S).map(([Y,L])=>MO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var P7=/\{[^{}]+\}/g,M7=({path:$,url:O})=>{let j=O,x=O.match(P7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,kj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,gj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${MO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},Y2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=M7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function m0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var Q2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var G2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var J2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=kj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=gj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=MO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},V2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},A7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function W2($){for(let O of $.security??[]){if(A7($,O.name))continue;let j=await Q2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var c0=($)=>Y2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:J2($.querySerializer),url:$.url}),u0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=vj($.headers,O.headers),j},F7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},vj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?F7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class yj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var B2=()=>({error:new yj,request:new yj,response:new yj}),E7=J2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),w7={"Content-Type":"application/json"},Oj=($={})=>({...G2,headers:w7,parseAs:"auto",querySerializer:E7,...$});var d0=($={})=>{let O=u0(Oj(),$),j=()=>({...O}),x=(G)=>{return O=u0(O,G),j()},S=B2(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:vj(O.headers,G.headers),serializedBody:void 0};if(J.security)await W2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=c0(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:m0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?V2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return K2({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:m0(I),url:z})};return{buildUrl:(G)=>c0({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var L2=d0(Oj());class N2{client;constructor($){this.client=$?.client??L2}}class U2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class hj extends N2{static __registry=new U2;constructor($){super($);hj.__registry.set(this,$?.key)}deleteAgentApiKey($){return($.client??this.client).delete({url:"/agents/{agent_id}/api-key",...$})}getAgentApiKey($){return($.client??this.client).get({url:"/agents/{agent_id}/api-key",...$})}putAgentApiKey($){return($.client??this.client).put({url:"/agents/{agent_id}/api-key",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAiBillingAutoReload($){return($.client??this.client).patch({url:"/ai-billing/auto-reload",...$,headers:{"Content-Type":"application/json",...$.headers}})}createAiCreditCheckout($){return($.client??this.client).post({url:"/ai-billing/credits/checkout",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAiBillingOverage($){return($.client??this.client).patch({url:"/ai-billing/overage",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAiBillingPlans($){return($?.client??this.client).get({url:"/ai-billing/plans",...$})}getAiBillingSummary($){return($?.client??this.client).get({url:"/ai-billing/summary",...$})}disconnectCodex($){return($?.client??this.client).delete({url:"/codex",...$})}getCodexConnection($){return($?.client??this.client).get({url:"/codex",...$})}configureCodex($){return($.client??this.client).put({url:"/codex/config",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCodexEnvironments($){return($?.client??this.client).get({url:"/codex/environments",...$})}startCodexLogin($){return($?.client??this.client).post({url:"/codex/login",...$})}cancelCodexLogin($){return($.client??this.client).delete({url:"/codex/login/{attempt_id}",...$})}pollCodexLogin($){return($.client??this.client).get({url:"/codex/login/{attempt_id}",...$})}deleteCursorApiKey($){return($?.client??this.client).delete({url:"/cursor-api-key",...$})}getCursorApiKey($){return($?.client??this.client).get({url:"/cursor-api-key",...$})}putCursorApiKey($){return($.client??this.client).put({url:"/cursor-api-key",...$,headers:{"Content-Type":"application/json",...$.headers}})}putCursorDefaultModel($){return($.client??this.client).put({url:"/cursor-api-key/default-model",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCursorModels($){return($?.client??this.client).get({url:"/cursor-api-key/models",...$})}verifyFusionauthUserEmail($){return($.client??this.client).get({url:"/email/fusionauth/verify/{verification_id}",...$})}resendFusionauthVerifyUserEmail($){return($.client??this.client).post({url:"/email/fusionauth_resend",...$,headers:{"Content-Type":"application/json",...$.headers}})}generateEmailLink($){return($.client??this.client).post({url:"/email/generate/link",...$,headers:{"Content-Type":"application/json",...$.headers}})}verifyEmailLink($){return($.client??this.client).get({url:"/email/verify/{verification_id}",...$})}setGithubPullRequestDraft($){return($.client??this.client).post({url:"/github_pull_requests/draft",...$,headers:{"Content-Type":"application/json",...$.headers}})}enrichGithubPullRequests($){return($.client??this.client).post({url:"/github_pull_requests/enrich",...$,headers:{"Content-Type":"application/json",...$.headers}})}mergeGithubPullRequest($){return($.client??this.client).post({url:"/github_pull_requests/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}getGithubPullRequestMergeability($){return($.client??this.client).post({url:"/github_pull_requests/mergeability",...$,headers:{"Content-Type":"application/json",...$.headers}})}listGtmInviteLinks($){return($?.client??this.client).get({url:"/gtm-invite/links",...$})}createGtmInviteLink($){return($.client??this.client).post({url:"/gtm-invite/links",...$,headers:{"Content-Type":"application/json",...$.headers}})}revokeGtmInviteLink($){return($.client??this.client).delete({url:"/gtm-invite/links/{id}",...$})}getGtmInviteOffer($){return($?.client??this.client).get({url:"/gtm-invite/offer",...$})}resolveGtmInviteLink($){return($.client??this.client).get({url:"/gtm-invite/public/{token}",...$})}redeemGtmInviteLink($){return($.client??this.client).post({url:"/gtm-invite/redeem",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}macroApiToken($){return($.client??this.client).get({url:"/jwt/macro_api_token",...$})}refresh($){return($?.client??this.client).post({url:"/jwt/refresh",...$})}createInProgressLink($){return($?.client??this.client).post({url:"/link",...$})}emailConnectionProviders($){return($?.client??this.client).get({url:"/link/email/providers",...$})}deleteGithubLink($){return($?.client??this.client).delete({url:"/link/github",...$})}initGithubLink($){return($.client??this.client).post({url:"/link/github",...$})}checkGithubLinkStatus($){return($?.client??this.client).get({url:"/link/github/status",...$})}initGmailLink($){return($.client??this.client).post({url:"/link/gmail",...$})}checkGmailLinkStatus($){return($?.client??this.client).get({url:"/link/gmail/status",...$})}initOutlookLink($){return($?.client??this.client).post({url:"/link/outlook",...$})}appleLogin($){return($.client??this.client).post({url:"/login/apple",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordLogin($){return($.client??this.client).post({url:"/login/password",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordlessLogin($){return($.client??this.client).post({url:"/login/passwordless",...$,headers:{"Content-Type":"application/json",...$.headers}})}ssoLogin($){return($.client??this.client).get({url:"/login/sso",...$})}logout($){return($?.client??this.client).post({url:"/logout",...$})}createMergeRequest($){return($.client??this.client).post({url:"/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}verifyMergeRequest($){return($.client??this.client).get({url:"/merge/verify/{code}",...$})}sendMobileWelcomeEmail($){return($.client??this.client).post({url:"/mobile-welcome-email",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordlessCallback($){return($.client??this.client).get({url:"/oauth/passwordless/{code}",...$})}oauthRedirect($){return($?.client??this.client).get({url:"/oauth/redirect",...$})}oauth2Callback($){return($.client??this.client).get({url:"/oauth2/{provider}/callback",...$})}getPermissions($){return($?.client??this.client).get({url:"/permissions",...$})}getUserPermissions($){return($?.client??this.client).get({url:"/permissions/me",...$})}getReferralCode($){return($?.client??this.client).get({url:"/referral/code",...$})}sendReferralCode($){return($.client??this.client).post({url:"/referral/send",...$,headers:{"Content-Type":"application/json",...$.headers}})}sessionCreation($){return($?.client??this.client).post({url:"/session",...$})}sessionLogin($){return($.client??this.client).get({url:"/session/login/{session_code}",...$})}deleteTeam($){return($?.client??this.client).delete({url:"/team",...$})}getTeam($){return($?.client??this.client).get({url:"/team",...$})}patchTeam($){return($.client??this.client).patch({url:"/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}createTeam($){return($.client??this.client).post({url:"/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}toggleTeamAutoJoinDomain($){return($?.client??this.client).post({url:"/team/auto-join-domain/toggle",...$})}patchTeamCrmSettings($){return($.client??this.client).patch({url:"/team/crm",...$,headers:{"Content-Type":"application/json",...$.headers}})}inviteToTeam($){return($.client??this.client).post({url:"/team/invite",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteTeamInviteLink($){return($?.client??this.client).delete({url:"/team/invite-link",...$})}getTeamInviteLink($){return($?.client??this.client).get({url:"/team/invite-link",...$})}createTeamInviteLink($){return($?.client??this.client).post({url:"/team/invite-link",...$})}joinTeamByInviteLink($){return($.client??this.client).post({url:"/team/invite-link/join",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTeamByInviteLink($){return($.client??this.client).post({url:"/team/invite-link/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteTeamInviteHandler($){return($.client??this.client).delete({url:"/team/invite/{team_invite_id}",...$})}getTeamInvites($){return($?.client??this.client).get({url:"/team/invites",...$})}rejectInvitation($){return($.client??this.client).delete({url:"/team/join/{team_invite_id}",...$})}joinTeam($){return($.client??this.client).get({url:"/team/join/{team_invite_id}",...$})}patchTeamMemberPlan($){return($.client??this.client).patch({url:"/team/members/{member_user_id}/plan",...$,headers:{"Content-Type":"application/json",...$.headers}})}toggleTeamNonAdminInvites($){return($?.client??this.client).post({url:"/team/non-admin-invites/toggle",...$})}removeUserFromTeam($){return($.client??this.client).delete({url:"/team/remove/{remove_user_id}",...$})}getUserTeams($){return($?.client??this.client).get({url:"/team/user",...$})}getUserInvites($){return($?.client??this.client).get({url:"/team/user/invites",...$})}getUserNames($){return($.client??this.client).post({url:"/user/get_names",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserNamesWithEmail($){return($.client??this.client).post({url:"/user/get_names_with_email",...$,headers:{"Content-Type":"application/json",...$.headers}})}patchUserGroup($){return($.client??this.client).patch({url:"/user/group",...$,headers:{"Content-Type":"application/json",...$.headers}})}getLegacyUserPermissions($){return($?.client??this.client).get({url:"/user/legacy_user_permissions",...$})}getUserLinkExists($){return($.client??this.client).get({url:"/user/link_exists",...$})}deleteUser($){return($?.client??this.client).delete({url:"/user/me",...$})}getUserInfo($){return($?.client??this.client).get({url:"/user/me",...$})}getUserName($){return($?.client??this.client).get({url:"/user/name",...$})}putUserName($){return($?.client??this.client).put({url:"/user/name",...$})}patchUserOnboarding($){return($.client??this.client).patch({url:"/user/onboarding",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserOrganization($){return($?.client??this.client).get({url:"/user/organization",...$})}putProfilePicture($){return($.client??this.client).put({url:"/user/profile_picture",...$})}postProfilePictures($){return($.client??this.client).post({url:"/user/profile_pictures",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserQuota($){return($?.client??this.client).get({url:"/user/quota",...$})}createCheckoutSessionV2($){return($.client??this.client).post({url:"/user/stripe/checkoutv2",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSubscriptionStatus($){return($?.client??this.client).get({url:"/user/stripe/plan",...$})}changePlan($){return($.client??this.client).post({url:"/user/stripe/plan",...$,headers:{"Content-Type":"application/json",...$.headers}})}createPortalSession($){return($.client??this.client).post({url:"/user/stripe/portal",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTrialEligibility($){return($?.client??this.client).get({url:"/user/stripe/trial_eligibility",...$})}patchUserTutorial($){return($.client??this.client).patch({url:"/user/tutorial",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function z2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var D7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},_7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},C7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},kj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(_7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=D7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return MO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},MO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},gj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=C7(x),X=Object.entries(S).map(([Y,L])=>MO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var P7=/\{[^{}]+\}/g,M7=({path:$,url:O})=>{let j=O,x=O.match(P7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,kj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,gj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${MO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},Y2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=M7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function m0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var G2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var Q2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var J2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=kj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=gj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=MO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},V2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},A7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function W2($){for(let O of $.security??[]){if(A7($,O.name))continue;let j=await G2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var c0=($)=>Y2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:J2($.querySerializer),url:$.url}),u0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=vj($.headers,O.headers),j},F7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},vj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?F7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class yj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var B2=()=>({error:new yj,request:new yj,response:new yj}),E7=J2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),w7={"Content-Type":"application/json"},Oj=($={})=>({...Q2,headers:w7,parseAs:"auto",querySerializer:E7,...$});var d0=($={})=>{let O=u0(Oj(),$),j=()=>({...O}),x=(Q)=>{return O=u0(O,Q),j()},S=B2(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:vj(O.headers,Q.headers),serializedBody:void 0};if(J.security)await W2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=c0(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:m0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?V2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return K2({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:m0(I),url:z})};return{buildUrl:(Q)=>c0({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var L2=d0(Oj());class N2{client;constructor($){this.client=$?.client??L2}}class U2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class hj extends N2{static __registry=new U2;constructor($){super($);hj.__registry.set(this,$?.key)}deleteAgentApiKey($){return($.client??this.client).delete({url:"/agents/{agent_id}/api-key",...$})}getAgentApiKey($){return($.client??this.client).get({url:"/agents/{agent_id}/api-key",...$})}putAgentApiKey($){return($.client??this.client).put({url:"/agents/{agent_id}/api-key",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAiBillingAutoReload($){return($.client??this.client).patch({url:"/ai-billing/auto-reload",...$,headers:{"Content-Type":"application/json",...$.headers}})}createAiCreditCheckout($){return($.client??this.client).post({url:"/ai-billing/credits/checkout",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAiBillingOverage($){return($.client??this.client).patch({url:"/ai-billing/overage",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAiBillingPlans($){return($?.client??this.client).get({url:"/ai-billing/plans",...$})}getAiBillingSummary($){return($?.client??this.client).get({url:"/ai-billing/summary",...$})}disconnectCodex($){return($?.client??this.client).delete({url:"/codex",...$})}getCodexConnection($){return($?.client??this.client).get({url:"/codex",...$})}configureCodex($){return($.client??this.client).put({url:"/codex/config",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCodexEnvironments($){return($?.client??this.client).get({url:"/codex/environments",...$})}startCodexLogin($){return($?.client??this.client).post({url:"/codex/login",...$})}cancelCodexLogin($){return($.client??this.client).delete({url:"/codex/login/{attempt_id}",...$})}pollCodexLogin($){return($.client??this.client).get({url:"/codex/login/{attempt_id}",...$})}deleteCursorApiKey($){return($?.client??this.client).delete({url:"/cursor-api-key",...$})}getCursorApiKey($){return($?.client??this.client).get({url:"/cursor-api-key",...$})}putCursorApiKey($){return($.client??this.client).put({url:"/cursor-api-key",...$,headers:{"Content-Type":"application/json",...$.headers}})}putCursorDefaultModel($){return($.client??this.client).put({url:"/cursor-api-key/default-model",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCursorModels($){return($?.client??this.client).get({url:"/cursor-api-key/models",...$})}verifyFusionauthUserEmail($){return($.client??this.client).get({url:"/email/fusionauth/verify/{verification_id}",...$})}resendFusionauthVerifyUserEmail($){return($.client??this.client).post({url:"/email/fusionauth_resend",...$,headers:{"Content-Type":"application/json",...$.headers}})}generateEmailLink($){return($.client??this.client).post({url:"/email/generate/link",...$,headers:{"Content-Type":"application/json",...$.headers}})}verifyEmailLink($){return($.client??this.client).get({url:"/email/verify/{verification_id}",...$})}setGithubPullRequestDraft($){return($.client??this.client).post({url:"/github_pull_requests/draft",...$,headers:{"Content-Type":"application/json",...$.headers}})}enrichGithubPullRequests($){return($.client??this.client).post({url:"/github_pull_requests/enrich",...$,headers:{"Content-Type":"application/json",...$.headers}})}mergeGithubPullRequest($){return($.client??this.client).post({url:"/github_pull_requests/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}getGithubPullRequestMergeability($){return($.client??this.client).post({url:"/github_pull_requests/mergeability",...$,headers:{"Content-Type":"application/json",...$.headers}})}listGtmInviteLinks($){return($?.client??this.client).get({url:"/gtm-invite/links",...$})}createGtmInviteLink($){return($.client??this.client).post({url:"/gtm-invite/links",...$,headers:{"Content-Type":"application/json",...$.headers}})}revokeGtmInviteLink($){return($.client??this.client).delete({url:"/gtm-invite/links/{id}",...$})}getGtmInviteOffer($){return($?.client??this.client).get({url:"/gtm-invite/offer",...$})}resolveGtmInviteLink($){return($.client??this.client).get({url:"/gtm-invite/public/{token}",...$})}redeemGtmInviteLink($){return($.client??this.client).post({url:"/gtm-invite/redeem",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}macroApiToken($){return($.client??this.client).get({url:"/jwt/macro_api_token",...$})}refresh($){return($?.client??this.client).post({url:"/jwt/refresh",...$})}createInProgressLink($){return($?.client??this.client).post({url:"/link",...$})}emailConnectionProviders($){return($?.client??this.client).get({url:"/link/email/providers",...$})}deleteGithubLink($){return($?.client??this.client).delete({url:"/link/github",...$})}initGithubLink($){return($.client??this.client).post({url:"/link/github",...$})}checkGithubLinkStatus($){return($?.client??this.client).get({url:"/link/github/status",...$})}initGmailLink($){return($.client??this.client).post({url:"/link/gmail",...$})}checkGmailLinkStatus($){return($?.client??this.client).get({url:"/link/gmail/status",...$})}initOutlookLink($){return($?.client??this.client).post({url:"/link/outlook",...$})}appleLogin($){return($.client??this.client).post({url:"/login/apple",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordLogin($){return($.client??this.client).post({url:"/login/password",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordlessLogin($){return($.client??this.client).post({url:"/login/passwordless",...$,headers:{"Content-Type":"application/json",...$.headers}})}ssoLogin($){return($.client??this.client).get({url:"/login/sso",...$})}logout($){return($?.client??this.client).post({url:"/logout",...$})}createMergeRequest($){return($.client??this.client).post({url:"/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}verifyMergeRequest($){return($.client??this.client).get({url:"/merge/verify/{code}",...$})}sendMobileWelcomeEmail($){return($.client??this.client).post({url:"/mobile-welcome-email",...$,headers:{"Content-Type":"application/json",...$.headers}})}passwordlessCallback($){return($.client??this.client).get({url:"/oauth/passwordless/{code}",...$})}oauthRedirect($){return($?.client??this.client).get({url:"/oauth/redirect",...$})}oauth2Callback($){return($.client??this.client).get({url:"/oauth2/{provider}/callback",...$})}getPermissions($){return($?.client??this.client).get({url:"/permissions",...$})}getUserPermissions($){return($?.client??this.client).get({url:"/permissions/me",...$})}getReferralCode($){return($?.client??this.client).get({url:"/referral/code",...$})}sendReferralCode($){return($.client??this.client).post({url:"/referral/send",...$,headers:{"Content-Type":"application/json",...$.headers}})}sessionCreation($){return($?.client??this.client).post({url:"/session",...$})}sessionLogin($){return($.client??this.client).get({url:"/session/login/{session_code}",...$})}deleteTeam($){return($?.client??this.client).delete({url:"/team",...$})}getTeam($){return($?.client??this.client).get({url:"/team",...$})}patchTeam($){return($.client??this.client).patch({url:"/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}createTeam($){return($.client??this.client).post({url:"/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}toggleTeamAutoJoinDomain($){return($?.client??this.client).post({url:"/team/auto-join-domain/toggle",...$})}patchTeamCrmSettings($){return($.client??this.client).patch({url:"/team/crm",...$,headers:{"Content-Type":"application/json",...$.headers}})}inviteToTeam($){return($.client??this.client).post({url:"/team/invite",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteTeamInviteLink($){return($?.client??this.client).delete({url:"/team/invite-link",...$})}getTeamInviteLink($){return($?.client??this.client).get({url:"/team/invite-link",...$})}createTeamInviteLink($){return($?.client??this.client).post({url:"/team/invite-link",...$})}joinTeamByInviteLink($){return($.client??this.client).post({url:"/team/invite-link/join",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTeamByInviteLink($){return($.client??this.client).post({url:"/team/invite-link/team",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteTeamInviteHandler($){return($.client??this.client).delete({url:"/team/invite/{team_invite_id}",...$})}getTeamInvites($){return($?.client??this.client).get({url:"/team/invites",...$})}rejectInvitation($){return($.client??this.client).delete({url:"/team/join/{team_invite_id}",...$})}joinTeam($){return($.client??this.client).get({url:"/team/join/{team_invite_id}",...$})}patchTeamMemberPlan($){return($.client??this.client).patch({url:"/team/members/{member_user_id}/plan",...$,headers:{"Content-Type":"application/json",...$.headers}})}toggleTeamNonAdminInvites($){return($?.client??this.client).post({url:"/team/non-admin-invites/toggle",...$})}removeUserFromTeam($){return($.client??this.client).delete({url:"/team/remove/{remove_user_id}",...$})}getUserTeams($){return($?.client??this.client).get({url:"/team/user",...$})}getUserInvites($){return($?.client??this.client).get({url:"/team/user/invites",...$})}getUserNames($){return($.client??this.client).post({url:"/user/get_names",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserNamesWithEmail($){return($.client??this.client).post({url:"/user/get_names_with_email",...$,headers:{"Content-Type":"application/json",...$.headers}})}patchUserGroup($){return($.client??this.client).patch({url:"/user/group",...$,headers:{"Content-Type":"application/json",...$.headers}})}getLegacyUserPermissions($){return($?.client??this.client).get({url:"/user/legacy_user_permissions",...$})}getUserLinkExists($){return($.client??this.client).get({url:"/user/link_exists",...$})}deleteUser($){return($?.client??this.client).delete({url:"/user/me",...$})}getUserInfo($){return($?.client??this.client).get({url:"/user/me",...$})}getUserName($){return($?.client??this.client).get({url:"/user/name",...$})}putUserName($){return($?.client??this.client).put({url:"/user/name",...$})}patchUserOnboarding($){return($.client??this.client).patch({url:"/user/onboarding",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserOrganization($){return($?.client??this.client).get({url:"/user/organization",...$})}putProfilePicture($){return($.client??this.client).put({url:"/user/profile_picture",...$})}postProfilePictures($){return($.client??this.client).post({url:"/user/profile_pictures",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUserQuota($){return($?.client??this.client).get({url:"/user/quota",...$})}createCheckoutSessionV2($){return($.client??this.client).post({url:"/user/stripe/checkoutv2",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSubscriptionStatus($){return($?.client??this.client).get({url:"/user/stripe/plan",...$})}changePlan($){return($.client??this.client).post({url:"/user/stripe/plan",...$,headers:{"Content-Type":"application/json",...$.headers}})}createPortalSession($){return($.client??this.client).post({url:"/user/stripe/portal",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTrialEligibility($){return($?.client??this.client).get({url:"/user/stripe/trial_eligibility",...$})}patchUserTutorial($){return($.client??this.client).patch({url:"/user/tutorial",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function z2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var q7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},f7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},b7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},mj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(f7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=q7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return AO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},AO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},cj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=b7(x),X=Object.entries(S).map(([Y,L])=>AO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var k7=/\{[^{}]+\}/g,g7=({path:$,url:O})=>{let j=O,x=O.match(k7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,mj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,cj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${AO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},I2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=g7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function l0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var T2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var H2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var R2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=mj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=cj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=AO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},D2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},y7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function C2($){for(let O of $.security??[]){if(y7($,O.name))continue;let j=await T2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var r0=($)=>I2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:R2($.querySerializer),url:$.url}),p0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=dj($.headers,O.headers),j},v7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},dj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?v7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class uj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var _2=()=>({error:new uj,request:new uj,response:new uj}),h7=R2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),m7={"Content-Type":"application/json"},jj=($={})=>({...H2,headers:m7,parseAs:"auto",querySerializer:h7,...$});var a0=($={})=>{let O=p0(jj(),$),j=()=>({...O}),x=(G)=>{return O=p0(O,G),j()},S=_2(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:dj(O.headers,G.headers),serializedBody:void 0};if(J.security)await C2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=r0(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:l0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?D2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return z2({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:l0(I),url:z})};return{buildUrl:(G)=>r0({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var P2=a0(jj());class M2{client;constructor($){this.client=$?.client??P2}}class A2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class lj extends M2{static __registry=new A2;constructor($){super($);lj.__registry.set(this,$?.key)}getAvailabilityCalendars($){return($?.client??this.client).get({url:"/availability-calendars",...$})}setAvailabilityCalendar($){return($.client??this.client).put({url:"/availability-calendars/{calendar_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCalendars($){return($?.client??this.client).get({url:"/calendars",...$})}createCalendarEvent($){return($.client??this.client).post({url:"/events",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCalendarEvent($){return($.client??this.client).delete({url:"/events/{event_id}",...$})}updateCalendarEvent($){return($.client??this.client).patch({url:"/events/{event_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}copyCalendarEvent($){return($.client??this.client).post({url:"/events/{event_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}inviteCalendarEventGuests($){return($.client??this.client).post({url:"/events/{event_id}/guests",...$,headers:{"Content-Type":"application/json",...$.headers}})}eventNotes($){return($.client??this.client).get({url:"/events/{event_id}/notes",...$})}unlinkEventNote($){return($.client??this.client).delete({url:"/events/{event_id}/notes/{document_id}",...$})}linkEventNote($){return($.client??this.client).put({url:"/events/{event_id}/notes/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}calendarEventProviderUrl($){return($.client??this.client).get({url:"/events/{event_id}/provider-url",...$})}prepareCalendarReplacement($){return($.client??this.client).post({url:"/events/{event_id}/replacement",...$,headers:{"Content-Type":"application/json",...$.headers}})}rsvpCalendarEvent($){return($.client??this.client).put({url:"/events/{event_id}/rsvp",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}respondToJoinRequest($){return($.client??this.client).put({url:"/join-requests/{request_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}noteDocuments($){return($?.client??this.client).get({url:"/meeting-notes/documents",...$})}documentNoteLinks($){return($.client??this.client).get({url:"/meeting-notes/documents/{document_id}/links",...$})}discardCalendarReplacement($){return($.client??this.client).delete({url:"/replacements/{operation_id}",...$})}calendarReplacementStatus($){return($.client??this.client).get({url:"/replacements/{operation_id}",...$})}confirmCalendarReplacement($){return($.client??this.client).post({url:"/replacements/{operation_id}/confirm",...$})}getTeamSharing($){return($?.client??this.client).get({url:"/team-sharing",...$})}setTeamSharing($){return($.client??this.client).put({url:"/team-sharing",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function F2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var q7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},f7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},b7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},mj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(f7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=q7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return AO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},AO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},cj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=b7(x),X=Object.entries(S).map(([Y,L])=>AO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var k7=/\{[^{}]+\}/g,g7=({path:$,url:O})=>{let j=O,x=O.match(k7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,mj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,cj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${AO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},I2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=g7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function l0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var T2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var H2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var R2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=mj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=cj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=AO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},D2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},y7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function _2($){for(let O of $.security??[]){if(y7($,O.name))continue;let j=await T2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var r0=($)=>I2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:R2($.querySerializer),url:$.url}),p0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=dj($.headers,O.headers),j},v7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},dj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?v7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class uj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var C2=()=>({error:new uj,request:new uj,response:new uj}),h7=R2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),m7={"Content-Type":"application/json"},jj=($={})=>({...H2,headers:m7,parseAs:"auto",querySerializer:h7,...$});var a0=($={})=>{let O=p0(jj(),$),j=()=>({...O}),x=(Q)=>{return O=p0(O,Q),j()},S=C2(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:dj(O.headers,Q.headers),serializedBody:void 0};if(J.security)await _2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=r0(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:l0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?D2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return z2({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:l0(I),url:z})};return{buildUrl:(Q)=>r0({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var P2=a0(jj());class M2{client;constructor($){this.client=$?.client??P2}}class A2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class lj extends M2{static __registry=new A2;constructor($){super($);lj.__registry.set(this,$?.key)}getAvailabilityCalendars($){return($?.client??this.client).get({url:"/availability-calendars",...$})}setAvailabilityCalendar($){return($.client??this.client).put({url:"/availability-calendars/{calendar_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCalendars($){return($?.client??this.client).get({url:"/calendars",...$})}createCalendarEvent($){return($.client??this.client).post({url:"/events",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCalendarEvent($){return($.client??this.client).delete({url:"/events/{event_id}",...$})}updateCalendarEvent($){return($.client??this.client).patch({url:"/events/{event_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}copyCalendarEvent($){return($.client??this.client).post({url:"/events/{event_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}inviteCalendarEventGuests($){return($.client??this.client).post({url:"/events/{event_id}/guests",...$,headers:{"Content-Type":"application/json",...$.headers}})}eventNotes($){return($.client??this.client).get({url:"/events/{event_id}/notes",...$})}unlinkEventNote($){return($.client??this.client).delete({url:"/events/{event_id}/notes/{document_id}",...$})}linkEventNote($){return($.client??this.client).put({url:"/events/{event_id}/notes/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}calendarEventProviderUrl($){return($.client??this.client).get({url:"/events/{event_id}/provider-url",...$})}prepareCalendarReplacement($){return($.client??this.client).post({url:"/events/{event_id}/replacement",...$,headers:{"Content-Type":"application/json",...$.headers}})}rsvpCalendarEvent($){return($.client??this.client).put({url:"/events/{event_id}/rsvp",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}respondToJoinRequest($){return($.client??this.client).put({url:"/join-requests/{request_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}noteDocuments($){return($?.client??this.client).get({url:"/meeting-notes/documents",...$})}documentNoteLinks($){return($.client??this.client).get({url:"/meeting-notes/documents/{document_id}/links",...$})}discardCalendarReplacement($){return($.client??this.client).delete({url:"/replacements/{operation_id}",...$})}calendarReplacementStatus($){return($.client??this.client).get({url:"/replacements/{operation_id}",...$})}confirmCalendarReplacement($){return($.client??this.client).post({url:"/replacements/{operation_id}/confirm",...$})}getTeamSharing($){return($?.client??this.client).get({url:"/team-sharing",...$})}setTeamSharing($){return($.client??this.client).put({url:"/team-sharing",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function F2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var c7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},u7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},d7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},rj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(u7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=c7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return FO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},FO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},pj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=d7(x),X=Object.entries(S).map(([Y,L])=>FO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var l7=/\{[^{}]+\}/g,r7=({path:$,url:O})=>{let j=O,x=O.match(l7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,rj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,pj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${FO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},E2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=r7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function i0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var w2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var q2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var f2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=rj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=pj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=FO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},b2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},p7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function k2($){for(let O of $.security??[]){if(p7($,O.name))continue;let j=await w2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var n0=($)=>E2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:f2($.querySerializer),url:$.url}),s0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=ij($.headers,O.headers),j},a7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},ij=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?a7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class aj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var g2=()=>({error:new aj,request:new aj,response:new aj}),i7=f2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),n7={"Content-Type":"application/json"},xj=($={})=>({...q2,headers:n7,parseAs:"auto",querySerializer:i7,...$});var t0=($={})=>{let O=s0(xj(),$),j=()=>({...O}),x=(G)=>{return O=s0(O,G),j()},S=g2(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:ij(O.headers,G.headers),serializedBody:void 0};if(J.security)await k2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=n0(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:i0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?b2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return F2({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:i0(I),url:z})};return{buildUrl:(G)=>n0({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var y2=t0(xj());class v2{client;constructor($){this.client=$?.client??y2}}class h2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class nj extends v2{static __registry=new h2;constructor($){super($);nj.__registry.set(this,$?.key)}setPricingHandler($){return($.client??this.client).post({url:"/ai-cost/pricing",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUsageHandler($){return($.client??this.client).post({url:"/ai-cost/usage",...$,headers:{"Content-Type":"application/json",...$.headers}})}upsertAiProjection($){return($.client??this.client).post({url:"/ai-projections",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChatsForAttachmentHandler($){return($.client??this.client).get({url:"/attachments/{attachment_id}/chats",...$})}deleteChat($){return($.client??this.client).delete({url:"/chat/{chat_id}",...$})}patchChat($){return($.client??this.client).patch({url:"/chat/{chat_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}permanentlyDeleteChat($){return($.client??this.client).delete({url:"/chat/{chat_id}/permanent",...$})}createChat($){return($.client??this.client).post({url:"/chats",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChatHistoryHandler($){return($.client??this.client).get({url:"/chats/history/{chat_id}",...$})}getChatHistoryBatchMessagesHandler($){return($.client??this.client).post({url:"/chats/history_batch_messages",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChat($){return($.client??this.client).get({url:"/chats/{chat_id}",...$})}copyChat($){return($.client??this.client).post({url:"/chats/{chat_id}/copy",...$})}getChatPermissions($){return($.client??this.client).get({url:"/chats/{chat_id}/permissions",...$})}revertDeleteChat($){return($.client??this.client).put({url:"/chats/{chat_id}/revert_delete",...$})}callTool($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/call",...$,headers:{"Content-Type":"application/json",...$.headers}})}rejectToolCall($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/reject",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateToolResponse($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/response/update",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateToolCall($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/update",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCitationHandler($){return($.client??this.client).get({url:"/citations/{id}",...$})}decisions($){return($.client??this.client).post({url:"/decisions",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}notionReportHandler($){return($?.client??this.client).get({url:"/import/notion",...$})}cancelNotionHandler($){return($?.client??this.client).post({url:"/import/notion/cancel",...$})}runImportHandler($){return($.client??this.client).post({url:"/import/run",...$,headers:{"Content-Type":"application/json",...$.headers}})}discoverHandler($){return($.client??this.client).post({url:"/import/runs/{source}/discover",...$})}getStateHandler($){return($?.client??this.client).get({url:"/import/state",...$})}workspaceReportHandler($){return($.client??this.client).get({url:"/import/workspaces/{source}",...$})}cancelWorkspaceHandler($){return($.client??this.client).post({url:"/import/workspaces/{source}/cancel",...$})}deleteMcpServer($){return($.client??this.client).delete({url:"/mcp/servers",...$})}listMcpServers($){return($?.client??this.client).get({url:"/mcp/servers",...$})}addMcpServer($){return($.client??this.client).post({url:"/mcp/servers",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateMcpServer($){return($.client??this.client).put({url:"/mcp/servers",...$,headers:{"Content-Type":"application/json",...$.headers}})}mcpAuthCallback($){return($?.client??this.client).get({url:"/mcp/servers/auth/callback",...$})}mcpOauthClientMetadata($){return($?.client??this.client).get({url:"/mcp/servers/auth/client-metadata",...$})}startMcpAuth($){return($.client??this.client).post({url:"/mcp/servers/auth/start",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMemoryHandler($){return($?.client??this.client).get({url:"/memory",...$})}getStateHandler2($){return($?.client??this.client).get({url:"/onboarding",...$})}completeHandler($){return($.client??this.client).post({url:"/onboarding/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}dismissedPromptsHandler($){return($?.client??this.client).get({url:"/onboarding/prompts",...$})}dismissPromptHandler($){return($.client??this.client).post({url:"/onboarding/prompts/{prompt_id}/dismiss",...$})}browsePipedreamMcpCatalog($){return($?.client??this.client).get({url:"/pipedream/mcp/catalog",...$})}completePipedreamMcpConnection($){return($.client??this.client).post({url:"/pipedream/mcp/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePipedreamMcpConnection($){return($.client??this.client).delete({url:"/pipedream/mcp/connections",...$})}listPipedreamMcpConnections($){return($?.client??this.client).get({url:"/pipedream/mcp/connections",...$})}updatePipedreamMcpConnection($){return($.client??this.client).put({url:"/pipedream/mcp/connections",...$,headers:{"Content-Type":"application/json",...$.headers}})}createPipedreamMcpToken($){return($?.client??this.client).post({url:"/pipedream/mcp/token",...$})}getBatchPreview($){return($.client??this.client).post({url:"/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}sendChatMessage($){return($.client??this.client).post({url:"/stream/chat/message",...$,headers:{"Content-Type":"application/json",...$.headers}})}stopChatStream($){return($.client??this.client).post({url:"/stream/chat/message/stop",...$,headers:{"Content-Type":"application/json",...$.headers}})}structuredCompletion($){return($.client??this.client).post({url:"/structured-completion",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function m2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var c7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},u7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},d7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},rj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(u7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=c7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return FO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},FO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},pj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=d7(x),X=Object.entries(S).map(([Y,L])=>FO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var l7=/\{[^{}]+\}/g,r7=({path:$,url:O})=>{let j=O,x=O.match(l7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,rj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,pj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${FO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},E2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=r7({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function i0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var w2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var q2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var f2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=rj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=pj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=FO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},b2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},p7=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function k2($){for(let O of $.security??[]){if(p7($,O.name))continue;let j=await w2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var n0=($)=>E2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:f2($.querySerializer),url:$.url}),s0=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=ij($.headers,O.headers),j},a7=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},ij=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?a7(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class aj{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var g2=()=>({error:new aj,request:new aj,response:new aj}),i7=f2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),n7={"Content-Type":"application/json"},xj=($={})=>({...q2,headers:n7,parseAs:"auto",querySerializer:i7,...$});var t0=($={})=>{let O=s0(xj(),$),j=()=>({...O}),x=(Q)=>{return O=s0(O,Q),j()},S=g2(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:ij(O.headers,Q.headers),serializedBody:void 0};if(J.security)await k2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=n0(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:i0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?b2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return F2({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:i0(I),url:z})};return{buildUrl:(Q)=>n0({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var y2=t0(xj());class v2{client;constructor($){this.client=$?.client??y2}}class h2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class nj extends v2{static __registry=new h2;constructor($){super($);nj.__registry.set(this,$?.key)}setPricingHandler($){return($.client??this.client).post({url:"/ai-cost/pricing",...$,headers:{"Content-Type":"application/json",...$.headers}})}getUsageHandler($){return($.client??this.client).post({url:"/ai-cost/usage",...$,headers:{"Content-Type":"application/json",...$.headers}})}upsertAiProjection($){return($.client??this.client).post({url:"/ai-projections",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChatsForAttachmentHandler($){return($.client??this.client).get({url:"/attachments/{attachment_id}/chats",...$})}deleteChat($){return($.client??this.client).delete({url:"/chat/{chat_id}",...$})}patchChat($){return($.client??this.client).patch({url:"/chat/{chat_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}permanentlyDeleteChat($){return($.client??this.client).delete({url:"/chat/{chat_id}/permanent",...$})}createChat($){return($.client??this.client).post({url:"/chats",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChatHistoryHandler($){return($.client??this.client).get({url:"/chats/history/{chat_id}",...$})}getChatHistoryBatchMessagesHandler($){return($.client??this.client).post({url:"/chats/history_batch_messages",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChat($){return($.client??this.client).get({url:"/chats/{chat_id}",...$})}copyChat($){return($.client??this.client).post({url:"/chats/{chat_id}/copy",...$})}getChatPermissions($){return($.client??this.client).get({url:"/chats/{chat_id}/permissions",...$})}revertDeleteChat($){return($.client??this.client).put({url:"/chats/{chat_id}/revert_delete",...$})}callTool($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/call",...$,headers:{"Content-Type":"application/json",...$.headers}})}rejectToolCall($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/reject",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateToolResponse($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/response/update",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateToolCall($){return($.client??this.client).post({url:"/chats/{chat_id}/tool/update",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCitationHandler($){return($.client??this.client).get({url:"/citations/{id}",...$})}decisions($){return($.client??this.client).post({url:"/decisions",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}notionReportHandler($){return($?.client??this.client).get({url:"/import/notion",...$})}cancelNotionHandler($){return($?.client??this.client).post({url:"/import/notion/cancel",...$})}runImportHandler($){return($.client??this.client).post({url:"/import/run",...$,headers:{"Content-Type":"application/json",...$.headers}})}discoverHandler($){return($.client??this.client).post({url:"/import/runs/{source}/discover",...$})}getStateHandler($){return($?.client??this.client).get({url:"/import/state",...$})}workspaceReportHandler($){return($.client??this.client).get({url:"/import/workspaces/{source}",...$})}cancelWorkspaceHandler($){return($.client??this.client).post({url:"/import/workspaces/{source}/cancel",...$})}deleteMcpServer($){return($.client??this.client).delete({url:"/mcp/servers",...$})}listMcpServers($){return($?.client??this.client).get({url:"/mcp/servers",...$})}addMcpServer($){return($.client??this.client).post({url:"/mcp/servers",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateMcpServer($){return($.client??this.client).put({url:"/mcp/servers",...$,headers:{"Content-Type":"application/json",...$.headers}})}mcpAuthCallback($){return($?.client??this.client).get({url:"/mcp/servers/auth/callback",...$})}mcpOauthClientMetadata($){return($?.client??this.client).get({url:"/mcp/servers/auth/client-metadata",...$})}startMcpAuth($){return($.client??this.client).post({url:"/mcp/servers/auth/start",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMemoryHandler($){return($?.client??this.client).get({url:"/memory",...$})}getStateHandler2($){return($?.client??this.client).get({url:"/onboarding",...$})}completeHandler($){return($.client??this.client).post({url:"/onboarding/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}dismissedPromptsHandler($){return($?.client??this.client).get({url:"/onboarding/prompts",...$})}dismissPromptHandler($){return($.client??this.client).post({url:"/onboarding/prompts/{prompt_id}/dismiss",...$})}browsePipedreamMcpCatalog($){return($?.client??this.client).get({url:"/pipedream/mcp/catalog",...$})}completePipedreamMcpConnection($){return($.client??this.client).post({url:"/pipedream/mcp/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePipedreamMcpConnection($){return($.client??this.client).delete({url:"/pipedream/mcp/connections",...$})}listPipedreamMcpConnections($){return($?.client??this.client).get({url:"/pipedream/mcp/connections",...$})}updatePipedreamMcpConnection($){return($.client??this.client).put({url:"/pipedream/mcp/connections",...$,headers:{"Content-Type":"application/json",...$.headers}})}createPipedreamMcpToken($){return($?.client??this.client).post({url:"/pipedream/mcp/token",...$})}getBatchPreview($){return($.client??this.client).post({url:"/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}sendChatMessage($){return($.client??this.client).post({url:"/stream/chat/message",...$,headers:{"Content-Type":"application/json",...$.headers}})}stopChatStream($){return($.client??this.client).post({url:"/stream/chat/message/stop",...$,headers:{"Content-Type":"application/json",...$.headers}})}structuredCompletion($){return($.client??this.client).post({url:"/structured-completion",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function m2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var s7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},t7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},e7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},sj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(t7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=s7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return EO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},EO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},tj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=e7(x),X=Object.entries(S).map(([Y,L])=>EO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var o7=/\{[^{}]+\}/g,$5=({path:$,url:O})=>{let j=O,x=O.match(o7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,sj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,tj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${EO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},c2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=$5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function e0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var u2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var d2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var l2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=sj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=tj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=EO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},r2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},O5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function p2($){for(let O of $.security??[]){if(O5($,O.name))continue;let j=await u2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var o0=($)=>c2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:l2($.querySerializer),url:$.url}),$1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=oj($.headers,O.headers),j},j5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},oj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?j5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class ej{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var a2=()=>({error:new ej,request:new ej,response:new ej}),x5=l2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),S5={"Content-Type":"application/json"},Sj=($={})=>({...d2,headers:S5,parseAs:"auto",querySerializer:x5,...$});var O1=($={})=>{let O=$1(Sj(),$),j=()=>({...O}),x=(G)=>{return O=$1(O,G),j()},S=a2(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:oj(O.headers,G.headers),serializedBody:void 0};if(J.security)await p2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=o0(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:e0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?r2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return m2({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:e0(I),url:z})};return{buildUrl:(G)=>o0({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var i2=O1(Sj());class n2{client;constructor($){this.client=$?.client??i2}}class s2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class $x extends n2{static __registry=new s2;constructor($){super($);$x.__registry.set(this,$?.key)}getContacts($){return($?.client??this.client).get({url:"/contacts",...$})}addContact($){return($.client??this.client).post({url:"/contacts",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function t2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var s7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},t7=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},e7=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},sj=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(t7(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=s7(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return EO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},EO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},tj=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=e7(x),X=Object.entries(S).map(([Y,L])=>EO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var o7=/\{[^{}]+\}/g,$5=({path:$,url:O})=>{let j=O,x=O.match(o7);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,sj({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,tj({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${EO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},c2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=$5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function e0($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var u2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var d2={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var l2=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=sj({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=tj({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=EO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},r2=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},O5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function p2($){for(let O of $.security??[]){if(O5($,O.name))continue;let j=await u2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var o0=($)=>c2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:l2($.querySerializer),url:$.url}),$1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=oj($.headers,O.headers),j},j5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},oj=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?j5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class ej{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var a2=()=>({error:new ej,request:new ej,response:new ej}),x5=l2({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),S5={"Content-Type":"application/json"},Sj=($={})=>({...d2,headers:S5,parseAs:"auto",querySerializer:x5,...$});var O1=($={})=>{let O=$1(Sj(),$),j=()=>({...O}),x=(Q)=>{return O=$1(O,Q),j()},S=a2(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:oj(O.headers,Q.headers),serializedBody:void 0};if(J.security)await p2(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=o0(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:e0(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?r2(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return m2({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:e0(I),url:z})};return{buildUrl:(Q)=>o0({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var i2=O1(Sj());class n2{client;constructor($){this.client=$?.client??i2}}class s2{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class $x extends n2{static __registry=new s2;constructor($){super($);$x.__registry.set(this,$?.key)}getContacts($){return($?.client??this.client).get({url:"/contacts",...$})}addContact($){return($.client??this.client).post({url:"/contacts",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function t2({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var Z5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},X5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},K5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Ox=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(X5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=Z5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return wO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},wO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},jx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=K5(x),X=Object.entries(S).map(([Y,L])=>wO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var Y5=/\{[^{}]+\}/g,Q5=({path:$,url:O})=>{let j=O,x=O.match(Y5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Ox({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,jx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${wO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},e2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=Q5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function j1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var o2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var $S={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var OS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Ox({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=jx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=wO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},jS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},G5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function xS($){for(let O of $.security??[]){if(G5($,O.name))continue;let j=await o2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var x1=($)=>e2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:OS($.querySerializer),url:$.url}),S1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Sx($.headers,O.headers),j},J5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Sx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?J5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class xx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var SS=()=>({error:new xx,request:new xx,response:new xx}),V5=OS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),W5={"Content-Type":"application/json"},Zj=($={})=>({...$S,headers:W5,parseAs:"auto",querySerializer:V5,...$});var Z1=($={})=>{let O=S1(Zj(),$),j=()=>({...O}),x=(G)=>{return O=S1(O,G),j()},S=SS(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Sx(O.headers,G.headers),serializedBody:void 0};if(J.security)await xS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=x1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:j1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?jS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return t2({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:j1(I),url:z})};return{buildUrl:(G)=>x1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var ZS=Z1(Zj());class XS{client;constructor($){this.client=$?.client??ZS}}class KS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Zx extends XS{static __registry=new KS;constructor($){super($);Zx.__registry.set(this,$?.key)}getAttachment($){return($.client??this.client).get({url:"/email/attachments/{id}",...$})}getAttachmentDocumentId($){return($.client??this.client).get({url:"/email/attachments/{id}/document_id",...$})}cancelBackfillGmail($){return($.client??this.client).delete({url:"/email/backfill/gmail",...$,headers:{"Content-Type":"application/json",...$.headers}})}listBackfillGmail($){return($?.client??this.client).get({url:"/email/backfill/gmail",...$})}getBackfillGmailActive($){return($?.client??this.client).get({url:"/email/backfill/gmail/active",...$})}getBackfillGmail($){return($.client??this.client).get({url:"/email/backfill/gmail/{id}",...$})}listContacts($){return($?.client??this.client).get({url:"/email/contacts",...$})}blockSender($){return($.client??this.client).post({url:"/email/contacts/block",...$,headers:{"Content-Type":"application/json",...$.headers}})}listBlockedSenders($){return($?.client??this.client).get({url:"/email/contacts/blocked",...$})}unblockSender($){return($.client??this.client).post({url:"/email/contacts/unblock",...$,headers:{"Content-Type":"application/json",...$.headers}})}recoverDraftTransfer($){return($.client??this.client).post({url:"/email/draft-transfers/{id}/recover",...$})}createDraft($){return($.client??this.client).post({url:"/email/drafts",...$,headers:{"Content-Type":"application/json",...$.headers}})}getScheduledMessages($){return($?.client??this.client).get({url:"/email/drafts/scheduled",...$})}upsertScheduledMessage($){return($.client??this.client).put({url:"/email/drafts/scheduled/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteScheduledDraft($){return($.client??this.client).delete({url:"/email/drafts/scheduled/{message_id}",...$})}deleteDraft($){return($.client??this.client).delete({url:"/email/drafts/{id}",...$})}addDraftAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeDraftAttachment($){return($.client??this.client).delete({url:"/email/drafts/{id}/attachments/{attachment_id}",...$})}completeDraftAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/attachments/{attachment_id}/complete",...$})}addForwardedAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/forwarded-attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeForwardedAttachment($){return($.client??this.client).delete({url:"/email/drafts/{id}/forwarded-attachments/{attachment_id}",...$})}messageOperationStatus($){return($.client??this.client).get({url:"/email/drafts/{id}/operation",...$})}resolveMessageOperation($){return($.client??this.client).post({url:"/email/drafts/{id}/resolve",...$,headers:{"Content-Type":"application/json",...$.headers}})}transferDraft($){return($.client??this.client).post({url:"/email/drafts/{id}/transfer",...$,headers:{"Content-Type":"application/json",...$.headers}})}listEmailFilters($){return($?.client??this.client).get({url:"/email/filters",...$})}upsertEmailFilter($){return($.client??this.client).put({url:"/email/filters",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteEmailFilter($){return($.client??this.client).delete({url:"/email/filters/{id}",...$})}initUser($){return($?.client??this.client).post({url:"/email/init",...$})}listLabels($){return($?.client??this.client).get({url:"/email/labels",...$})}createLabel($){return($.client??this.client).post({url:"/email/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteLabel($){return($.client??this.client).delete({url:"/email/labels/{id}",...$})}listLinks($){return($?.client??this.client).get({url:"/email/links",...$})}healthCheckLinks($){return($?.client??this.client).post({url:"/email/links/health-check",...$})}deleteLink($){return($.client??this.client).delete({url:"/email/links/{link_id}",...$})}disableLinkCalendar($){return($.client??this.client).delete({url:"/email/links/{link_id}/calendar",...$})}resyncLink($){return($.client??this.client).post({url:"/email/links/{link_id}/resync",...$})}sendMessage($){return($.client??this.client).post({url:"/email/messages",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMessagesBatch($){return($.client??this.client).post({url:"/email/messages/batch",...$,headers:{"Content-Type":"application/json",...$.headers}})}addRemoveLabel($){return($.client??this.client).patch({url:"/email/messages/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMessage($){return($.client??this.client).get({url:"/email/messages/{id}",...$})}patchSettings($){return($.client??this.client).patch({url:"/email/settings",...$,headers:{"Content-Type":"application/json",...$.headers}})}mailboxSettingsOperations($){return($?.client??this.client).get({url:"/email/settings/operations",...$})}disableSync($){return($?.client??this.client).delete({url:"/email/sync",...$})}previewsInboxCursor($){return($.client??this.client).get({url:"/email/threads/previews/cursor/{view}",...$})}archiveThread($){return($.client??this.client).patch({url:"/email/threads/{id}/archived",...$,headers:{"Content-Type":"application/json",...$.headers}})}addRemoveThreadLabel($){return($.client??this.client).patch({url:"/email/threads/{id}/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getThreadMessagesHandler($){return($.client??this.client).get({url:"/email/threads/{id}/messages",...$})}threadOperations($){return($.client??this.client).get({url:"/email/threads/{id}/operations",...$})}threadSeen($){return($.client??this.client).post({url:"/email/threads/{id}/seen",...$})}updateThreadState($){return($.client??this.client).patch({url:"/email/threads/{id}/state",...$,headers:{"Content-Type":"application/json",...$.headers}})}getThread($){return($.client??this.client).get({url:"/email/threads/{thread_id}",...$})}getThreadCalendarInvitations($){return($.client??this.client).get({url:"/email/threads/{thread_id}/calendar-invitations",...$})}copyThreadCalendarInvitation($){return($.client??this.client).post({url:"/email/threads/{thread_id}/messages/{message_id}/calendar-invitations/{invitation_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateThreadProject($){return($.client??this.client).patch({url:"/email/threads/{thread_id}/project",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}}function YS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var Z5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},X5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},K5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Ox=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(X5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=Z5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return wO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},wO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},jx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=K5(x),X=Object.entries(S).map(([Y,L])=>wO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var Y5=/\{[^{}]+\}/g,G5=({path:$,url:O})=>{let j=O,x=O.match(Y5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Ox({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,jx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${wO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},e2=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=G5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function j1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var o2=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var $S={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var OS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Ox({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=jx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=wO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},jS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},Q5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function xS($){for(let O of $.security??[]){if(Q5($,O.name))continue;let j=await o2(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var x1=($)=>e2({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:OS($.querySerializer),url:$.url}),S1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Sx($.headers,O.headers),j},J5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Sx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?J5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class xx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var SS=()=>({error:new xx,request:new xx,response:new xx}),V5=OS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),W5={"Content-Type":"application/json"},Zj=($={})=>({...$S,headers:W5,parseAs:"auto",querySerializer:V5,...$});var Z1=($={})=>{let O=S1(Zj(),$),j=()=>({...O}),x=(Q)=>{return O=S1(O,Q),j()},S=SS(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:Sx(O.headers,Q.headers),serializedBody:void 0};if(J.security)await xS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=x1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:j1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?jS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return t2({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:j1(I),url:z})};return{buildUrl:(Q)=>x1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var ZS=Z1(Zj());class XS{client;constructor($){this.client=$?.client??ZS}}class KS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Zx extends XS{static __registry=new KS;constructor($){super($);Zx.__registry.set(this,$?.key)}getAttachment($){return($.client??this.client).get({url:"/email/attachments/{id}",...$})}getAttachmentDocumentId($){return($.client??this.client).get({url:"/email/attachments/{id}/document_id",...$})}cancelBackfillGmail($){return($.client??this.client).delete({url:"/email/backfill/gmail",...$,headers:{"Content-Type":"application/json",...$.headers}})}listBackfillGmail($){return($?.client??this.client).get({url:"/email/backfill/gmail",...$})}getBackfillGmailActive($){return($?.client??this.client).get({url:"/email/backfill/gmail/active",...$})}getBackfillGmail($){return($.client??this.client).get({url:"/email/backfill/gmail/{id}",...$})}listContacts($){return($?.client??this.client).get({url:"/email/contacts",...$})}blockSender($){return($.client??this.client).post({url:"/email/contacts/block",...$,headers:{"Content-Type":"application/json",...$.headers}})}listBlockedSenders($){return($?.client??this.client).get({url:"/email/contacts/blocked",...$})}unblockSender($){return($.client??this.client).post({url:"/email/contacts/unblock",...$,headers:{"Content-Type":"application/json",...$.headers}})}recoverDraftTransfer($){return($.client??this.client).post({url:"/email/draft-transfers/{id}/recover",...$})}createDraft($){return($.client??this.client).post({url:"/email/drafts",...$,headers:{"Content-Type":"application/json",...$.headers}})}getScheduledMessages($){return($?.client??this.client).get({url:"/email/drafts/scheduled",...$})}upsertScheduledMessage($){return($.client??this.client).put({url:"/email/drafts/scheduled/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteScheduledDraft($){return($.client??this.client).delete({url:"/email/drafts/scheduled/{message_id}",...$})}deleteDraft($){return($.client??this.client).delete({url:"/email/drafts/{id}",...$})}addDraftAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeDraftAttachment($){return($.client??this.client).delete({url:"/email/drafts/{id}/attachments/{attachment_id}",...$})}completeDraftAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/attachments/{attachment_id}/complete",...$})}addForwardedAttachment($){return($.client??this.client).post({url:"/email/drafts/{id}/forwarded-attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeForwardedAttachment($){return($.client??this.client).delete({url:"/email/drafts/{id}/forwarded-attachments/{attachment_id}",...$})}messageOperationStatus($){return($.client??this.client).get({url:"/email/drafts/{id}/operation",...$})}resolveMessageOperation($){return($.client??this.client).post({url:"/email/drafts/{id}/resolve",...$,headers:{"Content-Type":"application/json",...$.headers}})}transferDraft($){return($.client??this.client).post({url:"/email/drafts/{id}/transfer",...$,headers:{"Content-Type":"application/json",...$.headers}})}listEmailFilters($){return($?.client??this.client).get({url:"/email/filters",...$})}upsertEmailFilter($){return($.client??this.client).put({url:"/email/filters",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteEmailFilter($){return($.client??this.client).delete({url:"/email/filters/{id}",...$})}initUser($){return($?.client??this.client).post({url:"/email/init",...$})}listLabels($){return($?.client??this.client).get({url:"/email/labels",...$})}createLabel($){return($.client??this.client).post({url:"/email/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteLabel($){return($.client??this.client).delete({url:"/email/labels/{id}",...$})}listLinks($){return($?.client??this.client).get({url:"/email/links",...$})}healthCheckLinks($){return($?.client??this.client).post({url:"/email/links/health-check",...$})}deleteLink($){return($.client??this.client).delete({url:"/email/links/{link_id}",...$})}disableLinkCalendar($){return($.client??this.client).delete({url:"/email/links/{link_id}/calendar",...$})}resyncLink($){return($.client??this.client).post({url:"/email/links/{link_id}/resync",...$})}sendMessage($){return($.client??this.client).post({url:"/email/messages",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMessagesBatch($){return($.client??this.client).post({url:"/email/messages/batch",...$,headers:{"Content-Type":"application/json",...$.headers}})}addRemoveLabel($){return($.client??this.client).patch({url:"/email/messages/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMessage($){return($.client??this.client).get({url:"/email/messages/{id}",...$})}patchSettings($){return($.client??this.client).patch({url:"/email/settings",...$,headers:{"Content-Type":"application/json",...$.headers}})}mailboxSettingsOperations($){return($?.client??this.client).get({url:"/email/settings/operations",...$})}disableSync($){return($?.client??this.client).delete({url:"/email/sync",...$})}previewsInboxCursor($){return($.client??this.client).get({url:"/email/threads/previews/cursor/{view}",...$})}archiveThread($){return($.client??this.client).patch({url:"/email/threads/{id}/archived",...$,headers:{"Content-Type":"application/json",...$.headers}})}addRemoveThreadLabel($){return($.client??this.client).patch({url:"/email/threads/{id}/labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getThreadMessagesHandler($){return($.client??this.client).get({url:"/email/threads/{id}/messages",...$})}threadOperations($){return($.client??this.client).get({url:"/email/threads/{id}/operations",...$})}threadSeen($){return($.client??this.client).post({url:"/email/threads/{id}/seen",...$})}updateThreadState($){return($.client??this.client).patch({url:"/email/threads/{id}/state",...$,headers:{"Content-Type":"application/json",...$.headers}})}getThread($){return($.client??this.client).get({url:"/email/threads/{thread_id}",...$})}getThreadCalendarInvitations($){return($.client??this.client).get({url:"/email/threads/{thread_id}/calendar-invitations",...$})}copyThreadCalendarInvitation($){return($.client??this.client).post({url:"/email/threads/{thread_id}/messages/{message_id}/calendar-invitations/{invitation_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateThreadProject($){return($.client??this.client).patch({url:"/email/threads/{thread_id}/project",...$,headers:{"Content-Type":"application/json",...$.headers}})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}}function YS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var B5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},L5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},N5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Xx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(L5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=B5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return qO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},qO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Kx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=N5(x),X=Object.entries(S).map(([Y,L])=>qO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var U5=/\{[^{}]+\}/g,z5=({path:$,url:O})=>{let j=O,x=O.match(U5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Xx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Kx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${qO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},QS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=z5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function X1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var GS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var JS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var VS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Xx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Kx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=qO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},WS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},I5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function BS($){for(let O of $.security??[]){if(I5($,O.name))continue;let j=await GS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var K1=($)=>QS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:VS($.querySerializer),url:$.url}),Y1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Qx($.headers,O.headers),j},T5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Qx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?T5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Yx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var LS=()=>({error:new Yx,request:new Yx,response:new Yx}),H5=VS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),R5={"Content-Type":"application/json"},Xj=($={})=>({...JS,headers:R5,parseAs:"auto",querySerializer:H5,...$});var Q1=($={})=>{let O=Y1(Xj(),$),j=()=>({...O}),x=(G)=>{return O=Y1(O,G),j()},S=LS(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Qx(O.headers,G.headers),serializedBody:void 0};if(J.security)await BS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=K1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:X1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?WS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return YS({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:X1(I),url:z})};return{buildUrl:(G)=>K1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var NS=Q1(Xj());class US{client;constructor($){this.client=$?.client??NS}}class zS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Gx extends US{static __registry=new zS;constructor($){super($);Gx.__registry.set(this,$?.key)}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}getUnsubscribes($){return($?.client??this.client).get({url:"/unsubscribe",...$})}unsubscribeEmail($){return($?.client??this.client).post({url:"/unsubscribe/email",...$})}removeUnsubscribeItem($){return($.client??this.client).delete({url:"/unsubscribe/item/{item_type}/{item_id}",...$})}unsubscribeItem($){return($.client??this.client).post({url:"/unsubscribe/item/{item_type}/{item_id}",...$})}removeUnsubscribeAll($){return($?.client??this.client).delete({url:"/unsubscribe/mute",...$})}unsubscribeAll($){return($?.client??this.client).post({url:"/unsubscribe/mute",...$})}listTypedNotifications($){return($?.client??this.client).get({url:"/v1/user_notifications",...$})}bulkGetTypedNotificationsByEventItemIds($){return($.client??this.client).post({url:"/v1/user_notifications/item/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTypedNotificationsByEventItemId($){return($.client??this.client).get({url:"/v1/user_notifications/item/{event_item_id}",...$})}getNotificationTypePreferences($){return($?.client??this.client).get({url:"/v1/user_notifications/preferences",...$})}disableNotificationType($){return($.client??this.client).put({url:"/v1/user_notifications/preferences/{notification_event_type}/disable",...$})}enableNotificationType($){return($.client??this.client).put({url:"/v1/user_notifications/preferences/{notification_event_type}/enable",...$})}getTypedNotificationById($){return($.client??this.client).get({url:"/v1/user_notifications/{notification_id}",...$})}bulkDeleteUserNotificationsV2($){return($.client??this.client).delete({url:"/v2/user_notifications/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsDone($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/done",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsSeen($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/seen",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsUndone($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/undone",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteUserNotificationV2($){return($.client??this.client).delete({url:"/v2/user_notifications/{notification_id}",...$})}}function IS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var B5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},L5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},N5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Xx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(L5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=B5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return qO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},qO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Kx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=N5(x),X=Object.entries(S).map(([Y,L])=>qO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var U5=/\{[^{}]+\}/g,z5=({path:$,url:O})=>{let j=O,x=O.match(U5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Xx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Kx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${qO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},GS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=z5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function X1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var QS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var JS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var VS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Xx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Kx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=qO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},WS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},I5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function BS($){for(let O of $.security??[]){if(I5($,O.name))continue;let j=await QS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var K1=($)=>GS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:VS($.querySerializer),url:$.url}),Y1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Gx($.headers,O.headers),j},T5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Gx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?T5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Yx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var LS=()=>({error:new Yx,request:new Yx,response:new Yx}),H5=VS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),R5={"Content-Type":"application/json"},Xj=($={})=>({...JS,headers:R5,parseAs:"auto",querySerializer:H5,...$});var G1=($={})=>{let O=Y1(Xj(),$),j=()=>({...O}),x=(Q)=>{return O=Y1(O,Q),j()},S=LS(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:Gx(O.headers,Q.headers),serializedBody:void 0};if(J.security)await BS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=K1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:X1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?WS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return YS({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:X1(I),url:z})};return{buildUrl:(Q)=>K1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var NS=G1(Xj());class US{client;constructor($){this.client=$?.client??NS}}class zS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Qx extends US{static __registry=new zS;constructor($){super($);Qx.__registry.set(this,$?.key)}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}getUnsubscribes($){return($?.client??this.client).get({url:"/unsubscribe",...$})}unsubscribeEmail($){return($?.client??this.client).post({url:"/unsubscribe/email",...$})}removeUnsubscribeItem($){return($.client??this.client).delete({url:"/unsubscribe/item/{item_type}/{item_id}",...$})}unsubscribeItem($){return($.client??this.client).post({url:"/unsubscribe/item/{item_type}/{item_id}",...$})}removeUnsubscribeAll($){return($?.client??this.client).delete({url:"/unsubscribe/mute",...$})}unsubscribeAll($){return($?.client??this.client).post({url:"/unsubscribe/mute",...$})}listTypedNotifications($){return($?.client??this.client).get({url:"/v1/user_notifications",...$})}bulkGetTypedNotificationsByEventItemIds($){return($.client??this.client).post({url:"/v1/user_notifications/item/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}getTypedNotificationsByEventItemId($){return($.client??this.client).get({url:"/v1/user_notifications/item/{event_item_id}",...$})}getNotificationTypePreferences($){return($?.client??this.client).get({url:"/v1/user_notifications/preferences",...$})}disableNotificationType($){return($.client??this.client).put({url:"/v1/user_notifications/preferences/{notification_event_type}/disable",...$})}enableNotificationType($){return($.client??this.client).put({url:"/v1/user_notifications/preferences/{notification_event_type}/enable",...$})}getTypedNotificationById($){return($.client??this.client).get({url:"/v1/user_notifications/{notification_id}",...$})}bulkDeleteUserNotificationsV2($){return($.client??this.client).delete({url:"/v2/user_notifications/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsDone($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/done",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsSeen($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/seen",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkMarkNotificationsUndone($){return($.client??this.client).patch({url:"/v2/user_notifications/bulk/undone",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteUserNotificationV2($){return($.client??this.client).delete({url:"/v2/user_notifications/{notification_id}",...$})}}function IS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var D5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},C5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},_5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Jx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(C5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=D5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return fO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},fO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Vx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=_5(x),X=Object.entries(S).map(([Y,L])=>fO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var P5=/\{[^{}]+\}/g,M5=({path:$,url:O})=>{let j=O,x=O.match(P5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Jx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Vx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${fO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},TS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=M5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function G1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var HS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var RS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var DS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Jx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Vx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=fO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},CS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},A5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function _S($){for(let O of $.security??[]){if(A5($,O.name))continue;let j=await HS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var J1=($)=>TS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:DS($.querySerializer),url:$.url}),V1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Bx($.headers,O.headers),j},F5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Bx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?F5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Wx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var PS=()=>({error:new Wx,request:new Wx,response:new Wx}),E5=DS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),w5={"Content-Type":"application/json"},Kj=($={})=>({...RS,headers:w5,parseAs:"auto",querySerializer:E5,...$});var W1=($={})=>{let O=V1(Kj(),$),j=()=>({...O}),x=(G)=>{return O=V1(O,G),j()},S=PS(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Bx(O.headers,G.headers),serializedBody:void 0};if(J.security)await _S(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=J1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:G1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?CS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return IS({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:G1(I),url:z})};return{buildUrl:(G)=>J1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var MS=W1(Kj());class AS{client;constructor($){this.client=$?.client??MS}}class FS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Lx extends AS{static __registry=new FS;constructor($){super($);Lx.__registry.set(this,$?.key)}listProperties($){return($.client??this.client).get({url:"/properties/definitions",...$})}createPropertyDefinition($){return($.client??this.client).post({url:"/properties/definitions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePropertyDefinition($){return($.client??this.client).delete({url:"/properties/definitions/{definition_id}",...$})}getPropertyDefinition($){return($.client??this.client).get({url:"/properties/definitions/{definition_id}",...$})}getPropertyOptions($){return($.client??this.client).get({url:"/properties/definitions/{definition_id}/options",...$})}addPropertyOption($){return($.client??this.client).post({url:"/properties/definitions/{definition_id}/options",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePropertyOption($){return($.client??this.client).delete({url:"/properties/definitions/{definition_id}/options/{option_id}",...$})}updatePropertyOption($){return($.client??this.client).patch({url:"/properties/definitions/{definition_id}/options/{option_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBulkEntityProperties($){return($.client??this.client).post({url:"/properties/entities/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}getEntityProperties($){return($.client??this.client).get({url:"/properties/entities/{entity_type}/{entity_id}",...$})}bulkUpdateEntityPropertyOptions($){return($.client??this.client).post({url:"/properties/entities/{entity_type}/{entity_id}/options/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}setEntityProperty($){return($.client??this.client).put({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeEntityPropertyOption($){return($.client??this.client).delete({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}/options/{option_id}",...$})}addEntityPropertyOption($){return($.client??this.client).post({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}/options/{option_id}",...$})}deleteEntityProperty($){return($.client??this.client).delete({url:"/properties/entity_properties/{entity_property_id}",...$})}bulkUpdateEntitiesPropertyOptions($){return($.client??this.client).post({url:"/properties/options/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}listTags($){return($?.client??this.client).get({url:"/properties/tags",...$})}ensureTagSet($){return($.client??this.client).post({url:"/properties/tags",...$,headers:{"Content-Type":"application/json",...$.headers}})}mergeTag($){return($.client??this.client).post({url:"/properties/tags/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}promoteTag($){return($.client??this.client).post({url:"/properties/tags/promote",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function ES({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var D5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},_5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},C5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Jx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(_5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=D5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return fO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},fO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Vx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=C5(x),X=Object.entries(S).map(([Y,L])=>fO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var P5=/\{[^{}]+\}/g,M5=({path:$,url:O})=>{let j=O,x=O.match(P5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Jx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Vx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${fO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},TS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=M5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function Q1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var HS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var RS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var DS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Jx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Vx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=fO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},_S=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},A5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function CS($){for(let O of $.security??[]){if(A5($,O.name))continue;let j=await HS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var J1=($)=>TS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:DS($.querySerializer),url:$.url}),V1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Bx($.headers,O.headers),j},F5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Bx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?F5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Wx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var PS=()=>({error:new Wx,request:new Wx,response:new Wx}),E5=DS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),w5={"Content-Type":"application/json"},Kj=($={})=>({...RS,headers:w5,parseAs:"auto",querySerializer:E5,...$});var W1=($={})=>{let O=V1(Kj(),$),j=()=>({...O}),x=(Q)=>{return O=V1(O,Q),j()},S=PS(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:Bx(O.headers,Q.headers),serializedBody:void 0};if(J.security)await CS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=J1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:Q1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?_S(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return IS({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:Q1(I),url:z})};return{buildUrl:(Q)=>J1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var MS=W1(Kj());class AS{client;constructor($){this.client=$?.client??MS}}class FS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Lx extends AS{static __registry=new FS;constructor($){super($);Lx.__registry.set(this,$?.key)}listProperties($){return($.client??this.client).get({url:"/properties/definitions",...$})}createPropertyDefinition($){return($.client??this.client).post({url:"/properties/definitions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePropertyDefinition($){return($.client??this.client).delete({url:"/properties/definitions/{definition_id}",...$})}getPropertyDefinition($){return($.client??this.client).get({url:"/properties/definitions/{definition_id}",...$})}getPropertyOptions($){return($.client??this.client).get({url:"/properties/definitions/{definition_id}/options",...$})}addPropertyOption($){return($.client??this.client).post({url:"/properties/definitions/{definition_id}/options",...$,headers:{"Content-Type":"application/json",...$.headers}})}deletePropertyOption($){return($.client??this.client).delete({url:"/properties/definitions/{definition_id}/options/{option_id}",...$})}updatePropertyOption($){return($.client??this.client).patch({url:"/properties/definitions/{definition_id}/options/{option_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBulkEntityProperties($){return($.client??this.client).post({url:"/properties/entities/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}getEntityProperties($){return($.client??this.client).get({url:"/properties/entities/{entity_type}/{entity_id}",...$})}bulkUpdateEntityPropertyOptions($){return($.client??this.client).post({url:"/properties/entities/{entity_type}/{entity_id}/options/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}setEntityProperty($){return($.client??this.client).put({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeEntityPropertyOption($){return($.client??this.client).delete({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}/options/{option_id}",...$})}addEntityPropertyOption($){return($.client??this.client).post({url:"/properties/entities/{entity_type}/{entity_id}/{property_id}/options/{option_id}",...$})}deleteEntityProperty($){return($.client??this.client).delete({url:"/properties/entity_properties/{entity_property_id}",...$})}bulkUpdateEntitiesPropertyOptions($){return($.client??this.client).post({url:"/properties/options/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}listTags($){return($?.client??this.client).get({url:"/properties/tags",...$})}ensureTagSet($){return($.client??this.client).post({url:"/properties/tags",...$,headers:{"Content-Type":"application/json",...$.headers}})}mergeTag($){return($.client??this.client).post({url:"/properties/tags/merge",...$,headers:{"Content-Type":"application/json",...$.headers}})}promoteTag($){return($.client??this.client).post({url:"/properties/tags/promote",...$,headers:{"Content-Type":"application/json",...$.headers}})}}function ES({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var q5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},f5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},b5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Nx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(f5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=q5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return bO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},bO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Ux=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=b5(x),X=Object.entries(S).map(([Y,L])=>bO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var k5=/\{[^{}]+\}/g,g5=({path:$,url:O})=>{let j=O,x=O.match(k5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Nx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Ux({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${bO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},wS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=g5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function B1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var qS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var fS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var bS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Nx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Ux({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=bO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},kS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},y5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function gS($){for(let O of $.security??[]){if(y5($,O.name))continue;let j=await qS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var L1=($)=>wS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:bS($.querySerializer),url:$.url}),N1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Ix($.headers,O.headers),j},v5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Ix=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?v5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class zx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var yS=()=>({error:new zx,request:new zx,response:new zx}),h5=bS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),m5={"Content-Type":"application/json"},Yj=($={})=>({...fS,headers:m5,parseAs:"auto",querySerializer:h5,...$});var U1=($={})=>{let O=N1(Yj(),$),j=()=>({...O}),x=(G)=>{return O=N1(O,G),j()},S=yS(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Ix(O.headers,G.headers),serializedBody:void 0};if(J.security)await gS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=L1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:B1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?kS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return ES({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:B1(I),url:z})};return{buildUrl:(G)=>L1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var vS=U1(Yj());class hS{client;constructor($){this.client=$?.client??vS}}class mS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Tx extends hS{static __registry=new mS;constructor($){super($);Tx.__registry.set(this,$?.key)}scheduledActionHealth($){return($?.client??this.client).get({url:"/health",...$})}listScheduledActions($){return($?.client??this.client).get({url:"/scheduled-actions",...$})}createScheduledAction($){return($.client??this.client).post({url:"/scheduled-actions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteScheduledAction($){return($.client??this.client).delete({url:"/scheduled-actions/{id}",...$})}getScheduledAction($){return($.client??this.client).get({url:"/scheduled-actions/{id}",...$})}updateScheduledAction($){return($.client??this.client).put({url:"/scheduled-actions/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}setScheduledActionEnabled($){return($.client??this.client).put({url:"/scheduled-actions/{id}/enabled",...$,headers:{"Content-Type":"application/json",...$.headers}})}executeScheduledActionNow($){return($.client??this.client).post({url:"/scheduled-actions/{id}/execute",...$})}listScheduledActionHistory($){return($.client??this.client).get({url:"/scheduled-actions/{id}/history",...$})}}function cS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var q5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},f5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},b5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Nx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(f5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=q5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return bO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},bO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Ux=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=b5(x),X=Object.entries(S).map(([Y,L])=>bO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var k5=/\{[^{}]+\}/g,g5=({path:$,url:O})=>{let j=O,x=O.match(k5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Nx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Ux({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${bO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},wS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=g5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function B1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var qS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var fS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var bS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Nx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Ux({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=bO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},kS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},y5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function gS($){for(let O of $.security??[]){if(y5($,O.name))continue;let j=await qS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var L1=($)=>wS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:bS($.querySerializer),url:$.url}),N1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Ix($.headers,O.headers),j},v5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Ix=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?v5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class zx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var yS=()=>({error:new zx,request:new zx,response:new zx}),h5=bS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),m5={"Content-Type":"application/json"},Yj=($={})=>({...fS,headers:m5,parseAs:"auto",querySerializer:h5,...$});var U1=($={})=>{let O=N1(Yj(),$),j=()=>({...O}),x=(Q)=>{return O=N1(O,Q),j()},S=yS(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:Ix(O.headers,Q.headers),serializedBody:void 0};if(J.security)await gS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=L1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:B1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?kS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return ES({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:B1(I),url:z})};return{buildUrl:(Q)=>L1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var vS=U1(Yj());class hS{client;constructor($){this.client=$?.client??vS}}class mS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Tx extends hS{static __registry=new mS;constructor($){super($);Tx.__registry.set(this,$?.key)}scheduledActionHealth($){return($?.client??this.client).get({url:"/health",...$})}listScheduledActions($){return($?.client??this.client).get({url:"/scheduled-actions",...$})}createScheduledAction($){return($.client??this.client).post({url:"/scheduled-actions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteScheduledAction($){return($.client??this.client).delete({url:"/scheduled-actions/{id}",...$})}getScheduledAction($){return($.client??this.client).get({url:"/scheduled-actions/{id}",...$})}updateScheduledAction($){return($.client??this.client).put({url:"/scheduled-actions/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}setScheduledActionEnabled($){return($.client??this.client).put({url:"/scheduled-actions/{id}/enabled",...$,headers:{"Content-Type":"application/json",...$.headers}})}executeScheduledActionNow($){return($.client??this.client).post({url:"/scheduled-actions/{id}/execute",...$})}listScheduledActionHistory($){return($.client??this.client).get({url:"/scheduled-actions/{id}/history",...$})}}function cS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var c5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},u5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},d5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Hx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(u5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=c5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return kO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},kO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Rx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=d5(x),X=Object.entries(S).map(([Y,L])=>kO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var l5=/\{[^{}]+\}/g,r5=({path:$,url:O})=>{let j=O,x=O.match(l5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Hx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Rx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${kO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},uS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=r5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function z1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var dS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var lS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var rS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Hx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Rx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=kO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},pS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},p5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function aS($){for(let O of $.security??[]){if(p5($,O.name))continue;let j=await dS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var I1=($)=>uS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:rS($.querySerializer),url:$.url}),T1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Cx($.headers,O.headers),j},a5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Cx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?a5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Dx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var iS=()=>({error:new Dx,request:new Dx,response:new Dx}),i5=rS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),n5={"Content-Type":"application/json"},Qj=($={})=>({...lS,headers:n5,parseAs:"auto",querySerializer:i5,...$});var H1=($={})=>{let O=T1(Qj(),$),j=()=>({...O}),x=(G)=>{return O=T1(O,G),j()},S=iS(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Cx(O.headers,G.headers),serializedBody:void 0};if(J.security)await aS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=I1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:z1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?pS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return cS({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:z1(I),url:z})};return{buildUrl:(G)=>I1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var nS=H1(Qj());class sS{client;constructor($){this.client=$?.client??nS}}class tS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class _x extends sS{static __registry=new tS;constructor($){super($);_x.__registry.set(this,$?.key)}unifiedSearch($){return($.client??this.client).post({url:"/search",...$,headers:{"Content-Type":"application/json",...$.headers}})}simpleUnifiedSearch($){return($.client??this.client).post({url:"/search/simple",...$,headers:{"Content-Type":"application/json",...$.headers}})}}var eS=($,O,j)=>{if(typeof j==="string"||j instanceof Blob)$.append(O,j);else if(j instanceof Date)$.append(O,j.toISOString());else $.append(O,JSON.stringify(j))};var R1={bodySerializer:($)=>{let O=new FormData;return Object.entries($).forEach(([j,x])=>{if(x===void 0||x===null)return;if(Array.isArray(x))x.forEach((S)=>eS(O,j,S));else eS(O,j,x)}),O}},D1={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};function oS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var c5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},u5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},d5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Hx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(u5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=c5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return kO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},kO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Rx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=d5(x),X=Object.entries(S).map(([Y,L])=>kO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var l5=/\{[^{}]+\}/g,r5=({path:$,url:O})=>{let j=O,x=O.match(l5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Hx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Rx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${kO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},uS=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=r5({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function z1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var dS=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var lS={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var rS=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Hx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Rx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=kO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},pS=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},p5=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function aS($){for(let O of $.security??[]){if(p5($,O.name))continue;let j=await dS(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var I1=($)=>uS({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:rS($.querySerializer),url:$.url}),T1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=_x($.headers,O.headers),j},a5=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},_x=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?a5(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Dx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var iS=()=>({error:new Dx,request:new Dx,response:new Dx}),i5=rS({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),n5={"Content-Type":"application/json"},Gj=($={})=>({...lS,headers:n5,parseAs:"auto",querySerializer:i5,...$});var H1=($={})=>{let O=T1(Gj(),$),j=()=>({...O}),x=(Q)=>{return O=T1(O,Q),j()},S=iS(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:_x(O.headers,Q.headers),serializedBody:void 0};if(J.security)await aS(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=I1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:z1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?pS(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return cS({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:z1(I),url:z})};return{buildUrl:(Q)=>I1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var nS=H1(Gj());class sS{client;constructor($){this.client=$?.client??nS}}class tS{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Cx extends sS{static __registry=new tS;constructor($){super($);Cx.__registry.set(this,$?.key)}unifiedSearch($){return($.client??this.client).post({url:"/search",...$,headers:{"Content-Type":"application/json",...$.headers}})}simpleUnifiedSearch($){return($.client??this.client).post({url:"/search/simple",...$,headers:{"Content-Type":"application/json",...$.headers}})}}var eS=($,O,j)=>{if(typeof j==="string"||j instanceof Blob)$.append(O,j);else if(j instanceof Date)$.append(O,j.toISOString());else $.append(O,JSON.stringify(j))};var R1={bodySerializer:($)=>{let O=new FormData;return Object.entries($).forEach(([j,x])=>{if(x===void 0||x===null)return;if(Array.isArray(x))x.forEach((S)=>eS(O,j,S));else eS(O,j,x)}),O}},D1={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};function oS({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var s5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},t5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},e5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Px=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(t5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=s5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return gO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},gO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Mx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=e5(x),X=Object.entries(S).map(([Y,L])=>gO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var o5=/\{[^{}]+\}/g,$4=({path:$,url:O})=>{let j=O,x=O.match(o5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Px({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Mx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${gO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},$6=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=$4({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function C1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var O6=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var j6=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Px({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Mx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=gO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},x6=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},O4=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function S6($){for(let O of $.security??[]){if(O4($,O.name))continue;let j=await O6(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var _1=($)=>$6({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:j6($.querySerializer),url:$.url}),P1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Fx($.headers,O.headers),j},j4=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Fx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?j4(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Ax{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var Z6=()=>({error:new Ax,request:new Ax,response:new Ax}),x4=j6({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),S4={"Content-Type":"application/json"},Gj=($={})=>({...D1,headers:S4,parseAs:"auto",querySerializer:x4,...$});var Jj=($={})=>{let O=P1(Gj(),$),j=()=>({...O}),x=(G)=>{return O=P1(O,G),j()},S=Z6(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:Fx(O.headers,G.headers),serializedBody:void 0};if(J.security)await S6(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=_1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:C1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?x6(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return oS({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:C1(I),url:z})};return{buildUrl:(G)=>_1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var X6=Jj(Gj());class K6{client;constructor($){this.client=$?.client??X6}}class Y6{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Ex extends K6{static __registry=new Y6;constructor($){super($);Ex.__registry.set(this,$?.key)}listAgents($){return($?.client??this.client).get({url:"/agents",...$})}createAgent($){return($.client??this.client).post({url:"/agents",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAgent($){return($.client??this.client).put({url:"/agents/{agent_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteAnchor($){return($.client??this.client).delete({url:"/annotations/anchors",...$,headers:{"Content-Type":"application/json",...$.headers}})}editAnchor($){return($.client??this.client).patch({url:"/annotations/anchors",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentAnchors($){return($.client??this.client).get({url:"/annotations/anchors/document/{document_id}",...$})}createAnchor($){return($.client??this.client).post({url:"/annotations/anchors/document/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSelfBot($){return($?.client??this.client).get({url:"/bots/me",...$})}getBotOwnerProfiles($){return($?.client??this.client).get({url:"/bots/profiles",...$})}listBotChannels($){return($.client??this.client).get({url:"/bots/{bot_id}/channels",...$})}removeBotFromChannelByBot($){return($.client??this.client).delete({url:"/bots/{bot_id}/channels/{channel_id}",...$})}listOccurrences($){return($.client??this.client).get({url:"/calendar-events",...$})}mentionPreviews($){return($.client??this.client).post({url:"/calendar-events/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}listTeamCalendar($){return($.client??this.client).get({url:"/calendar-events/team",...$})}listTeamOutOfOffice($){return($.client??this.client).get({url:"/calendar-events/team-out-of-office",...$})}eventIcs($){return($.client??this.client).get({url:"/calendar-events/{event_id}/ics",...$})}listJoinRequests($){return($.client??this.client).get({url:"/calendar-events/{event_id}/join-requests",...$})}requestToJoin($){return($.client??this.client).post({url:"/calendar-events/{event_id}/join-requests",...$})}getActiveCalls($){return($?.client??this.client).get({url:"/call/active",...$})}guestCallChatRead($){return($.client??this.client).get({url:"/call/guest-chat/{call_id}",...$})}guestCallChatPost($){return($.client??this.client).post({url:"/call/guest-chat/{call_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingLookup($){return($.client??this.client).get({url:"/call/join/{token}",...$})}meetingGuestJoin($){return($.client??this.client).post({url:"/call/join/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingLeave($){return($.client??this.client).post({url:"/call/join/{token}/leave",...$})}meetingGuestParticipants($){return($.client??this.client).get({url:"/call/join/{token}/participants",...$})}meetingList($){return($?.client??this.client).get({url:"/call/meetings",...$})}meetingCreate($){return($.client??this.client).post({url:"/call/meetings",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingListActive($){return($?.client??this.client).get({url:"/call/meetings/active",...$})}meetingInvitePermissions($){return($.client??this.client).get({url:"/call/meetings/invite/{token}",...$})}meetingInvite($){return($.client??this.client).post({url:"/call/meetings/invite/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingInviteUsers($){return($.client??this.client).post({url:"/call/meetings/invite/{token}/users",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingJoin($){return($.client??this.client).post({url:"/call/meetings/join/{token}",...$})}meetingParticipants($){return($.client??this.client).get({url:"/call/meetings/join/{token}/participants",...$})}meetingPrepare($){return($?.client??this.client).post({url:"/call/meetings/prepare",...$})}meetingCancelPreparation($){return($.client??this.client).delete({url:"/call/meetings/prepare/{preparation_id}",...$})}meetingCancel($){return($.client??this.client).delete({url:"/call/meetings/{meeting_id}",...$})}meetingUpdate($){return($.client??this.client).patch({url:"/call/meetings/{meeting_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBatchCallRecordPreview($){return($.client??this.client).post({url:"/call/record/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCallRecord($){return($.client??this.client).delete({url:"/call/record/{call_id}",...$})}getCallRecord($){return($.client??this.client).get({url:"/call/record/{call_id}",...$})}editCallRecord($){return($.client??this.client).patch({url:"/call/record/{call_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}declineCall($){return($.client??this.client).post({url:"/call/record/{call_id}/decline",...$})}meetingShare($){return($.client??this.client).post({url:"/call/record/{call_id}/link",...$})}toggleShareWithTeam($){return($.client??this.client).post({url:"/call/record/{call_id}/share-with-team/toggle",...$})}editCallTranscript($){return($.client??this.client).patch({url:"/call/record/{call_id}/transcript",...$,headers:{"Content-Type":"application/json",...$.headers}})}getRingStatus($){return($.client??this.client).get({url:"/call/ring-status/{call_id}",...$})}declineRing($){return($.client??this.client).post({url:"/call/ring-status/{call_id}/decline",...$})}callWebhook($){return($?.client??this.client).post({url:"/call/webhook",...$})}leaveOrEndCall($){return($.client??this.client).delete({url:"/call/{channel_id}",...$})}getOrCreateCall($){return($.client??this.client).get({url:"/call/{channel_id}",...$})}checkActiveCall($){return($.client??this.client).get({url:"/call/{channel_id}/active",...$})}ingestTranscript($){return($.client??this.client).post({url:"/call/{room_name}/transcript",...$,headers:{"Content-Type":"application/json",...$.headers}})}listChannelLabels($){return($?.client??this.client).get({url:"/channel-labels",...$})}createChannelLabel($){return($.client??this.client).post({url:"/channel-labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}setChannelLabel($){return($.client??this.client).put({url:"/channel-labels/channels/{channel_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}previewSmartTag($){return($.client??this.client).post({url:"/channel-labels/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteChannelLabel($){return($.client??this.client).delete({url:"/channel-labels/{label_id}",...$})}renameChannelLabel($){return($.client??this.client).patch({url:"/channel-labels/{label_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}createChannel($){return($.client??this.client).post({url:"/channels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getActivity($){return($?.client??this.client).get({url:"/channels/activity",...$})}postActivity($){return($.client??this.client).post({url:"/channels/activity",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAttachmentReferences($){return($.client??this.client).get({url:"/channels/attachments/{entity_type}/{entity_id}/references",...$})}getOrCreateDm($){return($.client??this.client).post({url:"/channels/get_or_create_dm",...$,headers:{"Content-Type":"application/json",...$.headers}})}getOrCreatePrivate($){return($.client??this.client).post({url:"/channels/get_or_create_private",...$,headers:{"Content-Type":"application/json",...$.headers}})}joinChannelByCode($){return($.client??this.client).post({url:"/channels/join/{join_code}",...$})}createEntityMention($){return($.client??this.client).post({url:"/channels/mentions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteEntityMention($){return($.client??this.client).delete({url:"/channels/mentions/{mention_id}",...$})}getBatchChannelPreview($){return($.client??this.client).post({url:"/channels/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteChannel($){return($.client??this.client).delete({url:"/channels/{channel_id}",...$})}getChannel($){return($.client??this.client).get({url:"/channels/{channel_id}",...$})}patchChannel($){return($.client??this.client).patch({url:"/channels/{channel_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChannelAttachments($){return($.client??this.client).get({url:"/channels/{channel_id}/attachments",...$})}createChannelScopedBot($){return($.client??this.client).post({url:"/channels/{channel_id}/bots/scoped",...$,headers:{"Content-Type":"application/json",...$.headers}})}joinChannel($){return($.client??this.client).post({url:"/channels/{channel_id}/join",...$})}getChannelJoinLink($){return($.client??this.client).get({url:"/channels/{channel_id}/join-link",...$})}leaveChannel($){return($.client??this.client).post({url:"/channels/{channel_id}/leave",...$})}removeParticipants($){return($.client??this.client).delete({url:"/channels/{channel_id}/participants",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChannelParticipants($){return($.client??this.client).get({url:"/channels/{channel_id}/participants",...$})}addParticipants($){return($.client??this.client).post({url:"/channels/{channel_id}/participants",...$,headers:{"Content-Type":"application/json",...$.headers}})}setChannelPicture($){return($.client??this.client).put({url:"/channels/{channel_id}/profile_picture",...$,headers:{"Content-Type":"application/json",...$.headers}})}postChannelBotWebhook($){return($.client??this.client).post({url:"/channels/{channel_id}/webhook",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCollabSurface($){return($.client??this.client).delete({url:"/collab_surfaces/{id}",...$})}getCollabSurface($){return($.client??this.client).get({url:"/collab_surfaces/{id}",...$})}ensureCollabSurface($){return($.client??this.client).put({url:"/collab_surfaces/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}createCollabSurfaceToken($){return($.client??this.client).post({url:"/collab_surfaces/{id}/token",...$})}getChannels($){return($?.client??this.client).get({url:"/comms/channels",...$})}createCrmCompany($){return($.client??this.client).post({url:"/crm/companies",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCompany($){return($.client??this.client).get({url:"/crm/companies/{company_id}",...$})}listCompanyContacts($){return($.client??this.client).get({url:"/crm/companies/{company_id}/contacts",...$})}createCrmContact($){return($.client??this.client).post({url:"/crm/companies/{company_id}/contacts",...$,headers:{"Content-Type":"application/json",...$.headers}})}setEmailSync($){return($.client??this.client).put({url:"/crm/companies/{company_id}/email-sync",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCompanyHidden($){return($.client??this.client).put({url:"/crm/companies/{company_id}/hidden",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCrmCompanyName($){return($.client??this.client).put({url:"/crm/companies/{company_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}searchContacts($){return($?.client??this.client).get({url:"/crm/contacts",...$})}getContactByEmail($){return($.client??this.client).get({url:"/crm/contacts/by-email",...$})}getContact($){return($.client??this.client).get({url:"/crm/contacts/{contact_id}",...$})}setContactHidden($){return($.client??this.client).put({url:"/crm/contacts/{contact_id}/hidden",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCrmContactName($){return($.client??this.client).put({url:"/crm/contacts/{contact_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCrmPipelines($){return($?.client??this.client).get({url:"/crm/pipelines",...$})}createCrmPipeline($){return($.client??this.client).post({url:"/crm/pipelines",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipeline($){return($.client??this.client).get({url:"/crm/pipelines/{id}",...$})}renameCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}applyCrmPipelineOps($){return($.client??this.client).post({url:"/crm/pipelines/{id}/ops",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelinePermissions($){return($.client??this.client).get({url:"/crm/pipelines/{id}/permissions",...$})}updateCrmPipelinePermissions($){return($.client??this.client).patch({url:"/crm/pipelines/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelineRows($){return($.client??this.client).get({url:"/crm/pipelines/{id}/rows",...$})}queryCrmPipelineRows($){return($.client??this.client).post({url:"/crm/pipelines/{id}/rows",...$,headers:{"Content-Type":"application/json",...$.headers}})}shareCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/sharing",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelineTable($){return($.client??this.client).get({url:"/crm/pipelines/{id}/table",...$})}trashCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/trash",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmTeamSettings($){return($?.client??this.client).get({url:"/crm/settings",...$})}putCrmTeamSettings($){return($.client??this.client).put({url:"/crm/settings",...$,headers:{"Content-Type":"application/json",...$.headers}})}resetCrmTeamStages($){return($?.client??this.client).delete({url:"/crm/stages",...$})}putCrmTeamStages($){return($.client??this.client).put({url:"/crm/stages",...$,headers:{"Content-Type":"application/json",...$.headers}})}listDatabases($){return($?.client??this.client).get({url:"/databases",...$})}createDatabase($){return($.client??this.client).post({url:"/databases",...$,headers:{"Content-Type":"application/json",...$.headers}})}saveDatabaseQuery($){return($.client??this.client).post({url:"/databases/queries",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseQuery($){return($.client??this.client).get({url:"/databases/queries/{query_id}",...$})}queryDatabases($){return($.client??this.client).post({url:"/databases/query",...$,headers:{"Content-Type":"application/json",...$.headers}})}ensureStarterHandler($){return($?.client??this.client).post({url:"/databases/starter",...$})}deliverDatabaseWebhook($){return($.client??this.client).post({url:"/databases/webhooks/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabase($){return($.client??this.client).get({url:"/databases/{id}",...$})}shareDatabaseAwareness($){return($.client??this.client).put({url:"/databases/{id}/awareness",...$,headers:{"Content-Type":"application/json",...$.headers}})}undoDatabaseChange($){return($.client??this.client).post({url:"/databases/{id}/changes/{change}/undo",...$})}importDatabaseTable($){return($.client??this.client).post({url:"/databases/{id}/import",...$,headers:{"Content-Type":"application/json",...$.headers}})}applyDatabaseOps($){return($.client??this.client).post({url:"/databases/{id}/ops",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabasePermissions($){return($.client??this.client).get({url:"/databases/{id}/permissions",...$})}updateDatabasePermissions($){return($.client??this.client).patch({url:"/databases/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseTableChanges($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/changes",...$})}listDatabaseColumnCasts($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/casts",...$})}convertDatabaseColumn($){return($.client??this.client).post({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/conversion",...$,headers:{"Content-Type":"application/json",...$.headers}})}inferDatabaseColumnType($){return($.client??this.client).post({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/infer-type",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseRowHistory($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/rows/{row_id}/history",...$})}getDatabaseViewPositions($){return($.client??this.client).get({url:"/databases/{id}/views/{view_id}/positions",...$})}listDatabaseWebhooks($){return($.client??this.client).get({url:"/databases/{id}/webhooks",...$})}createDatabaseWebhook($){return($.client??this.client).post({url:"/databases/{id}/webhooks",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteDatabaseWebhook($){return($.client??this.client).delete({url:"/databases/{id}/webhooks/{webhook_id}",...$})}transcribeDictation($){return($.client??this.client).post({bodySerializer:null,url:"/dictation/transcribe",...$,headers:{"Content-Type":"audio/webm",...$.headers}})}getUserDocumentsHandler($){return($.client??this.client).get({url:"/documents",...$})}createDocument($){return($.client??this.client).post({url:"/documents",...$,headers:{"Content-Type":"application/json",...$.headers}})}createCanvasHandler($){return($.client??this.client).post({url:"/documents/create_canvas",...$,headers:{"Content-Type":"application/json",...$.headers}})}createMarkdownHandler($){return($.client??this.client).post({url:"/documents/create_markdown",...$,headers:{"Content-Type":"application/json",...$.headers}})}createSkillHandler($){return($.client??this.client).post({url:"/documents/create_skill",...$,headers:{"Content-Type":"application/json",...$.headers}})}createSnippetHandler($){return($.client??this.client).post({url:"/documents/create_snippet",...$,headers:{"Content-Type":"application/json",...$.headers}})}createTaskHandler($){return($.client??this.client).post({url:"/documents/create_task",...$,headers:{"Content-Type":"application/json",...$.headers}})}getGithubPullRequestTasks($){return($.client??this.client).post({url:"/documents/github_prs/tasks",...$,headers:{"Content-Type":"application/json",...$.headers}})}initializeUserDocuments($){return($?.client??this.client).post({url:"/documents/initialize_user_documents",...$})}getDocumentListHandler($){return($?.client??this.client).get({url:"/documents/list",...$})}validateDocumentPermissionsToken($){return($.client??this.client).post({url:"/documents/permissions_token/validate",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentPermissionsToken($){return($.client??this.client).post({url:"/documents/permissions_token/{document_id}",...$})}presaveDocumentHandler($){return($.client??this.client).put({url:"/documents/presave/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBatchPreviewHandler($){return($.client??this.client).post({url:"/documents/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentByTeamSlug($){return($.client??this.client).get({url:"/documents/slug/{slug}",...$})}handler($){return($?.client??this.client).get({url:"/documents/starter_docs",...$})}getSystemSkillsHandler($){return($?.client??this.client).get({url:"/documents/system_skills",...$})}deleteDocument($){return($.client??this.client).delete({url:"/documents/{document_id}",...$})}getDocument($){return($.client??this.client).get({url:"/documents/{document_id}",...$})}editDocument($){return($.client??this.client).patch({url:"/documents/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}saveDocumentHandler($){return($.client??this.client).put({url:"/documents/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentBranchName($){return($.client??this.client).get({url:"/documents/{document_id}/branch_name",...$})}copyDocument($){return($.client??this.client).post({url:"/documents/{document_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}exportDocument($){return($.client??this.client).get({url:"/documents/{document_id}/export",...$})}getDocumentGithubPullRequests($){return($.client??this.client).get({url:"/documents/{document_id}/github_prs",...$})}getLocationHandler($){return($.client??this.client).get({url:"/documents/{document_id}/location",...$})}getDocumentLocationV3($){return($.client??this.client).get({url:"/documents/{document_id}/location_v3",...$})}permanentlyDeleteDocument($){return($.client??this.client).delete({url:"/documents/{document_id}/permanent",...$})}getDocumentProcessingResult($){return($.client??this.client).get({url:"/documents/{document_id}/processing",...$})}jobProcessingResultHandler($){return($.client??this.client).get({url:"/documents/{document_id}/processing/{job_id}",...$})}revertDeleteDocument($){return($.client??this.client).put({url:"/documents/{document_id}/revert_delete",...$})}getDocumentShortId($){return($.client??this.client).get({url:"/documents/{document_id}/short_id",...$})}simpleSave($){return($.client??this.client).put({url:"/documents/{document_id}/simple_save",...$})}getDocumentTeamShare($){return($.client??this.client).get({url:"/documents/{document_id}/team_share",...$})}setDocumentTeamShare($){return($.client??this.client).put({url:"/documents/{document_id}/team_share",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentTextContent($){return($.client??this.client).get({url:"/documents/{document_id}/text-content",...$})}getDocumentViewsHandler($){return($.client??this.client).get({url:"/documents/{document_id}/views",...$})}getDocumentVersion($){return($.client??this.client).get({url:"/documents/{document_id}/{document_version_id}",...$})}accessRequestsState($){return($.client??this.client).get({url:"/entities/{entity_type}/{entity_id}/access-requests",...$})}accessRequestsCancel($){return($.client??this.client).delete({url:"/entities/{entity_type}/{entity_id}/access-requests/mine",...$})}accessRequestsSubmit($){return($.client??this.client).put({url:"/entities/{entity_type}/{entity_id}/access-requests/mine",...$,headers:{"Content-Type":"application/json",...$.headers}})}accessRequestsResolve($){return($.client??this.client).post({url:"/entities/{entity_type}/{entity_id}/access-requests/{request_id}/resolve",...$,headers:{"Content-Type":"application/json",...$.headers}})}accessRequestsDirect($){return($.client??this.client).get({url:"/entities/{entity_type}/{entity_id}/direct-access",...$})}accessRequestsRemoveDirect($){return($.client??this.client).delete({url:"/entities/{entity_type}/{entity_id}/direct-access/{user_id}",...$})}accessRequestsSetDirect($){return($.client??this.client).put({url:"/entities/{entity_type}/{entity_id}/direct-access/{user_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getEntityPermission($){return($.client??this.client).get({url:"/entity/{entity_type}/{entity_id}/permissions",...$})}listFavorites($){return($?.client??this.client).get({url:"/favorites",...$})}addFavorite($){return($.client??this.client).post({url:"/favorites",...$,headers:{"Content-Type":"application/json",...$.headers}})}reorderFavorites($){return($.client??this.client).patch({url:"/favorites/reorder",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeFavoriteByEntity($){return($.client??this.client).delete({url:"/favorites/{entity_type}/{entity_id}",...$})}getForeignEntityBySource($){return($.client??this.client).get({url:"/foreign_entity/by_source/{source}/{foreign_entity_id}",...$})}getForeignEntity($){return($.client??this.client).get({url:"/foreign_entity/{id}",...$})}listForms($){return($.client??this.client).get({url:"/forms",...$})}createForm($){return($.client??this.client).post({url:"/forms",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAccessibleForms($){return($?.client??this.client).get({url:"/forms/accessible",...$})}getForm($){return($.client??this.client).get({url:"/forms/{id}",...$})}updateForm($){return($.client??this.client).patch({url:"/forms/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}collaborateForm($){return($.client??this.client).post({url:"/forms/{id}/collaboration",...$})}putFormLayout($){return($.client??this.client).put({url:"/forms/{id}/layout",...$,headers:{"Content-Type":"application/json",...$.headers}})}getFormPermissions($){return($.client??this.client).get({url:"/forms/{id}/permissions",...$})}updateFormPermissions($){return($.client??this.client).patch({url:"/forms/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}submitFormResponse($){return($.client??this.client).post({url:"/forms/{id}/responses",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMyFormResponse($){return($.client??this.client).get({url:"/forms/{id}/responses/mine",...$})}editMyFormResponse($){return($.client??this.client).put({url:"/forms/{id}/responses/mine",...$,headers:{"Content-Type":"application/json",...$.headers}})}getFormResponseSummary($){return($.client??this.client).get({url:"/forms/{id}/responses/summary",...$})}getFormTally($){return($.client??this.client).get({url:"/forms/{id}/tally",...$})}installSync($){return($?.client??this.client).get({url:"/github/install-sync",...$})}getGithubPullRequestFacets($){return($?.client??this.client).get({url:"/github_pull_requests/facets",...$})}getGithubPullRequest($){return($.client??this.client).get({url:"/github_pull_requests/{id}",...$})}getGithubPullRequestChanges($){return($.client??this.client).get({url:"/github_pull_requests/{id}/changes",...$})}getGithubPullRequestChangesPatch($){return($.client??this.client).get({url:"/github_pull_requests/{id}/changes/patch",...$})}createHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings",...$,headers:{"Content-Type":"application/json",...$.headers}})}getHarnessPairing($){return($.client??this.client).get({url:"/harness-pairings/{code}",...$})}approveHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings/{code}/approve",...$,headers:{"Content-Type":"application/json",...$.headers}})}claimHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings/{pairing_id}/claim",...$,headers:{"Content-Type":"application/json",...$.headers}})}listHarnesses($){return($?.client??this.client).get({url:"/harnesses",...$})}deleteSelfHarness($){return($?.client??this.client).delete({url:"/harnesses/me",...$})}getSelfHarness($){return($?.client??this.client).get({url:"/harnesses/me",...$})}listHarnessAgents($){return($?.client??this.client).get({url:"/harnesses/me/agents",...$})}listHarnessSessions($){return($?.client??this.client).get({url:"/harnesses/me/sessions",...$})}deleteHarness($){return($.client??this.client).delete({url:"/harnesses/{harness_id}",...$})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}getHistoryHandler($){return($?.client??this.client).get({url:"/history",...$})}deleteHistoryHandler($){return($.client??this.client).delete({url:"/history/{item_type}/{item_id}",...$})}upsertHistoryHandler($){return($.client??this.client).post({url:"/history/{item_type}/{item_id}",...$})}listInitiatives($){return($?.client??this.client).get({url:"/initiatives",...$})}createInitiative($){return($.client??this.client).post({url:"/initiatives",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteInitiative($){return($.client??this.client).delete({url:"/initiatives/{initiative_id}",...$})}getInitiative($){return($.client??this.client).get({url:"/initiatives/{initiative_id}",...$})}updateInitiative($){return($.client??this.client).patch({url:"/initiatives/{initiative_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getInstructionsHandler($){return($?.client??this.client).get({url:"/instructions",...$})}createInstructionsHandler($){return($?.client??this.client).post({url:"/instructions",...$})}getItemsSoup($){return($?.client??this.client).get({url:"/items/soup",...$})}postItemsSoup($){return($.client??this.client).post({url:"/items/soup",...$,headers:{"Content-Type":"application/json",...$.headers}})}postItemsSoupAst($){return($.client??this.client).post({url:"/items/soup/ast",...$,headers:{"Content-Type":"application/json",...$.headers}})}postItemsSoupAstGrouped($){return($.client??this.client).post({url:"/items/soup/ast/grouped",...$,headers:{"Content-Type":"application/json",...$.headers}})}messageTimeline($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}",...$})}entityMessageCreate($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageDeleteMessage($){return($.client??this.client).delete({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$})}entityMessageGetMessage($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$})}entityMessageEdit($){return($.client??this.client).patch({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageReact($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}/items/{id}/reactions",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageLegacy($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/legacy/{legacy_id}",...$})}entityMessageDeleteThread($){return($.client??this.client).delete({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$})}entityMessageGetThread($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$})}entityMessagePatchThread($){return($.client??this.client).patch({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}messageTimelineEntries($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/timeline",...$})}entityMessageTyping($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}/typing",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedAccount($){return($?.client??this.client).get({url:"/meta/linked/account",...$})}linkedConfiguration($){return($?.client??this.client).get({url:"/meta/linked/configuration",...$})}linkedConnect($){return($.client??this.client).post({url:"/meta/linked/connect",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedDisconnect($){return($.client??this.client).post({url:"/meta/linked/disconnect",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedGroups($){return($?.client??this.client).get({url:"/meta/linked/groups",...$})}linkedAdopt($){return($.client??this.client).post({url:"/meta/linked/groups/adopt",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedCancelPairing($){return($.client??this.client).delete({url:"/meta/linked/pairing/{id}",...$})}linkedPairing($){return($.client??this.client).get({url:"/meta/linked/pairing/{id}",...$})}linkedPasskey($){return($.client??this.client).post({url:"/meta/linked/pairing/{id}/passkey",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroups($){return($?.client??this.client).get({url:"/meta/linked/whatsapp-groups",...$})}linkedDetach($){return($.client??this.client).delete({url:"/meta/linked/whatsapp-groups/{group_id}",...$})}whatsappGroup($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}",...$})}linkedUpload($){return($.client??this.client).post({...R1,url:"/meta/linked/whatsapp-groups/{group_id}/attachments",...$,headers:{"Content-Type":null,...$.headers}})}linkedDelivery($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/delivery",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupMessages($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/messages",...$})}linkedMessageAttachments($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/messages/attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupPermissions($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/permissions",...$})}whatsappGroupUpdatePermissions($){return($.client??this.client).patch({url:"/meta/linked/whatsapp-groups/{group_id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupRead($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/read",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupSends($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/sends",...$})}linkedReply($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/sends",...$,headers:{"Content-Type":"application/json",...$.headers}})}getPinsHandler($){return($?.client??this.client).get({url:"/pins",...$})}reorderPinsHandler($){return($.client??this.client).patch({url:"/pins",...$,headers:{"Content-Type":"application/json",...$.headers}})}removePinHandler($){return($.client??this.client).delete({url:"/pins/{pinned_item_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}addPinHandler($){return($.client??this.client).post({url:"/pins/{pinned_item_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getProjectsHandler($){return($?.client??this.client).get({url:"/projects",...$})}createProjectHandler($){return($.client??this.client).post({url:"/projects",...$,headers:{"Content-Type":"application/json",...$.headers}})}getPendingProjectsHandler($){return($?.client??this.client).get({url:"/projects/pending",...$})}getBatchProjectPreview($){return($.client??this.client).post({url:"/projects/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}uploadFolderHandler($){return($.client??this.client).post({url:"/projects/upload",...$,headers:{"Content-Type":"application/json",...$.headers}})}uploadExtractFolderHandler($){return($.client??this.client).post({url:"/projects/upload_extract",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteProjectHandler($){return($.client??this.client).delete({url:"/projects/{id}",...$})}getProjectHandler($){return($.client??this.client).get({url:"/projects/{id}",...$})}getProjectUserAccessLevel($){return($.client??this.client).get({url:"/projects/{id}/access_level",...$})}getProjectContentHandler($){return($.client??this.client).get({url:"/projects/{id}/content",...$})}permanentlyDeleteProject($){return($.client??this.client).delete({url:"/projects/{id}/permanent",...$})}getProjectPermissionsV2($){return($.client??this.client).get({url:"/projects/{id}/permissions",...$})}revertDeleteProject($){return($.client??this.client).put({url:"/projects/{id}/revert_delete",...$})}recentlyDeleted($){return($?.client??this.client).get({url:"/recents/deleted",...$})}listEmailReminders($){return($?.client??this.client).get({url:"/reminders/email/collection",...$})}getEmailFollowup($){return($.client??this.client).get({url:"/reminders/email/{thread_id}",...$})}setEmailFollowup($){return($.client??this.client).put({url:"/reminders/email/{thread_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getViewsHandler($){return($?.client??this.client).get({url:"/saved_views",...$})}createViewHandler($){return($.client??this.client).post({url:"/saved_views",...$,headers:{"Content-Type":"application/json",...$.headers}})}excludeDefaultViewHandler($){return($.client??this.client).post({url:"/saved_views/exclude_default",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteViewHandler($){return($.client??this.client).delete({url:"/saved_views/{saved_view_id}",...$})}patchViewHandler($){return($.client??this.client).patch({url:"/saved_views/{saved_view_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listSlackImports($){return($?.client??this.client).get({url:"/slack/imports",...$})}createSlackImport($){return($.client??this.client).post({url:"/slack/imports",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSlackImport($){return($.client??this.client).get({url:"/slack/imports/{job_id}",...$})}cancelSlackImport($){return($.client??this.client).post({url:"/slack/imports/{job_id}/cancel",...$})}finalizeSlackImport($){return($.client??this.client).post({url:"/slack/imports/{job_id}/finalize",...$})}registerSlackImportUploads($){return($.client??this.client).post({url:"/slack/imports/{job_id}/uploads",...$,headers:{"Content-Type":"application/json",...$.headers}})}completeSlackImportUploads($){return($.client??this.client).post({url:"/slack/imports/{job_id}/uploads/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkWakeupSyncServiceDocuments($){return($.client??this.client).post({url:"/sync_service/wakeup",...$,headers:{"Content-Type":"application/json",...$.headers}})}editThreadV2($){return($.client??this.client).patch({url:"/threads/{thread_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listUserApiKeys($){return($?.client??this.client).get({url:"/user-api-keys",...$})}createUserApiKey($){return($.client??this.client).post({url:"/user-api-keys",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteUserApiKey($){return($.client??this.client).delete({url:"/user-api-keys/{id}",...$})}deleteUserDocumentViewLocation($){return($.client??this.client).delete({url:"/user_document_view_location/{document_id}",...$})}getUserDocumentViewLocation($){return($.client??this.client).get({url:"/user_document_view_location/{document_id}",...$})}upsertUserDocumentViewLocation($){return($.client??this.client).post({url:"/user_document_view_location/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentPermissionsV2($){return($.client??this.client).get({url:"/v2/documents/{document_id}/permissions",...$})}editProjectV2($){return($.client??this.client).patch({url:"/v2/projects/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}streamEvents($){return($.client??this.client).sse.get({url:"/webhook/events/stream",...$})}listWebhooks($){return($?.client??this.client).get({url:"/webhook/webhooks",...$})}createWebhook($){return($.client??this.client).post({url:"/webhook/webhooks",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteWebhook($){return($.client??this.client).delete({url:"/webhook/webhooks/{webhook_id}",...$})}getWebhook($){return($.client??this.client).get({url:"/webhook/webhooks/{webhook_id}",...$})}patchWebhook($){return($.client??this.client).patch({url:"/webhook/webhooks/{webhook_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}validateWebhook($){return($.client??this.client).post({url:"/webhook/webhooks/{webhook_id}/validate",...$})}}function Q6({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...G}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=G.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=G.headers instanceof Headers?G.headers:new Headers(G.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...G,body:G.serializedBody,headers:A,signal:T},C=new Request(L,D);if($)C=await $(L,D);let N=await(G.fetch??globalThis.fetch)(C);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var s5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},t5=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},e5=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},Px=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(t5(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=s5(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return gO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},gO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},Mx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=e5(x),X=Object.entries(S).map(([Y,L])=>gO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var o5=/\{[^{}]+\}/g,$4=({path:$,url:O})=>{let j=O,x=O.match(o5);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,Px({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,Mx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${gO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},$6=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=$4({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function _1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var O6=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var j6=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=Px({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=Mx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=gO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},x6=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},O4=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function S6($){for(let O of $.security??[]){if(O4($,O.name))continue;let j=await O6(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var C1=($)=>$6({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:j6($.querySerializer),url:$.url}),P1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=Fx($.headers,O.headers),j},j4=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},Fx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?j4(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class Ax{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var Z6=()=>({error:new Ax,request:new Ax,response:new Ax}),x4=j6({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),S4={"Content-Type":"application/json"},Qj=($={})=>({...D1,headers:S4,parseAs:"auto",querySerializer:x4,...$});var Jj=($={})=>{let O=P1(Qj(),$),j=()=>({...O}),x=(Q)=>{return O=P1(O,Q),j()},S=Z6(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:Fx(O.headers,Q.headers),serializedBody:void 0};if(J.security)await S6(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=C1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:_1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?x6(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return oS({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:_1(I),url:z})};return{buildUrl:(Q)=>C1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var X6=Jj(Qj());class K6{client;constructor($){this.client=$?.client??X6}}class Y6{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class Ex extends K6{static __registry=new Y6;constructor($){super($);Ex.__registry.set(this,$?.key)}listAgents($){return($?.client??this.client).get({url:"/agents",...$})}createAgent($){return($.client??this.client).post({url:"/agents",...$,headers:{"Content-Type":"application/json",...$.headers}})}updateAgent($){return($.client??this.client).put({url:"/agents/{agent_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteAnchor($){return($.client??this.client).delete({url:"/annotations/anchors",...$,headers:{"Content-Type":"application/json",...$.headers}})}editAnchor($){return($.client??this.client).patch({url:"/annotations/anchors",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentAnchors($){return($.client??this.client).get({url:"/annotations/anchors/document/{document_id}",...$})}createAnchor($){return($.client??this.client).post({url:"/annotations/anchors/document/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSelfBot($){return($?.client??this.client).get({url:"/bots/me",...$})}getBotOwnerProfiles($){return($?.client??this.client).get({url:"/bots/profiles",...$})}listBotChannels($){return($.client??this.client).get({url:"/bots/{bot_id}/channels",...$})}removeBotFromChannelByBot($){return($.client??this.client).delete({url:"/bots/{bot_id}/channels/{channel_id}",...$})}listOccurrences($){return($.client??this.client).get({url:"/calendar-events",...$})}mentionPreviews($){return($.client??this.client).post({url:"/calendar-events/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}listTeamCalendar($){return($.client??this.client).get({url:"/calendar-events/team",...$})}listTeamOutOfOffice($){return($.client??this.client).get({url:"/calendar-events/team-out-of-office",...$})}eventIcs($){return($.client??this.client).get({url:"/calendar-events/{event_id}/ics",...$})}listJoinRequests($){return($.client??this.client).get({url:"/calendar-events/{event_id}/join-requests",...$})}requestToJoin($){return($.client??this.client).post({url:"/calendar-events/{event_id}/join-requests",...$})}getActiveCalls($){return($?.client??this.client).get({url:"/call/active",...$})}guestCallChatRead($){return($.client??this.client).get({url:"/call/guest-chat/{call_id}",...$})}guestCallChatPost($){return($.client??this.client).post({url:"/call/guest-chat/{call_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingLookup($){return($.client??this.client).get({url:"/call/join/{token}",...$})}meetingGuestJoin($){return($.client??this.client).post({url:"/call/join/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingLeave($){return($.client??this.client).post({url:"/call/join/{token}/leave",...$})}meetingGuestParticipants($){return($.client??this.client).get({url:"/call/join/{token}/participants",...$})}meetingList($){return($?.client??this.client).get({url:"/call/meetings",...$})}meetingCreate($){return($.client??this.client).post({url:"/call/meetings",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingListActive($){return($?.client??this.client).get({url:"/call/meetings/active",...$})}meetingInvitePermissions($){return($.client??this.client).get({url:"/call/meetings/invite/{token}",...$})}meetingInvite($){return($.client??this.client).post({url:"/call/meetings/invite/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingInviteUsers($){return($.client??this.client).post({url:"/call/meetings/invite/{token}/users",...$,headers:{"Content-Type":"application/json",...$.headers}})}meetingJoin($){return($.client??this.client).post({url:"/call/meetings/join/{token}",...$})}meetingParticipants($){return($.client??this.client).get({url:"/call/meetings/join/{token}/participants",...$})}meetingPrepare($){return($?.client??this.client).post({url:"/call/meetings/prepare",...$})}meetingCancelPreparation($){return($.client??this.client).delete({url:"/call/meetings/prepare/{preparation_id}",...$})}meetingCancel($){return($.client??this.client).delete({url:"/call/meetings/{meeting_id}",...$})}meetingUpdate($){return($.client??this.client).patch({url:"/call/meetings/{meeting_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBatchCallRecordPreview($){return($.client??this.client).post({url:"/call/record/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCallRecord($){return($.client??this.client).delete({url:"/call/record/{call_id}",...$})}getCallRecord($){return($.client??this.client).get({url:"/call/record/{call_id}",...$})}editCallRecord($){return($.client??this.client).patch({url:"/call/record/{call_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}declineCall($){return($.client??this.client).post({url:"/call/record/{call_id}/decline",...$})}meetingShare($){return($.client??this.client).post({url:"/call/record/{call_id}/link",...$})}toggleShareWithTeam($){return($.client??this.client).post({url:"/call/record/{call_id}/share-with-team/toggle",...$})}editCallTranscript($){return($.client??this.client).patch({url:"/call/record/{call_id}/transcript",...$,headers:{"Content-Type":"application/json",...$.headers}})}getRingStatus($){return($.client??this.client).get({url:"/call/ring-status/{call_id}",...$})}declineRing($){return($.client??this.client).post({url:"/call/ring-status/{call_id}/decline",...$})}callWebhook($){return($?.client??this.client).post({url:"/call/webhook",...$})}leaveOrEndCall($){return($.client??this.client).delete({url:"/call/{channel_id}",...$})}getOrCreateCall($){return($.client??this.client).get({url:"/call/{channel_id}",...$})}checkActiveCall($){return($.client??this.client).get({url:"/call/{channel_id}/active",...$})}ingestTranscript($){return($.client??this.client).post({url:"/call/{room_name}/transcript",...$,headers:{"Content-Type":"application/json",...$.headers}})}listChannelLabels($){return($?.client??this.client).get({url:"/channel-labels",...$})}createChannelLabel($){return($.client??this.client).post({url:"/channel-labels",...$,headers:{"Content-Type":"application/json",...$.headers}})}setChannelLabel($){return($.client??this.client).put({url:"/channel-labels/channels/{channel_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}previewSmartTag($){return($.client??this.client).post({url:"/channel-labels/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteChannelLabel($){return($.client??this.client).delete({url:"/channel-labels/{label_id}",...$})}renameChannelLabel($){return($.client??this.client).patch({url:"/channel-labels/{label_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}createChannel($){return($.client??this.client).post({url:"/channels",...$,headers:{"Content-Type":"application/json",...$.headers}})}getActivity($){return($?.client??this.client).get({url:"/channels/activity",...$})}postActivity($){return($.client??this.client).post({url:"/channels/activity",...$,headers:{"Content-Type":"application/json",...$.headers}})}getAttachmentReferences($){return($.client??this.client).get({url:"/channels/attachments/{entity_type}/{entity_id}/references",...$})}getOrCreateDm($){return($.client??this.client).post({url:"/channels/get_or_create_dm",...$,headers:{"Content-Type":"application/json",...$.headers}})}getOrCreatePrivate($){return($.client??this.client).post({url:"/channels/get_or_create_private",...$,headers:{"Content-Type":"application/json",...$.headers}})}joinChannelByCode($){return($.client??this.client).post({url:"/channels/join/{join_code}",...$})}createEntityMention($){return($.client??this.client).post({url:"/channels/mentions",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteEntityMention($){return($.client??this.client).delete({url:"/channels/mentions/{mention_id}",...$})}getBatchChannelPreview($){return($.client??this.client).post({url:"/channels/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteChannel($){return($.client??this.client).delete({url:"/channels/{channel_id}",...$})}getChannel($){return($.client??this.client).get({url:"/channels/{channel_id}",...$})}patchChannel($){return($.client??this.client).patch({url:"/channels/{channel_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChannelAttachments($){return($.client??this.client).get({url:"/channels/{channel_id}/attachments",...$})}createChannelScopedBot($){return($.client??this.client).post({url:"/channels/{channel_id}/bots/scoped",...$,headers:{"Content-Type":"application/json",...$.headers}})}joinChannel($){return($.client??this.client).post({url:"/channels/{channel_id}/join",...$})}getChannelJoinLink($){return($.client??this.client).get({url:"/channels/{channel_id}/join-link",...$})}leaveChannel($){return($.client??this.client).post({url:"/channels/{channel_id}/leave",...$})}removeParticipants($){return($.client??this.client).delete({url:"/channels/{channel_id}/participants",...$,headers:{"Content-Type":"application/json",...$.headers}})}getChannelParticipants($){return($.client??this.client).get({url:"/channels/{channel_id}/participants",...$})}addParticipants($){return($.client??this.client).post({url:"/channels/{channel_id}/participants",...$,headers:{"Content-Type":"application/json",...$.headers}})}setChannelPicture($){return($.client??this.client).put({url:"/channels/{channel_id}/profile_picture",...$,headers:{"Content-Type":"application/json",...$.headers}})}postChannelBotWebhook($){return($.client??this.client).post({url:"/channels/{channel_id}/webhook",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteCollabSurface($){return($.client??this.client).delete({url:"/collab_surfaces/{id}",...$})}getCollabSurface($){return($.client??this.client).get({url:"/collab_surfaces/{id}",...$})}ensureCollabSurface($){return($.client??this.client).put({url:"/collab_surfaces/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}createCollabSurfaceToken($){return($.client??this.client).post({url:"/collab_surfaces/{id}/token",...$})}getChannels($){return($?.client??this.client).get({url:"/comms/channels",...$})}createCrmCompany($){return($.client??this.client).post({url:"/crm/companies",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCompany($){return($.client??this.client).get({url:"/crm/companies/{company_id}",...$})}listCompanyContacts($){return($.client??this.client).get({url:"/crm/companies/{company_id}/contacts",...$})}createCrmContact($){return($.client??this.client).post({url:"/crm/companies/{company_id}/contacts",...$,headers:{"Content-Type":"application/json",...$.headers}})}setEmailSync($){return($.client??this.client).put({url:"/crm/companies/{company_id}/email-sync",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCompanyHidden($){return($.client??this.client).put({url:"/crm/companies/{company_id}/hidden",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCrmCompanyName($){return($.client??this.client).put({url:"/crm/companies/{company_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}searchContacts($){return($?.client??this.client).get({url:"/crm/contacts",...$})}getContactByEmail($){return($.client??this.client).get({url:"/crm/contacts/by-email",...$})}getContact($){return($.client??this.client).get({url:"/crm/contacts/{contact_id}",...$})}setContactHidden($){return($.client??this.client).put({url:"/crm/contacts/{contact_id}/hidden",...$,headers:{"Content-Type":"application/json",...$.headers}})}setCrmContactName($){return($.client??this.client).put({url:"/crm/contacts/{contact_id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}listCrmPipelines($){return($?.client??this.client).get({url:"/crm/pipelines",...$})}createCrmPipeline($){return($.client??this.client).post({url:"/crm/pipelines",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipeline($){return($.client??this.client).get({url:"/crm/pipelines/{id}",...$})}renameCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/name",...$,headers:{"Content-Type":"application/json",...$.headers}})}applyCrmPipelineOps($){return($.client??this.client).post({url:"/crm/pipelines/{id}/ops",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelinePermissions($){return($.client??this.client).get({url:"/crm/pipelines/{id}/permissions",...$})}updateCrmPipelinePermissions($){return($.client??this.client).patch({url:"/crm/pipelines/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelineRows($){return($.client??this.client).get({url:"/crm/pipelines/{id}/rows",...$})}queryCrmPipelineRows($){return($.client??this.client).post({url:"/crm/pipelines/{id}/rows",...$,headers:{"Content-Type":"application/json",...$.headers}})}shareCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/sharing",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmPipelineTable($){return($.client??this.client).get({url:"/crm/pipelines/{id}/table",...$})}trashCrmPipeline($){return($.client??this.client).put({url:"/crm/pipelines/{id}/trash",...$,headers:{"Content-Type":"application/json",...$.headers}})}getCrmTeamSettings($){return($?.client??this.client).get({url:"/crm/settings",...$})}putCrmTeamSettings($){return($.client??this.client).put({url:"/crm/settings",...$,headers:{"Content-Type":"application/json",...$.headers}})}resetCrmTeamStages($){return($?.client??this.client).delete({url:"/crm/stages",...$})}putCrmTeamStages($){return($.client??this.client).put({url:"/crm/stages",...$,headers:{"Content-Type":"application/json",...$.headers}})}listDatabases($){return($?.client??this.client).get({url:"/databases",...$})}createDatabase($){return($.client??this.client).post({url:"/databases",...$,headers:{"Content-Type":"application/json",...$.headers}})}saveDatabaseQuery($){return($.client??this.client).post({url:"/databases/queries",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseQuery($){return($.client??this.client).get({url:"/databases/queries/{query_id}",...$})}queryDatabases($){return($.client??this.client).post({url:"/databases/query",...$,headers:{"Content-Type":"application/json",...$.headers}})}ensureStarterHandler($){return($?.client??this.client).post({url:"/databases/starter",...$})}deliverDatabaseWebhook($){return($.client??this.client).post({url:"/databases/webhooks/{token}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabase($){return($.client??this.client).get({url:"/databases/{id}",...$})}shareDatabaseAwareness($){return($.client??this.client).put({url:"/databases/{id}/awareness",...$,headers:{"Content-Type":"application/json",...$.headers}})}undoDatabaseChange($){return($.client??this.client).post({url:"/databases/{id}/changes/{change}/undo",...$})}importDatabaseTable($){return($.client??this.client).post({url:"/databases/{id}/import",...$,headers:{"Content-Type":"application/json",...$.headers}})}applyDatabaseOps($){return($.client??this.client).post({url:"/databases/{id}/ops",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabasePermissions($){return($.client??this.client).get({url:"/databases/{id}/permissions",...$})}updateDatabasePermissions($){return($.client??this.client).patch({url:"/databases/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseTableChanges($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/changes",...$})}listDatabaseColumnCasts($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/casts",...$})}convertDatabaseColumn($){return($.client??this.client).post({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/conversion",...$,headers:{"Content-Type":"application/json",...$.headers}})}inferDatabaseColumnType($){return($.client??this.client).post({url:"/databases/{id}/tables/{table_id}/columns/{column_id}/infer-type",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDatabaseRowHistory($){return($.client??this.client).get({url:"/databases/{id}/tables/{table_id}/rows/{row_id}/history",...$})}getDatabaseViewPositions($){return($.client??this.client).get({url:"/databases/{id}/views/{view_id}/positions",...$})}listDatabaseWebhooks($){return($.client??this.client).get({url:"/databases/{id}/webhooks",...$})}createDatabaseWebhook($){return($.client??this.client).post({url:"/databases/{id}/webhooks",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteDatabaseWebhook($){return($.client??this.client).delete({url:"/databases/{id}/webhooks/{webhook_id}",...$})}transcribeDictation($){return($.client??this.client).post({bodySerializer:null,url:"/dictation/transcribe",...$,headers:{"Content-Type":"audio/webm",...$.headers}})}getUserDocumentsHandler($){return($.client??this.client).get({url:"/documents",...$})}createDocument($){return($.client??this.client).post({url:"/documents",...$,headers:{"Content-Type":"application/json",...$.headers}})}createCanvasHandler($){return($.client??this.client).post({url:"/documents/create_canvas",...$,headers:{"Content-Type":"application/json",...$.headers}})}createMarkdownHandler($){return($.client??this.client).post({url:"/documents/create_markdown",...$,headers:{"Content-Type":"application/json",...$.headers}})}createSkillHandler($){return($.client??this.client).post({url:"/documents/create_skill",...$,headers:{"Content-Type":"application/json",...$.headers}})}createSnippetHandler($){return($.client??this.client).post({url:"/documents/create_snippet",...$,headers:{"Content-Type":"application/json",...$.headers}})}createTaskHandler($){return($.client??this.client).post({url:"/documents/create_task",...$,headers:{"Content-Type":"application/json",...$.headers}})}getGithubPullRequestTasks($){return($.client??this.client).post({url:"/documents/github_prs/tasks",...$,headers:{"Content-Type":"application/json",...$.headers}})}initializeUserDocuments($){return($?.client??this.client).post({url:"/documents/initialize_user_documents",...$})}getDocumentListHandler($){return($?.client??this.client).get({url:"/documents/list",...$})}validateDocumentPermissionsToken($){return($.client??this.client).post({url:"/documents/permissions_token/validate",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentPermissionsToken($){return($.client??this.client).post({url:"/documents/permissions_token/{document_id}",...$})}presaveDocumentHandler($){return($.client??this.client).put({url:"/documents/presave/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getBatchPreviewHandler($){return($.client??this.client).post({url:"/documents/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentByTeamSlug($){return($.client??this.client).get({url:"/documents/slug/{slug}",...$})}handler($){return($?.client??this.client).get({url:"/documents/starter_docs",...$})}getSystemSkillsHandler($){return($?.client??this.client).get({url:"/documents/system_skills",...$})}deleteDocument($){return($.client??this.client).delete({url:"/documents/{document_id}",...$})}getDocument($){return($.client??this.client).get({url:"/documents/{document_id}",...$})}editDocument($){return($.client??this.client).patch({url:"/documents/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}saveDocumentHandler($){return($.client??this.client).put({url:"/documents/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentBranchName($){return($.client??this.client).get({url:"/documents/{document_id}/branch_name",...$})}copyDocument($){return($.client??this.client).post({url:"/documents/{document_id}/copy",...$,headers:{"Content-Type":"application/json",...$.headers}})}exportDocument($){return($.client??this.client).get({url:"/documents/{document_id}/export",...$})}getDocumentGithubPullRequests($){return($.client??this.client).get({url:"/documents/{document_id}/github_prs",...$})}getLocationHandler($){return($.client??this.client).get({url:"/documents/{document_id}/location",...$})}getDocumentLocationV3($){return($.client??this.client).get({url:"/documents/{document_id}/location_v3",...$})}permanentlyDeleteDocument($){return($.client??this.client).delete({url:"/documents/{document_id}/permanent",...$})}getDocumentProcessingResult($){return($.client??this.client).get({url:"/documents/{document_id}/processing",...$})}jobProcessingResultHandler($){return($.client??this.client).get({url:"/documents/{document_id}/processing/{job_id}",...$})}revertDeleteDocument($){return($.client??this.client).put({url:"/documents/{document_id}/revert_delete",...$})}getDocumentShortId($){return($.client??this.client).get({url:"/documents/{document_id}/short_id",...$})}simpleSave($){return($.client??this.client).put({url:"/documents/{document_id}/simple_save",...$})}getDocumentTeamShare($){return($.client??this.client).get({url:"/documents/{document_id}/team_share",...$})}setDocumentTeamShare($){return($.client??this.client).put({url:"/documents/{document_id}/team_share",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentTextContent($){return($.client??this.client).get({url:"/documents/{document_id}/text-content",...$})}getDocumentViewsHandler($){return($.client??this.client).get({url:"/documents/{document_id}/views",...$})}getDocumentVersion($){return($.client??this.client).get({url:"/documents/{document_id}/{document_version_id}",...$})}accessRequestsState($){return($.client??this.client).get({url:"/entities/{entity_type}/{entity_id}/access-requests",...$})}accessRequestsCancel($){return($.client??this.client).delete({url:"/entities/{entity_type}/{entity_id}/access-requests/mine",...$})}accessRequestsSubmit($){return($.client??this.client).put({url:"/entities/{entity_type}/{entity_id}/access-requests/mine",...$,headers:{"Content-Type":"application/json",...$.headers}})}accessRequestsResolve($){return($.client??this.client).post({url:"/entities/{entity_type}/{entity_id}/access-requests/{request_id}/resolve",...$,headers:{"Content-Type":"application/json",...$.headers}})}accessRequestsDirect($){return($.client??this.client).get({url:"/entities/{entity_type}/{entity_id}/direct-access",...$})}accessRequestsRemoveDirect($){return($.client??this.client).delete({url:"/entities/{entity_type}/{entity_id}/direct-access/{user_id}",...$})}accessRequestsSetDirect($){return($.client??this.client).put({url:"/entities/{entity_type}/{entity_id}/direct-access/{user_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getEntityPermission($){return($.client??this.client).get({url:"/entity/{entity_type}/{entity_id}/permissions",...$})}listFavorites($){return($?.client??this.client).get({url:"/favorites",...$})}addFavorite($){return($.client??this.client).post({url:"/favorites",...$,headers:{"Content-Type":"application/json",...$.headers}})}reorderFavorites($){return($.client??this.client).patch({url:"/favorites/reorder",...$,headers:{"Content-Type":"application/json",...$.headers}})}removeFavoriteByEntity($){return($.client??this.client).delete({url:"/favorites/{entity_type}/{entity_id}",...$})}getForeignEntityBySource($){return($.client??this.client).get({url:"/foreign_entity/by_source/{source}/{foreign_entity_id}",...$})}getForeignEntity($){return($.client??this.client).get({url:"/foreign_entity/{id}",...$})}listForms($){return($.client??this.client).get({url:"/forms",...$})}createForm($){return($.client??this.client).post({url:"/forms",...$,headers:{"Content-Type":"application/json",...$.headers}})}listAccessibleForms($){return($?.client??this.client).get({url:"/forms/accessible",...$})}getForm($){return($.client??this.client).get({url:"/forms/{id}",...$})}updateForm($){return($.client??this.client).patch({url:"/forms/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}collaborateForm($){return($.client??this.client).post({url:"/forms/{id}/collaboration",...$})}putFormLayout($){return($.client??this.client).put({url:"/forms/{id}/layout",...$,headers:{"Content-Type":"application/json",...$.headers}})}getFormPermissions($){return($.client??this.client).get({url:"/forms/{id}/permissions",...$})}updateFormPermissions($){return($.client??this.client).patch({url:"/forms/{id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}submitFormResponse($){return($.client??this.client).post({url:"/forms/{id}/responses",...$,headers:{"Content-Type":"application/json",...$.headers}})}getMyFormResponse($){return($.client??this.client).get({url:"/forms/{id}/responses/mine",...$})}editMyFormResponse($){return($.client??this.client).put({url:"/forms/{id}/responses/mine",...$,headers:{"Content-Type":"application/json",...$.headers}})}getFormResponseSummary($){return($.client??this.client).get({url:"/forms/{id}/responses/summary",...$})}getFormTally($){return($.client??this.client).get({url:"/forms/{id}/tally",...$})}installSync($){return($?.client??this.client).get({url:"/github/install-sync",...$})}getGithubPullRequestFacets($){return($?.client??this.client).get({url:"/github_pull_requests/facets",...$})}getGithubPullRequest($){return($.client??this.client).get({url:"/github_pull_requests/{id}",...$})}getGithubPullRequestChanges($){return($.client??this.client).get({url:"/github_pull_requests/{id}/changes",...$})}getGithubPullRequestChangesPatch($){return($.client??this.client).get({url:"/github_pull_requests/{id}/changes/patch",...$})}createHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings",...$,headers:{"Content-Type":"application/json",...$.headers}})}getHarnessPairing($){return($.client??this.client).get({url:"/harness-pairings/{code}",...$})}approveHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings/{code}/approve",...$,headers:{"Content-Type":"application/json",...$.headers}})}claimHarnessPairing($){return($.client??this.client).post({url:"/harness-pairings/{pairing_id}/claim",...$,headers:{"Content-Type":"application/json",...$.headers}})}listHarnesses($){return($?.client??this.client).get({url:"/harnesses",...$})}deleteSelfHarness($){return($?.client??this.client).delete({url:"/harnesses/me",...$})}getSelfHarness($){return($?.client??this.client).get({url:"/harnesses/me",...$})}listHarnessAgents($){return($?.client??this.client).get({url:"/harnesses/me/agents",...$})}listHarnessSessions($){return($?.client??this.client).get({url:"/harnesses/me/sessions",...$})}deleteHarness($){return($.client??this.client).delete({url:"/harnesses/{harness_id}",...$})}healthHandler($){return($?.client??this.client).get({url:"/health",...$})}getHistoryHandler($){return($?.client??this.client).get({url:"/history",...$})}deleteHistoryHandler($){return($.client??this.client).delete({url:"/history/{item_type}/{item_id}",...$})}upsertHistoryHandler($){return($.client??this.client).post({url:"/history/{item_type}/{item_id}",...$})}listInitiatives($){return($?.client??this.client).get({url:"/initiatives",...$})}createInitiative($){return($.client??this.client).post({url:"/initiatives",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteInitiative($){return($.client??this.client).delete({url:"/initiatives/{initiative_id}",...$})}getInitiative($){return($.client??this.client).get({url:"/initiatives/{initiative_id}",...$})}updateInitiative($){return($.client??this.client).patch({url:"/initiatives/{initiative_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getInstructionsHandler($){return($?.client??this.client).get({url:"/instructions",...$})}createInstructionsHandler($){return($?.client??this.client).post({url:"/instructions",...$})}getItemsSoup($){return($?.client??this.client).get({url:"/items/soup",...$})}postItemsSoup($){return($.client??this.client).post({url:"/items/soup",...$,headers:{"Content-Type":"application/json",...$.headers}})}postItemsSoupAst($){return($.client??this.client).post({url:"/items/soup/ast",...$,headers:{"Content-Type":"application/json",...$.headers}})}postItemsSoupAstGrouped($){return($.client??this.client).post({url:"/items/soup/ast/grouped",...$,headers:{"Content-Type":"application/json",...$.headers}})}messageTimeline($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}",...$})}entityMessageCreate($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageDeleteMessage($){return($.client??this.client).delete({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$})}entityMessageGetMessage($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$})}entityMessageEdit($){return($.client??this.client).patch({url:"/messages/{parent_type}/{parent_id}/items/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageReact($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}/items/{id}/reactions",...$,headers:{"Content-Type":"application/json",...$.headers}})}entityMessageLegacy($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/legacy/{legacy_id}",...$})}entityMessageDeleteThread($){return($.client??this.client).delete({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$})}entityMessageGetThread($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$})}entityMessagePatchThread($){return($.client??this.client).patch({url:"/messages/{parent_type}/{parent_id}/threads/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}messageTimelineEntries($){return($.client??this.client).get({url:"/messages/{parent_type}/{parent_id}/timeline",...$})}entityMessageTyping($){return($.client??this.client).post({url:"/messages/{parent_type}/{parent_id}/typing",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedAccount($){return($?.client??this.client).get({url:"/meta/linked/account",...$})}linkedChats($){return($?.client??this.client).get({url:"/meta/linked/chats",...$})}linkedConfiguration($){return($?.client??this.client).get({url:"/meta/linked/configuration",...$})}linkedConnect($){return($.client??this.client).post({url:"/meta/linked/connect",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedDisconnect($){return($.client??this.client).post({url:"/meta/linked/disconnect",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedGroups($){return($?.client??this.client).get({url:"/meta/linked/groups",...$})}linkedAdopt($){return($.client??this.client).post({url:"/meta/linked/groups/adopt",...$,headers:{"Content-Type":"application/json",...$.headers}})}linkedCancelPairing($){return($.client??this.client).delete({url:"/meta/linked/pairing/{id}",...$})}linkedPairing($){return($.client??this.client).get({url:"/meta/linked/pairing/{id}",...$})}linkedPasskey($){return($.client??this.client).post({url:"/meta/linked/pairing/{id}/passkey",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroups($){return($?.client??this.client).get({url:"/meta/linked/whatsapp-groups",...$})}linkedDetach($){return($.client??this.client).delete({url:"/meta/linked/whatsapp-groups/{group_id}",...$})}whatsappGroup($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}",...$})}linkedUpload($){return($.client??this.client).post({...R1,url:"/meta/linked/whatsapp-groups/{group_id}/attachments",...$,headers:{"Content-Type":null,...$.headers}})}linkedDelivery($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/delivery",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupMessages($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/messages",...$})}linkedMessageAttachments($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/messages/attachments",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupPermissions($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/permissions",...$})}whatsappGroupUpdatePermissions($){return($.client??this.client).patch({url:"/meta/linked/whatsapp-groups/{group_id}/permissions",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupRead($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/read",...$,headers:{"Content-Type":"application/json",...$.headers}})}whatsappGroupSends($){return($.client??this.client).get({url:"/meta/linked/whatsapp-groups/{group_id}/sends",...$})}linkedReply($){return($.client??this.client).post({url:"/meta/linked/whatsapp-groups/{group_id}/sends",...$,headers:{"Content-Type":"application/json",...$.headers}})}getPinsHandler($){return($?.client??this.client).get({url:"/pins",...$})}reorderPinsHandler($){return($.client??this.client).patch({url:"/pins",...$,headers:{"Content-Type":"application/json",...$.headers}})}removePinHandler($){return($.client??this.client).delete({url:"/pins/{pinned_item_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}addPinHandler($){return($.client??this.client).post({url:"/pins/{pinned_item_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getProjectsHandler($){return($?.client??this.client).get({url:"/projects",...$})}createProjectHandler($){return($.client??this.client).post({url:"/projects",...$,headers:{"Content-Type":"application/json",...$.headers}})}getPendingProjectsHandler($){return($?.client??this.client).get({url:"/projects/pending",...$})}getBatchProjectPreview($){return($.client??this.client).post({url:"/projects/preview",...$,headers:{"Content-Type":"application/json",...$.headers}})}uploadFolderHandler($){return($.client??this.client).post({url:"/projects/upload",...$,headers:{"Content-Type":"application/json",...$.headers}})}uploadExtractFolderHandler($){return($.client??this.client).post({url:"/projects/upload_extract",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteProjectHandler($){return($.client??this.client).delete({url:"/projects/{id}",...$})}getProjectHandler($){return($.client??this.client).get({url:"/projects/{id}",...$})}getProjectUserAccessLevel($){return($.client??this.client).get({url:"/projects/{id}/access_level",...$})}getProjectContentHandler($){return($.client??this.client).get({url:"/projects/{id}/content",...$})}permanentlyDeleteProject($){return($.client??this.client).delete({url:"/projects/{id}/permanent",...$})}getProjectPermissionsV2($){return($.client??this.client).get({url:"/projects/{id}/permissions",...$})}revertDeleteProject($){return($.client??this.client).put({url:"/projects/{id}/revert_delete",...$})}recentlyDeleted($){return($?.client??this.client).get({url:"/recents/deleted",...$})}listEmailReminders($){return($?.client??this.client).get({url:"/reminders/email/collection",...$})}getEmailFollowup($){return($.client??this.client).get({url:"/reminders/email/{thread_id}",...$})}setEmailFollowup($){return($.client??this.client).put({url:"/reminders/email/{thread_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getViewsHandler($){return($?.client??this.client).get({url:"/saved_views",...$})}createViewHandler($){return($.client??this.client).post({url:"/saved_views",...$,headers:{"Content-Type":"application/json",...$.headers}})}excludeDefaultViewHandler($){return($.client??this.client).post({url:"/saved_views/exclude_default",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteViewHandler($){return($.client??this.client).delete({url:"/saved_views/{saved_view_id}",...$})}patchViewHandler($){return($.client??this.client).patch({url:"/saved_views/{saved_view_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listSlackImports($){return($?.client??this.client).get({url:"/slack/imports",...$})}createSlackImport($){return($.client??this.client).post({url:"/slack/imports",...$,headers:{"Content-Type":"application/json",...$.headers}})}getSlackImport($){return($.client??this.client).get({url:"/slack/imports/{job_id}",...$})}cancelSlackImport($){return($.client??this.client).post({url:"/slack/imports/{job_id}/cancel",...$})}finalizeSlackImport($){return($.client??this.client).post({url:"/slack/imports/{job_id}/finalize",...$})}registerSlackImportUploads($){return($.client??this.client).post({url:"/slack/imports/{job_id}/uploads",...$,headers:{"Content-Type":"application/json",...$.headers}})}completeSlackImportUploads($){return($.client??this.client).post({url:"/slack/imports/{job_id}/uploads/complete",...$,headers:{"Content-Type":"application/json",...$.headers}})}bulkWakeupSyncServiceDocuments($){return($.client??this.client).post({url:"/sync_service/wakeup",...$,headers:{"Content-Type":"application/json",...$.headers}})}editThreadV2($){return($.client??this.client).patch({url:"/threads/{thread_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}listUserApiKeys($){return($?.client??this.client).get({url:"/user-api-keys",...$})}createUserApiKey($){return($.client??this.client).post({url:"/user-api-keys",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteUserApiKey($){return($.client??this.client).delete({url:"/user-api-keys/{id}",...$})}deleteUserDocumentViewLocation($){return($.client??this.client).delete({url:"/user_document_view_location/{document_id}",...$})}getUserDocumentViewLocation($){return($.client??this.client).get({url:"/user_document_view_location/{document_id}",...$})}upsertUserDocumentViewLocation($){return($.client??this.client).post({url:"/user_document_view_location/{document_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}getDocumentPermissionsV2($){return($.client??this.client).get({url:"/v2/documents/{document_id}/permissions",...$})}editProjectV2($){return($.client??this.client).patch({url:"/v2/projects/{id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}streamEvents($){return($.client??this.client).sse.get({url:"/webhook/events/stream",...$})}listWebhooks($){return($?.client??this.client).get({url:"/webhook/webhooks",...$})}createWebhook($){return($.client??this.client).post({url:"/webhook/webhooks",...$,headers:{"Content-Type":"application/json",...$.headers}})}deleteWebhook($){return($.client??this.client).delete({url:"/webhook/webhooks/{webhook_id}",...$})}getWebhook($){return($.client??this.client).get({url:"/webhook/webhooks/{webhook_id}",...$})}patchWebhook($){return($.client??this.client).patch({url:"/webhook/webhooks/{webhook_id}",...$,headers:{"Content-Type":"application/json",...$.headers}})}validateWebhook($){return($.client??this.client).post({url:"/webhook/webhooks/{webhook_id}/validate",...$})}}function G6({onRequest:$,onSseError:O,onSseEvent:j,responseTransformer:x,responseValidator:S,sseDefaultRetryDelay:K,sseMaxRetryAttempts:Z,sseMaxRetryDelay:X,sseSleepFn:Y,url:L,...Q}){let J,I=Y??((V)=>new Promise((B)=>setTimeout(B,V)));return{stream:async function*(){let V=K??3000,B=0,T=Q.signal??new AbortController().signal;while(!0){if(T.aborted)break;B++;let A=Q.headers instanceof Headers?Q.headers:new Headers(Q.headers);if(J!==void 0)A.set("Last-Event-ID",J);try{let D={redirect:"follow",...Q,body:Q.serializedBody,headers:A,signal:T},_=new Request(L,D);if($)_=await $(L,D);let N=await(Q.fetch??globalThis.fetch)(_);if(!N.ok)throw Error(`SSE failed: ${N.status} ${N.statusText}`);if(!N.body)throw Error("No body in SSE response");let H=N.body.pipeThrough(new TextDecoderStream).getReader(),U="",k=()=>{try{H.cancel()}catch{}};T.addEventListener("abort",k);try{while(!0){let{done:l,value:r}=await H.read();if(l)break;U+=r,U=U.replace(/\r\n?/g,`
`);let g=U.split(`
`);U=g.pop()??"";for(let p of g){let a=p.split(`
-`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let _,v=!1;if(F.length){let R=F.join(`
-`);try{_=JSON.parse(R),v=!0}catch{_=R}}if(v){if(S)await S(_);if(x)_=await x(_)}if(j?.({data:_,event:y,id:J,retry:V}),F.length)yield _}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let C=Math.min(V*2**(B-1),X??30000);await I(C)}}}()}}var Z4=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},X4=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},K4=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},wx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(X4(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=Z4(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return yO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},yO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},qx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([G,J])=>{Y=[...Y,G,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=K4(x),X=Object.entries(S).map(([Y,L])=>yO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var Y4=/\{[^{}]+\}/g,Q4=({path:$,url:O})=>{let j=O,x=O.match(Y4);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,wx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,qx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${yO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},G6=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=Q4({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function M1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var J6=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var V6={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var W6=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=wx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=qx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=yO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},B6=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},G4=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function L6($){for(let O of $.security??[]){if(G4($,O.name))continue;let j=await J6(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var A1=($)=>G6({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:W6($.querySerializer),url:$.url}),F1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=bx($.headers,O.headers),j},J4=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},bx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?J4(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class fx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var N6=()=>({error:new fx,request:new fx,response:new fx}),V4=W6({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),W4={"Content-Type":"application/json"},Vj=($={})=>({...V6,headers:W4,parseAs:"auto",querySerializer:V4,...$});var E1=($={})=>{let O=F1(Vj(),$),j=()=>({...O}),x=(G)=>{return O=F1(O,G),j()},S=N6(),K=async(G)=>{let J={...O,...G,fetch:G.fetch??O.fetch??globalThis.fetch,headers:bx(O.headers,G.headers),serializedBody:void 0};if(J.security)await L6(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=A1(I);return{opts:I,url:z}},Z=async(G)=>{let J=G.throwOnError??O.throwOnError,I=G.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(G),T={redirect:"follow",...V,body:M1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?B6(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let C=await W.text(),q;try{q=JSON.parse(C)}catch{}throw q??C}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,G);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(G)=>(J)=>Z({...J,method:G}),Y=(G)=>async(J)=>{let{opts:I,url:z}=await K(J);return Q6({...I,body:I.body,method:G,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:M1(I),url:z})};return{buildUrl:(G)=>A1({...O,...G}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var U6=E1(Vj());class z6{client;constructor($){this.client=$?.client??U6}}class I6{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class kx extends z6{static __registry=new I6;constructor($){super($);kx.__registry.set(this,$?.key)}proxyRequestHandler($){return($.client??this.client).get({url:"/proxy",...$})}getUnfurl($){return($.client??this.client).get({url:"/unfurl",...$})}getUnfurlBulk($){return($.client??this.client).post({url:"/unfurl/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}}var T6={dev:"https://dev.macro.com",prod:"https://macro.com",local:"http://localhost:3000"},w1={dev:{"agent-harness":"https://dev-gateway.macro.com/agent-harness",storage:"https://dev-gateway.macro.com/dss",auth:"https://dev-gateway.macro.com/auth",email:"https://dev-gateway.macro.com/email",calendar:"https://dev-gateway.macro.com/calendar",cognition:"https://dev-gateway.macro.com/cognition",notification:"https://dev-gateway.macro.com/notification",properties:"https://dev-gateway.macro.com/dss",search:"https://dev-gateway.macro.com/dss","scheduled-action":"https://dev-gateway.macro.com/scheduled-action","static-files":"https://static-file-service-dev.macro.com",connection:"https://dev-gateway.macro.com/connection-gateway",contacts:"https://dev-gateway.macro.com/contacts",unfurl:"https://dev-gateway.macro.com/unfurl"},prod:{"agent-harness":"https://gateway.macro.com/agent-harness",storage:"https://gateway.macro.com/dss",auth:"https://gateway.macro.com/auth",email:"https://gateway.macro.com/email",calendar:"https://gateway.macro.com/calendar",cognition:"https://gateway.macro.com/cognition",notification:"https://gateway.macro.com/notification",properties:"https://gateway.macro.com/dss",search:"https://gateway.macro.com/dss","scheduled-action":"https://gateway.macro.com/scheduled-action","static-files":"https://static-file-service.macro.com",connection:"https://gateway.macro.com/connection-gateway",contacts:"https://gateway.macro.com/contacts",unfurl:"https://gateway.macro.com/unfurl"},local:{"agent-harness":"http://localhost:8101",storage:"http://localhost:8086",auth:"http://localhost:8080",email:"http://localhost:8087",calendar:"http://localhost:8088/calendar",cognition:"http://localhost:8101/cognition",notification:"http://localhost:8089",properties:"http://localhost:8086",search:"http://localhost:8086","scheduled-action":"http://localhost:8101/scheduled-action","static-files":"http://localhost:8100",connection:"http://localhost:8082",contacts:"http://localhost:8083",unfurl:"http://localhost:8095"}};function B4($,O){let j=O?.channel_id;return O&&j?{channel:b.byId($,j),thread:new h$($,j,O.thread_id)}:{channel:void 0,thread:void 0}}function E$($,O){return{session:i.byId($,O.session_id),owner:P.byId($,O.owner_id),...B4($,O.origin)}}function vO($,O,j){let x=O.origin?.channel_id;return x&&j?e.byId($,x,j):void 0}function hO($,O){return O?P.byId($,O):void 0}function H6($,O){return c(O).with({event_type:"agent_session.opened"},({metadata:j})=>({event_type:"agent_session.opened",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.turn_started"},({metadata:j})=>({event_type:"agent_session.turn_started",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.turn_ended"},({metadata:j})=>({event_type:"agent_session.turn_ended",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.command_rejected"},({metadata:j})=>({event_type:"agent_session.command_rejected",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.settled"},({metadata:j})=>({event_type:"agent_session.settled",metadata:j,...E$($,j.identity),actor:hO($,j.last_turn?.actor),announcement:vO($,j.identity,j.last_turn?.announcement_message_id)})).with({event_type:"agent_session.waiting_for_input"},({metadata:j})=>({event_type:"agent_session.waiting_for_input",metadata:j,...E$($,j.identity),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.input_received"},({metadata:j})=>({event_type:"agent_session.input_received",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.mentioned"},({metadata:j})=>({event_type:"agent_session.mentioned",metadata:j,...E$($,j.identity),mentionedBy:hO($,j.mentioned_by),mentioned:j.mentioned.map((x)=>P.byId($,x))})).with({event_type:"agent_session.stopped"},({metadata:j})=>({event_type:"agent_session.stopped",metadata:j,...E$($,j.identity),actor:hO($,j.turn_in_flight?.actor),announcement:vO($,j.identity,j.turn_in_flight?.announcement_message_id)})).with({event_type:"agent_session.renamed"},({metadata:j})=>({event_type:"agent_session.renamed",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.deleted"},({metadata:j})=>({event_type:"agent_session.deleted",metadata:j,...E$($,j.identity)})).exhaustive((j)=>{console.warn("macro sdk: unknown agent session event",j);return})}var R6="macro|";function P$($,O){return O.startsWith(R6)&&O.length>R6.length?P.byId($,O.toLowerCase()):void 0}function D6($,O){return c(O).with({event_type:"channel.created"},({metadata:j})=>({event_type:"channel.created",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor),participants:j.participant_user_ids.map((x)=>P.byId($,x))})).with({event_type:"channel.updated"},({metadata:j})=>({event_type:"channel.updated",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.deleted"},({metadata:j})=>({event_type:"channel.deleted",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.picture_changed"},({metadata:j})=>({event_type:"channel.picture_changed",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.participant_added"},({metadata:j})=>({event_type:"channel.participant_added",metadata:j,channel:b.byId($,j.channel_id),addedBy:P$($,j.added_by),addedUsers:j.added_user_ids.map((x)=>P.byId($,x))})).with({event_type:"channel.participant_removed"},({metadata:j})=>({event_type:"channel.participant_removed",metadata:j,channel:b.byId($,j.channel_id),removedBy:P.byId($,j.removed_by),removedUsers:j.removed_user_ids.map((x)=>P.byId($,x))})).exhaustive((j)=>{console.warn("macro sdk: unknown channel event",j);return})}function C6($,O){return c(O).with({event_type:"document.created"},({metadata:j})=>({event_type:"document.created",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner),project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.updated"},({metadata:j})=>({event_type:"document.updated",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner),actor:j.actor_user_id?P.byId($,j.actor_user_id):void 0,project:j.project_id?n.byId($,j.project_id):void 0,previousProject:j.previous_project_id?n.byId($,j.previous_project_id):void 0})).with({event_type:"document.deleted"},({metadata:j})=>({event_type:"document.deleted",metadata:j,document:w.byId($,j.document_id),actor:j.actor_user_id?P.byId($,j.actor_user_id):void 0,project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.content_uploaded"},({metadata:j})=>({event_type:"document.content_uploaded",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner)})).with({event_type:"document.sync_content_updated"},({metadata:j})=>({event_type:"document.sync_content_updated",metadata:j,document:w.byId($,j.document_id)})).with({event_type:"document.purged"},({metadata:j})=>({event_type:"document.purged",metadata:j,document:w.byId($,j.document_id)})).with({event_type:"document.copied"},({metadata:j})=>({event_type:"document.copied",metadata:j,document:w.byId($,j.document_id),sourceDocument:w.byId($,j.source_document_id),owner:P.byId($,j.owner),project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.interaction"},({metadata:j})=>({event_type:"document.interaction",metadata:j,document:w.byId($,j.document_id)})).exhaustive((j)=>{console.warn("macro sdk: unknown document event",j);return})}function mO($,O,j=[]){let x=O.parent;if(x.type==="call")return{type:"call",call:G$.byId($,x.id),message:u$.byId($,x.id,O.message_id),threadId:x.id};if(x.type==="channel")return{type:"channel",channel:b.byId($,x.id),message:e.byId($,x.id,O.message_id,j),thread:O.thread_id?new h$($,x.id,O.thread_id):void 0};return{type:"document",document:w.byId($,x.id),comment:c$.byId($,x.id,O.message_id),threadId:O.root_id}}function _6($,O){return c(O).with({event_type:"message.posted"},({metadata:j})=>({event_type:"message.posted",metadata:j,target:mO($,j,j.mentions),sender:P$($,j.sender)})).with({event_type:"message.mentioned"},({metadata:j})=>({event_type:"message.mentioned",metadata:j,target:mO($,j),sender:P$($,j.sender)})).with({event_type:"message.patched"},({metadata:j})=>({event_type:"message.patched",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.deleted"},({metadata:j})=>({event_type:"message.deleted",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.attachment_created"},({metadata:j})=>({event_type:"message.attachment_created",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.attachment_removed"},({metadata:j})=>({event_type:"message.attachment_removed",metadata:j,target:mO($,j),actor:P$($,j.actor)})).exhaustive((j)=>{console.warn("macro sdk: unknown message event",j);return})}async function P6($){let O=new TextEncoder,j=await crypto.subtle.importKey("raw",O.encode($.secret),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),x=await crypto.subtle.sign("HMAC",j,O.encode(`${$.timestamp}.${$.rawBody}`));return`v1=${new Uint8Array(x).toHex()}`===$.signature}var L4="webhook.validation.test";function N4($,O){return c(O).with({event_type:Z$.string.startsWith("document.")},(j)=>C6($,j)).with({event_type:Z$.string.startsWith("channel.")},(j)=>D6($,j)).with({event_type:Z$.string.startsWith("message.")},(j)=>_6($,j)).with({event_type:Z$.string.startsWith("agent_session.")},(j)=>H6($,j)).otherwise(()=>{return})}class q1{client;secret;handlers=new Map;constructor($,O){this.client=$;this.secret=O}on($,O){let j=this.handlers.get($)??new Set;return j.add(O),this.handlers.set($,j),()=>j.delete(O)}onSelfMention($){return this.on("message.mentioned",async(O)=>{if(O.metadata.mentioned.entity_id.toLowerCase()!==(await this.client.myPrincipalId()).toLowerCase())return;await $(O)})}async listen($={}){let O=$.filters??this.filtersFromHandlers();if(O.length===0||O.every((K)=>K.events.length===0))throw new f("listen() needs filters — pass filters or register handlers with .on() first");let j=new AbortController;if($.signal)if($.signal.aborted)j.abort();else $.signal.addEventListener("abort",()=>j.abort(),{once:!0});let{stream:x}=await this.client.storage.streamEvents({query:{scope:$.scope??"user",filters:JSON.stringify(O)},signal:j.signal});return(async()=>{try{for await(let K of x)await this.dispatchEvent(K)}catch{if(j.signal.aborted)return;throw new f("event stream failed")}})().catch(()=>{}),()=>{j.abort()}}async handle($,O){if(!this.secret)throw new f("webhookSecret is required to verify incoming webhook deliveries");if(!await P6({secret:this.secret,timestamp:O.timestamp??"",rawBody:$,signature:O.signature??""}))throw new f("invalid webhook signature");if(O.event===L4)return;await this.dispatchEvent(JSON.parse($))}webhook(){if(!this.secret)throw new f("webhookSecret is required to verify incoming webhook deliveries");return async($)=>{return await this.handle(await $.text(),{event:$.headers.get("x-macro-event")??void 0,eventId:$.headers.get("x-macro-event-id")??void 0,timestamp:$.headers.get("x-macro-timestamp")??void 0,signature:$.headers.get("x-macro-signature")??void 0}),new Response("ok")}}filtersFromHandlers(){let $=[...this.handlers.entries()].filter(([,O])=>O.size>0).map(([O])=>O);return $.length>0?[{events:$}]:[]}async dispatchEvent($){let O=typeof $==="string"?JSON.parse($):$;if(O===null||typeof O!=="object"||!("event_type"in O))return;let j=O,x=this.handlers.get(j.event_type);if(!x||x.size===0)return;let S=N4(this.client,j);if(!S)return;await Promise.all([...x].map((K)=>K(S)))}}function M6(){return}var U4=0,f1;function z4($){f1=$}function U$($,O,j){if(!j&&!f1)return $;let x=(S)=>{for(let K of[f1,j])try{Promise.resolve(K?.(S)).catch(()=>{})}catch{}};return new Proxy($,{get(S,K,Z){let X=Reflect.get(S,K,Z);if(typeof K!=="string"||typeof X!=="function")return X;return async(...Y)=>{let L={id:++U4,service:O,operation:K};x({...L,status:"started"});try{let G=await Reflect.apply(X,S,Y),J=G!==null&&typeof G==="object"&&"error"in G&&G.error!=null;return x({...L,status:J?"failed":"completed"}),G}catch(G){throw x({...L,status:"failed"}),G}}}})}var F6="x-macro-user-api-key",I4="mak_",b1="mbot_";function T4($){return c($).with(Z$.string.startsWith(b1),()=>{throw Error("bot token passed as a user credential. Use auth: { type: 'bot', token } or MACRO_BOT_TOKEN.")}).with(Z$.string.startsWith(I4),(O)=>[F6,O]).otherwise((O)=>["Authorization",`Bearer ${O}`])}async function A6($){return typeof $==="function"?await $():$}async function H4($,O,j){return c($).with({type:"bot"},async(x)=>{let S=await A6(x.token);if(!S.startsWith(b1))throw Error("user API key passed as a bot token. Use auth: { type: 'user', apiKey } or MACRO_API_KEY.");let K=[["x-macro-bot-token",S]];if(!j?.hasBotScope)K.push(["x-macro-bot-scope",x.scope??(O?"user":"team")]);if(O)K.push(["x-macro-bot-for-macro-user-id",O]);return K}).with({type:"user",apiKey:Z$.string},({apiKey:x})=>{if(x.startsWith(b1))throw Error("bot token passed as a user credential. Use auth: { type: 'bot', token } or MACRO_BOT_TOKEN.");return[[F6,x]]}).with({type:"user"},async({token:x})=>{return[T4(await A6(x))]}).exhaustive()}class k1{scheduledAction;unfurl;agentHarness;auth;calendar;cognition;contacts;email;notification;properties;search;storage;webAppUrl;wsVerify;events;authConfig;hosts;localPortmap;requestedAs;selfBotRecord;selfPrincipal;constructor($){let O=R4($),j=O==="local"?M6():void 0,x={...w1[O],...j?.hosts,...$.hosts};this.hosts=x,this.localPortmap=j;let S=typeof process<"u"?{}.MACRO_WEB_URL:void 0;if(this.webAppUrl=$.webAppUrl??S??j?.webAppUrl??T6[O],this.authConfig=D4($),this.requestedAs=$.requestedAs,this.requestedAs&&this.authConfig.type!=="bot")throw Error("requestedAs() requires bot auth — a user token always acts as its own user");this.wsVerify=$.wsVerify,this.scheduledAction=U$(new Tx({client:this.makeClient(x["scheduled-action"])}),"scheduled-action",$.onRequest),this.unfurl=U$(new kx({client:this.makeClient(x.unfurl)}),"unfurl",$.onRequest),this.agentHarness=U$(new bj({client:this.makeClient(x["agent-harness"])}),"agent-harness",$.onRequest),this.auth=U$(new hj({client:this.makeClient(x.auth)}),"auth",$.onRequest),this.calendar=U$(new lj({client:this.makeClient(x.calendar)}),"calendar",$.onRequest),this.cognition=U$(new nj({client:this.makeClient(x.cognition)}),"cognition",$.onRequest),this.contacts=U$(new $x({client:this.makeClient(x.contacts)}),"contacts",$.onRequest),this.email=U$(new Zx({client:this.makeClient(x.email)}),"email",$.onRequest),this.notification=U$(new Gx({client:this.makeClient(x.notification)}),"notification",$.onRequest),this.properties=U$(new Lx({client:this.makeClient(x.properties)}),"properties",$.onRequest),this.search=U$(new _x({client:this.makeClient(x.search)}),"search",$.onRequest),this.storage=U$(new Ex({client:this.makeClient(x.storage)}),"storage",$.onRequest);let K=typeof process<"u"?{}.MACRO_WEBHOOK_SECRET:void 0,Z=$.webhookSecret??K;this.events=new q1(this,Z)}hasActingUser(){return this.authConfig.type==="user"||this.requestedAs!==void 0}selfBot(){return this.selfBotRecord??=new lO(this).me().catch(($)=>{throw this.selfBotRecord=void 0,$}),this.selfBotRecord}myPrincipalId(){return this.selfPrincipal??=(this.authConfig.type==="bot"?this.selfBot().then(($)=>`bot|${$.id}`):P.me(this).then(($)=>$.id)).catch(($)=>{throw this.selfPrincipal=void 0,$}),this.selfPrincipal}makeClient($){let O=Jj({baseUrl:$});return O.interceptors.request.use(async(j)=>{let x=await H4(this.authConfig,this.requestedAs,{hasBotScope:j.headers.has("x-macro-bot-scope")});for(let[S,K]of x)j.headers.set(S,K);return j}),O}}function R4($){if($.env)return $.env;let O=typeof process<"u"?{}.MACRO_ENV:void 0;if(!O)return"prod";if(!(O in w1))throw Error(`invalid MACRO_ENV "${O}" — expected local, dev, or prod`);return O}function D4($){if($.auth)return $.auth;if($.token)return{type:"user",token:$.token};let O=typeof process<"u"?{}.MACRO_API_KEY:void 0,j=typeof process<"u"?{}.MACRO_BOT_TOKEN:void 0;if(O&&j)throw Error("both MACRO_API_KEY and MACRO_BOT_TOKEN are set — pass auth to new Macro() to pick one");if(j)return{type:"bot",token:j};return{type:"user",token:O??(()=>{throw Error("no Macro credential. Set MACRO_API_KEY (API key or bearer token) or MACRO_BOT_TOKEN, or pass token/auth to new Macro().")})}}class g1{id;constructor($){this.id=$}static byId($){return new g1($)}toJSON(){return{id:this.id}}}class E6{routines;unfurls;agents;initiatives;apiKeys;harnesses;meetings;githubPullRequests;entityMentions;agentSessions;ai;bots;calendar;calls;channels;whatsapp;chats;crm;databases;documents;email;favorites;foreignEntities;forms;notifications;pins;projects;properties;tasks;teams;users;webhooks;workspace;events;webAppUrl;_client;opts;constructor($){this.opts=$;let O=new k1($);this._client=O,this.routines=new _0(O),this.unfurls=new A0(O),this.agents=new mx(O),this.initiatives=new N0(O),this.apiKeys=new ux(O),this.harnesses=new L0(O),this.meetings=new U0(O),this.githubPullRequests=new B0(O),this.entityMentions=new Q0(O),this.agentSessions=new hx(O),this.ai=new cx(O),this.bots=new lO(O),this.calendar=new dx(O),this.calls=new lx(O),this.channels=new px(O),this.whatsapp=new w0(O),this.chats=new ax(O),this.crm=new nx(O),this.databases=new Z0(O),this.documents=new X0(O),this.email=new Y0(O),this.favorites=new G0(O),this.foreignEntities=new J0(O),this.forms=new V0(O),this.notifications=new z0(O),this.pins=new I0(O),this.projects=new T0(O),this.properties=new H0(O),this.tasks=new P0(O),this.teams=new M0(O),this.users=new F0(O),this.webhooks=new E0(O),this.workspace=new k0(O),this.events=O.events,this.webAppUrl=O.webAppUrl}myPrincipalId(){return this._client.myPrincipalId()}requestedAs($){return new E6({...this.opts,requestedAs:$.id})}}export{i$ as wrapXml,O$ as toBody,z4 as observeRequests,b6 as msg,f6 as here,YO as WhatsAppUpload,a$ as WhatsAppSend,_O as WhatsAppRemoteGroup,_$ as WhatsAppMessage,v$ as WhatsAppGroup,CO as WhatsAppAccount,s$ as UserApiKey,dO as ToolApproval,N$ as SessionReview,D0 as RoutineExecution,XO as Routine,vx as ReviewItem,W0 as PullRequestChangeset,Uj as PipelineTable,VO as PipelineRow,zj as PipelineColumn,L$ as MessageThread,H$ as Meeting,S0 as MacroOpRefusedError,E6 as Macro,SO as Initiative,RO as HarnessPairing,B$ as Harness,HO as GithubPullRequest,p$ as FormSection,TO as FormResponse,Mj as FormReference,r$ as FormQuestion,NO as FormOption,y$ as Form,IO as EntityMention,o as EntityAccess,LO as EmailFilter,BO as EmailDraft,eO as DraftAttachment,pO as DocumentVersion,JO as DocumentAnchor,oO as DevicePairing,t$ as CrmPipeline,yx as ConversationTurn,uO as CodeExecution,iO as ChatMessage,aO as ChatGeneration,g1 as ChannelPicture,GO as ChannelActivity,q$ as CalendarNote,Bj as AgentConversation,I$ as Agent,zO as AccessRequest};
+`),F=[],y;for(let R of a)if(R.startsWith("data:"))F.push(R.replace(/^data:\s*/,""));else if(R.startsWith("event:"))y=R.replace(/^event:\s*/,"");else if(R.startsWith("id:"))J=R.replace(/^id:\s*/,"");else if(R.startsWith("retry:")){let h=Number.parseInt(R.replace(/^retry:\s*/,""),10);if(!Number.isNaN(h))V=h}let C,v=!1;if(F.length){let R=F.join(`
+`);try{C=JSON.parse(R),v=!0}catch{C=R}}if(v){if(S)await S(C);if(x)C=await x(C)}if(j?.({data:C,event:y,id:J,retry:V}),F.length)yield C}}}finally{T.removeEventListener("abort",k),H.releaseLock()}break}catch(D){if(O?.(D),Z!==void 0&&B>=Z)break;let _=Math.min(V*2**(B-1),X??30000);await I(_)}}}()}}var Z4=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},X4=($)=>{switch($){case"form":return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20";default:return","}},K4=($)=>{switch($){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}},wx=({allowReserved:$,explode:O,name:j,style:x,value:S})=>{if(!O){let X=($?S:S.map((Y)=>encodeURIComponent(Y))).join(X4(x));switch(x){case"label":return`.${X}`;case"matrix":return`;${j}=${X}`;case"simple":return X;default:return`${j}=${X}`}}let K=Z4(x),Z=S.map((X)=>{if(x==="label"||x==="simple")return $?X:encodeURIComponent(X);return yO({allowReserved:$,name:j,value:X})}).join(K);return x==="label"||x==="matrix"?K+Z:Z},yO=({allowReserved:$,name:O,value:j})=>{if(j===void 0||j===null)return"";if(typeof j==="object")throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${O}=${$?j:encodeURIComponent(j)}`},qx=({allowReserved:$,explode:O,name:j,style:x,value:S,valueOnly:K})=>{if(S instanceof Date)return K?S.toISOString():`${j}=${S.toISOString()}`;if(x!=="deepObject"&&!O){let Y=[];Object.entries(S).forEach(([Q,J])=>{Y=[...Y,Q,$?J:encodeURIComponent(J)]});let L=Y.join(",");switch(x){case"form":return`${j}=${L}`;case"label":return`.${L}`;case"matrix":return`;${j}=${L}`;default:return L}}let Z=K4(x),X=Object.entries(S).map(([Y,L])=>yO({allowReserved:$,name:x==="deepObject"?`${j}[${Y}]`:Y,value:L})).join(Z);return x==="label"||x==="matrix"?Z+X:X};var Y4=/\{[^{}]+\}/g,G4=({path:$,url:O})=>{let j=O,x=O.match(Y4);if(x)for(let S of x){let K=!1,Z=S.substring(1,S.length-1),X="simple";if(Z.endsWith("*"))K=!0,Z=Z.substring(0,Z.length-1);if(Z.startsWith("."))Z=Z.substring(1),X="label";else if(Z.startsWith(";"))Z=Z.substring(1),X="matrix";let Y=$[Z];if(Y===void 0||Y===null)continue;if(Array.isArray(Y)){j=j.replace(S,wx({explode:K,name:Z,style:X,value:Y}));continue}if(typeof Y==="object"){j=j.replace(S,qx({explode:K,name:Z,style:X,value:Y,valueOnly:!0}));continue}if(X==="matrix"){j=j.replace(S,`;${yO({name:Z,value:Y})}`);continue}let L=encodeURIComponent(X==="label"?`.${Y}`:Y);j=j.replace(S,L)}return j},Q6=({baseUrl:$,path:O,query:j,querySerializer:x,url:S})=>{let K=S.startsWith("/")?S:`/${S}`,Z=($??"")+K;if(O)Z=G4({path:O,url:Z});let X=j?x(j):"";if(X.startsWith("?"))X=X.substring(1);if(X)Z+=`?${X}`;return Z};function M1($){let O=$.body!==void 0;if(O&&$.bodySerializer){if("serializedBody"in $)return $.serializedBody!==void 0&&$.serializedBody!==""?$.serializedBody:null;return $.body!==""?$.body:null}if(O)return $.body;return}var J6=async($,O)=>{let j=typeof O==="function"?await O($):O;if(!j)return;if($.scheme==="bearer")return`Bearer ${j}`;if($.scheme==="basic")return`Basic ${btoa(j)}`;return j};var V6={bodySerializer:($)=>JSON.stringify($,(O,j)=>typeof j==="bigint"?j.toString():j)};var W6=({parameters:$={},...O}={})=>{return(x)=>{let S=[];if(x&&typeof x==="object")for(let K in x){let Z=x[K];if(Z===void 0||Z===null)continue;let X=$[K]||O;if(Array.isArray(Z)){let Y=wx({allowReserved:X.allowReserved,explode:!0,name:K,style:"form",value:Z,...X.array});if(Y)S.push(Y)}else if(typeof Z==="object"){let Y=qx({allowReserved:X.allowReserved,explode:!0,name:K,style:"deepObject",value:Z,...X.object});if(Y)S.push(Y)}else{let Y=yO({allowReserved:X.allowReserved,name:K,value:Z});if(Y)S.push(Y)}}return S.join("&")}},B6=($)=>{if(!$)return"stream";let O=$.split(";")[0]?.trim();if(!O)return;if(O.startsWith("application/json")||O.endsWith("+json"))return"json";if(O==="multipart/form-data")return"formData";if(["application/","audio/","image/","video/"].some((j)=>O.startsWith(j)))return"blob";if(O.startsWith("text/"))return"text";return},Q4=($,O)=>{if(!O)return!1;if($.headers.has(O)||$.query?.[O]||$.headers.get("Cookie")?.includes(`${O}=`))return!0;return!1};async function L6($){for(let O of $.security??[]){if(Q4($,O.name))continue;let j=await J6(O,$.auth);if(!j)continue;let x=O.name??"Authorization";switch(O.in){case"query":if(!$.query)$.query={};$.query[x]=j;break;case"cookie":$.headers.append("Cookie",`${x}=${j}`);break;case"header":default:$.headers.set(x,j);break}}}var A1=($)=>Q6({baseUrl:$.baseUrl,path:$.path,query:$.query,querySerializer:typeof $.querySerializer==="function"?$.querySerializer:W6($.querySerializer),url:$.url}),F1=($,O)=>{let j={...$,...O};if(j.baseUrl?.endsWith("/"))j.baseUrl=j.baseUrl.substring(0,j.baseUrl.length-1);return j.headers=bx($.headers,O.headers),j},J4=($)=>{let O=[];return $.forEach((j,x)=>{O.push([x,j])}),O},bx=(...$)=>{let O=new Headers;for(let j of $){if(!j)continue;let x=j instanceof Headers?J4(j):Object.entries(j);for(let[S,K]of x)if(K===null)O.delete(S);else if(Array.isArray(K))for(let Z of K)O.append(S,Z);else if(K!==void 0)O.set(S,typeof K==="object"?JSON.stringify(K):K)}return O};class fx{fns=[];clear(){this.fns=[]}eject($){let O=this.getInterceptorIndex($);if(this.fns[O])this.fns[O]=null}exists($){let O=this.getInterceptorIndex($);return Boolean(this.fns[O])}getInterceptorIndex($){if(typeof $==="number")return this.fns[$]?$:-1;return this.fns.indexOf($)}update($,O){let j=this.getInterceptorIndex($);if(this.fns[j])return this.fns[j]=O,$;return!1}use($){return this.fns.push($),this.fns.length-1}}var N6=()=>({error:new fx,request:new fx,response:new fx}),V4=W6({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),W4={"Content-Type":"application/json"},Vj=($={})=>({...V6,headers:W4,parseAs:"auto",querySerializer:V4,...$});var E1=($={})=>{let O=F1(Vj(),$),j=()=>({...O}),x=(Q)=>{return O=F1(O,Q),j()},S=N6(),K=async(Q)=>{let J={...O,...Q,fetch:Q.fetch??O.fetch??globalThis.fetch,headers:bx(O.headers,Q.headers),serializedBody:void 0};if(J.security)await L6(J);if(J.requestValidator)await J.requestValidator(J);if(J.body!==void 0&&J.bodySerializer)J.serializedBody=J.bodySerializer(J.body);if(J.body===void 0||J.serializedBody==="")J.headers.delete("Content-Type");let I=J,z=A1(I);return{opts:I,url:z}},Z=async(Q)=>{let J=Q.throwOnError??O.throwOnError,I=Q.responseStyle??O.responseStyle,z,W;try{let{opts:V,url:B}=await K(Q),T={redirect:"follow",...V,body:M1(V)};z=new Request(B,T);for(let N of S.request.fns)if(N)z=await N(z,V);let A=V.fetch;W=await A(z);for(let N of S.response.fns)if(N)W=await N(W,z,V);let D={request:z,response:W};if(W.ok){let N=(V.parseAs==="auto"?B6(W.headers.get("Content-Type")):V.parseAs)??"json";if(W.status===204||W.headers.get("Content-Length")==="0"){let U;switch(N){case"arrayBuffer":case"blob":case"text":U=await W[N]();break;case"formData":U=new FormData;break;case"stream":U=W.body;break;case"json":default:U={};break}return V.responseStyle==="data"?U:{data:U,...D}}let H;switch(N){case"arrayBuffer":case"blob":case"formData":case"text":H=await W[N]();break;case"json":{let U=await W.text();H=U?JSON.parse(U):{};break}case"stream":return V.responseStyle==="data"?W.body:{data:W.body,...D}}if(N==="json"){if(V.responseValidator)await V.responseValidator(H);if(V.responseTransformer)H=await V.responseTransformer(H)}return V.responseStyle==="data"?H:{data:H,...D}}let _=await W.text(),q;try{q=JSON.parse(_)}catch{}throw q??_}catch(V){let B=V;for(let T of S.error.fns)if(T)B=await T(B,W,z,Q);if(B=B||{},J)throw B;return I==="data"?void 0:{error:B,request:z,response:W}}},X=(Q)=>(J)=>Z({...J,method:Q}),Y=(Q)=>async(J)=>{let{opts:I,url:z}=await K(J);return G6({...I,body:I.body,method:Q,onRequest:async(W,V)=>{let B=new Request(W,V);for(let T of S.request.fns)if(T)B=await T(B,I);return B},serializedBody:M1(I),url:z})};return{buildUrl:(Q)=>A1({...O,...Q}),connect:X("CONNECT"),delete:X("DELETE"),get:X("GET"),getConfig:j,head:X("HEAD"),interceptors:S,options:X("OPTIONS"),patch:X("PATCH"),post:X("POST"),put:X("PUT"),request:Z,setConfig:x,sse:{connect:Y("CONNECT"),delete:Y("DELETE"),get:Y("GET"),head:Y("HEAD"),options:Y("OPTIONS"),patch:Y("PATCH"),post:Y("POST"),put:Y("PUT"),trace:Y("TRACE")},trace:X("TRACE")}};var U6=E1(Vj());class z6{client;constructor($){this.client=$?.client??U6}}class I6{defaultKey="default";instances=new Map;get($){let O=this.instances.get($??this.defaultKey);if(!O)throw Error('No SDK client found. Create one with "new Sdk()" to fix this error.');return O}set($,O){this.instances.set(O??this.defaultKey,$)}}class kx extends z6{static __registry=new I6;constructor($){super($);kx.__registry.set(this,$?.key)}proxyRequestHandler($){return($.client??this.client).get({url:"/proxy",...$})}getUnfurl($){return($.client??this.client).get({url:"/unfurl",...$})}getUnfurlBulk($){return($.client??this.client).post({url:"/unfurl/bulk",...$,headers:{"Content-Type":"application/json",...$.headers}})}}var T6={dev:"https://dev.macro.com",prod:"https://macro.com",local:"http://localhost:3000"},w1={dev:{"agent-harness":"https://dev-gateway.macro.com/agent-harness",storage:"https://dev-gateway.macro.com/dss",auth:"https://dev-gateway.macro.com/auth",email:"https://dev-gateway.macro.com/email",calendar:"https://dev-gateway.macro.com/calendar",cognition:"https://dev-gateway.macro.com/cognition",notification:"https://dev-gateway.macro.com/notification",properties:"https://dev-gateway.macro.com/dss",search:"https://dev-gateway.macro.com/dss","scheduled-action":"https://dev-gateway.macro.com/scheduled-action","static-files":"https://static-file-service-dev.macro.com",connection:"https://dev-gateway.macro.com/connection-gateway",contacts:"https://dev-gateway.macro.com/contacts",unfurl:"https://dev-gateway.macro.com/unfurl"},prod:{"agent-harness":"https://gateway.macro.com/agent-harness",storage:"https://gateway.macro.com/dss",auth:"https://gateway.macro.com/auth",email:"https://gateway.macro.com/email",calendar:"https://gateway.macro.com/calendar",cognition:"https://gateway.macro.com/cognition",notification:"https://gateway.macro.com/notification",properties:"https://gateway.macro.com/dss",search:"https://gateway.macro.com/dss","scheduled-action":"https://gateway.macro.com/scheduled-action","static-files":"https://static-file-service.macro.com",connection:"https://gateway.macro.com/connection-gateway",contacts:"https://gateway.macro.com/contacts",unfurl:"https://gateway.macro.com/unfurl"},local:{"agent-harness":"http://localhost:8101",storage:"http://localhost:8086",auth:"http://localhost:8080",email:"http://localhost:8087",calendar:"http://localhost:8088/calendar",cognition:"http://localhost:8101/cognition",notification:"http://localhost:8089",properties:"http://localhost:8086",search:"http://localhost:8086","scheduled-action":"http://localhost:8101/scheduled-action","static-files":"http://localhost:8100",connection:"http://localhost:8082",contacts:"http://localhost:8083",unfurl:"http://localhost:8095"}};function B4($,O){let j=O?.channel_id;return O&&j?{channel:b.byId($,j),thread:new h$($,j,O.thread_id)}:{channel:void 0,thread:void 0}}function E$($,O){return{session:i.byId($,O.session_id),owner:P.byId($,O.owner_id),...B4($,O.origin)}}function vO($,O,j){let x=O.origin?.channel_id;return x&&j?e.byId($,x,j):void 0}function hO($,O){return O?P.byId($,O):void 0}function H6($,O){return c(O).with({event_type:"agent_session.opened"},({metadata:j})=>({event_type:"agent_session.opened",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.turn_started"},({metadata:j})=>({event_type:"agent_session.turn_started",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.turn_ended"},({metadata:j})=>({event_type:"agent_session.turn_ended",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.command_rejected"},({metadata:j})=>({event_type:"agent_session.command_rejected",metadata:j,...E$($,j.identity),actor:hO($,j.actor),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.settled"},({metadata:j})=>({event_type:"agent_session.settled",metadata:j,...E$($,j.identity),actor:hO($,j.last_turn?.actor),announcement:vO($,j.identity,j.last_turn?.announcement_message_id)})).with({event_type:"agent_session.waiting_for_input"},({metadata:j})=>({event_type:"agent_session.waiting_for_input",metadata:j,...E$($,j.identity),announcement:vO($,j.identity,j.announcement_message_id)})).with({event_type:"agent_session.input_received"},({metadata:j})=>({event_type:"agent_session.input_received",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.mentioned"},({metadata:j})=>({event_type:"agent_session.mentioned",metadata:j,...E$($,j.identity),mentionedBy:hO($,j.mentioned_by),mentioned:j.mentioned.map((x)=>P.byId($,x))})).with({event_type:"agent_session.stopped"},({metadata:j})=>({event_type:"agent_session.stopped",metadata:j,...E$($,j.identity),actor:hO($,j.turn_in_flight?.actor),announcement:vO($,j.identity,j.turn_in_flight?.announcement_message_id)})).with({event_type:"agent_session.renamed"},({metadata:j})=>({event_type:"agent_session.renamed",metadata:j,...E$($,j.identity)})).with({event_type:"agent_session.deleted"},({metadata:j})=>({event_type:"agent_session.deleted",metadata:j,...E$($,j.identity)})).exhaustive((j)=>{console.warn("macro sdk: unknown agent session event",j);return})}var R6="macro|";function P$($,O){return O.startsWith(R6)&&O.length>R6.length?P.byId($,O.toLowerCase()):void 0}function D6($,O){return c(O).with({event_type:"channel.created"},({metadata:j})=>({event_type:"channel.created",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor),participants:j.participant_user_ids.map((x)=>P.byId($,x))})).with({event_type:"channel.updated"},({metadata:j})=>({event_type:"channel.updated",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.deleted"},({metadata:j})=>({event_type:"channel.deleted",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.picture_changed"},({metadata:j})=>({event_type:"channel.picture_changed",metadata:j,channel:b.byId($,j.channel_id),actor:P$($,j.actor)})).with({event_type:"channel.participant_added"},({metadata:j})=>({event_type:"channel.participant_added",metadata:j,channel:b.byId($,j.channel_id),addedBy:P$($,j.added_by),addedUsers:j.added_user_ids.map((x)=>P.byId($,x))})).with({event_type:"channel.participant_removed"},({metadata:j})=>({event_type:"channel.participant_removed",metadata:j,channel:b.byId($,j.channel_id),removedBy:P.byId($,j.removed_by),removedUsers:j.removed_user_ids.map((x)=>P.byId($,x))})).exhaustive((j)=>{console.warn("macro sdk: unknown channel event",j);return})}function _6($,O){return c(O).with({event_type:"document.created"},({metadata:j})=>({event_type:"document.created",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner),project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.updated"},({metadata:j})=>({event_type:"document.updated",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner),actor:j.actor_user_id?P.byId($,j.actor_user_id):void 0,project:j.project_id?n.byId($,j.project_id):void 0,previousProject:j.previous_project_id?n.byId($,j.previous_project_id):void 0})).with({event_type:"document.deleted"},({metadata:j})=>({event_type:"document.deleted",metadata:j,document:w.byId($,j.document_id),actor:j.actor_user_id?P.byId($,j.actor_user_id):void 0,project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.content_uploaded"},({metadata:j})=>({event_type:"document.content_uploaded",metadata:j,document:w.byId($,j.document_id),owner:P.byId($,j.owner)})).with({event_type:"document.sync_content_updated"},({metadata:j})=>({event_type:"document.sync_content_updated",metadata:j,document:w.byId($,j.document_id)})).with({event_type:"document.purged"},({metadata:j})=>({event_type:"document.purged",metadata:j,document:w.byId($,j.document_id)})).with({event_type:"document.copied"},({metadata:j})=>({event_type:"document.copied",metadata:j,document:w.byId($,j.document_id),sourceDocument:w.byId($,j.source_document_id),owner:P.byId($,j.owner),project:j.project_id?n.byId($,j.project_id):void 0})).with({event_type:"document.interaction"},({metadata:j})=>({event_type:"document.interaction",metadata:j,document:w.byId($,j.document_id)})).exhaustive((j)=>{console.warn("macro sdk: unknown document event",j);return})}function mO($,O,j=[]){let x=O.parent;if(x.type==="call")return{type:"call",call:Q$.byId($,x.id),message:u$.byId($,x.id,O.message_id),threadId:x.id};if(x.type==="channel")return{type:"channel",channel:b.byId($,x.id),message:e.byId($,x.id,O.message_id,j),thread:O.thread_id?new h$($,x.id,O.thread_id):void 0};return{type:"document",document:w.byId($,x.id),comment:c$.byId($,x.id,O.message_id),threadId:O.root_id}}function C6($,O){return c(O).with({event_type:"message.posted"},({metadata:j})=>({event_type:"message.posted",metadata:j,target:mO($,j,j.mentions),sender:P$($,j.sender)})).with({event_type:"message.mentioned"},({metadata:j})=>({event_type:"message.mentioned",metadata:j,target:mO($,j),sender:P$($,j.sender)})).with({event_type:"message.patched"},({metadata:j})=>({event_type:"message.patched",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.deleted"},({metadata:j})=>({event_type:"message.deleted",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.attachment_created"},({metadata:j})=>({event_type:"message.attachment_created",metadata:j,target:mO($,j),actor:P$($,j.actor)})).with({event_type:"message.attachment_removed"},({metadata:j})=>({event_type:"message.attachment_removed",metadata:j,target:mO($,j),actor:P$($,j.actor)})).exhaustive((j)=>{console.warn("macro sdk: unknown message event",j);return})}async function P6($){let O=new TextEncoder,j=await crypto.subtle.importKey("raw",O.encode($.secret),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),x=await crypto.subtle.sign("HMAC",j,O.encode(`${$.timestamp}.${$.rawBody}`));return`v1=${new Uint8Array(x).toHex()}`===$.signature}var L4="webhook.validation.test";function N4($,O){return c(O).with({event_type:Z$.string.startsWith("document.")},(j)=>_6($,j)).with({event_type:Z$.string.startsWith("channel.")},(j)=>D6($,j)).with({event_type:Z$.string.startsWith("message.")},(j)=>C6($,j)).with({event_type:Z$.string.startsWith("agent_session.")},(j)=>H6($,j)).otherwise(()=>{return})}class q1{client;secret;handlers=new Map;constructor($,O){this.client=$;this.secret=O}on($,O){let j=this.handlers.get($)??new Set;return j.add(O),this.handlers.set($,j),()=>j.delete(O)}onSelfMention($){return this.on("message.mentioned",async(O)=>{if(O.metadata.mentioned.entity_id.toLowerCase()!==(await this.client.myPrincipalId()).toLowerCase())return;await $(O)})}async listen($={}){let O=$.filters??this.filtersFromHandlers();if(O.length===0||O.every((K)=>K.events.length===0))throw new f("listen() needs filters — pass filters or register handlers with .on() first");let j=new AbortController;if($.signal)if($.signal.aborted)j.abort();else $.signal.addEventListener("abort",()=>j.abort(),{once:!0});let{stream:x}=await this.client.storage.streamEvents({query:{scope:$.scope??"user",filters:JSON.stringify(O)},signal:j.signal});return(async()=>{try{for await(let K of x)await this.dispatchEvent(K)}catch{if(j.signal.aborted)return;throw new f("event stream failed")}})().catch(()=>{}),()=>{j.abort()}}async handle($,O){if(!this.secret)throw new f("webhookSecret is required to verify incoming webhook deliveries");if(!await P6({secret:this.secret,timestamp:O.timestamp??"",rawBody:$,signature:O.signature??""}))throw new f("invalid webhook signature");if(O.event===L4)return;await this.dispatchEvent(JSON.parse($))}webhook(){if(!this.secret)throw new f("webhookSecret is required to verify incoming webhook deliveries");return async($)=>{return await this.handle(await $.text(),{event:$.headers.get("x-macro-event")??void 0,eventId:$.headers.get("x-macro-event-id")??void 0,timestamp:$.headers.get("x-macro-timestamp")??void 0,signature:$.headers.get("x-macro-signature")??void 0}),new Response("ok")}}filtersFromHandlers(){let $=[...this.handlers.entries()].filter(([,O])=>O.size>0).map(([O])=>O);return $.length>0?[{events:$}]:[]}async dispatchEvent($){let O=typeof $==="string"?JSON.parse($):$;if(O===null||typeof O!=="object"||!("event_type"in O))return;let j=O,x=this.handlers.get(j.event_type);if(!x||x.size===0)return;let S=N4(this.client,j);if(!S)return;await Promise.all([...x].map((K)=>K(S)))}}function M6(){return}var U4=0,f1;function z4($){f1=$}function U$($,O,j){if(!j&&!f1)return $;let x=(S)=>{for(let K of[f1,j])try{Promise.resolve(K?.(S)).catch(()=>{})}catch{}};return new Proxy($,{get(S,K,Z){let X=Reflect.get(S,K,Z);if(typeof K!=="string"||typeof X!=="function")return X;return async(...Y)=>{let L={id:++U4,service:O,operation:K};x({...L,status:"started"});try{let Q=await Reflect.apply(X,S,Y),J=Q!==null&&typeof Q==="object"&&"error"in Q&&Q.error!=null;return x({...L,status:J?"failed":"completed"}),Q}catch(Q){throw x({...L,status:"failed"}),Q}}}})}var F6="x-macro-user-api-key",I4="mak_",b1="mbot_";function T4($){return c($).with(Z$.string.startsWith(b1),()=>{throw Error("bot token passed as a user credential. Use auth: { type: 'bot', token } or MACRO_BOT_TOKEN.")}).with(Z$.string.startsWith(I4),(O)=>[F6,O]).otherwise((O)=>["Authorization",`Bearer ${O}`])}async function A6($){return typeof $==="function"?await $():$}async function H4($,O,j){return c($).with({type:"bot"},async(x)=>{let S=await A6(x.token);if(!S.startsWith(b1))throw Error("user API key passed as a bot token. Use auth: { type: 'user', apiKey } or MACRO_API_KEY.");let K=[["x-macro-bot-token",S]];if(!j?.hasBotScope)K.push(["x-macro-bot-scope",x.scope??(O?"user":"team")]);if(O)K.push(["x-macro-bot-for-macro-user-id",O]);return K}).with({type:"user",apiKey:Z$.string},({apiKey:x})=>{if(x.startsWith(b1))throw Error("bot token passed as a user credential. Use auth: { type: 'bot', token } or MACRO_BOT_TOKEN.");return[[F6,x]]}).with({type:"user"},async({token:x})=>{return[T4(await A6(x))]}).exhaustive()}class k1{scheduledAction;unfurl;agentHarness;auth;calendar;cognition;contacts;email;notification;properties;search;storage;webAppUrl;wsVerify;events;authConfig;hosts;localPortmap;requestedAs;selfBotRecord;selfPrincipal;constructor($){let O=R4($),j=O==="local"?M6():void 0,x={...w1[O],...j?.hosts,...$.hosts};this.hosts=x,this.localPortmap=j;let S=typeof process<"u"?{}.MACRO_WEB_URL:void 0;if(this.webAppUrl=$.webAppUrl??S??j?.webAppUrl??T6[O],this.authConfig=D4($),this.requestedAs=$.requestedAs,this.requestedAs&&this.authConfig.type!=="bot")throw Error("requestedAs() requires bot auth — a user token always acts as its own user");this.wsVerify=$.wsVerify,this.scheduledAction=U$(new Tx({client:this.makeClient(x["scheduled-action"])}),"scheduled-action",$.onRequest),this.unfurl=U$(new kx({client:this.makeClient(x.unfurl)}),"unfurl",$.onRequest),this.agentHarness=U$(new bj({client:this.makeClient(x["agent-harness"])}),"agent-harness",$.onRequest),this.auth=U$(new hj({client:this.makeClient(x.auth)}),"auth",$.onRequest),this.calendar=U$(new lj({client:this.makeClient(x.calendar)}),"calendar",$.onRequest),this.cognition=U$(new nj({client:this.makeClient(x.cognition)}),"cognition",$.onRequest),this.contacts=U$(new $x({client:this.makeClient(x.contacts)}),"contacts",$.onRequest),this.email=U$(new Zx({client:this.makeClient(x.email)}),"email",$.onRequest),this.notification=U$(new Qx({client:this.makeClient(x.notification)}),"notification",$.onRequest),this.properties=U$(new Lx({client:this.makeClient(x.properties)}),"properties",$.onRequest),this.search=U$(new Cx({client:this.makeClient(x.search)}),"search",$.onRequest),this.storage=U$(new Ex({client:this.makeClient(x.storage)}),"storage",$.onRequest);let K=typeof process<"u"?{}.MACRO_WEBHOOK_SECRET:void 0,Z=$.webhookSecret??K;this.events=new q1(this,Z)}hasActingUser(){return this.authConfig.type==="user"||this.requestedAs!==void 0}selfBot(){return this.selfBotRecord??=new lO(this).me().catch(($)=>{throw this.selfBotRecord=void 0,$}),this.selfBotRecord}myPrincipalId(){return this.selfPrincipal??=(this.authConfig.type==="bot"?this.selfBot().then(($)=>`bot|${$.id}`):P.me(this).then(($)=>$.id)).catch(($)=>{throw this.selfPrincipal=void 0,$}),this.selfPrincipal}makeClient($){let O=Jj({baseUrl:$});return O.interceptors.request.use(async(j)=>{let x=await H4(this.authConfig,this.requestedAs,{hasBotScope:j.headers.has("x-macro-bot-scope")});for(let[S,K]of x)j.headers.set(S,K);return j}),O}}function R4($){if($.env)return $.env;let O=typeof process<"u"?{}.MACRO_ENV:void 0;if(!O)return"prod";if(!(O in w1))throw Error(`invalid MACRO_ENV "${O}" — expected local, dev, or prod`);return O}function D4($){if($.auth)return $.auth;if($.token)return{type:"user",token:$.token};let O=typeof process<"u"?{}.MACRO_API_KEY:void 0,j=typeof process<"u"?{}.MACRO_BOT_TOKEN:void 0;if(O&&j)throw Error("both MACRO_API_KEY and MACRO_BOT_TOKEN are set — pass auth to new Macro() to pick one");if(j)return{type:"bot",token:j};return{type:"user",token:O??(()=>{throw Error("no Macro credential. Set MACRO_API_KEY (API key or bearer token) or MACRO_BOT_TOKEN, or pass token/auth to new Macro().")})}}class g1{id;constructor($){this.id=$}static byId($){return new g1($)}toJSON(){return{id:this.id}}}class E6{routines;unfurls;agents;initiatives;apiKeys;harnesses;meetings;githubPullRequests;entityMentions;agentSessions;ai;bots;calendar;calls;channels;whatsapp;chats;crm;databases;documents;email;favorites;foreignEntities;forms;notifications;pins;projects;properties;tasks;teams;users;webhooks;workspace;events;webAppUrl;_client;opts;constructor($){this.opts=$;let O=new k1($);this._client=O,this.routines=new C0(O),this.unfurls=new A0(O),this.agents=new mx(O),this.initiatives=new N0(O),this.apiKeys=new ux(O),this.harnesses=new L0(O),this.meetings=new U0(O),this.githubPullRequests=new B0(O),this.entityMentions=new G0(O),this.agentSessions=new hx(O),this.ai=new cx(O),this.bots=new lO(O),this.calendar=new dx(O),this.calls=new lx(O),this.channels=new px(O),this.whatsapp=new w0(O),this.chats=new ax(O),this.crm=new nx(O),this.databases=new Z0(O),this.documents=new X0(O),this.email=new Y0(O),this.favorites=new Q0(O),this.foreignEntities=new J0(O),this.forms=new V0(O),this.notifications=new z0(O),this.pins=new I0(O),this.projects=new T0(O),this.properties=new H0(O),this.tasks=new P0(O),this.teams=new M0(O),this.users=new F0(O),this.webhooks=new E0(O),this.workspace=new k0(O),this.events=O.events,this.webAppUrl=O.webAppUrl}myPrincipalId(){return this._client.myPrincipalId()}requestedAs($){return new E6({...this.opts,requestedAs:$.id})}}export{i$ as wrapXml,O$ as toBody,z4 as observeRequests,b6 as msg,f6 as here,YO as WhatsAppUpload,a$ as WhatsAppSend,C$ as WhatsAppMessage,v$ as WhatsAppGroup,CO as WhatsAppChat,_O as WhatsAppAccount,s$ as UserApiKey,dO as ToolApproval,N$ as SessionReview,D0 as RoutineExecution,XO as Routine,vx as ReviewItem,W0 as PullRequestChangeset,Uj as PipelineTable,VO as PipelineRow,zj as PipelineColumn,L$ as MessageThread,H$ as Meeting,S0 as MacroOpRefusedError,E6 as Macro,SO as Initiative,RO as HarnessPairing,B$ as Harness,HO as GithubPullRequest,p$ as FormSection,TO as FormResponse,Mj as FormReference,r$ as FormQuestion,NO as FormOption,y$ as Form,IO as EntityMention,o as EntityAccess,LO as EmailFilter,BO as EmailDraft,eO as DraftAttachment,pO as DocumentVersion,JO as DocumentAnchor,oO as DevicePairing,t$ as CrmPipeline,yx as ConversationTurn,uO as CodeExecution,iO as ChatMessage,aO as ChatGeneration,g1 as ChannelPicture,QO as ChannelActivity,q$ as CalendarNote,Bj as AgentConversation,I$ as Agent,zO as AccessRequest};
diff --git a/crates/whatsapp_e2e/src/lib.rs b/crates/whatsapp_e2e/src/lib.rs
index fa21a886545..a6ef5847e27 100644
--- a/crates/whatsapp_e2e/src/lib.rs
+++ b/crates/whatsapp_e2e/src/lib.rs
@@ -45,6 +45,8 @@ pub const TIMINGS: Timings = Timings {
drain_deadline: Duration::from_secs(30),
health_every: Duration::from_secs(60),
groups_refresh_interval: Duration::ZERO,
+ backfill_timeout: Duration::from_secs(3),
+ backfill_retry: Duration::from_secs(2),
};
/// One fake KMS shared by every replica, as they share the real KMS key.
diff --git a/crates/whatsapp_e2e/src/test.rs b/crates/whatsapp_e2e/src/test.rs
index 3bf562bf202..495cf9b97a6 100644
--- a/crates/whatsapp_e2e/src/test.rs
+++ b/crates/whatsapp_e2e/src/test.rs
@@ -14,7 +14,7 @@ use sqlx::{Connection, PgConnection, PgPool};
use uuid::Uuid;
use whatsapp_fake_server::{FakePhone, FakeWhatsApp};
use whatsapp_linked::domain::models::{
- AccountState, AdoptGroup, Binding, Features, ReplyContent, SendAuthority, SendReply,
+ AccountState, AdoptGroup, Binding, ChatKind, Features, ReplyContent, SendAuthority, SendReply,
};
use whatsapp_linked::domain::ports::{Authorizer, LinkedResult};
use whatsapp_linked::domain::service::LinkedService;
@@ -139,6 +139,18 @@ impl World {
})
.await
.expect("the account connects as the phone's number");
+ // Like a real phone, send the new device its chat list once it can
+ // be encrypted to; this also starts the phone's session with it.
+ assert!(
+ self.whatsapp
+ .wait_until_keys_uploaded(&device, TIMEOUT)
+ .await,
+ "the new device uploads its keys"
+ );
+ phone
+ .send_history_sync(phone.chat_list())
+ .await
+ .expect("the phone sends the initial chat list");
device
}
@@ -275,6 +287,17 @@ impl World {
.fetch_all(pool)
.await,
),
+ (
+ "chats (jid, kind, anchor, backfill)",
+ sqlx::query_scalar!(
+ r#"SELECT c.chat_jid || ' ' || c.kind || ' ' || coalesce(c.anchor->>'id', '-') || ' '
+ || coalesce((SELECT string_agg(coalesce(g.backfill_state, '-') || '/' || g.backfill_imported, ',')
+ FROM whatsapp_group g WHERE g.group_jid = c.chat_jid), '') AS "row!"
+ FROM whatsapp_chat c"#
+ )
+ .fetch_all(pool)
+ .await,
+ ),
(
"sends (state, source)",
sqlx::query_scalar!(
@@ -875,3 +898,300 @@ async fn group_renames_and_removals_in_whatsapp_reach_macro_live(pool: PgPool) {
assert!(!detail.can_send, "Alice can no longer send");
replica.drain(TIMEOUT).await.unwrap();
}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn senders_named_only_by_lid_land_as_the_people_they_are(pool: PgPool) {
+ let world = World::new(pool).await;
+ let replica = world.replica().await;
+ let (_, binding) = world.alice_adopted().await;
+ world.whatsapp.address_by_lid_only(&world.group);
+
+ // Alice writes from her phone: WhatsApp names her by LID only, but the
+ // message is flagged as her own.
+ let own = world
+ .alice
+ .send_text(&world.group, "Hi there")
+ .await
+ .unwrap();
+ // The customer, named by LID only, is known from the group's participants.
+ let customer = world
+ .customer
+ .send_text(&world.group, "hello from a LID")
+ .await
+ .unwrap();
+ assert_eq!(world.timeline(&binding, &own).await, ["Hi there"]);
+ assert_eq!(
+ world.timeline(&binding, &customer).await,
+ ["hello from a LID"]
+ );
+
+ let authors = sqlx::query!(
+ r#"SELECT m.source_id, p.user_id, array_agg(a.jid ORDER BY a.jid) AS "aliases!"
+ FROM whatsapp_group_message m JOIN whatsapp_external_person p ON p.id = m.person_id
+ JOIN whatsapp_identity_alias a ON a.person_id = p.id
+ WHERE m.binding_id = $1 GROUP BY m.source_id, p.user_id"#,
+ binding.id
+ )
+ .fetch_all(&world.pool)
+ .await
+ .unwrap();
+ let author = |source: &str| {
+ authors
+ .iter()
+ .find(|row| row.source_id == source)
+ .map(|row| (row.user_id.clone(), row.aliases.clone()))
+ .unwrap()
+ };
+ assert_eq!(
+ author(&own),
+ (
+ Some(ALICE.to_owned()),
+ vec![world.alice.lid().to_string(), world.alice.jid().to_string()]
+ )
+ );
+ assert_eq!(
+ author(&customer),
+ (
+ None,
+ vec![
+ world.customer.lid().to_string(),
+ world.customer.jid().to_string()
+ ]
+ )
+ );
+ let quarantined = sqlx::query_scalar!(
+ r#"SELECT count(*) AS "count!" FROM whatsapp_inbound_event WHERE state = 'quarantined'"#
+ )
+ .fetch_one(&world.pool)
+ .await
+ .unwrap();
+ assert_eq!(quarantined, 0);
+ replica.drain(TIMEOUT).await.unwrap();
+}
+
+/// The group's backfill state and count once it is one of `states`.
+async fn backfill_state(world: &World, binding: &Binding, states: &[&str]) -> (String, i32) {
+ let state = wait_for_rows(&world.pool, TIMEOUT, || async {
+ let row = sqlx::query!(
+ "SELECT backfill_state, backfill_imported FROM whatsapp_group WHERE id = $1",
+ binding.id
+ )
+ .fetch_one(&world.pool)
+ .await
+ .unwrap();
+ let state = row.backfill_state?;
+ states
+ .contains(&state.as_str())
+ .then_some((state, row.backfill_imported))
+ })
+ .await;
+ world
+ .expect(state, &format!("the backfill reaches one of {states:?}"))
+ .await
+}
+
+/// Every stored copy of each message with its origin, by text (WhatsApp
+/// stamps whole seconds, so time does not order them within a test).
+async fn origins(pool: &PgPool, binding: Uuid) -> Vec<(String, String)> {
+ sqlx::query!(
+ "SELECT body, origin FROM whatsapp_group_message WHERE binding_id = $1 AND message_id IS NOT NULL ORDER BY body",
+ binding
+ )
+ .fetch_all(pool)
+ .await
+ .unwrap()
+ .into_iter()
+ .map(|row| (row.body, row.origin))
+ .collect()
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn adding_a_group_imports_its_earlier_messages_once_without_notifying(pool: PgPool) {
+ let world = World::new(pool).await;
+ let replica = world.replica().await;
+ world.pair(ALICE, &world.alice).await;
+ let mut before = vec![];
+ for text in ["first", "second", "third"] {
+ before.push(world.customer.send_text(&world.group, text).await.unwrap());
+ }
+ // Alice's device saw the newest one live: it is the chat's anchor.
+ let anchored = wait_for_rows(&world.pool, TIMEOUT, || async {
+ sqlx::query_scalar!(
+ "SELECT 1 AS found FROM whatsapp_chat WHERE chat_jid = $1 AND anchor->>'id' = $2",
+ world.group.to_string(),
+ before[2]
+ )
+ .fetch_optional(&world.pool)
+ .await
+ .unwrap()
+ })
+ .await;
+ world
+ .expect(anchored, "the chat list knows the group's newest message")
+ .await;
+
+ let binding = world.adopt(ALICE, &[]).await;
+ assert_eq!(
+ backfill_state(&world, &binding, &["done", "partial"]).await,
+ ("done".to_owned(), 2)
+ );
+ let imported = wait_for_rows(&world.pool, TIMEOUT, || async {
+ let stored = origins(&world.pool, binding.id).await;
+ (stored.len() == 3).then_some(stored)
+ })
+ .await;
+ assert_eq!(
+ world
+ .expect(imported, "all three earlier messages land")
+ .await,
+ [
+ ("first".to_owned(), "history".to_owned()),
+ ("second".to_owned(), "history".to_owned()),
+ ("third".to_owned(), "history".to_owned()),
+ ]
+ );
+ let summary = world
+ .linked
+ .adopted_groups(ALICE)
+ .await
+ .unwrap()
+ .into_iter()
+ .find(|group| group.id == binding.id)
+ .unwrap();
+ assert_eq!(summary.unread_count, 0, "history is never unread");
+ let notifying = sqlx::query_scalar!(
+ r#"SELECT count(*) AS "count!" FROM whatsapp_group_message WHERE binding_id = $1 AND origin <> 'history'"#,
+ binding.id
+ )
+ .fetch_one(&world.pool)
+ .await
+ .unwrap();
+ assert_eq!(notifying, 0, "nothing imported notifies");
+ replica.drain(TIMEOUT).await.unwrap();
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn backfill_waits_for_an_offline_phone_and_never_duplicates_live_messages(pool: PgPool) {
+ let world = World::new(pool).await;
+ let replica = world.replica().await;
+ world.pair(ALICE, &world.alice).await;
+ world
+ .customer
+ .send_text(&world.group, "old one")
+ .await
+ .unwrap();
+ world.alice.answer_history_requests(false);
+ let binding = world.adopt(ALICE, &[]).await;
+
+ // Live while the import waits: kept live, once.
+ let live = world
+ .customer
+ .send_text(&world.group, "live during import")
+ .await
+ .unwrap();
+ assert_eq!(
+ world.timeline(&binding, &live).await,
+ ["live during import"]
+ );
+ backfill_state(&world, &binding, &["waiting_for_phone"]).await;
+ let newest = world
+ .customer
+ .send_text(&world.group, "newest")
+ .await
+ .unwrap();
+ world.timeline(&binding, &newest).await;
+
+ // The phone comes back: the import resumes and the page that contains
+ // the live message adds only what was missing.
+ world.alice.answer_history_requests(true);
+ backfill_state(&world, &binding, &["done"]).await;
+ let stored = wait_for_rows(&world.pool, TIMEOUT, || async {
+ let stored = origins(&world.pool, binding.id).await;
+ (stored.len() == 3).then_some(stored)
+ })
+ .await;
+ let stored = world.expect(stored, "three messages, each once").await;
+ assert_eq!(
+ stored
+ .iter()
+ .map(|(body, _)| body.as_str())
+ .collect::>(),
+ ["live during import", "newest", "old one"]
+ );
+ // "old one" may also have arrived live, within adoption's clock skew.
+ assert_eq!(
+ (stored[0].1.as_str(), stored[1].1.as_str()),
+ ("whatsapp", "whatsapp")
+ );
+ replica.drain(TIMEOUT).await.unwrap();
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn the_chat_list_follows_history_sync_and_live_messages(pool: PgPool) {
+ let world = World::new(pool).await;
+ // Before linking: a direct chat and a group message on Alice's phone.
+ world
+ .customer
+ .send_text(&world.alice.jid(), "are you there?")
+ .await
+ .unwrap();
+ world
+ .customer
+ .send_text(&world.group, "hi all")
+ .await
+ .unwrap();
+ let replica = world.replica().await;
+ world.pair(ALICE, &world.alice).await;
+ world
+ .alice
+ .send_history_sync(world.alice.chat_list())
+ .await
+ .unwrap();
+ let listed = wait_for_rows(&world.pool, TIMEOUT, || async {
+ let chats = world.linked.chats(ALICE).await.ok()?.chats;
+ let direct = chats
+ .iter()
+ .find(|chat| chat.jid == world.customer.jid().to_string())?
+ .clone();
+ // History sync can land before the roster refresh that decides
+ // whether the group can be added.
+ let group = chats
+ .iter()
+ .find(|chat| {
+ chat.jid == world.group.to_string()
+ && chat.last_activity_at.is_some()
+ && chat.can_add
+ })?
+ .clone();
+ Some((direct, group))
+ })
+ .await;
+ let (direct, group) = world
+ .expect(listed, "history sync lists the direct chat and the group")
+ .await;
+ assert_eq!(direct.kind, ChatKind::Direct);
+ assert_eq!(direct.name, "Customer");
+ assert!(!direct.can_add);
+ assert_eq!(
+ direct.cannot_add_reason.as_deref(),
+ Some("direct chats can't be added to Macro yet")
+ );
+ assert_eq!(group.kind, ChatKind::Group);
+ assert_eq!(group.name, "Customer escalations");
+ assert!(group.can_add);
+
+ // A live direct message moves its chat to the top.
+ world
+ .bob
+ .send_text(&world.alice.jid(), "lunch?")
+ .await
+ .unwrap();
+ let top = wait_for_rows(&world.pool, TIMEOUT, || async {
+ let chats = world.linked.chats(ALICE).await.ok()?.chats;
+ (chats.first()?.jid == world.bob.jid().to_string()).then(|| chats[0].clone())
+ })
+ .await;
+ let top = world.expect(top, "Bob's new chat is first").await;
+ assert_eq!(top.name, "Bob");
+ replica.drain(TIMEOUT).await.unwrap();
+}
diff --git a/crates/whatsapp_e2e/src/watch_tables.sql b/crates/whatsapp_e2e/src/watch_tables.sql
index 2e05c6ab128..5e7a6b76959 100644
--- a/crates/whatsapp_e2e/src/watch_tables.sql
+++ b/crates/whatsapp_e2e/src/watch_tables.sql
@@ -26,3 +26,5 @@ CREATE TRIGGER e2e_changed AFTER INSERT OR UPDATE OR DELETE ON whatsapp_send
FOR EACH STATEMENT EXECUTE FUNCTION e2e_notify_changed();
CREATE TRIGGER e2e_changed AFTER INSERT OR UPDATE OR DELETE ON whatsapp_group_attachment
FOR EACH STATEMENT EXECUTE FUNCTION e2e_notify_changed();
+CREATE TRIGGER e2e_changed AFTER INSERT OR UPDATE OR DELETE ON whatsapp_chat
+ FOR EACH STATEMENT EXECUTE FUNCTION e2e_notify_changed();
diff --git a/crates/whatsapp_fake_server/AGENTS.md b/crates/whatsapp_fake_server/AGENTS.md
index 4e5c29e3c7a..ac4f847e3e7 100644
--- a/crates/whatsapp_fake_server/AGENTS.md
+++ b/crates/whatsapp_fake_server/AGENTS.md
@@ -31,6 +31,11 @@ Lets the session service and its tests run end to end without WhatsApp.
delivery counters, waiters).
- `src/state.rs`: routing, IQ handlers (encrypt, usync, w:g2, w:m), offline queues.
- `src/phone.rs`: fake phones: send/receive with real Signal, QR approval.
+ Phones remember chat messages and answer their linked devices' peer
+ requests: on-demand history pages and placeholder resends
+ (`answer_history_requests(false)` is an offline phone).
+ `send_history_sync` / `chat_list()` send history-sync bundles inline.
+ `FakeWhatsApp::address_by_lid_only` drops `participant_pn` in a group.
- `src/connection.rs`: handshake, login, `conflict replaced`, pairing.
## Checks
diff --git a/crates/whatsapp_fake_server/Cargo.toml b/crates/whatsapp_fake_server/Cargo.toml
index 0ebbdbce23b..68228d4c398 100644
--- a/crates/whatsapp_fake_server/Cargo.toml
+++ b/crates/whatsapp_fake_server/Cargo.toml
@@ -11,6 +11,7 @@ async-trait = { workspace = true }
axum = { workspace = true }
base64 = { workspace = true }
chrono = { workspace = true }
+flate2 = { workspace = true }
futures = { workspace = true }
hmac = { workspace = true }
nom = { workspace = true }
diff --git a/crates/whatsapp_fake_server/src/lib.rs b/crates/whatsapp_fake_server/src/lib.rs
index 715f502ce36..c11a54b4776 100644
--- a/crates/whatsapp_fake_server/src/lib.rs
+++ b/crates/whatsapp_fake_server/src/lib.rs
@@ -387,6 +387,15 @@ impl FakeWhatsApp {
group
}
+ /// From now on, messages in the group name their sender by LID only
+ /// (no `participant_pn`), so receivers must know the sender's pair.
+ pub fn address_by_lid_only(&self, group: &Jid) {
+ self.shared
+ .lock()
+ .lid_only_groups
+ .insert(group.user.clone());
+ }
+
/// Renames a group and notifies its members' linked devices.
pub fn rename_group(&self, group: &Jid, subject: &str) {
let mut state = self.shared.lock();
diff --git a/crates/whatsapp_fake_server/src/phone.rs b/crates/whatsapp_fake_server/src/phone.rs
index e88ad15b481..dd366e4ceee 100644
--- a/crates/whatsapp_fake_server/src/phone.rs
+++ b/crates/whatsapp_fake_server/src/phone.rs
@@ -6,6 +6,8 @@
//! groups, decrypts what it receives and sends delivery receipts. It also
//! approves pairing QR codes, like scanning one in "Linked devices".
+use std::io::Write as _;
+use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, PoisonError};
use std::time::Duration;
@@ -24,9 +26,17 @@ use whatsmeow::pair::ADV_ACCOUNT_SIGNATURE_PREFIX;
use whatsmeow::proto::wa_adv::{
AdvDeviceIdentity, AdvSignedDeviceIdentity, AdvSignedDeviceIdentityHmac,
};
+use whatsmeow::proto::wa_common::MessageKey;
use whatsmeow::proto::wa_e2e::{
- DeviceSentMessage, ImageMessage, Message, SenderKeyDistributionMessage,
+ DeviceSentMessage, HistorySyncNotification, ImageMessage, Message,
+ PeerDataOperationRequestMessage, PeerDataOperationRequestResponseMessage,
+ PeerDataOperationRequestType, ProtocolMessage, SenderKeyDistributionMessage,
+ peer_data_operation_request_response_message, protocol_message,
};
+use whatsmeow::proto::wa_history_sync::conversation::EndOfHistoryTransferType;
+use whatsmeow::proto::wa_history_sync::history_sync::HistorySyncType;
+use whatsmeow::proto::wa_history_sync::{Conversation, HistorySync, HistorySyncMsg};
+use whatsmeow::proto::wa_web::WebMessageInfo;
use whatsmeow::signal::{
CiphertextType, CurveSignatures, SenderKeyName, SignalAddress, SignalProtocol,
SignalProtocolStore,
@@ -90,6 +100,11 @@ pub(crate) struct Inbox {
pub(crate) receipts: Vec,
/// Why stanzas failed to decrypt, for test diagnostics.
pub(crate) failures: Vec,
+ /// Every chat message the phone sent or received, oldest first: what it
+ /// answers history requests from.
+ pub(crate) history: Vec,
+ /// History requests its linked devices sent (on demand and resends).
+ pub(crate) history_requests: usize,
}
/// One fake user's phone.
@@ -101,6 +116,9 @@ pub(crate) struct PhoneCore {
/// Serializes Signal operations, like whatsmeow's send lock.
crypto: tokio::sync::Mutex<()>,
pub(crate) inbox: Mutex,
+ /// Answers its linked devices' history requests; off is a phone that is
+ /// offline (requests are dropped, unanswered).
+ answers: AtomicBool,
}
impl PhoneCore {
@@ -112,6 +130,7 @@ impl PhoneCore {
signal: LibsignalProtocol::new(),
crypto: tokio::sync::Mutex::new(()),
inbox: Mutex::new(Inbox::default()),
+ answers: AtomicBool::new(true),
}
}
@@ -296,12 +315,292 @@ impl FakePhone {
.lock()
.route_message(&self.core.address(), &stanza);
self.shared.changed();
+ match attr_string(&ack, "error").as_str() {
+ "" => {
+ if message.protocol_message.is_none() && message.reaction_message.is_none() {
+ self.remember(chat, &id, true, None, &message);
+ }
+ Ok(id)
+ }
+ code => Err(SendError::Rejected(code.to_owned())),
+ }
+ }
+
+ /// Keeps a chat message for answering history requests.
+ fn remember(
+ &self,
+ chat: &Jid,
+ id: &str,
+ from_me: bool,
+ sender: Option<&Jid>,
+ message: &Message,
+ ) {
+ let participant = sender
+ .filter(|_| chat.server == GROUP_SERVER)
+ .map(|sender| sender.to_non_ad().to_string());
+ self.core.inbox().history.push(WebMessageInfo {
+ key: MessageKey {
+ remote_jid: Some(chat.to_string()),
+ from_me: Some(from_me),
+ id: Some(id.to_owned()),
+ participant: participant.clone(),
+ },
+ message: Some(message.clone()),
+ message_timestamp: Some(chrono::Utc::now().timestamp().max(0) as u64),
+ participant,
+ ..WebMessageInfo::default()
+ });
+ }
+
+ /// Whether the phone answers its linked devices' history requests (an
+ /// offline phone doesn't; requests sent meanwhile are lost).
+ pub fn answer_history_requests(&self, answers: bool) {
+ self.core.answers.store(answers, Ordering::SeqCst);
+ }
+
+ /// How many history requests (on demand or message resends) the phone's
+ /// linked devices sent it, answered or not.
+ pub fn history_requests(&self) -> usize {
+ self.core.inbox().history_requests
+ }
+
+ /// Sends a history-sync bundle to the user's linked devices, inline like
+ /// an initial bootstrap.
+ pub async fn send_history_sync(&self, history: HistorySync) -> Result {
+ let payload = {
+ let mut encoder =
+ flate2::write::ZlibEncoder::new(Vec::new(), flate2::Compression::fast());
+ encoder
+ .write_all(&history.encode_to_vec())
+ .map_err(|_| SendError::UnknownChat)?;
+ encoder.finish().map_err(|_| SendError::UnknownChat)?
+ };
+ self.send_to_own_devices(Message {
+ protocol_message: Some(Box::new(ProtocolMessage {
+ r#type: Some(protocol_message::Type::HistorySyncNotification as i32),
+ history_sync_notification: Some(HistorySyncNotification {
+ sync_type: Some(history.sync_type),
+ chunk_order: history.chunk_order,
+ initial_hist_bootstrap_inline_payload: Some(payload),
+ ..HistorySyncNotification::default()
+ }),
+ ..ProtocolMessage::default()
+ })),
+ ..Message::default()
+ })
+ .await
+ }
+
+ /// The phone's chat list as an initial-bootstrap history sync: every chat
+ /// it has messages in, named (group subject; the other person's name),
+ /// with its newest message.
+ pub fn chat_list(&self) -> HistorySync {
+ let history = self.core.inbox().history.clone();
+ let mut conversations: Vec = vec![];
+ for message in history.iter().rev() {
+ let chat = message.key.remote_jid.clone().unwrap_or_default();
+ if conversations
+ .iter()
+ .any(|conversation| conversation.id == chat)
+ {
+ continue;
+ }
+ // Direct chats are LID chats, with the phone number alongside.
+ let (name, pn_jid) = chat
+ .parse::()
+ .ok()
+ .map(|jid| {
+ let state = self.shared.lock();
+ if jid.server == GROUP_SERVER {
+ let name = state
+ .groups
+ .get(&jid.user)
+ .map(|group| group.subject.clone());
+ (name, None)
+ } else {
+ let phone = state.phone_of(&jid);
+ let name = phone
+ .as_ref()
+ .and_then(|phone| state.users.get(phone))
+ .map(|user| user.push_name.clone());
+ (
+ name,
+ phone.map(|phone| device_jid(&phone, 0, false).to_string()),
+ )
+ }
+ })
+ .unwrap_or_default();
+ conversations.push(Conversation {
+ id: chat,
+ name,
+ pn_jid,
+ conversation_timestamp: message.message_timestamp,
+ messages: vec![HistorySyncMsg {
+ message: Some(message.clone()),
+ msg_order_id: None,
+ }],
+ ..Conversation::default()
+ });
+ }
+ HistorySync {
+ sync_type: HistorySyncType::InitialBootstrap as i32,
+ conversations,
+ ..HistorySync::default()
+ }
+ }
+
+ /// Sends a protocol message to the user's own linked devices only, as a
+ /// peer message.
+ async fn send_to_own_devices(&self, message: Message) -> Result {
+ let id = random_id();
+ let _crypto = self.core.crypto.lock().await;
+ let targets: Vec = {
+ let state = self.shared.lock();
+ let user = state
+ .users
+ .get(&self.core.phone)
+ .ok_or(SendError::UnknownChat)?;
+ user.devices
+ .keys()
+ .filter(|device| **device != 0)
+ .map(|device| {
+ state.jid_of(
+ &DeviceAddress {
+ phone: self.core.phone.clone(),
+ device: *device,
+ },
+ true,
+ )
+ })
+ .collect()
+ };
+ let store = self.core.device.signal_store(None);
+ let plaintext = message.encode_to_vec();
+ let mut participants = Vec::new();
+ for target in targets {
+ participants.extend(self.encrypt_for(&store, &target, &plaintext).await?);
+ }
+ let stanza = node(
+ "message",
+ vec![
+ ("id", text(&id)),
+ ("to", jid(&self.jid())),
+ ("type", text("text")),
+ ("category", text("peer")),
+ ],
+ children(vec![node("participants", vec![], children(participants))]),
+ );
+ let ack = self
+ .shared
+ .lock()
+ .route_message(&self.core.address(), &stanza);
+ self.shared.changed();
match attr_string(&ack, "error").as_str() {
"" => Ok(id),
code => Err(SendError::Rejected(code.to_owned())),
}
}
+ /// Answers a linked device's history request: an on-demand page of a
+ /// chat's messages before a given one, or one message sent again.
+ async fn answer(&self, request_id: String, request: PeerDataOperationRequestMessage) {
+ {
+ let mut inbox = self.core.inbox();
+ inbox.history_requests += 1;
+ }
+ self.shared.changed();
+ if !self.core.answers.load(Ordering::SeqCst) {
+ return;
+ }
+ let history = self.core.inbox().history.clone();
+ let kind = request
+ .peer_data_operation_request_type
+ .and_then(|kind| PeerDataOperationRequestType::try_from(kind).ok());
+ let result = match kind {
+ Some(PeerDataOperationRequestType::HistorySyncOnDemand) => {
+ let Some(on_demand) = request.history_sync_on_demand_request else {
+ return;
+ };
+ let chat = on_demand.chat_jid.unwrap_or_default();
+ let in_chat: Vec<&WebMessageInfo> = history
+ .iter()
+ .filter(|message| message.key.remote_jid.as_deref() == Some(chat.as_str()))
+ .collect();
+ let before = in_chat
+ .iter()
+ .position(|message| message.key.id == on_demand.oldest_msg_id)
+ .unwrap_or(0);
+ let count = usize::try_from(on_demand.on_demand_msg_count.unwrap_or(50).max(0))
+ .unwrap_or(50);
+ let start = before.saturating_sub(count);
+ let page: Vec = in_chat[start..before]
+ .iter()
+ .map(|message| HistorySyncMsg {
+ message: Some((*message).clone()),
+ msg_order_id: None,
+ })
+ .collect();
+ let end = if start == 0 {
+ EndOfHistoryTransferType::CompleteAndNoMoreMessageRemainOnPrimary
+ } else {
+ EndOfHistoryTransferType::CompleteOnDemandSyncButMoreMsgRemainOnPrimary
+ };
+ self.send_history_sync(HistorySync {
+ sync_type: HistorySyncType::OnDemand as i32,
+ conversations: vec![Conversation {
+ id: chat,
+ messages: page,
+ end_of_history_transfer_type: Some(end as i32),
+ ..Conversation::default()
+ }],
+ ..HistorySync::default()
+ })
+ .await
+ }
+ Some(PeerDataOperationRequestType::PlaceholderMessageResend) => {
+ let results = request
+ .placeholder_message_resend_request
+ .iter()
+ .filter_map(|resend| {
+ let key = resend.message_key.as_ref()?;
+ let message = history.iter().find(|message| message.key.id == key.id)?;
+ Some(peer_data_operation_request_response_message::PeerDataOperationResult {
+ placeholder_message_resend_response: Some(
+ peer_data_operation_request_response_message::peer_data_operation_result::PlaceholderMessageResendResponse {
+ web_message_info_bytes: Some(message.encode_to_vec()),
+ },
+ ),
+ ..Default::default()
+ })
+ })
+ .collect();
+ self.send_to_own_devices(Message {
+ protocol_message: Some(Box::new(ProtocolMessage {
+ r#type: Some(
+ protocol_message::Type::PeerDataOperationRequestResponseMessage as i32,
+ ),
+ peer_data_operation_request_response_message: Some(
+ PeerDataOperationRequestResponseMessage {
+ peer_data_operation_request_type: Some(
+ PeerDataOperationRequestType::PlaceholderMessageResend as i32,
+ ),
+ stanza_id: Some(request_id),
+ peer_data_operation_result: results,
+ },
+ ),
+ ..ProtocolMessage::default()
+ })),
+ ..Message::default()
+ })
+ .await
+ }
+ _ => return,
+ };
+ if let Err(error) = result {
+ self.fail(&format!("answering a history request: {error:?}"));
+ }
+ }
+
async fn group_stanza(
&self,
chat: &Jid,
@@ -759,6 +1058,20 @@ impl FakePhone {
if message == Message::default() {
return;
}
+ if let Some(request) = message
+ .protocol_message
+ .as_ref()
+ .and_then(|protocol| protocol.peer_data_operation_request_message.clone())
+ {
+ // Answered once this stanza's crypto lock is released.
+ let phone = self.clone();
+ let id = id.to_owned();
+ tokio::spawn(async move { phone.answer(id, request).await });
+ return;
+ }
+ if message.protocol_message.is_none() && message.reaction_message.is_none() {
+ self.remember(&chat, id, false, Some(sender), &message);
+ }
self.core.inbox().messages.push(ReceivedMessage {
id: id.to_owned(),
chat,
diff --git a/crates/whatsapp_fake_server/src/state.rs b/crates/whatsapp_fake_server/src/state.rs
index 521b71beafa..6df3f09255f 100644
--- a/crates/whatsapp_fake_server/src/state.rs
+++ b/crates/whatsapp_fake_server/src/state.rs
@@ -122,6 +122,9 @@ pub(crate) struct State {
pub(crate) submitted: Vec<(DeviceAddress, String)>,
/// Devices whose submitted messages are routed but never acked.
pub(crate) withheld_acks: std::collections::HashSet,
+ /// Groups whose messages name the sender by LID only, without
+ /// `participant_pn`, as WhatsApp does for some senders.
+ pub(crate) lid_only_groups: std::collections::HashSet,
}
/// A device JID in the phone-number or LID domain.
@@ -383,28 +386,56 @@ impl State {
if content.is_empty() {
continue;
}
+ let mut attrs = vec![
+ ("from", jid(&to)),
+ ("participant", jid(&participant)),
+ ("addressing_mode", text("lid")),
+ ("id", text(&id)),
+ ("t", timestamp.clone()),
+ ("type", text(&message_type)),
+ ("notify", text(&push_name)),
+ ];
+ if !self.lid_only_groups.contains(&to.user) {
+ attrs.push(("participant_pn", jid(&participant_pn)));
+ }
+ let delivery = node("message", attrs, children(content));
+ self.deliver(&target, delivery);
+ }
+ return ack;
+ }
+
+ let Some(_) = self.phone_of(&to) else {
+ return with_error(ack, 404);
+ };
+ // A linked device's peer message (requests to its phone): one top-level
+ // `` for the user's primary device.
+ if attr_string(stanza, "category") == "peer" && direct.is_empty() {
+ let primary = DeviceAddress {
+ phone: sender.phone.clone(),
+ device: 0,
+ };
+ let content: Vec = stanza
+ .get_children()
+ .iter()
+ .filter(|child| child.tag == "enc")
+ .cloned()
+ .collect();
+ if primary != *sender && !content.is_empty() {
let delivery = node(
"message",
vec![
- ("from", jid(&to)),
- ("participant", jid(&participant)),
- ("participant_pn", jid(&participant_pn)),
- ("addressing_mode", text("lid")),
+ ("from", jid(&self.jid_of(sender, true))),
("id", text(&id)),
("t", timestamp.clone()),
("type", text(&message_type)),
- ("notify", text(&push_name)),
+ ("category", text("peer")),
],
- children(content),
+ children(with_identity(content)),
);
- self.deliver(&target, delivery);
+ self.deliver(&primary, delivery);
}
return ack;
}
-
- let Some(_) = self.phone_of(&to) else {
- return with_error(ack, 404);
- };
for (target_jid, enc) in direct {
let Some(target) = self.resolve(&target_jid) else {
continue;
@@ -421,6 +452,9 @@ impl State {
("type", text(&message_type)),
("notify", text(&push_name)),
];
+ if attr_string(stanza, "category") == "peer" {
+ attrs.push(("category", text("peer")));
+ }
if target.phone == sender.phone {
attrs.push(("recipient", jid(&to)));
if let Some(pn) = stanza.attrs.get("peer_recipient_pn") {
diff --git a/crates/whatsapp_linked/AGENTS.md b/crates/whatsapp_linked/AGENTS.md
index c4941e821af..2fa15d2b26a 100644
--- a/crates/whatsapp_linked/AGENTS.md
+++ b/crates/whatsapp_linked/AGENTS.md
@@ -17,7 +17,16 @@ rows and `NOTIFY` (the `outbound::pg` notify helper).
its event types (no whatsmeow types).
- `src/domain/effects.rs`: notification outbox drained by DSS.
- `src/outbound/pg/ingest.rs`: canonical identity `(binding, person, source id)`,
- quarantine, deferral and the standalone message write.
+ quarantine, deferral and the standalone message write. Senders are resolved
+ first (`resolve_sender_in`): WhatsApp's from-me flag means the account's own
+ identity; a LID-only sender takes its phone number from the account's roster
+ pair. Only what is still LID-only is quarantined.
+- `src/outbound/pg/chats.rs`: the account's chat list (`whatsapp_chat`,
+ `GET /chats` via `LinkedService::chats`) and importing earlier messages of
+ added groups (`backfill_*` columns on `whatsapp_group`; limits
+ `BACKFILL_MESSAGE_LIMIT` / `BACKFILL_MAX_AGE_DAYS` in `models.rs`). History
+ messages skip the adoption-time boundary but only reach the account owner's
+ own groups (`observed_bindings_in`).
- `src/outbound/pg/sends.rs`: enqueue, claim, dispatch fence, outcome. A
repeated intent key returns the stored send before any other check.
- `src/outbound/pg.rs` `signals`: JSON `NOTIFY` payloads with `traceparent`
diff --git a/crates/whatsapp_linked/src/domain/events.rs b/crates/whatsapp_linked/src/domain/events.rs
index 650fbed03bd..8f6e7a55eae 100644
--- a/crates/whatsapp_linked/src/domain/events.rs
+++ b/crates/whatsapp_linked/src/domain/events.rs
@@ -1,7 +1,7 @@
//! Types exchanged in-process with the WhatsApp session service. They carry no
//! whatsmeow types: the session service maps protocol events onto them.
-use super::models::{Identity, PairingState};
+use super::models::{BackfillState, ChatKind, Identity, PairingState};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -129,6 +129,10 @@ pub struct Message {
pub source_id: String,
/// Actual author, not the observing account.
pub sender: Identity,
+ /// WhatsApp's from-me flag: the observing account itself sent it, so
+ /// the sender is the account's own identity whatever address it carries.
+ #[serde(default)]
+ pub from_me: bool,
/// Kind.
pub kind: MessageKind,
/// Plain text, emoji or placeholder.
@@ -324,3 +328,76 @@ pub enum SendOutcome {
/// The request may have reached WhatsApp but no acknowledgement arrived.
Unknown,
}
+
+/// A message WhatsApp knows by its key: where importing earlier messages
+/// starts (a chat's newest message) or continues (the oldest imported).
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MessageAnchor {
+ /// WhatsApp message id.
+ pub id: String,
+ /// Protocol timestamp.
+ pub at: DateTime,
+ /// Sent by the account itself.
+ pub from_me: bool,
+ /// Author in a group (asking the phone to resend one message needs it).
+ #[serde(default)]
+ pub sender_jid: Option,
+}
+
+/// What the session service learned about one chat of the account's list.
+/// `None` fields keep what is stored.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ChatUpdate {
+ /// Chat JID (groups; direct chats by phone-number JID when known).
+ pub jid: String,
+ /// Group or direct.
+ pub kind: ChatKind,
+ /// Group subject, or the contact or WhatsApp name of a direct chat.
+ pub name: Option,
+ /// Activity; only ever moves forward.
+ pub last_activity_at: Option>,
+ /// Archived in WhatsApp.
+ pub archived: Option,
+ /// Pinned in WhatsApp.
+ pub pinned: Option,
+ /// A message in the chat; kept when newer than the stored one.
+ pub anchor: Option,
+ /// Add the chat when it is not listed yet. Name, archive and pin updates
+ /// alone never add a chat.
+ pub create: bool,
+}
+
+/// A group whose earlier messages the owner's account is importing.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct BackfillWork {
+ /// Group entity.
+ pub group_id: Uuid,
+ /// WhatsApp group.
+ pub group_jid: String,
+ /// Progress.
+ pub state: BackfillState,
+ /// Messages received so far.
+ pub imported: u32,
+ /// Oldest message imported so far; the next page is requested before it.
+ pub cursor: Option,
+ /// The chat's newest known message, where the first page starts.
+ pub anchor: Option,
+ /// When the group was added.
+ pub adopted_at: DateTime,
+ /// When the last page was requested and not answered yet.
+ pub requested_at: Option>,
+}
+
+/// One page of earlier messages the phone sent for a chat.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct HistoryPage {
+ /// Chat JID.
+ pub chat_jid: String,
+ /// Messages in the page.
+ pub messages: u32,
+ /// The oldest of them.
+ pub oldest: Option,
+ /// The phone says there is nothing older.
+ pub complete: bool,
+}
diff --git a/crates/whatsapp_linked/src/domain/models.rs b/crates/whatsapp_linked/src/domain/models.rs
index 2f66519f8f9..055e29ba0de 100644
--- a/crates/whatsapp_linked/src/domain/models.rs
+++ b/crates/whatsapp_linked/src/domain/models.rs
@@ -358,6 +358,158 @@ impl GroupInfo {
}
}
+/// Whether a WhatsApp chat is a group or a one-to-one chat.
+#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
+#[serde(rename_all = "snake_case")]
+#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
+#[cfg_attr(feature = "schema", schema(as = LinkedChatKind))]
+pub enum ChatKind {
+ /// A group chat (`…@g.us`).
+ Group,
+ /// A direct chat with one person.
+ Direct,
+}
+
+impl ChatKind {
+ /// Stable storage spelling.
+ pub const fn as_str(self) -> &'static str {
+ match self {
+ Self::Group => "group",
+ Self::Direct => "direct",
+ }
+ }
+
+ /// Parse the storage spelling.
+ pub fn parse(value: &str) -> Option {
+ Some(match value {
+ "group" => Self::Group,
+ "direct" => Self::Direct,
+ _ => return None,
+ })
+ }
+}
+
+/// Why a chat can't be added to Macro. The same sentences adoption refuses with.
+pub mod cannot_add {
+ /// The account's WhatsApp left the group or was removed.
+ pub const NOT_IN_GROUP: &str = "your WhatsApp is not in this group any more";
+ /// Community announcement or parent groups.
+ pub const COMMUNITY: &str = "community groups can't be added to Macro";
+ /// Disappearing messages are on.
+ pub const DISAPPEARING: &str = "groups with disappearing messages can't be added to Macro";
+ /// Direct chats are listed but not addable yet.
+ pub const DIRECT: &str = "direct chats can't be added to Macro yet";
+}
+
+/// One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.
+#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
+#[cfg_attr(feature = "schema", schema(as = LinkedChat))]
+pub struct Chat {
+ /// WhatsApp chat JID: a group, or the other person's phone-number JID
+ /// (LID when WhatsApp never told us the number).
+ pub jid: String,
+ /// Group or direct chat.
+ pub kind: ChatKind,
+ /// Group: the subject, or member names for an unnamed group. Direct: the
+ /// contact or WhatsApp name, else `+`. Always non-empty.
+ pub name: String,
+ /// Newest activity WhatsApp reported (message or history sync); `null`
+ /// when unknown. The list is sorted by it, newest first, unknown last.
+ pub last_activity_at: Option>,
+ /// Archived in WhatsApp.
+ pub archived: bool,
+ /// Pinned in WhatsApp.
+ pub pinned: bool,
+ /// The caller's own Macro group for this chat, once added.
+ pub group: Option,
+ /// Someone else's Macro group for this chat shared with the caller, when
+ /// the caller has not added their own.
+ pub shared: Option,
+ /// "Add to Macro" works now.
+ pub can_add: bool,
+ /// Why it can't be added, when it is neither added, shared nor addable.
+ pub cannot_add_reason: Option,
+}
+
+/// The caller's WhatsApp chat list.
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
+#[cfg_attr(feature = "schema", schema(as = LinkedChats))]
+pub struct ChatList {
+ /// Newest activity first; chats with unknown activity last, by name.
+ pub chats: Vec,
+}
+
+/// Where importing a group's earlier messages stands.
+#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
+#[serde(rename_all = "snake_case")]
+#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
+#[cfg_attr(feature = "schema", schema(as = LinkedBackfillState))]
+pub enum BackfillState {
+ /// Waiting to start: the owner's account has not seen a message in this
+ /// chat yet, or has not picked it up.
+ Pending,
+ /// Asking the owner's phone for earlier messages.
+ Running,
+ /// The owner's phone did not answer; retried when it is back.
+ WaitingForPhone,
+ /// Everything the phone had (within the limits) was imported.
+ Done,
+ /// Stopped at the limits ([`BACKFILL_MESSAGE_LIMIT`] messages or
+ /// [`BACKFILL_MAX_AGE_DAYS`] days); older messages stay in WhatsApp.
+ Partial,
+}
+
+impl BackfillState {
+ /// Stable storage spelling.
+ pub const fn as_str(self) -> &'static str {
+ match self {
+ Self::Pending => "pending",
+ Self::Running => "running",
+ Self::WaitingForPhone => "waiting_for_phone",
+ Self::Done => "done",
+ Self::Partial => "partial",
+ }
+ }
+
+ /// Parse the storage spelling.
+ pub fn parse(value: &str) -> Option {
+ Some(match value {
+ "pending" => Self::Pending,
+ "running" => Self::Running,
+ "waiting_for_phone" => Self::WaitingForPhone,
+ "done" => Self::Done,
+ "partial" => Self::Partial,
+ _ => return None,
+ })
+ }
+
+ /// Still importing (show "Importing history…").
+ pub const fn is_active(self) -> bool {
+ matches!(self, Self::Pending | Self::Running | Self::WaitingForPhone)
+ }
+}
+
+/// Earlier messages imported after adding a group.
+#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+#[cfg_attr(feature = "schema", derive(utoipa::ToSchema))]
+#[cfg_attr(feature = "schema", schema(as = LinkedBackfill))]
+pub struct Backfill {
+ /// Progress.
+ pub state: BackfillState,
+ /// Messages received from the phone so far (including ones already shown).
+ pub imported: u32,
+}
+
+/// Most earlier messages imported when a group is added.
+pub const BACKFILL_MESSAGE_LIMIT: u32 = 500;
+/// Earlier messages older than this many days before adding are not imported.
+pub const BACKFILL_MAX_AGE_DAYS: i64 = 90;
+
/// Deliberate operations on an existing linked-group message.
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
diff --git a/crates/whatsapp_linked/src/domain/ports.rs b/crates/whatsapp_linked/src/domain/ports.rs
index b4d2982e16c..e94026e3eb0 100644
--- a/crates/whatsapp_linked/src/domain/ports.rs
+++ b/crates/whatsapp_linked/src/domain/ports.rs
@@ -91,6 +91,26 @@ pub trait GroupRepository: Send + Sync {
) -> LinkedResult>;
/// Latest metadata for a binding's group from any account consenting to it.
async fn binding_roster(&self, binding: &Binding) -> LinkedResult>;
+
+ /// The account's stored chat list (without the roster), newest first.
+ async fn account_chats(&self, account: Uuid) -> LinkedResult>;
+}
+
+/// One stored row of an account's chat list.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct StoredChat {
+ /// Chat JID.
+ pub jid: String,
+ /// Group or direct.
+ pub kind: ChatKind,
+ /// Name WhatsApp reported, if any.
+ pub name: Option,
+ /// Newest activity.
+ pub last_activity_at: Option>,
+ /// Archived in WhatsApp.
+ pub archived: bool,
+ /// Pinned in WhatsApp.
+ pub pinned: bool,
}
/// A new binding, authorized by the domain.
@@ -336,6 +356,26 @@ pub trait SessionRepository: Send + Sync {
) -> LinkedResult<()>;
/// Groups this account currently observes for at least one adopted binding.
async fn observed_groups(&self, scope: SessionScope) -> LinkedResult>;
+
+ /// Upsert chat-list rows. Signals the owner's list when something changed.
+ async fn update_chats(&self, scope: SessionScope, chats: &[ChatUpdate]) -> LinkedResult<()>;
+
+ /// The account owner's groups still importing earlier messages.
+ async fn backfill_work(&self, scope: SessionScope) -> LinkedResult>;
+
+ /// A page was requested from the phone just now (`running`).
+ async fn backfill_requested(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()>;
+
+ /// The phone did not answer the last request (`waiting_for_phone`).
+ async fn backfill_unanswered(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()>;
+
+ /// Record a page the phone sent for a chat; returns the resulting state of
+ /// each of the owner's groups for that chat that was importing.
+ async fn backfill_page(
+ &self,
+ scope: SessionScope,
+ page: &HistoryPage,
+ ) -> LinkedResult>;
/// Persist one validated event into every binding it is observed for.
async fn ingest(
&self,
diff --git a/crates/whatsapp_linked/src/domain/service.rs b/crates/whatsapp_linked/src/domain/service.rs
index ad27e487f85..37595024fc3 100644
--- a/crates/whatsapp_linked/src/domain/service.rs
+++ b/crates/whatsapp_linked/src/domain/service.rs
@@ -165,27 +165,9 @@ impl LinkedService {
self.groups.request_groups_refresh(&[account.id]).await?;
let mut groups = self.groups.account_groups(account.id).await?;
let jids: Vec = groups.iter().map(|g| g.jid.clone()).collect();
- for adoption in self.groups.visible_adoptions(user, &jids).await? {
- let Some(group) = groups.iter_mut().find(|g| g.jid == adoption.group_jid) else {
- continue;
- };
- if adoption.owner_id == user {
- group.group = Some(GroupReference {
- id: adoption.id,
- name: adoption.name,
- });
- } else if group.shared.is_none() {
- group.shared = Some(SharedGroupReference {
- id: adoption.id,
- name: adoption.name,
- owner_id: adoption.owner_id,
- });
- }
- }
+ let adoptions = self.groups.visible_adoptions(user, &jids).await?;
for group in &mut groups {
- if group.group.is_some() {
- group.shared = None;
- }
+ (group.group, group.shared) = adoption_of(user, &adoptions, &group.jid);
group.name = group.display_name(&identity);
}
groups.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
@@ -193,6 +175,106 @@ impl LinkedService {
Ok(groups)
}
+ /// The person's WhatsApp chat list, as WhatsApp Web shows it: groups and
+ /// direct chats, newest activity first. Groups carry the same added /
+ /// shared / addable facts as [`Self::groups`]; direct chats are listed but
+ /// not addable yet. Returns stored data and requests a group refresh.
+ #[tracing::instrument(name = "whatsapp.linked.chats", skip_all, err, fields(count))]
+ pub async fn chats(&self, user: &str) -> LinkedResult {
+ if !self.features.adoption {
+ return Err(LinkedError::ConfigurationRequired.into());
+ }
+ let (account, identity) = self.connected(user).await?;
+ self.groups.request_groups_refresh(&[account.id]).await?;
+ let roster = self.groups.account_groups(account.id).await?;
+ let stored = self.groups.account_chats(account.id).await?;
+ let mut group_jids: Vec = roster.iter().map(|g| g.jid.clone()).collect();
+ group_jids.extend(
+ stored
+ .iter()
+ .filter(|chat| chat.kind == ChatKind::Group)
+ .map(|chat| chat.jid.clone()),
+ );
+ group_jids.sort();
+ group_jids.dedup();
+ let adoptions = self.groups.visible_adoptions(user, &group_jids).await?;
+ let mut chats: Vec = Vec::with_capacity(stored.len() + roster.len());
+ let mut listed = std::collections::HashMap::new();
+ for chat in stored {
+ listed.insert(chat.jid.clone(), chats.len());
+ let (group, shared) = adoption_of(user, &adoptions, &chat.jid);
+ let name = chat
+ .name
+ .clone()
+ .filter(|name| !name.trim().is_empty())
+ .unwrap_or_else(|| chat_fallback_name(&chat.jid, chat.kind, &identity));
+ let reason = match chat.kind {
+ ChatKind::Direct => cannot_add::DIRECT,
+ // Listed by WhatsApp but not in the account's groups any more.
+ ChatKind::Group => cannot_add::NOT_IN_GROUP,
+ };
+ chats.push(Chat {
+ name: if chat.jid == identity {
+ "You".to_owned()
+ } else {
+ name
+ },
+ jid: chat.jid,
+ kind: chat.kind,
+ last_activity_at: chat.last_activity_at,
+ archived: chat.archived,
+ pinned: chat.pinned,
+ can_add: false,
+ cannot_add_reason: (group.is_none() && shared.is_none()).then(|| reason.to_owned()),
+ group,
+ shared,
+ });
+ }
+ for info in roster {
+ let index = match listed.get(&info.jid) {
+ Some(index) => *index,
+ None => {
+ chats.push(Chat {
+ jid: info.jid.clone(),
+ kind: ChatKind::Group,
+ name: String::new(),
+ last_activity_at: None,
+ archived: false,
+ pinned: false,
+ group: None,
+ shared: None,
+ can_add: false,
+ cannot_add_reason: None,
+ });
+ chats.len() - 1
+ }
+ };
+ let chat = &mut chats[index];
+ chat.kind = ChatKind::Group;
+ chat.name = info.display_name(&identity);
+ (chat.group, chat.shared) = adoption_of(user, &adoptions, &info.jid);
+ let reason = if info.community {
+ Some(cannot_add::COMMUNITY)
+ } else if info.disappearing {
+ Some(cannot_add::DISAPPEARING)
+ } else if info.participant(&identity).is_none() {
+ Some(cannot_add::NOT_IN_GROUP)
+ } else {
+ None
+ };
+ let open = chat.group.is_none() && chat.shared.is_none();
+ chat.can_add = open && reason.is_none();
+ chat.cannot_add_reason = reason.filter(|_| open).map(str::to_owned);
+ }
+ chats.sort_by(|a, b| {
+ b.last_activity_at
+ .cmp(&a.last_activity_at)
+ .then_with(|| a.name.to_lowercase().cmp(&b.name.to_lowercase()))
+ });
+ tracing::Span::current().record("count", chats.len());
+ Ok(ChatList { chats })
+ }
+
/// Add an existing group the person has joined as their own Macro group;
/// never creates or joins a group in WhatsApp. Adding the same group twice
/// returns the existing one.
@@ -547,6 +629,45 @@ fn view_scope(
}
/// WhatsApp group JIDs: digits, optionally `creator-timestamp`, at `g.us`.
+/// The caller's own Macro group for a WhatsApp group, else someone else's
+/// group for it that was shared with them.
+fn adoption_of(
+ user: &str,
+ adoptions: &[VisibleAdoption],
+ jid: &str,
+) -> (Option, Option) {
+ let mine = adoptions
+ .iter()
+ .find(|adoption| adoption.group_jid == jid && adoption.owner_id == user)
+ .map(|adoption| GroupReference {
+ id: adoption.id,
+ name: adoption.name.clone(),
+ });
+ let shared = mine.is_none().then(|| {
+ adoptions
+ .iter()
+ .find(|adoption| adoption.group_jid == jid && adoption.owner_id != user)
+ .map(|adoption| SharedGroupReference {
+ id: adoption.id,
+ name: adoption.name.clone(),
+ owner_id: adoption.owner_id.clone(),
+ })
+ });
+ (mine, shared.flatten())
+}
+
+/// A chat WhatsApp gave no name: a direct chat by its phone number.
+fn chat_fallback_name(jid: &str, kind: ChatKind, identity: &str) -> String {
+ match kind {
+ ChatKind::Group => "WhatsApp group".to_owned(),
+ ChatKind::Direct if jid == identity => "You".to_owned(),
+ ChatKind::Direct => jid
+ .strip_suffix("@s.whatsapp.net")
+ .map(|phone| format!("+{phone}"))
+ .unwrap_or_else(|| "WhatsApp contact".to_owned()),
+ }
+}
+
pub(crate) fn is_group_jid(jid: &str) -> bool {
jid.len() <= 256
&& jid.strip_suffix("@g.us").is_some_and(|user| {
diff --git a/crates/whatsapp_linked/src/domain/session.rs b/crates/whatsapp_linked/src/domain/session.rs
index 89fd2a53014..06344462f38 100644
--- a/crates/whatsapp_linked/src/domain/session.rs
+++ b/crates/whatsapp_linked/src/domain/session.rs
@@ -226,6 +226,62 @@ impl SessionService {
self.repository.observed_groups(scope).await
}
+ /// Record what the account learned about chats in its WhatsApp chat list
+ /// (history sync, live messages, contact and chat-setting updates).
+ #[tracing::instrument(name = "whatsapp.session.update_chats", skip_all, err, fields(account_id = %scope.account_id, count = chats.len()))]
+ pub async fn update_chats(
+ &self,
+ scope: SessionScope,
+ chats: &[ChatUpdate],
+ ) -> LinkedResult<()> {
+ let valid: Vec = chats
+ .iter()
+ .filter(|chat| match chat.kind {
+ ChatKind::Group => is_group_jid(&chat.jid),
+ ChatKind::Direct => is_user_jid(&chat.jid) || is_lid_jid(&chat.jid),
+ })
+ .cloned()
+ .collect();
+ if valid.is_empty() {
+ return Ok(());
+ }
+ self.repository.update_chats(scope, &valid).await
+ }
+
+ /// The owner's groups still importing earlier messages from the phone.
+ #[tracing::instrument(name = "whatsapp.session.backfill_work", skip_all, err, fields(account_id = %scope.account_id, count))]
+ pub async fn backfill_work(&self, scope: SessionScope) -> LinkedResult> {
+ let work = self.repository.backfill_work(scope).await?;
+ tracing::Span::current().record("count", work.len());
+ Ok(work)
+ }
+
+ /// A page of earlier messages was requested from the phone just now.
+ #[tracing::instrument(name = "whatsapp.session.backfill_requested", skip_all, err, fields(account_id = %scope.account_id, group_id = %group))]
+ pub async fn backfill_requested(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()> {
+ self.repository.backfill_requested(scope, group).await
+ }
+
+ /// The phone did not answer; the import waits for it.
+ #[tracing::instrument(name = "whatsapp.session.backfill_unanswered", skip_all, err, fields(account_id = %scope.account_id, group_id = %group))]
+ pub async fn backfill_unanswered(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()> {
+ self.repository.backfill_unanswered(scope, group).await
+ }
+
+ /// The phone sent a page of a chat's earlier messages (the messages
+ /// themselves are ingested as history events).
+ #[tracing::instrument(name = "whatsapp.session.backfill_page", skip_all, err, fields(account_id = %scope.account_id, messages = page.messages, complete = page.complete))]
+ pub async fn backfill_page(
+ &self,
+ scope: SessionScope,
+ page: &HistoryPage,
+ ) -> LinkedResult> {
+ if !is_group_jid(&page.chat_jid) {
+ return Ok(vec![]);
+ }
+ self.repository.backfill_page(scope, page).await
+ }
+
/// Persist one event from an observed group. Safe to repeat: every observing
/// account converges on one group message per (binding, sender, source id).
#[tracing::instrument(
@@ -416,3 +472,10 @@ pub(crate) fn validate_event(event: &InboundEvent) -> LinkedResult<()> {
}
}
}
+
+fn is_lid_jid(jid: &str) -> bool {
+ jid.len() <= 256
+ && jid
+ .strip_suffix("@lid")
+ .is_some_and(|user| !user.is_empty() && user.bytes().all(|b| b.is_ascii_digit()))
+}
diff --git a/crates/whatsapp_linked/src/domain/session/test.rs b/crates/whatsapp_linked/src/domain/session/test.rs
index 3e8679e43bc..90c808f7d43 100644
--- a/crates/whatsapp_linked/src/domain/session/test.rs
+++ b/crates/whatsapp_linked/src/domain/session/test.rs
@@ -18,6 +18,7 @@ fn message(kind: MessageKind, sender: &str, target: Option<&str>) -> InboundEven
kind,
text: "hello".into(),
history: false,
+ from_me: false,
revision: 1,
target: target.map(|jid| Target {
source_id: "3EB0A0".into(),
diff --git a/crates/whatsapp_linked/src/domain/timeline.rs b/crates/whatsapp_linked/src/domain/timeline.rs
index dacc5094d88..0e020d7fafd 100644
--- a/crates/whatsapp_linked/src/domain/timeline.rs
+++ b/crates/whatsapp_linked/src/domain/timeline.rs
@@ -24,6 +24,9 @@ pub struct WhatsAppGroupSummary {
pub can_send: bool,
/// Reason sending is blocked.
pub send_reason: Option,
+ /// Importing earlier messages after the group was added; `null` for
+ /// groups added before this existed.
+ pub backfill: Option,
}
/// Full group detail and current viewer capabilities.
#[derive(Debug, Clone, Serialize)]
diff --git a/crates/whatsapp_linked/src/inbound/router.rs b/crates/whatsapp_linked/src/inbound/router.rs
index c27faa9438d..132dc450975 100644
--- a/crates/whatsapp_linked/src/inbound/router.rs
+++ b/crates/whatsapp_linked/src/inbound/router.rs
@@ -143,6 +143,7 @@ where
get(pairing::).delete(cancel::),
)
.route("/groups", get(groups::))
+ .route("/chats", get(chats::))
.route("/groups/adopt", post(adopt::))
.route("/whatsapp-groups", get(adopted_groups::))
.route(
@@ -376,6 +377,21 @@ pub async fn groups(
))
}
+/// The caller's WhatsApp chat list (groups and direct chats), newest
+/// activity first, with what can be added to Macro.
+#[utoipa::path(get, path = "/meta/linked/chats", operation_id = "linked_chats", responses((status = 200, body = ChatList)))]
+pub async fn chats(
+ State(state): State>,
+ auth: MacroAuthorizationExtractor,
+) -> Result, ApiError> {
+ Ok(Json(
+ state
+ .service
+ .chats(auth.authorization.macro_user_id.as_ref())
+ .await?,
+ ))
+}
+
/// Adopt one of the caller's groups into a standalone group entity.
#[utoipa::path(post, path = "/meta/linked/groups/adopt", operation_id = "linked_adopt", request_body = AdoptGroup, responses((status = 200, body = AdoptedGroup)))]
pub async fn adopt(
diff --git a/crates/whatsapp_linked/src/outbound/pg.rs b/crates/whatsapp_linked/src/outbound/pg.rs
index eea52d54e45..1494242b987 100644
--- a/crates/whatsapp_linked/src/outbound/pg.rs
+++ b/crates/whatsapp_linked/src/outbound/pg.rs
@@ -7,6 +7,7 @@ use uuid::Uuid;
mod accounts;
mod bindings;
+mod chats;
mod effects;
mod groups;
mod ingest;
diff --git a/crates/whatsapp_linked/src/outbound/pg/bindings.rs b/crates/whatsapp_linked/src/outbound/pg/bindings.rs
index de0a53d8b7d..5b4e8d4a2ee 100644
--- a/crates/whatsapp_linked/src/outbound/pg/bindings.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/bindings.rs
@@ -76,7 +76,7 @@ impl BindingRepository for PgLinkedRepository {
share_permission_db_utils::insert_private_permission(&mut *tx, &permission)
.await
.map_err(failure)?;
- let row = sqlx::query_as!(BindingRow,"INSERT INTO whatsapp_group (id, group_jid, name, user_id, state, share_permission_id) VALUES ($1,$2,$3,$4,'active',$5) RETURNING id, group_jid, user_id, state, adopted_at",id,group.jid,name,user,permission)
+ let row = sqlx::query_as!(BindingRow,"INSERT INTO whatsapp_group (id, group_jid, name, user_id, state, share_permission_id, backfill_state) VALUES ($1,$2,$3,$4,'active',$5,'pending') RETURNING id, group_jid, user_id, state, adopted_at",id,group.jid,name,user,permission)
.fetch_one(&mut *tx).await.map_err(failure)?;
let owner = Owner::from_principal_str(user).map_err(failure)?;
entity_registry_db_utils::insert_entity(
diff --git a/crates/whatsapp_linked/src/outbound/pg/chats.rs b/crates/whatsapp_linked/src/outbound/pg/chats.rs
new file mode 100644
index 00000000000..362e145b724
--- /dev/null
+++ b/crates/whatsapp_linked/src/outbound/pg/chats.rs
@@ -0,0 +1,266 @@
+//! The account's WhatsApp chat list and importing earlier messages of added
+//! groups from the owner's phone.
+
+use super::*;
+use crate::domain::events::{BackfillWork, ChatUpdate, HistoryPage, MessageAnchor};
+use crate::domain::ports::StoredChat;
+use chrono::{Duration, Utc};
+
+/// Upsert chat-list rows; signal the owner's list once if any row changed.
+pub(super) async fn update_chats_in(
+ tx: &mut Transaction<'_, Postgres>,
+ account: &Fenced,
+ chats: &[ChatUpdate],
+) -> LinkedResult<()> {
+ let mut changed = false;
+ for chat in chats {
+ let anchor = chat
+ .anchor
+ .as_ref()
+ .map(serde_json::to_value)
+ .transpose()
+ .map_err(failure)?;
+ let name = chat
+ .name
+ .as_deref()
+ .map(str::trim)
+ .filter(|name| !name.is_empty())
+ .map(|name| name.chars().take(256).collect::());
+ let rows = if chat.create {
+ sqlx::query!(
+ r#"INSERT INTO whatsapp_chat AS c (account_id, chat_jid, kind, name, last_activity_at, archived, pinned, anchor)
+ VALUES ($1, $2, $3, $4, $5, COALESCE($6, false), COALESCE($7, false), $8)
+ ON CONFLICT (account_id, chat_jid) DO UPDATE SET
+ name = COALESCE(excluded.name, c.name),
+ last_activity_at = GREATEST(c.last_activity_at, excluded.last_activity_at),
+ archived = COALESCE($6, c.archived),
+ pinned = COALESCE($7, c.pinned),
+ anchor = CASE WHEN excluded.anchor IS NOT NULL AND (c.anchor IS NULL
+ OR (excluded.anchor->>'at')::timestamptz >= (c.anchor->>'at')::timestamptz)
+ THEN excluded.anchor ELSE c.anchor END,
+ updated_at = now()
+ WHERE c.name IS DISTINCT FROM COALESCE(excluded.name, c.name)
+ OR c.last_activity_at IS DISTINCT FROM GREATEST(c.last_activity_at, excluded.last_activity_at)
+ OR c.archived IS DISTINCT FROM COALESCE($6, c.archived)
+ OR c.pinned IS DISTINCT FROM COALESCE($7, c.pinned)
+ OR (excluded.anchor IS NOT NULL AND c.anchor IS DISTINCT FROM excluded.anchor AND (c.anchor IS NULL
+ OR (excluded.anchor->>'at')::timestamptz >= (c.anchor->>'at')::timestamptz))"#,
+ account.id,
+ chat.jid,
+ chat.kind.as_str(),
+ name,
+ chat.last_activity_at,
+ chat.archived,
+ chat.pinned,
+ anchor
+ )
+ .execute(&mut **tx)
+ .await
+ } else {
+ sqlx::query!(
+ r#"UPDATE whatsapp_chat c SET
+ name = COALESCE($3, c.name),
+ last_activity_at = GREATEST(c.last_activity_at, $4),
+ archived = COALESCE($5, c.archived),
+ pinned = COALESCE($6, c.pinned),
+ updated_at = now()
+ WHERE c.account_id = $1 AND c.chat_jid = $2
+ AND (c.name IS DISTINCT FROM COALESCE($3, c.name)
+ OR c.last_activity_at IS DISTINCT FROM GREATEST(c.last_activity_at, $4)
+ OR c.archived IS DISTINCT FROM COALESCE($5, c.archived)
+ OR c.pinned IS DISTINCT FROM COALESCE($6, c.pinned))"#,
+ account.id,
+ chat.jid,
+ name,
+ chat.last_activity_at,
+ chat.archived,
+ chat.pinned
+ )
+ .execute(&mut **tx)
+ .await
+ }
+ .map_err(failure)?;
+ changed |= rows.rows_affected() > 0;
+ }
+ if changed {
+ notify_change(
+ tx,
+ signals::Change::Groups {
+ account_id: account.id,
+ },
+ )
+ .await?;
+ }
+ Ok(())
+}
+
+pub(super) async fn account_chats(pool: &PgPool, account: Uuid) -> LinkedResult> {
+ sqlx::query!(
+ r#"SELECT chat_jid, kind, name, last_activity_at, archived, pinned FROM whatsapp_chat
+ WHERE account_id = $1 ORDER BY last_activity_at DESC NULLS LAST, chat_jid LIMIT 5000"#,
+ account
+ )
+ .fetch_all(pool)
+ .await
+ .map_err(failure)?
+ .into_iter()
+ .map(|row| {
+ Ok(StoredChat {
+ kind: ChatKind::parse(&row.kind).ok_or(LinkedError::Unavailable)?,
+ jid: row.chat_jid,
+ name: row.name,
+ last_activity_at: row.last_activity_at,
+ archived: row.archived,
+ pinned: row.pinned,
+ })
+ })
+ .collect()
+}
+
+fn backfill_state(value: &str) -> LinkedResult {
+ BackfillState::parse(value).ok_or_else(|| LinkedError::Unavailable.into())
+}
+
+pub(super) async fn backfill_work_in(
+ tx: &mut Transaction<'_, Postgres>,
+ account: &Fenced,
+) -> LinkedResult> {
+ sqlx::query!(
+ r#"SELECT g.id, g.group_jid, g.backfill_state AS "state!", g.backfill_imported, g.backfill_cursor,
+ g.adopted_at, g.backfill_requested_at, c.anchor AS "anchor?"
+ FROM whatsapp_group g
+ LEFT JOIN whatsapp_chat c ON c.account_id = $1 AND c.chat_jid = g.group_jid
+ WHERE g.user_id = $2 AND g.state = 'active'
+ AND g.backfill_state IN ('pending', 'running', 'waiting_for_phone')
+ ORDER BY g.adopted_at, g.id LIMIT 20"#,
+ account.id,
+ account.user_id
+ )
+ .fetch_all(&mut **tx)
+ .await
+ .map_err(failure)?
+ .into_iter()
+ .map(|row| {
+ Ok(BackfillWork {
+ group_id: row.id,
+ group_jid: row.group_jid,
+ state: backfill_state(&row.state)?,
+ imported: row.backfill_imported.max(0) as u32,
+ cursor: row.backfill_cursor.map(decode).transpose()?,
+ anchor: row.anchor.map(decode).transpose()?,
+ adopted_at: row.adopted_at,
+ requested_at: row.backfill_requested_at,
+ })
+ })
+ .collect()
+}
+
+/// Move one of the owner's importing groups to `state`, stamping the request
+/// time when asked. Signals the group's viewers when the state changed.
+pub(super) async fn set_backfill_in(
+ tx: &mut Transaction<'_, Postgres>,
+ account: &Fenced,
+ group: Uuid,
+ state: BackfillState,
+ stamp_request: bool,
+) -> LinkedResult<()> {
+ let previous = sqlx::query_scalar!(
+ r#"UPDATE whatsapp_group g SET backfill_state = $3,
+ backfill_requested_at = CASE WHEN $4 THEN now() ELSE g.backfill_requested_at END
+ FROM (SELECT id, backfill_state FROM whatsapp_group WHERE id = $1 FOR UPDATE) old
+ WHERE g.id = old.id AND g.user_id = $2
+ AND g.backfill_state IN ('pending', 'running', 'waiting_for_phone')
+ RETURNING old.backfill_state AS "previous!""#,
+ group,
+ account.user_id,
+ state.as_str(),
+ stamp_request
+ )
+ .fetch_optional(&mut **tx)
+ .await
+ .map_err(failure)?;
+ if previous.is_some_and(|previous| previous != state.as_str()) {
+ notify_change(tx, signals::Change::Group { group_id: group }).await?;
+ }
+ Ok(())
+}
+
+/// What a page means for one group: the new cursor, count and state.
+fn after_page(
+ page: &HistoryPage,
+ imported: u32,
+ cursor: Option,
+ adopted_at: chrono::DateTime,
+) -> (u32, Option, BackfillState) {
+ let imported = imported.saturating_add(page.messages);
+ let moved = page.oldest.as_ref().is_some_and(|oldest| {
+ cursor
+ .as_ref()
+ .is_none_or(|cursor| oldest.id != cursor.id && oldest.at <= cursor.at)
+ });
+ let cursor = if moved { page.oldest.clone() } else { cursor };
+ let state = if page.complete || page.messages == 0 || !moved {
+ BackfillState::Done
+ } else if imported >= BACKFILL_MESSAGE_LIMIT
+ || cursor
+ .as_ref()
+ .is_some_and(|cursor| cursor.at < adopted_at - Duration::days(BACKFILL_MAX_AGE_DAYS))
+ {
+ BackfillState::Partial
+ } else {
+ BackfillState::Running
+ };
+ (imported, cursor, state)
+}
+
+pub(super) async fn backfill_page_in(
+ tx: &mut Transaction<'_, Postgres>,
+ account: &Fenced,
+ page: &HistoryPage,
+) -> LinkedResult> {
+ let rows = sqlx::query!(
+ r#"SELECT id, backfill_imported, backfill_cursor, adopted_at FROM whatsapp_group
+ WHERE user_id = $1 AND group_jid = $2 AND state = 'active'
+ AND backfill_state IN ('pending', 'running', 'waiting_for_phone')
+ ORDER BY id FOR UPDATE"#,
+ account.user_id,
+ page.chat_jid
+ )
+ .fetch_all(&mut **tx)
+ .await
+ .map_err(failure)?;
+ let mut states = Vec::with_capacity(rows.len());
+ for row in rows {
+ let cursor: Option = row.backfill_cursor.map(decode).transpose()?;
+ let (imported, cursor, state) = after_page(
+ page,
+ row.backfill_imported.max(0) as u32,
+ cursor,
+ row.adopted_at,
+ );
+ let cursor = cursor
+ .as_ref()
+ .map(serde_json::to_value)
+ .transpose()
+ .map_err(failure)?;
+ // A running group is ready for its next page: no request outstanding.
+ sqlx::query!(
+ r#"UPDATE whatsapp_group SET backfill_state = $2, backfill_imported = $3, backfill_cursor = $4,
+ backfill_requested_at = NULL
+ WHERE id = $1"#,
+ row.id,
+ state.as_str(),
+ i32::try_from(imported).unwrap_or(i32::MAX),
+ cursor
+ )
+ .execute(&mut **tx)
+ .await
+ .map_err(failure)?;
+ notify_change(tx, signals::Change::Group { group_id: row.id }).await?;
+ states.push((row.id, state));
+ }
+ Ok(states)
+}
+
+#[cfg(test)]
+mod test;
diff --git a/crates/whatsapp_linked/src/outbound/pg/chats/test.rs b/crates/whatsapp_linked/src/outbound/pg/chats/test.rs
new file mode 100644
index 00000000000..b899fdc2b56
--- /dev/null
+++ b/crates/whatsapp_linked/src/outbound/pg/chats/test.rs
@@ -0,0 +1,63 @@
+use super::*;
+use chrono::TimeZone;
+
+fn anchor(id: &str, minute: u32) -> MessageAnchor {
+ MessageAnchor {
+ id: id.to_owned(),
+ at: Utc.with_ymd_and_hms(2026, 10, 1, 12, minute, 0).unwrap(),
+ from_me: false,
+ sender_jid: None,
+ }
+}
+
+fn page(messages: u32, oldest: Option, complete: bool) -> HistoryPage {
+ HistoryPage {
+ chat_jid: "120363000000000001@g.us".to_owned(),
+ messages,
+ oldest,
+ complete,
+ }
+}
+
+#[test]
+fn pages_move_the_cursor_back_until_the_phone_has_nothing_older() {
+ let adopted = Utc.with_ymd_and_hms(2026, 10, 2, 0, 0, 0).unwrap();
+ let (imported, cursor, state) =
+ after_page(&page(50, Some(anchor("b", 30)), false), 0, None, adopted);
+ assert_eq!(
+ (imported, cursor.clone(), state),
+ (50, Some(anchor("b", 30)), BackfillState::Running)
+ );
+ let (_, _, state) = after_page(&page(3, Some(anchor("a", 10)), true), 50, cursor, adopted);
+ assert_eq!(state, BackfillState::Done);
+}
+
+#[test]
+fn the_message_limit_and_age_limit_stop_as_partial() {
+ let adopted = Utc.with_ymd_and_hms(2026, 10, 2, 0, 0, 0).unwrap();
+ let (_, _, state) = after_page(
+ &page(50, Some(anchor("b", 30)), false),
+ BACKFILL_MESSAGE_LIMIT - 10,
+ None,
+ adopted,
+ );
+ assert_eq!(state, BackfillState::Partial);
+ let long_ago = Utc.with_ymd_and_hms(2027, 3, 1, 0, 0, 0).unwrap();
+ let (_, _, state) = after_page(&page(50, Some(anchor("b", 30)), false), 0, None, long_ago);
+ assert_eq!(state, BackfillState::Partial);
+}
+
+#[test]
+fn a_page_that_does_not_go_further_back_ends_the_import() {
+ let adopted = Utc.with_ymd_and_hms(2026, 10, 2, 0, 0, 0).unwrap();
+ let (_, cursor, state) = after_page(
+ &page(5, Some(anchor("b", 30)), false),
+ 50,
+ Some(anchor("a", 10)),
+ adopted,
+ );
+ assert_eq!(
+ (cursor, state),
+ (Some(anchor("a", 10)), BackfillState::Done)
+ );
+}
diff --git a/crates/whatsapp_linked/src/outbound/pg/groups.rs b/crates/whatsapp_linked/src/outbound/pg/groups.rs
index fec8740a984..d8554342604 100644
--- a/crates/whatsapp_linked/src/outbound/pg/groups.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/groups.rs
@@ -1,7 +1,7 @@
//! Group metadata observed by accounts, and membership reconciliation.
use super::*;
-use crate::domain::ports::{GroupRepository, VisibleAdoption};
+use crate::domain::ports::{GroupRepository, StoredChat, VisibleAdoption};
use async_trait::async_trait;
use chrono::{DateTime, Utc};
@@ -370,4 +370,8 @@ impl GroupRepository for PgLinkedRepository {
.map(decode)
.transpose()
}
+
+ async fn account_chats(&self, account: Uuid) -> LinkedResult> {
+ super::chats::account_chats(&self.pool, account).await
+ }
}
diff --git a/crates/whatsapp_linked/src/outbound/pg/ingest.rs b/crates/whatsapp_linked/src/outbound/pg/ingest.rs
index 9c8279d9d08..30267ab92c5 100644
--- a/crates/whatsapp_linked/src/outbound/pg/ingest.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/ingest.rs
@@ -53,12 +53,15 @@ pub(super) enum Reserve {
/// is acceptable.
const CONSENT_SKEW_SECONDS: f64 = 10.0;
-/// Bindings whose consent covers this observation.
+/// Bindings whose consent covers this observation. Live messages count from
+/// adoption on; earlier messages the owner's phone sends as history go only to
+/// the owner's own groups, which asked for them by being added.
pub(super) async fn observed_bindings_in(
tx: &mut Transaction<'_, Postgres>,
account: &Fenced,
group: &str,
source_at: DateTime,
+ history: bool,
) -> LinkedResult> {
sqlx::query_as!(
bindings::BindingRow,
@@ -67,8 +70,9 @@ pub(super) async fn observed_bindings_in(
WHERE b.group_jid = $1 AND b.state = 'active'
AND m.account_id = $2 AND m.generation = $3 AND m.consent_ended_at IS NULL
AND m.remote_member AND m.reconciled
- AND $4 >= date_trunc('second', b.adopted_at) - make_interval(secs => $6)
- AND $4 >= date_trunc('second', m.consent_at) - make_interval(secs => $6)
+ AND CASE WHEN $7 THEN b.user_id = $5 ELSE
+ $4 >= date_trunc('second', b.adopted_at) - make_interval(secs => $6)
+ AND $4 >= date_trunc('second', m.consent_at) - make_interval(secs => $6) END
AND whatsapp_group_can_view(b.id, $5)
ORDER BY b.id LIMIT 100"#,
group,
@@ -76,7 +80,8 @@ pub(super) async fn observed_bindings_in(
account.generation,
source_at,
account.user_id,
- CONSENT_SKEW_SECONDS
+ CONSENT_SKEW_SECONDS,
+ history
)
.fetch_all(&mut **tx)
.await
@@ -462,6 +467,54 @@ pub(super) async fn finish_in(
Ok(())
}
+fn is_lid(jid: &str) -> bool {
+ jid.ends_with("@lid")
+}
+
+/// The sender with both halves of its phone-number/LID pair when the account
+/// knows them. A message with WhatsApp's from-me flag is the account's own,
+/// whatever address it carries. A LID-only sender takes its phone number from
+/// the account's roster of the group, which lists each participant's pair as
+/// WhatsApp reported it. Anything still LID-only is quarantined by
+/// `reserve_in`.
+async fn resolve_sender_in(
+ tx: &mut Transaction<'_, Postgres>,
+ account: &Fenced,
+ group: &str,
+ message: &Message,
+) -> LinkedResult {
+ let mut sender = message.sender.clone();
+ if message.from_me
+ && let Some(own) = &account.identity_jid
+ {
+ let lid = [Some(&sender.jid), sender.alternate_jid.as_ref()]
+ .into_iter()
+ .flatten()
+ .find(|jid| is_lid(jid))
+ .cloned();
+ sender.jid = own.clone();
+ sender.alternate_jid = lid;
+ return Ok(sender);
+ }
+ if !is_lid(&sender.jid) || sender.alternate_jid.is_some() {
+ return Ok(sender);
+ }
+ sender.alternate_jid = sqlx::query_scalar!(
+ r#"SELECT p->>'jid' AS "jid!" FROM whatsapp_group_roster r
+ CROSS JOIN LATERAL jsonb_array_elements(r.metadata->'participants') p
+ WHERE r.account_id = $1 AND r.group_jid = $2 AND p->>'alternateJid' = $3
+ AND p->>'jid' LIKE '%@s.whatsapp.net'
+ LIMIT 1"#,
+ account.id,
+ group,
+ sender.jid
+ )
+ .fetch_optional(&mut **tx)
+ .await
+ .map_err(failure)?;
+ Ok(sender)
+}
+
/// Retain an event for later ingestion or retry, bounded per account.
async fn retain_in(
tx: &mut Transaction<'_, Postgres>,
@@ -539,8 +592,18 @@ async fn apply_in(
})
}
InboundKind::Message(message) => {
- let bindings =
- observed_bindings_in(tx, account, &event.group_jid, event.source_at).await?;
+ let message = &Message {
+ sender: resolve_sender_in(tx, account, &event.group_jid, message).await?,
+ ..message.clone()
+ };
+ let bindings = observed_bindings_in(
+ tx,
+ account,
+ &event.group_jid,
+ event.source_at,
+ message.history,
+ )
+ .await?;
if bindings.is_empty() {
tracing::debug!(
account_id = %account.id,
diff --git a/crates/whatsapp_linked/src/outbound/pg/sends.rs b/crates/whatsapp_linked/src/outbound/pg/sends.rs
index 5fc5658f149..1390a5e9097 100644
--- a/crates/whatsapp_linked/src/outbound/pg/sends.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/sends.rs
@@ -690,6 +690,7 @@ impl PgLinkedRepository {
kind,
text,
history: false,
+ from_me: true,
revision: server_at.timestamp_millis(),
target,
media,
diff --git a/crates/whatsapp_linked/src/outbound/pg/session.rs b/crates/whatsapp_linked/src/outbound/pg/session.rs
index c05ffce1eaf..8fb9e72739f 100644
--- a/crates/whatsapp_linked/src/outbound/pg/session.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/session.rs
@@ -428,6 +428,60 @@ impl SessionRepository for PgLinkedRepository {
})
}
+ async fn update_chats(&self, scope: SessionScope, chats: &[ChatUpdate]) -> LinkedResult<()> {
+ let mut tx = self.pool.begin().await.map_err(failure)?;
+ let account = fence_in(&mut tx, scope).await?;
+ if account.state != AccountState::Connected {
+ return Ok(());
+ }
+ chats::update_chats_in(&mut tx, &account, chats).await?;
+ tx.commit().await.map_err(failure)
+ }
+
+ async fn backfill_work(&self, scope: SessionScope) -> LinkedResult> {
+ let mut tx = self.pool.begin().await.map_err(failure)?;
+ let account = fence_in(&mut tx, scope).await?;
+ if account.state != AccountState::Connected {
+ return Ok(vec![]);
+ }
+ let work = chats::backfill_work_in(&mut tx, &account).await?;
+ tx.commit().await.map_err(failure)?;
+ Ok(work)
+ }
+
+ async fn backfill_requested(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()> {
+ let mut tx = self.pool.begin().await.map_err(failure)?;
+ let account = fence_in(&mut tx, scope).await?;
+ chats::set_backfill_in(&mut tx, &account, group, BackfillState::Running, true).await?;
+ tx.commit().await.map_err(failure)
+ }
+
+ async fn backfill_unanswered(&self, scope: SessionScope, group: Uuid) -> LinkedResult<()> {
+ let mut tx = self.pool.begin().await.map_err(failure)?;
+ let account = fence_in(&mut tx, scope).await?;
+ chats::set_backfill_in(
+ &mut tx,
+ &account,
+ group,
+ BackfillState::WaitingForPhone,
+ false,
+ )
+ .await?;
+ tx.commit().await.map_err(failure)
+ }
+
+ async fn backfill_page(
+ &self,
+ scope: SessionScope,
+ page: &HistoryPage,
+ ) -> LinkedResult> {
+ let mut tx = self.pool.begin().await.map_err(failure)?;
+ let account = fence_in(&mut tx, scope).await?;
+ let states = chats::backfill_page_in(&mut tx, &account, page).await?;
+ tx.commit().await.map_err(failure)?;
+ Ok(states)
+ }
+
async fn ingest(
&self,
scope: SessionScope,
diff --git a/crates/whatsapp_linked/src/outbound/pg/test.rs b/crates/whatsapp_linked/src/outbound/pg/test.rs
index 48959bfca3e..4ce67727c9d 100644
--- a/crates/whatsapp_linked/src/outbound/pg/test.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/test.rs
@@ -171,6 +171,7 @@ fn text(event: u128, sender: &str, source: &str, body: &str) -> InboundEvent {
kind: MessageKind::Text,
text: body.into(),
history: false,
+ from_me: false,
revision: 0,
target: None,
media: vec![],
@@ -416,6 +417,89 @@ async fn an_unverified_lid_is_quarantined_instead_of_guessed(pool: PgPool) {
assert_eq!(state, "quarantined");
}
+/// The person and Macro user each alias of the binding resolves to.
+async fn aliases(pool: &PgPool, binding: Uuid) -> Vec<(String, Uuid, Option)> {
+ sqlx::query!(
+ "SELECT a.jid, a.person_id, p.user_id FROM whatsapp_identity_alias a JOIN whatsapp_external_person p ON p.id = a.person_id WHERE a.binding_id = $1 ORDER BY a.jid",
+ binding
+ )
+ .fetch_all(pool)
+ .await
+ .unwrap()
+ .into_iter()
+ .map(|row| (row.jid, row.person_id, row.user_id))
+ .collect()
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn a_message_from_me_is_the_account_owner_even_when_addressed_by_lid(pool: PgPool) {
+ let (_, session, _, binding, alice, _) = adopted(&pool).await;
+ let by_phone = text(1, ALICE_JID, "3EB0D001", "from my phone number");
+ session.ingest_event(alice, &by_phone).await.unwrap();
+ let mut by_lid = text(2, "53949570789492@lid", "3EB0D002", "Hi there");
+ let InboundKind::Message(message) = &mut by_lid.kind else {
+ unreachable!()
+ };
+ message.from_me = true;
+
+ assert_eq!(
+ session.ingest_event(alice, &by_lid).await.unwrap(),
+ IngestOutcome::Applied
+ );
+ let aliases = aliases(&pool, binding.id).await;
+ assert_eq!(
+ aliases
+ .iter()
+ .map(|(jid, _, user)| (jid.as_str(), user.as_deref()))
+ .collect::>(),
+ [
+ (ALICE_JID, Some(ALICE)),
+ ("53949570789492@lid", Some(ALICE))
+ ]
+ );
+ assert_eq!(aliases[0].1, aliases[1].1, "one person for both addresses");
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn a_quarantined_lid_sender_ingests_once_the_roster_pairs_it(pool: PgPool) {
+ let (_, session, _, binding, alice, _) = adopted(&pool).await;
+ const CUSTOMER_LID: &str = "987654321@lid";
+ session
+ .ingest_event(alice, &text(1, CUSTOMER_JID, "3EB0E001", "by phone"))
+ .await
+ .unwrap();
+ let by_lid = text(2, CUSTOMER_LID, "3EB0E002", "by lid");
+ assert_eq!(
+ session.ingest_event(alice, &by_lid).await.unwrap(),
+ IngestOutcome::Quarantined
+ );
+
+ let mut info = group(&[ALICE_JID, BOB_JID, CUSTOMER_JID]);
+ info.participants[2].identity.alternate_jid = Some(CUSTOMER_LID.to_owned());
+ session.update_groups(alice, &[info], true).await.unwrap();
+ sqlx::query!("UPDATE whatsapp_inbound_event SET retry_at = now()")
+ .execute(&pool)
+ .await
+ .unwrap();
+
+ assert_eq!(session.replay_deferred(alice).await.unwrap(), 1);
+ let aliases = aliases(&pool, binding.id).await;
+ assert_eq!(
+ aliases
+ .iter()
+ .map(|(jid, _, _)| jid.as_str())
+ .collect::>(),
+ [CUSTOMER_JID, CUSTOMER_LID]
+ );
+ assert_eq!(aliases[0].1, aliases[1].1, "one person for both addresses");
+ let remaining =
+ sqlx::query_scalar!(r#"SELECT count(*) AS "count!" FROM whatsapp_inbound_event"#)
+ .fetch_one(&pool)
+ .await
+ .unwrap();
+ assert_eq!(remaining, 0);
+}
+
#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
async fn a_reaction_before_its_message_is_deferred_and_replayed(pool: PgPool) {
let (_, session, repository, binding, alice, _) = adopted(&pool).await;
@@ -430,6 +514,7 @@ async fn a_reaction_before_its_message_is_deferred_and_replayed(pool: PgPool) {
kind: MessageKind::Reaction,
text: "👍".into(),
history: false,
+ from_me: false,
revision: 1,
target: Some(Target {
source_id: "3EB0ORIG".into(),
@@ -486,6 +571,7 @@ async fn edits_apply_in_source_order_and_deletes_are_permanent(pool: PgPool) {
kind: MessageKind::Edit,
text: body.into(),
history: false,
+ from_me: false,
revision,
target: Some(Target {
source_id: "3EB0EDIT".into(),
@@ -959,3 +1045,5 @@ async fn rate_limited_send_never_creates_a_dispatchable_intent(pool: PgPool) {
assert_eq!(error.current_context(), &LinkedError::RateLimited);
assert!(session.claim_sends(alice, 8).await.unwrap().is_empty());
}
+
+mod chats;
diff --git a/crates/whatsapp_linked/src/outbound/pg/test/chats.rs b/crates/whatsapp_linked/src/outbound/pg/test/chats.rs
new file mode 100644
index 00000000000..c04f6d6f411
--- /dev/null
+++ b/crates/whatsapp_linked/src/outbound/pg/test/chats.rs
@@ -0,0 +1,205 @@
+//! The chat list: history sync, live activity, names and settings; and the
+//! add/shared/can't-be-added facts of `chats`.
+
+use super::*;
+use chrono::TimeZone;
+
+const DIRECT: &str = "15558880001@s.whatsapp.net";
+const OTHER_GROUP: &str = "120363000000000002@g.us";
+
+fn at(minute: u32) -> chrono::DateTime {
+ Utc.with_ymd_and_hms(2026, 10, 1, 12, minute, 0).unwrap()
+}
+
+fn chat(jid: &str, kind: ChatKind, name: Option<&str>, minute: Option) -> ChatUpdate {
+ ChatUpdate {
+ jid: jid.to_owned(),
+ kind,
+ name: name.map(str::to_owned),
+ last_activity_at: minute.map(at),
+ archived: None,
+ pinned: None,
+ anchor: minute.map(|minute| MessageAnchor {
+ id: format!("3EB0{minute:04}"),
+ at: at(minute),
+ from_me: false,
+ sender_jid: None,
+ }),
+ create: true,
+ }
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn the_chat_list_merges_history_activity_and_the_roster(pool: PgPool) {
+ let (linked, session, _, binding, alice, _) = adopted(&pool).await;
+ session
+ .update_chats(
+ alice,
+ &[
+ chat(DIRECT, ChatKind::Direct, Some("Customer"), Some(30)),
+ chat(
+ GROUP,
+ ChatKind::Group,
+ Some("ignored: roster wins"),
+ Some(10),
+ ),
+ chat(OTHER_GROUP, ChatKind::Group, Some("Old group"), Some(20)),
+ ],
+ )
+ .await
+ .unwrap();
+ // Older activity never moves a chat back; a name-only update never adds one.
+ session
+ .update_chats(
+ alice,
+ &[
+ chat(DIRECT, ChatKind::Direct, None, Some(5)),
+ ChatUpdate {
+ archived: Some(true),
+ ..chat(OTHER_GROUP, ChatKind::Group, None, None)
+ },
+ ChatUpdate {
+ create: false,
+ ..chat(
+ "15559990000@s.whatsapp.net",
+ ChatKind::Direct,
+ Some("Stranger"),
+ None,
+ )
+ },
+ ],
+ )
+ .await
+ .unwrap();
+
+ let chats = linked.chats(ALICE).await.unwrap().chats;
+ let summary: Vec<_> = chats
+ .iter()
+ .map(|chat| {
+ (
+ chat.jid.as_str(),
+ chat.kind,
+ chat.name.as_str(),
+ chat.archived,
+ chat.can_add,
+ chat.cannot_add_reason.as_deref(),
+ chat.group.as_ref().map(|group| group.id),
+ )
+ })
+ .collect();
+ assert_eq!(
+ summary,
+ [
+ (
+ DIRECT,
+ ChatKind::Direct,
+ "Customer",
+ false,
+ false,
+ Some(cannot_add::DIRECT),
+ None
+ ),
+ (
+ OTHER_GROUP,
+ ChatKind::Group,
+ "Old group",
+ true,
+ false,
+ Some(cannot_add::NOT_IN_GROUP),
+ None
+ ),
+ (
+ GROUP,
+ ChatKind::Group,
+ "Customer escalations",
+ false,
+ false,
+ None,
+ Some(binding.id)
+ ),
+ ]
+ );
+ assert_eq!(chats[0].last_activity_at, Some(at(30)));
+ let anchor = sqlx::query_scalar!(
+ "SELECT anchor->>'id' FROM whatsapp_chat WHERE chat_jid = $1",
+ DIRECT
+ )
+ .fetch_one(&pool)
+ .await
+ .unwrap();
+ assert_eq!(
+ anchor.as_deref(),
+ Some("3EB00030"),
+ "the newest message stays the anchor"
+ );
+}
+
+#[sqlx::test(migrator = "MACRO_DB_MIGRATIONS")]
+async fn a_new_adoption_backfills_from_the_chat_anchor_page_by_page(pool: PgPool) {
+ let (_, session, _, binding, alice, _) = adopted(&pool).await;
+ let work = session.backfill_work(alice).await.unwrap();
+ assert_eq!(work.len(), 1);
+ assert_eq!(
+ (
+ work[0].state,
+ work[0].anchor.clone(),
+ work[0].cursor.clone()
+ ),
+ (BackfillState::Pending, None, None),
+ "no message seen yet: waits for one"
+ );
+ session
+ .update_chats(alice, &[chat(GROUP, ChatKind::Group, None, Some(40))])
+ .await
+ .unwrap();
+ let work = session.backfill_work(alice).await.unwrap();
+ assert_eq!(
+ work[0].anchor.as_ref().map(|anchor| anchor.id.as_str()),
+ Some("3EB00040")
+ );
+
+ session.backfill_requested(alice, binding.id).await.unwrap();
+ session
+ .backfill_unanswered(alice, binding.id)
+ .await
+ .unwrap();
+ let work = session.backfill_work(alice).await.unwrap();
+ assert_eq!(work[0].state, BackfillState::WaitingForPhone);
+
+ let page = |messages, oldest: u32, complete| HistoryPage {
+ chat_jid: GROUP.to_owned(),
+ messages,
+ oldest: Some(MessageAnchor {
+ id: format!("3EB0{oldest:04}"),
+ at: at(oldest),
+ from_me: false,
+ sender_jid: None,
+ }),
+ complete,
+ };
+ assert_eq!(
+ session
+ .backfill_page(alice, &page(50, 20, false))
+ .await
+ .unwrap(),
+ [(binding.id, BackfillState::Running)]
+ );
+ let work = session.backfill_work(alice).await.unwrap();
+ assert_eq!(
+ (
+ work[0].imported,
+ work[0].requested_at,
+ work[0].cursor.as_ref().map(|c| c.id.as_str())
+ ),
+ (50, None, Some("3EB00020")),
+ "ready for the next page, before the oldest imported"
+ );
+ assert_eq!(
+ session
+ .backfill_page(alice, &page(7, 1, true))
+ .await
+ .unwrap(),
+ [(binding.id, BackfillState::Done)]
+ );
+ assert!(session.backfill_work(alice).await.unwrap().is_empty());
+}
diff --git a/crates/whatsapp_linked/src/outbound/pg/timeline.rs b/crates/whatsapp_linked/src/outbound/pg/timeline.rs
index c43a7b0fe4b..74ed930e7c0 100644
--- a/crates/whatsapp_linked/src/outbound/pg/timeline.rs
+++ b/crates/whatsapp_linked/src/outbound/pg/timeline.rs
@@ -6,10 +6,17 @@ use models_permissions::share_permission::{
LinkShare, SharePermissionV2, UpdateSharePermissionRequestV2, access_level::AccessLevel,
};
+fn backfill(state: Option<&str>, imported: i32) -> Option {
+ Some(Backfill {
+ state: BackfillState::parse(state?)?,
+ imported: imported.max(0) as u32,
+ })
+}
+
#[async_trait]
impl TimelineRepository for PgLinkedRepository {
async fn visible_groups(&self, user: &str) -> LinkedResult> {
- let rows = sqlx::query!(r#"SELECT g.id,g.name,g.user_id,g.group_jid,g.state,g.adopted_at,
+ let rows = sqlx::query!(r#"SELECT g.id,g.name,g.user_id,g.group_jid,g.state,g.adopted_at,g.backfill_state,g.backfill_imported,
(SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id=g.id AND m.message_id IS NOT NULL
AND m.deleted_at IS NULL AND m.origin<>'history'
AND NOT EXISTS(SELECT 1 FROM whatsapp_external_person p WHERE p.id=m.person_id AND p.user_id=$1)
@@ -38,6 +45,7 @@ impl TimelineRepository for PgLinkedRepository {
last_message_at: row.last_message_at,
can_send: false,
send_reason: None,
+ backfill: backfill(row.backfill_state.as_deref(), row.backfill_imported),
},
binding: bindings::binding(bindings::BindingRow {
id: row.id,
@@ -52,7 +60,7 @@ impl TimelineRepository for PgLinkedRepository {
.collect()
}
async fn summary(&self, group: Uuid, user: &str) -> LinkedResult {
- let row = sqlx::query!(r#"SELECT g.id,g.name,g.user_id,
+ let row = sqlx::query!(r#"SELECT g.id,g.name,g.user_id,g.backfill_state,g.backfill_imported,
(SELECT count(*) FROM whatsapp_group_message m WHERE m.binding_id = g.id AND m.message_id IS NOT NULL
AND m.deleted_at IS NULL AND m.origin <> 'history'
AND NOT EXISTS (SELECT 1 FROM whatsapp_external_person p WHERE p.id = m.person_id AND p.user_id = $2)
@@ -68,6 +76,7 @@ impl TimelineRepository for PgLinkedRepository {
last_message_at: row.last_message_at,
can_send: false,
send_reason: None,
+ backfill: backfill(row.backfill_state.as_deref(), row.backfill_imported),
})
}
async fn messages(
diff --git a/docs/agent-guide/external.md b/docs/agent-guide/external.md
index 2a5b7bff654..e5b73b3f2d4 100644
--- a/docs/agent-guide/external.md
+++ b/docs/agent-guide/external.md
@@ -13,15 +13,16 @@ it on locally with `VITE_ENABLE_WHATSAPP_LINKED=true`.
the command menu.
- Mobile: **More views → External**. It never takes a dock slot and has no
back button, like other navigation views; the External sidebar is hidden on
- touch, so the WhatsApp page fills the pane with **In Macro** first. Opening a
+ touch, so the WhatsApp page fills the pane with its added **Groups** first. Opening a
group drills in full-screen; its **Back to WhatsApp** button returns.
## Sidebar
-Desktop's External sidebar has **WhatsApp** (the page below) and a collapsible
-**In Macro** section: every WhatsApp group the viewer can read (their own and
-shared ones), each with its unread count and a **Read-only** tag when the
-viewer's WhatsApp can't send there. The open group's row is highlighted.
+Desktop's External sidebar has **WhatsApp** (the page below) with every
+WhatsApp group the viewer can read (their own and shared ones) nested under it,
+each with its unread count and a **Read-only** tag when the viewer's WhatsApp
+can't send there. The caret on WhatsApp folds the groups; folded, WhatsApp shows
+their total unread count. The open group's row is highlighted.
DSS's `whatsapp_changed` gateway events refresh the lists; without one, External
re-fetches once ~3 s after opening.
@@ -32,7 +33,7 @@ re-fetches once ~3 s after opening.
| Not linked | Outlined WhatsApp row, the unofficial-client account-risk note, **Connect** (disabled with a tooltip when the server turns pairing off). A signed-out device reads **Reconnect**. |
| Passkey | When WhatsApp asks for a passkey, the dialog says **Confirm on your desktop**. In Macro desktop, **Confirm with passkey** runs the native `whatsapp_passkey_authenticate` command (its caBLE QR shows in the dialog) and posts the assertion to `pairing//passkey`; a returned code then shows to type on the phone. In a browser, **Continue in Macro desktop** opens `macro:///external?whatsappPairing=`, which reopens the same pairing there; closing the browser dialog then doesn't cancel it. |
| Pairing | Dialog **Link WhatsApp**: a locally encoded QR (`role="img"`, name "Scan this code with WhatsApp on your phone"), **Expires in m:ss**, four numbered steps, **Cancel**. The dialog carries `ph-no-capture`. A code confirmation step shows **The codes match**; expiry or failure shows **Show a new code**. |
-| Linked | Account row with the phone number, **Use a different account** (asks to confirm, then pairs with `replace: true`) and **Disconnect** (asks to confirm), then **Add to Macro**: the account's groups not yet in Macro, each with a one-click **Add to Macro** (no dialog, no name: the Macro group follows the WhatsApp name; unnamed groups show member names), and groups someone already shared with the viewer as **Shared with you by · Open**. Groups already in Macro are only in the sidebar. **Can't be added (n)** is collapsed and lists community and disappearing-message groups with the reason. A refused add shows DSS's specific reason under that group. |
+| Linked | A full-width list like Drive's. Its header has **Search chats** (filters every section by name or phone digits) and a slim account strip: the phone number, "Connected" and a **WhatsApp account options** menu with **Disconnect** (asks to confirm). One account at a time: to switch, disconnect and connect again. Below, the account's WhatsApp chat list (`GET chats`), newest activity first, one line per chat: a group or person icon, the name, "Group" / "Direct chat · Archived", and the last activity on the right. Row actions show on hover or keyboard focus (always on touch). While searching, **In Macro** lists matching added groups with **Open** (otherwise they are only in the sidebar). **Add to Macro**: addable groups with a one-click **Add to Macro** (no dialog, no name: the Macro group follows the WhatsApp name; unnamed groups show member names), and groups someone already shared with the viewer as "Shared with you by " with **Open**. **Can't be added (n)** is collapsed (searching unfolds it) and lists direct chats ("Can't add direct chats yet"), community and disappearing-message groups, and groups the account left, with DSS's reason. A refused add shows DSS's specific reason in that chat's row. An account paired before the chat list existed shows only groups and chats with new messages until it is re-linked. |
Cancel sends `DELETE /meta/linked/pairing/`; closing after the phone links
does not. Disconnect that WhatsApp did not confirm tells the person to remove
@@ -44,7 +45,7 @@ No environment has the WhatsApp session service yet, so intercept DSS
`/meta/linked/*` in the browser (Playwright `page.route`). The functional test
`apps/web/tests/functional/whatsapp-linked.spec.ts` is the reference mock: it
answers `configuration`, `account`, `connect`, `pairing/` (poll and
-`DELETE`), `groups` (`GET`), `groups/adopt` (`POST`, body `{group_jid}`), standalone `whatsapp-groups` routes and `disconnect`, and flips the pairing
+`DELETE`), `chats` (`GET`), `groups/adopt` (`POST`, body `{group_jid}`), standalone `whatsapp-groups` routes and `disconnect`, and flips the pairing
to `success` to simulate the phone scanning. Never link a real account from an
automated run.
@@ -65,11 +66,15 @@ The timeline pages newest-first from
`GET /meta/linked/whatsapp-groups//messages`, including verified sender names,
replies, grouped reactions, edit/delete flags, attachment states, and delivery
for the caller's own sends. Entering the view marks messages read through `/read`.
-Ready attachments open their imported document; other states show loading,
-unavailable or unsupported. The layout supports phone-width panes.
-
-The composer shows the caller's own sending phone or the reason replies are
-unavailable. Sending requires view access, the caller's own connected account,
+Ready images and videos show inline in Chat's media grid (click opens the
+viewer), voice notes and audio in an inline player; their bytes come from the
+imported document's presigned URL. Other ready files show as document chips;
+other states show loading, unavailable or unsupported. Senders show their
+WhatsApp name. The header has the group name, a **N members** button that
+toggles the WhatsApp roster, and **Share**. The layout supports phone-width panes.
+
+The composer placeholder names the caller's own sending phone ("Message Test 11
+as +1…"); otherwise the reason replies are unavailable shows in its place. Sending requires view access, the caller's own connected account,
and current membership that permits posting. A shared second member can send
from their number without owning or re-adopting the group. Text/media/replies,
reactions, and edits/deletes of the caller's own recent messages use
@@ -77,6 +82,16 @@ reactions, and edits/deletes of the caller's own recent messages use
The detail's `limits` supplies allowed MIME types, bytes and the edit window.
The owner may stop syncing with `DELETE` on the group; history remains readable.
+After adding, DSS imports earlier messages from the owner's phone (up to 500
+messages or 90 days). The detail's `backfill` drives the header's subtitle:
+**WhatsApp · Importing history…** while `pending`/`running`, **WhatsApp · Waiting
+for your phone to import history** (or *the owner's phone* for shared viewers)
+while `waiting_for_phone`; the same line shows above the oldest message. Imported
+messages appear older than what is shown as each page lands (pushed as
+`whatsapp_changed`), without moving the viewer's scroll position. `done` is
+silent; `partial` leaves **Earlier messages stay in WhatsApp** above the oldest
+message.
+
Pending and uncertain sends are read from `GET .../sends`. An `unknown` outcome
may already have arrived and must never be resent automatically. Requests are
limited to one per second per user across groups; HTTP 429 carries
diff --git a/docs/architecture/whatsapp-linked-devices.md b/docs/architecture/whatsapp-linked-devices.md
index b3e784cea2b..bf77cc47ff4 100644
--- a/docs/architecture/whatsapp-linked-devices.md
+++ b/docs/architecture/whatsapp-linked-devices.md
@@ -75,6 +75,29 @@ change. `GET /groups` marks each remote group with the caller's own Macro group
(`group`) or, when they have none, one shared with them by someone else
(`shared`, with its owner).
+`whatsapp_chat` is each account's chat list as WhatsApp Web shows it, groups
+and direct chats: name, last activity, archived and pinned, and the newest
+known message (the anchor). WhatsApp's history sync right after pairing fills
+it (initial, recent and full bundles; push-name bundles rename direct chats);
+live messages in any chat bump activity and add new chats; contact, push-name,
+archive and pin updates change existing rows. It never holds message content.
+`GET /chats` merges it with the roster (the roster names groups and decides
+what can be added; direct chats are listed but not addable yet), newest first.
+An account paired before the list existed only gets groups and chats with new
+messages: WhatsApp sends the full list once, at pairing.
+
+Adding a group sets `backfill_state = 'pending'`. The owner's account then
+imports the chat's earlier messages from the phone, on demand only: it asks for
+the anchor message itself when it predates adoption (a placeholder resend) and
+for pages of 50 messages before the oldest imported one (history sync on
+demand), until the phone has nothing older (`done`) or 500 messages / 90 days
+(`partial`). An unanswered request (60 s) means `waiting_for_phone`, retried
+every 5 minutes and at once on reconnect; a chat without an anchor waits for its
+first live message. Imported messages are ingested as history (origin
+`history`): no notifications, no unread, deduplicated with live messages by
+source id, and only into the owner's own groups, which replaces the
+adoption-time boundary for them.
+
Viewing uses ordinary entity sharing: direct people grants and access requests
at `/entities/whatsapp_group/{id}/...`, canonical explicit team grants, link
sharing, and channel grants: mentioning a group in a channel message shares it
@@ -102,7 +125,10 @@ The replica keeps only events for adopted groups, persists them before ACK and
calls `ingest_event`. Unadopted events never enter storage. Every observer converges
on `(group, verified person, source id)` in `whatsapp_group_message`; messages do
not reference native comms storage. Sender associations use verified phone/LID
-aliases; ambiguous identities are quarantined. Missing reaction/revision targets
+aliases: WhatsApp's from-me flag makes the sender the account's own identity,
+and the session service fills the other half of a sender's pair from the
+account's LID store (ingest also from the account's roster). Identities still
+ambiguous are quarantined and retried. Missing reaction/revision targets
are deferred. Edits follow source revision order; deletes are permanent tombstones.
Reactions and media live in `whatsapp_group_reaction` and `whatsapp_group_attachment`.
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/README.md b/packages/sdk-docs/reference/generated/storage/types.gen/README.md
index 6e28571a4df..af906151dbf 100644
--- a/packages/sdk-docs/reference/generated/storage/types.gen/README.md
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/README.md
@@ -1345,10 +1345,18 @@
- [LinkedAdoptResponses](type-aliases/LinkedAdoptResponses.md)
- [LinkedAttachment](type-aliases/LinkedAttachment.md)
- [LinkedAttachmentState](type-aliases/LinkedAttachmentState.md)
+- [LinkedBackfill](type-aliases/LinkedBackfill.md)
+- [LinkedBackfillState](type-aliases/LinkedBackfillState.md)
- [LinkedCancelPairingData](type-aliases/LinkedCancelPairingData.md)
- [LinkedCancelPairingResponse](type-aliases/LinkedCancelPairingResponse.md)
- [LinkedCancelPairingResponses](type-aliases/LinkedCancelPairingResponses.md)
- [LinkedCapabilities](type-aliases/LinkedCapabilities.md)
+- [LinkedChat](type-aliases/LinkedChat.md)
+- [LinkedChatKind](type-aliases/LinkedChatKind.md)
+- [LinkedChats](type-aliases/LinkedChats.md)
+- [LinkedChatsData](type-aliases/LinkedChatsData.md)
+- [LinkedChatsResponse](type-aliases/LinkedChatsResponse.md)
+- [LinkedChatsResponses](type-aliases/LinkedChatsResponses.md)
- [LinkedConfigurationData](type-aliases/LinkedConfigurationData.md)
- [LinkedConfigurationResponse](type-aliases/LinkedConfigurationResponse.md)
- [LinkedConfigurationResponses](type-aliases/LinkedConfigurationResponses.md)
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfill.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfill.md
new file mode 100644
index 00000000000..9844711cb9a
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfill.md
@@ -0,0 +1,12 @@
+# Type Alias: LinkedBackfill
+
+> **LinkedBackfill** = \{ `imported`: `number`; `state`: [`LinkedBackfillState`](LinkedBackfillState.md); \}
+
+Earlier messages imported after adding a group.
+
+## Properties
+
+| Property | Type | Description |
+| ------ | ------ | ------ |
+| `imported` | `number` | Messages received from the phone so far (including ones already shown). |
+| `state` | [`LinkedBackfillState`](LinkedBackfillState.md) | Progress. |
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfillState.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfillState.md
new file mode 100644
index 00000000000..69bdf6e6409
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedBackfillState.md
@@ -0,0 +1,5 @@
+# Type Alias: LinkedBackfillState
+
+> **LinkedBackfillState** = `"pending"` \| `"running"` \| `"waiting_for_phone"` \| `"done"` \| `"partial"`
+
+Where importing a group's earlier messages stands.
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChat.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChat.md
new file mode 100644
index 00000000000..11b66c7751d
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChat.md
@@ -0,0 +1,20 @@
+# Type Alias: LinkedChat
+
+> **LinkedChat** = \{ `archived`: `boolean`; `canAdd`: `boolean`; `cannotAddReason?`: `string` \| `null`; `group?`: `null` \| [`LinkedGroupReference`](LinkedGroupReference.md); `jid`: `string`; `kind`: [`LinkedChatKind`](LinkedChatKind.md); `lastActivityAt?`: `string` \| `null`; `name`: `string`; `pinned`: `boolean`; `shared?`: `null` \| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md); \}
+
+One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.
+
+## Properties
+
+| Property | Type | Description |
+| ------ | ------ | ------ |
+| `archived` | `boolean` | Archived in WhatsApp. |
+| `canAdd` | `boolean` | "Add to Macro" works now. |
+| `cannotAddReason?` | `string` \| `null` | Why it can't be added, when it is neither added, shared nor addable. |
+| `group?` | `null` \| [`LinkedGroupReference`](LinkedGroupReference.md) | - |
+| `jid` | `string` | WhatsApp chat JID: a group, or the other person's phone-number JID (LID when WhatsApp never told us the number). |
+| `kind` | [`LinkedChatKind`](LinkedChatKind.md) | Group or direct chat. |
+| `lastActivityAt?` | `string` \| `null` | Newest activity WhatsApp reported (message or history sync); `null` when unknown. The list is sorted by it, newest first, unknown last. |
+| `name` | `string` | Group: the subject, or member names for an unnamed group. Direct: the contact or WhatsApp name, else `+`. Always non-empty. |
+| `pinned` | `boolean` | Pinned in WhatsApp. |
+| `shared?` | `null` \| [`LinkedSharedGroupReference`](LinkedSharedGroupReference.md) | - |
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatKind.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatKind.md
new file mode 100644
index 00000000000..43c944413ad
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatKind.md
@@ -0,0 +1,5 @@
+# Type Alias: LinkedChatKind
+
+> **LinkedChatKind** = `"group"` \| `"direct"`
+
+Whether a WhatsApp chat is a group or a one-to-one chat.
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChats.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChats.md
new file mode 100644
index 00000000000..fba36002ad2
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChats.md
@@ -0,0 +1,11 @@
+# Type Alias: LinkedChats
+
+> **LinkedChats** = \{ `chats`: [`LinkedChat`](LinkedChat.md)[]; \}
+
+The caller's WhatsApp chat list.
+
+## Properties
+
+| Property | Type | Description |
+| ------ | ------ | ------ |
+| `chats` | [`LinkedChat`](LinkedChat.md)[] | Newest activity first; chats with unknown activity last, by name. |
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsData.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsData.md
new file mode 100644
index 00000000000..85ba67876fe
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsData.md
@@ -0,0 +1,12 @@
+# Type Alias: LinkedChatsData
+
+> **LinkedChatsData** = \{ `body?`: `never`; `path?`: `never`; `query?`: `never`; `url`: `"/meta/linked/chats"`; \}
+
+## Properties
+
+| Property | Type |
+| ------ | ------ |
+| `body?` | `never` |
+| `path?` | `never` |
+| `query?` | `never` |
+| `url` | `"/meta/linked/chats"` |
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponse.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponse.md
new file mode 100644
index 00000000000..2cee92a6749
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponse.md
@@ -0,0 +1,3 @@
+# Type Alias: LinkedChatsResponse
+
+> **LinkedChatsResponse** = [`LinkedChatsResponses`](LinkedChatsResponses.md)\[keyof [`LinkedChatsResponses`](LinkedChatsResponses.md)\]
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponses.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponses.md
new file mode 100644
index 00000000000..6d668c5d065
--- /dev/null
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/LinkedChatsResponses.md
@@ -0,0 +1,9 @@
+# Type Alias: LinkedChatsResponses
+
+> **LinkedChatsResponses** = \{ `200`: [`LinkedChats`](LinkedChats.md); \}
+
+## Properties
+
+| Property | Type |
+| ------ | ------ |
+| `200` | [`LinkedChats`](LinkedChats.md) |
diff --git a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/WhatsAppGroupSummary.md b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/WhatsAppGroupSummary.md
index 04862a02fb7..bef52a5dc52 100644
--- a/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/WhatsAppGroupSummary.md
+++ b/packages/sdk-docs/reference/generated/storage/types.gen/type-aliases/WhatsAppGroupSummary.md
@@ -1,6 +1,6 @@
# Type Alias: WhatsAppGroupSummary
-> **WhatsAppGroupSummary** = \{ `can_send`: `boolean`; `id`: `string`; `last_message_at?`: `string` \| `null`; `name`: `string`; `send_reason?`: `null` \| [`LinkedReplyBlock`](LinkedReplyBlock.md); `unread_count`: `number`; `user_id`: `string`; \}
+> **WhatsAppGroupSummary** = \{ `backfill?`: `null` \| [`LinkedBackfill`](LinkedBackfill.md); `can_send`: `boolean`; `id`: `string`; `last_message_at?`: `string` \| `null`; `name`: `string`; `send_reason?`: `null` \| [`LinkedReplyBlock`](LinkedReplyBlock.md); `unread_count`: `number`; `user_id`: `string`; \}
Adopted group visible through ordinary entity sharing.
@@ -8,6 +8,7 @@ Adopted group visible through ordinary entity sharing.
| Property | Type | Description |
| ------ | ------ | ------ |
+| `backfill?` | `null` \| [`LinkedBackfill`](LinkedBackfill.md) | - |
| `can_send` | `boolean` | Caller may currently send from their own account. |
| `id` | `string` | Entity identifier. |
| `last_message_at?` | `string` \| `null` | Latest message timestamp. |
diff --git a/packages/sdk-docs/reference/modules.md b/packages/sdk-docs/reference/modules.md
index c230850a9fb..c37bed2d657 100644
--- a/packages/sdk-docs/reference/modules.md
+++ b/packages/sdk-docs/reference/modules.md
@@ -122,10 +122,10 @@
- [src/entities/webhooks/namespace](src/entities/webhooks/namespace/README.md)
- [src/entities/webhooks/webhook](src/entities/webhooks/webhook/README.md)
- [src/entities/whatsapp/account](src/entities/whatsapp/account/README.md)
+- [src/entities/whatsapp/chat](src/entities/whatsapp/chat/README.md)
- [src/entities/whatsapp/group](src/entities/whatsapp/group/README.md)
- [src/entities/whatsapp/message](src/entities/whatsapp/message/README.md)
- [src/entities/whatsapp/namespace](src/entities/whatsapp/namespace/README.md)
-- [src/entities/whatsapp/remote-group](src/entities/whatsapp/remote-group/README.md)
- [src/entities/whatsapp/send](src/entities/whatsapp/send/README.md)
- [src/entities/whatsapp/upload](src/entities/whatsapp/upload/README.md)
- [src/entities/workspace/items](src/entities/workspace/items/README.md)
diff --git a/packages/sdk-docs/reference/src/entities/entity/classes/MacroEntity.md b/packages/sdk-docs/reference/src/entities/entity/classes/MacroEntity.md
index fc2025978ef..7fd6ae75d27 100644
--- a/packages/sdk-docs/reference/src/entities/entity/classes/MacroEntity.md
+++ b/packages/sdk-docs/reference/src/entities/entity/classes/MacroEntity.md
@@ -44,8 +44,8 @@ field and mutate.
- [`Team`](../../teams/team/classes/Team.md)
- [`Webhook`](../../webhooks/webhook/classes/Webhook.md)
- [`WhatsAppAccount`](../../whatsapp/account/classes/WhatsAppAccount.md)
+- [`WhatsAppChat`](../../whatsapp/chat/classes/WhatsAppChat.md)
- [`WhatsAppMessage`](../../whatsapp/message/classes/WhatsAppMessage.md)
-- [`WhatsAppRemoteGroup`](../../whatsapp/remote-group/classes/WhatsAppRemoteGroup.md)
- [`WhatsAppSend`](../../whatsapp/send/classes/WhatsAppSend.md)
## Type Parameters
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/chat/README.md b/packages/sdk-docs/reference/src/entities/whatsapp/chat/README.md
new file mode 100644
index 00000000000..1c3abbc4fee
--- /dev/null
+++ b/packages/sdk-docs/reference/src/entities/whatsapp/chat/README.md
@@ -0,0 +1,5 @@
+# src/entities/whatsapp/chat
+
+## Classes
+
+- [WhatsAppChat](classes/WhatsAppChat.md)
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/chat/classes/WhatsAppChat.md b/packages/sdk-docs/reference/src/entities/whatsapp/chat/classes/WhatsAppChat.md
new file mode 100644
index 00000000000..b096f967807
--- /dev/null
+++ b/packages/sdk-docs/reference/src/entities/whatsapp/chat/classes/WhatsAppChat.md
@@ -0,0 +1,105 @@
+# Class: WhatsAppChat
+
+One chat of the current user's WhatsApp chat list: a group or a direct chat.
+
+## Extends
+
+- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\<[`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md)\>
+
+## Properties
+
+| Property | Modifier | Type | Description | Inherited from |
+| ------ | ------ | ------ | ------ | ------ |
+| `archived` | `readonly` | () => `Promise`\<`boolean`\> | Archived in WhatsApp. | - |
+| `canAdd` | `readonly` | () => `Promise`\<`boolean`\> | Whether adding it to Macro works now. | - |
+| `cannotAddReason` | `readonly` | () => `Promise`\<`string` \| `undefined`\> | Why it can't be added, when it is neither added, shared nor addable. | - |
+| `group` | `readonly` | () => `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \| `undefined`\> | The current user's own Macro group for this chat, once added. | - |
+| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |
+| `kind` | `readonly` | () => `Promise`\<[`LinkedChatKind`](../../../../../generated/storage/types.gen/type-aliases/LinkedChatKind.md)\> | `group` or `direct`. | - |
+| `lastActivityAt` | `readonly` | () => `Promise`\<`string` \| `undefined`\> | Newest activity WhatsApp reported, when known. | - |
+| `name` | `readonly` | () => `Promise`\<`string`\> | Group subject (or member names), or the other person's name or number. | - |
+| `pinned` | `readonly` | () => `Promise`\<`boolean`\> | Pinned in WhatsApp. | - |
+| `shared` | `readonly` | () => `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \| `undefined`\> | Someone else's Macro group for this chat, shared with the current user. | - |
+
+## Methods
+
+### adopt()
+
+> **adopt**(): `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\>
+
+Add a group chat to Macro as the current user's own group; its earlier
+messages are imported from the phone. Adding it again returns the same
+group. Direct chats can't be added yet.
+
+#### Returns
+
+`Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\>
+
+***
+
+### refresh()
+
+> **refresh**(): `Promise`\<`WhatsAppChat`\>
+
+Reload the chat's list entry.
+
+#### Returns
+
+`Promise`\<`WhatsAppChat`\>
+
+***
+
+### toJSON()
+
+> **toJSON**(): \{ `detail?`: [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md); `id`: `string`; \}
+
+#### Returns
+
+\{ `detail?`: [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md); `id`: `string`; \}
+
+| Name | Type |
+| ------ | ------ |
+| `detail?` | [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md) |
+| `id` | `string` |
+
+#### Inherited from
+
+[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)
+
+***
+
+### byId()
+
+> `static` **byId**(`client`, `id`): `WhatsAppChat`
+
+Reference a chat by its WhatsApp JID.
+
+#### Parameters
+
+| Parameter | Type |
+| ------ | ------ |
+| `client` | `MacroClient` |
+| `id` | `string` |
+
+#### Returns
+
+`WhatsAppChat`
+
+***
+
+### from()
+
+> `static` **from**(`client`, `record`): `WhatsAppChat`
+
+Seed a chat handle from the chat list.
+
+#### Parameters
+
+| Parameter | Type |
+| ------ | ------ |
+| `client` | `MacroClient` |
+| `record` | [`LinkedChat`](../../../../../generated/storage/types.gen/type-aliases/LinkedChat.md) |
+
+#### Returns
+
+`WhatsAppChat`
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/group/classes/WhatsAppGroup.md b/packages/sdk-docs/reference/src/entities/whatsapp/group/classes/WhatsAppGroup.md
index f44644017fa..c552655c914 100644
--- a/packages/sdk-docs/reference/src/entities/whatsapp/group/classes/WhatsAppGroup.md
+++ b/packages/sdk-docs/reference/src/entities/whatsapp/group/classes/WhatsAppGroup.md
@@ -10,6 +10,7 @@ Independently shareable adopted WhatsApp group entity.
| Property | Modifier | Type | Description | Overrides | Inherited from |
| ------ | ------ | ------ | ------ | ------ | ------ |
+| `backfill` | `readonly` | () => `Promise`\<[`LinkedBackfill`](../../../../../generated/storage/types.gen/type-aliases/LinkedBackfill.md) \| `undefined`\> | Importing earlier messages from the owner's phone after adding, if any. | - | - |
| `canSend` | `readonly` | () => `Promise`\<`boolean`\> | Whether the caller can send from their own connected account. | - | - |
| `entityType` | `readonly` | `"whatsapp_group"` | Canonical sharing and favorites kind. | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`entityType`](../../../entity/classes/FavoritableEntity.md#property-entitytype) | - |
| `id` | `public readonly` | `string` | - | - | [`FavoritableEntity`](../../../entity/classes/FavoritableEntity.md).[`id`](../../../entity/classes/FavoritableEntity.md#property-id) |
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/namespace/classes/WhatsAppNamespace.md b/packages/sdk-docs/reference/src/entities/whatsapp/namespace/classes/WhatsAppNamespace.md
index 46d8b18e7f9..cc1ca0aadfd 100644
--- a/packages/sdk-docs/reference/src/entities/whatsapp/namespace/classes/WhatsAppNamespace.md
+++ b/packages/sdk-docs/reference/src/entities/whatsapp/namespace/classes/WhatsAppNamespace.md
@@ -52,24 +52,26 @@ Reference an adopted entity without fetching it.
***
-### groups()
+### chats()
-> **groups**(): `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\>
+> **chats**(): `Promise`\<[`WhatsAppChat`](../../chat/classes/WhatsAppChat.md)[]\>
-Adopted groups shared with the caller, including without WhatsApp.
+The caller's WhatsApp chat list (groups and direct chats), newest
+activity first: each chat says whether it is added, shared with the caller
+or addable, and `chat.adopt()` adds it.
#### Returns
-`Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\>
+`Promise`\<[`WhatsAppChat`](../../chat/classes/WhatsAppChat.md)[]\>
***
-### remoteGroups()
+### groups()
-> **remoteGroups**(): `Promise`\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\>
+> **groups**(): `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\>
-Groups discoverable through the caller's own connected account.
+Adopted groups shared with the caller, including without WhatsApp.
#### Returns
-`Promise`\<[`WhatsAppRemoteGroup`](../../remote-group/classes/WhatsAppRemoteGroup.md)[]\>
+`Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)[]\>
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/README.md b/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/README.md
deleted file mode 100644
index 5895e94b8b7..00000000000
--- a/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# src/entities/whatsapp/remote-group
-
-## Classes
-
-- [WhatsAppRemoteGroup](classes/WhatsAppRemoteGroup.md)
diff --git a/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/classes/WhatsAppRemoteGroup.md b/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/classes/WhatsAppRemoteGroup.md
deleted file mode 100644
index 42cabff2c53..00000000000
--- a/packages/sdk-docs/reference/src/entities/whatsapp/remote-group/classes/WhatsAppRemoteGroup.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Class: WhatsAppRemoteGroup
-
-An existing group joined by the current user's connected WhatsApp account.
-
-## Extends
-
-- [`MacroEntity`](../../../entity/classes/MacroEntity.md)\<[`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md)\>
-
-## Properties
-
-| Property | Modifier | Type | Description | Inherited from |
-| ------ | ------ | ------ | ------ | ------ |
-| `announce` | `readonly` | () => `Promise`\<`boolean`\> | Whether only remote administrators can post. | - |
-| `community` | `readonly` | () => `Promise`\<`boolean`\> | Whether this group is an unsupported community parent or announcement group. | - |
-| `disappearing` | `readonly` | () => `Promise`\<`boolean`\> | Whether disappearing messages prevent retention of group content. | - |
-| `group` | `readonly` | () => `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \| `undefined`\> | The current user's own Macro group for this remote group, once added. | - |
-| `id` | `public readonly` | `string` | - | [`MacroEntity`](../../../entity/classes/MacroEntity.md).[`id`](../../../entity/classes/MacroEntity.md#property-id) |
-| `name` | `readonly` | () => `Promise`\<`string`\> | The WhatsApp subject, or the other members' names for an unnamed group. | - |
-| `observedAt` | `readonly` | () => `Promise`\<`string`\> | When the session service last observed this metadata. | - |
-| `participants` | `readonly` | () => `Promise`\<[`LinkedParticipant`](../../../../../generated/storage/types.gen/type-aliases/LinkedParticipant.md)[]\> | Current remote roster; membership alone does not grant Macro history access. | - |
-| `shared` | `readonly` | () => `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md) \| `undefined`\> | Someone else's Macro group for this remote group, shared with the current user. | - |
-
-## Methods
-
-### adopt()
-
-> **adopt**(): `Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\>
-
-Add the group to Macro as the current user's own group, named after
-WhatsApp; adding it again returns the same group. Share it through the
-normal entity sharing endpoints.
-
-#### Returns
-
-`Promise`\<[`WhatsAppGroup`](../../group/classes/WhatsAppGroup.md)\>
-
-***
-
-### refresh()
-
-> **refresh**(): `Promise`\<`WhatsAppRemoteGroup`\>
-
-Reload the group's roster and adoption state.
-
-#### Returns
-
-`Promise`\<`WhatsAppRemoteGroup`\>
-
-***
-
-### toJSON()
-
-> **toJSON**(): \{ `detail?`: [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md); `id`: `string`; \}
-
-#### Returns
-
-\{ `detail?`: [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md); `id`: `string`; \}
-
-| Name | Type |
-| ------ | ------ |
-| `detail?` | [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) |
-| `id` | `string` |
-
-#### Inherited from
-
-[`MacroEntity`](../../../entity/classes/MacroEntity.md).[`toJSON`](../../../entity/classes/MacroEntity.md#tojson)
-
-***
-
-### byId()
-
-> `static` **byId**(`client`, `id`): `WhatsAppRemoteGroup`
-
-Reference a remote group by its verified JID.
-
-#### Parameters
-
-| Parameter | Type |
-| ------ | ------ |
-| `client` | `MacroClient` |
-| `id` | `string` |
-
-#### Returns
-
-`WhatsAppRemoteGroup`
-
-***
-
-### from()
-
-> `static` **from**(`client`, `record`): `WhatsAppRemoteGroup`
-
-Seed a group handle from the current account's roster.
-
-#### Parameters
-
-| Parameter | Type |
-| ------ | ------ |
-| `client` | `MacroClient` |
-| `record` | [`LinkedGroupInfo`](../../../../../generated/storage/types.gen/type-aliases/LinkedGroupInfo.md) |
-
-#### Returns
-
-`WhatsAppRemoteGroup`
diff --git a/packages/sdk-docs/reference/src/macro/README.md b/packages/sdk-docs/reference/src/macro/README.md
index 9387607ae53..f397e0ea925 100644
--- a/packages/sdk-docs/reference/src/macro/README.md
+++ b/packages/sdk-docs/reference/src/macro/README.md
@@ -622,21 +622,21 @@ Re-exports [WhatsAppAccount](../entities/whatsapp/account/classes/WhatsAppAccoun
***
-### WhatsAppGroup
+### WhatsAppChat
-Re-exports [WhatsAppGroup](../entities/whatsapp/group/classes/WhatsAppGroup.md)
+Re-exports [WhatsAppChat](../entities/whatsapp/chat/classes/WhatsAppChat.md)
***
-### WhatsAppMessage
+### WhatsAppGroup
-Re-exports [WhatsAppMessage](../entities/whatsapp/message/classes/WhatsAppMessage.md)
+Re-exports [WhatsAppGroup](../entities/whatsapp/group/classes/WhatsAppGroup.md)
***
-### WhatsAppRemoteGroup
+### WhatsAppMessage
-Re-exports [WhatsAppRemoteGroup](../entities/whatsapp/remote-group/classes/WhatsAppRemoteGroup.md)
+Re-exports [WhatsAppMessage](../entities/whatsapp/message/classes/WhatsAppMessage.md)
***
diff --git a/packages/sdk/AGENTS.md b/packages/sdk/AGENTS.md
index 5caad9a2d64..d23114e9983 100644
--- a/packages/sdk/AGENTS.md
+++ b/packages/sdk/AGENTS.md
@@ -20,7 +20,7 @@ enforced by the ordinary backend APIs.
- `src/entities/sharing/`, `messages/`: scoped access requests and message threads.
- `src/entities/databases/query.ts`: SQL statements, typed table/row references and version guards.
- `src/entities/crm/pipeline.ts`: pipeline-authorized table/row handles.
-- `src/entities/whatsapp/`: owner account, standalone group/message/send/upload handles, and remote discovery.
+- `src/entities/whatsapp/`: owner account, the chat list (`WhatsAppChat`), and added-chat group/message/send/upload/participant handles.
- `services.ts`, `openapi-ts.config.ts`: generated service contract inputs.
## Boundaries
@@ -99,7 +99,3 @@ the existing gateway prefixes.
- Workspace-import report/cancel endpoints remain app-only review plumbing,
explicitly classified alongside the existing Notion routes in coverage skips.
-
-WhatsApp handles address adopted `whatsapp_group` entities and their own messages;
-remote discovery uses `WhatsAppRemoteGroup`. Pairing/passkey/configuration remain
-excluded; personal sessions and owner API tokens can send, bots cannot.
diff --git a/packages/sdk/README.md b/packages/sdk/README.md
index 699f53bd79d..5db72c7efad 100644
--- a/packages/sdk/README.md
+++ b/packages/sdk/README.md
@@ -791,25 +791,35 @@ conflict, refresh and inspect the review; never automatically retry a send whose
outcome is unknown. These SDK methods have the same user authorization as the
ordinary API: review cards offer a user workflow, not a separate security grant.
-### WhatsApp linked groups
-
-Pair your personal account in Macro's External view first. Adopted groups are
-independent `WhatsAppGroup` entities with their own history and ordinary sharing.
-Shared viewers can read without WhatsApp. Sending and media uploads require your
-own connected member account, using your personal session or own API credential;
-bots never send. Adoption and detachment require a personal bearer session.
-Each user is limited to one send request per second across all groups.
+### WhatsApp chats
+
+Pair your personal account in Macro's External view first. Your WhatsApp chat
+list (`whatsapp.chats()`) holds groups and direct chats; adding one makes an
+independent `WhatsAppGroup` entity (a group or a direct chat) with its own
+history and ordinary sharing, and its earlier messages are imported from your
+phone. Shared viewers can read without WhatsApp. Sending and media uploads
+require your own connected account in the chat, using your personal session or
+own API credential; only the owner sends in a direct chat, and bots never send.
+Adding and detaching require a personal bearer session. Each user is limited to
+one send request per second across all chats.
```ts
const personal = new Macro({
auth: { type: 'user', token: () => session.accessToken() },
});
-const remoteGroups = await personal.whatsapp.remoteGroups();
-const group = remoteGroups[0] ? await remoteGroups[0].adopt({ name: 'Support' }) : undefined;
-if (group && await group.canSend()) {
- const send = await group.reply({ type: 'text', text: 'Hello' }, {
- idempotencyKey: crypto.randomUUID(),
- });
+const chats = await personal.whatsapp.chats();
+const addable = chats.find((chat) => chat.canAdd());
+const group = addable ? await addable.adopt() : undefined;
+if (group && (await group.canSend())) {
+ const [someone] = await group.participants();
+ const send = await group.reply(
+ {
+ type: 'text',
+ text: someone ? `Hello @${someone.mentionToken}` : 'Hello',
+ mentions: someone ? [someone] : [],
+ },
+ { idempotencyKey: crypto.randomUUID() },
+ );
await send.refresh();
console.log(await send.state());
}
@@ -820,4 +830,4 @@ for (const shared of await personal.whatsapp.groups()) {
Keep the same idempotency key when retrying the same request. A delivery state of
`unknown` must be reconciled; never automatically resend it. Uploads, quoted
-messages, mutations, and delivery references must belong to the same group.
+messages, mentions, mutations, and delivery references must belong to the same chat.
diff --git a/packages/sdk/generated/storage/index.ts b/packages/sdk/generated/storage/index.ts
index 329d0f5ba6d..d06a8aad049 100644
--- a/packages/sdk/generated/storage/index.ts
+++ b/packages/sdk/generated/storage/index.ts
@@ -1,4 +1,4 @@
// This file is auto-generated by @hey-api/openapi-ts
export { type Options, Sdk } from './sdk.gen';
-export type { AccessiblePipeline, AccessLevel, AccessRequest, AccessRequestsCancelData, AccessRequestsCancelErrors, AccessRequestsCancelResponses, AccessRequestsDirectData, AccessRequestsDirectErrors, AccessRequestsDirectResponse, AccessRequestsDirectResponses, AccessRequestsRemoveDirectData, AccessRequestsRemoveDirectErrors, AccessRequestsRemoveDirectResponses, AccessRequestsResolveData, AccessRequestsResolveErrors, AccessRequestsResolveResponse, AccessRequestsResolveResponses, AccessRequestsSetDirectData, AccessRequestsSetDirectErrors, AccessRequestsSetDirectResponses, AccessRequestsStateData, AccessRequestsStateErrors, AccessRequestsStateResponse, AccessRequestsStateResponses, AccessRequestsSubmitData, AccessRequestsSubmitErrors, AccessRequestsSubmitResponse, AccessRequestsSubmitResponses, AccessRequestState, ActiveCallsResponse, ActiveCallSummary, ActiveMeeting, ActiveMeetingsResponse, ActivityType, AddFavoriteData, AddFavoriteError, AddFavoriteErrors, AddFavoriteRequest, AddFavoriteResponse, AddFavoriteResponses, AddParticipantsData, AddParticipantsError, AddParticipantsErrors, AddParticipantsRequest, AddParticipantsResponses, AddPinHandlerData, AddPinHandlerError, AddPinHandlerErrors, AddPinHandlerResponse, AddPinHandlerResponses, AddPinRequest, AdoptedGroup, Agent, AgentActionId, AgentChannelScope, AgentDmProfile, AgentMcpServer, AgentMcpServers, AgentPullRequestState, AgentSessionFilters, AgentSessionLifecycleEvent, AgentSessionSource, AgentSessionVisibility, AgentTyping, AgentTypingPhase, Anchor, AnchorId, AnchorResponse, AnnotationIncrementalUpdate, Answer, ApiActivity, ApiAttachmentChannelReference, ApiAttachmentCommentReference, ApiAttachmentEntityReference, ApiAttachmentGenericReference, ApiChannelAttachment, ApiChannelAttachmentsPage, ApiChannelDetail, ApiChannelListMessage, ApiChannelListPage, ApiChannelListParticipant, ApiChannelListType, ApiChannelParticipant, ApiChannelWithLatest, ApiEntityFilterAst, ApiGroupByField, ApiGroupMeta, ApiParticipantListRole, ApiParticipantRole, ApiPropertyEntityType, AppliedOps, ApplyCrmPipelineOpsData, ApplyCrmPipelineOpsResponse, ApplyCrmPipelineOpsResponses, ApplyDatabaseOpsData, ApplyDatabaseOpsError, ApplyDatabaseOpsErrors, ApplyDatabaseOpsResponse, ApplyDatabaseOpsResponses, ApplyOpsRequest, ApplyOpsResponse, ApproveHarnessPairingData, ApproveHarnessPairingError, ApproveHarnessPairingErrors, ApproveHarnessPairingResponse, ApproveHarnessPairingResponses, ApprovePairingRequest, AttachmentChange, AttendeeResponseStatus, Audience, Awareness, AwarenessRelay, BasicDocument, BasicDocumentSubType, BomPart, BookingTarget, Bot, BotChannel, BotChannelType, BotId, BotKind, BotOwner, BotOwnerProfile, BotSenderProfile, BotToken, BranchNameResponse, BTreeMap, BulkWakeupRequest, BulkWakeupResponse, BulkWakeupSyncServiceDocumentsData, BulkWakeupSyncServiceDocumentsErrors, BulkWakeupSyncServiceDocumentsResponse, BulkWakeupSyncServiceDocumentsResponses, CalendarAttendee, CalendarEvent, CalendarEventFilters, CalendarEventSourceContent, CalendarJoinRequest, CalendarJoinRequestApiError, CalendarJoinRequestErrorCode, CalendarJoinRequestsResponse, CalendarJoinRequestStatus, CalendarMentionEvent, CalendarMentionPreviewItem, CalendarMentionPreviewKind, CalendarMentionPreviewRequest, CalendarMentionPreviewRequestItem, CalendarMentionPreviewResponse, CalendarMentionViewerCopy, CalendarOccurrence, CalendarOccurrenceItem, CalendarOccurrenceResponse, CalendarSyncStatus, CallActiveResponse, CallFilters, CallProvider, CallRecord, CallRecordGuest, CallRecordParticipant, CallRecordPreview, CallRecordPreviewData, CallRecordSource, CallRecordTranscriptSegment, CallStatus, CallTokenResponse, CallWebhookData, CallWebhookError, CallWebhookErrors, CallWebhookResponses, CancelSlackImportData, CancelSlackImportErrors, CancelSlackImportResponse, CancelSlackImportResponses, CardPosition, CastVerdict, CellValue, CellWrite, ChangedFileDto, ChangesetDto, ChangesetSourceDto, Channel, ChannelCreatedMetadata, ChannelDeletedMetadata, ChannelFilters, ChannelJoinCodeResponse, ChannelLabel, ChannelLabelRule, ChannelLabelsList, ChannelMessage, ChannelParticipant, ChannelParticipantAddedMetadata, ChannelParticipantRemovedMetadata, ChannelPictureChangedMetadata, ChannelPreview, ChannelPreviewData, ChannelSender, ChannelSharePermission, ChannelThreadFilters, ChannelTopicEvent, ChannelType, ChannelUpdatedMetadata, ChannelWebhookRequest, ChannelWebhookResponse, ChannelWithParticipants, Chat, ChatFilters, CheckActiveCallData, CheckActiveCallError, CheckActiveCallErrors, CheckActiveCallResponse, CheckActiveCallResponses, ClaimedPairing, ClaimHarnessPairingData, ClaimHarnessPairingError, ClaimHarnessPairingErrors, ClaimHarnessPairingResponse, ClaimHarnessPairingResponses, ClaimPairingRequest, ClientOptions, CloudStorageItemType, CollaborateFormData, CollaborateFormError, CollaborateFormErrors, CollaborateFormResponse, CollaborateFormResponses, CollabSurfaceResponse, CollabSurfaceTokenResponse, Column, ColumnCast, ColumnChange, ColumnChangeKind, ColumnConfig, ColumnConversion, ColumnConversionRequest, ColumnDetail, ColumnId, ColumnKind, ColumnProtection, ColumnResult, CommandFailure, CommandRejectedMetadata, CommittedChange, CompleteSlackImportUploadsData, CompleteSlackImportUploadsErrors, CompleteSlackImportUploadsResponse, CompleteSlackImportUploadsResponses, CompleteUploads, ConferenceProvider, Conjunction, ConversationId, ConversationKind, ConversationMetadata, ConversationProgress, ConversationSeal, ConversationStatus, ConvertDatabaseColumnData, ConvertDatabaseColumnError, ConvertDatabaseColumnErrors, ConvertDatabaseColumnResponse, ConvertDatabaseColumnResponses, ConvertedCell, CopyDocumentData, CopyDocumentError, CopyDocumentErrors, CopyDocumentQueryParams, CopyDocumentRequest, CopyDocumentResponse, CopyDocumentResponse2, CopyDocumentResponses, CountedReaction, CreateAgentData, CreateAgentError, CreateAgentErrors, CreateAgentRequest, CreateAgentResponse, CreateAgentResponses, CreateAnchorData, CreateAnchorError, CreateAnchorErrors, CreateAnchorResponse, CreateAnchorResponses, CreateBotRequest, CreateBulkDocumentResponse, CreateBulkDocumentResponseData, CreateCanvasDocumentRequest, CreateCanvasDocumentResponse, CreateCanvasHandlerData, CreateCanvasHandlerError, CreateCanvasHandlerErrors, CreateCanvasHandlerResponse, CreateCanvasHandlerResponses, CreateChannelData, CreateChannelError, CreateChannelErrors, CreateChannelLabelData, CreateChannelLabelError, CreateChannelLabelErrors, CreateChannelLabelRequest, CreateChannelLabelResponse, CreateChannelLabelResponses, CreateChannelRequest, CreateChannelResponse, CreateChannelResponse2, CreateChannelResponses, CreateChannelScopedBotData, CreateChannelScopedBotError, CreateChannelScopedBotErrors, CreateChannelScopedBotRequest, CreateChannelScopedBotResponse, CreateChannelScopedBotResponse2, CreateChannelScopedBotResponses, CreateCollabSurfaceTokenData, CreateCollabSurfaceTokenError, CreateCollabSurfaceTokenErrors, CreateCollabSurfaceTokenResponse, CreateCollabSurfaceTokenResponses, CreateCrmCompanyData, CreateCrmCompanyError, CreateCrmCompanyErrors, CreateCrmCompanyRequest, CreateCrmCompanyResponse, CreateCrmCompanyResponses, CreateCrmContactData, CreateCrmContactError, CreateCrmContactErrors, CreateCrmContactRequest, CreateCrmContactResponse, CreateCrmContactResponses, CreateCrmPipelineData, CreateCrmPipelineResponse, CreateCrmPipelineResponses, CreateDatabaseData, CreateDatabaseError, CreateDatabaseErrors, CreateDatabaseRequest, CreateDatabaseResponse, CreateDatabaseResponses, CreateDatabaseWebhookData, CreateDatabaseWebhookError, CreateDatabaseWebhookErrors, CreateDatabaseWebhookRequest, CreateDatabaseWebhookResponse, CreateDatabaseWebhookResponses, CreatedDatabaseWebhookResponse, CreateDocumentData, CreateDocumentError, CreateDocumentErrors, CreateDocumentRequest, CreateDocumentResponse, CreateDocumentResponseData, CreateDocumentResponses, CreatedPairing, CreatedUserApiKey, CreateEntityMentionData, CreateEntityMentionError, CreateEntityMentionErrors, CreateEntityMentionRequest, CreateEntityMentionResponse, CreateEntityMentionResponse2, CreateEntityMentionResponses, CreateForm, CreateFormData, CreateFormError, CreateFormErrors, CreateFormResponse, CreateFormResponses, CreateHarnessPairingData, CreateHarnessPairingError, CreateHarnessPairingErrors, CreateHarnessPairingResponse, CreateHarnessPairingResponses, CreateImport, CreateInitiativeData, CreateInitiativeError, CreateInitiativeErrors, CreateInitiativeRequest, CreateInitiativeResponse, CreateInitiativeResponses, CreateInstructionsDocumentResponse, CreateInstructionsHandlerData, CreateInstructionsHandlerError, CreateInstructionsHandlerErrors, CreateInstructionsHandlerResponse, CreateInstructionsHandlerResponses, CreateMarkdownDocumentRequest, CreateMarkdownDocumentResponse, CreateMarkdownHandlerData, CreateMarkdownHandlerError, CreateMarkdownHandlerErrors, CreateMarkdownHandlerResponse, CreateMarkdownHandlerResponses, CreateMeetingRequest, CreatePairingRequest, CreatePipeline, CreateProjectHandlerData, CreateProjectHandlerError, CreateProjectHandlerErrors, CreateProjectHandlerResponse, CreateProjectHandlerResponses, CreateProjectRequest, CreateProjectResponse, CreateSkillHandlerData, CreateSkillHandlerError, CreateSkillHandlerErrors, CreateSkillHandlerResponse, CreateSkillHandlerResponses, CreateSkillRequest, CreateSkillResponse, CreateSlackImportData, CreateSlackImportErrors, CreateSlackImportResponse, CreateSlackImportResponses, CreateSnippetHandlerData, CreateSnippetHandlerError, CreateSnippetHandlerErrors, CreateSnippetHandlerResponse, CreateSnippetHandlerResponses, CreateSnippetRequest, CreateSnippetResponse, CreateTaskHandlerData, CreateTaskHandlerError, CreateTaskHandlerErrors, CreateTaskHandlerResponse, CreateTaskHandlerResponses, CreateTaskRequest, CreateTaskResponse, CreateToken, CreateUnthreadedAnchorRequest, CreateUnthreadedAnchorResponse, CreateUnthreadedPdfAnchorRequest, CreateUserApiKeyData, CreateUserApiKeyError, CreateUserApiKeyErrors, CreateUserApiKeyRequest, CreateUserApiKeyResponse, CreateUserApiKeyResponses, CreateViewHandlerData, CreateViewHandlerError, CreateViewHandlerErrors, CreateViewHandlerResponse, CreateViewHandlerResponses, CreateViewRequest, CreateWebhookData, CreateWebhookError, CreateWebhookErrors, CreateWebhookRequest, CreateWebhookResponse, CreateWebhookResponse2, CreateWebhookResponses, CrmAssociation, CrmCompanyFilters, CrmCompanyResponse, CrmContactResponse, CrmDomainResponse, CrmPermissionRole, CrmStageInput, CrmStageResponse, CrmStagesResponse, CrmTeamSettingsResponse, CustomSpeakerAssignment, Database, DatabaseDetail, DatabaseId, DatabaseOp, DatabaseQueryRequest, DatabaseView, DatabaseWebhookDeliveryResponse, DatabaseWebhookPayloadProblem, DatabaseWebhookResponse, DataType, DateOperator, DeclineCallData, DeclineCallError, DeclineCallErrors, DeclineCallResponse, DeclineCallResponses, DeclineRingData, DeclineRingError, DeclineRingErrors, DeclineRingResponse, DeclineRingResponses, DeleteAnchorData, DeleteAnchorError, DeleteAnchorErrors, DeleteAnchorResponse, DeleteAnchorResponses, DeleteCallRecordData, DeleteCallRecordError, DeleteCallRecordErrors, DeleteCallRecordResponse, DeleteCallRecordResponses, DeleteChannelData, DeleteChannelError, DeleteChannelErrors, DeleteChannelLabelData, DeleteChannelLabelError, DeleteChannelLabelErrors, DeleteChannelLabelResponse, DeleteChannelLabelResponses, DeleteChannelResponse, DeleteChannelResponses, DeleteCollabSurfaceData, DeleteCollabSurfaceError, DeleteCollabSurfaceErrors, DeleteCollabSurfaceResponse, DeleteCollabSurfaceResponses, DeleteDatabaseWebhookData, DeleteDatabaseWebhookError, DeleteDatabaseWebhookErrors, DeleteDatabaseWebhookResponse, DeleteDatabaseWebhookResponses, DeleteDocumentData, DeleteDocumentError, DeleteDocumentErrors, DeleteDocumentResponse, DeleteDocumentResponses, DeleteEntityMentionData, DeleteEntityMentionError, DeleteEntityMentionErrors, DeleteEntityMentionResponse, DeleteEntityMentionResponse2, DeleteEntityMentionResponses, DeleteHarnessData, DeleteHarnessError, DeleteHarnessErrors, DeleteHarnessResponse, DeleteHarnessResponses, DeleteHistoryHandlerData, DeleteHistoryHandlerError, DeleteHistoryHandlerErrors, DeleteHistoryHandlerResponse, DeleteHistoryHandlerResponses, DeleteInitiativeData, DeleteInitiativeError, DeleteInitiativeErrors, DeleteInitiativeResponse, DeleteInitiativeResponses, DeleteProjectHandlerData, DeleteProjectHandlerError, DeleteProjectHandlerErrors, DeleteProjectHandlerResponse, DeleteProjectHandlerResponses, DeleteSelfHarnessData, DeleteSelfHarnessError, DeleteSelfHarnessErrors, DeleteSelfHarnessResponse, DeleteSelfHarnessResponses, DeleteUnthreadedAnchorRequest, DeleteUnthreadedAnchorResponse, DeleteUnthreadedPdfAnchorRequest, DeleteUserApiKeyData, DeleteUserApiKeyError, DeleteUserApiKeyErrors, DeleteUserApiKeyResponse, DeleteUserApiKeyResponses, DeleteUserDocumentViewLocationData, DeleteUserDocumentViewLocationError, DeleteUserDocumentViewLocationErrors, DeleteUserDocumentViewLocationResponse, DeleteUserDocumentViewLocationResponses, DeleteViewHandlerData, DeleteViewHandlerError, DeleteViewHandlerErrors, DeleteViewHandlerResponses, DeleteWebhookData, DeleteWebhookError, DeleteWebhookErrors, DeleteWebhookResponse, DeleteWebhookResponses, DeliverDatabaseWebhookData, DeliverDatabaseWebhookError, DeliverDatabaseWebhookErrors, DeliverDatabaseWebhookResponse, DeliverDatabaseWebhookResponses, DirectAccess, DocumentBasic, DocumentContent, DocumentContentLocation, DocumentContentState, DocumentContentUploadedMetadata, DocumentCopiedMetadata, DocumentCreatedMetadata, DocumentDeletedMetadata, DocumentFilters, DocumentId, DocumentInteractionMetadata, DocumentMetadata, DocumentMetadataWithContent, DocumentPermissionsToken, DocumentPermissionsTokenRequest, DocumentPermissionsTokenResponse, DocumentPreview, DocumentPreviewData, DocumentPreviewDataSubType, DocumentPurgedMetadata, DocumentResponse, DocumentResponseMetadata, DocumentResponseMetadataWithContent, DocumentStorageServiceApiVersion, DocumentSubType, DocumentSyncContentUpdatedMetadata, DocumentSyncEditor, DocumentTeamShareResponse, DocumentTextContent, DocumentTopicEvent, DocumentUpdatedMetadata, EditAnchorData, EditAnchorError, EditAnchorErrors, EditAnchorRequest, EditAnchorResponse, EditAnchorResponse2, EditAnchorResponses, EditCallRecordData, EditCallRecordError, EditCallRecordErrors, EditCallRecordRequest, EditCallRecordResponse, EditCallRecordResponses, EditCallTranscriptData, EditCallTranscriptError, EditCallTranscriptErrors, EditCallTranscriptRequest, EditCallTranscriptResponse, EditCallTranscriptResponses, EditDocumentData, EditDocumentError, EditDocumentErrors, EditDocumentResponse, EditDocumentResponse2, EditDocumentResponses, EditDocumentServiceArgs, EditMyFormResponseData, EditMyFormResponseError, EditMyFormResponseErrors, EditMyFormResponseResponse, EditMyFormResponseResponses, EditPdfAnchorRequest, EditPdfPlaceableCommentAnchorRequest, EditProjectV2Data, EditProjectV2Error, EditProjectV2Errors, EditProjectV2Response, EditProjectV2Responses, EditThreadV2Data, EditThreadV2Error, EditThreadV2Errors, EditThreadV2Response, EditThreadV2Responses, EmailFilters, EmailFollowup, EmailFollowupCommand, EmailFollowupResponse, EmailReminderCondition, EmailReminderPage, EmailReminderSummary, EmptyResponse, EnsureCollabSurfaceData, EnsureCollabSurfaceError, EnsureCollabSurfaceErrors, EnsureCollabSurfaceRequest, EnsureCollabSurfaceResponse, EnsureCollabSurfaceResponses, EnsureStarterHandlerData, EnsureStarterHandlerErrors, EnsureStarterHandlerResponse, EnsureStarterHandlerResponses, EntityFilters, EntityKind, EntityMessageCreateData, EntityMessageCreateResponse, EntityMessageCreateResponses, EntityMessageDeleteMessageData, EntityMessageDeleteMessageResponse, EntityMessageDeleteMessageResponses, EntityMessageDeleteThreadData, EntityMessageDeleteThreadResponse, EntityMessageDeleteThreadResponses, EntityMessageEditData, EntityMessageEditResponse, EntityMessageEditResponses, EntityMessageGetMessageData, EntityMessageGetMessageResponse, EntityMessageGetMessageResponses, EntityMessageGetThreadData, EntityMessageGetThreadResponse, EntityMessageGetThreadResponses, EntityMessageLegacyData, EntityMessageLegacyResponse, EntityMessageLegacyResponses, EntityMessagePatchThreadData, EntityMessagePatchThreadResponse, EntityMessagePatchThreadResponses, EntityMessageReactData, EntityMessageReactResponse, EntityMessageReactResponses, EntityMessageTypingData, EntityMessageTypingResponse, EntityMessageTypingResponses, EntityPermission, EntityPermissionResponse, EntityRef, EntityReference, EntityType, ErrorResponse, EventIcsData, EventIcsErrors, EventIcsResponse, EventIcsResponses, EventReminderOverride, EventReminders, EventStatus, EventTime, EventTransparency, EventType, EventVisibility, ExcludedDefaultView, ExcludeDefaultViewHandlerData, ExcludeDefaultViewHandlerError, ExcludeDefaultViewHandlerErrors, ExcludeDefaultViewHandlerResponses, ExcludeDefaultViewRequest, ExportDocumentData, ExportDocumentError, ExportDocumentErrors, ExportDocumentResponse, ExportDocumentResponse2, ExportDocumentResponses, Favorite, FavoriteEntityRef, FavoritesList, FileChangeKindDto, FileSystemNodeWithIds, FileType, FileTypeUpdate, FilterCondition, FilterGroup, FilterNode, FilterTest, FinalizeSlackImportData, FinalizeSlackImportErrors, FinalizeSlackImportResponse, FinalizeSlackImportResponses, FolderItem, FollowupState, ForeignEntity, ForeignEntityFilters, Form, FormAccess, FormCollaboration, FormDetail, FormErrorCode, FormErrorResponse, FormLayout, FormPublicationProblem, FormQuestionDetail, FormResponse, FormSection, FormSectionDetail, FormSource, FormStatus, FormTally, Formula, GenericErrorResponse, GenericResponse, GenericSuccessResponse, GetActiveCallsData, GetActiveCallsError, GetActiveCallsErrors, GetActiveCallsResponse, GetActiveCallsResponses, GetActivityData, GetActivityError, GetActivityErrors, GetActivityResponse, GetActivityResponses, GetAttachmentReferencesData, GetAttachmentReferencesError, GetAttachmentReferencesErrors, GetAttachmentReferencesResponse, GetAttachmentReferencesResponse2, GetAttachmentReferencesResponses, GetBatchCallRecordPreviewData, GetBatchCallRecordPreviewError, GetBatchCallRecordPreviewErrors, GetBatchCallRecordPreviewRequest, GetBatchCallRecordPreviewResponse, GetBatchCallRecordPreviewResponse2, GetBatchCallRecordPreviewResponses, GetBatchChannelPreviewData, GetBatchChannelPreviewError, GetBatchChannelPreviewErrors, GetBatchChannelPreviewRequest, GetBatchChannelPreviewResponse, GetBatchChannelPreviewResponse2, GetBatchChannelPreviewResponses, GetBatchPreviewHandlerData, GetBatchPreviewHandlerError, GetBatchPreviewHandlerErrors, GetBatchPreviewHandlerResponse, GetBatchPreviewHandlerResponses, GetBatchPreviewRequest, GetBatchPreviewResponse, GetBatchProjectPreviewData, GetBatchProjectPreviewError, GetBatchProjectPreviewErrors, GetBatchProjectPreviewRequest, GetBatchProjectPreviewResponse, GetBatchProjectPreviewResponse2, GetBatchProjectPreviewResponses, GetBotOwnerProfilesData, GetBotOwnerProfilesError, GetBotOwnerProfilesErrors, GetBotOwnerProfilesResponse, GetBotOwnerProfilesResponses, GetCallRecordData, GetCallRecordError, GetCallRecordErrors, GetCallRecordResponse, GetCallRecordResponses, GetChannelAttachmentsData, GetChannelAttachmentsError, GetChannelAttachmentsErrors, GetChannelAttachmentsResponse, GetChannelAttachmentsResponses, GetChannelData, GetChannelError, GetChannelErrors, GetChannelJoinLinkData, GetChannelJoinLinkError, GetChannelJoinLinkErrors, GetChannelJoinLinkResponse, GetChannelJoinLinkResponses, GetChannelParticipantsData, GetChannelParticipantsError, GetChannelParticipantsErrors, GetChannelParticipantsResponse, GetChannelParticipantsResponses, GetChannelResponse, GetChannelResponses, GetChannelsData, GetChannelsError, GetChannelsErrors, GetChannelsResponse, GetChannelsResponses, GetCollabSurfaceData, GetCollabSurfaceError, GetCollabSurfaceErrors, GetCollabSurfaceResponse, GetCollabSurfaceResponses, GetCompanyData, GetCompanyError, GetCompanyErrors, GetCompanyResponse, GetCompanyResponses, GetContactByEmailData, GetContactByEmailError, GetContactByEmailErrors, GetContactByEmailResponse, GetContactByEmailResponse2, GetContactByEmailResponses, GetContactData, GetContactError, GetContactErrors, GetContactResponse, GetContactResponses, GetCrmPipelineData, GetCrmPipelinePermissionsData, GetCrmPipelinePermissionsResponse, GetCrmPipelinePermissionsResponses, GetCrmPipelineResponse, GetCrmPipelineResponses, GetCrmPipelineRowsData, GetCrmPipelineRowsResponse, GetCrmPipelineRowsResponses, GetCrmPipelineTableData, GetCrmPipelineTableResponse, GetCrmPipelineTableResponses, GetCrmTeamSettingsData, GetCrmTeamSettingsError, GetCrmTeamSettingsErrors, GetCrmTeamSettingsResponse, GetCrmTeamSettingsResponses, GetDatabaseData, GetDatabaseError, GetDatabaseErrors, GetDatabasePermissionsData, GetDatabasePermissionsError, GetDatabasePermissionsErrors, GetDatabasePermissionsResponse, GetDatabasePermissionsResponses, GetDatabaseQueryData, GetDatabaseQueryError, GetDatabaseQueryErrors, GetDatabaseQueryResponse, GetDatabaseQueryResponses, GetDatabaseResponse, GetDatabaseResponses, GetDatabaseRowHistoryData, GetDatabaseRowHistoryError, GetDatabaseRowHistoryErrors, GetDatabaseRowHistoryResponse, GetDatabaseRowHistoryResponses, GetDatabaseTableChangesData, GetDatabaseTableChangesError, GetDatabaseTableChangesErrors, GetDatabaseTableChangesResponse, GetDatabaseTableChangesResponses, GetDatabaseViewPositionsData, GetDatabaseViewPositionsError, GetDatabaseViewPositionsErrors, GetDatabaseViewPositionsResponse, GetDatabaseViewPositionsResponses, GetDocumentAnchorsData, GetDocumentAnchorsError, GetDocumentAnchorsErrors, GetDocumentAnchorsResponse, GetDocumentAnchorsResponses, GetDocumentBranchNameData, GetDocumentBranchNameError, GetDocumentBranchNameErrors, GetDocumentBranchNameResponse, GetDocumentBranchNameResponses, GetDocumentByTeamSlugData, GetDocumentByTeamSlugError, GetDocumentByTeamSlugErrors, GetDocumentByTeamSlugResponse, GetDocumentByTeamSlugResponses, GetDocumentData, GetDocumentError, GetDocumentErrors, GetDocumentGithubPullRequestsData, GetDocumentGithubPullRequestsError, GetDocumentGithubPullRequestsErrors, GetDocumentGithubPullRequestsResponse, GetDocumentGithubPullRequestsResponses, GetDocumentKeyResponse, GetDocumentKeyResponseData, GetDocumentListHandlerData, GetDocumentListHandlerError, GetDocumentListHandlerErrors, GetDocumentListHandlerResponse, GetDocumentListHandlerResponses, GetDocumentListResult, GetDocumentLocationV3Data, GetDocumentLocationV3Error, GetDocumentLocationV3Errors, GetDocumentLocationV3Response, GetDocumentLocationV3Responses, GetDocumentPermissionsResponseDataV2, GetDocumentPermissionsTokenData, GetDocumentPermissionsTokenError, GetDocumentPermissionsTokenErrors, GetDocumentPermissionsTokenResponse, GetDocumentPermissionsTokenResponses, GetDocumentPermissionsV2Data, GetDocumentPermissionsV2Error, GetDocumentPermissionsV2Errors, GetDocumentPermissionsV2Response, GetDocumentPermissionsV2Responses, GetDocumentProcessingResult, GetDocumentProcessingResultData, GetDocumentProcessingResultError, GetDocumentProcessingResultErrors, GetDocumentProcessingResultResponse, GetDocumentProcessingResultResponse2, GetDocumentProcessingResultResponses, GetDocumentResponse, GetDocumentResponse2, GetDocumentResponseData, GetDocumentResponses, GetDocumentSearchResponse, GetDocumentShortIdData, GetDocumentShortIdError, GetDocumentShortIdErrors, GetDocumentShortIdResponse, GetDocumentShortIdResponses, GetDocumentsResponse, GetDocumentTeamShareData, GetDocumentTeamShareError, GetDocumentTeamShareErrors, GetDocumentTeamShareResponse, GetDocumentTeamShareResponses, GetDocumentTextContentData, GetDocumentTextContentErrors, GetDocumentTextContentResponse, GetDocumentTextContentResponses, GetDocumentUserAccessLevelResponse, GetDocumentVersionData, GetDocumentVersionError, GetDocumentVersionErrors, GetDocumentVersionResponse, GetDocumentVersionResponses, GetDocumentViewsHandlerData, GetDocumentViewsHandlerError, GetDocumentViewsHandlerErrors, GetDocumentViewsHandlerResponse, GetDocumentViewsHandlerResponses, GetEmailFollowupData, GetEmailFollowupError, GetEmailFollowupErrors, GetEmailFollowupResponse, GetEmailFollowupResponses, GetEntityPermissionData, GetEntityPermissionErrors, GetEntityPermissionResponse, GetEntityPermissionResponses, GetForeignEntityBySourceData, GetForeignEntityBySourceError, GetForeignEntityBySourceErrors, GetForeignEntityBySourceResponse, GetForeignEntityBySourceResponses, GetForeignEntityData, GetForeignEntityError, GetForeignEntityErrors, GetForeignEntityResponse, GetForeignEntityResponses, GetFormData, GetFormError, GetFormErrors, GetFormPermissionsData, GetFormPermissionsError, GetFormPermissionsErrors, GetFormPermissionsResponse, GetFormPermissionsResponses, GetFormResponse, GetFormResponses, GetFormResponseSummaryData, GetFormResponseSummaryError, GetFormResponseSummaryErrors, GetFormResponseSummaryResponse, GetFormResponseSummaryResponses, GetFormTallyData, GetFormTallyError, GetFormTallyErrors, GetFormTallyResponse, GetFormTallyResponses, GetGithubPullRequestChangesData, GetGithubPullRequestChangesError, GetGithubPullRequestChangesErrors, GetGithubPullRequestChangesPatchData, GetGithubPullRequestChangesPatchError, GetGithubPullRequestChangesPatchErrors, GetGithubPullRequestChangesPatchResponse, GetGithubPullRequestChangesPatchResponses, GetGithubPullRequestChangesResponse, GetGithubPullRequestChangesResponses, GetGithubPullRequestData, GetGithubPullRequestError, GetGithubPullRequestErrors, GetGithubPullRequestFacetsData, GetGithubPullRequestFacetsError, GetGithubPullRequestFacetsErrors, GetGithubPullRequestFacetsResponse, GetGithubPullRequestFacetsResponses, GetGithubPullRequestResponse, GetGithubPullRequestResponses, GetGithubPullRequestTasksData, GetGithubPullRequestTasksError, GetGithubPullRequestTasksErrors, GetGithubPullRequestTasksResponse, GetGithubPullRequestTasksResponses, GetHarnessPairingData, GetHarnessPairingError, GetHarnessPairingErrors, GetHarnessPairingResponse, GetHarnessPairingResponses, GetHistoryHandlerData, GetHistoryHandlerError, GetHistoryHandlerErrors, GetHistoryHandlerResponse, GetHistoryHandlerResponses, GetInitiativeData, GetInitiativeError, GetInitiativeErrors, GetInitiativeResponse, GetInitiativeResponses, GetInstructionsDocumentResponse, GetInstructionsHandlerData, GetInstructionsHandlerError, GetInstructionsHandlerErrors, GetInstructionsHandlerResponse, GetInstructionsHandlerResponses, GetItemsSoupData, GetItemsSoupError, GetItemsSoupErrors, GetItemsSoupResponse, GetItemsSoupResponses, GetLocationHandlerData, GetLocationHandlerError, GetLocationHandlerErrors, GetLocationHandlerResponse, GetLocationHandlerResponses, GetMyFormResponseData, GetMyFormResponseError, GetMyFormResponseErrors, GetMyFormResponseResponse, GetMyFormResponseResponses, GetOrCreateAction, GetOrCreateCallData, GetOrCreateCallError, GetOrCreateCallErrors, GetOrCreateCallResponse, GetOrCreateCallResponses, GetOrCreateChannelResponse, GetOrCreateDmData, GetOrCreateDmError, GetOrCreateDmErrors, GetOrCreateDmRequest, GetOrCreateDmResponse, GetOrCreateDmResponses, GetOrCreatePrivateData, GetOrCreatePrivateError, GetOrCreatePrivateErrors, GetOrCreatePrivateRequest, GetOrCreatePrivateResponse, GetOrCreatePrivateResponses, GetPendingProjectsHandlerData, GetPendingProjectsHandlerError, GetPendingProjectsHandlerErrors, GetPendingProjectsHandlerResponse, GetPendingProjectsHandlerResponses, GetPinsHandlerData, GetPinsHandlerError, GetPinsHandlerErrors, GetPinsHandlerResponse, GetPinsHandlerResponses, GetPinsResponse, GetProjectContentHandlerData, GetProjectContentHandlerError, GetProjectContentHandlerErrors, GetProjectContentHandlerResponse, GetProjectContentHandlerResponses, GetProjectContentResponse, GetProjectHandlerData, GetProjectHandlerError, GetProjectHandlerErrors, GetProjectHandlerResponse, GetProjectHandlerResponses, GetProjectPermissionsV2Data, GetProjectPermissionsV2Error, GetProjectPermissionsV2Errors, GetProjectPermissionsV2Response, GetProjectPermissionsV2Responses, GetProjectResponse, GetProjectResponseData, GetProjectsHandlerData, GetProjectsHandlerError, GetProjectsHandlerErrors, GetProjectsHandlerResponse, GetProjectsHandlerResponses, GetProjectsResponse, GetProjectUserAccessLevelData, GetProjectUserAccessLevelError, GetProjectUserAccessLevelErrors, GetProjectUserAccessLevelResponse, GetProjectUserAccessLevelResponses, GetRingStatusData, GetRingStatusError, GetRingStatusErrors, GetRingStatusResponse, GetRingStatusResponses, GetSelfBotData, GetSelfBotError, GetSelfBotErrors, GetSelfBotResponse, GetSelfBotResponses, GetSelfHarnessData, GetSelfHarnessError, GetSelfHarnessErrors, GetSelfHarnessResponse, GetSelfHarnessResponses, GetSlackImportData, GetSlackImportErrors, GetSlackImportResponse, GetSlackImportResponses, GetSystemSkillsHandlerData, GetSystemSkillsHandlerError, GetSystemSkillsHandlerErrors, GetSystemSkillsHandlerResponse, GetSystemSkillsHandlerResponses, GetUserDocumentsHandlerData, GetUserDocumentsHandlerError, GetUserDocumentsHandlerErrors, GetUserDocumentsHandlerResponse, GetUserDocumentsHandlerResponses, GetUserDocumentViewLocationData, GetUserDocumentViewLocationError, GetUserDocumentViewLocationErrors, GetUserDocumentViewLocationResponse, GetUserDocumentViewLocationResponses, GetUserHistoryResponse, GetViewsHandlerData, GetViewsHandlerError, GetViewsHandlerErrors, GetViewsHandlerResponse, GetViewsHandlerResponses, GetWebhookData, GetWebhookError, GetWebhookErrors, GetWebhookResponse, GetWebhookResponses, GithubLabelFacet, GithubPullRequest, GithubPullRequestChangesPatchResponse, GithubPullRequestChangesResponse, GithubPullRequestCheckRun, GithubPullRequestComment, GithubPullRequestFacets, GithubPullRequestLabel, GithubPullRequestReview, GithubPullRequestReviewDecision, GithubPullRequestReviewState, GithubPullRequestsResponse, GithubPullRequestTasks, GithubPullRequestTasksRequest, GithubPullRequestTasksResponse, GithubPullRequestUser, GithubRepositoryFacet, GithubUserFacet, GitRefDto, GroupedInitialParams, GroupedPageParams, GroupedSoupGroupPage, GroupedSoupInitialPage, GroupedSoupPage, GroupedSoupSort, GuestCallChatPostData, GuestCallChatPostErrors, GuestCallChatPostResponse, GuestCallChatPostResponses, GuestCallChatReadData, GuestCallChatReadErrors, GuestCallChatReadResponse, GuestCallChatReadResponses, GuestChatMessage, GuestChatPage, GuestChatPost, GuestId, GuestJoinRequest, GuestPolicy, HandlerData, HandlerError, HandlerErrors, HandlerResponse, HandlerResponses, Harness, HarnessAgent, HarnessId, HarnessOwner, HarnessSession, HashMap, HealthHandlerData, HealthHandlerResponse, HealthHandlerResponses, HighlightType, ImportCounters, ImportDatabaseTableData, ImportDatabaseTableError, ImportDatabaseTableErrors, ImportDatabaseTableResponse, ImportDatabaseTableResponses, ImportedAuthor, ImportError, ImportLimits, ImportPage, ImportProgress, ImportTable, ImportWarning, InferColumnTypeOutcome, InferColumnTypeRequest, InferDatabaseColumnTypeData, InferDatabaseColumnTypeError, InferDatabaseColumnTypeErrors, InferDatabaseColumnTypeResponse, InferDatabaseColumnTypeResponses, InFlightTurnSummary, IngestTranscriptData, IngestTranscriptError, IngestTranscriptErrors, IngestTranscriptResponses, InitializeUserDocumentsData, InitializeUserDocumentsError, InitializeUserDocumentsErrors, InitializeUserDocumentsResponse, InitializeUserDocumentsResponses, InitialPropertyValue, InitiativeDetail, InitiativeFilters, InitiativeId, InitiativeList, InitiativeSummary, InputReceivedMetadata, InstallSyncData, InstallSyncErrors, InteractionReason, InvalidDatabaseWebhookPayloadResponse, InviteMeetingRequest, InviteMeetingUsersRequest, Item, ItemWithUserAccessLevel, JobId, JobProcessingResultHandlerData, JobProcessingResultHandlerError, JobProcessingResultHandlerErrors, JobProcessingResultHandlerResponse, JobProcessingResultHandlerResponses, JobStatus, JoinChannelByCodeData, JoinChannelByCodeError, JoinChannelByCodeErrors, JoinChannelByCodeResponses, JoinChannelData, JoinChannelError, JoinChannelErrors, JoinChannelResponses, KeySegment, Lane, LaneKey, LatestMessage, LayoutProblem, LeaveCallResponse, LeaveChannelData, LeaveChannelError, LeaveChannelErrors, LeaveChannelResponses, LeaveOrEndCallData, LeaveOrEndCallError, LeaveOrEndCallErrors, LeaveOrEndCallResponse, LeaveOrEndCallResponses, LinkedAccount, LinkedAccountData, LinkedAccountResponse, LinkedAccountResponses, LinkedAccountState, LinkedAccountView, LinkedAdoptData, LinkedAdoptGroup, LinkedAdoptResponse, LinkedAdoptResponses, LinkedAttachment, LinkedAttachmentState, LinkedCancelPairingData, LinkedCancelPairingResponse, LinkedCancelPairingResponses, LinkedCapabilities, LinkedConfigurationData, LinkedConfigurationResponse, LinkedConfigurationResponses, LinkedConnect, LinkedConnectData, LinkedConnectResponse, LinkedConnectResponses, LinkedDeliveryData, LinkedDeliveryResponse, LinkedDeliveryResponses, LinkedDeliveryState, LinkedDetachData, LinkedDetachResponse, LinkedDetachResponses, LinkedDisconnect, LinkedDisconnectData, LinkedDisconnectRequest, LinkedDisconnectResponse, LinkedDisconnectResponses, LinkedFeatures, LinkedGroupInfo, LinkedGroupReference, LinkedGroupsData, LinkedGroupsResponse, LinkedGroupsResponses, LinkedIdentity, LinkedMediaKind, LinkedMessageAttachments, LinkedMessageAttachmentsData, LinkedMessageAttachmentsResponse, LinkedMessageAttachmentsResponses, LinkedMutation, LinkedPairing, LinkedPairingData, LinkedPairingResponse, LinkedPairingResponses, LinkedPairingState, LinkedPairState, LinkedParticipant, LinkedPasskeyData, LinkedPasskeyResponse, LinkedPasskeyResponses, LinkedReplyBlock, LinkedReplyContent, LinkedReplyData, LinkedReplyErrors, LinkedReplyResponse, LinkedReplyResponses, LinkedSendProgress, LinkedSendReply, LinkedSharedGroupReference, LinkedUploadData, LinkedUploadedAttachment, LinkedUploadRequest, LinkedUploadResponse, LinkedUploadResponses, LinkShare, ListAccessibleFormsData, ListAccessibleFormsError, ListAccessibleFormsErrors, ListAccessibleFormsResponse, ListAccessibleFormsResponses, ListAgentsData, ListAgentsError, ListAgentsErrors, ListAgentsResponse, ListAgentsResponses, ListBotChannelsData, ListBotChannelsError, ListBotChannelsErrors, ListBotChannelsResponse, ListBotChannelsResponses, ListChannelLabelsData, ListChannelLabelsError, ListChannelLabelsErrors, ListChannelLabelsResponse, ListChannelLabelsResponses, ListCompanyContactsData, ListCompanyContactsError, ListCompanyContactsErrors, ListCompanyContactsResponse, ListCompanyContactsResponses, ListCrmPipelinesData, ListCrmPipelinesResponse, ListCrmPipelinesResponses, ListDatabaseColumnCastsData, ListDatabaseColumnCastsError, ListDatabaseColumnCastsErrors, ListDatabaseColumnCastsResponse, ListDatabaseColumnCastsResponses, ListDatabasesData, ListDatabasesError, ListDatabasesErrors, ListDatabasesResponse, ListDatabasesResponses, ListDatabaseWebhooksData, ListDatabaseWebhooksError, ListDatabaseWebhooksErrors, ListDatabaseWebhooksResponse, ListDatabaseWebhooksResponse2, ListDatabaseWebhooksResponses, ListedDatabase, ListedForm, ListEmailRemindersData, ListEmailRemindersError, ListEmailRemindersErrors, ListEmailRemindersResponse, ListEmailRemindersResponses, ListFavoritesData, ListFavoritesError, ListFavoritesErrors, ListFavoritesResponse, ListFavoritesResponses, ListFormsData, ListFormsError, ListFormsErrors, ListFormsResponse, ListFormsResponses, ListHarnessAgentsData, ListHarnessAgentsError, ListHarnessAgentsErrors, ListHarnessAgentsResponse, ListHarnessAgentsResponses, ListHarnessesData, ListHarnessesError, ListHarnessesErrors, ListHarnessesResponse, ListHarnessesResponses, ListHarnessSessionsData, ListHarnessSessionsError, ListHarnessSessionsErrors, ListHarnessSessionsResponse, ListHarnessSessionsResponses, ListInitiativesData, ListInitiativesError, ListInitiativesErrors, ListInitiativesResponse, ListInitiativesResponses, ListJoinRequestsData, ListJoinRequestsError, ListJoinRequestsErrors, ListJoinRequestsResponse, ListJoinRequestsResponses, ListOccurrencesData, ListOccurrencesErrors, ListOccurrencesResponse, ListOccurrencesResponses, ListSlackImportsData, ListSlackImportsResponse, ListSlackImportsResponses, ListTeamCalendarData, ListTeamCalendarResponse, ListTeamCalendarResponses, ListTeamOutOfOfficeData, ListTeamOutOfOfficeErrors, ListTeamOutOfOfficeResponse, ListTeamOutOfOfficeResponses, ListUserApiKeysData, ListUserApiKeysError, ListUserApiKeysErrors, ListUserApiKeysResponse, ListUserApiKeysResponses, ListWebhooksData, ListWebhooksError, ListWebhooksErrors, ListWebhooksResponse, ListWebhooksResponse2, ListWebhooksResponses, LocationResponseData, LocationResponseV3, MacroUserIdStr, MarkRead, Meeting, MeetingCancelData, MeetingCancelError, MeetingCancelErrors, MeetingCancelPreparationData, MeetingCancelPreparationError, MeetingCancelPreparationErrors, MeetingCancelPreparationResponse, MeetingCancelPreparationResponses, MeetingCancelResponse, MeetingCancelResponses, MeetingCreateData, MeetingCreateError, MeetingCreateErrors, MeetingCreateResponse, MeetingCreateResponses, MeetingGuestJoinData, MeetingGuestJoinError, MeetingGuestJoinErrors, MeetingGuestJoinResponse, MeetingGuestJoinResponses, MeetingGuestParticipantsData, MeetingGuestParticipantsError, MeetingGuestParticipantsErrors, MeetingGuestParticipantsResponse, MeetingGuestParticipantsResponses, MeetingInviteData, MeetingInviteError, MeetingInviteErrors, MeetingInvitePermissions, MeetingInvitePermissionsData, MeetingInvitePermissionsError, MeetingInvitePermissionsErrors, MeetingInvitePermissionsResponse, MeetingInvitePermissionsResponses, MeetingInviteResponse, MeetingInviteResponses, MeetingInviteUsersData, MeetingInviteUsersError, MeetingInviteUsersErrors, MeetingInviteUsersResponse, MeetingInviteUsersResponses, MeetingJoinData, MeetingJoinError, MeetingJoinErrors, MeetingJoinResponse, MeetingJoinResponses, MeetingLeaveData, MeetingLeaveError, MeetingLeaveErrors, MeetingLeaveResponse, MeetingLeaveResponses, MeetingListActiveData, MeetingListActiveError, MeetingListActiveErrors, MeetingListActiveResponse, MeetingListActiveResponses, MeetingListData, MeetingListError, MeetingListErrors, MeetingListResponse, MeetingListResponses, MeetingLookupData, MeetingLookupError, MeetingLookupErrors, MeetingLookupResponse, MeetingLookupResponses, MeetingParticipant, MeetingParticipants, MeetingParticipantsData, MeetingParticipantsError, MeetingParticipantsErrors, MeetingParticipantsResponse, MeetingParticipantsResponses, MeetingPreparation, MeetingPrepareData, MeetingPrepareError, MeetingPrepareErrors, MeetingPrepareResponse, MeetingPrepareResponses, MeetingShareData, MeetingShareError, MeetingShareErrors, MeetingShareResponse, MeetingShareResponses, MeetingsResponse, MeetingToken, MeetingUpdateData, MeetingUpdateError, MeetingUpdateErrors, MeetingUpdateResponse, MeetingUpdateResponses, MentionPreviewsData, MentionPreviewsErrors, MentionPreviewsResponse, MentionPreviewsResponses, Message, MessageAttachment, MessageAttachmentCreatedMetadata, MessageAttachmentRemovedMetadata, MessageChange, MessageCursor, MessageDeletedMetadata, MessageDirection, MessageEvent, MessageEventAttachment, MessageListItem, MessageMentionedMetadata, MessagePage, MessageParent, MessagePatch, MessagePatchedMetadata, MessagePostedMetadata, MessageThread, MessageThreadPreview, MessageTimelineData, MessageTimelineEntriesData, MessageTimelineEntriesResponse, MessageTimelineEntriesResponses, MessageTimelineEntry, MessageTimelinePage, MessageTimelineQuery, MessageTimelineResponse, MessageTimelineResponses, MessageTopicEvent, MyResponse, NewAttachment, NewColumn, NewOption, NewThreadAnchor, NewView, NotificationFilters, NotificationState, NumberOperator, OpBatch, Operator, OpRefusalResponse, OpResult, OptionId, OptionRef, PairingDetails, Params, ParticipantRole, PatchBotRequest, PatchChannelData, PatchChannelError, PatchChannelErrors, PatchChannelRequest, PatchChannelResponse, PatchChannelResponses, PatchMessageNotificationPolicy, PatchProjectRequestV2, PatchThreadRequestV2, PatchViewHandlerData, PatchViewHandlerError, PatchViewHandlerErrors, PatchViewHandlerResponses, PatchWebhookData, PatchWebhookError, PatchWebhookErrors, PatchWebhookRequest, PatchWebhookResponse, PatchWebhookResponses, PdfAnchor, PdfAnchorId, PdfHighlightAnchor, PdfHighlightAnchorRequest, PdfHighlightRect, PdfHighlightRectAnchorRequest, PdfPlaceableCommentAnchor, PendingClaimResponse, PermanentlyDeleteDocumentData, PermanentlyDeleteDocumentError, PermanentlyDeleteDocumentErrors, PermanentlyDeleteDocumentResponse, PermanentlyDeleteDocumentResponses, PermanentlyDeleteProjectData, PermanentlyDeleteProjectError, PermanentlyDeleteProjectErrors, PermanentlyDeleteProjectResponse, PermanentlyDeleteProjectResponses, PinnedItem, PinRequest, Pipeline, PipelineRecordType, PipelineSharing, PostActivityData, PostActivityError, PostActivityErrors, PostActivityRequest, PostActivityResponse, PostActivityResponses, PostChannelBotWebhookData, PostChannelBotWebhookError, PostChannelBotWebhookErrors, PostChannelBotWebhookResponse, PostChannelBotWebhookResponses, PostGroupedSoupAstGroupPageRequest, PostGroupedSoupAstInitialRequest, PostGroupedSoupAstRequest, PostItemsSoupAstData, PostItemsSoupAstError, PostItemsSoupAstErrors, PostItemsSoupAstGroupedData, PostItemsSoupAstGroupedError, PostItemsSoupAstGroupedErrors, PostItemsSoupAstGroupedResponse, PostItemsSoupAstGroupedResponses, PostItemsSoupAstResponse, PostItemsSoupAstResponses, PostItemsSoupData, PostItemsSoupError, PostItemsSoupErrors, PostItemsSoupResponse, PostItemsSoupResponses, PostMessage, PostMessageNotificationPolicy, PostSoupAstRequest, PostSoupRequest, PresaveDocumentHandlerData, PresaveDocumentHandlerError, PresaveDocumentHandlerErrors, PresaveDocumentHandlerResponse, PresaveDocumentHandlerResponses, PreSaveDocumentRequest, PreSaveDocumentResponse, PreSaveDocumentResponseData, PresenceOperator, PresignedUrl, PreviewSmartTagData, PreviewSmartTagError, PreviewSmartTagErrors, PreviewSmartTagResponse, PreviewSmartTagResponses, Project, ProjectDeleteResponseData, ProjectDocumentStatus, ProjectFilters, ProjectPreview, ProjectPreviewData, PropertyDefinition, PropertyDefinitionWithOptions, PropertyFilter, PropertyInput, PropertyOption, PropertyOptionValue, PropertyOwner, PropertyValue, PutCrmTeamSettingsData, PutCrmTeamSettingsError, PutCrmTeamSettingsErrors, PutCrmTeamSettingsResponse, PutCrmTeamSettingsResponses, PutCrmTeamStagesData, PutCrmTeamStagesError, PutCrmTeamStagesErrors, PutCrmTeamStagesResponse, PutCrmTeamStagesResponses, PutFormLayoutData, PutFormLayoutError, PutFormLayoutErrors, PutFormLayoutResponse, PutFormLayoutResponses, QueryCrmPipelineRowsData, QueryCrmPipelineRowsResponse, QueryCrmPipelineRowsResponses, QueryDatabasesData, QueryDatabasesError, QueryDatabasesErrors, QueryDatabasesResponse, QueryDatabasesResponses, QueryDefinition, QuestionLayout, QuestionOption, QuestionTally, ReactionInput, RecentlyDeletedData, RecentlyDeletedError, RecentlyDeletedErrors, RecentlyDeletedResponse, RecentlyDeletedResponseData, RecentlyDeletedResponses, RegisterSlackImportUploadsData, RegisterSlackImportUploadsErrors, RegisterSlackImportUploadsResponse, RegisterSlackImportUploadsResponses, RegisterUploads, RemoveBotFromChannelByBotData, RemoveBotFromChannelByBotError, RemoveBotFromChannelByBotErrors, RemoveBotFromChannelByBotResponse, RemoveBotFromChannelByBotResponses, RemoveFavoriteByEntityData, RemoveFavoriteByEntityError, RemoveFavoriteByEntityErrors, RemoveFavoriteByEntityResponses, RemoveParticipantsData, RemoveParticipantsError, RemoveParticipantsErrors, RemoveParticipantsRequest, RemoveParticipantsResponses, RemovePinHandlerData, RemovePinHandlerError, RemovePinHandlerErrors, RemovePinHandlerResponse, RemovePinHandlerResponses, RenameChannelLabelData, RenameChannelLabelError, RenameChannelLabelErrors, RenameChannelLabelRequest, RenameChannelLabelResponse, RenameChannelLabelResponses, RenameCrmPipelineData, RenameCrmPipelineResponse, RenameCrmPipelineResponses, RenamePipeline, ReorderFavoritesData, ReorderFavoritesError, ReorderFavoritesErrors, ReorderFavoritesRequest, ReorderFavoritesResponses, ReorderPinRequest, ReorderPinsHandlerData, ReorderPinsHandlerError, ReorderPinsHandlerErrors, ReorderPinsHandlerResponse, ReorderPinsHandlerResponses, ReplaceCrmStagesRequest, RequestAccess, RequestedHarnessScope, RequestedLayout, RequestStatus, RequestToJoinData, RequestToJoinError, RequestToJoinErrors, RequestToJoinResponse, RequestToJoinResponses, ResetCrmTeamStagesData, ResetCrmTeamStagesError, ResetCrmTeamStagesErrors, ResetCrmTeamStagesResponse, ResetCrmTeamStagesResponses, ResolveRequest, ResponseStatus, ResponseSummary, ResultColumn, ResultSet, RevertDeleteDocumentData, RevertDeleteDocumentError, RevertDeleteDocumentErrors, RevertDeleteDocumentResponse, RevertDeleteDocumentResponses, RevertDeleteProjectData, RevertDeleteProjectError, RevertDeleteProjectErrors, RevertDeleteProjectResponse, RevertDeleteProjectResponses, RingStatus, RingStatusResponse, RowChange, RowChangeKind, RowChanges, RowHistoryEntry, RowHistoryResponse, RowId, RowsChange, RowsResult, S3ObjectInfo, SaveBomPart, SaveDatabaseQueryData, SaveDatabaseQueryError, SaveDatabaseQueryErrors, SaveDatabaseQueryResponse, SaveDatabaseQueryResponses, SaveDocumentHandlerData, SaveDocumentHandlerError, SaveDocumentHandlerErrors, SaveDocumentHandlerResponse, SaveDocumentHandlerResponses, SaveDocumentRequest, SaveDocumentResponse, SaveDocumentResponseData, SavedQuery, SaveQueryRequest, SearchContactsData, SearchContactsError, SearchContactsErrors, SearchContactsResponse, SearchContactsResponse2, SearchContactsResponses, SearchState, SectionCount, SessionDeletedMetadata, SessionIdentity, SessionMentionedMetadata, SessionOpenedMetadata, SessionRenamedMetadata, SessionSettledMetadata, SessionSource, SessionStoppedMetadata, SetChannelLabelData, SetChannelLabelError, SetChannelLabelErrors, SetChannelLabelRequest, SetChannelLabelResponse, SetChannelLabelResponses, SetChannelPictureData, SetChannelPictureError, SetChannelPictureErrors, SetChannelPictureRequest, SetChannelPictureResponse, SetChannelPictureResponses, SetCompanyHiddenData, SetCompanyHiddenError, SetCompanyHiddenErrors, SetCompanyHiddenRequest, SetCompanyHiddenResponse, SetCompanyHiddenResponses, SetCompanyNameRequest, SetContactHiddenData, SetContactHiddenError, SetContactHiddenErrors, SetContactHiddenRequest, SetContactHiddenResponse, SetContactHiddenResponses, SetContactNameRequest, SetCrmCompanyNameData, SetCrmCompanyNameError, SetCrmCompanyNameErrors, SetCrmCompanyNameResponse, SetCrmCompanyNameResponses, SetCrmContactNameData, SetCrmContactNameError, SetCrmContactNameErrors, SetCrmContactNameResponse, SetCrmContactNameResponses, SetDirectAccess, SetDocumentTeamShareData, SetDocumentTeamShareError, SetDocumentTeamShareErrors, SetDocumentTeamShareRequest, SetDocumentTeamShareResponse, SetDocumentTeamShareResponses, SetEmailFollowupData, SetEmailFollowupError, SetEmailFollowupErrors, SetEmailFollowupResponse, SetEmailFollowupResponses, SetEmailSyncData, SetEmailSyncError, SetEmailSyncErrors, SetEmailSyncRequest, SetEmailSyncResponse, SetEmailSyncResponses, SetOperator, SetPropertyValue, Sha256Digest, ShareCrmPipelineData, ShareCrmPipelineResponse, ShareCrmPipelineResponses, ShareDatabaseAwarenessData, ShareDatabaseAwarenessError, ShareDatabaseAwarenessErrors, ShareDatabaseAwarenessResponse, ShareDatabaseAwarenessResponses, SharedEmailFilter, ShareEntity, ShareEntityType, SharePermissionV2, SharePipeline, ShortIdResponse, SimpleMention, SimpleSaveData, SimpleSaveError, SimpleSaveErrors, SimpleSaveResponse, SimpleSaveResponses, SkippedCell, SlackCompleteRequest, SlackCreateRequest, SlackRegisterRequest, SlackTimestamp, SlackUserId, SmartTagChannelMatch, SmartTagPreview, SortDirection, SortKey, SoupAgentSessionSoupPropertiesField, SoupApiItem, SoupApiSort, SoupApiSortDirection, SoupAttachment, SoupCalendarEventSoupPropertiesField, SoupCalendarEventTime, SoupCallRecordGuest, SoupCallRecordParticipant, SoupCallRecordSoupPropertiesField, SoupChannel, SoupChannelThread, SoupChatSoupPropertiesField, SoupContact, SoupCountedReaction, SoupCrmCompanySoupPropertiesField, SoupCrmContactSoupPropertiesField, SoupCrmDomain, SoupDatabaseRowSoupPropertiesField, SoupDocumentSoupPropertiesField, SoupDocumentSubType, SoupEmailThreadPreview, SoupEnrichedEmailThreadPreviewSoupPropertiesField, SoupForeignEntity, SoupInitiativeSoupPropertiesField, SoupItem, SoupLabel, SoupLabelListVisibility, SoupLabelType, SoupMessageAttachment, SoupMessageListVisibility, SoupMessageSender, SoupMessageSenderType, SoupPage, SoupProjectSoupPropertiesField, SoupPropertiesField, SoupProperty, SoupThreadInfo, SoupThreadReply, SourceBinding, SourceId, SourceIdentity, SqlCell, SqlEntityKind, SqlOutcome, SqlOutcomeKind, SqlSelectOption, SqlStatement, StarterDatabase, StarterDocumentsResponse, StorageRow, StorageRows, StorageRowsQuery, StoredGithubPullRequest, StreamEventsData, StreamEventsError, StreamEventsErrors, StreamEventsResponse, StreamEventsResponses, String, Submission, SubmissionOutcome, SubmitFormResponseData, SubmitFormResponseError, SubmitFormResponseErrors, SubmitFormResponseResponse, SubmitFormResponseResponses, SuccessResponse, SurfaceState, SyncServiceVersionId, SystemSkillSummary, Table, TableChange, TableChanged, TableChanges, TableDetail, TableId, TableResult, TableVersion, TagFilterMode, TakenId, TallyBucket, TallyValue, TaskFilters, TeamCalendarContent, TeamCalendarCoverage, TeamCalendarDetails, TeamCalendarItem, TeamCalendarMember, TeamCalendarPage, TeamCalendarSharing, TeamOutOfOfficeItem, TeamOutOfOfficeResponse, TeamRole, TextOperator, ThreadAnchor, ThreadOrigin, ThreadPatch, ThreadState, TimelineActivity, ToggleShareWithTeamData, ToggleShareWithTeamError, ToggleShareWithTeamErrors, ToggleShareWithTeamResponse, ToggleShareWithTeamResponses, TouchedColumn, TouchedRow, TranscribeDictationData, TranscribeDictationError, TranscribeDictationErrors, TranscribeDictationResponse, TranscribeDictationResponses, TranscribeResponse, TranscriptSegmentRequest, TrashCrmPipelineData, TrashCrmPipelineResponse, TrashCrmPipelineResponses, TrashPipeline, TurnEndedMetadata, TurnStartedMetadata, TurnSummary, TypedSuccessResponse, TypedSuccessResponseGetDocumentResponseData, TypingInput, UndoChangeResponse, UndoDatabaseChangeData, UndoDatabaseChangeError, UndoDatabaseChangeErrors, UndoDatabaseChangeResponse, UndoDatabaseChangeResponses, UndoOutcome, UndoRefusal, UnlockedBooking, UpdateAgentData, UpdateAgentError, UpdateAgentErrors, UpdateAgentRequest, UpdateAgentResponse, UpdateAgentResponses, UpdateChannelSharePermission, UpdateCrmPipelinePermissionsData, UpdateCrmPipelinePermissionsResponse, UpdateCrmPipelinePermissionsResponses, UpdateCrmTeamSettingsRequest, UpdateDatabasePermissionsData, UpdateDatabasePermissionsError, UpdateDatabasePermissionsErrors, UpdateDatabasePermissionsResponse, UpdateDatabasePermissionsResponses, UpdateForm, UpdateFormData, UpdateFormError, UpdateFormErrors, UpdateFormPermissionsData, UpdateFormPermissionsError, UpdateFormPermissionsErrors, UpdateFormPermissionsResponse, UpdateFormPermissionsResponses, UpdateFormResponse, UpdateFormResponses, UpdateInitiativeData, UpdateInitiativeError, UpdateInitiativeErrors, UpdateInitiativeRequest, UpdateInitiativeResponse, UpdateInitiativeResponses, UpdateMeetingRequest, UpdateOperation, UpdateSharePermissionRequestV2, UploadDescriptor, UploadDocumentStatus, UploadExtractFolderHandlerData, UploadExtractFolderHandlerError, UploadExtractFolderHandlerErrors, UploadExtractFolderHandlerResponse, UploadExtractFolderHandlerResponses, UploadExtractFolderRequest, UploadFolderHandlerData, UploadFolderHandlerError, UploadFolderHandlerErrors, UploadFolderHandlerResponse, UploadFolderHandlerResponses, UploadFolderRequest, UploadGrant, UploadId, UpsertHistoryHandlerData, UpsertHistoryHandlerError, UpsertHistoryHandlerErrors, UpsertHistoryHandlerResponse, UpsertHistoryHandlerResponses, UpsertUserDocumentViewLocationData, UpsertUserDocumentViewLocationError, UpsertUserDocumentViewLocationErrors, UpsertUserDocumentViewLocationRequest, UpsertUserDocumentViewLocationResponse, UpsertUserDocumentViewLocationResponses, UserApiKeyId, UserApiKeyInfo, UserApiKeysList, UserDocumentsResponse, UserDocumentViewLocation, UserDocumentViewLocationResponse, UserPinsResponse, UserViewsResponse, ValidateDocumentPermissionsTokenData, ValidateDocumentPermissionsTokenError, ValidateDocumentPermissionsTokenErrors, ValidateDocumentPermissionsTokenResponse, ValidateDocumentPermissionsTokenResponses, ValidateWebhookData, ValidateWebhookError, ValidateWebhookErrors, ValidateWebhookResponse, ValidateWebhookResponse2, ValidateWebhookResponses, Vec, VersionedTable, View, ViewChange, ViewColumn, ViewerCapabilities, ViewLayout, ViewPatch, ViewPosition, ViewPositionsResponse, ViewQuery, ViewResult, ViewsResponse, WaitingForInputMetadata, Webhook, WebhookEvent, WebhookFilter, WebhookScope, WebhookStatus, WebhookValidationTestEvent, WhatsappGroupData, WhatsAppGroupDetail, WhatsAppGroupMessage, WhatsAppGroupMessages, WhatsappGroupMessagesData, WhatsappGroupMessagesResponse, WhatsappGroupMessagesResponses, WhatsappGroupPermissionsData, WhatsappGroupPermissionsResponse, WhatsappGroupPermissionsResponses, WhatsAppGroupReaction, WhatsappGroupReadData, WhatsappGroupReadResponse, WhatsappGroupReadResponses, WhatsappGroupResponse, WhatsappGroupResponses, WhatsappGroupsData, WhatsAppGroupSender, WhatsappGroupSendsData, WhatsappGroupSendsResponse, WhatsappGroupSendsResponses, WhatsappGroupsResponse, WhatsappGroupsResponses, WhatsAppGroupSummary, WhatsappGroupUpdatePermissionsData, WhatsappGroupUpdatePermissionsResponse, WhatsappGroupUpdatePermissionsResponses, Widget, WithCallId, WithChannelId, WithDocumentId, WithProjectId } from './types.gen';
+export type { AccessiblePipeline, AccessLevel, AccessRequest, AccessRequestsCancelData, AccessRequestsCancelErrors, AccessRequestsCancelResponses, AccessRequestsDirectData, AccessRequestsDirectErrors, AccessRequestsDirectResponse, AccessRequestsDirectResponses, AccessRequestsRemoveDirectData, AccessRequestsRemoveDirectErrors, AccessRequestsRemoveDirectResponses, AccessRequestsResolveData, AccessRequestsResolveErrors, AccessRequestsResolveResponse, AccessRequestsResolveResponses, AccessRequestsSetDirectData, AccessRequestsSetDirectErrors, AccessRequestsSetDirectResponses, AccessRequestsStateData, AccessRequestsStateErrors, AccessRequestsStateResponse, AccessRequestsStateResponses, AccessRequestsSubmitData, AccessRequestsSubmitErrors, AccessRequestsSubmitResponse, AccessRequestsSubmitResponses, AccessRequestState, ActiveCallsResponse, ActiveCallSummary, ActiveMeeting, ActiveMeetingsResponse, ActivityType, AddFavoriteData, AddFavoriteError, AddFavoriteErrors, AddFavoriteRequest, AddFavoriteResponse, AddFavoriteResponses, AddParticipantsData, AddParticipantsError, AddParticipantsErrors, AddParticipantsRequest, AddParticipantsResponses, AddPinHandlerData, AddPinHandlerError, AddPinHandlerErrors, AddPinHandlerResponse, AddPinHandlerResponses, AddPinRequest, AdoptedGroup, Agent, AgentActionId, AgentChannelScope, AgentDmProfile, AgentMcpServer, AgentMcpServers, AgentPullRequestState, AgentSessionFilters, AgentSessionLifecycleEvent, AgentSessionSource, AgentSessionVisibility, AgentTyping, AgentTypingPhase, Anchor, AnchorId, AnchorResponse, AnnotationIncrementalUpdate, Answer, ApiActivity, ApiAttachmentChannelReference, ApiAttachmentCommentReference, ApiAttachmentEntityReference, ApiAttachmentGenericReference, ApiChannelAttachment, ApiChannelAttachmentsPage, ApiChannelDetail, ApiChannelListMessage, ApiChannelListPage, ApiChannelListParticipant, ApiChannelListType, ApiChannelParticipant, ApiChannelWithLatest, ApiEntityFilterAst, ApiGroupByField, ApiGroupMeta, ApiParticipantListRole, ApiParticipantRole, ApiPropertyEntityType, AppliedOps, ApplyCrmPipelineOpsData, ApplyCrmPipelineOpsResponse, ApplyCrmPipelineOpsResponses, ApplyDatabaseOpsData, ApplyDatabaseOpsError, ApplyDatabaseOpsErrors, ApplyDatabaseOpsResponse, ApplyDatabaseOpsResponses, ApplyOpsRequest, ApplyOpsResponse, ApproveHarnessPairingData, ApproveHarnessPairingError, ApproveHarnessPairingErrors, ApproveHarnessPairingResponse, ApproveHarnessPairingResponses, ApprovePairingRequest, AttachmentChange, AttendeeResponseStatus, Audience, Awareness, AwarenessRelay, BasicDocument, BasicDocumentSubType, BomPart, BookingTarget, Bot, BotChannel, BotChannelType, BotId, BotKind, BotOwner, BotOwnerProfile, BotSenderProfile, BotToken, BranchNameResponse, BTreeMap, BulkWakeupRequest, BulkWakeupResponse, BulkWakeupSyncServiceDocumentsData, BulkWakeupSyncServiceDocumentsErrors, BulkWakeupSyncServiceDocumentsResponse, BulkWakeupSyncServiceDocumentsResponses, CalendarAttendee, CalendarEvent, CalendarEventFilters, CalendarEventSourceContent, CalendarJoinRequest, CalendarJoinRequestApiError, CalendarJoinRequestErrorCode, CalendarJoinRequestsResponse, CalendarJoinRequestStatus, CalendarMentionEvent, CalendarMentionPreviewItem, CalendarMentionPreviewKind, CalendarMentionPreviewRequest, CalendarMentionPreviewRequestItem, CalendarMentionPreviewResponse, CalendarMentionViewerCopy, CalendarOccurrence, CalendarOccurrenceItem, CalendarOccurrenceResponse, CalendarSyncStatus, CallActiveResponse, CallFilters, CallProvider, CallRecord, CallRecordGuest, CallRecordParticipant, CallRecordPreview, CallRecordPreviewData, CallRecordSource, CallRecordTranscriptSegment, CallStatus, CallTokenResponse, CallWebhookData, CallWebhookError, CallWebhookErrors, CallWebhookResponses, CancelSlackImportData, CancelSlackImportErrors, CancelSlackImportResponse, CancelSlackImportResponses, CardPosition, CastVerdict, CellValue, CellWrite, ChangedFileDto, ChangesetDto, ChangesetSourceDto, Channel, ChannelCreatedMetadata, ChannelDeletedMetadata, ChannelFilters, ChannelJoinCodeResponse, ChannelLabel, ChannelLabelRule, ChannelLabelsList, ChannelMessage, ChannelParticipant, ChannelParticipantAddedMetadata, ChannelParticipantRemovedMetadata, ChannelPictureChangedMetadata, ChannelPreview, ChannelPreviewData, ChannelSender, ChannelSharePermission, ChannelThreadFilters, ChannelTopicEvent, ChannelType, ChannelUpdatedMetadata, ChannelWebhookRequest, ChannelWebhookResponse, ChannelWithParticipants, Chat, ChatFilters, CheckActiveCallData, CheckActiveCallError, CheckActiveCallErrors, CheckActiveCallResponse, CheckActiveCallResponses, ClaimedPairing, ClaimHarnessPairingData, ClaimHarnessPairingError, ClaimHarnessPairingErrors, ClaimHarnessPairingResponse, ClaimHarnessPairingResponses, ClaimPairingRequest, ClientOptions, CloudStorageItemType, CollaborateFormData, CollaborateFormError, CollaborateFormErrors, CollaborateFormResponse, CollaborateFormResponses, CollabSurfaceResponse, CollabSurfaceTokenResponse, Column, ColumnCast, ColumnChange, ColumnChangeKind, ColumnConfig, ColumnConversion, ColumnConversionRequest, ColumnDetail, ColumnId, ColumnKind, ColumnProtection, ColumnResult, CommandFailure, CommandRejectedMetadata, CommittedChange, CompleteSlackImportUploadsData, CompleteSlackImportUploadsErrors, CompleteSlackImportUploadsResponse, CompleteSlackImportUploadsResponses, CompleteUploads, ConferenceProvider, Conjunction, ConversationId, ConversationKind, ConversationMetadata, ConversationProgress, ConversationSeal, ConversationStatus, ConvertDatabaseColumnData, ConvertDatabaseColumnError, ConvertDatabaseColumnErrors, ConvertDatabaseColumnResponse, ConvertDatabaseColumnResponses, ConvertedCell, CopyDocumentData, CopyDocumentError, CopyDocumentErrors, CopyDocumentQueryParams, CopyDocumentRequest, CopyDocumentResponse, CopyDocumentResponse2, CopyDocumentResponses, CountedReaction, CreateAgentData, CreateAgentError, CreateAgentErrors, CreateAgentRequest, CreateAgentResponse, CreateAgentResponses, CreateAnchorData, CreateAnchorError, CreateAnchorErrors, CreateAnchorResponse, CreateAnchorResponses, CreateBotRequest, CreateBulkDocumentResponse, CreateBulkDocumentResponseData, CreateCanvasDocumentRequest, CreateCanvasDocumentResponse, CreateCanvasHandlerData, CreateCanvasHandlerError, CreateCanvasHandlerErrors, CreateCanvasHandlerResponse, CreateCanvasHandlerResponses, CreateChannelData, CreateChannelError, CreateChannelErrors, CreateChannelLabelData, CreateChannelLabelError, CreateChannelLabelErrors, CreateChannelLabelRequest, CreateChannelLabelResponse, CreateChannelLabelResponses, CreateChannelRequest, CreateChannelResponse, CreateChannelResponse2, CreateChannelResponses, CreateChannelScopedBotData, CreateChannelScopedBotError, CreateChannelScopedBotErrors, CreateChannelScopedBotRequest, CreateChannelScopedBotResponse, CreateChannelScopedBotResponse2, CreateChannelScopedBotResponses, CreateCollabSurfaceTokenData, CreateCollabSurfaceTokenError, CreateCollabSurfaceTokenErrors, CreateCollabSurfaceTokenResponse, CreateCollabSurfaceTokenResponses, CreateCrmCompanyData, CreateCrmCompanyError, CreateCrmCompanyErrors, CreateCrmCompanyRequest, CreateCrmCompanyResponse, CreateCrmCompanyResponses, CreateCrmContactData, CreateCrmContactError, CreateCrmContactErrors, CreateCrmContactRequest, CreateCrmContactResponse, CreateCrmContactResponses, CreateCrmPipelineData, CreateCrmPipelineResponse, CreateCrmPipelineResponses, CreateDatabaseData, CreateDatabaseError, CreateDatabaseErrors, CreateDatabaseRequest, CreateDatabaseResponse, CreateDatabaseResponses, CreateDatabaseWebhookData, CreateDatabaseWebhookError, CreateDatabaseWebhookErrors, CreateDatabaseWebhookRequest, CreateDatabaseWebhookResponse, CreateDatabaseWebhookResponses, CreatedDatabaseWebhookResponse, CreateDocumentData, CreateDocumentError, CreateDocumentErrors, CreateDocumentRequest, CreateDocumentResponse, CreateDocumentResponseData, CreateDocumentResponses, CreatedPairing, CreatedUserApiKey, CreateEntityMentionData, CreateEntityMentionError, CreateEntityMentionErrors, CreateEntityMentionRequest, CreateEntityMentionResponse, CreateEntityMentionResponse2, CreateEntityMentionResponses, CreateForm, CreateFormData, CreateFormError, CreateFormErrors, CreateFormResponse, CreateFormResponses, CreateHarnessPairingData, CreateHarnessPairingError, CreateHarnessPairingErrors, CreateHarnessPairingResponse, CreateHarnessPairingResponses, CreateImport, CreateInitiativeData, CreateInitiativeError, CreateInitiativeErrors, CreateInitiativeRequest, CreateInitiativeResponse, CreateInitiativeResponses, CreateInstructionsDocumentResponse, CreateInstructionsHandlerData, CreateInstructionsHandlerError, CreateInstructionsHandlerErrors, CreateInstructionsHandlerResponse, CreateInstructionsHandlerResponses, CreateMarkdownDocumentRequest, CreateMarkdownDocumentResponse, CreateMarkdownHandlerData, CreateMarkdownHandlerError, CreateMarkdownHandlerErrors, CreateMarkdownHandlerResponse, CreateMarkdownHandlerResponses, CreateMeetingRequest, CreatePairingRequest, CreatePipeline, CreateProjectHandlerData, CreateProjectHandlerError, CreateProjectHandlerErrors, CreateProjectHandlerResponse, CreateProjectHandlerResponses, CreateProjectRequest, CreateProjectResponse, CreateSkillHandlerData, CreateSkillHandlerError, CreateSkillHandlerErrors, CreateSkillHandlerResponse, CreateSkillHandlerResponses, CreateSkillRequest, CreateSkillResponse, CreateSlackImportData, CreateSlackImportErrors, CreateSlackImportResponse, CreateSlackImportResponses, CreateSnippetHandlerData, CreateSnippetHandlerError, CreateSnippetHandlerErrors, CreateSnippetHandlerResponse, CreateSnippetHandlerResponses, CreateSnippetRequest, CreateSnippetResponse, CreateTaskHandlerData, CreateTaskHandlerError, CreateTaskHandlerErrors, CreateTaskHandlerResponse, CreateTaskHandlerResponses, CreateTaskRequest, CreateTaskResponse, CreateToken, CreateUnthreadedAnchorRequest, CreateUnthreadedAnchorResponse, CreateUnthreadedPdfAnchorRequest, CreateUserApiKeyData, CreateUserApiKeyError, CreateUserApiKeyErrors, CreateUserApiKeyRequest, CreateUserApiKeyResponse, CreateUserApiKeyResponses, CreateViewHandlerData, CreateViewHandlerError, CreateViewHandlerErrors, CreateViewHandlerResponse, CreateViewHandlerResponses, CreateViewRequest, CreateWebhookData, CreateWebhookError, CreateWebhookErrors, CreateWebhookRequest, CreateWebhookResponse, CreateWebhookResponse2, CreateWebhookResponses, CrmAssociation, CrmCompanyFilters, CrmCompanyResponse, CrmContactResponse, CrmDomainResponse, CrmPermissionRole, CrmStageInput, CrmStageResponse, CrmStagesResponse, CrmTeamSettingsResponse, CustomSpeakerAssignment, Database, DatabaseDetail, DatabaseId, DatabaseOp, DatabaseQueryRequest, DatabaseView, DatabaseWebhookDeliveryResponse, DatabaseWebhookPayloadProblem, DatabaseWebhookResponse, DataType, DateOperator, DeclineCallData, DeclineCallError, DeclineCallErrors, DeclineCallResponse, DeclineCallResponses, DeclineRingData, DeclineRingError, DeclineRingErrors, DeclineRingResponse, DeclineRingResponses, DeleteAnchorData, DeleteAnchorError, DeleteAnchorErrors, DeleteAnchorResponse, DeleteAnchorResponses, DeleteCallRecordData, DeleteCallRecordError, DeleteCallRecordErrors, DeleteCallRecordResponse, DeleteCallRecordResponses, DeleteChannelData, DeleteChannelError, DeleteChannelErrors, DeleteChannelLabelData, DeleteChannelLabelError, DeleteChannelLabelErrors, DeleteChannelLabelResponse, DeleteChannelLabelResponses, DeleteChannelResponse, DeleteChannelResponses, DeleteCollabSurfaceData, DeleteCollabSurfaceError, DeleteCollabSurfaceErrors, DeleteCollabSurfaceResponse, DeleteCollabSurfaceResponses, DeleteDatabaseWebhookData, DeleteDatabaseWebhookError, DeleteDatabaseWebhookErrors, DeleteDatabaseWebhookResponse, DeleteDatabaseWebhookResponses, DeleteDocumentData, DeleteDocumentError, DeleteDocumentErrors, DeleteDocumentResponse, DeleteDocumentResponses, DeleteEntityMentionData, DeleteEntityMentionError, DeleteEntityMentionErrors, DeleteEntityMentionResponse, DeleteEntityMentionResponse2, DeleteEntityMentionResponses, DeleteHarnessData, DeleteHarnessError, DeleteHarnessErrors, DeleteHarnessResponse, DeleteHarnessResponses, DeleteHistoryHandlerData, DeleteHistoryHandlerError, DeleteHistoryHandlerErrors, DeleteHistoryHandlerResponse, DeleteHistoryHandlerResponses, DeleteInitiativeData, DeleteInitiativeError, DeleteInitiativeErrors, DeleteInitiativeResponse, DeleteInitiativeResponses, DeleteProjectHandlerData, DeleteProjectHandlerError, DeleteProjectHandlerErrors, DeleteProjectHandlerResponse, DeleteProjectHandlerResponses, DeleteSelfHarnessData, DeleteSelfHarnessError, DeleteSelfHarnessErrors, DeleteSelfHarnessResponse, DeleteSelfHarnessResponses, DeleteUnthreadedAnchorRequest, DeleteUnthreadedAnchorResponse, DeleteUnthreadedPdfAnchorRequest, DeleteUserApiKeyData, DeleteUserApiKeyError, DeleteUserApiKeyErrors, DeleteUserApiKeyResponse, DeleteUserApiKeyResponses, DeleteUserDocumentViewLocationData, DeleteUserDocumentViewLocationError, DeleteUserDocumentViewLocationErrors, DeleteUserDocumentViewLocationResponse, DeleteUserDocumentViewLocationResponses, DeleteViewHandlerData, DeleteViewHandlerError, DeleteViewHandlerErrors, DeleteViewHandlerResponses, DeleteWebhookData, DeleteWebhookError, DeleteWebhookErrors, DeleteWebhookResponse, DeleteWebhookResponses, DeliverDatabaseWebhookData, DeliverDatabaseWebhookError, DeliverDatabaseWebhookErrors, DeliverDatabaseWebhookResponse, DeliverDatabaseWebhookResponses, DirectAccess, DocumentBasic, DocumentContent, DocumentContentLocation, DocumentContentState, DocumentContentUploadedMetadata, DocumentCopiedMetadata, DocumentCreatedMetadata, DocumentDeletedMetadata, DocumentFilters, DocumentId, DocumentInteractionMetadata, DocumentMetadata, DocumentMetadataWithContent, DocumentPermissionsToken, DocumentPermissionsTokenRequest, DocumentPermissionsTokenResponse, DocumentPreview, DocumentPreviewData, DocumentPreviewDataSubType, DocumentPurgedMetadata, DocumentResponse, DocumentResponseMetadata, DocumentResponseMetadataWithContent, DocumentStorageServiceApiVersion, DocumentSubType, DocumentSyncContentUpdatedMetadata, DocumentSyncEditor, DocumentTeamShareResponse, DocumentTextContent, DocumentTopicEvent, DocumentUpdatedMetadata, EditAnchorData, EditAnchorError, EditAnchorErrors, EditAnchorRequest, EditAnchorResponse, EditAnchorResponse2, EditAnchorResponses, EditCallRecordData, EditCallRecordError, EditCallRecordErrors, EditCallRecordRequest, EditCallRecordResponse, EditCallRecordResponses, EditCallTranscriptData, EditCallTranscriptError, EditCallTranscriptErrors, EditCallTranscriptRequest, EditCallTranscriptResponse, EditCallTranscriptResponses, EditDocumentData, EditDocumentError, EditDocumentErrors, EditDocumentResponse, EditDocumentResponse2, EditDocumentResponses, EditDocumentServiceArgs, EditMyFormResponseData, EditMyFormResponseError, EditMyFormResponseErrors, EditMyFormResponseResponse, EditMyFormResponseResponses, EditPdfAnchorRequest, EditPdfPlaceableCommentAnchorRequest, EditProjectV2Data, EditProjectV2Error, EditProjectV2Errors, EditProjectV2Response, EditProjectV2Responses, EditThreadV2Data, EditThreadV2Error, EditThreadV2Errors, EditThreadV2Response, EditThreadV2Responses, EmailFilters, EmailFollowup, EmailFollowupCommand, EmailFollowupResponse, EmailReminderCondition, EmailReminderPage, EmailReminderSummary, EmptyResponse, EnsureCollabSurfaceData, EnsureCollabSurfaceError, EnsureCollabSurfaceErrors, EnsureCollabSurfaceRequest, EnsureCollabSurfaceResponse, EnsureCollabSurfaceResponses, EnsureStarterHandlerData, EnsureStarterHandlerErrors, EnsureStarterHandlerResponse, EnsureStarterHandlerResponses, EntityFilters, EntityKind, EntityMessageCreateData, EntityMessageCreateResponse, EntityMessageCreateResponses, EntityMessageDeleteMessageData, EntityMessageDeleteMessageResponse, EntityMessageDeleteMessageResponses, EntityMessageDeleteThreadData, EntityMessageDeleteThreadResponse, EntityMessageDeleteThreadResponses, EntityMessageEditData, EntityMessageEditResponse, EntityMessageEditResponses, EntityMessageGetMessageData, EntityMessageGetMessageResponse, EntityMessageGetMessageResponses, EntityMessageGetThreadData, EntityMessageGetThreadResponse, EntityMessageGetThreadResponses, EntityMessageLegacyData, EntityMessageLegacyResponse, EntityMessageLegacyResponses, EntityMessagePatchThreadData, EntityMessagePatchThreadResponse, EntityMessagePatchThreadResponses, EntityMessageReactData, EntityMessageReactResponse, EntityMessageReactResponses, EntityMessageTypingData, EntityMessageTypingResponse, EntityMessageTypingResponses, EntityPermission, EntityPermissionResponse, EntityRef, EntityReference, EntityType, ErrorResponse, EventIcsData, EventIcsErrors, EventIcsResponse, EventIcsResponses, EventReminderOverride, EventReminders, EventStatus, EventTime, EventTransparency, EventType, EventVisibility, ExcludedDefaultView, ExcludeDefaultViewHandlerData, ExcludeDefaultViewHandlerError, ExcludeDefaultViewHandlerErrors, ExcludeDefaultViewHandlerResponses, ExcludeDefaultViewRequest, ExportDocumentData, ExportDocumentError, ExportDocumentErrors, ExportDocumentResponse, ExportDocumentResponse2, ExportDocumentResponses, Favorite, FavoriteEntityRef, FavoritesList, FileChangeKindDto, FileSystemNodeWithIds, FileType, FileTypeUpdate, FilterCondition, FilterGroup, FilterNode, FilterTest, FinalizeSlackImportData, FinalizeSlackImportErrors, FinalizeSlackImportResponse, FinalizeSlackImportResponses, FolderItem, FollowupState, ForeignEntity, ForeignEntityFilters, Form, FormAccess, FormCollaboration, FormDetail, FormErrorCode, FormErrorResponse, FormLayout, FormPublicationProblem, FormQuestionDetail, FormResponse, FormSection, FormSectionDetail, FormSource, FormStatus, FormTally, Formula, GenericErrorResponse, GenericResponse, GenericSuccessResponse, GetActiveCallsData, GetActiveCallsError, GetActiveCallsErrors, GetActiveCallsResponse, GetActiveCallsResponses, GetActivityData, GetActivityError, GetActivityErrors, GetActivityResponse, GetActivityResponses, GetAttachmentReferencesData, GetAttachmentReferencesError, GetAttachmentReferencesErrors, GetAttachmentReferencesResponse, GetAttachmentReferencesResponse2, GetAttachmentReferencesResponses, GetBatchCallRecordPreviewData, GetBatchCallRecordPreviewError, GetBatchCallRecordPreviewErrors, GetBatchCallRecordPreviewRequest, GetBatchCallRecordPreviewResponse, GetBatchCallRecordPreviewResponse2, GetBatchCallRecordPreviewResponses, GetBatchChannelPreviewData, GetBatchChannelPreviewError, GetBatchChannelPreviewErrors, GetBatchChannelPreviewRequest, GetBatchChannelPreviewResponse, GetBatchChannelPreviewResponse2, GetBatchChannelPreviewResponses, GetBatchPreviewHandlerData, GetBatchPreviewHandlerError, GetBatchPreviewHandlerErrors, GetBatchPreviewHandlerResponse, GetBatchPreviewHandlerResponses, GetBatchPreviewRequest, GetBatchPreviewResponse, GetBatchProjectPreviewData, GetBatchProjectPreviewError, GetBatchProjectPreviewErrors, GetBatchProjectPreviewRequest, GetBatchProjectPreviewResponse, GetBatchProjectPreviewResponse2, GetBatchProjectPreviewResponses, GetBotOwnerProfilesData, GetBotOwnerProfilesError, GetBotOwnerProfilesErrors, GetBotOwnerProfilesResponse, GetBotOwnerProfilesResponses, GetCallRecordData, GetCallRecordError, GetCallRecordErrors, GetCallRecordResponse, GetCallRecordResponses, GetChannelAttachmentsData, GetChannelAttachmentsError, GetChannelAttachmentsErrors, GetChannelAttachmentsResponse, GetChannelAttachmentsResponses, GetChannelData, GetChannelError, GetChannelErrors, GetChannelJoinLinkData, GetChannelJoinLinkError, GetChannelJoinLinkErrors, GetChannelJoinLinkResponse, GetChannelJoinLinkResponses, GetChannelParticipantsData, GetChannelParticipantsError, GetChannelParticipantsErrors, GetChannelParticipantsResponse, GetChannelParticipantsResponses, GetChannelResponse, GetChannelResponses, GetChannelsData, GetChannelsError, GetChannelsErrors, GetChannelsResponse, GetChannelsResponses, GetCollabSurfaceData, GetCollabSurfaceError, GetCollabSurfaceErrors, GetCollabSurfaceResponse, GetCollabSurfaceResponses, GetCompanyData, GetCompanyError, GetCompanyErrors, GetCompanyResponse, GetCompanyResponses, GetContactByEmailData, GetContactByEmailError, GetContactByEmailErrors, GetContactByEmailResponse, GetContactByEmailResponse2, GetContactByEmailResponses, GetContactData, GetContactError, GetContactErrors, GetContactResponse, GetContactResponses, GetCrmPipelineData, GetCrmPipelinePermissionsData, GetCrmPipelinePermissionsResponse, GetCrmPipelinePermissionsResponses, GetCrmPipelineResponse, GetCrmPipelineResponses, GetCrmPipelineRowsData, GetCrmPipelineRowsResponse, GetCrmPipelineRowsResponses, GetCrmPipelineTableData, GetCrmPipelineTableResponse, GetCrmPipelineTableResponses, GetCrmTeamSettingsData, GetCrmTeamSettingsError, GetCrmTeamSettingsErrors, GetCrmTeamSettingsResponse, GetCrmTeamSettingsResponses, GetDatabaseData, GetDatabaseError, GetDatabaseErrors, GetDatabasePermissionsData, GetDatabasePermissionsError, GetDatabasePermissionsErrors, GetDatabasePermissionsResponse, GetDatabasePermissionsResponses, GetDatabaseQueryData, GetDatabaseQueryError, GetDatabaseQueryErrors, GetDatabaseQueryResponse, GetDatabaseQueryResponses, GetDatabaseResponse, GetDatabaseResponses, GetDatabaseRowHistoryData, GetDatabaseRowHistoryError, GetDatabaseRowHistoryErrors, GetDatabaseRowHistoryResponse, GetDatabaseRowHistoryResponses, GetDatabaseTableChangesData, GetDatabaseTableChangesError, GetDatabaseTableChangesErrors, GetDatabaseTableChangesResponse, GetDatabaseTableChangesResponses, GetDatabaseViewPositionsData, GetDatabaseViewPositionsError, GetDatabaseViewPositionsErrors, GetDatabaseViewPositionsResponse, GetDatabaseViewPositionsResponses, GetDocumentAnchorsData, GetDocumentAnchorsError, GetDocumentAnchorsErrors, GetDocumentAnchorsResponse, GetDocumentAnchorsResponses, GetDocumentBranchNameData, GetDocumentBranchNameError, GetDocumentBranchNameErrors, GetDocumentBranchNameResponse, GetDocumentBranchNameResponses, GetDocumentByTeamSlugData, GetDocumentByTeamSlugError, GetDocumentByTeamSlugErrors, GetDocumentByTeamSlugResponse, GetDocumentByTeamSlugResponses, GetDocumentData, GetDocumentError, GetDocumentErrors, GetDocumentGithubPullRequestsData, GetDocumentGithubPullRequestsError, GetDocumentGithubPullRequestsErrors, GetDocumentGithubPullRequestsResponse, GetDocumentGithubPullRequestsResponses, GetDocumentKeyResponse, GetDocumentKeyResponseData, GetDocumentListHandlerData, GetDocumentListHandlerError, GetDocumentListHandlerErrors, GetDocumentListHandlerResponse, GetDocumentListHandlerResponses, GetDocumentListResult, GetDocumentLocationV3Data, GetDocumentLocationV3Error, GetDocumentLocationV3Errors, GetDocumentLocationV3Response, GetDocumentLocationV3Responses, GetDocumentPermissionsResponseDataV2, GetDocumentPermissionsTokenData, GetDocumentPermissionsTokenError, GetDocumentPermissionsTokenErrors, GetDocumentPermissionsTokenResponse, GetDocumentPermissionsTokenResponses, GetDocumentPermissionsV2Data, GetDocumentPermissionsV2Error, GetDocumentPermissionsV2Errors, GetDocumentPermissionsV2Response, GetDocumentPermissionsV2Responses, GetDocumentProcessingResult, GetDocumentProcessingResultData, GetDocumentProcessingResultError, GetDocumentProcessingResultErrors, GetDocumentProcessingResultResponse, GetDocumentProcessingResultResponse2, GetDocumentProcessingResultResponses, GetDocumentResponse, GetDocumentResponse2, GetDocumentResponseData, GetDocumentResponses, GetDocumentSearchResponse, GetDocumentShortIdData, GetDocumentShortIdError, GetDocumentShortIdErrors, GetDocumentShortIdResponse, GetDocumentShortIdResponses, GetDocumentsResponse, GetDocumentTeamShareData, GetDocumentTeamShareError, GetDocumentTeamShareErrors, GetDocumentTeamShareResponse, GetDocumentTeamShareResponses, GetDocumentTextContentData, GetDocumentTextContentErrors, GetDocumentTextContentResponse, GetDocumentTextContentResponses, GetDocumentUserAccessLevelResponse, GetDocumentVersionData, GetDocumentVersionError, GetDocumentVersionErrors, GetDocumentVersionResponse, GetDocumentVersionResponses, GetDocumentViewsHandlerData, GetDocumentViewsHandlerError, GetDocumentViewsHandlerErrors, GetDocumentViewsHandlerResponse, GetDocumentViewsHandlerResponses, GetEmailFollowupData, GetEmailFollowupError, GetEmailFollowupErrors, GetEmailFollowupResponse, GetEmailFollowupResponses, GetEntityPermissionData, GetEntityPermissionErrors, GetEntityPermissionResponse, GetEntityPermissionResponses, GetForeignEntityBySourceData, GetForeignEntityBySourceError, GetForeignEntityBySourceErrors, GetForeignEntityBySourceResponse, GetForeignEntityBySourceResponses, GetForeignEntityData, GetForeignEntityError, GetForeignEntityErrors, GetForeignEntityResponse, GetForeignEntityResponses, GetFormData, GetFormError, GetFormErrors, GetFormPermissionsData, GetFormPermissionsError, GetFormPermissionsErrors, GetFormPermissionsResponse, GetFormPermissionsResponses, GetFormResponse, GetFormResponses, GetFormResponseSummaryData, GetFormResponseSummaryError, GetFormResponseSummaryErrors, GetFormResponseSummaryResponse, GetFormResponseSummaryResponses, GetFormTallyData, GetFormTallyError, GetFormTallyErrors, GetFormTallyResponse, GetFormTallyResponses, GetGithubPullRequestChangesData, GetGithubPullRequestChangesError, GetGithubPullRequestChangesErrors, GetGithubPullRequestChangesPatchData, GetGithubPullRequestChangesPatchError, GetGithubPullRequestChangesPatchErrors, GetGithubPullRequestChangesPatchResponse, GetGithubPullRequestChangesPatchResponses, GetGithubPullRequestChangesResponse, GetGithubPullRequestChangesResponses, GetGithubPullRequestData, GetGithubPullRequestError, GetGithubPullRequestErrors, GetGithubPullRequestFacetsData, GetGithubPullRequestFacetsError, GetGithubPullRequestFacetsErrors, GetGithubPullRequestFacetsResponse, GetGithubPullRequestFacetsResponses, GetGithubPullRequestResponse, GetGithubPullRequestResponses, GetGithubPullRequestTasksData, GetGithubPullRequestTasksError, GetGithubPullRequestTasksErrors, GetGithubPullRequestTasksResponse, GetGithubPullRequestTasksResponses, GetHarnessPairingData, GetHarnessPairingError, GetHarnessPairingErrors, GetHarnessPairingResponse, GetHarnessPairingResponses, GetHistoryHandlerData, GetHistoryHandlerError, GetHistoryHandlerErrors, GetHistoryHandlerResponse, GetHistoryHandlerResponses, GetInitiativeData, GetInitiativeError, GetInitiativeErrors, GetInitiativeResponse, GetInitiativeResponses, GetInstructionsDocumentResponse, GetInstructionsHandlerData, GetInstructionsHandlerError, GetInstructionsHandlerErrors, GetInstructionsHandlerResponse, GetInstructionsHandlerResponses, GetItemsSoupData, GetItemsSoupError, GetItemsSoupErrors, GetItemsSoupResponse, GetItemsSoupResponses, GetLocationHandlerData, GetLocationHandlerError, GetLocationHandlerErrors, GetLocationHandlerResponse, GetLocationHandlerResponses, GetMyFormResponseData, GetMyFormResponseError, GetMyFormResponseErrors, GetMyFormResponseResponse, GetMyFormResponseResponses, GetOrCreateAction, GetOrCreateCallData, GetOrCreateCallError, GetOrCreateCallErrors, GetOrCreateCallResponse, GetOrCreateCallResponses, GetOrCreateChannelResponse, GetOrCreateDmData, GetOrCreateDmError, GetOrCreateDmErrors, GetOrCreateDmRequest, GetOrCreateDmResponse, GetOrCreateDmResponses, GetOrCreatePrivateData, GetOrCreatePrivateError, GetOrCreatePrivateErrors, GetOrCreatePrivateRequest, GetOrCreatePrivateResponse, GetOrCreatePrivateResponses, GetPendingProjectsHandlerData, GetPendingProjectsHandlerError, GetPendingProjectsHandlerErrors, GetPendingProjectsHandlerResponse, GetPendingProjectsHandlerResponses, GetPinsHandlerData, GetPinsHandlerError, GetPinsHandlerErrors, GetPinsHandlerResponse, GetPinsHandlerResponses, GetPinsResponse, GetProjectContentHandlerData, GetProjectContentHandlerError, GetProjectContentHandlerErrors, GetProjectContentHandlerResponse, GetProjectContentHandlerResponses, GetProjectContentResponse, GetProjectHandlerData, GetProjectHandlerError, GetProjectHandlerErrors, GetProjectHandlerResponse, GetProjectHandlerResponses, GetProjectPermissionsV2Data, GetProjectPermissionsV2Error, GetProjectPermissionsV2Errors, GetProjectPermissionsV2Response, GetProjectPermissionsV2Responses, GetProjectResponse, GetProjectResponseData, GetProjectsHandlerData, GetProjectsHandlerError, GetProjectsHandlerErrors, GetProjectsHandlerResponse, GetProjectsHandlerResponses, GetProjectsResponse, GetProjectUserAccessLevelData, GetProjectUserAccessLevelError, GetProjectUserAccessLevelErrors, GetProjectUserAccessLevelResponse, GetProjectUserAccessLevelResponses, GetRingStatusData, GetRingStatusError, GetRingStatusErrors, GetRingStatusResponse, GetRingStatusResponses, GetSelfBotData, GetSelfBotError, GetSelfBotErrors, GetSelfBotResponse, GetSelfBotResponses, GetSelfHarnessData, GetSelfHarnessError, GetSelfHarnessErrors, GetSelfHarnessResponse, GetSelfHarnessResponses, GetSlackImportData, GetSlackImportErrors, GetSlackImportResponse, GetSlackImportResponses, GetSystemSkillsHandlerData, GetSystemSkillsHandlerError, GetSystemSkillsHandlerErrors, GetSystemSkillsHandlerResponse, GetSystemSkillsHandlerResponses, GetUserDocumentsHandlerData, GetUserDocumentsHandlerError, GetUserDocumentsHandlerErrors, GetUserDocumentsHandlerResponse, GetUserDocumentsHandlerResponses, GetUserDocumentViewLocationData, GetUserDocumentViewLocationError, GetUserDocumentViewLocationErrors, GetUserDocumentViewLocationResponse, GetUserDocumentViewLocationResponses, GetUserHistoryResponse, GetViewsHandlerData, GetViewsHandlerError, GetViewsHandlerErrors, GetViewsHandlerResponse, GetViewsHandlerResponses, GetWebhookData, GetWebhookError, GetWebhookErrors, GetWebhookResponse, GetWebhookResponses, GithubLabelFacet, GithubPullRequest, GithubPullRequestChangesPatchResponse, GithubPullRequestChangesResponse, GithubPullRequestCheckRun, GithubPullRequestComment, GithubPullRequestFacets, GithubPullRequestLabel, GithubPullRequestReview, GithubPullRequestReviewDecision, GithubPullRequestReviewState, GithubPullRequestsResponse, GithubPullRequestTasks, GithubPullRequestTasksRequest, GithubPullRequestTasksResponse, GithubPullRequestUser, GithubRepositoryFacet, GithubUserFacet, GitRefDto, GroupedInitialParams, GroupedPageParams, GroupedSoupGroupPage, GroupedSoupInitialPage, GroupedSoupPage, GroupedSoupSort, GuestCallChatPostData, GuestCallChatPostErrors, GuestCallChatPostResponse, GuestCallChatPostResponses, GuestCallChatReadData, GuestCallChatReadErrors, GuestCallChatReadResponse, GuestCallChatReadResponses, GuestChatMessage, GuestChatPage, GuestChatPost, GuestId, GuestJoinRequest, GuestPolicy, HandlerData, HandlerError, HandlerErrors, HandlerResponse, HandlerResponses, Harness, HarnessAgent, HarnessId, HarnessOwner, HarnessSession, HashMap, HealthHandlerData, HealthHandlerResponse, HealthHandlerResponses, HighlightType, ImportCounters, ImportDatabaseTableData, ImportDatabaseTableError, ImportDatabaseTableErrors, ImportDatabaseTableResponse, ImportDatabaseTableResponses, ImportedAuthor, ImportError, ImportLimits, ImportPage, ImportProgress, ImportTable, ImportWarning, InferColumnTypeOutcome, InferColumnTypeRequest, InferDatabaseColumnTypeData, InferDatabaseColumnTypeError, InferDatabaseColumnTypeErrors, InferDatabaseColumnTypeResponse, InferDatabaseColumnTypeResponses, InFlightTurnSummary, IngestTranscriptData, IngestTranscriptError, IngestTranscriptErrors, IngestTranscriptResponses, InitializeUserDocumentsData, InitializeUserDocumentsError, InitializeUserDocumentsErrors, InitializeUserDocumentsResponse, InitializeUserDocumentsResponses, InitialPropertyValue, InitiativeDetail, InitiativeFilters, InitiativeId, InitiativeList, InitiativeSummary, InputReceivedMetadata, InstallSyncData, InstallSyncErrors, InteractionReason, InvalidDatabaseWebhookPayloadResponse, InviteMeetingRequest, InviteMeetingUsersRequest, Item, ItemWithUserAccessLevel, JobId, JobProcessingResultHandlerData, JobProcessingResultHandlerError, JobProcessingResultHandlerErrors, JobProcessingResultHandlerResponse, JobProcessingResultHandlerResponses, JobStatus, JoinChannelByCodeData, JoinChannelByCodeError, JoinChannelByCodeErrors, JoinChannelByCodeResponses, JoinChannelData, JoinChannelError, JoinChannelErrors, JoinChannelResponses, KeySegment, Lane, LaneKey, LatestMessage, LayoutProblem, LeaveCallResponse, LeaveChannelData, LeaveChannelError, LeaveChannelErrors, LeaveChannelResponses, LeaveOrEndCallData, LeaveOrEndCallError, LeaveOrEndCallErrors, LeaveOrEndCallResponse, LeaveOrEndCallResponses, LinkedAccount, LinkedAccountData, LinkedAccountResponse, LinkedAccountResponses, LinkedAccountState, LinkedAccountView, LinkedAdoptData, LinkedAdoptGroup, LinkedAdoptResponse, LinkedAdoptResponses, LinkedAttachment, LinkedAttachmentState, LinkedBackfill, LinkedBackfillState, LinkedCancelPairingData, LinkedCancelPairingResponse, LinkedCancelPairingResponses, LinkedCapabilities, LinkedChat, LinkedChatKind, LinkedChats, LinkedChatsData, LinkedChatsResponse, LinkedChatsResponses, LinkedConfigurationData, LinkedConfigurationResponse, LinkedConfigurationResponses, LinkedConnect, LinkedConnectData, LinkedConnectResponse, LinkedConnectResponses, LinkedDeliveryData, LinkedDeliveryResponse, LinkedDeliveryResponses, LinkedDeliveryState, LinkedDetachData, LinkedDetachResponse, LinkedDetachResponses, LinkedDisconnect, LinkedDisconnectData, LinkedDisconnectRequest, LinkedDisconnectResponse, LinkedDisconnectResponses, LinkedFeatures, LinkedGroupInfo, LinkedGroupReference, LinkedGroupsData, LinkedGroupsResponse, LinkedGroupsResponses, LinkedIdentity, LinkedMediaKind, LinkedMessageAttachments, LinkedMessageAttachmentsData, LinkedMessageAttachmentsResponse, LinkedMessageAttachmentsResponses, LinkedMutation, LinkedPairing, LinkedPairingData, LinkedPairingResponse, LinkedPairingResponses, LinkedPairingState, LinkedPairState, LinkedParticipant, LinkedPasskeyData, LinkedPasskeyResponse, LinkedPasskeyResponses, LinkedReplyBlock, LinkedReplyContent, LinkedReplyData, LinkedReplyErrors, LinkedReplyResponse, LinkedReplyResponses, LinkedSendProgress, LinkedSendReply, LinkedSharedGroupReference, LinkedUploadData, LinkedUploadedAttachment, LinkedUploadRequest, LinkedUploadResponse, LinkedUploadResponses, LinkShare, ListAccessibleFormsData, ListAccessibleFormsError, ListAccessibleFormsErrors, ListAccessibleFormsResponse, ListAccessibleFormsResponses, ListAgentsData, ListAgentsError, ListAgentsErrors, ListAgentsResponse, ListAgentsResponses, ListBotChannelsData, ListBotChannelsError, ListBotChannelsErrors, ListBotChannelsResponse, ListBotChannelsResponses, ListChannelLabelsData, ListChannelLabelsError, ListChannelLabelsErrors, ListChannelLabelsResponse, ListChannelLabelsResponses, ListCompanyContactsData, ListCompanyContactsError, ListCompanyContactsErrors, ListCompanyContactsResponse, ListCompanyContactsResponses, ListCrmPipelinesData, ListCrmPipelinesResponse, ListCrmPipelinesResponses, ListDatabaseColumnCastsData, ListDatabaseColumnCastsError, ListDatabaseColumnCastsErrors, ListDatabaseColumnCastsResponse, ListDatabaseColumnCastsResponses, ListDatabasesData, ListDatabasesError, ListDatabasesErrors, ListDatabasesResponse, ListDatabasesResponses, ListDatabaseWebhooksData, ListDatabaseWebhooksError, ListDatabaseWebhooksErrors, ListDatabaseWebhooksResponse, ListDatabaseWebhooksResponse2, ListDatabaseWebhooksResponses, ListedDatabase, ListedForm, ListEmailRemindersData, ListEmailRemindersError, ListEmailRemindersErrors, ListEmailRemindersResponse, ListEmailRemindersResponses, ListFavoritesData, ListFavoritesError, ListFavoritesErrors, ListFavoritesResponse, ListFavoritesResponses, ListFormsData, ListFormsError, ListFormsErrors, ListFormsResponse, ListFormsResponses, ListHarnessAgentsData, ListHarnessAgentsError, ListHarnessAgentsErrors, ListHarnessAgentsResponse, ListHarnessAgentsResponses, ListHarnessesData, ListHarnessesError, ListHarnessesErrors, ListHarnessesResponse, ListHarnessesResponses, ListHarnessSessionsData, ListHarnessSessionsError, ListHarnessSessionsErrors, ListHarnessSessionsResponse, ListHarnessSessionsResponses, ListInitiativesData, ListInitiativesError, ListInitiativesErrors, ListInitiativesResponse, ListInitiativesResponses, ListJoinRequestsData, ListJoinRequestsError, ListJoinRequestsErrors, ListJoinRequestsResponse, ListJoinRequestsResponses, ListOccurrencesData, ListOccurrencesErrors, ListOccurrencesResponse, ListOccurrencesResponses, ListSlackImportsData, ListSlackImportsResponse, ListSlackImportsResponses, ListTeamCalendarData, ListTeamCalendarResponse, ListTeamCalendarResponses, ListTeamOutOfOfficeData, ListTeamOutOfOfficeErrors, ListTeamOutOfOfficeResponse, ListTeamOutOfOfficeResponses, ListUserApiKeysData, ListUserApiKeysError, ListUserApiKeysErrors, ListUserApiKeysResponse, ListUserApiKeysResponses, ListWebhooksData, ListWebhooksError, ListWebhooksErrors, ListWebhooksResponse, ListWebhooksResponse2, ListWebhooksResponses, LocationResponseData, LocationResponseV3, MacroUserIdStr, MarkRead, Meeting, MeetingCancelData, MeetingCancelError, MeetingCancelErrors, MeetingCancelPreparationData, MeetingCancelPreparationError, MeetingCancelPreparationErrors, MeetingCancelPreparationResponse, MeetingCancelPreparationResponses, MeetingCancelResponse, MeetingCancelResponses, MeetingCreateData, MeetingCreateError, MeetingCreateErrors, MeetingCreateResponse, MeetingCreateResponses, MeetingGuestJoinData, MeetingGuestJoinError, MeetingGuestJoinErrors, MeetingGuestJoinResponse, MeetingGuestJoinResponses, MeetingGuestParticipantsData, MeetingGuestParticipantsError, MeetingGuestParticipantsErrors, MeetingGuestParticipantsResponse, MeetingGuestParticipantsResponses, MeetingInviteData, MeetingInviteError, MeetingInviteErrors, MeetingInvitePermissions, MeetingInvitePermissionsData, MeetingInvitePermissionsError, MeetingInvitePermissionsErrors, MeetingInvitePermissionsResponse, MeetingInvitePermissionsResponses, MeetingInviteResponse, MeetingInviteResponses, MeetingInviteUsersData, MeetingInviteUsersError, MeetingInviteUsersErrors, MeetingInviteUsersResponse, MeetingInviteUsersResponses, MeetingJoinData, MeetingJoinError, MeetingJoinErrors, MeetingJoinResponse, MeetingJoinResponses, MeetingLeaveData, MeetingLeaveError, MeetingLeaveErrors, MeetingLeaveResponse, MeetingLeaveResponses, MeetingListActiveData, MeetingListActiveError, MeetingListActiveErrors, MeetingListActiveResponse, MeetingListActiveResponses, MeetingListData, MeetingListError, MeetingListErrors, MeetingListResponse, MeetingListResponses, MeetingLookupData, MeetingLookupError, MeetingLookupErrors, MeetingLookupResponse, MeetingLookupResponses, MeetingParticipant, MeetingParticipants, MeetingParticipantsData, MeetingParticipantsError, MeetingParticipantsErrors, MeetingParticipantsResponse, MeetingParticipantsResponses, MeetingPreparation, MeetingPrepareData, MeetingPrepareError, MeetingPrepareErrors, MeetingPrepareResponse, MeetingPrepareResponses, MeetingShareData, MeetingShareError, MeetingShareErrors, MeetingShareResponse, MeetingShareResponses, MeetingsResponse, MeetingToken, MeetingUpdateData, MeetingUpdateError, MeetingUpdateErrors, MeetingUpdateResponse, MeetingUpdateResponses, MentionPreviewsData, MentionPreviewsErrors, MentionPreviewsResponse, MentionPreviewsResponses, Message, MessageAttachment, MessageAttachmentCreatedMetadata, MessageAttachmentRemovedMetadata, MessageChange, MessageCursor, MessageDeletedMetadata, MessageDirection, MessageEvent, MessageEventAttachment, MessageListItem, MessageMentionedMetadata, MessagePage, MessageParent, MessagePatch, MessagePatchedMetadata, MessagePostedMetadata, MessageThread, MessageThreadPreview, MessageTimelineData, MessageTimelineEntriesData, MessageTimelineEntriesResponse, MessageTimelineEntriesResponses, MessageTimelineEntry, MessageTimelinePage, MessageTimelineQuery, MessageTimelineResponse, MessageTimelineResponses, MessageTopicEvent, MyResponse, NewAttachment, NewColumn, NewOption, NewThreadAnchor, NewView, NotificationFilters, NotificationState, NumberOperator, OpBatch, Operator, OpRefusalResponse, OpResult, OptionId, OptionRef, PairingDetails, Params, ParticipantRole, PatchBotRequest, PatchChannelData, PatchChannelError, PatchChannelErrors, PatchChannelRequest, PatchChannelResponse, PatchChannelResponses, PatchMessageNotificationPolicy, PatchProjectRequestV2, PatchThreadRequestV2, PatchViewHandlerData, PatchViewHandlerError, PatchViewHandlerErrors, PatchViewHandlerResponses, PatchWebhookData, PatchWebhookError, PatchWebhookErrors, PatchWebhookRequest, PatchWebhookResponse, PatchWebhookResponses, PdfAnchor, PdfAnchorId, PdfHighlightAnchor, PdfHighlightAnchorRequest, PdfHighlightRect, PdfHighlightRectAnchorRequest, PdfPlaceableCommentAnchor, PendingClaimResponse, PermanentlyDeleteDocumentData, PermanentlyDeleteDocumentError, PermanentlyDeleteDocumentErrors, PermanentlyDeleteDocumentResponse, PermanentlyDeleteDocumentResponses, PermanentlyDeleteProjectData, PermanentlyDeleteProjectError, PermanentlyDeleteProjectErrors, PermanentlyDeleteProjectResponse, PermanentlyDeleteProjectResponses, PinnedItem, PinRequest, Pipeline, PipelineRecordType, PipelineSharing, PostActivityData, PostActivityError, PostActivityErrors, PostActivityRequest, PostActivityResponse, PostActivityResponses, PostChannelBotWebhookData, PostChannelBotWebhookError, PostChannelBotWebhookErrors, PostChannelBotWebhookResponse, PostChannelBotWebhookResponses, PostGroupedSoupAstGroupPageRequest, PostGroupedSoupAstInitialRequest, PostGroupedSoupAstRequest, PostItemsSoupAstData, PostItemsSoupAstError, PostItemsSoupAstErrors, PostItemsSoupAstGroupedData, PostItemsSoupAstGroupedError, PostItemsSoupAstGroupedErrors, PostItemsSoupAstGroupedResponse, PostItemsSoupAstGroupedResponses, PostItemsSoupAstResponse, PostItemsSoupAstResponses, PostItemsSoupData, PostItemsSoupError, PostItemsSoupErrors, PostItemsSoupResponse, PostItemsSoupResponses, PostMessage, PostMessageNotificationPolicy, PostSoupAstRequest, PostSoupRequest, PresaveDocumentHandlerData, PresaveDocumentHandlerError, PresaveDocumentHandlerErrors, PresaveDocumentHandlerResponse, PresaveDocumentHandlerResponses, PreSaveDocumentRequest, PreSaveDocumentResponse, PreSaveDocumentResponseData, PresenceOperator, PresignedUrl, PreviewSmartTagData, PreviewSmartTagError, PreviewSmartTagErrors, PreviewSmartTagResponse, PreviewSmartTagResponses, Project, ProjectDeleteResponseData, ProjectDocumentStatus, ProjectFilters, ProjectPreview, ProjectPreviewData, PropertyDefinition, PropertyDefinitionWithOptions, PropertyFilter, PropertyInput, PropertyOption, PropertyOptionValue, PropertyOwner, PropertyValue, PutCrmTeamSettingsData, PutCrmTeamSettingsError, PutCrmTeamSettingsErrors, PutCrmTeamSettingsResponse, PutCrmTeamSettingsResponses, PutCrmTeamStagesData, PutCrmTeamStagesError, PutCrmTeamStagesErrors, PutCrmTeamStagesResponse, PutCrmTeamStagesResponses, PutFormLayoutData, PutFormLayoutError, PutFormLayoutErrors, PutFormLayoutResponse, PutFormLayoutResponses, QueryCrmPipelineRowsData, QueryCrmPipelineRowsResponse, QueryCrmPipelineRowsResponses, QueryDatabasesData, QueryDatabasesError, QueryDatabasesErrors, QueryDatabasesResponse, QueryDatabasesResponses, QueryDefinition, QuestionLayout, QuestionOption, QuestionTally, ReactionInput, RecentlyDeletedData, RecentlyDeletedError, RecentlyDeletedErrors, RecentlyDeletedResponse, RecentlyDeletedResponseData, RecentlyDeletedResponses, RegisterSlackImportUploadsData, RegisterSlackImportUploadsErrors, RegisterSlackImportUploadsResponse, RegisterSlackImportUploadsResponses, RegisterUploads, RemoveBotFromChannelByBotData, RemoveBotFromChannelByBotError, RemoveBotFromChannelByBotErrors, RemoveBotFromChannelByBotResponse, RemoveBotFromChannelByBotResponses, RemoveFavoriteByEntityData, RemoveFavoriteByEntityError, RemoveFavoriteByEntityErrors, RemoveFavoriteByEntityResponses, RemoveParticipantsData, RemoveParticipantsError, RemoveParticipantsErrors, RemoveParticipantsRequest, RemoveParticipantsResponses, RemovePinHandlerData, RemovePinHandlerError, RemovePinHandlerErrors, RemovePinHandlerResponse, RemovePinHandlerResponses, RenameChannelLabelData, RenameChannelLabelError, RenameChannelLabelErrors, RenameChannelLabelRequest, RenameChannelLabelResponse, RenameChannelLabelResponses, RenameCrmPipelineData, RenameCrmPipelineResponse, RenameCrmPipelineResponses, RenamePipeline, ReorderFavoritesData, ReorderFavoritesError, ReorderFavoritesErrors, ReorderFavoritesRequest, ReorderFavoritesResponses, ReorderPinRequest, ReorderPinsHandlerData, ReorderPinsHandlerError, ReorderPinsHandlerErrors, ReorderPinsHandlerResponse, ReorderPinsHandlerResponses, ReplaceCrmStagesRequest, RequestAccess, RequestedHarnessScope, RequestedLayout, RequestStatus, RequestToJoinData, RequestToJoinError, RequestToJoinErrors, RequestToJoinResponse, RequestToJoinResponses, ResetCrmTeamStagesData, ResetCrmTeamStagesError, ResetCrmTeamStagesErrors, ResetCrmTeamStagesResponse, ResetCrmTeamStagesResponses, ResolveRequest, ResponseStatus, ResponseSummary, ResultColumn, ResultSet, RevertDeleteDocumentData, RevertDeleteDocumentError, RevertDeleteDocumentErrors, RevertDeleteDocumentResponse, RevertDeleteDocumentResponses, RevertDeleteProjectData, RevertDeleteProjectError, RevertDeleteProjectErrors, RevertDeleteProjectResponse, RevertDeleteProjectResponses, RingStatus, RingStatusResponse, RowChange, RowChangeKind, RowChanges, RowHistoryEntry, RowHistoryResponse, RowId, RowsChange, RowsResult, S3ObjectInfo, SaveBomPart, SaveDatabaseQueryData, SaveDatabaseQueryError, SaveDatabaseQueryErrors, SaveDatabaseQueryResponse, SaveDatabaseQueryResponses, SaveDocumentHandlerData, SaveDocumentHandlerError, SaveDocumentHandlerErrors, SaveDocumentHandlerResponse, SaveDocumentHandlerResponses, SaveDocumentRequest, SaveDocumentResponse, SaveDocumentResponseData, SavedQuery, SaveQueryRequest, SearchContactsData, SearchContactsError, SearchContactsErrors, SearchContactsResponse, SearchContactsResponse2, SearchContactsResponses, SearchState, SectionCount, SessionDeletedMetadata, SessionIdentity, SessionMentionedMetadata, SessionOpenedMetadata, SessionRenamedMetadata, SessionSettledMetadata, SessionSource, SessionStoppedMetadata, SetChannelLabelData, SetChannelLabelError, SetChannelLabelErrors, SetChannelLabelRequest, SetChannelLabelResponse, SetChannelLabelResponses, SetChannelPictureData, SetChannelPictureError, SetChannelPictureErrors, SetChannelPictureRequest, SetChannelPictureResponse, SetChannelPictureResponses, SetCompanyHiddenData, SetCompanyHiddenError, SetCompanyHiddenErrors, SetCompanyHiddenRequest, SetCompanyHiddenResponse, SetCompanyHiddenResponses, SetCompanyNameRequest, SetContactHiddenData, SetContactHiddenError, SetContactHiddenErrors, SetContactHiddenRequest, SetContactHiddenResponse, SetContactHiddenResponses, SetContactNameRequest, SetCrmCompanyNameData, SetCrmCompanyNameError, SetCrmCompanyNameErrors, SetCrmCompanyNameResponse, SetCrmCompanyNameResponses, SetCrmContactNameData, SetCrmContactNameError, SetCrmContactNameErrors, SetCrmContactNameResponse, SetCrmContactNameResponses, SetDirectAccess, SetDocumentTeamShareData, SetDocumentTeamShareError, SetDocumentTeamShareErrors, SetDocumentTeamShareRequest, SetDocumentTeamShareResponse, SetDocumentTeamShareResponses, SetEmailFollowupData, SetEmailFollowupError, SetEmailFollowupErrors, SetEmailFollowupResponse, SetEmailFollowupResponses, SetEmailSyncData, SetEmailSyncError, SetEmailSyncErrors, SetEmailSyncRequest, SetEmailSyncResponse, SetEmailSyncResponses, SetOperator, SetPropertyValue, Sha256Digest, ShareCrmPipelineData, ShareCrmPipelineResponse, ShareCrmPipelineResponses, ShareDatabaseAwarenessData, ShareDatabaseAwarenessError, ShareDatabaseAwarenessErrors, ShareDatabaseAwarenessResponse, ShareDatabaseAwarenessResponses, SharedEmailFilter, ShareEntity, ShareEntityType, SharePermissionV2, SharePipeline, ShortIdResponse, SimpleMention, SimpleSaveData, SimpleSaveError, SimpleSaveErrors, SimpleSaveResponse, SimpleSaveResponses, SkippedCell, SlackCompleteRequest, SlackCreateRequest, SlackRegisterRequest, SlackTimestamp, SlackUserId, SmartTagChannelMatch, SmartTagPreview, SortDirection, SortKey, SoupAgentSessionSoupPropertiesField, SoupApiItem, SoupApiSort, SoupApiSortDirection, SoupAttachment, SoupCalendarEventSoupPropertiesField, SoupCalendarEventTime, SoupCallRecordGuest, SoupCallRecordParticipant, SoupCallRecordSoupPropertiesField, SoupChannel, SoupChannelThread, SoupChatSoupPropertiesField, SoupContact, SoupCountedReaction, SoupCrmCompanySoupPropertiesField, SoupCrmContactSoupPropertiesField, SoupCrmDomain, SoupDatabaseRowSoupPropertiesField, SoupDocumentSoupPropertiesField, SoupDocumentSubType, SoupEmailThreadPreview, SoupEnrichedEmailThreadPreviewSoupPropertiesField, SoupForeignEntity, SoupInitiativeSoupPropertiesField, SoupItem, SoupLabel, SoupLabelListVisibility, SoupLabelType, SoupMessageAttachment, SoupMessageListVisibility, SoupMessageSender, SoupMessageSenderType, SoupPage, SoupProjectSoupPropertiesField, SoupPropertiesField, SoupProperty, SoupThreadInfo, SoupThreadReply, SourceBinding, SourceId, SourceIdentity, SqlCell, SqlEntityKind, SqlOutcome, SqlOutcomeKind, SqlSelectOption, SqlStatement, StarterDatabase, StarterDocumentsResponse, StorageRow, StorageRows, StorageRowsQuery, StoredGithubPullRequest, StreamEventsData, StreamEventsError, StreamEventsErrors, StreamEventsResponse, StreamEventsResponses, String, Submission, SubmissionOutcome, SubmitFormResponseData, SubmitFormResponseError, SubmitFormResponseErrors, SubmitFormResponseResponse, SubmitFormResponseResponses, SuccessResponse, SurfaceState, SyncServiceVersionId, SystemSkillSummary, Table, TableChange, TableChanged, TableChanges, TableDetail, TableId, TableResult, TableVersion, TagFilterMode, TakenId, TallyBucket, TallyValue, TaskFilters, TeamCalendarContent, TeamCalendarCoverage, TeamCalendarDetails, TeamCalendarItem, TeamCalendarMember, TeamCalendarPage, TeamCalendarSharing, TeamOutOfOfficeItem, TeamOutOfOfficeResponse, TeamRole, TextOperator, ThreadAnchor, ThreadOrigin, ThreadPatch, ThreadState, TimelineActivity, ToggleShareWithTeamData, ToggleShareWithTeamError, ToggleShareWithTeamErrors, ToggleShareWithTeamResponse, ToggleShareWithTeamResponses, TouchedColumn, TouchedRow, TranscribeDictationData, TranscribeDictationError, TranscribeDictationErrors, TranscribeDictationResponse, TranscribeDictationResponses, TranscribeResponse, TranscriptSegmentRequest, TrashCrmPipelineData, TrashCrmPipelineResponse, TrashCrmPipelineResponses, TrashPipeline, TurnEndedMetadata, TurnStartedMetadata, TurnSummary, TypedSuccessResponse, TypedSuccessResponseGetDocumentResponseData, TypingInput, UndoChangeResponse, UndoDatabaseChangeData, UndoDatabaseChangeError, UndoDatabaseChangeErrors, UndoDatabaseChangeResponse, UndoDatabaseChangeResponses, UndoOutcome, UndoRefusal, UnlockedBooking, UpdateAgentData, UpdateAgentError, UpdateAgentErrors, UpdateAgentRequest, UpdateAgentResponse, UpdateAgentResponses, UpdateChannelSharePermission, UpdateCrmPipelinePermissionsData, UpdateCrmPipelinePermissionsResponse, UpdateCrmPipelinePermissionsResponses, UpdateCrmTeamSettingsRequest, UpdateDatabasePermissionsData, UpdateDatabasePermissionsError, UpdateDatabasePermissionsErrors, UpdateDatabasePermissionsResponse, UpdateDatabasePermissionsResponses, UpdateForm, UpdateFormData, UpdateFormError, UpdateFormErrors, UpdateFormPermissionsData, UpdateFormPermissionsError, UpdateFormPermissionsErrors, UpdateFormPermissionsResponse, UpdateFormPermissionsResponses, UpdateFormResponse, UpdateFormResponses, UpdateInitiativeData, UpdateInitiativeError, UpdateInitiativeErrors, UpdateInitiativeRequest, UpdateInitiativeResponse, UpdateInitiativeResponses, UpdateMeetingRequest, UpdateOperation, UpdateSharePermissionRequestV2, UploadDescriptor, UploadDocumentStatus, UploadExtractFolderHandlerData, UploadExtractFolderHandlerError, UploadExtractFolderHandlerErrors, UploadExtractFolderHandlerResponse, UploadExtractFolderHandlerResponses, UploadExtractFolderRequest, UploadFolderHandlerData, UploadFolderHandlerError, UploadFolderHandlerErrors, UploadFolderHandlerResponse, UploadFolderHandlerResponses, UploadFolderRequest, UploadGrant, UploadId, UpsertHistoryHandlerData, UpsertHistoryHandlerError, UpsertHistoryHandlerErrors, UpsertHistoryHandlerResponse, UpsertHistoryHandlerResponses, UpsertUserDocumentViewLocationData, UpsertUserDocumentViewLocationError, UpsertUserDocumentViewLocationErrors, UpsertUserDocumentViewLocationRequest, UpsertUserDocumentViewLocationResponse, UpsertUserDocumentViewLocationResponses, UserApiKeyId, UserApiKeyInfo, UserApiKeysList, UserDocumentsResponse, UserDocumentViewLocation, UserDocumentViewLocationResponse, UserPinsResponse, UserViewsResponse, ValidateDocumentPermissionsTokenData, ValidateDocumentPermissionsTokenError, ValidateDocumentPermissionsTokenErrors, ValidateDocumentPermissionsTokenResponse, ValidateDocumentPermissionsTokenResponses, ValidateWebhookData, ValidateWebhookError, ValidateWebhookErrors, ValidateWebhookResponse, ValidateWebhookResponse2, ValidateWebhookResponses, Vec, VersionedTable, View, ViewChange, ViewColumn, ViewerCapabilities, ViewLayout, ViewPatch, ViewPosition, ViewPositionsResponse, ViewQuery, ViewResult, ViewsResponse, WaitingForInputMetadata, Webhook, WebhookEvent, WebhookFilter, WebhookScope, WebhookStatus, WebhookValidationTestEvent, WhatsappGroupData, WhatsAppGroupDetail, WhatsAppGroupMessage, WhatsAppGroupMessages, WhatsappGroupMessagesData, WhatsappGroupMessagesResponse, WhatsappGroupMessagesResponses, WhatsappGroupPermissionsData, WhatsappGroupPermissionsResponse, WhatsappGroupPermissionsResponses, WhatsAppGroupReaction, WhatsappGroupReadData, WhatsappGroupReadResponse, WhatsappGroupReadResponses, WhatsappGroupResponse, WhatsappGroupResponses, WhatsappGroupsData, WhatsAppGroupSender, WhatsappGroupSendsData, WhatsappGroupSendsResponse, WhatsappGroupSendsResponses, WhatsappGroupsResponse, WhatsappGroupsResponses, WhatsAppGroupSummary, WhatsappGroupUpdatePermissionsData, WhatsappGroupUpdatePermissionsResponse, WhatsappGroupUpdatePermissionsResponses, Widget, WithCallId, WithChannelId, WithDocumentId, WithProjectId } from './types.gen';
diff --git a/packages/sdk/generated/storage/sdk.gen.ts b/packages/sdk/generated/storage/sdk.gen.ts
index 7a6171555c5..216fde30602 100644
--- a/packages/sdk/generated/storage/sdk.gen.ts
+++ b/packages/sdk/generated/storage/sdk.gen.ts
@@ -2,7 +2,7 @@
import { type Client, type ClientMeta, formDataBodySerializer, type Options as Options2, type RequestResult, type ServerSentEventsResult, type TDataShape } from './client';
import { client } from './client.gen';
-import type { AccessRequestsCancelData, AccessRequestsCancelErrors, AccessRequestsCancelResponses, AccessRequestsDirectData, AccessRequestsDirectErrors, AccessRequestsDirectResponses, AccessRequestsRemoveDirectData, AccessRequestsRemoveDirectErrors, AccessRequestsRemoveDirectResponses, AccessRequestsResolveData, AccessRequestsResolveErrors, AccessRequestsResolveResponses, AccessRequestsSetDirectData, AccessRequestsSetDirectErrors, AccessRequestsSetDirectResponses, AccessRequestsStateData, AccessRequestsStateErrors, AccessRequestsStateResponses, AccessRequestsSubmitData, AccessRequestsSubmitErrors, AccessRequestsSubmitResponses, AddFavoriteData, AddFavoriteErrors, AddFavoriteResponses, AddParticipantsData, AddParticipantsErrors, AddParticipantsResponses, AddPinHandlerData, AddPinHandlerErrors, AddPinHandlerResponses, ApplyCrmPipelineOpsData, ApplyCrmPipelineOpsResponses, ApplyDatabaseOpsData, ApplyDatabaseOpsErrors, ApplyDatabaseOpsResponses, ApproveHarnessPairingData, ApproveHarnessPairingErrors, ApproveHarnessPairingResponses, BulkWakeupSyncServiceDocumentsData, BulkWakeupSyncServiceDocumentsErrors, BulkWakeupSyncServiceDocumentsResponses, CallWebhookData, CallWebhookErrors, CallWebhookResponses, CancelSlackImportData, CancelSlackImportErrors, CancelSlackImportResponses, CheckActiveCallData, CheckActiveCallErrors, CheckActiveCallResponses, ClaimHarnessPairingData, ClaimHarnessPairingErrors, ClaimHarnessPairingResponses, CollaborateFormData, CollaborateFormErrors, CollaborateFormResponses, CompleteSlackImportUploadsData, CompleteSlackImportUploadsErrors, CompleteSlackImportUploadsResponses, ConvertDatabaseColumnData, ConvertDatabaseColumnErrors, ConvertDatabaseColumnResponses, CopyDocumentData, CopyDocumentErrors, CopyDocumentResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateAnchorData, CreateAnchorErrors, CreateAnchorResponses, CreateCanvasHandlerData, CreateCanvasHandlerErrors, CreateCanvasHandlerResponses, CreateChannelData, CreateChannelErrors, CreateChannelLabelData, CreateChannelLabelErrors, CreateChannelLabelResponses, CreateChannelResponses, CreateChannelScopedBotData, CreateChannelScopedBotErrors, CreateChannelScopedBotResponses, CreateCollabSurfaceTokenData, CreateCollabSurfaceTokenErrors, CreateCollabSurfaceTokenResponses, CreateCrmCompanyData, CreateCrmCompanyErrors, CreateCrmCompanyResponses, CreateCrmContactData, CreateCrmContactErrors, CreateCrmContactResponses, CreateCrmPipelineData, CreateCrmPipelineResponses, CreateDatabaseData, CreateDatabaseErrors, CreateDatabaseResponses, CreateDatabaseWebhookData, CreateDatabaseWebhookErrors, CreateDatabaseWebhookResponses, CreateDocumentData, CreateDocumentErrors, CreateDocumentResponses, CreateEntityMentionData, CreateEntityMentionErrors, CreateEntityMentionResponses, CreateFormData, CreateFormErrors, CreateFormResponses, CreateHarnessPairingData, CreateHarnessPairingErrors, CreateHarnessPairingResponses, CreateInitiativeData, CreateInitiativeErrors, CreateInitiativeResponses, CreateInstructionsHandlerData, CreateInstructionsHandlerErrors, CreateInstructionsHandlerResponses, CreateMarkdownHandlerData, CreateMarkdownHandlerErrors, CreateMarkdownHandlerResponses, CreateProjectHandlerData, CreateProjectHandlerErrors, CreateProjectHandlerResponses, CreateSkillHandlerData, CreateSkillHandlerErrors, CreateSkillHandlerResponses, CreateSlackImportData, CreateSlackImportErrors, CreateSlackImportResponses, CreateSnippetHandlerData, CreateSnippetHandlerErrors, CreateSnippetHandlerResponses, CreateTaskHandlerData, CreateTaskHandlerErrors, CreateTaskHandlerResponses, CreateUserApiKeyData, CreateUserApiKeyErrors, CreateUserApiKeyResponses, CreateViewHandlerData, CreateViewHandlerErrors, CreateViewHandlerResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookResponses, DeclineCallData, DeclineCallErrors, DeclineCallResponses, DeclineRingData, DeclineRingErrors, DeclineRingResponses, DeleteAnchorData, DeleteAnchorErrors, DeleteAnchorResponses, DeleteCallRecordData, DeleteCallRecordErrors, DeleteCallRecordResponses, DeleteChannelData, DeleteChannelErrors, DeleteChannelLabelData, DeleteChannelLabelErrors, DeleteChannelLabelResponses, DeleteChannelResponses, DeleteCollabSurfaceData, DeleteCollabSurfaceErrors, DeleteCollabSurfaceResponses, DeleteDatabaseWebhookData, DeleteDatabaseWebhookErrors, DeleteDatabaseWebhookResponses, DeleteDocumentData, DeleteDocumentErrors, DeleteDocumentResponses, DeleteEntityMentionData, DeleteEntityMentionErrors, DeleteEntityMentionResponses, DeleteHarnessData, DeleteHarnessErrors, DeleteHarnessResponses, DeleteHistoryHandlerData, DeleteHistoryHandlerErrors, DeleteHistoryHandlerResponses, DeleteInitiativeData, DeleteInitiativeErrors, DeleteInitiativeResponses, DeleteProjectHandlerData, DeleteProjectHandlerErrors, DeleteProjectHandlerResponses, DeleteSelfHarnessData, DeleteSelfHarnessErrors, DeleteSelfHarnessResponses, DeleteUserApiKeyData, DeleteUserApiKeyErrors, DeleteUserApiKeyResponses, DeleteUserDocumentViewLocationData, DeleteUserDocumentViewLocationErrors, DeleteUserDocumentViewLocationResponses, DeleteViewHandlerData, DeleteViewHandlerErrors, DeleteViewHandlerResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponses, DeliverDatabaseWebhookData, DeliverDatabaseWebhookErrors, DeliverDatabaseWebhookResponses, EditAnchorData, EditAnchorErrors, EditAnchorResponses, EditCallRecordData, EditCallRecordErrors, EditCallRecordResponses, EditCallTranscriptData, EditCallTranscriptErrors, EditCallTranscriptResponses, EditDocumentData, EditDocumentErrors, EditDocumentResponses, EditMyFormResponseData, EditMyFormResponseErrors, EditMyFormResponseResponses, EditProjectV2Data, EditProjectV2Errors, EditProjectV2Responses, EditThreadV2Data, EditThreadV2Errors, EditThreadV2Responses, EnsureCollabSurfaceData, EnsureCollabSurfaceErrors, EnsureCollabSurfaceResponses, EnsureStarterHandlerData, EnsureStarterHandlerErrors, EnsureStarterHandlerResponses, EntityMessageCreateData, EntityMessageCreateResponses, EntityMessageDeleteMessageData, EntityMessageDeleteMessageResponses, EntityMessageDeleteThreadData, EntityMessageDeleteThreadResponses, EntityMessageEditData, EntityMessageEditResponses, EntityMessageGetMessageData, EntityMessageGetMessageResponses, EntityMessageGetThreadData, EntityMessageGetThreadResponses, EntityMessageLegacyData, EntityMessageLegacyResponses, EntityMessagePatchThreadData, EntityMessagePatchThreadResponses, EntityMessageReactData, EntityMessageReactResponses, EntityMessageTypingData, EntityMessageTypingResponses, EventIcsData, EventIcsErrors, EventIcsResponses, ExcludeDefaultViewHandlerData, ExcludeDefaultViewHandlerErrors, ExcludeDefaultViewHandlerResponses, ExportDocumentData, ExportDocumentErrors, ExportDocumentResponses, FinalizeSlackImportData, FinalizeSlackImportErrors, FinalizeSlackImportResponses, GetActiveCallsData, GetActiveCallsErrors, GetActiveCallsResponses, GetActivityData, GetActivityErrors, GetActivityResponses, GetAttachmentReferencesData, GetAttachmentReferencesErrors, GetAttachmentReferencesResponses, GetBatchCallRecordPreviewData, GetBatchCallRecordPreviewErrors, GetBatchCallRecordPreviewResponses, GetBatchChannelPreviewData, GetBatchChannelPreviewErrors, GetBatchChannelPreviewResponses, GetBatchPreviewHandlerData, GetBatchPreviewHandlerErrors, GetBatchPreviewHandlerResponses, GetBatchProjectPreviewData, GetBatchProjectPreviewErrors, GetBatchProjectPreviewResponses, GetBotOwnerProfilesData, GetBotOwnerProfilesErrors, GetBotOwnerProfilesResponses, GetCallRecordData, GetCallRecordErrors, GetCallRecordResponses, GetChannelAttachmentsData, GetChannelAttachmentsErrors, GetChannelAttachmentsResponses, GetChannelData, GetChannelErrors, GetChannelJoinLinkData, GetChannelJoinLinkErrors, GetChannelJoinLinkResponses, GetChannelParticipantsData, GetChannelParticipantsErrors, GetChannelParticipantsResponses, GetChannelResponses, GetChannelsData, GetChannelsErrors, GetChannelsResponses, GetCollabSurfaceData, GetCollabSurfaceErrors, GetCollabSurfaceResponses, GetCompanyData, GetCompanyErrors, GetCompanyResponses, GetContactByEmailData, GetContactByEmailErrors, GetContactByEmailResponses, GetContactData, GetContactErrors, GetContactResponses, GetCrmPipelineData, GetCrmPipelinePermissionsData, GetCrmPipelinePermissionsResponses, GetCrmPipelineResponses, GetCrmPipelineRowsData, GetCrmPipelineRowsResponses, GetCrmPipelineTableData, GetCrmPipelineTableResponses, GetCrmTeamSettingsData, GetCrmTeamSettingsErrors, GetCrmTeamSettingsResponses, GetDatabaseData, GetDatabaseErrors, GetDatabasePermissionsData, GetDatabasePermissionsErrors, GetDatabasePermissionsResponses, GetDatabaseQueryData, GetDatabaseQueryErrors, GetDatabaseQueryResponses, GetDatabaseResponses, GetDatabaseRowHistoryData, GetDatabaseRowHistoryErrors, GetDatabaseRowHistoryResponses, GetDatabaseTableChangesData, GetDatabaseTableChangesErrors, GetDatabaseTableChangesResponses, GetDatabaseViewPositionsData, GetDatabaseViewPositionsErrors, GetDatabaseViewPositionsResponses, GetDocumentAnchorsData, GetDocumentAnchorsErrors, GetDocumentAnchorsResponses, GetDocumentBranchNameData, GetDocumentBranchNameErrors, GetDocumentBranchNameResponses, GetDocumentByTeamSlugData, GetDocumentByTeamSlugErrors, GetDocumentByTeamSlugResponses, GetDocumentData, GetDocumentErrors, GetDocumentGithubPullRequestsData, GetDocumentGithubPullRequestsErrors, GetDocumentGithubPullRequestsResponses, GetDocumentListHandlerData, GetDocumentListHandlerErrors, GetDocumentListHandlerResponses, GetDocumentLocationV3Data, GetDocumentLocationV3Errors, GetDocumentLocationV3Responses, GetDocumentPermissionsTokenData, GetDocumentPermissionsTokenErrors, GetDocumentPermissionsTokenResponses, GetDocumentPermissionsV2Data, GetDocumentPermissionsV2Errors, GetDocumentPermissionsV2Responses, GetDocumentProcessingResultData, GetDocumentProcessingResultErrors, GetDocumentProcessingResultResponses, GetDocumentResponses, GetDocumentShortIdData, GetDocumentShortIdErrors, GetDocumentShortIdResponses, GetDocumentTeamShareData, GetDocumentTeamShareErrors, GetDocumentTeamShareResponses, GetDocumentTextContentData, GetDocumentTextContentErrors, GetDocumentTextContentResponses, GetDocumentVersionData, GetDocumentVersionErrors, GetDocumentVersionResponses, GetDocumentViewsHandlerData, GetDocumentViewsHandlerErrors, GetDocumentViewsHandlerResponses, GetEmailFollowupData, GetEmailFollowupErrors, GetEmailFollowupResponses, GetEntityPermissionData, GetEntityPermissionErrors, GetEntityPermissionResponses, GetForeignEntityBySourceData, GetForeignEntityBySourceErrors, GetForeignEntityBySourceResponses, GetForeignEntityData, GetForeignEntityErrors, GetForeignEntityResponses, GetFormData, GetFormErrors, GetFormPermissionsData, GetFormPermissionsErrors, GetFormPermissionsResponses, GetFormResponses, GetFormResponseSummaryData, GetFormResponseSummaryErrors, GetFormResponseSummaryResponses, GetFormTallyData, GetFormTallyErrors, GetFormTallyResponses, GetGithubPullRequestChangesData, GetGithubPullRequestChangesErrors, GetGithubPullRequestChangesPatchData, GetGithubPullRequestChangesPatchErrors, GetGithubPullRequestChangesPatchResponses, GetGithubPullRequestChangesResponses, GetGithubPullRequestData, GetGithubPullRequestErrors, GetGithubPullRequestFacetsData, GetGithubPullRequestFacetsErrors, GetGithubPullRequestFacetsResponses, GetGithubPullRequestResponses, GetGithubPullRequestTasksData, GetGithubPullRequestTasksErrors, GetGithubPullRequestTasksResponses, GetHarnessPairingData, GetHarnessPairingErrors, GetHarnessPairingResponses, GetHistoryHandlerData, GetHistoryHandlerErrors, GetHistoryHandlerResponses, GetInitiativeData, GetInitiativeErrors, GetInitiativeResponses, GetInstructionsHandlerData, GetInstructionsHandlerErrors, GetInstructionsHandlerResponses, GetItemsSoupData, GetItemsSoupErrors, GetItemsSoupResponses, GetLocationHandlerData, GetLocationHandlerErrors, GetLocationHandlerResponses, GetMyFormResponseData, GetMyFormResponseErrors, GetMyFormResponseResponses, GetOrCreateCallData, GetOrCreateCallErrors, GetOrCreateCallResponses, GetOrCreateDmData, GetOrCreateDmErrors, GetOrCreateDmResponses, GetOrCreatePrivateData, GetOrCreatePrivateErrors, GetOrCreatePrivateResponses, GetPendingProjectsHandlerData, GetPendingProjectsHandlerErrors, GetPendingProjectsHandlerResponses, GetPinsHandlerData, GetPinsHandlerErrors, GetPinsHandlerResponses, GetProjectContentHandlerData, GetProjectContentHandlerErrors, GetProjectContentHandlerResponses, GetProjectHandlerData, GetProjectHandlerErrors, GetProjectHandlerResponses, GetProjectPermissionsV2Data, GetProjectPermissionsV2Errors, GetProjectPermissionsV2Responses, GetProjectsHandlerData, GetProjectsHandlerErrors, GetProjectsHandlerResponses, GetProjectUserAccessLevelData, GetProjectUserAccessLevelErrors, GetProjectUserAccessLevelResponses, GetRingStatusData, GetRingStatusErrors, GetRingStatusResponses, GetSelfBotData, GetSelfBotErrors, GetSelfBotResponses, GetSelfHarnessData, GetSelfHarnessErrors, GetSelfHarnessResponses, GetSlackImportData, GetSlackImportErrors, GetSlackImportResponses, GetSystemSkillsHandlerData, GetSystemSkillsHandlerErrors, GetSystemSkillsHandlerResponses, GetUserDocumentsHandlerData, GetUserDocumentsHandlerErrors, GetUserDocumentsHandlerResponses, GetUserDocumentViewLocationData, GetUserDocumentViewLocationErrors, GetUserDocumentViewLocationResponses, GetViewsHandlerData, GetViewsHandlerErrors, GetViewsHandlerResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponses, GuestCallChatPostData, GuestCallChatPostErrors, GuestCallChatPostResponses, GuestCallChatReadData, GuestCallChatReadErrors, GuestCallChatReadResponses, HandlerData, HandlerErrors, HandlerResponses, HealthHandlerData, HealthHandlerResponses, ImportDatabaseTableData, ImportDatabaseTableErrors, ImportDatabaseTableResponses, InferDatabaseColumnTypeData, InferDatabaseColumnTypeErrors, InferDatabaseColumnTypeResponses, IngestTranscriptData, IngestTranscriptErrors, IngestTranscriptResponses, InitializeUserDocumentsData, InitializeUserDocumentsErrors, InitializeUserDocumentsResponses, InstallSyncData, InstallSyncErrors, JobProcessingResultHandlerData, JobProcessingResultHandlerErrors, JobProcessingResultHandlerResponses, JoinChannelByCodeData, JoinChannelByCodeErrors, JoinChannelByCodeResponses, JoinChannelData, JoinChannelErrors, JoinChannelResponses, LeaveChannelData, LeaveChannelErrors, LeaveChannelResponses, LeaveOrEndCallData, LeaveOrEndCallErrors, LeaveOrEndCallResponses, LinkedAccountData, LinkedAccountResponses, LinkedAdoptData, LinkedAdoptResponses, LinkedCancelPairingData, LinkedCancelPairingResponses, LinkedConfigurationData, LinkedConfigurationResponses, LinkedConnectData, LinkedConnectResponses, LinkedDeliveryData, LinkedDeliveryResponses, LinkedDetachData, LinkedDetachResponses, LinkedDisconnectData, LinkedDisconnectResponses, LinkedGroupsData, LinkedGroupsResponses, LinkedMessageAttachmentsData, LinkedMessageAttachmentsResponses, LinkedPairingData, LinkedPairingResponses, LinkedPasskeyData, LinkedPasskeyResponses, LinkedReplyData, LinkedReplyErrors, LinkedReplyResponses, LinkedUploadData, LinkedUploadResponses, ListAccessibleFormsData, ListAccessibleFormsErrors, ListAccessibleFormsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponses, ListBotChannelsData, ListBotChannelsErrors, ListBotChannelsResponses, ListChannelLabelsData, ListChannelLabelsErrors, ListChannelLabelsResponses, ListCompanyContactsData, ListCompanyContactsErrors, ListCompanyContactsResponses, ListCrmPipelinesData, ListCrmPipelinesResponses, ListDatabaseColumnCastsData, ListDatabaseColumnCastsErrors, ListDatabaseColumnCastsResponses, ListDatabasesData, ListDatabasesErrors, ListDatabasesResponses, ListDatabaseWebhooksData, ListDatabaseWebhooksErrors, ListDatabaseWebhooksResponses, ListEmailRemindersData, ListEmailRemindersErrors, ListEmailRemindersResponses, ListFavoritesData, ListFavoritesErrors, ListFavoritesResponses, ListFormsData, ListFormsErrors, ListFormsResponses, ListHarnessAgentsData, ListHarnessAgentsErrors, ListHarnessAgentsResponses, ListHarnessesData, ListHarnessesErrors, ListHarnessesResponses, ListHarnessSessionsData, ListHarnessSessionsErrors, ListHarnessSessionsResponses, ListInitiativesData, ListInitiativesErrors, ListInitiativesResponses, ListJoinRequestsData, ListJoinRequestsErrors, ListJoinRequestsResponses, ListOccurrencesData, ListOccurrencesErrors, ListOccurrencesResponses, ListSlackImportsData, ListSlackImportsResponses, ListTeamCalendarData, ListTeamCalendarResponses, ListTeamOutOfOfficeData, ListTeamOutOfOfficeErrors, ListTeamOutOfOfficeResponses, ListUserApiKeysData, ListUserApiKeysErrors, ListUserApiKeysResponses, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponses, MeetingCancelData, MeetingCancelErrors, MeetingCancelPreparationData, MeetingCancelPreparationErrors, MeetingCancelPreparationResponses, MeetingCancelResponses, MeetingCreateData, MeetingCreateErrors, MeetingCreateResponses, MeetingGuestJoinData, MeetingGuestJoinErrors, MeetingGuestJoinResponses, MeetingGuestParticipantsData, MeetingGuestParticipantsErrors, MeetingGuestParticipantsResponses, MeetingInviteData, MeetingInviteErrors, MeetingInvitePermissionsData, MeetingInvitePermissionsErrors, MeetingInvitePermissionsResponses, MeetingInviteResponses, MeetingInviteUsersData, MeetingInviteUsersErrors, MeetingInviteUsersResponses, MeetingJoinData, MeetingJoinErrors, MeetingJoinResponses, MeetingLeaveData, MeetingLeaveErrors, MeetingLeaveResponses, MeetingListActiveData, MeetingListActiveErrors, MeetingListActiveResponses, MeetingListData, MeetingListErrors, MeetingListResponses, MeetingLookupData, MeetingLookupErrors, MeetingLookupResponses, MeetingParticipantsData, MeetingParticipantsErrors, MeetingParticipantsResponses, MeetingPrepareData, MeetingPrepareErrors, MeetingPrepareResponses, MeetingShareData, MeetingShareErrors, MeetingShareResponses, MeetingUpdateData, MeetingUpdateErrors, MeetingUpdateResponses, MentionPreviewsData, MentionPreviewsErrors, MentionPreviewsResponses, MessageTimelineData, MessageTimelineEntriesData, MessageTimelineEntriesResponses, MessageTimelineResponses, PatchChannelData, PatchChannelErrors, PatchChannelResponses, PatchViewHandlerData, PatchViewHandlerErrors, PatchViewHandlerResponses, PatchWebhookData, PatchWebhookErrors, PatchWebhookResponses, PermanentlyDeleteDocumentData, PermanentlyDeleteDocumentErrors, PermanentlyDeleteDocumentResponses, PermanentlyDeleteProjectData, PermanentlyDeleteProjectErrors, PermanentlyDeleteProjectResponses, PostActivityData, PostActivityErrors, PostActivityResponses, PostChannelBotWebhookData, PostChannelBotWebhookErrors, PostChannelBotWebhookResponses, PostItemsSoupAstData, PostItemsSoupAstErrors, PostItemsSoupAstGroupedData, PostItemsSoupAstGroupedErrors, PostItemsSoupAstGroupedResponses, PostItemsSoupAstResponses, PostItemsSoupData, PostItemsSoupErrors, PostItemsSoupResponses, PresaveDocumentHandlerData, PresaveDocumentHandlerErrors, PresaveDocumentHandlerResponses, PreviewSmartTagData, PreviewSmartTagErrors, PreviewSmartTagResponses, PutCrmTeamSettingsData, PutCrmTeamSettingsErrors, PutCrmTeamSettingsResponses, PutCrmTeamStagesData, PutCrmTeamStagesErrors, PutCrmTeamStagesResponses, PutFormLayoutData, PutFormLayoutErrors, PutFormLayoutResponses, QueryCrmPipelineRowsData, QueryCrmPipelineRowsResponses, QueryDatabasesData, QueryDatabasesErrors, QueryDatabasesResponses, RecentlyDeletedData, RecentlyDeletedErrors, RecentlyDeletedResponses, RegisterSlackImportUploadsData, RegisterSlackImportUploadsErrors, RegisterSlackImportUploadsResponses, RemoveBotFromChannelByBotData, RemoveBotFromChannelByBotErrors, RemoveBotFromChannelByBotResponses, RemoveFavoriteByEntityData, RemoveFavoriteByEntityErrors, RemoveFavoriteByEntityResponses, RemoveParticipantsData, RemoveParticipantsErrors, RemoveParticipantsResponses, RemovePinHandlerData, RemovePinHandlerErrors, RemovePinHandlerResponses, RenameChannelLabelData, RenameChannelLabelErrors, RenameChannelLabelResponses, RenameCrmPipelineData, RenameCrmPipelineResponses, ReorderFavoritesData, ReorderFavoritesErrors, ReorderFavoritesResponses, ReorderPinsHandlerData, ReorderPinsHandlerErrors, ReorderPinsHandlerResponses, RequestToJoinData, RequestToJoinErrors, RequestToJoinResponses, ResetCrmTeamStagesData, ResetCrmTeamStagesErrors, ResetCrmTeamStagesResponses, RevertDeleteDocumentData, RevertDeleteDocumentErrors, RevertDeleteDocumentResponses, RevertDeleteProjectData, RevertDeleteProjectErrors, RevertDeleteProjectResponses, SaveDatabaseQueryData, SaveDatabaseQueryErrors, SaveDatabaseQueryResponses, SaveDocumentHandlerData, SaveDocumentHandlerErrors, SaveDocumentHandlerResponses, SearchContactsData, SearchContactsErrors, SearchContactsResponses, SetChannelLabelData, SetChannelLabelErrors, SetChannelLabelResponses, SetChannelPictureData, SetChannelPictureErrors, SetChannelPictureResponses, SetCompanyHiddenData, SetCompanyHiddenErrors, SetCompanyHiddenResponses, SetContactHiddenData, SetContactHiddenErrors, SetContactHiddenResponses, SetCrmCompanyNameData, SetCrmCompanyNameErrors, SetCrmCompanyNameResponses, SetCrmContactNameData, SetCrmContactNameErrors, SetCrmContactNameResponses, SetDocumentTeamShareData, SetDocumentTeamShareErrors, SetDocumentTeamShareResponses, SetEmailFollowupData, SetEmailFollowupErrors, SetEmailFollowupResponses, SetEmailSyncData, SetEmailSyncErrors, SetEmailSyncResponses, ShareCrmPipelineData, ShareCrmPipelineResponses, ShareDatabaseAwarenessData, ShareDatabaseAwarenessErrors, ShareDatabaseAwarenessResponses, SimpleSaveData, SimpleSaveErrors, SimpleSaveResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponse, StreamEventsResponses, SubmitFormResponseData, SubmitFormResponseErrors, SubmitFormResponseResponses, ToggleShareWithTeamData, ToggleShareWithTeamErrors, ToggleShareWithTeamResponses, TranscribeDictationData, TranscribeDictationErrors, TranscribeDictationResponses, TrashCrmPipelineData, TrashCrmPipelineResponses, UndoDatabaseChangeData, UndoDatabaseChangeErrors, UndoDatabaseChangeResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateCrmPipelinePermissionsData, UpdateCrmPipelinePermissionsResponses, UpdateDatabasePermissionsData, UpdateDatabasePermissionsErrors, UpdateDatabasePermissionsResponses, UpdateFormData, UpdateFormErrors, UpdateFormPermissionsData, UpdateFormPermissionsErrors, UpdateFormPermissionsResponses, UpdateFormResponses, UpdateInitiativeData, UpdateInitiativeErrors, UpdateInitiativeResponses, UploadExtractFolderHandlerData, UploadExtractFolderHandlerErrors, UploadExtractFolderHandlerResponses, UploadFolderHandlerData, UploadFolderHandlerErrors, UploadFolderHandlerResponses, UpsertHistoryHandlerData, UpsertHistoryHandlerErrors, UpsertHistoryHandlerResponses, UpsertUserDocumentViewLocationData, UpsertUserDocumentViewLocationErrors, UpsertUserDocumentViewLocationResponses, ValidateDocumentPermissionsTokenData, ValidateDocumentPermissionsTokenErrors, ValidateDocumentPermissionsTokenResponses, ValidateWebhookData, ValidateWebhookErrors, ValidateWebhookResponses, WhatsappGroupData, WhatsappGroupMessagesData, WhatsappGroupMessagesResponses, WhatsappGroupPermissionsData, WhatsappGroupPermissionsResponses, WhatsappGroupReadData, WhatsappGroupReadResponses, WhatsappGroupResponses, WhatsappGroupsData, WhatsappGroupSendsData, WhatsappGroupSendsResponses, WhatsappGroupsResponses, WhatsappGroupUpdatePermissionsData, WhatsappGroupUpdatePermissionsResponses } from './types.gen';
+import type { AccessRequestsCancelData, AccessRequestsCancelErrors, AccessRequestsCancelResponses, AccessRequestsDirectData, AccessRequestsDirectErrors, AccessRequestsDirectResponses, AccessRequestsRemoveDirectData, AccessRequestsRemoveDirectErrors, AccessRequestsRemoveDirectResponses, AccessRequestsResolveData, AccessRequestsResolveErrors, AccessRequestsResolveResponses, AccessRequestsSetDirectData, AccessRequestsSetDirectErrors, AccessRequestsSetDirectResponses, AccessRequestsStateData, AccessRequestsStateErrors, AccessRequestsStateResponses, AccessRequestsSubmitData, AccessRequestsSubmitErrors, AccessRequestsSubmitResponses, AddFavoriteData, AddFavoriteErrors, AddFavoriteResponses, AddParticipantsData, AddParticipantsErrors, AddParticipantsResponses, AddPinHandlerData, AddPinHandlerErrors, AddPinHandlerResponses, ApplyCrmPipelineOpsData, ApplyCrmPipelineOpsResponses, ApplyDatabaseOpsData, ApplyDatabaseOpsErrors, ApplyDatabaseOpsResponses, ApproveHarnessPairingData, ApproveHarnessPairingErrors, ApproveHarnessPairingResponses, BulkWakeupSyncServiceDocumentsData, BulkWakeupSyncServiceDocumentsErrors, BulkWakeupSyncServiceDocumentsResponses, CallWebhookData, CallWebhookErrors, CallWebhookResponses, CancelSlackImportData, CancelSlackImportErrors, CancelSlackImportResponses, CheckActiveCallData, CheckActiveCallErrors, CheckActiveCallResponses, ClaimHarnessPairingData, ClaimHarnessPairingErrors, ClaimHarnessPairingResponses, CollaborateFormData, CollaborateFormErrors, CollaborateFormResponses, CompleteSlackImportUploadsData, CompleteSlackImportUploadsErrors, CompleteSlackImportUploadsResponses, ConvertDatabaseColumnData, ConvertDatabaseColumnErrors, ConvertDatabaseColumnResponses, CopyDocumentData, CopyDocumentErrors, CopyDocumentResponses, CreateAgentData, CreateAgentErrors, CreateAgentResponses, CreateAnchorData, CreateAnchorErrors, CreateAnchorResponses, CreateCanvasHandlerData, CreateCanvasHandlerErrors, CreateCanvasHandlerResponses, CreateChannelData, CreateChannelErrors, CreateChannelLabelData, CreateChannelLabelErrors, CreateChannelLabelResponses, CreateChannelResponses, CreateChannelScopedBotData, CreateChannelScopedBotErrors, CreateChannelScopedBotResponses, CreateCollabSurfaceTokenData, CreateCollabSurfaceTokenErrors, CreateCollabSurfaceTokenResponses, CreateCrmCompanyData, CreateCrmCompanyErrors, CreateCrmCompanyResponses, CreateCrmContactData, CreateCrmContactErrors, CreateCrmContactResponses, CreateCrmPipelineData, CreateCrmPipelineResponses, CreateDatabaseData, CreateDatabaseErrors, CreateDatabaseResponses, CreateDatabaseWebhookData, CreateDatabaseWebhookErrors, CreateDatabaseWebhookResponses, CreateDocumentData, CreateDocumentErrors, CreateDocumentResponses, CreateEntityMentionData, CreateEntityMentionErrors, CreateEntityMentionResponses, CreateFormData, CreateFormErrors, CreateFormResponses, CreateHarnessPairingData, CreateHarnessPairingErrors, CreateHarnessPairingResponses, CreateInitiativeData, CreateInitiativeErrors, CreateInitiativeResponses, CreateInstructionsHandlerData, CreateInstructionsHandlerErrors, CreateInstructionsHandlerResponses, CreateMarkdownHandlerData, CreateMarkdownHandlerErrors, CreateMarkdownHandlerResponses, CreateProjectHandlerData, CreateProjectHandlerErrors, CreateProjectHandlerResponses, CreateSkillHandlerData, CreateSkillHandlerErrors, CreateSkillHandlerResponses, CreateSlackImportData, CreateSlackImportErrors, CreateSlackImportResponses, CreateSnippetHandlerData, CreateSnippetHandlerErrors, CreateSnippetHandlerResponses, CreateTaskHandlerData, CreateTaskHandlerErrors, CreateTaskHandlerResponses, CreateUserApiKeyData, CreateUserApiKeyErrors, CreateUserApiKeyResponses, CreateViewHandlerData, CreateViewHandlerErrors, CreateViewHandlerResponses, CreateWebhookData, CreateWebhookErrors, CreateWebhookResponses, DeclineCallData, DeclineCallErrors, DeclineCallResponses, DeclineRingData, DeclineRingErrors, DeclineRingResponses, DeleteAnchorData, DeleteAnchorErrors, DeleteAnchorResponses, DeleteCallRecordData, DeleteCallRecordErrors, DeleteCallRecordResponses, DeleteChannelData, DeleteChannelErrors, DeleteChannelLabelData, DeleteChannelLabelErrors, DeleteChannelLabelResponses, DeleteChannelResponses, DeleteCollabSurfaceData, DeleteCollabSurfaceErrors, DeleteCollabSurfaceResponses, DeleteDatabaseWebhookData, DeleteDatabaseWebhookErrors, DeleteDatabaseWebhookResponses, DeleteDocumentData, DeleteDocumentErrors, DeleteDocumentResponses, DeleteEntityMentionData, DeleteEntityMentionErrors, DeleteEntityMentionResponses, DeleteHarnessData, DeleteHarnessErrors, DeleteHarnessResponses, DeleteHistoryHandlerData, DeleteHistoryHandlerErrors, DeleteHistoryHandlerResponses, DeleteInitiativeData, DeleteInitiativeErrors, DeleteInitiativeResponses, DeleteProjectHandlerData, DeleteProjectHandlerErrors, DeleteProjectHandlerResponses, DeleteSelfHarnessData, DeleteSelfHarnessErrors, DeleteSelfHarnessResponses, DeleteUserApiKeyData, DeleteUserApiKeyErrors, DeleteUserApiKeyResponses, DeleteUserDocumentViewLocationData, DeleteUserDocumentViewLocationErrors, DeleteUserDocumentViewLocationResponses, DeleteViewHandlerData, DeleteViewHandlerErrors, DeleteViewHandlerResponses, DeleteWebhookData, DeleteWebhookErrors, DeleteWebhookResponses, DeliverDatabaseWebhookData, DeliverDatabaseWebhookErrors, DeliverDatabaseWebhookResponses, EditAnchorData, EditAnchorErrors, EditAnchorResponses, EditCallRecordData, EditCallRecordErrors, EditCallRecordResponses, EditCallTranscriptData, EditCallTranscriptErrors, EditCallTranscriptResponses, EditDocumentData, EditDocumentErrors, EditDocumentResponses, EditMyFormResponseData, EditMyFormResponseErrors, EditMyFormResponseResponses, EditProjectV2Data, EditProjectV2Errors, EditProjectV2Responses, EditThreadV2Data, EditThreadV2Errors, EditThreadV2Responses, EnsureCollabSurfaceData, EnsureCollabSurfaceErrors, EnsureCollabSurfaceResponses, EnsureStarterHandlerData, EnsureStarterHandlerErrors, EnsureStarterHandlerResponses, EntityMessageCreateData, EntityMessageCreateResponses, EntityMessageDeleteMessageData, EntityMessageDeleteMessageResponses, EntityMessageDeleteThreadData, EntityMessageDeleteThreadResponses, EntityMessageEditData, EntityMessageEditResponses, EntityMessageGetMessageData, EntityMessageGetMessageResponses, EntityMessageGetThreadData, EntityMessageGetThreadResponses, EntityMessageLegacyData, EntityMessageLegacyResponses, EntityMessagePatchThreadData, EntityMessagePatchThreadResponses, EntityMessageReactData, EntityMessageReactResponses, EntityMessageTypingData, EntityMessageTypingResponses, EventIcsData, EventIcsErrors, EventIcsResponses, ExcludeDefaultViewHandlerData, ExcludeDefaultViewHandlerErrors, ExcludeDefaultViewHandlerResponses, ExportDocumentData, ExportDocumentErrors, ExportDocumentResponses, FinalizeSlackImportData, FinalizeSlackImportErrors, FinalizeSlackImportResponses, GetActiveCallsData, GetActiveCallsErrors, GetActiveCallsResponses, GetActivityData, GetActivityErrors, GetActivityResponses, GetAttachmentReferencesData, GetAttachmentReferencesErrors, GetAttachmentReferencesResponses, GetBatchCallRecordPreviewData, GetBatchCallRecordPreviewErrors, GetBatchCallRecordPreviewResponses, GetBatchChannelPreviewData, GetBatchChannelPreviewErrors, GetBatchChannelPreviewResponses, GetBatchPreviewHandlerData, GetBatchPreviewHandlerErrors, GetBatchPreviewHandlerResponses, GetBatchProjectPreviewData, GetBatchProjectPreviewErrors, GetBatchProjectPreviewResponses, GetBotOwnerProfilesData, GetBotOwnerProfilesErrors, GetBotOwnerProfilesResponses, GetCallRecordData, GetCallRecordErrors, GetCallRecordResponses, GetChannelAttachmentsData, GetChannelAttachmentsErrors, GetChannelAttachmentsResponses, GetChannelData, GetChannelErrors, GetChannelJoinLinkData, GetChannelJoinLinkErrors, GetChannelJoinLinkResponses, GetChannelParticipantsData, GetChannelParticipantsErrors, GetChannelParticipantsResponses, GetChannelResponses, GetChannelsData, GetChannelsErrors, GetChannelsResponses, GetCollabSurfaceData, GetCollabSurfaceErrors, GetCollabSurfaceResponses, GetCompanyData, GetCompanyErrors, GetCompanyResponses, GetContactByEmailData, GetContactByEmailErrors, GetContactByEmailResponses, GetContactData, GetContactErrors, GetContactResponses, GetCrmPipelineData, GetCrmPipelinePermissionsData, GetCrmPipelinePermissionsResponses, GetCrmPipelineResponses, GetCrmPipelineRowsData, GetCrmPipelineRowsResponses, GetCrmPipelineTableData, GetCrmPipelineTableResponses, GetCrmTeamSettingsData, GetCrmTeamSettingsErrors, GetCrmTeamSettingsResponses, GetDatabaseData, GetDatabaseErrors, GetDatabasePermissionsData, GetDatabasePermissionsErrors, GetDatabasePermissionsResponses, GetDatabaseQueryData, GetDatabaseQueryErrors, GetDatabaseQueryResponses, GetDatabaseResponses, GetDatabaseRowHistoryData, GetDatabaseRowHistoryErrors, GetDatabaseRowHistoryResponses, GetDatabaseTableChangesData, GetDatabaseTableChangesErrors, GetDatabaseTableChangesResponses, GetDatabaseViewPositionsData, GetDatabaseViewPositionsErrors, GetDatabaseViewPositionsResponses, GetDocumentAnchorsData, GetDocumentAnchorsErrors, GetDocumentAnchorsResponses, GetDocumentBranchNameData, GetDocumentBranchNameErrors, GetDocumentBranchNameResponses, GetDocumentByTeamSlugData, GetDocumentByTeamSlugErrors, GetDocumentByTeamSlugResponses, GetDocumentData, GetDocumentErrors, GetDocumentGithubPullRequestsData, GetDocumentGithubPullRequestsErrors, GetDocumentGithubPullRequestsResponses, GetDocumentListHandlerData, GetDocumentListHandlerErrors, GetDocumentListHandlerResponses, GetDocumentLocationV3Data, GetDocumentLocationV3Errors, GetDocumentLocationV3Responses, GetDocumentPermissionsTokenData, GetDocumentPermissionsTokenErrors, GetDocumentPermissionsTokenResponses, GetDocumentPermissionsV2Data, GetDocumentPermissionsV2Errors, GetDocumentPermissionsV2Responses, GetDocumentProcessingResultData, GetDocumentProcessingResultErrors, GetDocumentProcessingResultResponses, GetDocumentResponses, GetDocumentShortIdData, GetDocumentShortIdErrors, GetDocumentShortIdResponses, GetDocumentTeamShareData, GetDocumentTeamShareErrors, GetDocumentTeamShareResponses, GetDocumentTextContentData, GetDocumentTextContentErrors, GetDocumentTextContentResponses, GetDocumentVersionData, GetDocumentVersionErrors, GetDocumentVersionResponses, GetDocumentViewsHandlerData, GetDocumentViewsHandlerErrors, GetDocumentViewsHandlerResponses, GetEmailFollowupData, GetEmailFollowupErrors, GetEmailFollowupResponses, GetEntityPermissionData, GetEntityPermissionErrors, GetEntityPermissionResponses, GetForeignEntityBySourceData, GetForeignEntityBySourceErrors, GetForeignEntityBySourceResponses, GetForeignEntityData, GetForeignEntityErrors, GetForeignEntityResponses, GetFormData, GetFormErrors, GetFormPermissionsData, GetFormPermissionsErrors, GetFormPermissionsResponses, GetFormResponses, GetFormResponseSummaryData, GetFormResponseSummaryErrors, GetFormResponseSummaryResponses, GetFormTallyData, GetFormTallyErrors, GetFormTallyResponses, GetGithubPullRequestChangesData, GetGithubPullRequestChangesErrors, GetGithubPullRequestChangesPatchData, GetGithubPullRequestChangesPatchErrors, GetGithubPullRequestChangesPatchResponses, GetGithubPullRequestChangesResponses, GetGithubPullRequestData, GetGithubPullRequestErrors, GetGithubPullRequestFacetsData, GetGithubPullRequestFacetsErrors, GetGithubPullRequestFacetsResponses, GetGithubPullRequestResponses, GetGithubPullRequestTasksData, GetGithubPullRequestTasksErrors, GetGithubPullRequestTasksResponses, GetHarnessPairingData, GetHarnessPairingErrors, GetHarnessPairingResponses, GetHistoryHandlerData, GetHistoryHandlerErrors, GetHistoryHandlerResponses, GetInitiativeData, GetInitiativeErrors, GetInitiativeResponses, GetInstructionsHandlerData, GetInstructionsHandlerErrors, GetInstructionsHandlerResponses, GetItemsSoupData, GetItemsSoupErrors, GetItemsSoupResponses, GetLocationHandlerData, GetLocationHandlerErrors, GetLocationHandlerResponses, GetMyFormResponseData, GetMyFormResponseErrors, GetMyFormResponseResponses, GetOrCreateCallData, GetOrCreateCallErrors, GetOrCreateCallResponses, GetOrCreateDmData, GetOrCreateDmErrors, GetOrCreateDmResponses, GetOrCreatePrivateData, GetOrCreatePrivateErrors, GetOrCreatePrivateResponses, GetPendingProjectsHandlerData, GetPendingProjectsHandlerErrors, GetPendingProjectsHandlerResponses, GetPinsHandlerData, GetPinsHandlerErrors, GetPinsHandlerResponses, GetProjectContentHandlerData, GetProjectContentHandlerErrors, GetProjectContentHandlerResponses, GetProjectHandlerData, GetProjectHandlerErrors, GetProjectHandlerResponses, GetProjectPermissionsV2Data, GetProjectPermissionsV2Errors, GetProjectPermissionsV2Responses, GetProjectsHandlerData, GetProjectsHandlerErrors, GetProjectsHandlerResponses, GetProjectUserAccessLevelData, GetProjectUserAccessLevelErrors, GetProjectUserAccessLevelResponses, GetRingStatusData, GetRingStatusErrors, GetRingStatusResponses, GetSelfBotData, GetSelfBotErrors, GetSelfBotResponses, GetSelfHarnessData, GetSelfHarnessErrors, GetSelfHarnessResponses, GetSlackImportData, GetSlackImportErrors, GetSlackImportResponses, GetSystemSkillsHandlerData, GetSystemSkillsHandlerErrors, GetSystemSkillsHandlerResponses, GetUserDocumentsHandlerData, GetUserDocumentsHandlerErrors, GetUserDocumentsHandlerResponses, GetUserDocumentViewLocationData, GetUserDocumentViewLocationErrors, GetUserDocumentViewLocationResponses, GetViewsHandlerData, GetViewsHandlerErrors, GetViewsHandlerResponses, GetWebhookData, GetWebhookErrors, GetWebhookResponses, GuestCallChatPostData, GuestCallChatPostErrors, GuestCallChatPostResponses, GuestCallChatReadData, GuestCallChatReadErrors, GuestCallChatReadResponses, HandlerData, HandlerErrors, HandlerResponses, HealthHandlerData, HealthHandlerResponses, ImportDatabaseTableData, ImportDatabaseTableErrors, ImportDatabaseTableResponses, InferDatabaseColumnTypeData, InferDatabaseColumnTypeErrors, InferDatabaseColumnTypeResponses, IngestTranscriptData, IngestTranscriptErrors, IngestTranscriptResponses, InitializeUserDocumentsData, InitializeUserDocumentsErrors, InitializeUserDocumentsResponses, InstallSyncData, InstallSyncErrors, JobProcessingResultHandlerData, JobProcessingResultHandlerErrors, JobProcessingResultHandlerResponses, JoinChannelByCodeData, JoinChannelByCodeErrors, JoinChannelByCodeResponses, JoinChannelData, JoinChannelErrors, JoinChannelResponses, LeaveChannelData, LeaveChannelErrors, LeaveChannelResponses, LeaveOrEndCallData, LeaveOrEndCallErrors, LeaveOrEndCallResponses, LinkedAccountData, LinkedAccountResponses, LinkedAdoptData, LinkedAdoptResponses, LinkedCancelPairingData, LinkedCancelPairingResponses, LinkedChatsData, LinkedChatsResponses, LinkedConfigurationData, LinkedConfigurationResponses, LinkedConnectData, LinkedConnectResponses, LinkedDeliveryData, LinkedDeliveryResponses, LinkedDetachData, LinkedDetachResponses, LinkedDisconnectData, LinkedDisconnectResponses, LinkedGroupsData, LinkedGroupsResponses, LinkedMessageAttachmentsData, LinkedMessageAttachmentsResponses, LinkedPairingData, LinkedPairingResponses, LinkedPasskeyData, LinkedPasskeyResponses, LinkedReplyData, LinkedReplyErrors, LinkedReplyResponses, LinkedUploadData, LinkedUploadResponses, ListAccessibleFormsData, ListAccessibleFormsErrors, ListAccessibleFormsResponses, ListAgentsData, ListAgentsErrors, ListAgentsResponses, ListBotChannelsData, ListBotChannelsErrors, ListBotChannelsResponses, ListChannelLabelsData, ListChannelLabelsErrors, ListChannelLabelsResponses, ListCompanyContactsData, ListCompanyContactsErrors, ListCompanyContactsResponses, ListCrmPipelinesData, ListCrmPipelinesResponses, ListDatabaseColumnCastsData, ListDatabaseColumnCastsErrors, ListDatabaseColumnCastsResponses, ListDatabasesData, ListDatabasesErrors, ListDatabasesResponses, ListDatabaseWebhooksData, ListDatabaseWebhooksErrors, ListDatabaseWebhooksResponses, ListEmailRemindersData, ListEmailRemindersErrors, ListEmailRemindersResponses, ListFavoritesData, ListFavoritesErrors, ListFavoritesResponses, ListFormsData, ListFormsErrors, ListFormsResponses, ListHarnessAgentsData, ListHarnessAgentsErrors, ListHarnessAgentsResponses, ListHarnessesData, ListHarnessesErrors, ListHarnessesResponses, ListHarnessSessionsData, ListHarnessSessionsErrors, ListHarnessSessionsResponses, ListInitiativesData, ListInitiativesErrors, ListInitiativesResponses, ListJoinRequestsData, ListJoinRequestsErrors, ListJoinRequestsResponses, ListOccurrencesData, ListOccurrencesErrors, ListOccurrencesResponses, ListSlackImportsData, ListSlackImportsResponses, ListTeamCalendarData, ListTeamCalendarResponses, ListTeamOutOfOfficeData, ListTeamOutOfOfficeErrors, ListTeamOutOfOfficeResponses, ListUserApiKeysData, ListUserApiKeysErrors, ListUserApiKeysResponses, ListWebhooksData, ListWebhooksErrors, ListWebhooksResponses, MeetingCancelData, MeetingCancelErrors, MeetingCancelPreparationData, MeetingCancelPreparationErrors, MeetingCancelPreparationResponses, MeetingCancelResponses, MeetingCreateData, MeetingCreateErrors, MeetingCreateResponses, MeetingGuestJoinData, MeetingGuestJoinErrors, MeetingGuestJoinResponses, MeetingGuestParticipantsData, MeetingGuestParticipantsErrors, MeetingGuestParticipantsResponses, MeetingInviteData, MeetingInviteErrors, MeetingInvitePermissionsData, MeetingInvitePermissionsErrors, MeetingInvitePermissionsResponses, MeetingInviteResponses, MeetingInviteUsersData, MeetingInviteUsersErrors, MeetingInviteUsersResponses, MeetingJoinData, MeetingJoinErrors, MeetingJoinResponses, MeetingLeaveData, MeetingLeaveErrors, MeetingLeaveResponses, MeetingListActiveData, MeetingListActiveErrors, MeetingListActiveResponses, MeetingListData, MeetingListErrors, MeetingListResponses, MeetingLookupData, MeetingLookupErrors, MeetingLookupResponses, MeetingParticipantsData, MeetingParticipantsErrors, MeetingParticipantsResponses, MeetingPrepareData, MeetingPrepareErrors, MeetingPrepareResponses, MeetingShareData, MeetingShareErrors, MeetingShareResponses, MeetingUpdateData, MeetingUpdateErrors, MeetingUpdateResponses, MentionPreviewsData, MentionPreviewsErrors, MentionPreviewsResponses, MessageTimelineData, MessageTimelineEntriesData, MessageTimelineEntriesResponses, MessageTimelineResponses, PatchChannelData, PatchChannelErrors, PatchChannelResponses, PatchViewHandlerData, PatchViewHandlerErrors, PatchViewHandlerResponses, PatchWebhookData, PatchWebhookErrors, PatchWebhookResponses, PermanentlyDeleteDocumentData, PermanentlyDeleteDocumentErrors, PermanentlyDeleteDocumentResponses, PermanentlyDeleteProjectData, PermanentlyDeleteProjectErrors, PermanentlyDeleteProjectResponses, PostActivityData, PostActivityErrors, PostActivityResponses, PostChannelBotWebhookData, PostChannelBotWebhookErrors, PostChannelBotWebhookResponses, PostItemsSoupAstData, PostItemsSoupAstErrors, PostItemsSoupAstGroupedData, PostItemsSoupAstGroupedErrors, PostItemsSoupAstGroupedResponses, PostItemsSoupAstResponses, PostItemsSoupData, PostItemsSoupErrors, PostItemsSoupResponses, PresaveDocumentHandlerData, PresaveDocumentHandlerErrors, PresaveDocumentHandlerResponses, PreviewSmartTagData, PreviewSmartTagErrors, PreviewSmartTagResponses, PutCrmTeamSettingsData, PutCrmTeamSettingsErrors, PutCrmTeamSettingsResponses, PutCrmTeamStagesData, PutCrmTeamStagesErrors, PutCrmTeamStagesResponses, PutFormLayoutData, PutFormLayoutErrors, PutFormLayoutResponses, QueryCrmPipelineRowsData, QueryCrmPipelineRowsResponses, QueryDatabasesData, QueryDatabasesErrors, QueryDatabasesResponses, RecentlyDeletedData, RecentlyDeletedErrors, RecentlyDeletedResponses, RegisterSlackImportUploadsData, RegisterSlackImportUploadsErrors, RegisterSlackImportUploadsResponses, RemoveBotFromChannelByBotData, RemoveBotFromChannelByBotErrors, RemoveBotFromChannelByBotResponses, RemoveFavoriteByEntityData, RemoveFavoriteByEntityErrors, RemoveFavoriteByEntityResponses, RemoveParticipantsData, RemoveParticipantsErrors, RemoveParticipantsResponses, RemovePinHandlerData, RemovePinHandlerErrors, RemovePinHandlerResponses, RenameChannelLabelData, RenameChannelLabelErrors, RenameChannelLabelResponses, RenameCrmPipelineData, RenameCrmPipelineResponses, ReorderFavoritesData, ReorderFavoritesErrors, ReorderFavoritesResponses, ReorderPinsHandlerData, ReorderPinsHandlerErrors, ReorderPinsHandlerResponses, RequestToJoinData, RequestToJoinErrors, RequestToJoinResponses, ResetCrmTeamStagesData, ResetCrmTeamStagesErrors, ResetCrmTeamStagesResponses, RevertDeleteDocumentData, RevertDeleteDocumentErrors, RevertDeleteDocumentResponses, RevertDeleteProjectData, RevertDeleteProjectErrors, RevertDeleteProjectResponses, SaveDatabaseQueryData, SaveDatabaseQueryErrors, SaveDatabaseQueryResponses, SaveDocumentHandlerData, SaveDocumentHandlerErrors, SaveDocumentHandlerResponses, SearchContactsData, SearchContactsErrors, SearchContactsResponses, SetChannelLabelData, SetChannelLabelErrors, SetChannelLabelResponses, SetChannelPictureData, SetChannelPictureErrors, SetChannelPictureResponses, SetCompanyHiddenData, SetCompanyHiddenErrors, SetCompanyHiddenResponses, SetContactHiddenData, SetContactHiddenErrors, SetContactHiddenResponses, SetCrmCompanyNameData, SetCrmCompanyNameErrors, SetCrmCompanyNameResponses, SetCrmContactNameData, SetCrmContactNameErrors, SetCrmContactNameResponses, SetDocumentTeamShareData, SetDocumentTeamShareErrors, SetDocumentTeamShareResponses, SetEmailFollowupData, SetEmailFollowupErrors, SetEmailFollowupResponses, SetEmailSyncData, SetEmailSyncErrors, SetEmailSyncResponses, ShareCrmPipelineData, ShareCrmPipelineResponses, ShareDatabaseAwarenessData, ShareDatabaseAwarenessErrors, ShareDatabaseAwarenessResponses, SimpleSaveData, SimpleSaveErrors, SimpleSaveResponses, StreamEventsData, StreamEventsErrors, StreamEventsResponse, StreamEventsResponses, SubmitFormResponseData, SubmitFormResponseErrors, SubmitFormResponseResponses, ToggleShareWithTeamData, ToggleShareWithTeamErrors, ToggleShareWithTeamResponses, TranscribeDictationData, TranscribeDictationErrors, TranscribeDictationResponses, TrashCrmPipelineData, TrashCrmPipelineResponses, UndoDatabaseChangeData, UndoDatabaseChangeErrors, UndoDatabaseChangeResponses, UpdateAgentData, UpdateAgentErrors, UpdateAgentResponses, UpdateCrmPipelinePermissionsData, UpdateCrmPipelinePermissionsResponses, UpdateDatabasePermissionsData, UpdateDatabasePermissionsErrors, UpdateDatabasePermissionsResponses, UpdateFormData, UpdateFormErrors, UpdateFormPermissionsData, UpdateFormPermissionsErrors, UpdateFormPermissionsResponses, UpdateFormResponses, UpdateInitiativeData, UpdateInitiativeErrors, UpdateInitiativeResponses, UploadExtractFolderHandlerData, UploadExtractFolderHandlerErrors, UploadExtractFolderHandlerResponses, UploadFolderHandlerData, UploadFolderHandlerErrors, UploadFolderHandlerResponses, UpsertHistoryHandlerData, UpsertHistoryHandlerErrors, UpsertHistoryHandlerResponses, UpsertUserDocumentViewLocationData, UpsertUserDocumentViewLocationErrors, UpsertUserDocumentViewLocationResponses, ValidateDocumentPermissionsTokenData, ValidateDocumentPermissionsTokenErrors, ValidateDocumentPermissionsTokenResponses, ValidateWebhookData, ValidateWebhookErrors, ValidateWebhookResponses, WhatsappGroupData, WhatsappGroupMessagesData, WhatsappGroupMessagesResponses, WhatsappGroupPermissionsData, WhatsappGroupPermissionsResponses, WhatsappGroupReadData, WhatsappGroupReadResponses, WhatsappGroupResponses, WhatsappGroupsData, WhatsappGroupSendsData, WhatsappGroupSendsResponses, WhatsappGroupsResponses, WhatsappGroupUpdatePermissionsData, WhatsappGroupUpdatePermissionsResponses } from './types.gen';
export type Options = Options2 & {
/**
@@ -2728,6 +2728,14 @@ export class Sdk extends HeyApiClient {
return (options?.client ?? this.client).get({ url: '/meta/linked/account', ...options });
}
+ /**
+ * The caller's WhatsApp chat list (groups and direct chats), newest
+ * activity first, with what can be added to Macro.
+ */
+ public linkedChats(options?: Options): RequestResult {
+ return (options?.client ?? this.client).get({ url: '/meta/linked/chats', ...options });
+ }
+
/**
* Server rollout switches.
*/
diff --git a/packages/sdk/generated/storage/types.gen.ts b/packages/sdk/generated/storage/types.gen.ts
index 0b942717a34..e29dbca3bd8 100644
--- a/packages/sdk/generated/storage/types.gen.ts
+++ b/packages/sdk/generated/storage/types.gen.ts
@@ -9027,6 +9027,25 @@ export type LinkedAttachment = {
*/
export type LinkedAttachmentState = 'loading' | 'ready' | 'unavailable' | 'unsupported';
+/**
+ * Earlier messages imported after adding a group.
+ */
+export type LinkedBackfill = {
+ /**
+ * Messages received from the phone so far (including ones already shown).
+ */
+ imported: number;
+ /**
+ * Progress.
+ */
+ state: LinkedBackfillState;
+};
+
+/**
+ * Where importing a group's earlier messages stands.
+ */
+export type LinkedBackfillState = 'pending' | 'running' | 'waiting_for_phone' | 'done' | 'partial';
+
/**
* Operations implemented for linked groups, independent of current permission.
*/
@@ -9057,6 +9076,64 @@ export type LinkedCapabilities = {
text_limit_bytes: number;
};
+/**
+ * One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.
+ */
+export type LinkedChat = {
+ /**
+ * Archived in WhatsApp.
+ */
+ archived: boolean;
+ /**
+ * "Add to Macro" works now.
+ */
+ canAdd: boolean;
+ /**
+ * Why it can't be added, when it is neither added, shared nor addable.
+ */
+ cannotAddReason?: string | null;
+ group?: null | LinkedGroupReference;
+ /**
+ * WhatsApp chat JID: a group, or the other person's phone-number JID
+ * (LID when WhatsApp never told us the number).
+ */
+ jid: string;
+ /**
+ * Group or direct chat.
+ */
+ kind: LinkedChatKind;
+ /**
+ * Newest activity WhatsApp reported (message or history sync); `null`
+ * when unknown. The list is sorted by it, newest first, unknown last.
+ */
+ lastActivityAt?: string | null;
+ /**
+ * Group: the subject, or member names for an unnamed group. Direct: the
+ * contact or WhatsApp name, else `+`. Always non-empty.
+ */
+ name: string;
+ /**
+ * Pinned in WhatsApp.
+ */
+ pinned: boolean;
+ shared?: null | LinkedSharedGroupReference;
+};
+
+/**
+ * Whether a WhatsApp chat is a group or a one-to-one chat.
+ */
+export type LinkedChatKind = 'group' | 'direct';
+
+/**
+ * The caller's WhatsApp chat list.
+ */
+export type LinkedChats = {
+ /**
+ * Newest activity first; chats with unknown activity last, by name.
+ */
+ chats: Array;
+};
+
/**
* Explicit pairing intent; replacement is a separate deliberate action.
*/
@@ -16108,6 +16185,7 @@ export type WhatsAppGroupSender = {
* Adopted group visible through ordinary entity sharing.
*/
export type WhatsAppGroupSummary = {
+ backfill?: null | LinkedBackfill;
/**
* Caller may currently send from their own account.
*/
@@ -22785,6 +22863,19 @@ export type LinkedAccountResponses = {
export type LinkedAccountResponse = LinkedAccountResponses[keyof LinkedAccountResponses];
+export type LinkedChatsData = {
+ body?: never;
+ path?: never;
+ query?: never;
+ url: '/meta/linked/chats';
+};
+
+export type LinkedChatsResponses = {
+ 200: LinkedChats;
+};
+
+export type LinkedChatsResponse = LinkedChatsResponses[keyof LinkedChatsResponses];
+
export type LinkedConfigurationData = {
body?: never;
path?: never;
diff --git a/packages/sdk/specs/storage.json b/packages/sdk/specs/storage.json
index 98b444366c2..f5ea543636e 100644
--- a/packages/sdk/specs/storage.json
+++ b/packages/sdk/specs/storage.json
@@ -16047,6 +16047,25 @@
}
}
},
+ "/meta/linked/chats": {
+ "get": {
+ "tags": ["whatsapp_linked::inbound::router"],
+ "summary": "The caller's WhatsApp chat list (groups and direct chats), newest\nactivity first, with what can be added to Macro.",
+ "operationId": "linked_chats",
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/LinkedChats"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/meta/linked/configuration": {
"get": {
"tags": ["whatsapp_linked::inbound::router"],
@@ -33385,6 +33404,28 @@
"description": "Where an attachment of a linked message stands.",
"enum": ["loading", "ready", "unavailable", "unsupported"]
},
+ "LinkedBackfill": {
+ "type": "object",
+ "description": "Earlier messages imported after adding a group.",
+ "required": ["state", "imported"],
+ "properties": {
+ "imported": {
+ "type": "integer",
+ "format": "int32",
+ "description": "Messages received from the phone so far (including ones already shown).",
+ "minimum": 0
+ },
+ "state": {
+ "$ref": "#/components/schemas/LinkedBackfillState",
+ "description": "Progress."
+ }
+ }
+ },
+ "LinkedBackfillState": {
+ "type": "string",
+ "description": "Where importing a group's earlier messages stands.",
+ "enum": ["pending", "running", "waiting_for_phone", "done", "partial"]
+ },
"LinkedCapabilities": {
"type": "object",
"description": "Operations implemented for linked groups, independent of current permission.",
@@ -33437,6 +33478,87 @@
}
}
},
+ "LinkedChat": {
+ "type": "object",
+ "description": "One chat of the caller's WhatsApp chat list, as WhatsApp Web lists it.",
+ "required": ["jid", "kind", "name", "archived", "pinned", "canAdd"],
+ "properties": {
+ "archived": {
+ "type": "boolean",
+ "description": "Archived in WhatsApp."
+ },
+ "canAdd": {
+ "type": "boolean",
+ "description": "\"Add to Macro\" works now."
+ },
+ "cannotAddReason": {
+ "type": ["string", "null"],
+ "description": "Why it can't be added, when it is neither added, shared nor addable."
+ },
+ "group": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedGroupReference",
+ "description": "The caller's own Macro group for this chat, once added."
+ }
+ ]
+ },
+ "jid": {
+ "type": "string",
+ "description": "WhatsApp chat JID: a group, or the other person's phone-number JID\n(LID when WhatsApp never told us the number)."
+ },
+ "kind": {
+ "$ref": "#/components/schemas/LinkedChatKind",
+ "description": "Group or direct chat."
+ },
+ "lastActivityAt": {
+ "type": ["string", "null"],
+ "format": "date-time",
+ "description": "Newest activity WhatsApp reported (message or history sync); `null`\nwhen unknown. The list is sorted by it, newest first, unknown last."
+ },
+ "name": {
+ "type": "string",
+ "description": "Group: the subject, or member names for an unnamed group. Direct: the\ncontact or WhatsApp name, else `+`. Always non-empty."
+ },
+ "pinned": {
+ "type": "boolean",
+ "description": "Pinned in WhatsApp."
+ },
+ "shared": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedSharedGroupReference",
+ "description": "Someone else's Macro group for this chat shared with the caller, when\nthe caller has not added their own."
+ }
+ ]
+ }
+ }
+ },
+ "LinkedChatKind": {
+ "type": "string",
+ "description": "Whether a WhatsApp chat is a group or a one-to-one chat.",
+ "enum": ["group", "direct"]
+ },
+ "LinkedChats": {
+ "type": "object",
+ "description": "The caller's WhatsApp chat list.",
+ "required": ["chats"],
+ "properties": {
+ "chats": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/LinkedChat"
+ },
+ "description": "Newest activity first; chats with unknown activity last, by name."
+ }
+ }
+ },
"LinkedConnect": {
"type": "object",
"description": "Explicit pairing intent; replacement is a separate deliberate action.",
@@ -44597,6 +44719,17 @@
"description": "Adopted group visible through ordinary entity sharing.",
"required": ["id", "name", "user_id", "unread_count", "can_send"],
"properties": {
+ "backfill": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/components/schemas/LinkedBackfill",
+ "description": "Importing earlier messages after the group was added; `null` for\ngroups added before this existed."
+ }
+ ]
+ },
"can_send": {
"type": "boolean",
"description": "Caller may currently send from their own account."
diff --git a/packages/sdk/src/coverage/skipped.ts b/packages/sdk/src/coverage/skipped.ts
index 575538313e7..98c4d5b30d4 100644
--- a/packages/sdk/src/coverage/skipped.ts
+++ b/packages/sdk/src/coverage/skipped.ts
@@ -364,6 +364,8 @@ export const storageExcluded = [
'linkedDisconnect',
'linkedPairing',
'linkedPasskey',
+ // The roster group listing is superseded by the chat list (linkedChats).
+ 'linkedGroups',
// Live meeting admission and participant previews are app session flows.
'meetingGuestJoin',
// Browser setup reserves an empty RTC room before creating a meeting.
diff --git a/packages/sdk/src/entities/whatsapp/chat.ts b/packages/sdk/src/entities/whatsapp/chat.ts
new file mode 100644
index 00000000000..f90ad09381e
--- /dev/null
+++ b/packages/sdk/src/entities/whatsapp/chat.ts
@@ -0,0 +1,75 @@
+import type { LinkedChat } from '../../../generated/storage/types.gen';
+import { MacroNotFoundError, unwrap } from '../../utils';
+import type { MacroClient } from '../../utils/client';
+import { MacroEntity } from '../entity';
+import { WhatsAppGroup } from './group';
+
+/** One chat of the current user's WhatsApp chat list: a group or a direct chat. */
+export class WhatsAppChat extends MacroEntity {
+ /** Reference a chat by its WhatsApp JID. */
+ static byId(client: MacroClient, id: string): WhatsAppChat {
+ return new WhatsAppChat(client, id);
+ }
+
+ /** Seed a chat handle from the chat list. */
+ static from(client: MacroClient, record: LinkedChat): WhatsAppChat {
+ return new WhatsAppChat(client, record.jid, record);
+ }
+
+ protected async fetch(): Promise {
+ const { chats } = unwrap(await this.client.storage.linkedChats());
+ const chat = chats.find((record) => record.jid === this.id);
+ if (!chat) throw new MacroNotFoundError('WhatsApp chat is not available');
+ return chat;
+ }
+
+ /** `group` or `direct`. */
+ readonly kind = this.field('kind');
+
+ /** Group subject (or member names), or the other person's name or number. */
+ readonly name = this.field('name');
+
+ /** Newest activity WhatsApp reported, when known. */
+ readonly lastActivityAt = this.field('lastActivityAt');
+
+ /** Archived in WhatsApp. */
+ readonly archived = this.field('archived');
+
+ /** Pinned in WhatsApp. */
+ readonly pinned = this.field('pinned');
+
+ /** Whether adding it to Macro works now. */
+ readonly canAdd = this.field('canAdd');
+
+ /** Why it can't be added, when it is neither added, shared nor addable. */
+ readonly cannotAddReason = this.field('cannotAddReason');
+
+ /** The current user's own Macro group for this chat, once added. */
+ readonly group = this.mappedField('group', (record) =>
+ record ? WhatsAppGroup.byId(this.client, record.id) : undefined,
+ );
+
+ /** Someone else's Macro group for this chat, shared with the current user. */
+ readonly shared = this.mappedField('shared', (record) =>
+ record ? WhatsAppGroup.byId(this.client, record.id) : undefined,
+ );
+
+ /**
+ * Add a group chat to Macro as the current user's own group; its earlier
+ * messages are imported from the phone. Adding it again returns the same
+ * group. Direct chats can't be added yet.
+ */
+ async adopt(): Promise {
+ const result = await this.mutate((client) =>
+ client.storage.linkedAdopt({ body: { group_jid: this.id } }),
+ );
+ return WhatsAppGroup.byId(this.client, result.group_id);
+ }
+
+ /** Reload the chat's list entry. */
+ async refresh(): Promise {
+ this.detail.clear();
+ await this.detail.get();
+ return this;
+ }
+}
diff --git a/packages/sdk/src/entities/whatsapp/group.ts b/packages/sdk/src/entities/whatsapp/group.ts
index 59038d80fae..42bf533e2c9 100644
--- a/packages/sdk/src/entities/whatsapp/group.ts
+++ b/packages/sdk/src/entities/whatsapp/group.ts
@@ -50,6 +50,8 @@ export class WhatsAppGroup extends FavoritableEntity {
readonly sendingIdentity = this.field('sending_identity');
/** Per-user unread count. */
readonly unreadCount = this.field('unread_count');
+ /** Importing earlier messages from the owner's phone after adding, if any. */
+ readonly backfill = this.field('backfill');
/** Supported sizes and mutation window. */
readonly limits = this.field('limits');
/** Current remote roster, when available. */
diff --git a/packages/sdk/src/entities/whatsapp/namespace.ts b/packages/sdk/src/entities/whatsapp/namespace.ts
index ec1e2495249..b380525c43c 100644
--- a/packages/sdk/src/entities/whatsapp/namespace.ts
+++ b/packages/sdk/src/entities/whatsapp/namespace.ts
@@ -1,8 +1,8 @@
import { unwrap } from '../../utils';
import type { MacroClient } from '../../utils/client';
import { WhatsAppAccount } from './account';
+import { WhatsAppChat } from './chat';
import { WhatsAppGroup } from './group';
-import { WhatsAppRemoteGroup } from './remote-group';
/** Operate on an account already paired through the Macro app. */
export class WhatsAppNamespace {
@@ -22,10 +22,14 @@ export class WhatsAppNamespace {
);
}
- /** Groups discoverable through the caller's own connected account. */
- async remoteGroups(): Promise {
- return unwrap(await this.client.storage.linkedGroups()).map((record) =>
- WhatsAppRemoteGroup.from(this.client, record),
+ /**
+ * The caller's WhatsApp chat list (groups and direct chats), newest
+ * activity first: each chat says whether it is added, shared with the caller
+ * or addable, and `chat.adopt()` adds it.
+ */
+ async chats(): Promise