@hanzo/build 0.2.9 → 0.2.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.
Files changed (152) hide show
  1. package/README.md +126 -23
  2. package/lib/api/agents.d.ts +80 -0
  3. package/lib/api/agents.js +148 -0
  4. package/lib/api/billing.d.ts +205 -0
  5. package/lib/api/billing.js +300 -0
  6. package/lib/api/call.d.ts +6 -0
  7. package/lib/api/call.js +11 -0
  8. package/lib/api/capabilities.d.ts +25 -0
  9. package/lib/api/capabilities.js +40 -0
  10. package/lib/api/changes.d.ts +56 -0
  11. package/lib/api/changes.js +63 -0
  12. package/lib/api/coding.d.ts +42 -4
  13. package/lib/api/coding.js +62 -3
  14. package/lib/api/connectors.d.ts +90 -0
  15. package/lib/api/connectors.js +109 -0
  16. package/lib/api/consent.d.ts +22 -0
  17. package/lib/api/consent.js +28 -0
  18. package/lib/api/environment.d.ts +57 -0
  19. package/lib/api/environment.js +85 -0
  20. package/lib/api/git.d.ts +6 -2
  21. package/lib/api/git.js +13 -5
  22. package/lib/api/github.d.ts +13 -0
  23. package/lib/api/github.js +9 -0
  24. package/lib/api/harness.d.ts +44 -0
  25. package/lib/api/harness.js +348 -0
  26. package/lib/api/keys.d.ts +41 -0
  27. package/lib/api/keys.js +55 -0
  28. package/lib/api/machines.d.ts +56 -0
  29. package/lib/api/machines.js +84 -0
  30. package/lib/api/members.d.ts +47 -0
  31. package/lib/api/members.js +88 -0
  32. package/lib/api/memory.d.ts +25 -0
  33. package/lib/api/memory.js +34 -0
  34. package/lib/api/places.d.ts +2 -2
  35. package/lib/api/places.js +3 -26
  36. package/lib/api/plugins.d.ts +55 -0
  37. package/lib/api/plugins.js +62 -0
  38. package/lib/api/pref.d.ts +49 -0
  39. package/lib/api/pref.js +68 -0
  40. package/lib/api/profile.d.ts +21 -0
  41. package/lib/api/profile.js +40 -0
  42. package/lib/api/projects.d.ts +19 -2
  43. package/lib/api/projects.js +29 -4
  44. package/lib/api/provider.d.ts +42 -0
  45. package/lib/api/provider.js +58 -0
  46. package/lib/api/sandbox.d.ts +30 -0
  47. package/lib/api/sandbox.js +49 -0
  48. package/lib/api/sessions.d.ts +39 -4
  49. package/lib/api/sessions.js +58 -6
  50. package/lib/api/skills.d.ts +70 -0
  51. package/lib/api/skills.js +90 -0
  52. package/lib/api/tools.d.ts +34 -0
  53. package/lib/api/tools.js +37 -0
  54. package/lib/api/turn.d.ts +84 -16
  55. package/lib/api/turn.js +224 -4
  56. package/lib/api/webhooks.d.ts +60 -0
  57. package/lib/api/webhooks.js +81 -0
  58. package/lib/ask.d.ts +18 -0
  59. package/lib/ask.js +69 -0
  60. package/lib/builder.js +39 -19
  61. package/lib/customize/agents.d.ts +2 -0
  62. package/lib/customize/agents.js +125 -0
  63. package/lib/customize/connectors.d.ts +2 -0
  64. package/lib/customize/connectors.js +197 -0
  65. package/lib/customize/index.d.ts +6 -0
  66. package/lib/customize/index.js +50 -0
  67. package/lib/customize/plugins.d.ts +2 -0
  68. package/lib/customize/plugins.js +93 -0
  69. package/lib/customize/skills.d.ts +2 -0
  70. package/lib/customize/skills.js +125 -0
  71. package/lib/customize/ui.d.ts +110 -0
  72. package/lib/customize/ui.js +99 -0
  73. package/lib/desk.d.ts +8 -1
  74. package/lib/desk.js +29 -35
  75. package/lib/door.d.ts +7 -0
  76. package/lib/door.js +89 -0
  77. package/lib/environment.d.ts +15 -0
  78. package/lib/environment.js +132 -0
  79. package/lib/files.d.ts +14 -0
  80. package/lib/files.js +111 -0
  81. package/lib/find.d.ts +7 -0
  82. package/lib/find.js +77 -0
  83. package/lib/foot.d.ts +16 -0
  84. package/lib/foot.js +36 -0
  85. package/lib/forge.js +8 -4
  86. package/lib/git.d.ts +9 -0
  87. package/lib/git.js +74 -0
  88. package/lib/host.d.ts +5 -0
  89. package/lib/landing.d.ts +10 -0
  90. package/lib/landing.js +47 -14
  91. package/lib/markdown.d.ts +49 -0
  92. package/lib/markdown.js +123 -0
  93. package/lib/plans.d.ts +1 -0
  94. package/lib/plans.js +113 -0
  95. package/lib/prefs.d.ts +30 -0
  96. package/lib/prefs.js +83 -0
  97. package/lib/prose.d.ts +4 -0
  98. package/lib/prose.js +53 -0
  99. package/lib/route.d.ts +16 -1
  100. package/lib/route.js +32 -1
  101. package/lib/run.js +207 -28
  102. package/lib/section.js +2 -2
  103. package/lib/settings/account.d.ts +5 -0
  104. package/lib/settings/account.js +111 -0
  105. package/lib/settings/billing.d.ts +1 -0
  106. package/lib/settings/billing.js +104 -0
  107. package/lib/settings/capabilities.d.ts +1 -0
  108. package/lib/settings/capabilities.js +55 -0
  109. package/lib/settings/card.d.ts +31 -0
  110. package/lib/settings/card.js +105 -0
  111. package/lib/settings/code.d.ts +1 -0
  112. package/lib/settings/code.js +51 -0
  113. package/lib/settings/environments.d.ts +1 -0
  114. package/lib/settings/environments.js +53 -0
  115. package/lib/settings/general.d.ts +1 -0
  116. package/lib/settings/general.js +44 -0
  117. package/lib/settings/index.d.ts +4 -0
  118. package/lib/settings/index.js +22 -0
  119. package/lib/settings/integrations.d.ts +1 -0
  120. package/lib/settings/integrations.js +81 -0
  121. package/lib/settings/keys.d.ts +1 -0
  122. package/lib/settings/keys.js +102 -0
  123. package/lib/settings/machines.d.ts +1 -0
  124. package/lib/settings/machines.js +118 -0
  125. package/lib/settings/members.d.ts +1 -0
  126. package/lib/settings/members.js +67 -0
  127. package/lib/settings/memory.d.ts +1 -0
  128. package/lib/settings/memory.js +56 -0
  129. package/lib/settings/notifications.d.ts +1 -0
  130. package/lib/settings/notifications.js +97 -0
  131. package/lib/settings/privacy.d.ts +1 -0
  132. package/lib/settings/privacy.js +63 -0
  133. package/lib/settings/sections.d.ts +16 -0
  134. package/lib/settings/sections.js +32 -0
  135. package/lib/settings/ui.d.ts +49 -0
  136. package/lib/settings/ui.js +47 -0
  137. package/lib/settings/usage.d.ts +1 -0
  138. package/lib/settings/usage.js +114 -0
  139. package/lib/shelf.d.ts +6 -0
  140. package/lib/shelf.js +86 -16
  141. package/lib/switch.js +1 -2
  142. package/lib/transcript.d.ts +12 -0
  143. package/lib/transcript.js +56 -0
  144. package/lib/voice.d.ts +3 -1
  145. package/lib/voice.js +10 -4
  146. package/package.json +1 -1
  147. package/lib/account.d.ts +0 -14
  148. package/lib/account.js +0 -38
  149. package/lib/e2e/site.spec.d.ts +0 -1
  150. package/lib/e2e/site.spec.js +0 -125
  151. package/lib/mcp.d.ts +0 -1
  152. package/lib/mcp.js +0 -28
@@ -1,125 +0,0 @@
1
- /**
2
- * hanzo.build in a browser: every screen draws, stays on this origin, and
3
- * never asks platform.hanzo.ai for anything. Signed out, so it checks what a
4
- * visitor sees; the MCP list is public and is read live.
5
- */
6
- import { expect, test } from '@playwright/test';
7
- const SCREENS = [
8
- ['new', '/', /What.s up next\?/],
9
- ['automations', '/-/automations', /New automation/],
10
- ['codebases', '/-/codebases', /Create and browse this organization.s repositories/],
11
- ['sync', '/-/sync', /Select repositories/],
12
- ['projects', '/-/projects', /Boards on the forge/],
13
- ['issues', '/-/issues', /Open work across every board/],
14
- ['artifacts', '/-/artifacts', /What this organization has built/],
15
- ['templates', '/-/templates', /Start from a working app/],
16
- ['mcp', '/-/mcp', /Native servers/],
17
- ['run', '/sess_0992f90537264a6b154ebff799f38e1c', /Sign in to follow this run/],
18
- ];
19
- const RAIL = ['New', 'Automations', 'Codebase', 'Projects', 'Issues', 'Artifacts', 'MCP'];
20
- /** Everything the page asked for and every error it threw, for the whole test. */
21
- function watch(page) {
22
- const hosts = new Set();
23
- const errors = [];
24
- page.on('request', (r) => hosts.add(new URL(r.url()).hostname));
25
- page.on('pageerror', (e) => errors.push(e.message));
26
- return { hosts, errors };
27
- }
28
- for (const [name, path, says] of SCREENS) {
29
- test(`${name} draws on this origin`, async ({ page, baseURL }, info) => {
30
- const seen = watch(page);
31
- await page.goto(path);
32
- await expect(page.getByText(says).first()).toBeVisible();
33
- for (const label of RAIL)
34
- await expect(page.getByText(label, { exact: true }).first()).toBeVisible();
35
- await page.waitForLoadState('networkidle');
36
- expect(new URL(page.url()).origin).toBe(new URL(baseURL).origin);
37
- expect([...seen.hosts]).not.toContain('platform.hanzo.ai');
38
- expect(seen.errors).toEqual([]);
39
- await page.screenshot({ path: info.outputPath(`${name}.png`) });
40
- });
41
- }
42
- test('the rail moves between screens without leaving the page', async ({ page, baseURL }) => {
43
- const seen = watch(page);
44
- await page.goto('/');
45
- for (const [label, at] of [
46
- ['Automations', '/-/automations'],
47
- ['Codebase', '/-/codebases'],
48
- ['Projects', '/-/projects'],
49
- ['Issues', '/-/issues'],
50
- ['Artifacts', '/-/artifacts'],
51
- ['MCP', '/-/mcp'],
52
- ['New', '/'],
53
- ]) {
54
- await page.getByText(label, { exact: true }).first().click();
55
- await expect(page).toHaveURL(new URL(at, baseURL).href);
56
- }
57
- expect([...seen.hosts]).not.toContain('platform.hanzo.ai');
58
- });
59
- test('one mark at the top left when signed out', async ({ page }) => {
60
- await page.goto('/');
61
- await expect(page.getByRole('button', { name: 'Hanzo', exact: true })).toHaveCount(1);
62
- await expect(page.getByText('Sign in', { exact: true }).first()).toBeVisible();
63
- });
64
- test('settings stays on this page', async ({ page, baseURL }) => {
65
- await page.goto('/-/codebases');
66
- await page.getByText('Settings', { exact: true }).first().click();
67
- expect(new URL(page.url()).origin).toBe(new URL(baseURL).origin);
68
- });
69
- test('the MCP screen lists the native servers', async ({ page }, info) => {
70
- await page.goto('/-/mcp');
71
- const count = page.getByText(/^\d+ servers · \d+ operations$/);
72
- await expect(count).toBeVisible();
73
- const servers = Number((await count.innerText()).split(' ')[0]);
74
- expect(servers).toBeGreaterThan(100);
75
- await page.getByLabel('Find a server').fill('git');
76
- await expect(page.getByLabel('git', { exact: true })).toBeVisible();
77
- await page.screenshot({ path: info.outputPath('mcp-git.png') });
78
- });
79
- test('a run hides and shows its side pane', async ({ page }) => {
80
- await page.goto('/sess_0992f90537264a6b154ebff799f38e1c');
81
- await page.getByLabel('Hide the side pane').click();
82
- await expect(page.getByText('Subscriptions', { exact: true })).toHaveCount(0);
83
- await page.getByLabel('Show the side pane').click();
84
- await expect(page.getByText('Subscriptions', { exact: true })).toBeVisible();
85
- });
86
- /** Controls and text a phone would cut off at its right edge, or that sit on top of another control. */
87
- async function cramped(page) {
88
- return page.evaluate(() => {
89
- const w = window.innerWidth;
90
- const out = [];
91
- const leaves = [...document.querySelectorAll('body *')].filter((el) => !el.children.length || ['BUTTON', 'INPUT'].includes(el.tagName) || el.getAttribute('role') === 'button');
92
- for (const el of leaves) {
93
- const r = el.getBoundingClientRect();
94
- const s = getComputedStyle(el);
95
- if (!r.width || !r.height || s.visibility === 'hidden' || s.opacity === '0')
96
- continue;
97
- if (r.right > w + 1 || r.left < -1)
98
- out.push(`${el.tagName} ${(el.textContent || el.getAttribute('aria-label') || '').trim().slice(0, 40)}`);
99
- }
100
- const menu = document.querySelector('[aria-label="Open runs"]')?.getBoundingClientRect();
101
- const mark = [...document.querySelectorAll('[aria-label="Hanzo"], [aria-label^="Organization"]')]
102
- .map((el) => el.getBoundingClientRect())
103
- .find((r) => r.width && r.height);
104
- if (menu && mark && mark.left < menu.right && menu.left < mark.right && mark.top < menu.bottom && menu.top < mark.bottom)
105
- out.push('the mark sits on the menu button');
106
- return out;
107
- });
108
- }
109
- test('a phone gets every screen whole, with the rail as a drawer', async ({ page }, info) => {
110
- await page.setViewportSize({ width: 390, height: 844 });
111
- for (const [name, path, says] of SCREENS) {
112
- await page.goto(path);
113
- await expect(page.getByText(says).first()).toBeVisible();
114
- await expect(page.getByLabel('Open runs')).toBeVisible();
115
- expect(await cramped(page), name).toEqual([]);
116
- await page.screenshot({ path: info.outputPath(`phone-${name}.png`) });
117
- }
118
- await page.getByLabel('Open runs').click();
119
- await expect(page.getByRole('navigation', { name: 'Runs' }).getByText('Codebase', { exact: true })).toBeVisible();
120
- });
121
- test('a run asks a visitor to sign in, not for an API key', async ({ page }) => {
122
- await page.goto('/sess_0992f90537264a6b154ebff799f38e1c');
123
- await expect(page.getByText('Sign in to follow this run.').first()).toBeVisible();
124
- await expect(page.getByText(/Authorization: Bearer/)).toHaveCount(0);
125
- });
package/lib/mcp.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function Servers(): import("react").JSX.Element;
package/lib/mcp.js DELETED
@@ -1,28 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * The fleet's native MCP servers.
4
- *
5
- * The list is the MCP server's own tools/list. A server starts when a run
6
- * calls it and stays up afterwards, so this pane lists them rather than
7
- * starting them.
8
- */
9
- import { SizableText, XStack, YStack } from '@hanzo/gui';
10
- import { ChevronDown } from '@hanzogui/lucide-icons-2';
11
- import { Input } from '@hanzo/ui';
12
- import { useState } from 'react';
13
- import { natives } from './api/mcp.js';
14
- import { useRead } from './data.js';
15
- import { useTarget } from './host.js';
16
- export function Servers() {
17
- const t = useTarget();
18
- const list = useRead(() => natives(t), [], [t]);
19
- const [q, setQ] = useState('');
20
- const [open, setOpen] = useState(null);
21
- const needle = q.trim().toLowerCase();
22
- const shown = list.value.filter((s) => !needle || s.name.toLowerCase().includes(needle) || s.ops.some((op) => op.toLowerCase().includes(needle)));
23
- const ops = shown.reduce((n, s) => n + s.ops.length, 0);
24
- return (_jsx(YStack, { flex: 1, minH: 0, overflow: "scroll", px: "$6", py: "$6", children: _jsxs(YStack, { width: "100%", maxW: 1040, mx: "auto", gap: "$4", children: [_jsxs(YStack, { gap: "$1", children: [_jsx(SizableText, { render: "h1", size: "$6", color: "$ink", children: "MCP" }), _jsx(SizableText, { size: "$2", color: "$soft", children: "Native servers. A run starts one when it calls it, and the server stays up afterwards." })] }), _jsx(Input, { value: q, onChangeText: setQ, placeholder: "Find a server or an operation\u2026", "aria-label": "Find a server" }), list.loading && list.value.length === 0 ? (_jsx(SizableText, { size: "$2", color: "$soft", children: "Reading the servers\u2026" })) : list.error && list.value.length === 0 ? (_jsx(SizableText, { size: "$2", color: "$soft", children: list.error.message })) : shown.length === 0 ? (_jsx(SizableText, { size: "$2", color: "$soft", children: list.value.length === 0 ? 'The MCP server listed no native servers.' : 'No server matches.' })) : (_jsxs(YStack, { gap: "$1", children: [_jsxs(SizableText, { size: "$1", color: "$soft", children: [shown.length, " servers \u00B7 ", ops, " operations"] }), shown.map((s) => {
25
- const on = open === s.name;
26
- return (_jsxs(YStack, { borderWidth: 1, borderColor: "$borderColor", rounded: "$3", overflow: "hidden", children: [_jsxs(XStack, { render: "button", "aria-expanded": on, "aria-label": s.name, items: "center", gap: "$3", px: "$3", py: "$2.5", hoverStyle: { bg: '$hover' }, onPress: () => setOpen(on ? null : s.name), children: [_jsxs(YStack, { flex: 1, minW: 0, gap: "$1", children: [_jsx(SizableText, { size: "$3", color: "$ink", children: s.name }), s.description ? (_jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: on ? undefined : 2, children: s.description })) : null] }), _jsx(SizableText, { size: "$1", color: "$soft", children: s.ops.length }), _jsx(ChevronDown, { size: 14, style: { transform: on ? 'rotate(180deg)' : undefined } })] }), on ? (_jsx(YStack, { px: "$3", py: "$2", gap: "$1", borderTopWidth: 1, borderColor: "$borderColor", children: s.ops.length === 0 ? (_jsx(SizableText, { size: "$1", color: "$soft", children: "This server named no operations." })) : (s.ops.map((op) => (_jsx(SizableText, { size: "$1", color: "$ink", children: op }, op)))) })) : null] }, s.name));
27
- })] }))] }) }));
28
- }