@outlit/cli 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +795 -178
  2. package/package.json +4 -3
package/dist/cli.js CHANGED
@@ -104,7 +104,7 @@ var package_default;
104
104
  var init_package = __esm(() => {
105
105
  package_default = {
106
106
  name: "@outlit/cli",
107
- version: "1.5.0",
107
+ version: "1.6.0",
108
108
  description: "CLI for Outlit customer intelligence platform",
109
109
  license: "Apache-2.0",
110
110
  repository: {
@@ -134,8 +134,9 @@ var init_package = __esm(() => {
134
134
  typecheck: "tsc --noEmit"
135
135
  },
136
136
  dependencies: {
137
- citty: "^0.2.1",
138
- "@clack/prompts": "^1.0.1"
137
+ "@clack/prompts": "^1.0.1",
138
+ "@outlit/tools": "^0.1.0",
139
+ citty: "^0.2.1"
139
140
  },
140
141
  devDependencies: {
141
142
  typescript: "^5.9.3",
@@ -1488,6 +1489,725 @@ var init_signup = __esm(() => {
1488
1489
  });
1489
1490
  });
1490
1491
 
1492
+ // ../tools/dist/index.js
1493
+ function isCustomerToolName(value) {
1494
+ return customerToolNameSet.has(value);
1495
+ }
1496
+ function resolveCustomerContextSearchInput(value) {
1497
+ if (!value.query) {
1498
+ return {
1499
+ ok: false,
1500
+ message: "A query argument is required"
1501
+ };
1502
+ }
1503
+ const normalizedQuery = value.query.trim();
1504
+ if (normalizedQuery.length < 2) {
1505
+ return {
1506
+ ok: false,
1507
+ message: "Query must be at least 2 non-whitespace characters"
1508
+ };
1509
+ }
1510
+ if (value.after !== undefined && !iso8601UtcDateTimeRegex.test(value.after)) {
1511
+ return {
1512
+ ok: false,
1513
+ message: "--after must be a valid ISO 8601 datetime"
1514
+ };
1515
+ }
1516
+ const afterTime = value.after === undefined ? undefined : new Date(value.after).getTime();
1517
+ if (afterTime !== undefined && Number.isNaN(afterTime)) {
1518
+ return {
1519
+ ok: false,
1520
+ message: "--after must be a valid ISO 8601 datetime"
1521
+ };
1522
+ }
1523
+ if (value.before !== undefined && !iso8601UtcDateTimeRegex.test(value.before)) {
1524
+ return {
1525
+ ok: false,
1526
+ message: "--before must be a valid ISO 8601 datetime"
1527
+ };
1528
+ }
1529
+ const beforeTime = value.before === undefined ? undefined : new Date(value.before).getTime();
1530
+ if (beforeTime !== undefined && Number.isNaN(beforeTime)) {
1531
+ return {
1532
+ ok: false,
1533
+ message: "--before must be a valid ISO 8601 datetime"
1534
+ };
1535
+ }
1536
+ if (afterTime !== undefined && beforeTime !== undefined && afterTime > beforeTime) {
1537
+ return {
1538
+ ok: false,
1539
+ message: "--after must be before or equal to --before"
1540
+ };
1541
+ }
1542
+ return {
1543
+ ok: true,
1544
+ request: {
1545
+ query: normalizedQuery,
1546
+ customer: value.customer,
1547
+ topK: value.topK,
1548
+ after: value.after,
1549
+ before: value.before,
1550
+ sourceTypes: value.sourceTypes
1551
+ }
1552
+ };
1553
+ }
1554
+ function createOutlitClient(options) {
1555
+ const key = options.apiKey.trim();
1556
+ const baseUrl = options.baseUrl ?? DEFAULT_OUTLIT_API_URL;
1557
+ const fetchImpl = options.fetch ?? globalThis.fetch;
1558
+ if (!key) {
1559
+ throw new Error("apiKey is required");
1560
+ }
1561
+ if (!fetchImpl) {
1562
+ throw new Error("fetch is not available");
1563
+ }
1564
+ return {
1565
+ key,
1566
+ baseUrl,
1567
+ async callTool(toolName, input = {}) {
1568
+ if (!isCustomerToolName(toolName)) {
1569
+ throw new Error(`Unknown customer tool: ${toolName}`);
1570
+ }
1571
+ const response = await fetchImpl(new URL("/api/tools/call", baseUrl).toString(), {
1572
+ method: "POST",
1573
+ headers: {
1574
+ Authorization: `Bearer ${key}`,
1575
+ "Content-Type": "application/json"
1576
+ },
1577
+ body: JSON.stringify({
1578
+ tool: toolName,
1579
+ input
1580
+ })
1581
+ });
1582
+ if (!response.ok) {
1583
+ const text = await response.text();
1584
+ throw new Error(`API error (${response.status}): ${text}`);
1585
+ }
1586
+ return response.json();
1587
+ }
1588
+ };
1589
+ }
1590
+ var customerToolNames, customerToolContracts, customerBillingStatuses, customerFactStatuses, customerFactTypes, unsupportedCustomerFactTypes, customerFactCategories, customerIncludeSections, customerSourceTypes, customerTimeframes, timelineChannels, timelineTimeframes, userJourneyStages, schemaTables, customerToolNameSet, iso8601UtcDateTimeRegex, DEFAULT_OUTLIT_API_URL = "https://app.outlit.ai", defaultAgentToolNames, sqlToolNames, analyticalAgentToolNames;
1591
+ var init_dist4 = __esm(() => {
1592
+ customerToolNames = [
1593
+ "outlit_list_customers",
1594
+ "outlit_list_users",
1595
+ "outlit_get_customer",
1596
+ "outlit_get_timeline",
1597
+ "outlit_list_facts",
1598
+ "outlit_get_fact",
1599
+ "outlit_get_source",
1600
+ "outlit_search_customer_context",
1601
+ "outlit_query",
1602
+ "outlit_schema"
1603
+ ];
1604
+ customerToolContracts = {
1605
+ outlit_list_customers: {
1606
+ toolName: "outlit_list_customers",
1607
+ description: "Browse and filter customers. Use this to find customers by billing status, activity recency, revenue, or name. Returns a paginated list with summary info (MRR, last activity, status).",
1608
+ inputSchema: {
1609
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1610
+ type: "object",
1611
+ properties: {
1612
+ billingStatus: {
1613
+ description: "Filter by billing status",
1614
+ type: "string",
1615
+ enum: ["NONE", "TRIALING", "PAYING", "PAST_DUE", "CHURNED"]
1616
+ },
1617
+ hasActivityInLast: {
1618
+ description: "Filter customers with activity in the last N days",
1619
+ type: "string",
1620
+ enum: ["7d", "14d", "30d", "90d"]
1621
+ },
1622
+ noActivityInLast: {
1623
+ description: "Filter customers with NO activity in the last N days",
1624
+ type: "string",
1625
+ enum: ["7d", "14d", "30d", "90d"]
1626
+ },
1627
+ mrrAbove: {
1628
+ description: "Minimum MRR in cents (e.g., 10000 = $100)",
1629
+ type: "number",
1630
+ minimum: 0
1631
+ },
1632
+ mrrBelow: {
1633
+ description: "Maximum MRR in cents",
1634
+ type: "number",
1635
+ minimum: 0
1636
+ },
1637
+ traitFilters: {
1638
+ description: "Filter by exact trait values using key/value pairs",
1639
+ type: "object",
1640
+ propertyNames: {
1641
+ type: "string",
1642
+ pattern: "^[A-Za-z0-9_-]{1,100}$"
1643
+ },
1644
+ additionalProperties: {
1645
+ anyOf: [
1646
+ {
1647
+ type: "string",
1648
+ maxLength: 500
1649
+ },
1650
+ {
1651
+ type: "number"
1652
+ },
1653
+ {
1654
+ type: "boolean"
1655
+ }
1656
+ ]
1657
+ }
1658
+ },
1659
+ search: {
1660
+ description: "Search by customer name or domain (case-insensitive)",
1661
+ type: "string",
1662
+ maxLength: 500
1663
+ },
1664
+ limit: {
1665
+ description: "Results per page (max 1000)",
1666
+ default: 50,
1667
+ type: "number",
1668
+ minimum: 1,
1669
+ maximum: 1000
1670
+ },
1671
+ cursor: {
1672
+ description: "Pagination cursor from previous response",
1673
+ type: "string"
1674
+ },
1675
+ orderBy: {
1676
+ description: "Field to order results by",
1677
+ default: "last_activity_at",
1678
+ type: "string",
1679
+ enum: ["last_activity_at", "first_seen_at", "name", "mrr_cents"]
1680
+ },
1681
+ orderDirection: {
1682
+ description: "Sort direction",
1683
+ default: "desc",
1684
+ type: "string",
1685
+ enum: ["asc", "desc"]
1686
+ }
1687
+ },
1688
+ additionalProperties: false
1689
+ }
1690
+ },
1691
+ outlit_list_users: {
1692
+ toolName: "outlit_list_users",
1693
+ description: "Browse and filter users. Use this to find users by journey stage, activity recency, customer, or email/name. Returns a paginated list with activity info.",
1694
+ inputSchema: {
1695
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1696
+ type: "object",
1697
+ properties: {
1698
+ journeyStage: {
1699
+ description: "Filter by user journey stage",
1700
+ type: "string",
1701
+ enum: ["DISCOVERED", "SIGNED_UP", "ACTIVATED", "ENGAGED", "INACTIVE"]
1702
+ },
1703
+ customerId: {
1704
+ description: "Filter users by customer ID",
1705
+ type: "string",
1706
+ maxLength: 500
1707
+ },
1708
+ traitFilters: {
1709
+ description: "Filter by exact trait values using key/value pairs",
1710
+ type: "object",
1711
+ propertyNames: {
1712
+ type: "string",
1713
+ pattern: "^[A-Za-z0-9_-]{1,100}$"
1714
+ },
1715
+ additionalProperties: {
1716
+ anyOf: [
1717
+ {
1718
+ type: "string",
1719
+ maxLength: 500
1720
+ },
1721
+ {
1722
+ type: "number"
1723
+ },
1724
+ {
1725
+ type: "boolean"
1726
+ }
1727
+ ]
1728
+ }
1729
+ },
1730
+ hasActivityInLast: {
1731
+ description: "Filter users active within this window. Format: Nd, Nh, or Nm (e.g., '7d', '24h', '90m')",
1732
+ type: "string",
1733
+ pattern: "^\\d+(d|h|m)$"
1734
+ },
1735
+ noActivityInLast: {
1736
+ description: "Filter users NOT active within this window. Format: Nd, Nh, or Nm (e.g., '30d', '2h')",
1737
+ type: "string",
1738
+ pattern: "^\\d+(d|h|m)$"
1739
+ },
1740
+ search: {
1741
+ description: "Search by user email or name (case-insensitive)",
1742
+ type: "string",
1743
+ maxLength: 500
1744
+ },
1745
+ limit: {
1746
+ description: "Results per page (max 1000)",
1747
+ default: 50,
1748
+ type: "number",
1749
+ minimum: 1,
1750
+ maximum: 1000
1751
+ },
1752
+ cursor: {
1753
+ description: "Pagination cursor from previous response",
1754
+ type: "string"
1755
+ },
1756
+ orderBy: {
1757
+ description: "Field to order by",
1758
+ default: "last_activity_at",
1759
+ type: "string",
1760
+ enum: ["last_activity_at", "first_seen_at", "email"]
1761
+ },
1762
+ orderDirection: {
1763
+ description: "Sort direction",
1764
+ default: "desc",
1765
+ type: "string",
1766
+ enum: ["asc", "desc"]
1767
+ }
1768
+ },
1769
+ additionalProperties: false
1770
+ }
1771
+ },
1772
+ outlit_get_customer: {
1773
+ toolName: "outlit_get_customer",
1774
+ description: "Get full details for a single customer. Use this when you already know which customer you want to inspect. Optionally include related data (users, revenue, recent activity, engagement metrics).",
1775
+ inputSchema: {
1776
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1777
+ type: "object",
1778
+ properties: {
1779
+ customer: {
1780
+ type: "string",
1781
+ description: "Customer ID, domain, or name to look up"
1782
+ },
1783
+ include: {
1784
+ description: "Additional data sections to include in the response",
1785
+ type: "array",
1786
+ items: {
1787
+ type: "string",
1788
+ enum: ["users", "revenue", "recentTimeline", "behaviorMetrics"]
1789
+ }
1790
+ },
1791
+ timeframe: {
1792
+ description: "Timeframe for timeline and behavior metrics (default: 30d)",
1793
+ default: "30d",
1794
+ type: "string",
1795
+ enum: ["7d", "14d", "30d", "90d"]
1796
+ }
1797
+ },
1798
+ required: ["customer"],
1799
+ additionalProperties: false
1800
+ }
1801
+ },
1802
+ outlit_get_timeline: {
1803
+ toolName: "outlit_get_timeline",
1804
+ description: "Get the chronological activity timeline for a customer. Use this to see what happened and when — emails, calls, Slack messages, billing events, etc. Supports channel and date filtering.",
1805
+ inputSchema: {
1806
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1807
+ type: "object",
1808
+ properties: {
1809
+ customer: {
1810
+ type: "string",
1811
+ description: "Customer ID or domain"
1812
+ },
1813
+ channels: {
1814
+ description: "Filter by event channel (e.g., EMAIL, SLACK, CALL)",
1815
+ type: "array",
1816
+ items: {
1817
+ type: "string",
1818
+ enum: ["SDK", "EMAIL", "SLACK", "CALL", "CRM", "BILLING", "SUPPORT", "INTERNAL"]
1819
+ }
1820
+ },
1821
+ eventTypes: {
1822
+ description: "Filter by event type",
1823
+ type: "array",
1824
+ items: {
1825
+ type: "string"
1826
+ }
1827
+ },
1828
+ timeframe: {
1829
+ description: "Relative time window (default: 30d). Cannot be used with startDate/endDate.",
1830
+ type: "string",
1831
+ enum: ["7d", "14d", "30d", "90d", "all"]
1832
+ },
1833
+ startDate: {
1834
+ description: "Start of time window (ISO 8601, e.g. '2025-01-01T00:00:00Z'). Cannot be used with timeframe.",
1835
+ type: "string",
1836
+ format: "date-time",
1837
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1838
+ },
1839
+ endDate: {
1840
+ description: "End of time window (ISO 8601, e.g. '2025-01-31T23:59:59Z'). Cannot be used with timeframe.",
1841
+ type: "string",
1842
+ format: "date-time",
1843
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1844
+ },
1845
+ limit: {
1846
+ description: "Results per page (max 1000)",
1847
+ default: 50,
1848
+ type: "number",
1849
+ minimum: 1,
1850
+ maximum: 1000
1851
+ },
1852
+ cursor: {
1853
+ description: "Pagination cursor from previous response",
1854
+ type: "string"
1855
+ }
1856
+ },
1857
+ required: ["customer"],
1858
+ additionalProperties: false
1859
+ }
1860
+ },
1861
+ outlit_list_facts: {
1862
+ toolName: "outlit_list_facts",
1863
+ description: "List structured facts known about a customer. Use filters like status, sourceTypes, factTypes, factCategories, and date bounds to narrow the result set. For topic-specific retrieval, use outlit_search_customer_context instead.",
1864
+ inputSchema: {
1865
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1866
+ type: "object",
1867
+ properties: {
1868
+ customer: {
1869
+ type: "string",
1870
+ description: "Customer ID or domain"
1871
+ },
1872
+ status: {
1873
+ description: "Optional fact status filter",
1874
+ type: "array",
1875
+ items: {
1876
+ type: "string",
1877
+ enum: ["ACTIVE", "ACKNOWLEDGED", "RESOLVED", "SNOOZED", "CANDIDATE"]
1878
+ }
1879
+ },
1880
+ sourceTypes: {
1881
+ description: "Optional generic source types to restrict fact results to.",
1882
+ type: "array",
1883
+ items: {
1884
+ type: "string",
1885
+ enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
1886
+ }
1887
+ },
1888
+ factTypes: {
1889
+ description: "Optional customer-memory fact type filters, such as CHURN_RISK, EXPANSION, SENTIMENT, or BUDGET. Anomaly detector fact types are not supported.",
1890
+ type: "array",
1891
+ items: {
1892
+ type: "string",
1893
+ enum: [
1894
+ "CUSTOM",
1895
+ "COMPANY_CHANGE",
1896
+ "FUNDING_REVENUE",
1897
+ "TECHNOLOGY",
1898
+ "STRATEGY",
1899
+ "COMPETITIVE",
1900
+ "SENTIMENT",
1901
+ "CHAMPION_RISK",
1902
+ "EXPANSION",
1903
+ "CHURN_RISK",
1904
+ "TIMELINE",
1905
+ "BUDGET",
1906
+ "DECISION_MAKER",
1907
+ "REQUIREMENTS",
1908
+ "PRODUCT_USAGE",
1909
+ "CONTACT_INFO",
1910
+ "CONTACT_PREFERENCE"
1911
+ ]
1912
+ }
1913
+ },
1914
+ factCategories: {
1915
+ description: "Optional public fact category filters. Supported values: MEMORY, CUSTOM.",
1916
+ type: "array",
1917
+ items: {
1918
+ type: "string",
1919
+ enum: ["MEMORY", "CUSTOM"]
1920
+ }
1921
+ },
1922
+ after: {
1923
+ description: "ISO 8601 datetime lower bound",
1924
+ type: "string",
1925
+ format: "date-time",
1926
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1927
+ },
1928
+ before: {
1929
+ description: "ISO 8601 datetime upper bound",
1930
+ type: "string",
1931
+ format: "date-time",
1932
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
1933
+ },
1934
+ limit: {
1935
+ description: "Results per page (max 100)",
1936
+ default: 50,
1937
+ type: "number",
1938
+ minimum: 1,
1939
+ maximum: 100
1940
+ },
1941
+ cursor: {
1942
+ description: "Pagination cursor from previous response",
1943
+ type: "string"
1944
+ }
1945
+ },
1946
+ required: ["customer"],
1947
+ additionalProperties: false
1948
+ }
1949
+ },
1950
+ outlit_get_fact: {
1951
+ toolName: "outlit_get_fact",
1952
+ description: "Get one exact fact by ID. Returns the canonical fact shape and optionally expands requested related data such as evidence.",
1953
+ inputSchema: {
1954
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1955
+ type: "object",
1956
+ properties: {
1957
+ factId: {
1958
+ type: "string",
1959
+ minLength: 1,
1960
+ maxLength: 500,
1961
+ description: "Exact fact ID to retrieve"
1962
+ },
1963
+ include: {
1964
+ description: "Optional best-effort expansions. Use include=['evidence'] to request evidence when available; unsupported include values are ignored.",
1965
+ type: "array",
1966
+ items: {
1967
+ type: "string",
1968
+ minLength: 1,
1969
+ maxLength: 100
1970
+ }
1971
+ }
1972
+ },
1973
+ required: ["factId"],
1974
+ additionalProperties: false
1975
+ }
1976
+ },
1977
+ outlit_get_source: {
1978
+ toolName: "outlit_get_source",
1979
+ description: "Get one exact source record by generic sourceType and sourceId. Use this when you already know the concrete underlying source you want to inspect.",
1980
+ inputSchema: {
1981
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1982
+ type: "object",
1983
+ properties: {
1984
+ sourceType: {
1985
+ type: "string",
1986
+ enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
1987
+ },
1988
+ sourceId: {
1989
+ type: "string",
1990
+ minLength: 1,
1991
+ maxLength: 500
1992
+ }
1993
+ },
1994
+ required: ["sourceType", "sourceId"],
1995
+ additionalProperties: false
1996
+ }
1997
+ },
1998
+ outlit_search_customer_context: {
1999
+ toolName: "outlit_search_customer_context",
2000
+ description: "Search across all known customer context using a natural-language query. Returns grouped artifact-level results for matching sources and facts. Omit customer to search across all customers in the organization.",
2001
+ inputSchema: {
2002
+ $schema: "https://json-schema.org/draft/2020-12/schema",
2003
+ type: "object",
2004
+ properties: {
2005
+ customer: {
2006
+ description: "Customer ID, domain, or name. Omit to search across all customers.",
2007
+ anyOf: [
2008
+ {
2009
+ type: "string",
2010
+ minLength: 1,
2011
+ maxLength: 500
2012
+ },
2013
+ {
2014
+ type: "null"
2015
+ }
2016
+ ]
2017
+ },
2018
+ query: {
2019
+ type: "string",
2020
+ minLength: 2,
2021
+ maxLength: 2000,
2022
+ description: "Natural language query or topic to search for."
2023
+ },
2024
+ topK: {
2025
+ description: "Maximum number of artifact results to return (default 20).",
2026
+ type: "integer",
2027
+ minimum: 1,
2028
+ maximum: 50
2029
+ },
2030
+ after: {
2031
+ description: "ISO 8601 datetime lower bound",
2032
+ type: "string",
2033
+ format: "date-time",
2034
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
2035
+ },
2036
+ before: {
2037
+ description: "ISO 8601 datetime upper bound",
2038
+ type: "string",
2039
+ format: "date-time",
2040
+ pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
2041
+ },
2042
+ sourceTypes: {
2043
+ description: "Optional generic source types to restrict the search to.",
2044
+ type: "array",
2045
+ items: {
2046
+ type: "string",
2047
+ enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
2048
+ }
2049
+ }
2050
+ },
2051
+ required: ["query"],
2052
+ additionalProperties: false
2053
+ }
2054
+ },
2055
+ outlit_query: {
2056
+ toolName: "outlit_query",
2057
+ description: `Execute raw SQL queries against your analytics data.
2058
+
2059
+ Available tables:
2060
+ - events: Customer activity events (event_type, event_channel, customer_id, occurred_at, properties, ...)
2061
+ - customer_dimensions: Customer attributes (customer_id, domain, name, billing_status, plan, mrr_cents, ...)
2062
+ - user_dimensions: User attributes (user_id, email, name, customer_id, ...)
2063
+ - mrr_snapshots: Revenue snapshots over time (customer_id, snapshot_date, mrr_cents, ...)
2064
+
2065
+ All queries are automatically filtered to your organization's data.
2066
+ Only SELECT queries are allowed.
2067
+
2068
+ Example queries:
2069
+ - SELECT event_type, count(*) FROM events GROUP BY 1 ORDER BY 2 DESC LIMIT 10
2070
+ - SELECT billing_status, sum(mrr_cents)/100 as mrr FROM customer_dimensions GROUP BY 1
2071
+ - SELECT * FROM events WHERE customer_id = 'cust_123' ORDER BY occurred_at DESC LIMIT 50`,
2072
+ inputSchema: {
2073
+ $schema: "https://json-schema.org/draft/2020-12/schema",
2074
+ type: "object",
2075
+ properties: {
2076
+ sql: {
2077
+ type: "string",
2078
+ description: "SQL SELECT query to execute"
2079
+ },
2080
+ limit: {
2081
+ description: "Max rows to return (default 1000, max 10000)",
2082
+ default: 1000,
2083
+ type: "number",
2084
+ maximum: 1e4
2085
+ }
2086
+ },
2087
+ required: ["sql"],
2088
+ additionalProperties: false
2089
+ }
2090
+ },
2091
+ outlit_schema: {
2092
+ toolName: "outlit_schema",
2093
+ description: `Get table schemas for available analytics tables.
2094
+
2095
+ Use this to discover column names, types, and descriptions before writing SQL queries.
2096
+ Returns column definitions and example queries for each table.`,
2097
+ inputSchema: {
2098
+ $schema: "https://json-schema.org/draft/2020-12/schema",
2099
+ type: "object",
2100
+ properties: {
2101
+ table: {
2102
+ description: "Specific table to describe, or omit for all tables",
2103
+ type: "string",
2104
+ enum: ["events", "customer_dimensions", "user_dimensions", "mrr_snapshots"]
2105
+ }
2106
+ },
2107
+ additionalProperties: false
2108
+ }
2109
+ }
2110
+ };
2111
+ customerBillingStatuses = [
2112
+ "NONE",
2113
+ "TRIALING",
2114
+ "PAYING",
2115
+ "PAST_DUE",
2116
+ "CHURNED"
2117
+ ];
2118
+ customerFactStatuses = [
2119
+ "ACTIVE",
2120
+ "ACKNOWLEDGED",
2121
+ "RESOLVED",
2122
+ "SNOOZED",
2123
+ "CANDIDATE"
2124
+ ];
2125
+ customerFactTypes = [
2126
+ "CUSTOM",
2127
+ "COMPANY_CHANGE",
2128
+ "FUNDING_REVENUE",
2129
+ "TECHNOLOGY",
2130
+ "STRATEGY",
2131
+ "COMPETITIVE",
2132
+ "SENTIMENT",
2133
+ "CHAMPION_RISK",
2134
+ "EXPANSION",
2135
+ "CHURN_RISK",
2136
+ "TIMELINE",
2137
+ "BUDGET",
2138
+ "DECISION_MAKER",
2139
+ "REQUIREMENTS",
2140
+ "PRODUCT_USAGE",
2141
+ "CONTACT_INFO",
2142
+ "CONTACT_PREFERENCE"
2143
+ ];
2144
+ unsupportedCustomerFactTypes = [
2145
+ "TRACKING_GAP",
2146
+ "SCHEMA_DRIFT",
2147
+ "INGESTION_LAG",
2148
+ "ACTIVATION_RATE_DROP",
2149
+ "FUNNEL_DROPOFF",
2150
+ "CORE_ACTION_DECAY",
2151
+ "CADENCE_BREAK",
2152
+ "QUIET_ACCOUNT",
2153
+ "CHAMPION_AT_RISK",
2154
+ "SEGMENT_DIVERGENCE"
2155
+ ];
2156
+ customerFactCategories = ["MEMORY", "CUSTOM"];
2157
+ customerIncludeSections = [
2158
+ "users",
2159
+ "revenue",
2160
+ "recentTimeline",
2161
+ "behaviorMetrics"
2162
+ ];
2163
+ customerSourceTypes = ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"];
2164
+ customerTimeframes = ["7d", "14d", "30d", "90d"];
2165
+ timelineChannels = [
2166
+ "SDK",
2167
+ "EMAIL",
2168
+ "SLACK",
2169
+ "CALL",
2170
+ "CRM",
2171
+ "BILLING",
2172
+ "SUPPORT",
2173
+ "INTERNAL"
2174
+ ];
2175
+ timelineTimeframes = ["7d", "14d", "30d", "90d", "all"];
2176
+ userJourneyStages = [
2177
+ "DISCOVERED",
2178
+ "SIGNED_UP",
2179
+ "ACTIVATED",
2180
+ "ENGAGED",
2181
+ "INACTIVE"
2182
+ ];
2183
+ schemaTables = [
2184
+ "events",
2185
+ "customer_dimensions",
2186
+ "user_dimensions",
2187
+ "mrr_snapshots"
2188
+ ];
2189
+ customerToolNameSet = new Set(customerToolNames);
2190
+ iso8601UtcDateTimeRegex = /^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$/;
2191
+ defaultAgentToolNames = [
2192
+ "outlit_list_customers",
2193
+ "outlit_list_users",
2194
+ "outlit_get_customer",
2195
+ "outlit_get_timeline",
2196
+ "outlit_list_facts",
2197
+ "outlit_get_fact",
2198
+ "outlit_get_source",
2199
+ "outlit_search_customer_context"
2200
+ ];
2201
+ sqlToolNames = [
2202
+ "outlit_schema",
2203
+ "outlit_query"
2204
+ ];
2205
+ analyticalAgentToolNames = [
2206
+ ...defaultAgentToolNames,
2207
+ ...sqlToolNames
2208
+ ];
2209
+ });
2210
+
1491
2211
  // src/lib/client.ts
1492
2212
  function buildUrl(base, path, params) {
1493
2213
  const url = new URL(path, base);
@@ -1513,11 +2233,18 @@ async function createClient(flagApiKey) {
1513
2233
  throw new Error(`Invalid API key format. Keys must start with "ok_" followed by at least 32 alphanumeric characters. Get one at ${OUTLIT_DASHBOARD_URL}`);
1514
2234
  }
1515
2235
  const baseUrl = process.env.OUTLIT_API_URL ?? DEFAULT_API_URL;
2236
+ const toolsClient = createOutlitClient({
2237
+ apiKey: credential.key,
2238
+ baseUrl
2239
+ });
1516
2240
  return {
1517
2241
  key: credential.key,
1518
2242
  baseUrl,
1519
2243
  async callTool(toolName, params) {
1520
- const endpoint = TOOL_ENDPOINTS[toolName];
2244
+ if (isCustomerToolName(toolName)) {
2245
+ return toolsClient.callTool(toolName, params);
2246
+ }
2247
+ const endpoint = CLI_TOOL_ENDPOINTS[toolName];
1521
2248
  if (!endpoint) {
1522
2249
  throw new Error(`Unknown tool: ${toolName}`);
1523
2250
  }
@@ -1546,31 +2273,22 @@ async function createClient(flagApiKey) {
1546
2273
  }
1547
2274
  };
1548
2275
  }
1549
- var API_KEY_REGEX, TOOL_ENDPOINTS;
2276
+ var API_KEY_REGEX, CLI_TOOL_ENDPOINTS;
1550
2277
  var init_client = __esm(() => {
2278
+ init_dist4();
1551
2279
  init_config();
1552
2280
  API_KEY_REGEX = /^ok_[A-Za-z0-9_-]{32,}$/;
1553
- TOOL_ENDPOINTS = {
1554
- outlit_list_customers: { method: "GET", path: "/api/internal/mcp/customers" },
1555
- outlit_get_customer: { method: "POST", path: "/api/internal/mcp/customers" },
1556
- outlit_list_users: { method: "GET", path: "/api/internal/mcp/users" },
1557
- outlit_get_timeline: { method: "POST", path: "/api/internal/mcp/timeline" },
1558
- outlit_list_facts: { method: "POST", path: "/api/internal/mcp/facts" },
1559
- outlit_get_fact: { method: "POST", path: "/api/internal/mcp/facts/get" },
1560
- outlit_get_source: { method: "POST", path: "/api/internal/mcp/context-source" },
1561
- outlit_schema: { method: "GET", path: "/api/internal/mcp/sql-schema" },
1562
- outlit_query: { method: "POST", path: "/api/internal/mcp/sql" },
1563
- outlit_search_customer_context: { method: "POST", path: "/api/internal/mcp/context-search" },
1564
- outlit_list_integrations: { method: "GET", path: "/api/internal/mcp/integrations" },
1565
- outlit_connect_integration: { method: "POST", path: "/api/internal/mcp/integrations/connect" },
1566
- outlit_connect_status: { method: "GET", path: "/api/internal/mcp/integrations/connect/status" },
2281
+ CLI_TOOL_ENDPOINTS = {
2282
+ outlit_list_integrations: { method: "GET", path: "/api/integrations" },
2283
+ outlit_connect_integration: { method: "POST", path: "/api/integrations/connect" },
2284
+ outlit_connect_status: { method: "GET", path: "/api/integrations/connect/status" },
1567
2285
  outlit_disconnect_integration: {
1568
2286
  method: "POST",
1569
- path: "/api/internal/mcp/integrations/disconnect"
2287
+ path: "/api/integrations/disconnect"
1570
2288
  },
1571
2289
  outlit_integration_sync_status: {
1572
2290
  method: "GET",
1573
- path: "/api/internal/mcp/integrations/sync-status"
2291
+ path: "/api/integrations/sync-status"
1574
2292
  }
1575
2293
  };
1576
2294
  });
@@ -1700,7 +2418,7 @@ async function getClientOrExit(flagApiKey, json) {
1700
2418
  }
1701
2419
  async function pingApiKey(apiKey) {
1702
2420
  const baseUrl = process.env.OUTLIT_API_URL ?? DEFAULT_API_URL;
1703
- const url = new URL("/api/internal/mcp/validate-api-key", baseUrl).toString();
2421
+ const url = new URL("/api/validate-api-key", baseUrl).toString();
1704
2422
  const response = await globalThis.fetch(url, {
1705
2423
  method: "POST",
1706
2424
  headers: {
@@ -2201,148 +2919,6 @@ Use this to fetch the next page of results.`
2201
2919
  };
2202
2920
  });
2203
2921
 
2204
- // src/generated/tool-contracts.ts
2205
- function resolveCustomerContextSearchInput(value) {
2206
- if (!value.query) {
2207
- return {
2208
- ok: false,
2209
- message: "A query argument is required"
2210
- };
2211
- }
2212
- const normalizedQuery = value.query.trim();
2213
- if (normalizedQuery.length < 2) {
2214
- return {
2215
- ok: false,
2216
- message: "Query must be at least 2 non-whitespace characters"
2217
- };
2218
- }
2219
- if (value.after !== undefined && value.before !== undefined && new Date(value.after).getTime() > new Date(value.before).getTime()) {
2220
- return {
2221
- ok: false,
2222
- message: "--after must be before or equal to --before"
2223
- };
2224
- }
2225
- return {
2226
- ok: true,
2227
- request: {
2228
- query: normalizedQuery,
2229
- customer: value.customer,
2230
- topK: value.topK,
2231
- after: value.after,
2232
- before: value.before,
2233
- sourceTypes: value.sourceTypes
2234
- }
2235
- };
2236
- }
2237
- var customerToolContracts, customerBillingStatuses, customerFactStatuses, customerIncludeSections, customerSourceTypes, customerTimeframes, timelineChannels, timelineTimeframes, userJourneyStages, schemaTables;
2238
- var init_tool_contracts = __esm(() => {
2239
- customerToolContracts = {
2240
- outlit_list_customers: {
2241
- toolName: "outlit_list_customers",
2242
- description: "Browse and filter customers. Use this to find customers by billing status, activity recency, revenue, or name. Returns a paginated list with summary info (MRR, last activity, status)."
2243
- },
2244
- outlit_list_users: {
2245
- toolName: "outlit_list_users",
2246
- description: "Browse and filter users. Use this to find users by journey stage, activity recency, customer, or email/name. Returns a paginated list with activity info."
2247
- },
2248
- outlit_get_customer: {
2249
- toolName: "outlit_get_customer",
2250
- description: "Get full details for a single customer. Use this when you already know which customer you want to inspect. Optionally include related data (users, revenue, recent activity, engagement metrics)."
2251
- },
2252
- outlit_get_timeline: {
2253
- toolName: "outlit_get_timeline",
2254
- description: "Get the chronological activity timeline for a customer. Use this to see what happened and when — emails, calls, Slack messages, billing events, etc. Supports channel and date filtering."
2255
- },
2256
- outlit_list_facts: {
2257
- toolName: "outlit_list_facts",
2258
- description: "List structured facts known about a customer. Use filters like status, sourceTypes, and date bounds to narrow the result set. For topic-specific retrieval, use outlit_search_customer_context instead."
2259
- },
2260
- outlit_get_fact: {
2261
- toolName: "outlit_get_fact",
2262
- description: "Get one exact fact by ID. Returns the canonical fact shape and optionally expands requested related data such as evidence."
2263
- },
2264
- outlit_get_source: {
2265
- toolName: "outlit_get_source",
2266
- description: "Get one exact source record by generic sourceType and sourceId. Use this when you already know the concrete underlying source you want to inspect."
2267
- },
2268
- outlit_search_customer_context: {
2269
- toolName: "outlit_search_customer_context",
2270
- description: "Search across all known customer context using a natural-language query. Returns grouped artifact-level results for matching sources and facts. Omit customer to search across all customers in the organization."
2271
- },
2272
- outlit_query: {
2273
- toolName: "outlit_query",
2274
- description: `Execute raw SQL queries against your analytics data.
2275
-
2276
- Available tables:
2277
- - events: Customer activity events (event_type, event_channel, customer_id, occurred_at, properties, ...)
2278
- - customer_dimensions: Customer attributes (customer_id, domain, name, billing_status, plan, mrr_cents, ...)
2279
- - user_dimensions: User attributes (user_id, email, name, customer_id, ...)
2280
- - mrr_snapshots: Revenue snapshots over time (customer_id, snapshot_date, mrr_cents, ...)
2281
-
2282
- All queries are automatically filtered to your organization's data.
2283
- Only SELECT queries are allowed.
2284
-
2285
- Example queries:
2286
- - SELECT event_type, count(*) FROM events GROUP BY 1 ORDER BY 2 DESC LIMIT 10
2287
- - SELECT billing_status, sum(mrr_cents)/100 as mrr FROM customer_dimensions GROUP BY 1
2288
- - SELECT * FROM events WHERE customer_id = 'cust_123' ORDER BY occurred_at DESC LIMIT 50`
2289
- },
2290
- outlit_schema: {
2291
- toolName: "outlit_schema",
2292
- description: `Get table schemas for available analytics tables.
2293
-
2294
- Use this to discover column names, types, and descriptions before writing SQL queries.
2295
- Returns column definitions and example queries for each table.`
2296
- }
2297
- };
2298
- customerBillingStatuses = [
2299
- "NONE",
2300
- "TRIALING",
2301
- "PAYING",
2302
- "PAST_DUE",
2303
- "CHURNED"
2304
- ];
2305
- customerFactStatuses = [
2306
- "ACTIVE",
2307
- "ACKNOWLEDGED",
2308
- "RESOLVED",
2309
- "SNOOZED",
2310
- "CANDIDATE"
2311
- ];
2312
- customerIncludeSections = [
2313
- "users",
2314
- "revenue",
2315
- "recentTimeline",
2316
- "behaviorMetrics"
2317
- ];
2318
- customerSourceTypes = ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"];
2319
- customerTimeframes = ["7d", "14d", "30d", "90d"];
2320
- timelineChannels = [
2321
- "SDK",
2322
- "EMAIL",
2323
- "SLACK",
2324
- "CALL",
2325
- "CRM",
2326
- "BILLING",
2327
- "SUPPORT",
2328
- "INTERNAL"
2329
- ];
2330
- timelineTimeframes = ["7d", "14d", "30d", "90d", "all"];
2331
- userJourneyStages = [
2332
- "DISCOVERED",
2333
- "SIGNED_UP",
2334
- "ACTIVATED",
2335
- "ENGAGED",
2336
- "INACTIVE"
2337
- ];
2338
- schemaTables = [
2339
- "events",
2340
- "customer_dimensions",
2341
- "user_dimensions",
2342
- "mrr_snapshots"
2343
- ];
2344
- });
2345
-
2346
2922
  // src/lib/format.ts
2347
2923
  function formatCents(value) {
2348
2924
  if (value == null || typeof value !== "number" || Number.isNaN(value))
@@ -2401,12 +2977,12 @@ __export(exports_list, {
2401
2977
  });
2402
2978
  var list_default;
2403
2979
  var init_list = __esm(() => {
2980
+ init_dist4();
2404
2981
  init_dist();
2405
2982
  init_auth();
2406
2983
  init_filters();
2407
2984
  init_output2();
2408
2985
  init_pagination();
2409
- init_tool_contracts();
2410
2986
  init_api();
2411
2987
  init_output();
2412
2988
  list_default = defineCommand2({
@@ -2514,10 +3090,10 @@ __export(exports_get, {
2514
3090
  });
2515
3091
  var get_default;
2516
3092
  var init_get = __esm(() => {
3093
+ init_dist4();
2517
3094
  init_dist();
2518
3095
  init_auth();
2519
3096
  init_output2();
2520
- init_tool_contracts();
2521
3097
  init_api();
2522
3098
  init_config();
2523
3099
  get_default = defineCommand2({
@@ -2591,11 +3167,11 @@ __export(exports_timeline, {
2591
3167
  });
2592
3168
  var timeline_default;
2593
3169
  var init_timeline = __esm(() => {
3170
+ init_dist4();
2594
3171
  init_dist();
2595
3172
  init_auth();
2596
3173
  init_output2();
2597
3174
  init_pagination();
2598
- init_tool_contracts();
2599
3175
  init_api();
2600
3176
  init_config();
2601
3177
  timeline_default = defineCommand2({
@@ -2617,7 +3193,7 @@ var init_timeline = __esm(() => {
2617
3193
  " outlit customers timeline acme.com",
2618
3194
  " outlit customers timeline acme.com --timeframe 90d",
2619
3195
  " outlit customers timeline acme.com --channels EMAIL,SLACK",
2620
- " outlit customers timeline acme.com --start-date 2025-01-01 --end-date 2025-03-01",
3196
+ " outlit customers timeline acme.com --start-date 2025-01-01T00:00:00Z --end-date 2025-03-01T23:59:59Z",
2621
3197
  " outlit customers timeline acme.com --event-types PAGE_VIEW,MEETING --limit 50",
2622
3198
  "",
2623
3199
  AGENT_JSON_HINT
@@ -2648,11 +3224,11 @@ var init_timeline = __esm(() => {
2648
3224
  },
2649
3225
  "start-date": {
2650
3226
  type: "string",
2651
- description: "Start date for the event range (ISO 8601, e.g. 2025-01-01). When set, --timeframe is ignored."
3227
+ description: "Start datetime for the event range (ISO 8601, e.g. 2025-01-01T00:00:00Z). When set, --timeframe is ignored."
2652
3228
  },
2653
3229
  "end-date": {
2654
3230
  type: "string",
2655
- description: "End date for the event range (ISO 8601, e.g. 2025-03-01). When set, --timeframe is ignored."
3231
+ description: "End datetime for the event range (ISO 8601, e.g. 2025-03-01T23:59:59Z). When set, --timeframe is ignored."
2656
3232
  }
2657
3233
  },
2658
3234
  async run({ args }) {
@@ -2719,12 +3295,12 @@ __export(exports_list2, {
2719
3295
  });
2720
3296
  var list_default2;
2721
3297
  var init_list2 = __esm(() => {
3298
+ init_dist4();
2722
3299
  init_dist();
2723
3300
  init_auth();
2724
3301
  init_filters();
2725
3302
  init_output2();
2726
3303
  init_pagination();
2727
- init_tool_contracts();
2728
3304
  init_api();
2729
3305
  init_output();
2730
3306
  list_default2 = defineCommand2({
@@ -3797,11 +4373,11 @@ function invalidValues(values, allowed) {
3797
4373
  }
3798
4374
  var list_default3;
3799
4375
  var init_list3 = __esm(() => {
4376
+ init_dist4();
3800
4377
  init_dist();
3801
4378
  init_auth();
3802
4379
  init_output2();
3803
4380
  init_pagination();
3804
- init_tool_contracts();
3805
4381
  init_api();
3806
4382
  init_config();
3807
4383
  init_output();
@@ -3816,11 +4392,13 @@ var init_list3 = __esm(() => {
3816
4392
  "Examples:",
3817
4393
  " outlit facts list acme.com",
3818
4394
  " outlit facts list acme.com --status ACTIVE",
4395
+ " outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION",
3819
4396
  " outlit facts list acme.com --source-types CALL,EMAIL --after 2025-01-01T00:00:00Z",
3820
4397
  " outlit facts list acme.com --limit 50 --json",
3821
4398
  "",
3822
4399
  `Statuses: ${customerFactStatuses.join(", ")}`,
3823
4400
  `Source types: ${customerSourceTypes.join(", ")}`,
4401
+ `Fact categories: ${customerFactCategories.join(", ")}`,
3824
4402
  "",
3825
4403
  AGENT_JSON_HINT
3826
4404
  ].join(`
@@ -3843,6 +4421,14 @@ var init_list3 = __esm(() => {
3843
4421
  type: "string",
3844
4422
  description: `Comma-separated generic source type filter (${customerSourceTypes.join(", ")})`
3845
4423
  },
4424
+ "fact-types": {
4425
+ type: "string",
4426
+ description: "Comma-separated customer-memory fact type filter, such as CHURN_RISK, EXPANSION, or SENTIMENT"
4427
+ },
4428
+ "fact-categories": {
4429
+ type: "string",
4430
+ description: `Comma-separated fact category filter (${customerFactCategories.join(", ")})`
4431
+ },
3846
4432
  after: {
3847
4433
  type: "string",
3848
4434
  description: "Filter to facts occurring after this ISO 8601 datetime"
@@ -3856,6 +4442,8 @@ var init_list3 = __esm(() => {
3856
4442
  const json = !!args.json;
3857
4443
  const statuses = parseCsvArg(args.status);
3858
4444
  const sourceTypes = parseCsvArg(args["source-types"]);
4445
+ const factTypes = parseCsvArg(args["fact-types"]);
4446
+ const factCategories = parseCsvArg(args["fact-categories"]);
3859
4447
  const invalidStatuses = invalidValues(statuses, customerFactStatuses);
3860
4448
  if (invalidStatuses.length > 0) {
3861
4449
  return outputError({
@@ -3870,6 +4458,29 @@ var init_list3 = __esm(() => {
3870
4458
  code: "invalid_input"
3871
4459
  }, json);
3872
4460
  }
4461
+ const invalidFactTypes = invalidValues(factTypes, customerFactTypes);
4462
+ if (invalidFactTypes.length > 0) {
4463
+ const anomalyFactTypes = invalidFactTypes.filter((value) => unsupportedCustomerFactTypes.includes(value));
4464
+ const unknownFactTypes = invalidFactTypes.filter((value) => !unsupportedCustomerFactTypes.includes(value));
4465
+ const messageParts = [];
4466
+ if (anomalyFactTypes.length > 0) {
4467
+ messageParts.push(`Anomaly detector fact types are not supported as public filters: ${anomalyFactTypes.join(", ")}. Use customer-memory fact types such as CHURN_RISK, EXPANSION, SENTIMENT, or PRODUCT_USAGE.`);
4468
+ }
4469
+ if (unknownFactTypes.length > 0) {
4470
+ messageParts.push(`Unknown fact types: ${unknownFactTypes.join(", ")}. Allowed: ${customerFactTypes.join(", ")}`);
4471
+ }
4472
+ return outputError({
4473
+ message: messageParts.join(" "),
4474
+ code: "invalid_input"
4475
+ }, json);
4476
+ }
4477
+ const invalidFactCategories = invalidValues(factCategories, customerFactCategories);
4478
+ if (invalidFactCategories.length > 0) {
4479
+ return outputError({
4480
+ message: `Unsupported fact categories: ${invalidFactCategories.join(", ")}. Allowed: ${customerFactCategories.join(", ")}`,
4481
+ code: "invalid_input"
4482
+ }, json);
4483
+ }
3873
4484
  const afterDate = args.after ? new Date(args.after) : null;
3874
4485
  const beforeDate = args.before ? new Date(args.before) : null;
3875
4486
  if (afterDate && Number.isNaN(afterDate.getTime())) {
@@ -3898,6 +4509,10 @@ var init_list3 = __esm(() => {
3898
4509
  params.status = statuses;
3899
4510
  if (sourceTypes)
3900
4511
  params.sourceTypes = sourceTypes;
4512
+ if (factTypes)
4513
+ params.factTypes = factTypes;
4514
+ if (factCategories)
4515
+ params.factCategories = factCategories;
3901
4516
  if (args.after)
3902
4517
  params.after = args.after;
3903
4518
  if (args.before)
@@ -3921,10 +4536,10 @@ function parseCsvArg2(value) {
3921
4536
  }
3922
4537
  var get_default2;
3923
4538
  var init_get2 = __esm(() => {
4539
+ init_dist4();
3924
4540
  init_dist();
3925
4541
  init_auth();
3926
4542
  init_output2();
3927
- init_tool_contracts();
3928
4543
  init_api();
3929
4544
  init_config();
3930
4545
  get_default2 = defineCommand2({
@@ -4007,10 +4622,10 @@ __export(exports_get3, {
4007
4622
  });
4008
4623
  var get_default3;
4009
4624
  var init_get3 = __esm(() => {
4625
+ init_dist4();
4010
4626
  init_dist();
4011
4627
  init_auth();
4012
4628
  init_output2();
4013
- init_tool_contracts();
4014
4629
  init_api();
4015
4630
  init_output();
4016
4631
  get_default3 = defineCommand2({
@@ -4095,10 +4710,10 @@ __export(exports_search, {
4095
4710
  });
4096
4711
  var search_default;
4097
4712
  var init_search = __esm(() => {
4713
+ init_dist4();
4098
4714
  init_dist();
4099
4715
  init_auth();
4100
4716
  init_output2();
4101
- init_tool_contracts();
4102
4717
  init_api();
4103
4718
  init_config();
4104
4719
  init_output();
@@ -4193,10 +4808,10 @@ __export(exports_sql, {
4193
4808
  import { readFileSync as readFileSync4 } from "node:fs";
4194
4809
  var sql_default;
4195
4810
  var init_sql = __esm(() => {
4811
+ init_dist4();
4196
4812
  init_dist();
4197
4813
  init_auth();
4198
4814
  init_output2();
4199
- init_tool_contracts();
4200
4815
  init_api();
4201
4816
  init_output();
4202
4817
  sql_default = defineCommand2({
@@ -4271,10 +4886,10 @@ __export(exports_schema, {
4271
4886
  });
4272
4887
  var schema_default;
4273
4888
  var init_schema = __esm(() => {
4889
+ init_dist4();
4274
4890
  init_dist();
4275
4891
  init_auth();
4276
4892
  init_output2();
4277
- init_tool_contracts();
4278
4893
  init_api();
4279
4894
  schema_default = defineCommand2({
4280
4895
  meta: {
@@ -5181,6 +5796,8 @@ var init_completions = __esm(() => {
5181
5796
  ...PAGINATED,
5182
5797
  { name: "--status", desc: "Filter by fact status" },
5183
5798
  { name: "--source-types", desc: "Filter by source types" },
5799
+ { name: "--fact-types", desc: "Filter by fact types" },
5800
+ { name: "--fact-categories", desc: "Filter by fact categories" },
5184
5801
  { name: "--after", desc: "Facts after date (ISO 8601)" },
5185
5802
  { name: "--before", desc: "Facts before date (ISO 8601)" }
5186
5803
  ]
@@ -6053,7 +6670,7 @@ Usage examples:
6053
6670
  outlit customers get acme.com --include users,revenue
6054
6671
  outlit customers timeline acme.com --timeframe 90d
6055
6672
  outlit users list --journey-stage CHAMPION
6056
- outlit facts list acme.com --source-types CALL --after 2025-01-01T00:00:00Z
6673
+ outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION
6057
6674
  outlit facts get --fact-id fact_123 --include evidence
6058
6675
  outlit sources get --source-type CALL --source-id call_123
6059
6676
  outlit search 'pricing objections last quarter' --source-types CALL,EMAIL
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outlit/cli",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "CLI for Outlit customer intelligence platform",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -30,8 +30,9 @@
30
30
  "typecheck": "tsc --noEmit"
31
31
  },
32
32
  "dependencies": {
33
- "citty": "^0.2.1",
34
- "@clack/prompts": "^1.0.1"
33
+ "@clack/prompts": "^1.0.1",
34
+ "@outlit/tools": "^0.1.0",
35
+ "citty": "^0.2.1"
35
36
  },
36
37
  "devDependencies": {
37
38
  "typescript": "^5.9.3",