zinkee 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -674,6 +674,13 @@ var commandRegistry = {
674
674
  supportsRaw: true,
675
675
  output: writeOutput
676
676
  },
677
+ "logs list": {
678
+ command: "logs list",
679
+ accessLevel: "read",
680
+ supportsExample: true,
681
+ supportsRaw: false,
682
+ output: readOutput
683
+ },
677
684
  "teamspace folders list": {
678
685
  command: "teamspace folders list",
679
686
  accessLevel: "read",
@@ -1608,132 +1615,484 @@ var fieldTypeDefinitions = [
1608
1615
  className: "TextField",
1609
1616
  aliases: ["text", "TextField"],
1610
1617
  description: "Plain text field.",
1611
- rawShape: '{"type":"text","slug":"name","label":"Name"}',
1612
- examplePayload: {
1613
- type: "text",
1614
- slug: "name",
1615
- label: "Name"
1616
- }
1618
+ rawShape: '{"type":"TextField","slug":"name","label":"Name","config":{"textType":"NORMAL"}}',
1619
+ examplePayloads: [
1620
+ {
1621
+ name: "Text field (normal)",
1622
+ payload: {
1623
+ type: "TextField",
1624
+ slug: "customer-name",
1625
+ label: "Customer Name",
1626
+ required: true,
1627
+ config: {
1628
+ textType: "NORMAL",
1629
+ defaultValue: null,
1630
+ conditionalFormatting: []
1631
+ }
1632
+ }
1633
+ },
1634
+ {
1635
+ name: "Text field (long)",
1636
+ payload: {
1637
+ type: "TextField",
1638
+ slug: "customer-notes",
1639
+ label: "Customer Notes",
1640
+ required: false,
1641
+ config: {
1642
+ textType: "LONG",
1643
+ defaultValue: "Add internal notes here...",
1644
+ conditionalFormatting: []
1645
+ }
1646
+ }
1647
+ }
1648
+ ]
1617
1649
  },
1618
1650
  {
1619
1651
  key: "number",
1620
1652
  className: "NumberField",
1621
1653
  aliases: ["number", "NumberField"],
1622
1654
  description: "Numeric field.",
1623
- rawShape: '{"type":"number","slug":"price-eur","label":"Price EUR","config":{"defaultValue":"0","formatOptions":{"format":"number","decimals":2,"thousandsSeparator":true,"symbolEnabled":true,"symbolValue":" \u20AC","symbolPosition":"right"}}}',
1624
- examplePayload: {
1625
- type: "number",
1626
- slug: "price-eur",
1627
- label: "Price EUR",
1628
- config: {
1629
- defaultValue: "0",
1630
- formatOptions: {
1631
- format: "number",
1632
- decimals: 2,
1633
- thousandsSeparator: true,
1634
- symbolEnabled: true,
1635
- symbolValue: " \u20AC",
1636
- symbolPosition: "right"
1655
+ rawShape: '{"type":"NumberField","slug":"quantity","label":"Quantity","config":{"defaultValue":"0","formatOptions":{"format":"number","decimals":0,"thousandsSeparator":false}}}',
1656
+ examplePayloads: [
1657
+ {
1658
+ name: "Number field (plain integer)",
1659
+ payload: {
1660
+ type: "NumberField",
1661
+ slug: "quantity",
1662
+ label: "Quantity",
1663
+ required: false,
1664
+ config: {
1665
+ defaultValue: "0",
1666
+ formatOptions: {
1667
+ format: "number",
1668
+ decimals: 0,
1669
+ thousandsSeparator: false
1670
+ },
1671
+ conditionalFormatting: []
1672
+ }
1673
+ }
1674
+ },
1675
+ {
1676
+ name: "Number field (decimal with thousands)",
1677
+ payload: {
1678
+ type: "NumberField",
1679
+ slug: "weight",
1680
+ label: "Weight (kg)",
1681
+ required: false,
1682
+ config: {
1683
+ defaultValue: "0",
1684
+ formatOptions: {
1685
+ format: "number",
1686
+ decimals: 2,
1687
+ thousandsSeparator: true,
1688
+ negativesInRed: false
1689
+ },
1690
+ conditionalFormatting: []
1691
+ }
1692
+ }
1693
+ },
1694
+ {
1695
+ name: "Number field (currency \u20AC prefix)",
1696
+ payload: {
1697
+ type: "NumberField",
1698
+ slug: "amount-eur",
1699
+ label: "Amount (EUR)",
1700
+ required: false,
1701
+ config: {
1702
+ defaultValue: "0",
1703
+ formatOptions: {
1704
+ format: "currency",
1705
+ decimals: 2,
1706
+ negativesInRed: true,
1707
+ thousandsSeparator: true,
1708
+ symbolEnabled: true,
1709
+ symbolPosition: "before",
1710
+ symbolValue: "\u20AC"
1711
+ },
1712
+ conditionalFormatting: []
1713
+ }
1714
+ }
1715
+ },
1716
+ {
1717
+ name: "Number field (currency $ suffix)",
1718
+ payload: {
1719
+ type: "NumberField",
1720
+ slug: "amount-usd",
1721
+ label: "Amount (USD)",
1722
+ required: false,
1723
+ config: {
1724
+ defaultValue: "0",
1725
+ formatOptions: {
1726
+ format: "currency",
1727
+ decimals: 2,
1728
+ negativesInRed: false,
1729
+ thousandsSeparator: true,
1730
+ symbolEnabled: true,
1731
+ symbolPosition: "right",
1732
+ symbolValue: " $"
1733
+ },
1734
+ conditionalFormatting: []
1735
+ }
1736
+ }
1737
+ },
1738
+ {
1739
+ name: "Number field (percentage)",
1740
+ payload: {
1741
+ type: "NumberField",
1742
+ slug: "discount-rate",
1743
+ label: "Discount Rate",
1744
+ required: false,
1745
+ config: {
1746
+ defaultValue: "0",
1747
+ formatOptions: {
1748
+ format: "percentage",
1749
+ decimals: 1,
1750
+ negativesInRed: true
1751
+ },
1752
+ conditionalFormatting: []
1753
+ }
1754
+ }
1755
+ },
1756
+ {
1757
+ name: "Number field (duration HH:MM)",
1758
+ payload: {
1759
+ type: "NumberField",
1760
+ slug: "tracked-time",
1761
+ label: "Tracked Time",
1762
+ required: false,
1763
+ config: {
1764
+ defaultValue: "0",
1765
+ formatOptions: {
1766
+ format: "duration",
1767
+ durationFormat: "HH:MM"
1768
+ },
1769
+ conditionalFormatting: []
1770
+ }
1637
1771
  }
1638
1772
  }
1639
- }
1773
+ ]
1640
1774
  },
1641
1775
  {
1642
1776
  key: "date",
1643
1777
  className: "DateField",
1644
1778
  aliases: ["date", "DateField"],
1645
1779
  description: "Date or datetime field.",
1646
- rawShape: '{"type":"date","slug":"due-date","label":"Due date"}',
1647
- examplePayload: {
1648
- type: "date",
1649
- slug: "due-date",
1650
- label: "Due date"
1651
- }
1780
+ rawShape: '{"type":"DateField","slug":"due-date","label":"Due Date","config":{"formatOptions":{"format":"date","dateFormat":"YYYY-MM-DD","showTime":false}}}',
1781
+ examplePayloads: [
1782
+ {
1783
+ name: "Date field (date only)",
1784
+ payload: {
1785
+ type: "DateField",
1786
+ slug: "birth-date",
1787
+ label: "Birth Date",
1788
+ required: false,
1789
+ config: {
1790
+ defaultValue: null,
1791
+ formatOptions: {
1792
+ format: "date",
1793
+ dateFormat: "YYYY-MM-DD",
1794
+ showTime: false
1795
+ },
1796
+ conditionalFormatting: []
1797
+ }
1798
+ }
1799
+ },
1800
+ {
1801
+ name: "Date field (datetime EU)",
1802
+ payload: {
1803
+ type: "DateField",
1804
+ slug: "due-date",
1805
+ label: "Due Date",
1806
+ required: false,
1807
+ config: {
1808
+ defaultValue: null,
1809
+ formatOptions: {
1810
+ format: "datetime",
1811
+ dateFormat: "DD/MM/YYYY",
1812
+ showTime: true
1813
+ },
1814
+ conditionalFormatting: []
1815
+ }
1816
+ }
1817
+ },
1818
+ {
1819
+ name: "Date field (datetime US)",
1820
+ payload: {
1821
+ type: "DateField",
1822
+ slug: "appointment-at",
1823
+ label: "Appointment",
1824
+ required: false,
1825
+ config: {
1826
+ defaultValue: null,
1827
+ formatOptions: {
1828
+ format: "datetime",
1829
+ dateFormat: "MM/DD/YYYY",
1830
+ showTime: true
1831
+ },
1832
+ conditionalFormatting: []
1833
+ }
1834
+ }
1835
+ }
1836
+ ]
1652
1837
  },
1653
1838
  {
1654
1839
  key: "option",
1655
1840
  className: "OptionField",
1656
1841
  aliases: ["option", "OptionField"],
1657
1842
  description: "Dropdown/select field with options.",
1658
- rawShape: '{"type":"option","slug":"status","label":"Status","config":{"options":[{"id":1,"name":"Open","color":"default"},{"id":2,"name":"Closed","color":"success"}]}}',
1659
- examplePayload: {
1660
- type: "option",
1661
- slug: "status",
1662
- label: "Status",
1663
- config: {
1664
- options: [
1665
- {
1666
- id: 1,
1667
- name: "Open",
1668
- color: "default"
1669
- },
1670
- {
1671
- id: 2,
1672
- name: "Closed",
1673
- color: "success"
1843
+ rawShape: '{"type":"OptionField","slug":"status","label":"Status","config":{"options":[{"id":1,"name":"Open","color":"default"},{"id":2,"name":"Closed","color":"success"}]}}',
1844
+ examplePayloads: [
1845
+ {
1846
+ name: "Option field (select dropdown)",
1847
+ payload: {
1848
+ type: "OptionField",
1849
+ slug: "priority",
1850
+ label: "Priority",
1851
+ required: false,
1852
+ config: {
1853
+ options: [
1854
+ { id: 1, name: "Low", color: "default" },
1855
+ { id: 2, name: "Medium", color: "warning" },
1856
+ { id: 3, name: "High", color: "danger" }
1857
+ ],
1858
+ defaultValue: 1,
1859
+ conditionalFormatting: [],
1860
+ buttonConfig: null
1674
1861
  }
1675
- ]
1862
+ }
1863
+ },
1864
+ {
1865
+ name: "Option field (button cycle)",
1866
+ payload: {
1867
+ type: "OptionField",
1868
+ slug: "stage",
1869
+ label: "Stage",
1870
+ required: false,
1871
+ config: {
1872
+ options: [
1873
+ { id: 1, name: "To Do", color: "default" },
1874
+ { id: 2, name: "Doing", color: "warning" },
1875
+ { id: 3, name: "Done", color: "success" }
1876
+ ],
1877
+ defaultValue: 1,
1878
+ conditionalFormatting: [],
1879
+ buttonConfig: {
1880
+ displayMode: "button",
1881
+ buttonBehavior: {
1882
+ mode: "cycle",
1883
+ cycleOrder: [1, 2, 3],
1884
+ requireConfirmation: false,
1885
+ lockAfterSelection: false,
1886
+ allowReselect: true
1887
+ }
1888
+ }
1889
+ }
1890
+ }
1891
+ },
1892
+ {
1893
+ name: "Option field (button dropdown w/ confirm)",
1894
+ payload: {
1895
+ type: "OptionField",
1896
+ slug: "status",
1897
+ label: "Status",
1898
+ required: false,
1899
+ config: {
1900
+ options: [
1901
+ { id: 1, name: "Open", color: "default" },
1902
+ { id: 2, name: "In Progress", color: "warning" },
1903
+ { id: 3, name: "Done", color: "success" }
1904
+ ],
1905
+ defaultValue: 1,
1906
+ conditionalFormatting: [],
1907
+ buttonConfig: {
1908
+ displayMode: "button",
1909
+ buttonBehavior: {
1910
+ mode: "dropdown",
1911
+ requireConfirmation: true,
1912
+ confirmationMessage: "Confirm status change",
1913
+ useFixedLabel: true,
1914
+ buttonLabel: "Set status",
1915
+ allowReselect: true
1916
+ }
1917
+ }
1918
+ }
1919
+ }
1676
1920
  }
1677
- }
1921
+ ]
1678
1922
  },
1679
1923
  {
1680
1924
  key: "file",
1681
1925
  className: "FileField",
1682
1926
  aliases: ["file", "FileField"],
1683
1927
  description: "File attachment field.",
1684
- rawShape: '{"type":"file","slug":"attachment","label":"Attachment"}',
1685
- examplePayload: {
1686
- type: "file",
1687
- slug: "attachment",
1688
- label: "Attachment"
1689
- }
1928
+ rawShape: '{"type":"FileField","slug":"attachment","label":"Attachment","config":{}}',
1929
+ examplePayloads: [
1930
+ {
1931
+ name: "File field",
1932
+ payload: {
1933
+ type: "FileField",
1934
+ slug: "attachment",
1935
+ label: "Attachment",
1936
+ required: false,
1937
+ config: {}
1938
+ }
1939
+ }
1940
+ ]
1690
1941
  },
1691
1942
  {
1692
1943
  key: "reference",
1693
1944
  className: "ReferenceField",
1694
1945
  aliases: ["reference", "ReferenceField"],
1695
1946
  description: "Reference to another schema.",
1696
- rawShape: '{"type":"reference","slug":"project","label":"Project","config":{"targetSchema":"<schema-uuid>","targetDisplayField":"<field-uuid>","deleteBehavior":"SET_NULL"}}',
1697
- examplePayload: {
1698
- type: "reference",
1699
- slug: "project",
1700
- label: "Project",
1701
- config: {
1702
- targetSchema: "<schema-uuid>",
1703
- targetDisplayField: "<field-uuid>",
1704
- deleteBehavior: "SET_NULL"
1947
+ rawShape: '{"type":"ReferenceField","slug":"company-ref","label":"Company","config":{"targetSchema":"<schema-uuid>","targetDisplayField":"<field-uuid>"}}',
1948
+ examplePayloads: [
1949
+ {
1950
+ name: "Reference field (minimal)",
1951
+ payload: {
1952
+ type: "ReferenceField",
1953
+ slug: "company-ref",
1954
+ label: "Company",
1955
+ required: false,
1956
+ config: {
1957
+ targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
1958
+ targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34"
1959
+ }
1960
+ }
1961
+ },
1962
+ {
1963
+ name: "Reference field (restrict + filter + description)",
1964
+ payload: {
1965
+ type: "ReferenceField",
1966
+ slug: "customer-ref",
1967
+ label: "Customer",
1968
+ required: false,
1969
+ config: {
1970
+ targetSchema: "5223cbc8-8c6c-4694-93bc-dd176364df9b",
1971
+ targetDisplayField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1972
+ deleteBehavior: "RESTRICT",
1973
+ defaultValue: "8ad602a1-f6e3-43f6-9ab2-f1c5afc99621::Ref A",
1974
+ filterFields: [
1975
+ {
1976
+ fatherField: "c60b8526-5835-4c9f-aecd-9a16c7704a34",
1977
+ currentField: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
1978
+ comparison: "EQUAL",
1979
+ value: null
1980
+ }
1981
+ ],
1982
+ descriptionFields: [
1983
+ {
1984
+ id: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
1985
+ fieldType: "NumberField",
1986
+ options: null,
1987
+ format: "number"
1988
+ }
1989
+ ],
1990
+ conditionalFormatting: []
1991
+ }
1992
+ }
1705
1993
  }
1706
- }
1994
+ ]
1707
1995
  },
1708
1996
  {
1709
1997
  key: "formula",
1710
1998
  className: "FormulaField",
1711
1999
  aliases: ["formula", "FormulaField"],
1712
2000
  description: "Calculated field from a formula.",
1713
- rawShape: '{"type":"formula","slug":"total","label":"Total","config":{"formulaText":"{price} * {quantity}"}}',
1714
- examplePayload: {
1715
- type: "formula",
1716
- slug: "total",
1717
- label: "Total",
1718
- config: {
1719
- formulaText: "{price} * {quantity}"
2001
+ rawShape: `{"type":"FormulaField","slug":"formula-summary","label":"Formula Summary","config":{"formulaText":"concat(firstName, ' ', lastName)","uiFormatKind":"none"}}`,
2002
+ examplePayloads: [
2003
+ {
2004
+ name: "Formula field (none)",
2005
+ payload: {
2006
+ type: "FormulaField",
2007
+ slug: "formula-summary",
2008
+ label: "Formula Summary",
2009
+ required: false,
2010
+ config: {
2011
+ formulaText: "concat(firstName, ' ', lastName)",
2012
+ uiFormatKind: "none",
2013
+ status: "ACTIVE",
2014
+ conditionalFormatting: []
2015
+ }
2016
+ }
2017
+ },
2018
+ {
2019
+ name: "Formula field (number)",
2020
+ payload: {
2021
+ type: "FormulaField",
2022
+ slug: "formula-total",
2023
+ label: "Formula Total",
2024
+ required: false,
2025
+ config: {
2026
+ formulaText: "amount * 1.21",
2027
+ uiFormatKind: "number",
2028
+ status: "ACTIVE",
2029
+ numberFormatOptions: {
2030
+ format: "number",
2031
+ decimals: 2,
2032
+ thousandsSeparator: true
2033
+ },
2034
+ conditionalFormatting: []
2035
+ }
2036
+ }
2037
+ },
2038
+ {
2039
+ name: "Formula field (date)",
2040
+ payload: {
2041
+ type: "FormulaField",
2042
+ slug: "formula-deadline",
2043
+ label: "Computed Deadline",
2044
+ required: false,
2045
+ config: {
2046
+ formulaText: "addDays(startDate, 7)",
2047
+ uiFormatKind: "date",
2048
+ status: "ACTIVE",
2049
+ dateFormatOptions: {
2050
+ format: "date",
2051
+ dateFormat: "DD/MM/YYYY",
2052
+ showTime: false
2053
+ },
2054
+ conditionalFormatting: []
2055
+ }
2056
+ }
2057
+ },
2058
+ {
2059
+ name: "Formula field (member)",
2060
+ payload: {
2061
+ type: "FormulaField",
2062
+ slug: "formula-assignee",
2063
+ label: "Computed Assignee",
2064
+ required: false,
2065
+ config: {
2066
+ formulaText: "manager",
2067
+ uiFormatKind: "member",
2068
+ status: "ACTIVE",
2069
+ conditionalFormatting: []
2070
+ }
2071
+ }
1720
2072
  }
1721
- }
2073
+ ]
1722
2074
  },
1723
2075
  {
1724
2076
  key: "member",
1725
2077
  className: "MemberField",
1726
2078
  aliases: ["member", "MemberField"],
1727
2079
  description: "Workspace member field.",
1728
- rawShape: '{"type":"member","slug":"owner","label":"Owner","config":{"defaultValue":"<member-id>"}}',
1729
- examplePayload: {
1730
- type: "member",
1731
- slug: "owner",
1732
- label: "Owner",
1733
- config: {
1734
- defaultValue: "<member-id>"
2080
+ rawShape: '{"type":"MemberField","slug":"owner","label":"Owner","config":{"defaultValue":null}}',
2081
+ examplePayloads: [
2082
+ {
2083
+ name: "Member field",
2084
+ payload: {
2085
+ type: "MemberField",
2086
+ slug: "owner",
2087
+ label: "Owner",
2088
+ required: false,
2089
+ config: {
2090
+ defaultValue: null,
2091
+ conditionalFormatting: []
2092
+ }
2093
+ }
1735
2094
  }
1736
- }
2095
+ ]
1737
2096
  },
1738
2097
  {
1739
2098
  key: "autoincremental",
@@ -1745,15 +2104,74 @@ var fieldTypeDefinitions = [
1745
2104
  "AutoIncrementalField"
1746
2105
  ],
1747
2106
  description: "Auto-generated incremental counter.",
1748
- rawShape: '{"type":"autoincremental","slug":"counter","label":"Counter","config":{"segmentedByFieldId":null}}',
1749
- examplePayload: {
1750
- type: "autoincremental",
1751
- slug: "counter",
1752
- label: "Counter",
1753
- config: {
1754
- segmentedByFieldId: null
2107
+ rawShape: '{"type":"AutoIncrementalField","slug":"order-number","label":"Order Number","config":{"segmentedByFieldId":null}}',
2108
+ examplePayloads: [
2109
+ {
2110
+ name: "Autoincremental (global counter)",
2111
+ payload: {
2112
+ type: "AutoIncrementalField",
2113
+ slug: "order-number",
2114
+ label: "Order Number",
2115
+ required: false,
2116
+ config: {
2117
+ segmentedByFieldId: null,
2118
+ conditionalFormatting: []
2119
+ }
2120
+ }
2121
+ },
2122
+ {
2123
+ name: "Autoincremental (segmented)",
2124
+ payload: {
2125
+ type: "AutoIncrementalField",
2126
+ slug: "sequence-code",
2127
+ label: "Sequence Code",
2128
+ required: false,
2129
+ config: {
2130
+ segmentedByFieldId: "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
2131
+ conditionalFormatting: []
2132
+ }
2133
+ }
1755
2134
  }
1756
- }
2135
+ ]
2136
+ },
2137
+ {
2138
+ key: "schedule",
2139
+ className: "ScheduleField",
2140
+ aliases: ["schedule", "ScheduleField"],
2141
+ description: "Recurrence/schedule field bound to a number reference and a date period (frequency: monthly or daily).",
2142
+ rawShape: '{"type":"ScheduleField","slug":"recurrence","label":"Recurrence","config":{"referenceField":"<number-field-uuid>","beginningPeriodField":"<date-field-uuid>","endingPeriodField":"<date-field-uuid>","frequency":"monthly"}}',
2143
+ examplePayloads: [
2144
+ {
2145
+ name: "Schedule field (monthly)",
2146
+ payload: {
2147
+ type: "ScheduleField",
2148
+ slug: "monthly-recurrence",
2149
+ label: "Monthly Recurrence",
2150
+ required: false,
2151
+ config: {
2152
+ referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
2153
+ beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2154
+ endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2155
+ frequency: "monthly"
2156
+ }
2157
+ }
2158
+ },
2159
+ {
2160
+ name: "Schedule field (daily)",
2161
+ payload: {
2162
+ type: "ScheduleField",
2163
+ slug: "daily-recurrence",
2164
+ label: "Daily Recurrence",
2165
+ required: false,
2166
+ config: {
2167
+ referenceField: "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
2168
+ beginningPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2169
+ endingPeriodField: "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2170
+ frequency: "daily"
2171
+ }
2172
+ }
2173
+ }
2174
+ ]
1757
2175
  }
1758
2176
  ];
1759
2177
  var fieldTypeDefinitionByAlias = new Map(
@@ -1877,6 +2295,49 @@ function normalizeReferencePayload(input) {
1877
2295
  }
1878
2296
  return normalized;
1879
2297
  }
2298
+ var scheduleAllowedFrequencies = /* @__PURE__ */ new Set(["monthly", "daily"]);
2299
+ function normalizeSchedulePayload(input) {
2300
+ const additionalProperties = toJsonObject(input.additionalProperties) ?? {};
2301
+ const config = toJsonObject(input.config) ?? {};
2302
+ const referenceField = config.referenceField ?? input.referenceField ?? additionalProperties.referenceField;
2303
+ const beginningPeriodField = config.beginningPeriodField ?? input.beginningPeriodField ?? additionalProperties.beginningPeriodField;
2304
+ const endingPeriodField = config.endingPeriodField ?? input.endingPeriodField ?? additionalProperties.endingPeriodField;
2305
+ const frequency = config.frequency ?? input.frequency ?? additionalProperties.frequency;
2306
+ const {
2307
+ referenceField: _referenceField,
2308
+ beginningPeriodField: _beginningPeriodField,
2309
+ endingPeriodField: _endingPeriodField,
2310
+ frequency: _frequency,
2311
+ additionalProperties: _additionalProperties,
2312
+ ...rest
2313
+ } = input;
2314
+ const normalized = {
2315
+ ...rest,
2316
+ config: {
2317
+ ...config,
2318
+ ...referenceField !== void 0 ? { referenceField } : {},
2319
+ ...beginningPeriodField !== void 0 ? { beginningPeriodField } : {},
2320
+ ...endingPeriodField !== void 0 ? { endingPeriodField } : {},
2321
+ ...frequency !== void 0 ? { frequency } : {}
2322
+ }
2323
+ };
2324
+ const normalizedConfig = toJsonObject(normalized.config) ?? {};
2325
+ const definition = resolveSchemaFieldType("schedule");
2326
+ if (!toStringValue2(normalizedConfig.referenceField) || !toStringValue2(normalizedConfig.beginningPeriodField) || !toStringValue2(normalizedConfig.endingPeriodField) || !toStringValue2(normalizedConfig.frequency)) {
2327
+ throw new CliError(
2328
+ "invalid_cli_usage",
2329
+ `Schedule fields require "referenceField", "beginningPeriodField", "endingPeriodField" and "frequency". Expected raw shape: ${definition.rawShape}`
2330
+ );
2331
+ }
2332
+ const frequencyValue = toStringValue2(normalizedConfig.frequency);
2333
+ if (!scheduleAllowedFrequencies.has(frequencyValue)) {
2334
+ throw new CliError(
2335
+ "invalid_cli_usage",
2336
+ `Schedule "frequency" must be "monthly" or "daily" (received "${frequencyValue}").`
2337
+ );
2338
+ }
2339
+ return normalized;
2340
+ }
1880
2341
  function normalizeFormulaPayload(input) {
1881
2342
  const { status: _status, ...rest } = input;
1882
2343
  const rawAdditionalProperties = toJsonObject(input.additionalProperties);
@@ -1924,6 +2385,8 @@ function normalizeSchemaFieldCreatePayload(input) {
1924
2385
  return normalizeReferencePayload(normalizedWithType);
1925
2386
  case "formula":
1926
2387
  return normalizeFormulaPayload(normalizedWithType);
2388
+ case "schedule":
2389
+ return normalizeSchedulePayload(normalizedWithType);
1927
2390
  case "autoincremental": {
1928
2391
  const config = toJsonObject(normalizedWithType.config) ?? {};
1929
2392
  const segmentedByFieldId = config.segmentedByFieldId ?? normalizedWithType.segmentedByFieldId ?? null;
@@ -2160,13 +2623,10 @@ var specificExamples = {
2160
2623
  ]),
2161
2624
  "schemas update": buildCommandExamples([
2162
2625
  {
2163
- description: "Rename a schema and change its slug.",
2164
- command: 'zinkee --json schemas update contacts --name "Customer Contacts" --slug customer-contacts',
2626
+ description: "Toggle the commentable flag on a schema.",
2627
+ command: "zinkee --json schemas update contacts --commentable true",
2165
2628
  raw: `{
2166
- "set": {
2167
- "name": "Customer Contacts",
2168
- "slug": "customer-contacts"
2169
- }
2629
+ "commentable": true
2170
2630
  }`,
2171
2631
  response: `{
2172
2632
  "id": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
@@ -2179,37 +2639,46 @@ var specificExamples = {
2179
2639
  },
2180
2640
  "auditable": true,
2181
2641
  "commentable": true,
2182
- "fields": []
2642
+ "fields": [
2643
+ {
2644
+ "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2645
+ "type": "TextField",
2646
+ "slug": "contact-name",
2647
+ "label": "Customer Name",
2648
+ "required": true,
2649
+ "system": false,
2650
+ "config": {
2651
+ "textType": "LONG",
2652
+ "defaultValue": "Unknown",
2653
+ "conditionalFormatting": []
2654
+ }
2655
+ }
2656
+ ]
2183
2657
  }`
2184
2658
  },
2185
2659
  {
2186
- description: "Enable the audit log on a schema.",
2187
- command: "zinkee --json schemas update contacts --auditable true",
2660
+ description: "Rename a schema and change its slug.",
2661
+ command: 'zinkee --json schemas update contacts --name "Customer Contacts" --slug customer-contacts',
2188
2662
  raw: `{
2189
- "set": {
2190
- "auditable": true
2191
- }
2663
+ "name": "Customer Contacts",
2664
+ "slug": "customer-contacts"
2192
2665
  }`
2193
2666
  },
2194
2667
  {
2195
- description: "Toggle commentable off.",
2196
- command: "zinkee --json schemas update contacts --commentable false",
2668
+ description: "Enable the audit log on a schema.",
2669
+ command: "zinkee --json schemas update contacts --auditable true",
2197
2670
  raw: `{
2198
- "set": {
2199
- "commentable": false
2200
- }
2671
+ "auditable": true
2201
2672
  }`
2202
2673
  }
2203
2674
  ]),
2204
2675
  "schemas fields update": buildCommandExamples([
2205
2676
  {
2206
- description: "Rename a field label and drop the required flag.",
2207
- command: 'zinkee --json schemas fields update contacts contact-name --label "Customer Full Name" --required false',
2677
+ description: "Rename slug and label.",
2678
+ command: `zinkee --json schemas fields update contacts contact-name --label "Customer Full Name" --raw '{"slug":"customer-full-name"}'`,
2208
2679
  raw: `{
2209
- "set": {
2210
- "label": "Customer Full Name",
2211
- "required": false
2212
- }
2680
+ "slug": "customer-full-name",
2681
+ "label": "Customer Full Name"
2213
2682
  }`,
2214
2683
  response: `{
2215
2684
  "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
@@ -2218,95 +2687,243 @@ var specificExamples = {
2218
2687
  }`
2219
2688
  },
2220
2689
  {
2221
- description: "Make a field required.",
2690
+ description: "Toggle required.",
2222
2691
  command: "zinkee --json schemas fields update contacts status --required true",
2223
2692
  raw: `{
2224
- "set": {
2225
- "required": true
2226
- }
2693
+ "required": true
2227
2694
  }`
2228
2695
  },
2229
2696
  {
2230
- description: "Patch the format options of a number field through a raw set payload (no dedicated flag exists for nested config paths).",
2231
- command: `zinkee --json schemas fields update contacts amount --raw '{"set":{"config":{"formatOptions":{"format":"percent","decimals":1}}}}'`,
2697
+ description: "Patch text field (long with default).",
2698
+ command: `zinkee --json schemas fields update contacts contact-name --raw '{"type":"TextField","label":"Customer Full Name","required":false,"config":{"textType":"LONG","defaultValue":"Unknown","conditionalFormatting":[]}}'`,
2232
2699
  raw: `{
2233
- "set": {
2234
- "config": {
2235
- "formatOptions": {
2236
- "format": "percent",
2237
- "decimals": 1
2238
- }
2239
- }
2700
+ "type": "TextField",
2701
+ "label": "Customer Full Name",
2702
+ "required": false,
2703
+ "config": {
2704
+ "textType": "LONG",
2705
+ "defaultValue": "Unknown",
2706
+ "conditionalFormatting": []
2240
2707
  }
2241
2708
  }`
2242
- }
2243
- ]),
2244
- "records query": buildCommandExamples([
2709
+ },
2245
2710
  {
2246
- description: "Lookup a single record by id.",
2247
- command: 'zinkee --json records query contacts --select id,contact-name --where "id eq 550e8400-e29b-41d4-a716-446655440000" --sort id:desc --limit 10',
2711
+ description: "Patch number field (to currency).",
2712
+ command: `zinkee --json schemas fields update contacts amount --raw '{"type":"NumberField","config":{"defaultValue":"0","formatOptions":{"format":"currency","decimals":2,"thousandsSeparator":true,"symbolEnabled":true,"symbolPosition":"before","symbolValue":"\u20AC"},"conditionalFormatting":[]}}'`,
2248
2713
  raw: `{
2249
- "select": ["id", "contact-name"],
2250
- "where": [
2251
- { "field": "id", "op": "eq", "value": "550e8400-e29b-41d4-a716-446655440000" }
2252
- ],
2253
- "sort": [
2254
- { "field": "id", "direction": "DESC" }
2255
- ],
2256
- "page": { "offset": 0, "size": 10 }
2257
- }`,
2258
- response: `{
2259
- "records": [
2260
- {
2261
- "recordId": "550e8400-e29b-41d4-a716-446655440000",
2262
- "values": {
2263
- "contact-name": "Ada Lovelace",
2264
- "status": 2,
2265
- "amount": 1250.50
2266
- }
2267
- }
2268
- ],
2269
- "page": {
2270
- "offset": 0,
2271
- "limit": 25,
2272
- "total": 1,
2273
- "count": 1,
2274
- "hasMore": false
2714
+ "type": "NumberField",
2715
+ "config": {
2716
+ "defaultValue": "0",
2717
+ "formatOptions": {
2718
+ "format": "currency",
2719
+ "decimals": 2,
2720
+ "thousandsSeparator": true,
2721
+ "symbolEnabled": true,
2722
+ "symbolPosition": "before",
2723
+ "symbolValue": "\u20AC"
2724
+ },
2725
+ "conditionalFormatting": []
2275
2726
  }
2276
2727
  }`
2277
2728
  },
2278
2729
  {
2279
- description: "Filter by multiple conditions and sort by amount then name.",
2280
- command: `zinkee --json records query contacts --select id,contact-name,status,amount --where "status in 1,2" --where "amount gte 500" --sort amount:desc --sort contact-name:asc --limit 25`,
2730
+ description: "Patch number field (to percentage).",
2731
+ command: `zinkee --json schemas fields update contacts discount-rate --raw '{"type":"NumberField","config":{"defaultValue":"0","formatOptions":{"format":"percentage","decimals":1},"conditionalFormatting":[]}}'`,
2281
2732
  raw: `{
2282
- "select": ["id", "contact-name", "status", "amount"],
2283
- "where": [
2284
- { "field": "status", "op": "in", "value": [1, 2] },
2285
- { "field": "amount", "op": "gte", "value": 500 }
2286
- ],
2287
- "sort": [
2288
- { "field": "amount", "direction": "DESC" },
2289
- { "field": "contact-name", "direction": "ASC" }
2290
- ],
2291
- "page": { "offset": 0, "size": 25 }
2733
+ "type": "NumberField",
2734
+ "config": {
2735
+ "defaultValue": "0",
2736
+ "formatOptions": {
2737
+ "format": "percentage",
2738
+ "decimals": 1
2739
+ },
2740
+ "conditionalFormatting": []
2741
+ }
2292
2742
  }`
2293
2743
  },
2294
2744
  {
2295
- description: "Text contains search.",
2296
- command: 'zinkee --json records query contacts --select id,contact-name,contact-email --where "contact-name contains Lovelace" --limit 50',
2745
+ description: "Patch date field (to date only).",
2746
+ command: `zinkee --json schemas fields update contacts due-date --raw '{"type":"DateField","config":{"defaultValue":null,"formatOptions":{"format":"date","dateFormat":"YYYY-MM-DD","showTime":false},"conditionalFormatting":[]}}'`,
2297
2747
  raw: `{
2298
- "select": ["id", "contact-name", "contact-email"],
2299
- "where": [
2300
- { "field": "contact-name", "op": "contains", "value": "Lovelace" }
2301
- ],
2302
- "page": { "offset": 0, "size": 50 }
2748
+ "type": "DateField",
2749
+ "config": {
2750
+ "defaultValue": null,
2751
+ "formatOptions": {
2752
+ "format": "date",
2753
+ "dateFormat": "YYYY-MM-DD",
2754
+ "showTime": false
2755
+ },
2756
+ "conditionalFormatting": []
2757
+ }
2303
2758
  }`
2304
2759
  },
2305
2760
  {
2306
- description: "Records with a non-empty due-date inside a date range.",
2307
- command: 'zinkee --json records query contacts --where "due-date is_not_empty" --where "due-date lte 2026-12-31T23:59:59Z" --sort due-date:asc',
2761
+ description: "Patch option field (button cycle).",
2762
+ command: `zinkee --json schemas fields update contacts stage --raw '{"type":"OptionField","config":{"options":[{"id":1,"name":"To Do","color":"default"},{"id":2,"name":"Doing","color":"warning"},{"id":3,"name":"Done","color":"success"}],"defaultValue":1,"conditionalFormatting":[],"buttonConfig":{"displayMode":"button","buttonBehavior":{"mode":"cycle","cycleOrder":[1,2,3],"allowReselect":true}}}}'`,
2308
2763
  raw: `{
2309
- "where": [
2764
+ "type": "OptionField",
2765
+ "config": {
2766
+ "options": [
2767
+ { "id": 1, "name": "To Do", "color": "default" },
2768
+ { "id": 2, "name": "Doing", "color": "warning" },
2769
+ { "id": 3, "name": "Done", "color": "success" }
2770
+ ],
2771
+ "defaultValue": 1,
2772
+ "conditionalFormatting": [],
2773
+ "buttonConfig": {
2774
+ "displayMode": "button",
2775
+ "buttonBehavior": {
2776
+ "mode": "cycle",
2777
+ "cycleOrder": [1, 2, 3],
2778
+ "allowReselect": true
2779
+ }
2780
+ }
2781
+ }
2782
+ }`
2783
+ },
2784
+ {
2785
+ description: "Patch option field (drop button mode).",
2786
+ command: `zinkee --json schemas fields update contacts status --raw '{"type":"OptionField","config":{"options":[{"id":1,"name":"Open","color":"default"},{"id":2,"name":"In Progress","color":"warning"},{"id":3,"name":"Done","color":"success"}],"defaultValue":1,"conditionalFormatting":[],"buttonConfig":null}}'`,
2787
+ raw: `{
2788
+ "type": "OptionField",
2789
+ "config": {
2790
+ "options": [
2791
+ { "id": 1, "name": "Open", "color": "default" },
2792
+ { "id": 2, "name": "In Progress", "color": "warning" },
2793
+ { "id": 3, "name": "Done", "color": "success" }
2794
+ ],
2795
+ "defaultValue": 1,
2796
+ "conditionalFormatting": [],
2797
+ "buttonConfig": null
2798
+ }
2799
+ }`
2800
+ },
2801
+ {
2802
+ description: "Patch formula field (formula text).",
2803
+ command: `zinkee --json schemas fields update contacts formula-total --raw '{"type":"FormulaField","config":{"formulaText":"amount * 1.10","uiFormatKind":"number","status":"ACTIVE","numberFormatOptions":{"format":"number","decimals":2,"thousandsSeparator":true},"conditionalFormatting":[]}}'`,
2804
+ raw: `{
2805
+ "type": "FormulaField",
2806
+ "config": {
2807
+ "formulaText": "amount * 1.10",
2808
+ "uiFormatKind": "number",
2809
+ "status": "ACTIVE",
2810
+ "numberFormatOptions": {
2811
+ "format": "number",
2812
+ "decimals": 2,
2813
+ "thousandsSeparator": true
2814
+ },
2815
+ "conditionalFormatting": []
2816
+ }
2817
+ }`
2818
+ },
2819
+ {
2820
+ description: "Patch reference field (delete behavior).",
2821
+ command: `zinkee --json schemas fields update contacts customer-ref --raw '{"type":"ReferenceField","config":{"targetSchema":"5223cbc8-8c6c-4694-93bc-dd176364df9b","targetDisplayField":"c60b8526-5835-4c9f-aecd-9a16c7704a34","deleteBehavior":"RESTRICT","defaultValue":null,"filterFields":[],"descriptionFields":[],"conditionalFormatting":[]}}'`,
2822
+ raw: `{
2823
+ "type": "ReferenceField",
2824
+ "config": {
2825
+ "targetSchema": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
2826
+ "targetDisplayField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
2827
+ "deleteBehavior": "RESTRICT",
2828
+ "defaultValue": null,
2829
+ "filterFields": [],
2830
+ "descriptionFields": [],
2831
+ "conditionalFormatting": []
2832
+ }
2833
+ }`
2834
+ },
2835
+ {
2836
+ description: "Patch schedule field (to daily).",
2837
+ command: `zinkee --json schemas fields update contacts recurrence --raw '{"type":"ScheduleField","config":{"referenceField":"c52efe3f-2825-4c60-a7e3-34dd4c1ce043","beginningPeriodField":"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90","endingPeriodField":"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90","frequency":"daily"}}'`,
2838
+ raw: `{
2839
+ "type": "ScheduleField",
2840
+ "config": {
2841
+ "referenceField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
2842
+ "beginningPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2843
+ "endingPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
2844
+ "frequency": "daily"
2845
+ }
2846
+ }`
2847
+ }
2848
+ ]),
2849
+ "records query": buildCommandExamples([
2850
+ {
2851
+ description: "Lookup a single record by id.",
2852
+ command: 'zinkee --json records query contacts --select id,contact-name --where "id eq 550e8400-e29b-41d4-a716-446655440000" --sort id:desc --limit 10',
2853
+ raw: `{
2854
+ "select": ["id", "contact-name"],
2855
+ "where": [
2856
+ { "field": "id", "op": "eq", "value": "550e8400-e29b-41d4-a716-446655440000" }
2857
+ ],
2858
+ "sort": [
2859
+ { "field": "id", "direction": "DESC" }
2860
+ ],
2861
+ "page": { "offset": 0, "limit": 10 }
2862
+ }`,
2863
+ response: `{
2864
+ "records": [
2865
+ {
2866
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
2867
+ "values": {
2868
+ "contact-name": "Ada Lovelace",
2869
+ "status": 2,
2870
+ "amount": 1250.50
2871
+ }
2872
+ }
2873
+ ],
2874
+ "page": {
2875
+ "offset": 0,
2876
+ "limit": 25,
2877
+ "total": 1,
2878
+ "count": 1,
2879
+ "hasMore": false
2880
+ }
2881
+ }`
2882
+ },
2883
+ {
2884
+ description: "Filter by multiple conditions and sort by amount then name.",
2885
+ command: `zinkee --json records query contacts --select id,contact-name,status,amount --where "status in 1,2" --where "amount gte 500" --sort amount:desc --sort contact-name:asc --limit 25`,
2886
+ raw: `{
2887
+ "select": ["id", "contact-name", "status", "amount"],
2888
+ "where": [
2889
+ { "field": "status", "op": "in", "value": [1, 2] },
2890
+ { "field": "amount", "op": "gte", "value": 500 }
2891
+ ],
2892
+ "sort": [
2893
+ { "field": "amount", "direction": "DESC" },
2894
+ { "field": "contact-name", "direction": "ASC" }
2895
+ ],
2896
+ "page": { "offset": 0, "limit": 25 }
2897
+ }`
2898
+ },
2899
+ {
2900
+ description: "Filter by status with a free-text search term.",
2901
+ command: `zinkee --json records query contacts --select id,contact-name,status --where "status in OPEN" --limit 25 --raw '{"search":{"term":"garcia"}}'`,
2902
+ raw: `{
2903
+ "select": ["id", "contact-name", "status"],
2904
+ "where": [
2905
+ { "field": "status", "op": "in", "value": ["OPEN"] }
2906
+ ],
2907
+ "search": { "term": "garcia" },
2908
+ "page": { "offset": 0, "limit": 25 }
2909
+ }`
2910
+ },
2911
+ {
2912
+ description: "Text contains search.",
2913
+ command: 'zinkee --json records query contacts --select id,contact-name,contact-email --where "contact-name contains Lovelace" --limit 50',
2914
+ raw: `{
2915
+ "select": ["id", "contact-name", "contact-email"],
2916
+ "where": [
2917
+ { "field": "contact-name", "op": "contains", "value": "Lovelace" }
2918
+ ],
2919
+ "page": { "offset": 0, "limit": 50 }
2920
+ }`
2921
+ },
2922
+ {
2923
+ description: "Records with a non-empty due-date inside a date range.",
2924
+ command: 'zinkee --json records query contacts --where "due-date is_not_empty" --where "due-date lte 2026-12-31T23:59:59Z" --sort due-date:asc',
2925
+ raw: `{
2926
+ "where": [
2310
2927
  { "field": "due-date", "op": "is_not_empty" },
2311
2928
  { "field": "due-date", "op": "lte", "value": "2026-12-31T23:59:59Z" }
2312
2929
  ],
@@ -3453,27 +4070,22 @@ var specificExamples = {
3453
4070
  "required": true,
3454
4071
  "system": false,
3455
4072
  "config": {
3456
- "textType": "LONG",
4073
+ "textType": "NORMAL",
3457
4074
  "defaultValue": "Unknown",
3458
4075
  "conditionalFormatting": []
3459
4076
  }
3460
4077
  },
3461
4078
  {
3462
- "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3463
- "type": "OptionField",
3464
- "slug": "status",
3465
- "label": "Status",
4079
+ "id": "1d2e3f4a-5b6c-7d8e-9f01-23456789abcd",
4080
+ "type": "TextField",
4081
+ "slug": "notes",
4082
+ "label": "Notes",
3466
4083
  "required": false,
3467
4084
  "system": false,
3468
4085
  "config": {
3469
- "options": [
3470
- { "id": 1, "name": "Open", "color": "default" },
3471
- { "id": 2, "name": "In Progress", "color": "warning" },
3472
- { "id": 3, "name": "Done", "color": "success" }
3473
- ],
3474
- "defaultValue": 1,
3475
- "conditionalFormatting": [],
3476
- "buttonConfig": null
4086
+ "textType": "LONG",
4087
+ "defaultValue": null,
4088
+ "conditionalFormatting": []
3477
4089
  }
3478
4090
  },
3479
4091
  {
@@ -3497,6 +4109,40 @@ var specificExamples = {
3497
4109
  "conditionalFormatting": []
3498
4110
  }
3499
4111
  },
4112
+ {
4113
+ "id": "2f3a4b5c-6d7e-8f90-1234-56789abcdef0",
4114
+ "type": "NumberField",
4115
+ "slug": "quantity",
4116
+ "label": "Quantity",
4117
+ "required": false,
4118
+ "system": false,
4119
+ "config": {
4120
+ "defaultValue": "0",
4121
+ "formatOptions": {
4122
+ "format": "number",
4123
+ "decimals": 0,
4124
+ "thousandsSeparator": false
4125
+ },
4126
+ "conditionalFormatting": []
4127
+ }
4128
+ },
4129
+ {
4130
+ "id": "3a4b5c6d-7e8f-9012-3456-789abcdef012",
4131
+ "type": "NumberField",
4132
+ "slug": "discount-rate",
4133
+ "label": "Discount Rate",
4134
+ "required": false,
4135
+ "system": false,
4136
+ "config": {
4137
+ "defaultValue": "0",
4138
+ "formatOptions": {
4139
+ "format": "percentage",
4140
+ "decimals": 1,
4141
+ "negativesInRed": true
4142
+ },
4143
+ "conditionalFormatting": []
4144
+ }
4145
+ },
3500
4146
  {
3501
4147
  "id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
3502
4148
  "type": "DateField",
@@ -3515,77 +4161,274 @@ var specificExamples = {
3515
4161
  }
3516
4162
  },
3517
4163
  {
3518
- "id": "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
3519
- "type": "MemberField",
3520
- "slug": "owner",
3521
- "label": "Owner",
4164
+ "id": "4b5c6d7e-8f90-1234-5678-9abcdef01234",
4165
+ "type": "DateField",
4166
+ "slug": "birth-date",
4167
+ "label": "Birth Date",
3522
4168
  "required": false,
3523
4169
  "system": false,
3524
4170
  "config": {
3525
4171
  "defaultValue": null,
4172
+ "formatOptions": {
4173
+ "format": "date",
4174
+ "dateFormat": "YYYY-MM-DD",
4175
+ "showTime": false
4176
+ },
3526
4177
  "conditionalFormatting": []
3527
4178
  }
3528
- }
3529
- ]
3530
- }`
3531
- }
3532
- ]),
3533
- "schemas delete": buildCommandExamples([
4179
+ },
3534
4180
  {
3535
- description: "Delete a schema (also removes it from navigation folders).",
3536
- command: "zinkee --json schemas delete contacts",
3537
- response: `{
3538
- "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
3539
- "deleted": true
3540
- }`
3541
- }
3542
- ]),
3543
- "schemas fields list": buildCommandExamples([
4181
+ "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
4182
+ "type": "OptionField",
4183
+ "slug": "status",
4184
+ "label": "Status",
4185
+ "required": false,
4186
+ "system": false,
4187
+ "config": {
4188
+ "options": [
4189
+ { "id": 1, "name": "Open", "color": "default" },
4190
+ { "id": 2, "name": "In Progress", "color": "warning" },
4191
+ { "id": 3, "name": "Done", "color": "success" }
4192
+ ],
4193
+ "defaultValue": 1,
4194
+ "conditionalFormatting": [],
4195
+ "buttonConfig": null
4196
+ }
4197
+ },
3544
4198
  {
3545
- description: "List the fields of a schema (fields are inlined in the schema resource).",
3546
- command: "zinkee --json schemas fields list contacts",
3547
- response: `[
3548
- {
3549
- "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
3550
- "type": "TextField",
3551
- "slug": "contact-name",
3552
- "label": "Customer Name",
3553
- "required": true,
3554
- "system": false,
3555
- "config": {
3556
- "textType": "LONG",
3557
- "defaultValue": "Unknown",
3558
- "conditionalFormatting": []
3559
- }
3560
- },
3561
- {
3562
- "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3563
- "type": "OptionField",
3564
- "slug": "status",
3565
- "label": "Status",
3566
- "required": false,
3567
- "system": false,
3568
- "config": {
3569
- "options": [
3570
- { "id": 1, "name": "Open", "color": "default" },
3571
- { "id": 2, "name": "In Progress", "color": "warning" },
3572
- { "id": 3, "name": "Done", "color": "success" }
3573
- ],
3574
- "defaultValue": 1,
3575
- "conditionalFormatting": [],
3576
- "buttonConfig": null
3577
- }
3578
- }
3579
- ]`
3580
- }
3581
- ]),
3582
- "schemas fields get": buildCommandExamples([
4199
+ "id": "5c6d7e8f-9012-3456-789a-bcdef0123456",
4200
+ "type": "OptionField",
4201
+ "slug": "stage",
4202
+ "label": "Stage",
4203
+ "required": false,
4204
+ "system": false,
4205
+ "config": {
4206
+ "options": [
4207
+ { "id": 1, "name": "To Do", "color": "default" },
4208
+ { "id": 2, "name": "Doing", "color": "warning" },
4209
+ { "id": 3, "name": "Done", "color": "success" }
4210
+ ],
4211
+ "defaultValue": 1,
4212
+ "conditionalFormatting": [],
4213
+ "buttonConfig": {
4214
+ "displayMode": "button",
4215
+ "buttonBehavior": {
4216
+ "mode": "cycle",
4217
+ "cycleOrder": [1, 2, 3],
4218
+ "requireConfirmation": false,
4219
+ "lockAfterSelection": false,
4220
+ "allowReselect": true
4221
+ }
4222
+ }
4223
+ }
4224
+ },
3583
4225
  {
3584
- description: "Get a schema field (returns the full typed field contract).",
3585
- command: "zinkee --json schemas fields get contacts status",
3586
- response: `{
3587
- "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
3588
- "type": "OptionField",
4226
+ "id": "3e9f8c12-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
4227
+ "type": "FormulaField",
4228
+ "slug": "formula-total",
4229
+ "label": "Formula Total",
4230
+ "required": false,
4231
+ "system": false,
4232
+ "config": {
4233
+ "formulaText": "amount * 1.21",
4234
+ "uiFormatKind": "number",
4235
+ "status": "ACTIVE",
4236
+ "defaultValue": null,
4237
+ "numberFormatOptions": {
4238
+ "format": "number",
4239
+ "decimals": 2,
4240
+ "thousandsSeparator": true
4241
+ },
4242
+ "conditionalFormatting": []
4243
+ }
4244
+ },
4245
+ {
4246
+ "id": "6d7e8f90-1234-5678-9abc-def012345678",
4247
+ "type": "FormulaField",
4248
+ "slug": "formula-deadline",
4249
+ "label": "Computed Deadline",
4250
+ "required": false,
4251
+ "system": false,
4252
+ "config": {
4253
+ "formulaText": "addDays(startDate, 7)",
4254
+ "uiFormatKind": "date",
4255
+ "status": "ACTIVE",
4256
+ "defaultValue": null,
4257
+ "dateFormatOptions": {
4258
+ "format": "date",
4259
+ "dateFormat": "DD/MM/YYYY",
4260
+ "showTime": false
4261
+ },
4262
+ "conditionalFormatting": []
4263
+ }
4264
+ },
4265
+ {
4266
+ "id": "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
4267
+ "type": "ReferenceField",
4268
+ "slug": "customer-ref",
4269
+ "label": "Customer",
4270
+ "required": false,
4271
+ "system": false,
4272
+ "config": {
4273
+ "targetSchema": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
4274
+ "targetDisplayField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4275
+ "deleteBehavior": "SET_NULL",
4276
+ "defaultValue": null,
4277
+ "filterFields": [],
4278
+ "descriptionFields": [],
4279
+ "conditionalFormatting": []
4280
+ }
4281
+ },
4282
+ {
4283
+ "id": "7e8f9012-3456-789a-bcde-f01234567890",
4284
+ "type": "ReferenceField",
4285
+ "slug": "company-ref",
4286
+ "label": "Company",
4287
+ "required": false,
4288
+ "system": false,
4289
+ "config": {
4290
+ "targetSchema": "5223cbc8-8c6c-4694-93bc-dd176364df9b",
4291
+ "targetDisplayField": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4292
+ "deleteBehavior": "RESTRICT",
4293
+ "defaultValue": null,
4294
+ "filterFields": [],
4295
+ "descriptionFields": [],
4296
+ "conditionalFormatting": []
4297
+ }
4298
+ },
4299
+ {
4300
+ "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
4301
+ "type": "AutoIncrementalField",
4302
+ "slug": "sequence-code",
4303
+ "label": "Sequence Code",
4304
+ "required": false,
4305
+ "system": true,
4306
+ "config": {
4307
+ "segmentedByFieldId": "45c5da96-0dc2-4cc1-ba61-7660a9c6da32",
4308
+ "conditionalFormatting": []
4309
+ }
4310
+ },
4311
+ {
4312
+ "id": "8f901234-5678-9abc-def0-123456789012",
4313
+ "type": "AutoIncrementalField",
4314
+ "slug": "order-number",
4315
+ "label": "Order Number",
4316
+ "required": false,
4317
+ "system": true,
4318
+ "config": {
4319
+ "segmentedByFieldId": null,
4320
+ "conditionalFormatting": []
4321
+ }
4322
+ },
4323
+ {
4324
+ "id": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9012",
4325
+ "type": "FileField",
4326
+ "slug": "attachment",
4327
+ "label": "Attachment",
4328
+ "required": false,
4329
+ "system": false,
4330
+ "config": {}
4331
+ },
4332
+ {
4333
+ "id": "f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f901234",
4334
+ "type": "ScheduleField",
4335
+ "slug": "recurrence",
4336
+ "label": "Recurrence",
4337
+ "required": false,
4338
+ "system": false,
4339
+ "config": {
4340
+ "referenceField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
4341
+ "beginningPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
4342
+ "endingPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
4343
+ "frequency": "monthly"
4344
+ }
4345
+ },
4346
+ {
4347
+ "id": "9012abcd-ef01-2345-6789-abcdef012345",
4348
+ "type": "ScheduleField",
4349
+ "slug": "daily-recurrence",
4350
+ "label": "Daily Recurrence",
4351
+ "required": false,
4352
+ "system": false,
4353
+ "config": {
4354
+ "referenceField": "c52efe3f-2825-4c60-a7e3-34dd4c1ce043",
4355
+ "beginningPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
4356
+ "endingPeriodField": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
4357
+ "frequency": "daily"
4358
+ }
4359
+ },
4360
+ {
4361
+ "id": "a7b8c9d0-e1f2-3a4b-5c6d-7e8f90123456",
4362
+ "type": "MemberField",
4363
+ "slug": "owner",
4364
+ "label": "Owner",
4365
+ "required": false,
4366
+ "system": false,
4367
+ "config": {
4368
+ "defaultValue": null,
4369
+ "conditionalFormatting": []
4370
+ }
4371
+ }
4372
+ ]
4373
+ }`
4374
+ }
4375
+ ]),
4376
+ "schemas delete": buildCommandExamples([
4377
+ {
4378
+ description: "Delete a schema (also removes it from navigation folders).",
4379
+ command: "zinkee --json schemas delete contacts",
4380
+ response: `{
4381
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
4382
+ "deleted": true
4383
+ }`
4384
+ }
4385
+ ]),
4386
+ "schemas fields list": buildCommandExamples([
4387
+ {
4388
+ description: "List the fields of a schema (fields are inlined in the schema resource).",
4389
+ command: "zinkee --json schemas fields list contacts",
4390
+ response: `[
4391
+ {
4392
+ "id": "c60b8526-5835-4c9f-aecd-9a16c7704a34",
4393
+ "type": "TextField",
4394
+ "slug": "contact-name",
4395
+ "label": "Customer Name",
4396
+ "required": true,
4397
+ "system": false,
4398
+ "config": {
4399
+ "textType": "LONG",
4400
+ "defaultValue": "Unknown",
4401
+ "conditionalFormatting": []
4402
+ }
4403
+ },
4404
+ {
4405
+ "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
4406
+ "type": "OptionField",
4407
+ "slug": "status",
4408
+ "label": "Status",
4409
+ "required": false,
4410
+ "system": false,
4411
+ "config": {
4412
+ "options": [
4413
+ { "id": 1, "name": "Open", "color": "default" },
4414
+ { "id": 2, "name": "In Progress", "color": "warning" },
4415
+ { "id": 3, "name": "Done", "color": "success" }
4416
+ ],
4417
+ "defaultValue": 1,
4418
+ "conditionalFormatting": [],
4419
+ "buttonConfig": null
4420
+ }
4421
+ }
4422
+ ]`
4423
+ }
4424
+ ]),
4425
+ "schemas fields get": buildCommandExamples([
4426
+ {
4427
+ description: "Get a schema field (returns the full typed field contract).",
4428
+ command: "zinkee --json schemas fields get contacts status",
4429
+ response: `{
4430
+ "id": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
4431
+ "type": "OptionField",
3589
4432
  "slug": "status",
3590
4433
  "label": "Status",
3591
4434
  "required": false,
@@ -3717,6 +4560,47 @@ var specificExamples = {
3717
4560
  { "type": "TEXT", "value": " for follow up." }
3718
4561
  ]
3719
4562
  }
4563
+ ]`
4564
+ }
4565
+ ]),
4566
+ "logs list": buildCommandExamples([
4567
+ {
4568
+ description: "List the change history for a record (CREATE entry plus UPDATE entries with before/after values per field).",
4569
+ command: `zinkee --json logs list contacts ${SAMPLE_UUID}`,
4570
+ response: `[
4571
+ {
4572
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
4573
+ "timestamp": "2026-04-22T10:00:00Z",
4574
+ "changeField": "",
4575
+ "change": {
4576
+ "beforeValue": null,
4577
+ "afterValue": null,
4578
+ "author": "developer@zinkee.com",
4579
+ "operation": "CREATE"
4580
+ }
4581
+ },
4582
+ {
4583
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
4584
+ "timestamp": "2026-04-22T10:15:00Z",
4585
+ "changeField": "status",
4586
+ "change": {
4587
+ "beforeValue": "1",
4588
+ "afterValue": "2",
4589
+ "author": "developer@zinkee.com",
4590
+ "operation": "UPDATE"
4591
+ }
4592
+ },
4593
+ {
4594
+ "recordId": "550e8400-e29b-41d4-a716-446655440000",
4595
+ "timestamp": "2026-04-22T10:20:00Z",
4596
+ "changeField": "amount",
4597
+ "change": {
4598
+ "beforeValue": "1000.00",
4599
+ "afterValue": "1250.50",
4600
+ "author": "developer@zinkee.com",
4601
+ "operation": "UPDATE"
4602
+ }
4603
+ }
3720
4604
  ]`
3721
4605
  }
3722
4606
  ]),
@@ -5007,24 +5891,28 @@ function buildSchemaFieldCreateExamples(type) {
5007
5891
  const definitions = getSchemaFieldTypeDefinitions();
5008
5892
  const selectedDefinition = resolveSchemaFieldType(type);
5009
5893
  const filteredDefinitions = selectedDefinition ? definitions.filter((definition) => definition.key === selectedDefinition.key) : definitions;
5894
+ const flat = filteredDefinitions.flatMap(
5895
+ (definition) => definition.examplePayloads.map((example) => ({ definition, example }))
5896
+ );
5010
5897
  return buildCommandExamples(
5011
- filteredDefinitions.flatMap((definition) => {
5012
- if (definition.key !== "number") {
5013
- return [{
5014
- description: `Create a ${definition.key} field`,
5015
- command: `zinkee --json schemas fields create contacts --raw '${JSON.stringify(definition.examplePayload)}'`
5016
- }];
5898
+ flat.map(({ example }, index) => {
5899
+ const slug = typeof example.payload.slug === "string" ? example.payload.slug : "field";
5900
+ const command = `zinkee --json schemas fields create contacts --raw '${JSON.stringify(example.payload)}'`;
5901
+ if (index === 0) {
5902
+ return {
5903
+ description: example.name,
5904
+ command,
5905
+ response: `{
5906
+ "schemaId": "2eb8bdcf-6d9c-4fbb-9018-7fa8180f4c5e",
5907
+ "fieldId": "a8f1d7e3-2b5c-4d9e-8a1b-3c4d5e6f7890",
5908
+ "slug": "${slug}"
5909
+ }`
5910
+ };
5017
5911
  }
5018
- return [
5019
- {
5020
- description: "Create a required number field with a default value",
5021
- command: "zinkee --json schemas fields create contacts --type number --slug amount --label Amount --required true --default 0"
5022
- },
5023
- {
5024
- description: "Create a number field formatted like Moneda",
5025
- command: `zinkee --json schemas fields create contacts --raw '${JSON.stringify(definition.examplePayload)}'`
5026
- }
5027
- ];
5912
+ return {
5913
+ description: example.name,
5914
+ command
5915
+ };
5028
5916
  })
5029
5917
  );
5030
5918
  }
@@ -5617,7 +6505,7 @@ ${index + 1}. ${example.description}
5617
6505
 
5618
6506
  // src/program.ts
5619
6507
  import { createRequire } from "module";
5620
- import { Command as Command9 } from "commander";
6508
+ import { Command as Command10 } from "commander";
5621
6509
 
5622
6510
  // src/commands/config.ts
5623
6511
  function getCommandIo(stdout) {
@@ -8110,57 +8998,25 @@ function registerFilesCommands(program, options = {}) {
8110
8998
  });
8111
8999
  }
8112
9000
 
8113
- // src/commands/navigation.ts
8114
- import { readFileSync as readFileSync6 } from "fs";
9001
+ // src/commands/logs.ts
8115
9002
  import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
8116
9003
 
8117
- // src/api/navigation.ts
8118
- function jsonOptions5(body, method) {
8119
- return {
8120
- method,
8121
- headers: {
8122
- "content-type": "application/json"
8123
- },
8124
- body: JSON.stringify(body)
8125
- };
8126
- }
9004
+ // src/api/logs.ts
8127
9005
  function selectorValue6(selector2) {
8128
9006
  return selector2.value;
8129
9007
  }
8130
- var NavigationApi = class {
9008
+ var LogsApi = class {
8131
9009
  constructor(client) {
8132
9010
  this.client = client;
8133
9011
  }
8134
- listFolders() {
8135
- return this.client.getJson("/api/v2/navigation/folders");
8136
- }
8137
- createFolder(body) {
8138
- return this.client.requestJson(
8139
- "/api/v2/navigation/folders",
8140
- jsonOptions5(body, "POST")
8141
- );
8142
- }
8143
- updateFolder(folder, body) {
8144
- return this.client.requestJson(
8145
- `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8146
- jsonOptions5(body, "PATCH")
8147
- );
8148
- }
8149
- deleteFolder(folder) {
8150
- return this.client.requestJson(
8151
- `/api/v2/navigation/folders/${selectorValue6(folder)}`,
8152
- { method: "DELETE" }
8153
- );
8154
- }
8155
- moveResource(body) {
8156
- return this.client.requestJson(
8157
- "/api/v2/navigation/resources:move",
8158
- jsonOptions5(body, "POST")
9012
+ listLogs(schema, recordId) {
9013
+ return this.client.getJson(
9014
+ `/api/v2/schemas/${selectorValue6(schema)}/records/${recordId}/logs`
8159
9015
  );
8160
9016
  }
8161
9017
  };
8162
9018
 
8163
- // src/commands/navigation.ts
9019
+ // src/commands/logs.ts
8164
9020
  function getCommandIo6(stdout) {
8165
9021
  return stdout ?? process.stdout;
8166
9022
  }
@@ -8171,8 +9027,11 @@ function writeLine6(stdout, value) {
8171
9027
  function getGlobalOptions6(command) {
8172
9028
  return command.optsWithGlobals();
8173
9029
  }
8174
- function emitJson6(stdout, commandName, data, configPath) {
8175
- writeLine6(stdout, JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath })));
9030
+ function emitJson6(stdout, commandName, data, ..._extra) {
9031
+ writeLine6(
9032
+ stdout,
9033
+ JSON.stringify(buildJsonSuccess(data, { command: commandName }))
9034
+ );
8176
9035
  }
8177
9036
  function toConfigurationError6(filePath, error) {
8178
9037
  if (error instanceof CliError) {
@@ -8186,36 +9045,29 @@ function toConfigurationError6(filePath, error) {
8186
9045
  }
8187
9046
  throw error;
8188
9047
  }
8189
- function createNavigationApi(command, filePath) {
9048
+ function createLogsApi(command, filePath) {
8190
9049
  try {
8191
9050
  const config = readRuntimeConfig(filePath);
8192
9051
  const runtime = resolveRuntimeContext(config, getGlobalOptions6(command));
8193
9052
  if (!runtime.baseUrl) {
8194
- throw new CliError("configuration_error", `Resolved profile "${runtime.profile}" is missing a base URL.`);
9053
+ throw new CliError(
9054
+ "configuration_error",
9055
+ `Resolved profile "${runtime.profile}" is missing a base URL.`
9056
+ );
8195
9057
  }
8196
9058
  return {
8197
- api: new NavigationApi(
9059
+ api: new LogsApi(
8198
9060
  new ApiClient({
8199
9061
  baseUrl: runtime.baseUrl,
8200
9062
  apiKey: runtime.apiKey
8201
9063
  })
8202
9064
  ),
8203
- json: runtime.json,
8204
- readOnly: runtime.readOnly
9065
+ json: runtime.json
8205
9066
  };
8206
9067
  } catch (error) {
8207
9068
  toConfigurationError6(filePath, error);
8208
9069
  }
8209
9070
  }
8210
- function ensureWritable5(commandName, readOnly, mode) {
8211
- if (readOnly) {
8212
- throw new CliError(
8213
- "command_not_allowed_in_read_only_mode",
8214
- `Command "${commandName}" is not allowed in read-only mode.`,
8215
- { commandMode: mode, executionMode: "read-only" }
8216
- );
8217
- }
8218
- }
8219
9071
  function parseUuidOrSlugSelector5(input) {
8220
9072
  try {
8221
9073
  return normalizeUuidOrSlug(input);
@@ -8224,35 +9076,179 @@ function parseUuidOrSlugSelector5(input) {
8224
9076
  throw new InvalidArgumentError5(message);
8225
9077
  }
8226
9078
  }
8227
- function parseInteger(value, flagName) {
8228
- if (value === void 0) {
8229
- return void 0;
8230
- }
8231
- const parsed = Number.parseInt(value, 10);
8232
- if (Number.isNaN(parsed)) {
8233
- throw new CliError("invalid_cli_usage", `${flagName} must be an integer.`);
8234
- }
8235
- return parsed;
9079
+ function isJsonObject4(value) {
9080
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8236
9081
  }
8237
- function readJsonObject(raw, rawFile) {
8238
- if (raw && rawFile) {
8239
- throw new CliError("invalid_cli_usage", 'Use either "--props" or "--props-file", not both.');
9082
+ function toTableRows3(data) {
9083
+ if (Array.isArray(data)) {
9084
+ return data.map((entry) => isJsonObject4(entry) ? entry : { value: entry });
8240
9085
  }
8241
- const source = rawFile ? readFileSync6(rawFile, "utf8") : raw;
8242
- if (!source) {
8243
- return {};
9086
+ if (isJsonObject4(data)) {
9087
+ return [data];
8244
9088
  }
8245
- try {
8246
- const parsed = JSON.parse(source);
8247
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
8248
- throw new CliError("invalid_cli_usage", "Props payload must be a JSON object.");
8249
- }
8250
- return parsed;
8251
- } catch (error) {
8252
- if (error instanceof CliError) {
8253
- throw error;
8254
- }
8255
- throw new CliError("invalid_cli_usage", "Props payload is invalid JSON.");
9089
+ return [{ value: data }];
9090
+ }
9091
+ function emitTable3(stdout, data) {
9092
+ printTable(toTableRows3(data), void 0, stdout);
9093
+ }
9094
+ function registerLogsCommands(program, options = {}) {
9095
+ const filePath = options.configPath ?? defaultConfigPath;
9096
+ const stdout = getCommandIo6(options.stdout);
9097
+ const logs = program.command("logs").description("Inspect record change logs");
9098
+ logs.command("list").description("List change logs for a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector5).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector5).action(async function action(schema, record) {
9099
+ const { api, json } = createLogsApi(this, filePath);
9100
+ const data = await api.listLogs(schema, record.value);
9101
+ if (json) {
9102
+ emitJson6(stdout, "logs list", data, filePath);
9103
+ return;
9104
+ }
9105
+ emitTable3(stdout, data);
9106
+ });
9107
+ }
9108
+
9109
+ // src/commands/navigation.ts
9110
+ import { readFileSync as readFileSync6 } from "fs";
9111
+ import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
9112
+
9113
+ // src/api/navigation.ts
9114
+ function jsonOptions5(body, method) {
9115
+ return {
9116
+ method,
9117
+ headers: {
9118
+ "content-type": "application/json"
9119
+ },
9120
+ body: JSON.stringify(body)
9121
+ };
9122
+ }
9123
+ function selectorValue7(selector2) {
9124
+ return selector2.value;
9125
+ }
9126
+ var NavigationApi = class {
9127
+ constructor(client) {
9128
+ this.client = client;
9129
+ }
9130
+ listFolders() {
9131
+ return this.client.getJson("/api/v2/navigation/folders");
9132
+ }
9133
+ createFolder(body) {
9134
+ return this.client.requestJson(
9135
+ "/api/v2/navigation/folders",
9136
+ jsonOptions5(body, "POST")
9137
+ );
9138
+ }
9139
+ updateFolder(folder, body) {
9140
+ return this.client.requestJson(
9141
+ `/api/v2/navigation/folders/${selectorValue7(folder)}`,
9142
+ jsonOptions5(body, "PATCH")
9143
+ );
9144
+ }
9145
+ deleteFolder(folder) {
9146
+ return this.client.requestJson(
9147
+ `/api/v2/navigation/folders/${selectorValue7(folder)}`,
9148
+ { method: "DELETE" }
9149
+ );
9150
+ }
9151
+ moveResource(body) {
9152
+ return this.client.requestJson(
9153
+ "/api/v2/navigation/resources:move",
9154
+ jsonOptions5(body, "POST")
9155
+ );
9156
+ }
9157
+ };
9158
+
9159
+ // src/commands/navigation.ts
9160
+ function getCommandIo7(stdout) {
9161
+ return stdout ?? process.stdout;
9162
+ }
9163
+ function writeLine7(stdout, value) {
9164
+ stdout.write(`${value}
9165
+ `);
9166
+ }
9167
+ function getGlobalOptions7(command) {
9168
+ return command.optsWithGlobals();
9169
+ }
9170
+ function emitJson7(stdout, commandName, data, configPath) {
9171
+ writeLine7(stdout, JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath })));
9172
+ }
9173
+ function toConfigurationError7(filePath, error) {
9174
+ if (error instanceof CliError) {
9175
+ throw error;
9176
+ }
9177
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
9178
+ throw new CliError("configuration_error", `Config file not found at ${filePath}.`);
9179
+ }
9180
+ if (error instanceof Error) {
9181
+ throw new CliError("configuration_error", error.message);
9182
+ }
9183
+ throw error;
9184
+ }
9185
+ function createNavigationApi(command, filePath) {
9186
+ try {
9187
+ const config = readRuntimeConfig(filePath);
9188
+ const runtime = resolveRuntimeContext(config, getGlobalOptions7(command));
9189
+ if (!runtime.baseUrl) {
9190
+ throw new CliError("configuration_error", `Resolved profile "${runtime.profile}" is missing a base URL.`);
9191
+ }
9192
+ return {
9193
+ api: new NavigationApi(
9194
+ new ApiClient({
9195
+ baseUrl: runtime.baseUrl,
9196
+ apiKey: runtime.apiKey
9197
+ })
9198
+ ),
9199
+ json: runtime.json,
9200
+ readOnly: runtime.readOnly
9201
+ };
9202
+ } catch (error) {
9203
+ toConfigurationError7(filePath, error);
9204
+ }
9205
+ }
9206
+ function ensureWritable5(commandName, readOnly, mode) {
9207
+ if (readOnly) {
9208
+ throw new CliError(
9209
+ "command_not_allowed_in_read_only_mode",
9210
+ `Command "${commandName}" is not allowed in read-only mode.`,
9211
+ { commandMode: mode, executionMode: "read-only" }
9212
+ );
9213
+ }
9214
+ }
9215
+ function parseUuidOrSlugSelector6(input) {
9216
+ try {
9217
+ return normalizeUuidOrSlug(input);
9218
+ } catch (error) {
9219
+ const message = error instanceof Error ? error.message : "Invalid selector.";
9220
+ throw new InvalidArgumentError6(message);
9221
+ }
9222
+ }
9223
+ function parseInteger(value, flagName) {
9224
+ if (value === void 0) {
9225
+ return void 0;
9226
+ }
9227
+ const parsed = Number.parseInt(value, 10);
9228
+ if (Number.isNaN(parsed)) {
9229
+ throw new CliError("invalid_cli_usage", `${flagName} must be an integer.`);
9230
+ }
9231
+ return parsed;
9232
+ }
9233
+ function readJsonObject(raw, rawFile) {
9234
+ if (raw && rawFile) {
9235
+ throw new CliError("invalid_cli_usage", 'Use either "--props" or "--props-file", not both.');
9236
+ }
9237
+ const source = rawFile ? readFileSync6(rawFile, "utf8") : raw;
9238
+ if (!source) {
9239
+ return {};
9240
+ }
9241
+ try {
9242
+ const parsed = JSON.parse(source);
9243
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
9244
+ throw new CliError("invalid_cli_usage", "Props payload must be a JSON object.");
9245
+ }
9246
+ return parsed;
9247
+ } catch (error) {
9248
+ if (error instanceof CliError) {
9249
+ throw error;
9250
+ }
9251
+ throw new CliError("invalid_cli_usage", "Props payload is invalid JSON.");
8256
9252
  }
8257
9253
  }
8258
9254
  function buildFolderBody(options) {
@@ -8300,24 +9296,24 @@ function folderRows2(folders) {
8300
9296
  }
8301
9297
  function registerNavigationCommands(program, options = {}) {
8302
9298
  const filePath = options.configPath ?? defaultConfigPath;
8303
- const stdout = getCommandIo6(options.stdout);
9299
+ const stdout = getCommandIo7(options.stdout);
8304
9300
  const navigation = program.command("navigation").description("Manage workspace navigation");
8305
9301
  const folders = navigation.command("folders").description("Manage navigation folders");
8306
9302
  folders.command("list").description("List navigation folders").action(async function action() {
8307
9303
  const { api, json } = createNavigationApi(this, filePath);
8308
9304
  const data = await api.listFolders();
8309
9305
  if (json) {
8310
- emitJson6(stdout, "navigation folders list", data, filePath);
9306
+ emitJson7(stdout, "navigation folders list", data, filePath);
8311
9307
  return;
8312
9308
  }
8313
9309
  printTable(folderRows2(data), ["id", "order", "name", "resourceCount"], stdout);
8314
9310
  });
8315
- folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector5).action(async function action(folder) {
9311
+ folders.command("get").description("Get a navigation folder by UUID or exact name").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).action(async function action(folder) {
8316
9312
  const { api, json } = createNavigationApi(this, filePath);
8317
9313
  const data = await api.listFolders();
8318
9314
  const resolved = resolveFolder2(data, folder);
8319
9315
  if (json) {
8320
- emitJson6(stdout, "navigation folders get", resolved, filePath);
9316
+ emitJson7(stdout, "navigation folders get", resolved, filePath);
8321
9317
  return;
8322
9318
  }
8323
9319
  printTable(folderRows2([resolved]), ["id", "order", "name", "resourceCount"], stdout);
@@ -8327,12 +9323,12 @@ function registerNavigationCommands(program, options = {}) {
8327
9323
  ensureWritable5("navigation folders create", readOnly, "write");
8328
9324
  const data = await api.createFolder(buildFolderBody(commandOptions));
8329
9325
  if (json) {
8330
- emitJson6(stdout, "navigation folders create", data, filePath);
9326
+ emitJson7(stdout, "navigation folders create", data, filePath);
8331
9327
  return;
8332
9328
  }
8333
- writeLine6(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
9329
+ writeLine7(stdout, `Created navigation folder "${String(data.name ?? commandOptions.name)}".`);
8334
9330
  });
8335
- folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector5).option("--name <name>", "folder name").option("--order <n>", "folder order").option("--props <json>", "folder additionalProperties JSON").option("--props-file <path>", "folder additionalProperties JSON file").action(async function action(folder, commandOptions) {
9331
+ folders.command("update").description("Update a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).option("--name <name>", "folder name").option("--order <n>", "folder order").option("--props <json>", "folder additionalProperties JSON").option("--props-file <path>", "folder additionalProperties JSON file").action(async function action(folder, commandOptions) {
8336
9332
  const { api, json, readOnly } = createNavigationApi(this, filePath);
8337
9333
  ensureWritable5("navigation folders update", readOnly, "write");
8338
9334
  const allFolders = await api.listFolders();
@@ -8343,54 +9339,54 @@ function registerNavigationCommands(program, options = {}) {
8343
9339
  }
8344
9340
  const data = await api.updateFolder({ kind: "uuid", value: resolved.id }, body);
8345
9341
  if (json) {
8346
- emitJson6(stdout, "navigation folders update", data, filePath);
9342
+ emitJson7(stdout, "navigation folders update", data, filePath);
8347
9343
  return;
8348
9344
  }
8349
- writeLine6(stdout, `Updated navigation folder "${String(data.name ?? resolved.name ?? resolved.id)}".`);
9345
+ writeLine7(stdout, `Updated navigation folder "${String(data.name ?? resolved.name ?? resolved.id)}".`);
8350
9346
  });
8351
- folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector5).action(async function action(folder) {
9347
+ folders.command("delete").description("Delete a navigation folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector6).action(async function action(folder) {
8352
9348
  const { api, json, readOnly } = createNavigationApi(this, filePath);
8353
9349
  ensureWritable5("navigation folders delete", readOnly, "destructive");
8354
9350
  const allFolders = await api.listFolders();
8355
9351
  const resolved = resolveFolder2(allFolders, folder);
8356
9352
  const data = await api.deleteFolder({ kind: "uuid", value: resolved.id });
8357
9353
  if (json) {
8358
- emitJson6(stdout, "navigation folders delete", data, filePath);
9354
+ emitJson7(stdout, "navigation folders delete", data, filePath);
8359
9355
  return;
8360
9356
  }
8361
- writeLine6(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
9357
+ writeLine7(stdout, `Deleted navigation folder "${resolved.name ?? resolved.id}".`);
8362
9358
  });
8363
9359
  navigation.command("resources").description("Manage navigation resources").command("move").description("Move a resource into a folder").argument("<resource>", "resource UUID").requiredOption("--type <type>", "resource type").requiredOption("--to <folder>", "target folder UUID or exact name").action(async function action(resourceId, commandOptions) {
8364
9360
  const { api, json, readOnly } = createNavigationApi(this, filePath);
8365
9361
  ensureWritable5("navigation resources move", readOnly, "write");
8366
9362
  const allFolders = await api.listFolders();
8367
- const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector5(commandOptions.to));
9363
+ const resolved = resolveFolder2(allFolders, parseUuidOrSlugSelector6(commandOptions.to));
8368
9364
  const data = await api.moveResource({
8369
9365
  resourceId,
8370
9366
  resourceType: commandOptions.type.toUpperCase(),
8371
9367
  targetFolderId: resolved.id
8372
9368
  });
8373
9369
  if (json) {
8374
- emitJson6(stdout, "navigation resources move", data, filePath);
9370
+ emitJson7(stdout, "navigation resources move", data, filePath);
8375
9371
  return;
8376
9372
  }
8377
- writeLine6(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
9373
+ writeLine7(stdout, `Moved resource "${resourceId}" to "${resolved.name ?? resolved.id}".`);
8378
9374
  });
8379
9375
  }
8380
9376
 
8381
9377
  // src/commands/profiles.ts
8382
- function getCommandIo7(stdout) {
9378
+ function getCommandIo8(stdout) {
8383
9379
  return stdout ?? process.stdout;
8384
9380
  }
8385
- function writeLine7(stdout, value) {
9381
+ function writeLine8(stdout, value) {
8386
9382
  stdout.write(`${value}
8387
9383
  `);
8388
9384
  }
8389
- function getGlobalOptions7(command) {
9385
+ function getGlobalOptions8(command) {
8390
9386
  return command.optsWithGlobals();
8391
9387
  }
8392
- function emitJson7(stdout, commandName, data, configPath) {
8393
- writeLine7(
9388
+ function emitJson8(stdout, commandName, data, configPath) {
9389
+ writeLine8(
8394
9390
  stdout,
8395
9391
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
8396
9392
  );
@@ -8433,15 +9429,15 @@ function emitProfilesTable(stdout, data) {
8433
9429
  }
8434
9430
  function registerProfilesCommands(program, options = {}) {
8435
9431
  const filePath = options.configPath ?? defaultConfigPath;
8436
- const stdout = getCommandIo7(options.stdout);
9432
+ const stdout = getCommandIo8(options.stdout);
8437
9433
  const profiles = program.command("profiles").description("Manage local CLI profiles");
8438
9434
  profiles.command("list").description("List configured profiles").action(function action() {
8439
9435
  const config = readRequiredConfig(filePath);
8440
9436
  const data = Object.entries(config.profiles).map(
8441
9437
  ([name, profile]) => toDisplayProfile(name, profile, config.defaultProfile)
8442
9438
  );
8443
- if (getGlobalOptions7(this).json) {
8444
- emitJson7(stdout, "profiles list", data, filePath);
9439
+ if (getGlobalOptions8(this).json) {
9440
+ emitJson8(stdout, "profiles list", data, filePath);
8445
9441
  return;
8446
9442
  }
8447
9443
  emitProfilesTable(stdout, data);
@@ -8450,8 +9446,8 @@ function registerProfilesCommands(program, options = {}) {
8450
9446
  const config = readRequiredConfig(filePath);
8451
9447
  const profile = getRequiredProfile(config, profileName);
8452
9448
  const data = toDisplayProfile(profileName, profile, config.defaultProfile);
8453
- if (getGlobalOptions7(this).json) {
8454
- emitJson7(stdout, "profiles get", data, filePath);
9449
+ if (getGlobalOptions8(this).json) {
9450
+ emitJson8(stdout, "profiles get", data, filePath);
8455
9451
  return;
8456
9452
  }
8457
9453
  emitProfilesTable(stdout, [data]);
@@ -8465,11 +9461,11 @@ function registerProfilesCommands(program, options = {}) {
8465
9461
  profile: profileName,
8466
9462
  defaultProfile: nextConfig.defaultProfile
8467
9463
  };
8468
- if (getGlobalOptions7(this).json) {
8469
- emitJson7(stdout, "profiles use", data, filePath);
9464
+ if (getGlobalOptions8(this).json) {
9465
+ emitJson8(stdout, "profiles use", data, filePath);
8470
9466
  return;
8471
9467
  }
8472
- writeLine7(stdout, `Using profile "${profileName}".`);
9468
+ writeLine8(stdout, `Using profile "${profileName}".`);
8473
9469
  });
8474
9470
  profiles.command("add").description("Add a profile to the local config").argument("<profile>", "profile name").requiredOption("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
8475
9471
  const config = loadConfigForAdd(filePath);
@@ -8492,11 +9488,11 @@ function registerProfilesCommands(program, options = {}) {
8492
9488
  nextConfig.profiles[profileName] ?? {},
8493
9489
  nextConfig.defaultProfile
8494
9490
  );
8495
- if (getGlobalOptions7(this).json) {
8496
- emitJson7(stdout, "profiles add", data, filePath);
9491
+ if (getGlobalOptions8(this).json) {
9492
+ emitJson8(stdout, "profiles add", data, filePath);
8497
9493
  return;
8498
9494
  }
8499
- writeLine7(stdout, `Added profile "${profileName}".`);
9495
+ writeLine8(stdout, `Added profile "${profileName}".`);
8500
9496
  });
8501
9497
  profiles.command("update").description("Update an existing profile").argument("<profile>", "profile name").option("--api-key <token>", "API key").option("--base-url <url>", "base URL").action(function action(profileName, commandOptions) {
8502
9498
  if (commandOptions.apiKey === void 0 && commandOptions.baseUrl === void 0) {
@@ -8517,11 +9513,11 @@ function registerProfilesCommands(program, options = {}) {
8517
9513
  nextConfig.profiles[profileName] ?? {},
8518
9514
  nextConfig.defaultProfile
8519
9515
  );
8520
- if (getGlobalOptions7(this).json) {
8521
- emitJson7(stdout, "profiles update", data, filePath);
9516
+ if (getGlobalOptions8(this).json) {
9517
+ emitJson8(stdout, "profiles update", data, filePath);
8522
9518
  return;
8523
9519
  }
8524
- writeLine7(stdout, `Updated profile "${profileName}".`);
9520
+ writeLine8(stdout, `Updated profile "${profileName}".`);
8525
9521
  });
8526
9522
  profiles.command("remove").description("Remove a profile from the local config").argument("<profile>", "profile name").action(function action(profileName) {
8527
9523
  const config = readRequiredConfig(filePath);
@@ -8532,17 +9528,17 @@ function registerProfilesCommands(program, options = {}) {
8532
9528
  profile: profileName,
8533
9529
  defaultProfile: nextConfig.defaultProfile
8534
9530
  };
8535
- if (getGlobalOptions7(this).json) {
8536
- emitJson7(stdout, "profiles remove", data, filePath);
9531
+ if (getGlobalOptions8(this).json) {
9532
+ emitJson8(stdout, "profiles remove", data, filePath);
8537
9533
  return;
8538
9534
  }
8539
- writeLine7(stdout, `Removed profile "${profileName}".`);
9535
+ writeLine8(stdout, `Removed profile "${profileName}".`);
8540
9536
  });
8541
9537
  }
8542
9538
 
8543
9539
  // src/commands/records.ts
8544
9540
  import { readFileSync as readFileSync7 } from "fs";
8545
- import { InvalidArgumentError as InvalidArgumentError6 } from "commander";
9541
+ import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
8546
9542
 
8547
9543
  // src/api/records.ts
8548
9544
  function jsonOptions6(body, method) {
@@ -8554,7 +9550,7 @@ function jsonOptions6(body, method) {
8554
9550
  body: JSON.stringify(body)
8555
9551
  };
8556
9552
  }
8557
- function selectorValue7(selector2) {
9553
+ function selectorValue8(selector2) {
8558
9554
  return selector2.value;
8559
9555
  }
8560
9556
  var RecordsApi = class {
@@ -8569,7 +9565,7 @@ var RecordsApi = class {
8569
9565
  if (query.offset !== void 0) {
8570
9566
  params.set("offset", String(query.offset));
8571
9567
  }
8572
- const path = `/api/v2/schemas/${selectorValue7(schema)}/records`;
9568
+ const path = `/api/v2/schemas/${selectorValue8(schema)}/records`;
8573
9569
  const queryString = params.toString();
8574
9570
  return this.client.getJson(
8575
9571
  queryString ? `${path}?${queryString}` : path
@@ -8578,30 +9574,30 @@ var RecordsApi = class {
8578
9574
  queryRecords(schema, query) {
8579
9575
  const body = this.normalizeQueryInput(query);
8580
9576
  return this.client.requestJson(
8581
- `/api/v2/schemas/${selectorValue7(schema)}/records:query`,
9577
+ `/api/v2/schemas/${selectorValue8(schema)}/records:query`,
8582
9578
  jsonOptions6(body, "POST")
8583
9579
  );
8584
9580
  }
8585
9581
  getRecord(schema, record) {
8586
9582
  return this.client.getJson(
8587
- `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`
9583
+ `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`
8588
9584
  );
8589
9585
  }
8590
9586
  createRecord(schema, input) {
8591
9587
  return this.client.requestJson(
8592
- `/api/v2/schemas/${selectorValue7(schema)}/records`,
9588
+ `/api/v2/schemas/${selectorValue8(schema)}/records`,
8593
9589
  jsonOptions6(input, "POST")
8594
9590
  );
8595
9591
  }
8596
9592
  updateRecord(schema, record, input) {
8597
9593
  return this.client.requestJson(
8598
- `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9594
+ `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
8599
9595
  jsonOptions6(input, "PATCH")
8600
9596
  );
8601
9597
  }
8602
9598
  deleteRecord(schema, record) {
8603
9599
  return this.client.requestJson(
8604
- `/api/v2/schemas/${selectorValue7(schema)}/records/${selectorValue7(record)}`,
9600
+ `/api/v2/schemas/${selectorValue8(schema)}/records/${selectorValue8(record)}`,
8605
9601
  { method: "DELETE" }
8606
9602
  );
8607
9603
  }
@@ -8714,23 +9710,23 @@ function parseExpression(input) {
8714
9710
  }
8715
9711
 
8716
9712
  // src/commands/records.ts
8717
- function getCommandIo8(stdout) {
9713
+ function getCommandIo9(stdout) {
8718
9714
  return stdout ?? process.stdout;
8719
9715
  }
8720
- function writeLine8(stdout, value) {
9716
+ function writeLine9(stdout, value) {
8721
9717
  stdout.write(`${value}
8722
9718
  `);
8723
9719
  }
8724
- function getGlobalOptions8(command) {
9720
+ function getGlobalOptions9(command) {
8725
9721
  return command.optsWithGlobals();
8726
9722
  }
8727
- function emitJson8(stdout, commandName, data, configPath, meta = {}) {
8728
- writeLine8(
9723
+ function emitJson9(stdout, commandName, data, configPath, meta = {}) {
9724
+ writeLine9(
8729
9725
  stdout,
8730
9726
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath, ...meta }))
8731
9727
  );
8732
9728
  }
8733
- function toConfigurationError7(filePath, error) {
9729
+ function toConfigurationError8(filePath, error) {
8734
9730
  if (error instanceof CliError) {
8735
9731
  throw error;
8736
9732
  }
@@ -8745,7 +9741,7 @@ function toConfigurationError7(filePath, error) {
8745
9741
  function createRecordsApi(command, filePath) {
8746
9742
  try {
8747
9743
  const config = readRuntimeConfig(filePath);
8748
- const runtime = resolveRuntimeContext(config, getGlobalOptions8(command));
9744
+ const runtime = resolveRuntimeContext(config, getGlobalOptions9(command));
8749
9745
  if (!runtime.baseUrl) {
8750
9746
  throw new CliError(
8751
9747
  "configuration_error",
@@ -8764,7 +9760,7 @@ function createRecordsApi(command, filePath) {
8764
9760
  readOnly: runtime.readOnly
8765
9761
  };
8766
9762
  } catch (error) {
8767
- toConfigurationError7(filePath, error);
9763
+ toConfigurationError8(filePath, error);
8768
9764
  }
8769
9765
  }
8770
9766
  function ensureWritable6(commandName, readOnly, commandMode) {
@@ -8779,24 +9775,24 @@ function ensureWritable6(commandName, readOnly, commandMode) {
8779
9775
  );
8780
9776
  }
8781
9777
  }
8782
- function parseUuidOrSlugSelector6(input) {
9778
+ function parseUuidOrSlugSelector7(input) {
8783
9779
  try {
8784
9780
  return normalizeUuidOrSlug(input);
8785
9781
  } catch (error) {
8786
9782
  const message = error instanceof Error ? error.message : "Invalid selector.";
8787
- throw new InvalidArgumentError6(message);
9783
+ throw new InvalidArgumentError7(message);
8788
9784
  }
8789
9785
  }
8790
9786
  function parseNonNegativeInteger2(input) {
8791
9787
  if (!/^\d+$/.test(input.trim())) {
8792
- throw new InvalidArgumentError6(`Expected a non-negative integer, received "${input}".`);
9788
+ throw new InvalidArgumentError7(`Expected a non-negative integer, received "${input}".`);
8793
9789
  }
8794
9790
  return Number(input);
8795
9791
  }
8796
9792
  function parseCommaSeparatedValues(input, label) {
8797
9793
  const values = input.split(",").map((value) => value.trim()).filter(Boolean);
8798
9794
  if (values.length === 0) {
8799
- throw new InvalidArgumentError6(`Expected ${label} to contain at least one value.`);
9795
+ throw new InvalidArgumentError7(`Expected ${label} to contain at least one value.`);
8800
9796
  }
8801
9797
  return values;
8802
9798
  }
@@ -8805,7 +9801,7 @@ function parseExpressionValue(input) {
8805
9801
  return parseExpression(input);
8806
9802
  } catch (error) {
8807
9803
  const message = error instanceof Error ? error.message : "Invalid expression.";
8808
- throw new InvalidArgumentError6(message);
9804
+ throw new InvalidArgumentError7(message);
8809
9805
  }
8810
9806
  }
8811
9807
  function parseKeyValueAssignment(input) {
@@ -8813,7 +9809,7 @@ function parseKeyValueAssignment(input) {
8813
9809
  return parseKeyValue(input);
8814
9810
  } catch (error) {
8815
9811
  const message = error instanceof Error ? error.message : "Invalid assignment.";
8816
- throw new InvalidArgumentError6(message);
9812
+ throw new InvalidArgumentError7(message);
8817
9813
  }
8818
9814
  }
8819
9815
  function parseJsonKeyValueAssignment(input) {
@@ -8821,7 +9817,7 @@ function parseJsonKeyValueAssignment(input) {
8821
9817
  return parseJsonAssignment(input);
8822
9818
  } catch (error) {
8823
9819
  const message = error instanceof Error ? error.message : "Invalid JSON assignment.";
8824
- throw new InvalidArgumentError6(message);
9820
+ throw new InvalidArgumentError7(message);
8825
9821
  }
8826
9822
  }
8827
9823
  function collectStringValues(value, previous = []) {
@@ -8839,7 +9835,7 @@ function collectKeyValueAssignments(value, previous = []) {
8839
9835
  function collectJsonAssignments(value, previous = []) {
8840
9836
  return [...previous, parseJsonKeyValueAssignment(value)];
8841
9837
  }
8842
- function isJsonObject4(value) {
9838
+ function isJsonObject5(value) {
8843
9839
  return typeof value === "object" && value !== null && !Array.isArray(value);
8844
9840
  }
8845
9841
  function parseRawJsonObject2(input, sourceLabel) {
@@ -8853,7 +9849,7 @@ function parseRawJsonObject2(input, sourceLabel) {
8853
9849
  `Failed to parse JSON from ${sourceLabel}: ${message}`
8854
9850
  );
8855
9851
  }
8856
- if (!isJsonObject4(parsed)) {
9852
+ if (!isJsonObject5(parsed)) {
8857
9853
  throw new CliError(
8858
9854
  "invalid_cli_usage",
8859
9855
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -8947,7 +9943,7 @@ function readRawSetPayload2(raw) {
8947
9943
  if (setValue === void 0) {
8948
9944
  return {};
8949
9945
  }
8950
- if (!isJsonObject4(setValue)) {
9946
+ if (!isJsonObject5(setValue)) {
8951
9947
  throw new CliError(
8952
9948
  "invalid_cli_usage",
8953
9949
  'Expected raw update payload field "set" to be a JSON object.'
@@ -9000,17 +9996,17 @@ function buildRecordUpdateInput(options) {
9000
9996
  }
9001
9997
  return input;
9002
9998
  }
9003
- function toTableRows3(data) {
9999
+ function toTableRows4(data) {
9004
10000
  if (Array.isArray(data)) {
9005
- return data.map((entry) => isJsonObject4(entry) ? entry : { value: entry });
10001
+ return data.map((entry) => isJsonObject5(entry) ? entry : { value: entry });
9006
10002
  }
9007
- if (isJsonObject4(data)) {
10003
+ if (isJsonObject5(data)) {
9008
10004
  return [data];
9009
10005
  }
9010
10006
  return [{ value: data }];
9011
10007
  }
9012
- function emitTable3(stdout, data) {
9013
- printTable(toTableRows3(data), void 0, stdout);
10008
+ function emitTable4(stdout, data) {
10009
+ printTable(toTableRows4(data), void 0, stdout);
9014
10010
  }
9015
10011
  function getQueryRecords(result) {
9016
10012
  return Array.isArray(result.records) ? result.records : [];
@@ -9034,9 +10030,9 @@ async function resolveSchemaSelector(api, selector2) {
9034
10030
  }
9035
10031
  function registerRecordsCommands(program, options = {}) {
9036
10032
  const filePath = options.configPath ?? defaultConfigPath;
9037
- const stdout = getCommandIo8(options.stdout);
10033
+ const stdout = getCommandIo9(options.stdout);
9038
10034
  const records = program.command("records").description("Manage schema records");
9039
- records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).action(async function action(schema, commandOptions) {
10035
+ records.command("list").description("List records for a schema with simple pagination").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).action(async function action(schema, commandOptions) {
9040
10036
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
9041
10037
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
9042
10038
  const data = await api.listRecords(
@@ -9045,7 +10041,7 @@ function registerRecordsCommands(program, options = {}) {
9045
10041
  );
9046
10042
  const recordsData = getQueryRecords(data);
9047
10043
  if (json) {
9048
- emitJson8(
10044
+ emitJson9(
9049
10045
  stdout,
9050
10046
  "records list",
9051
10047
  recordsData,
@@ -9054,9 +10050,9 @@ function registerRecordsCommands(program, options = {}) {
9054
10050
  );
9055
10051
  return;
9056
10052
  }
9057
- emitTable3(stdout, recordsData);
10053
+ emitTable4(stdout, recordsData);
9058
10054
  });
9059
- records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).option("--select <fields>", "comma-separated field selection", (value) => parseCommaSeparatedValues(value, "--select")).option("--where <expression>", "where expression", collectWhereExpressions, []).option("--sort <field:direction>", "sort field(s)", collectSortValues, []).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
10055
+ records.command("query").description("Query records for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--select <fields>", "comma-separated field selection", (value) => parseCommaSeparatedValues(value, "--select")).option("--where <expression>", "where expression", collectWhereExpressions, []).option("--sort <field:direction>", "sort field(s)", collectSortValues, []).option("--limit <number>", "limit results", parseNonNegativeInteger2).option("--offset <number>", "offset results", parseNonNegativeInteger2).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
9060
10056
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
9061
10057
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
9062
10058
  const data = await api.queryRecords(
@@ -9065,7 +10061,7 @@ function registerRecordsCommands(program, options = {}) {
9065
10061
  );
9066
10062
  const recordsData = getQueryRecords(data);
9067
10063
  if (json) {
9068
- emitJson8(
10064
+ emitJson9(
9069
10065
  stdout,
9070
10066
  "records query",
9071
10067
  recordsData,
@@ -9074,19 +10070,19 @@ function registerRecordsCommands(program, options = {}) {
9074
10070
  );
9075
10071
  return;
9076
10072
  }
9077
- emitTable3(stdout, recordsData);
10073
+ emitTable4(stdout, recordsData);
9078
10074
  });
9079
- records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector6).action(async function action(schema, record) {
10075
+ records.command("get").description("Get a record by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, record) {
9080
10076
  const { api, schemasApi, json } = createRecordsApi(this, filePath);
9081
10077
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
9082
10078
  const data = await api.getRecord(resolvedSchema, record);
9083
10079
  if (json) {
9084
- emitJson8(stdout, "records get", data, filePath);
10080
+ emitJson9(stdout, "records get", data, filePath);
9085
10081
  return;
9086
10082
  }
9087
- emitTable3(stdout, data);
10083
+ emitTable4(stdout, data);
9088
10084
  });
9089
- records.command("create").description("Create a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
10085
+ records.command("create").description("Create a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
9090
10086
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
9091
10087
  ensureWritable6("records create", readOnly, "write");
9092
10088
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
@@ -9095,12 +10091,12 @@ function registerRecordsCommands(program, options = {}) {
9095
10091
  buildRecordCreateInput(commandOptions)
9096
10092
  );
9097
10093
  if (json) {
9098
- emitJson8(stdout, "records create", data, filePath);
10094
+ emitJson9(stdout, "records create", data, filePath);
9099
10095
  return;
9100
10096
  }
9101
- writeLine8(stdout, `Created record "${getRecordIdentifier(data)}".`);
10097
+ writeLine9(stdout, `Created record "${getRecordIdentifier(data)}".`);
9102
10098
  });
9103
- records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector6).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--unset <field>", "unset a field", collectStringValues, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, record, commandOptions) {
10099
+ records.command("update").description("Update a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).option("--set <field=value>", "set a string field", collectKeyValueAssignments, []).option("--set-json <field=json>", "set a structured field", collectJsonAssignments, []).option("--unset <field>", "unset a field", collectStringValues, []).option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, record, commandOptions) {
9104
10100
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
9105
10101
  ensureWritable6("records update", readOnly, "write");
9106
10102
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
@@ -9110,12 +10106,12 @@ function registerRecordsCommands(program, options = {}) {
9110
10106
  buildRecordUpdateInput(commandOptions)
9111
10107
  );
9112
10108
  if (json) {
9113
- emitJson8(stdout, "records update", data, filePath);
10109
+ emitJson9(stdout, "records update", data, filePath);
9114
10110
  return;
9115
10111
  }
9116
- writeLine8(stdout, `Updated record "${getRecordIdentifier(data)}".`);
10112
+ writeLine9(stdout, `Updated record "${getRecordIdentifier(data)}".`);
9117
10113
  });
9118
- records.command("delete").description("Delete a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector6).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector6).action(async function action(schema, record) {
10114
+ records.command("delete").description("Delete a record").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<record>", "record uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, record) {
9119
10115
  const { api, schemasApi, json, readOnly } = createRecordsApi(this, filePath);
9120
10116
  ensureWritable6("records delete", readOnly, "destructive");
9121
10117
  const resolvedSchema = await resolveSchemaSelector(schemasApi, schema);
@@ -9126,33 +10122,33 @@ function registerRecordsCommands(program, options = {}) {
9126
10122
  deleted: true
9127
10123
  };
9128
10124
  if (json) {
9129
- emitJson8(stdout, "records delete", data, filePath);
10125
+ emitJson9(stdout, "records delete", data, filePath);
9130
10126
  return;
9131
10127
  }
9132
- writeLine8(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
10128
+ writeLine9(stdout, `Deleted record "${record.value}" from schema "${schema.value}".`);
9133
10129
  });
9134
10130
  }
9135
10131
 
9136
10132
  // src/commands/schemas.ts
9137
10133
  import { readFileSync as readFileSync8 } from "fs";
9138
- import { InvalidArgumentError as InvalidArgumentError7 } from "commander";
9139
- function getCommandIo9(stdout) {
10134
+ import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
10135
+ function getCommandIo10(stdout) {
9140
10136
  return stdout ?? process.stdout;
9141
10137
  }
9142
- function writeLine9(stdout, value) {
10138
+ function writeLine10(stdout, value) {
9143
10139
  stdout.write(`${value}
9144
10140
  `);
9145
10141
  }
9146
- function getGlobalOptions9(command) {
10142
+ function getGlobalOptions10(command) {
9147
10143
  return command.optsWithGlobals();
9148
10144
  }
9149
- function emitJson9(stdout, commandName, data, configPath) {
9150
- writeLine9(
10145
+ function emitJson10(stdout, commandName, data, configPath) {
10146
+ writeLine10(
9151
10147
  stdout,
9152
10148
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
9153
10149
  );
9154
10150
  }
9155
- function toConfigurationError8(filePath, error) {
10151
+ function toConfigurationError9(filePath, error) {
9156
10152
  if (error instanceof CliError) {
9157
10153
  throw error;
9158
10154
  }
@@ -9167,7 +10163,7 @@ function toConfigurationError8(filePath, error) {
9167
10163
  function createSchemasApi(command, filePath) {
9168
10164
  try {
9169
10165
  const config = readRuntimeConfig(filePath);
9170
- const runtime = resolveRuntimeContext(config, getGlobalOptions9(command));
10166
+ const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
9171
10167
  if (!runtime.baseUrl) {
9172
10168
  throw new CliError(
9173
10169
  "configuration_error",
@@ -9186,7 +10182,7 @@ function createSchemasApi(command, filePath) {
9186
10182
  readOnly: runtime.readOnly
9187
10183
  };
9188
10184
  } catch (error) {
9189
- toConfigurationError8(filePath, error);
10185
+ toConfigurationError9(filePath, error);
9190
10186
  }
9191
10187
  }
9192
10188
  function ensureWritable7(commandName, readOnly, commandMode) {
@@ -9201,12 +10197,12 @@ function ensureWritable7(commandName, readOnly, commandMode) {
9201
10197
  );
9202
10198
  }
9203
10199
  }
9204
- function parseUuidOrSlugSelector7(input) {
10200
+ function parseUuidOrSlugSelector8(input) {
9205
10201
  try {
9206
10202
  return normalizeUuidOrSlug(input);
9207
10203
  } catch (error) {
9208
10204
  const message = error instanceof Error ? error.message : "Invalid selector.";
9209
- throw new InvalidArgumentError7(message);
10205
+ throw new InvalidArgumentError8(message);
9210
10206
  }
9211
10207
  }
9212
10208
  function parseBooleanFlag(input) {
@@ -9217,9 +10213,9 @@ function parseBooleanFlag(input) {
9217
10213
  if (["false", "0", "no", "n", "off"].includes(normalized)) {
9218
10214
  return false;
9219
10215
  }
9220
- throw new InvalidArgumentError7(`Expected a boolean value, received "${input}".`);
10216
+ throw new InvalidArgumentError8(`Expected a boolean value, received "${input}".`);
9221
10217
  }
9222
- function isJsonObject5(value) {
10218
+ function isJsonObject6(value) {
9223
10219
  return typeof value === "object" && value !== null && !Array.isArray(value);
9224
10220
  }
9225
10221
  function parseRawJsonObject3(input, sourceLabel) {
@@ -9233,7 +10229,7 @@ function parseRawJsonObject3(input, sourceLabel) {
9233
10229
  `Failed to parse JSON from ${sourceLabel}: ${message}`
9234
10230
  );
9235
10231
  }
9236
- if (!isJsonObject5(parsed)) {
10232
+ if (!isJsonObject6(parsed)) {
9237
10233
  throw new CliError(
9238
10234
  "invalid_cli_usage",
9239
10235
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -9313,7 +10309,7 @@ function applyFieldDefaultValue(input, defaultValue) {
9313
10309
  return;
9314
10310
  }
9315
10311
  const config = input.config;
9316
- if (config !== void 0 && !isJsonObject5(config)) {
10312
+ if (config !== void 0 && !isJsonObject6(config)) {
9317
10313
  throw new CliError(
9318
10314
  "invalid_cli_usage",
9319
10315
  'Expected field "config" to be a JSON object when using "--default".'
@@ -9353,7 +10349,7 @@ function buildFieldCreateInput(options) {
9353
10349
  input.required = options.required;
9354
10350
  }
9355
10351
  applyFieldDefaultValue(input, options.default);
9356
- if ("config" in input && isJsonObject5(input.config) && isEmptyObject5(input.config)) {
10352
+ if ("config" in input && isJsonObject6(input.config) && isEmptyObject5(input.config)) {
9357
10353
  delete input.config;
9358
10354
  }
9359
10355
  return input;
@@ -9431,23 +10427,23 @@ function isEmptyObject5(value) {
9431
10427
  }
9432
10428
  function registerSchemasCommands(program, options = {}) {
9433
10429
  const filePath = options.configPath ?? defaultConfigPath;
9434
- const stdout = getCommandIo9(options.stdout);
10430
+ const stdout = getCommandIo10(options.stdout);
9435
10431
  const schemas = program.command("schemas").description("Manage schemas and schema fields");
9436
10432
  schemas.command("list").description("List schemas").action(async function action() {
9437
10433
  const { api, json } = createSchemasApi(this, filePath);
9438
10434
  const data = await api.listSchemas();
9439
10435
  if (json) {
9440
- emitJson9(stdout, "schemas list", data, filePath);
10436
+ emitJson10(stdout, "schemas list", data, filePath);
9441
10437
  return;
9442
10438
  }
9443
10439
  emitSchemasTable(stdout, data);
9444
10440
  });
9445
- schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
10441
+ schemas.command("get").description("Get a schema by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
9446
10442
  const { api, json } = createSchemasApi(this, filePath);
9447
10443
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
9448
10444
  const data = await api.getSchema(resolvedSchema);
9449
10445
  if (json) {
9450
- emitJson9(stdout, "schemas get", data, filePath);
10446
+ emitJson10(stdout, "schemas get", data, filePath);
9451
10447
  return;
9452
10448
  }
9453
10449
  emitSchemasTable(stdout, [data]);
@@ -9463,12 +10459,12 @@ function registerSchemasCommands(program, options = {}) {
9463
10459
  };
9464
10460
  const data = await api.createSchema(input);
9465
10461
  if (json) {
9466
- emitJson9(stdout, "schemas create", data, filePath);
10462
+ emitJson10(stdout, "schemas create", data, filePath);
9467
10463
  return;
9468
10464
  }
9469
- writeLine9(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
10465
+ writeLine10(stdout, `Created schema "${data.slug ?? commandOptions.slug}".`);
9470
10466
  });
9471
- schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).action(async function action(schema, commandOptions) {
10467
+ schemas.command("update").description("Update a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--name <name>", "schema name").option("--slug <slug>", "schema slug").option("--auditable <bool>", "auditable flag", parseBooleanFlag).option("--commentable <bool>", "commentable flag", parseBooleanFlag).action(async function action(schema, commandOptions) {
9472
10468
  const { api, json, readOnly } = createSchemasApi(this, filePath);
9473
10469
  ensureWritable7("schemas update", readOnly, "write");
9474
10470
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
@@ -9481,12 +10477,12 @@ function registerSchemasCommands(program, options = {}) {
9481
10477
  }
9482
10478
  const data = await api.updateSchema(resolvedSchema, input);
9483
10479
  if (json) {
9484
- emitJson9(stdout, "schemas update", data, filePath);
10480
+ emitJson10(stdout, "schemas update", data, filePath);
9485
10481
  return;
9486
10482
  }
9487
- writeLine9(stdout, `Updated schema "${data.slug ?? schema.value}".`);
10483
+ writeLine10(stdout, `Updated schema "${data.slug ?? schema.value}".`);
9488
10484
  });
9489
- schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
10485
+ schemas.command("delete").description("Delete a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
9490
10486
  const { api, json, readOnly } = createSchemasApi(this, filePath);
9491
10487
  ensureWritable7("schemas delete", readOnly, "destructive");
9492
10488
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
@@ -9496,34 +10492,34 @@ function registerSchemasCommands(program, options = {}) {
9496
10492
  deleted: true
9497
10493
  };
9498
10494
  if (json) {
9499
- emitJson9(stdout, "schemas delete", data, filePath);
10495
+ emitJson10(stdout, "schemas delete", data, filePath);
9500
10496
  return;
9501
10497
  }
9502
- writeLine9(stdout, `Deleted schema "${schema.value}".`);
10498
+ writeLine10(stdout, `Deleted schema "${schema.value}".`);
9503
10499
  });
9504
10500
  const fields = schemas.command("fields").description("Manage schema fields");
9505
- fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema) {
10501
+ fields.command("list").description("List fields for a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema) {
9506
10502
  const { api, json } = createSchemasApi(this, filePath);
9507
10503
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
9508
10504
  const data = await api.listFields(resolvedSchema);
9509
10505
  if (json) {
9510
- emitJson9(stdout, "schemas fields list", data, filePath);
10506
+ emitJson10(stdout, "schemas fields list", data, filePath);
9511
10507
  return;
9512
10508
  }
9513
10509
  emitFieldsTable(stdout, data);
9514
10510
  });
9515
- fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, field) {
10511
+ fields.command("get").description("Get a field by UUID or slug").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema, field) {
9516
10512
  const { api, json } = createSchemasApi(this, filePath);
9517
10513
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
9518
10514
  const resolvedField = await resolveFieldSelector(api, resolvedSchema, field);
9519
10515
  const data = await api.getField(resolvedSchema, resolvedField);
9520
10516
  if (json) {
9521
- emitJson9(stdout, "schemas fields get", data, filePath);
10517
+ emitJson10(stdout, "schemas fields get", data, filePath);
9522
10518
  return;
9523
10519
  }
9524
10520
  emitFieldsTable(stdout, [data]);
9525
10521
  });
9526
- fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).option("--type <type>", `field type (${formatSchemaFieldTypes()})`).option("--slug <slug>", "field slug").option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload (see type-specific shapes in --help)").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
10522
+ fields.command("create").description(`Create a field in a schema.${buildSchemaFieldCreateHelpText()}`).argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).option("--type <type>", `field type (${formatSchemaFieldTypes()})`).option("--slug <slug>", "field slug").option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload (see type-specific shapes in --help)").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, commandOptions) {
9527
10523
  const { api, json, readOnly } = createSchemasApi(this, filePath);
9528
10524
  ensureWritable7("schemas fields create", readOnly, "write");
9529
10525
  const input = buildFieldCreateInput(commandOptions);
@@ -9535,12 +10531,12 @@ function registerSchemasCommands(program, options = {}) {
9535
10531
  toFieldCreateError(error, input);
9536
10532
  }
9537
10533
  if (json) {
9538
- emitJson9(stdout, "schemas fields create", data, filePath);
10534
+ emitJson10(stdout, "schemas fields create", data, filePath);
9539
10535
  return;
9540
10536
  }
9541
- writeLine9(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
10537
+ writeLine10(stdout, `Created field "${data.slug ?? commandOptions.slug}".`);
9542
10538
  });
9543
- fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector7).option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, field, commandOptions) {
10539
+ fields.command("update").description("Update a field in a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).option("--label <label>", "field label").option("--required <bool>", "required flag", parseBooleanFlag).option("--default <value>", "default field value").option("--raw <json>", "raw JSON object payload").option("--raw-file <path>", "path to a raw JSON object payload").action(async function action(schema, field, commandOptions) {
9544
10540
  const { api, json, readOnly } = createSchemasApi(this, filePath);
9545
10541
  ensureWritable7("schemas fields update", readOnly, "write");
9546
10542
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
@@ -9559,12 +10555,12 @@ function registerSchemasCommands(program, options = {}) {
9559
10555
  }
9560
10556
  const data = await api.updateField(resolvedSchema, resolvedField, input);
9561
10557
  if (json) {
9562
- emitJson9(stdout, "schemas fields update", data, filePath);
10558
+ emitJson10(stdout, "schemas fields update", data, filePath);
9563
10559
  return;
9564
10560
  }
9565
- writeLine9(stdout, `Updated field "${data.slug ?? field.value}".`);
10561
+ writeLine10(stdout, `Updated field "${data.slug ?? field.value}".`);
9566
10562
  });
9567
- fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector7).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector7).action(async function action(schema, field) {
10563
+ fields.command("delete").description("Delete a field from a schema").argument("<schema>", "schema uuid or slug", parseUuidOrSlugSelector8).argument("<field>", "field uuid or slug", parseUuidOrSlugSelector8).action(async function action(schema, field) {
9568
10564
  const { api, json, readOnly } = createSchemasApi(this, filePath);
9569
10565
  ensureWritable7("schemas fields delete", readOnly, "destructive");
9570
10566
  const resolvedSchema = await resolveSchemaSelector2(api, schema);
@@ -9576,16 +10572,16 @@ function registerSchemasCommands(program, options = {}) {
9576
10572
  deleted: true
9577
10573
  };
9578
10574
  if (json) {
9579
- emitJson9(stdout, "schemas fields delete", data, filePath);
10575
+ emitJson10(stdout, "schemas fields delete", data, filePath);
9580
10576
  return;
9581
10577
  }
9582
- writeLine9(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
10578
+ writeLine10(stdout, `Deleted field "${field.value}" from schema "${schema.value}".`);
9583
10579
  });
9584
10580
  }
9585
10581
 
9586
10582
  // src/commands/teamspace.ts
9587
10583
  import { readFileSync as readFileSync9 } from "fs";
9588
- import { InvalidArgumentError as InvalidArgumentError8 } from "commander";
10584
+ import { InvalidArgumentError as InvalidArgumentError9 } from "commander";
9589
10585
 
9590
10586
  // src/api/teamspace.ts
9591
10587
  function jsonOptions7(body, method) {
@@ -9597,7 +10593,7 @@ function jsonOptions7(body, method) {
9597
10593
  body: JSON.stringify(body)
9598
10594
  };
9599
10595
  }
9600
- function selectorValue8(selector2) {
10596
+ function selectorValue9(selector2) {
9601
10597
  return selector2.value;
9602
10598
  }
9603
10599
  var TeamspaceApi = class {
@@ -9623,13 +10619,13 @@ var TeamspaceApi = class {
9623
10619
  }
9624
10620
  updateFolder(folder, input) {
9625
10621
  return this.client.requestJson(
9626
- `/api/v2/teamspaces/folders/${selectorValue8(folder)}`,
10622
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
9627
10623
  jsonOptions7(input, "PATCH")
9628
10624
  );
9629
10625
  }
9630
10626
  deleteFolder(folder) {
9631
10627
  return this.client.requestJson(
9632
- `/api/v2/teamspaces/folders/${selectorValue8(folder)}`,
10628
+ `/api/v2/teamspaces/folders/${selectorValue9(folder)}`,
9633
10629
  { method: "DELETE" }
9634
10630
  );
9635
10631
  }
@@ -9648,23 +10644,23 @@ var TeamspaceApi = class {
9648
10644
  };
9649
10645
 
9650
10646
  // src/commands/teamspace.ts
9651
- function getCommandIo10(stdout) {
10647
+ function getCommandIo11(stdout) {
9652
10648
  return stdout ?? process.stdout;
9653
10649
  }
9654
- function writeLine10(stdout, value) {
10650
+ function writeLine11(stdout, value) {
9655
10651
  stdout.write(`${value}
9656
10652
  `);
9657
10653
  }
9658
- function getGlobalOptions10(command) {
10654
+ function getGlobalOptions11(command) {
9659
10655
  return command.optsWithGlobals();
9660
10656
  }
9661
- function emitJson10(stdout, commandName, data, configPath) {
9662
- writeLine10(
10657
+ function emitJson11(stdout, commandName, data, configPath) {
10658
+ writeLine11(
9663
10659
  stdout,
9664
10660
  JSON.stringify(buildJsonSuccess(data, { command: commandName, configPath }))
9665
10661
  );
9666
10662
  }
9667
- function toConfigurationError9(filePath, error) {
10663
+ function toConfigurationError10(filePath, error) {
9668
10664
  if (error instanceof CliError) {
9669
10665
  throw error;
9670
10666
  }
@@ -9679,7 +10675,7 @@ function toConfigurationError9(filePath, error) {
9679
10675
  function createTeamspaceApi(command, filePath) {
9680
10676
  try {
9681
10677
  const config = readRuntimeConfig(filePath);
9682
- const runtime = resolveRuntimeContext(config, getGlobalOptions10(command));
10678
+ const runtime = resolveRuntimeContext(config, getGlobalOptions11(command));
9683
10679
  if (!runtime.baseUrl) {
9684
10680
  throw new CliError(
9685
10681
  "configuration_error",
@@ -9697,7 +10693,7 @@ function createTeamspaceApi(command, filePath) {
9697
10693
  readOnly: runtime.readOnly
9698
10694
  };
9699
10695
  } catch (error) {
9700
- toConfigurationError9(filePath, error);
10696
+ toConfigurationError10(filePath, error);
9701
10697
  }
9702
10698
  }
9703
10699
  function ensureWritable8(commandName, readOnly, commandMode) {
@@ -9712,21 +10708,21 @@ function ensureWritable8(commandName, readOnly, commandMode) {
9712
10708
  );
9713
10709
  }
9714
10710
  }
9715
- function parseUuidOrSlugSelector8(input) {
10711
+ function parseUuidOrSlugSelector9(input) {
9716
10712
  try {
9717
10713
  return normalizeUuidOrSlug(input);
9718
10714
  } catch (error) {
9719
10715
  const message = error instanceof Error ? error.message : "Invalid selector.";
9720
- throw new InvalidArgumentError8(message);
10716
+ throw new InvalidArgumentError9(message);
9721
10717
  }
9722
10718
  }
9723
10719
  function parseNonNegativeInteger3(input) {
9724
10720
  if (!/^\d+$/.test(input.trim())) {
9725
- throw new InvalidArgumentError8(`Expected a non-negative integer, received "${input}".`);
10721
+ throw new InvalidArgumentError9(`Expected a non-negative integer, received "${input}".`);
9726
10722
  }
9727
10723
  return Number(input);
9728
10724
  }
9729
- function isJsonObject6(value) {
10725
+ function isJsonObject7(value) {
9730
10726
  return typeof value === "object" && value !== null && !Array.isArray(value);
9731
10727
  }
9732
10728
  function parseRawJsonObject4(input, sourceLabel) {
@@ -9740,7 +10736,7 @@ function parseRawJsonObject4(input, sourceLabel) {
9740
10736
  `Failed to parse JSON from ${sourceLabel}: ${message}`
9741
10737
  );
9742
10738
  }
9743
- if (!isJsonObject6(parsed)) {
10739
+ if (!isJsonObject7(parsed)) {
9744
10740
  throw new CliError(
9745
10741
  "invalid_cli_usage",
9746
10742
  `Expected ${sourceLabel} to contain a JSON object.`
@@ -9812,17 +10808,17 @@ function buildFolderUpdateInput(options) {
9812
10808
  }
9813
10809
  return input;
9814
10810
  }
9815
- function toTableRows4(data) {
10811
+ function toTableRows5(data) {
9816
10812
  if (Array.isArray(data)) {
9817
- return data.map((entry) => isJsonObject6(entry) ? entry : { value: entry });
10813
+ return data.map((entry) => isJsonObject7(entry) ? entry : { value: entry });
9818
10814
  }
9819
- if (isJsonObject6(data)) {
10815
+ if (isJsonObject7(data)) {
9820
10816
  return [data];
9821
10817
  }
9822
10818
  return [{ value: data }];
9823
10819
  }
9824
- function emitTable4(stdout, data) {
9825
- printTable(toTableRows4(data), void 0, stdout);
10820
+ function emitTable5(stdout, data) {
10821
+ printTable(toTableRows5(data), void 0, stdout);
9826
10822
  }
9827
10823
  function getFolderIdentifier(folder) {
9828
10824
  return typeof folder.id === "string" ? folder.id : typeof folder.name === "string" ? folder.name : "unknown";
@@ -9878,63 +10874,63 @@ async function resolveFolderSelector2(api, selector2) {
9878
10874
  }
9879
10875
  function registerTeamspaceCommands(program, options = {}) {
9880
10876
  const filePath = options.configPath ?? defaultConfigPath;
9881
- const stdout = getCommandIo10(options.stdout);
10877
+ const stdout = getCommandIo11(options.stdout);
9882
10878
  const teamspace = program.command("teamspace").description("Manage teamspace folders and resources");
9883
10879
  const folders = teamspace.command("folders").description("Manage teamspace folders");
9884
10880
  folders.command("list").description("List teamspace folders").option("--include-resources", "include nested resources").action(async function action(commandOptions) {
9885
10881
  const { api, json } = createTeamspaceApi(this, filePath);
9886
10882
  const data = await api.listFolders(Boolean(commandOptions.includeResources));
9887
10883
  if (json) {
9888
- emitJson10(stdout, "teamspace folders list", data, filePath);
10884
+ emitJson11(stdout, "teamspace folders list", data, filePath);
9889
10885
  return;
9890
10886
  }
9891
- emitTable4(stdout, data);
10887
+ emitTable5(stdout, data);
9892
10888
  });
9893
- folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).option("--include-resources", "include nested resources").action(async function action(folder, commandOptions) {
10889
+ folders.command("get").description("Get a teamspace folder by exact name or UUID").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).option("--include-resources", "include nested resources").action(async function action(folder, commandOptions) {
9894
10890
  const { api, json } = createTeamspaceApi(this, filePath);
9895
10891
  const resolvedFolder = await resolveFolderSelector2(api, folder);
9896
10892
  const allFolders = await api.listFolders(Boolean(commandOptions.includeResources));
9897
10893
  const data = findFolderEntity(allFolders, resolvedFolder);
9898
10894
  if (json) {
9899
- emitJson10(stdout, "teamspace folders get", data, filePath);
10895
+ emitJson11(stdout, "teamspace folders get", data, filePath);
9900
10896
  return;
9901
10897
  }
9902
- emitTable4(stdout, data);
10898
+ emitTable5(stdout, data);
9903
10899
  });
9904
10900
  folders.command("create").description("Create a teamspace folder").requiredOption("--name <name>", "folder name").option("--order <n>", "folder order", parseNonNegativeInteger3).option("--props <json>", "folder properties payload").option("--props-file <path>", "path to a folder properties JSON payload").action(async function action(commandOptions) {
9905
10901
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
9906
10902
  ensureWritable8("teamspace folders create", readOnly, "write");
9907
10903
  const data = await api.createFolder(buildFolderCreateInput(commandOptions));
9908
10904
  if (json) {
9909
- emitJson10(stdout, "teamspace folders create", data, filePath);
10905
+ emitJson11(stdout, "teamspace folders create", data, filePath);
9910
10906
  return;
9911
10907
  }
9912
- writeLine10(stdout, `Created folder "${getFolderIdentifier(data)}".`);
10908
+ writeLine11(stdout, `Created folder "${getFolderIdentifier(data)}".`);
9913
10909
  });
9914
- folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).option("--name <name>", "folder name").option("--order <n>", "folder order", parseNonNegativeInteger3).option("--props <json>", "folder properties payload").option("--props-file <path>", "path to a folder properties JSON payload").action(async function action(folder, commandOptions) {
10910
+ folders.command("update").description("Update a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).option("--name <name>", "folder name").option("--order <n>", "folder order", parseNonNegativeInteger3).option("--props <json>", "folder properties payload").option("--props-file <path>", "path to a folder properties JSON payload").action(async function action(folder, commandOptions) {
9915
10911
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
9916
10912
  ensureWritable8("teamspace folders update", readOnly, "write");
9917
10913
  const resolvedFolder = await resolveFolderSelector2(api, folder);
9918
10914
  const data = await api.updateFolder(resolvedFolder, buildFolderUpdateInput(commandOptions));
9919
10915
  if (json) {
9920
- emitJson10(stdout, "teamspace folders update", data, filePath);
10916
+ emitJson11(stdout, "teamspace folders update", data, filePath);
9921
10917
  return;
9922
10918
  }
9923
- writeLine10(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
10919
+ writeLine11(stdout, `Updated folder "${getFolderIdentifier(data)}".`);
9924
10920
  });
9925
- folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector8).action(async function action(folder) {
10921
+ folders.command("delete").description("Delete a teamspace folder").argument("<folder>", "folder UUID or exact name", parseUuidOrSlugSelector9).action(async function action(folder) {
9926
10922
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
9927
10923
  ensureWritable8("teamspace folders delete", readOnly, "destructive");
9928
10924
  const resolvedFolder = await resolveFolderSelector2(api, folder);
9929
10925
  const data = await api.deleteFolder(resolvedFolder);
9930
10926
  if (json) {
9931
- emitJson10(stdout, "teamspace folders delete", data, filePath);
10927
+ emitJson11(stdout, "teamspace folders delete", data, filePath);
9932
10928
  return;
9933
10929
  }
9934
- writeLine10(stdout, `Deleted folder "${resolvedFolder.value}".`);
10930
+ writeLine11(stdout, `Deleted folder "${resolvedFolder.value}".`);
9935
10931
  });
9936
10932
  const resources = teamspace.command("resources").description("Manage teamspace resources");
9937
- resources.command("publish").description("Publish a resource to a teamspace folder").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector8).requiredOption("--to <folder>", "target folder", parseUuidOrSlugSelector8).action(async function action(resource, commandOptions) {
10933
+ resources.command("publish").description("Publish a resource to a teamspace folder").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector9).requiredOption("--to <folder>", "target folder", parseUuidOrSlugSelector9).action(async function action(resource, commandOptions) {
9938
10934
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
9939
10935
  ensureWritable8("teamspace resources publish", readOnly, "write");
9940
10936
  const folder = await resolveFolderSelector2(api, commandOptions.to);
@@ -9943,20 +10939,20 @@ function registerTeamspaceCommands(program, options = {}) {
9943
10939
  targetFolderId: folder.value
9944
10940
  });
9945
10941
  if (json) {
9946
- emitJson10(stdout, "teamspace resources publish", data, filePath);
10942
+ emitJson11(stdout, "teamspace resources publish", data, filePath);
9947
10943
  return;
9948
10944
  }
9949
- writeLine10(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
10945
+ writeLine11(stdout, `Published resource "${resource.value}" to folder "${folder.value}".`);
9950
10946
  });
9951
- resources.command("unpublish").description("Unpublish a resource from teamspace").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector8).action(async function action(resource) {
10947
+ resources.command("unpublish").description("Unpublish a resource from teamspace").argument("<resource>", "resource UUID or exact name", parseUuidOrSlugSelector9).action(async function action(resource) {
9952
10948
  const { api, json, readOnly } = createTeamspaceApi(this, filePath);
9953
10949
  ensureWritable8("teamspace resources unpublish", readOnly, "write");
9954
10950
  const data = await api.unpublishResource(resource.value);
9955
10951
  if (json) {
9956
- emitJson10(stdout, "teamspace resources unpublish", data, filePath);
10952
+ emitJson11(stdout, "teamspace resources unpublish", data, filePath);
9957
10953
  return;
9958
10954
  }
9959
- writeLine10(stdout, `Unpublished resource "${resource.value}".`);
10955
+ writeLine11(stdout, `Unpublished resource "${resource.value}".`);
9960
10956
  });
9961
10957
  }
9962
10958
 
@@ -9964,8 +10960,8 @@ function registerTeamspaceCommands(program, options = {}) {
9964
10960
  var require2 = createRequire(import.meta.url);
9965
10961
  var { version } = require2("../package.json");
9966
10962
  function buildProgram(options = {}) {
9967
- const program = new Command9();
9968
- program.name("zinkee").description("CLI for Zinkee API v2").version(version).enablePositionalOptions().showHelpAfterError().option("--profile <name>", "select a profile from config").option("--base-url <url>", "override the configured base URL").option("--api-key <token>", "override the configured API key").option("--read-only", "run in read-only mode").option("--example", "show examples for a command").option("--json", "emit JSON output");
10963
+ const program = new Command10();
10964
+ program.name("zinkee").description("CLI for Zinkee API v2").version(version).enablePositionalOptions().showHelpAfterError().option("--profile <name>", "select a profile from config").option("--base-url <url>", "override the configured base URL").option("--api-key <token>", "override the configured API key").option("--read-only", "run in read-only mode").option("--example", "show examples for a command").option("--json", "emit JSON output").option("--install-completion [shell]", "install shell completion (bash, zsh, fish, powershell)").option("--show-completion [shell]", "print shell completion script for the current shell");
9969
10965
  registerProfilesCommands(program, options);
9970
10966
  registerAutomationsCommands(program, options);
9971
10967
  registerConfigCommands(program, options);
@@ -9975,10 +10971,544 @@ function buildProgram(options = {}) {
9975
10971
  registerSchemasCommands(program, options);
9976
10972
  registerRecordsCommands(program, options);
9977
10973
  registerCommentsCommands(program, options);
10974
+ registerLogsCommands(program, options);
9978
10975
  registerTeamspaceCommands(program, options);
9979
10976
  return program;
9980
10977
  }
9981
10978
 
10979
+ // src/completion/engine.ts
10980
+ function readProfileNamesFromConfig(configPath) {
10981
+ try {
10982
+ const config = readConfigIfExists(configPath);
10983
+ if (!config) {
10984
+ return [];
10985
+ }
10986
+ return Object.keys(config.profiles).sort();
10987
+ } catch {
10988
+ return [];
10989
+ }
10990
+ }
10991
+ function findSubcommand(command, name) {
10992
+ return command.commands.find((sub) => {
10993
+ if (sub.name() === name) {
10994
+ return true;
10995
+ }
10996
+ const aliases = sub.aliases();
10997
+ return aliases.includes(name);
10998
+ });
10999
+ }
11000
+ function collectFlagsThatTakeValues(root) {
11001
+ const flags = /* @__PURE__ */ new Set();
11002
+ const walk = (command) => {
11003
+ for (const option of command.options) {
11004
+ if (!option.required && !option.optional) {
11005
+ continue;
11006
+ }
11007
+ if (option.long) {
11008
+ flags.add(option.long);
11009
+ }
11010
+ if (option.short) {
11011
+ flags.add(option.short);
11012
+ }
11013
+ }
11014
+ for (const sub of command.commands) {
11015
+ walk(sub);
11016
+ }
11017
+ };
11018
+ walk(root);
11019
+ return flags;
11020
+ }
11021
+ function descend(root, words) {
11022
+ const flagsWithValues = collectFlagsThatTakeValues(root);
11023
+ let current = root;
11024
+ let index = 0;
11025
+ while (index < words.length) {
11026
+ const word = words[index];
11027
+ if (word.startsWith("-")) {
11028
+ const [flagPart] = word.split("=", 1);
11029
+ if (flagPart && flagsWithValues.has(flagPart) && !word.includes("=")) {
11030
+ index += 2;
11031
+ } else {
11032
+ index += 1;
11033
+ }
11034
+ continue;
11035
+ }
11036
+ const next = findSubcommand(current, word);
11037
+ if (!next) {
11038
+ break;
11039
+ }
11040
+ current = next;
11041
+ index += 1;
11042
+ }
11043
+ return current;
11044
+ }
11045
+ function collectVisibleSubcommands(command) {
11046
+ const names = [];
11047
+ for (const sub of command.commands) {
11048
+ if (sub.name().startsWith("__")) {
11049
+ continue;
11050
+ }
11051
+ names.push(sub.name());
11052
+ }
11053
+ return names;
11054
+ }
11055
+ function collectVisibleLongFlags(command) {
11056
+ const flags = [];
11057
+ let current = command;
11058
+ while (current) {
11059
+ for (const option of current.options) {
11060
+ if (option.hidden || !option.long) {
11061
+ continue;
11062
+ }
11063
+ if (!flags.includes(option.long)) {
11064
+ flags.push(option.long);
11065
+ }
11066
+ }
11067
+ current = current.parent;
11068
+ }
11069
+ if (!flags.includes("--help")) {
11070
+ flags.push("--help");
11071
+ }
11072
+ return flags;
11073
+ }
11074
+ function getCompletions(program, request, deps = {}) {
11075
+ const { words, cwordIndex } = request;
11076
+ const safeIndex = Math.max(0, Math.min(cwordIndex, words.length));
11077
+ const current = words[safeIndex] ?? "";
11078
+ const prevToken = safeIndex > 0 ? words[safeIndex - 1] : void 0;
11079
+ const readProfiles = deps.readProfileNames ?? readProfileNamesFromConfig;
11080
+ if (prevToken === "--profile" || prevToken === "-p") {
11081
+ try {
11082
+ return readProfiles(deps.configPath).filter((name) => name.startsWith(current)).slice().sort();
11083
+ } catch {
11084
+ return [];
11085
+ }
11086
+ }
11087
+ const tokensBeforeCurrent = words.slice(1, safeIndex);
11088
+ const command = descend(program, tokensBeforeCurrent);
11089
+ const candidates = /* @__PURE__ */ new Set();
11090
+ if (current.startsWith("-")) {
11091
+ for (const flag of collectVisibleLongFlags(command)) {
11092
+ if (flag.startsWith(current)) {
11093
+ candidates.add(flag);
11094
+ }
11095
+ }
11096
+ return [...candidates].sort();
11097
+ }
11098
+ for (const subcommand of collectVisibleSubcommands(command)) {
11099
+ if (subcommand.startsWith(current)) {
11100
+ candidates.add(subcommand);
11101
+ }
11102
+ }
11103
+ for (const flag of collectVisibleLongFlags(command)) {
11104
+ if (flag.startsWith(current)) {
11105
+ candidates.add(flag);
11106
+ }
11107
+ }
11108
+ return [...candidates].sort();
11109
+ }
11110
+
11111
+ // src/completion/install.ts
11112
+ import { execFileSync } from "child_process";
11113
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "fs";
11114
+ import { homedir as homedir2, platform } from "os";
11115
+ import { basename as basename2, dirname as dirname2, join as join2 } from "path";
11116
+
11117
+ // src/completion/scripts.ts
11118
+ var PROGRAM = "zinkee";
11119
+ var ENV_VAR = "_ZINKEE_COMPLETE";
11120
+ function renderBashScript() {
11121
+ return `_zinkee_completion() {
11122
+ local IFS=$'\\n'
11123
+ local response
11124
+
11125
+ response=$(env COMP_WORDS="\${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD ${ENV_VAR}=bash_complete ${PROGRAM} 2>/dev/null)
11126
+
11127
+ COMPREPLY=( \${response} )
11128
+ return 0
11129
+ }
11130
+
11131
+ complete -o default -F _zinkee_completion ${PROGRAM}
11132
+ `;
11133
+ }
11134
+ function renderZshScript() {
11135
+ return `#compdef ${PROGRAM}
11136
+
11137
+ _zinkee_completion() {
11138
+ local -a response
11139
+ (( ! $+commands[${PROGRAM}] )) && return 1
11140
+
11141
+ response=("\${(@f)$(env COMP_WORDS="\${words[*]}" COMP_CWORD=$((CURRENT - 1)) ${ENV_VAR}=zsh_complete ${PROGRAM} 2>/dev/null)}")
11142
+
11143
+ if [ -n "$response" ]; then
11144
+ compadd -U -V unsorted -a response
11145
+ fi
11146
+ }
11147
+
11148
+ if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
11149
+ _zinkee_completion "$@"
11150
+ else
11151
+ compdef _zinkee_completion ${PROGRAM}
11152
+ fi
11153
+ `;
11154
+ }
11155
+ function renderFishScript() {
11156
+ return `function __zinkee_completion
11157
+ set -l tokens (commandline -opc) (commandline -ct)
11158
+ set -l cword (math (count $tokens) - 1)
11159
+ set -l joined (string join " " -- $tokens)
11160
+
11161
+ env COMP_WORDS="$joined" COMP_CWORD=$cword ${ENV_VAR}=fish_complete ${PROGRAM} 2>/dev/null
11162
+ end
11163
+
11164
+ complete --no-files --command ${PROGRAM} --arguments '(__zinkee_completion)'
11165
+ `;
11166
+ }
11167
+ function renderPowerShellScript() {
11168
+ return `Register-ArgumentCompleter -Native -CommandName ${PROGRAM} -ScriptBlock {
11169
+ param($wordToComplete, $commandAst, $cursorPosition)
11170
+
11171
+ $tokens = @($commandAst.CommandElements | ForEach-Object { $_.ToString() })
11172
+ $cword = [Math]::Max(0, $tokens.Count - 1)
11173
+
11174
+ $env:COMP_WORDS = ($tokens -join ' ')
11175
+ $env:COMP_CWORD = $cword
11176
+ $env:${ENV_VAR} = 'powershell_complete'
11177
+
11178
+ try {
11179
+ & ${PROGRAM} 2>$null | ForEach-Object {
11180
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
11181
+ }
11182
+ } finally {
11183
+ Remove-Item Env:COMP_WORDS -ErrorAction SilentlyContinue
11184
+ Remove-Item Env:COMP_CWORD -ErrorAction SilentlyContinue
11185
+ Remove-Item Env:${ENV_VAR} -ErrorAction SilentlyContinue
11186
+ }
11187
+ }
11188
+ `;
11189
+ }
11190
+ function renderScript(shell) {
11191
+ switch (shell) {
11192
+ case "bash":
11193
+ return renderBashScript();
11194
+ case "zsh":
11195
+ return renderZshScript();
11196
+ case "fish":
11197
+ return renderFishScript();
11198
+ case "powershell":
11199
+ return renderPowerShellScript();
11200
+ }
11201
+ }
11202
+
11203
+ // src/completion/install.ts
11204
+ var SUPPORTED_SHELLS = [
11205
+ "bash",
11206
+ "zsh",
11207
+ "fish",
11208
+ "powershell"
11209
+ ];
11210
+ var BLOCK_BEGIN = "# >>> zinkee completion >>>";
11211
+ var BLOCK_END = "# <<< zinkee completion <<<";
11212
+ var CompletionShellError = class extends Error {
11213
+ name = "CompletionShellError";
11214
+ };
11215
+ function defaultPowerShellProfile(env) {
11216
+ for (const exe of ["pwsh", "powershell.exe"]) {
11217
+ try {
11218
+ const out = execFileSync(exe, ["-NoProfile", "-Command", "$PROFILE"], {
11219
+ encoding: "utf8",
11220
+ stdio: ["ignore", "pipe", "ignore"]
11221
+ });
11222
+ const path = out.trim();
11223
+ if (path) {
11224
+ return path;
11225
+ }
11226
+ } catch {
11227
+ }
11228
+ }
11229
+ if (env.platform === "win32") {
11230
+ return join2(env.home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
11231
+ }
11232
+ return join2(env.home, ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
11233
+ }
11234
+ function detectShell(env) {
11235
+ const fromEnv = env.shellEnv;
11236
+ if (fromEnv) {
11237
+ const name = basename2(fromEnv).toLowerCase().replace(/\.exe$/, "");
11238
+ if (name === "bash") {
11239
+ return "bash";
11240
+ }
11241
+ if (name === "zsh") {
11242
+ return "zsh";
11243
+ }
11244
+ if (name === "fish") {
11245
+ return "fish";
11246
+ }
11247
+ if (name === "pwsh" || name === "powershell") {
11248
+ return "powershell";
11249
+ }
11250
+ }
11251
+ if (env.platform === "win32") {
11252
+ return "powershell";
11253
+ }
11254
+ throw new CompletionShellError(
11255
+ `Could not detect a supported shell from $SHELL=${fromEnv ?? ""}. Pass one of: ${SUPPORTED_SHELLS.join(", ")}.`
11256
+ );
11257
+ }
11258
+ function parseShell(value) {
11259
+ const normalized = value.toLowerCase();
11260
+ if (normalized === "bash" || normalized === "zsh" || normalized === "fish" || normalized === "powershell") {
11261
+ return normalized;
11262
+ }
11263
+ if (normalized === "pwsh") {
11264
+ return "powershell";
11265
+ }
11266
+ throw new CompletionShellError(
11267
+ `Unsupported shell "${value}". Supported: ${SUPPORTED_SHELLS.join(", ")}.`
11268
+ );
11269
+ }
11270
+ function resolveTarget(shell, env) {
11271
+ switch (shell) {
11272
+ case "bash":
11273
+ return {
11274
+ shell,
11275
+ scriptPath: join2(env.home, ".bash_completions", "zinkee.sh"),
11276
+ rcPath: join2(env.home, ".bashrc")
11277
+ };
11278
+ case "zsh":
11279
+ return {
11280
+ shell,
11281
+ scriptPath: join2(env.home, ".zfunc", "_zinkee"),
11282
+ rcPath: join2(env.home, ".zshrc")
11283
+ };
11284
+ case "fish":
11285
+ return {
11286
+ shell,
11287
+ scriptPath: join2(env.home, ".config", "fish", "completions", "zinkee.fish")
11288
+ };
11289
+ case "powershell": {
11290
+ const resolver = env.resolvePowerShellProfile ?? (() => defaultPowerShellProfile(env));
11291
+ const profilePath = resolver();
11292
+ if (!profilePath) {
11293
+ throw new CompletionShellError(
11294
+ "Could not resolve PowerShell $PROFILE path. Install PowerShell or use --show-completion."
11295
+ );
11296
+ }
11297
+ return {
11298
+ shell,
11299
+ scriptPath: profilePath,
11300
+ rcPath: profilePath
11301
+ };
11302
+ }
11303
+ }
11304
+ }
11305
+ function buildRcSnippet(shell, scriptPath) {
11306
+ switch (shell) {
11307
+ case "bash":
11308
+ return `source "${scriptPath}"`;
11309
+ case "zsh":
11310
+ return [
11311
+ `fpath=("${dirname2(scriptPath)}" $fpath)`,
11312
+ "autoload -Uz compinit && compinit"
11313
+ ].join("\n");
11314
+ default:
11315
+ return "";
11316
+ }
11317
+ }
11318
+ function applyBlock(existing, block) {
11319
+ const wrapped = `${BLOCK_BEGIN}
11320
+ ${block.trimEnd()}
11321
+ ${BLOCK_END}
11322
+ `;
11323
+ const blockPattern = new RegExp(
11324
+ `${BLOCK_BEGIN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${BLOCK_END.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\n?`,
11325
+ "m"
11326
+ );
11327
+ if (blockPattern.test(existing)) {
11328
+ return existing.replace(blockPattern, wrapped);
11329
+ }
11330
+ const separator = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
11331
+ return `${existing}${separator}${wrapped}`;
11332
+ }
11333
+ function readFileOrEmpty(path) {
11334
+ try {
11335
+ return readFileSync10(path, "utf8");
11336
+ } catch (error) {
11337
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
11338
+ return "";
11339
+ }
11340
+ throw error;
11341
+ }
11342
+ }
11343
+ function writeFileEnsuringDir(path, content) {
11344
+ mkdirSync2(dirname2(path), { recursive: true });
11345
+ writeFileSync3(path, content, "utf8");
11346
+ }
11347
+ function installCompletion(shell, env) {
11348
+ const target = resolveTarget(shell, env);
11349
+ const script = renderScript(shell);
11350
+ if (shell === "powershell") {
11351
+ const existing = readFileOrEmpty(target.scriptPath);
11352
+ const updated = applyBlock(existing, script);
11353
+ writeFileEnsuringDir(target.scriptPath, updated);
11354
+ return {
11355
+ shell,
11356
+ scriptPath: target.scriptPath,
11357
+ rcPath: target.scriptPath,
11358
+ rcUpdated: true
11359
+ };
11360
+ }
11361
+ writeFileEnsuringDir(target.scriptPath, script);
11362
+ if (!target.rcPath) {
11363
+ return {
11364
+ shell,
11365
+ scriptPath: target.scriptPath,
11366
+ rcUpdated: false
11367
+ };
11368
+ }
11369
+ const snippet = buildRcSnippet(shell, target.scriptPath);
11370
+ if (!snippet) {
11371
+ return {
11372
+ shell,
11373
+ scriptPath: target.scriptPath,
11374
+ rcPath: target.rcPath,
11375
+ rcUpdated: false
11376
+ };
11377
+ }
11378
+ const existingRc = readFileOrEmpty(target.rcPath);
11379
+ const updatedRc = applyBlock(existingRc, snippet);
11380
+ if (updatedRc !== existingRc) {
11381
+ writeFileEnsuringDir(target.rcPath, updatedRc);
11382
+ return {
11383
+ shell,
11384
+ scriptPath: target.scriptPath,
11385
+ rcPath: target.rcPath,
11386
+ rcUpdated: true
11387
+ };
11388
+ }
11389
+ return {
11390
+ shell,
11391
+ scriptPath: target.scriptPath,
11392
+ rcPath: target.rcPath,
11393
+ rcUpdated: false
11394
+ };
11395
+ }
11396
+ function currentEnvironment() {
11397
+ return {
11398
+ home: homedir2(),
11399
+ platform: platform(),
11400
+ shellEnv: process.env.SHELL
11401
+ };
11402
+ }
11403
+
11404
+ // src/completion/runtime.ts
11405
+ var COMPLETION_ENV_VAR = "_ZINKEE_COMPLETE";
11406
+ function getStream(stream, fallback) {
11407
+ return stream ?? fallback;
11408
+ }
11409
+ function parseEnvWords(env) {
11410
+ const raw = env.COMP_WORDS ?? "";
11411
+ if (raw.trim().length === 0) {
11412
+ return [];
11413
+ }
11414
+ return raw.split(/\s+/).filter((token) => token.length > 0);
11415
+ }
11416
+ function parseEnvCwordIndex(env) {
11417
+ const raw = env.COMP_CWORD ?? "0";
11418
+ const parsed = Number.parseInt(raw, 10);
11419
+ if (Number.isNaN(parsed) || parsed < 0) {
11420
+ return 0;
11421
+ }
11422
+ return parsed;
11423
+ }
11424
+ function isCompletionRequest(env = process.env) {
11425
+ return typeof env[COMPLETION_ENV_VAR] === "string" && env[COMPLETION_ENV_VAR].length > 0;
11426
+ }
11427
+ function runCompletionRequest(env = process.env, stdout) {
11428
+ const out = getStream(stdout, process.stdout);
11429
+ try {
11430
+ const program = buildProgram();
11431
+ const candidates = getCompletions(program, {
11432
+ words: parseEnvWords(env),
11433
+ cwordIndex: parseEnvCwordIndex(env)
11434
+ });
11435
+ if (candidates.length > 0) {
11436
+ out.write(`${candidates.join("\n")}
11437
+ `);
11438
+ }
11439
+ } catch {
11440
+ }
11441
+ }
11442
+ function extractCompletionFlag(argv) {
11443
+ for (let index = 0; index < argv.length; index += 1) {
11444
+ const token = argv[index];
11445
+ if (!token) {
11446
+ continue;
11447
+ }
11448
+ if (token === "--install-completion" || token === "--show-completion") {
11449
+ const mode = token === "--install-completion" ? "install" : "show";
11450
+ const next = argv[index + 1];
11451
+ const shellOverride = next && !next.startsWith("-") ? next : void 0;
11452
+ return { mode, shellOverride };
11453
+ }
11454
+ if (token.startsWith("--install-completion=")) {
11455
+ const value = token.slice("--install-completion=".length);
11456
+ return { mode: "install", shellOverride: value || void 0 };
11457
+ }
11458
+ if (token.startsWith("--show-completion=")) {
11459
+ const value = token.slice("--show-completion=".length);
11460
+ return { mode: "show", shellOverride: value || void 0 };
11461
+ }
11462
+ }
11463
+ return null;
11464
+ }
11465
+ function resolveShell(request, env) {
11466
+ if (request.shellOverride) {
11467
+ return parseShell(request.shellOverride);
11468
+ }
11469
+ return detectShell(env);
11470
+ }
11471
+ function handleCompletionFlag(request, deps = {}) {
11472
+ const env = deps.environment ?? currentEnvironment();
11473
+ const out = getStream(deps.stdout, process.stdout);
11474
+ const err = getStream(deps.stderr, process.stderr);
11475
+ let shell;
11476
+ try {
11477
+ shell = resolveShell(request, env);
11478
+ } catch (error) {
11479
+ const message = error instanceof CompletionShellError ? error.message : String(error);
11480
+ err.write(`${message}
11481
+ `);
11482
+ return 1;
11483
+ }
11484
+ if (request.mode === "show") {
11485
+ out.write(renderScript(shell));
11486
+ return 0;
11487
+ }
11488
+ try {
11489
+ const result = installCompletion(shell, env);
11490
+ err.write(`zinkee completion installed for ${shell}.
11491
+ `);
11492
+ err.write(` script: ${result.scriptPath}
11493
+ `);
11494
+ if (result.rcPath && result.rcPath !== result.scriptPath) {
11495
+ err.write(
11496
+ result.rcUpdated ? ` updated: ${result.rcPath}
11497
+ ` : ` unchanged: ${result.rcPath}
11498
+ `
11499
+ );
11500
+ }
11501
+ err.write(`Restart your shell or open a new session to enable completion.
11502
+ `);
11503
+ return 0;
11504
+ } catch (error) {
11505
+ const message = error instanceof Error ? error.message : String(error);
11506
+ err.write(`Failed to install zinkee completion: ${message}
11507
+ `);
11508
+ return 1;
11509
+ }
11510
+ }
11511
+
9982
11512
  // src/cli-runner.ts
9983
11513
  var ExampleDisplayed = class extends Error {
9984
11514
  name = "ExampleDisplayed";
@@ -10001,6 +11531,16 @@ function isExecutedAsEntry(argvEntry, moduleUrl) {
10001
11531
  }
10002
11532
  async function runCli(argv) {
10003
11533
  try {
11534
+ if (isCompletionRequest()) {
11535
+ runCompletionRequest();
11536
+ return;
11537
+ }
11538
+ const completionFlag = extractCompletionFlag(argv);
11539
+ if (completionFlag) {
11540
+ const exitCode = handleCompletionFlag(completionFlag);
11541
+ process.exitCode = exitCode;
11542
+ return;
11543
+ }
10004
11544
  const exampleRequest = extractExampleRequest(argv);
10005
11545
  if (exampleRequest) {
10006
11546
  await showExamples(