@tai42/api-client 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/schemas.ts CHANGED
@@ -490,6 +490,25 @@ export const manifestView = z.object({
490
490
  mcp: z.array(manifestMcpEntry),
491
491
  user_tools: z.array(z.string()),
492
492
  });
493
+
494
+ /**
495
+ * One `!ENV ${VAR[:default]}` marker the manifest's MCP section carries
496
+ * (`GET /api/manifest/mcp-env-refs`) — NAMES and BOOLEANS only, NEVER values.
497
+ * `pointer` is the RFC 6901 json-pointer of the leaf (`/mcp/<i>/config/...`);
498
+ * `has_default` is whether the marker carries a `:default`; `set` is whether the
499
+ * var resolves in the EFFECTIVE env (the resolution truth the install-time
500
+ * dangling refusal reads), so a var supplied by the deployment shows green, never
501
+ * a false red. The checklist derives from THIS alone — no env value is ever fetched.
502
+ */
503
+ export const mcpEnvRef = z.object({
504
+ var: z.string(),
505
+ pointer: z.string(),
506
+ has_default: z.boolean(),
507
+ set: z.boolean(),
508
+ });
509
+ export type McpEnvRef = z.infer<typeof mcpEnvRef>;
510
+ export const mcpEnvRefs = z.array(mcpEnvRef);
511
+ export type McpEnvRefs = z.infer<typeof mcpEnvRefs>;
493
512
  /**
494
513
  * The apply result every config-writer mutation returns (`POST /api/mcp-config`,
495
514
  * `POST /api/config/env`): the serving worker's local reload result (`status` +
@@ -784,7 +803,7 @@ export const connectionsList = z.object({
784
803
  total: z.number(),
785
804
  // Count of connections whose `auth_health_state` is not healthy across the whole
786
805
  // set (independent of any filter/limit) — the attention-badge count. Optional:
787
- // no UI consumes it this mission, and an older worker mid-rollout omits it.
806
+ // no UI consumes it, and an older worker mid-rollout omits it.
788
807
  unhealthy: z.number().optional(),
789
808
  });
790
809
 
@@ -1805,26 +1824,52 @@ export type RunTrace = z.infer<typeof runTrace>;
1805
1824
  // -- marketplace -------------------------------------------------------------
1806
1825
 
1807
1826
  /**
1808
- * One contained item of a marketplace plugin (a searchable row): its kind
1809
- * (tool / agent / extension / …), name, description, and free-form tags.
1827
+ * One contained item of a marketplace plugin's published version: its kind
1828
+ * (tool / agent / extension / …), name, description, free-form tags, and the
1829
+ * logical group it belongs to (`null` when ungrouped).
1810
1830
  */
1811
1831
  export const marketplaceItem = z.object({
1812
1832
  kind: z.string(),
1813
1833
  name: z.string(),
1814
1834
  description: z.string(),
1815
1835
  tags: z.array(z.string()),
1836
+ group: z.string().nullable(),
1816
1837
  });
1817
1838
  export type MarketplaceItem = z.infer<typeof marketplaceItem>;
1818
1839
 
1819
1840
  /**
1820
- * One item-level search row (`GET /api/marketplace/search`): the contained item
1821
- * plus the listing it belongs to. `ref` is the "namespace/name" install target
1822
- * (install targets the LISTING), so every row carries enough to group under and
1823
- * link to its plugin. `latest_version` is nullable defensively; the search
1824
- * relation only emits listings with a published version.
1841
+ * One kind summary of a search row: an item kind, how many UNGROUPED items of
1842
+ * that kind the listing's latest published version carries, and their names.
1843
+ * The registry orders the array count DESC then kind ASC, and each entry's
1844
+ * `names` ASC; the UI renders in that order.
1845
+ */
1846
+ export const marketplaceSearchKind = z.object({
1847
+ kind: z.string(),
1848
+ count: z.number(),
1849
+ names: z.array(z.string()),
1850
+ });
1851
+ export type MarketplaceSearchKind = z.infer<typeof marketplaceSearchKind>;
1852
+
1853
+ /**
1854
+ * One logical group of a search row: the group name and how many items the
1855
+ * listing's latest published version places in it. The registry orders the
1856
+ * array count DESC then name ASC; the UI renders in that order.
1857
+ */
1858
+ export const marketplaceSearchGroup = z.object({
1859
+ name: z.string(),
1860
+ count: z.number(),
1861
+ });
1862
+ export type MarketplaceSearchGroup = z.infer<typeof marketplaceSearchGroup>;
1863
+
1864
+ /**
1865
+ * One listing-level search row (`GET /api/marketplace/search`). `ref` is the
1866
+ * "namespace/name" install target, so every row carries enough to link to its
1867
+ * plugin. `latest_version` is nullable defensively; the search relation only
1868
+ * emits listings with a published version. `kinds` summarizes that latest
1869
+ * version's UNGROUPED items; `groups` summarizes its logical groups (`[]` when
1870
+ * none). Both keys are always present.
1825
1871
  */
1826
1872
  export const marketplaceSearchRow = z.object({
1827
- item: marketplaceItem,
1828
1873
  ref: z.string(),
1829
1874
  namespace: z.string(),
1830
1875
  name: z.string(),
@@ -1836,18 +1881,23 @@ export const marketplaceSearchRow = z.object({
1836
1881
  tags: z.array(z.string()),
1837
1882
  trust_tier: z.string(),
1838
1883
  pricing: z.string(),
1884
+ // A display-only premium flag: a badge, never a payment surface. Nullable
1885
+ // + optional: an older registry omits it, and it is absent on non-premium rows.
1886
+ premium: z.boolean().nullish(),
1839
1887
  latest_version: z.string().nullable(),
1840
1888
  downloads: z.number(),
1841
1889
  updated_at: z.string(),
1890
+ kinds: z.array(marketplaceSearchKind),
1891
+ groups: z.array(marketplaceSearchGroup),
1842
1892
  });
1843
1893
  export type MarketplaceSearchRow = z.infer<typeof marketplaceSearchRow>;
1844
1894
 
1845
1895
  /**
1846
- * One page of search rows. The wire carries no next-page field — has-next is
1896
+ * One page of listing rows. The wire carries no next-page field — has-next is
1847
1897
  * COMPUTED: `page * page_size < total`.
1848
1898
  */
1849
1899
  export const marketplaceSearchPage = z.object({
1850
- items: z.array(marketplaceSearchRow),
1900
+ listings: z.array(marketplaceSearchRow),
1851
1901
  total: z.number(),
1852
1902
  page: z.number(),
1853
1903
  page_size: z.number(),
@@ -1869,11 +1919,35 @@ export const marketplaceVersion = z.object({
1869
1919
  export type MarketplaceVersion = z.infer<typeof marketplaceVersion>;
1870
1920
 
1871
1921
  /**
1872
- * The listing's latest published version as embedded in its detail: the version
1873
- * plus the items that version contains.
1922
+ * The listing's latest published version as embedded in its detail: the version,
1923
+ * the items it contains, and a minimal typed passthrough of the published spec.
1924
+ *
1925
+ * `spec` is carried so the install dialog can read an mcp-server item's public
1926
+ * `mcp.env` marker strings (`provides[].mcp.env`) and collect its required `!ENV`
1927
+ * vars before install. Only that path is typed; everything else on the spec is
1928
+ * `.passthrough()`-preserved but unmodelled (zod would otherwise strip the whole
1929
+ * `spec` as an unknown key). Nullable + optional: a listing with nothing published
1930
+ * carries no spec.
1874
1931
  */
1875
1932
  export const marketplaceLatestVersion = marketplaceVersion.extend({
1876
1933
  items: z.array(marketplaceItem),
1934
+ spec: z
1935
+ .object({
1936
+ provides: z.array(
1937
+ z
1938
+ .object({
1939
+ kind: z.string(),
1940
+ name: z.string(),
1941
+ mcp: z
1942
+ .object({ env: z.record(z.string(), z.string()).nullish() })
1943
+ .passthrough()
1944
+ .nullish(),
1945
+ })
1946
+ .passthrough(),
1947
+ ),
1948
+ })
1949
+ .passthrough()
1950
+ .nullish(),
1877
1951
  });
1878
1952
  export type MarketplaceLatestVersion = z.infer<typeof marketplaceLatestVersion>;
1879
1953
 
@@ -1907,10 +1981,15 @@ export const marketplacePluginDetail = z.object({
1907
1981
  license: z.string().nullable(),
1908
1982
  homepage_url: z.string().nullable(),
1909
1983
  repository_url: z.string().nullable(),
1984
+ // The marketplace-stored docs-site URL: the store is the source, the UI a
1985
+ // link. Nullable + optional: absent on a listing with no published docs.
1986
+ docs_url: z.string().nullish(),
1910
1987
  categories: z.array(z.string()),
1911
1988
  tags: z.array(z.string()),
1912
1989
  trust_tier: z.string(),
1913
1990
  pricing: z.string(),
1991
+ // A display-only premium flag: a badge, never a payment surface.
1992
+ premium: z.boolean().nullish(),
1914
1993
  downloads: z.number(),
1915
1994
  latest: marketplaceLatestVersion.nullable(),
1916
1995
  versions: z.array(marketplaceVersion),
@@ -1954,6 +2033,10 @@ export const marketplaceInstalledPlugin = z
1954
2033
  incompatible_newer: z.string().nullable(),
1955
2034
  missing_upstream: z.boolean(),
1956
2035
  compat: marketplaceInstalledCompat,
2036
+ // The `{kind, name}` of every item this plugin's stored spec provides
2037
+ // (local truth). The McpTab joins the mcp-server item names against the
2038
+ // manifest's mcp-entry titles to render an installer-written entry read-only.
2039
+ items: z.array(marketplaceItem.pick({ kind: true, name: true })),
1957
2040
  })
1958
2041
  .strict();
1959
2042
  export type MarketplaceInstalledPlugin = z.infer<typeof marketplaceInstalledPlugin>;