@hanzo/build 0.2.79 → 0.2.81

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 (167) hide show
  1. package/README.md +22 -4
  2. package/lib/activity.d.ts +3 -7
  3. package/lib/activity.js +18 -5
  4. package/lib/api/agents.d.ts +36 -35
  5. package/lib/api/agents.js +66 -29
  6. package/lib/api/auto.d.ts +3 -23
  7. package/lib/api/auto.js +39 -22
  8. package/lib/api/billing.d.ts +0 -35
  9. package/lib/api/billing.js +6 -5
  10. package/lib/api/call.d.ts +16 -8
  11. package/lib/api/call.js +32 -1
  12. package/lib/api/capabilities.d.ts +0 -11
  13. package/lib/api/capabilities.js +2 -1
  14. package/lib/api/codebases.d.ts +0 -10
  15. package/lib/api/codebases.js +3 -2
  16. package/lib/api/coding.d.ts +3 -32
  17. package/lib/api/coding.js +13 -7
  18. package/lib/api/connectors.d.ts +1 -17
  19. package/lib/api/connectors.js +5 -4
  20. package/lib/api/environment.d.ts +6 -20
  21. package/lib/api/environment.js +22 -19
  22. package/lib/api/github.d.ts +0 -22
  23. package/lib/api/github.js +3 -2
  24. package/lib/api/keys.d.ts +0 -14
  25. package/lib/api/keys.js +4 -3
  26. package/lib/api/library.d.ts +3 -17
  27. package/lib/api/library.js +23 -22
  28. package/lib/api/machines.d.ts +0 -15
  29. package/lib/api/machines.js +6 -5
  30. package/lib/api/mcp.d.ts +0 -9
  31. package/lib/api/mcp.js +3 -2
  32. package/lib/api/members.d.ts +0 -15
  33. package/lib/api/members.js +4 -3
  34. package/lib/api/memory.d.ts +0 -11
  35. package/lib/api/memory.js +2 -1
  36. package/lib/api/places.d.ts +1 -9
  37. package/lib/api/places.js +12 -1
  38. package/lib/api/plugins.d.ts +1 -16
  39. package/lib/api/plugins.js +4 -3
  40. package/lib/api/profile.d.ts +0 -10
  41. package/lib/api/profile.js +5 -4
  42. package/lib/api/projects.d.ts +0 -14
  43. package/lib/api/projects.js +2 -1
  44. package/lib/api/provider.d.ts +2 -14
  45. package/lib/api/provider.js +12 -10
  46. package/lib/api/sandbox.d.ts +0 -17
  47. package/lib/api/sandbox.js +5 -4
  48. package/lib/api/sessions.d.ts +0 -17
  49. package/lib/api/sessions.js +5 -4
  50. package/lib/api/skills.d.ts +1 -15
  51. package/lib/api/skills.js +5 -4
  52. package/lib/api/studio.d.ts +0 -14
  53. package/lib/api/studio.js +6 -5
  54. package/lib/api/turn.d.ts +6 -28
  55. package/lib/api/turn.js +105 -49
  56. package/lib/api/verdict.d.ts +0 -9
  57. package/lib/api/verdict.js +2 -1
  58. package/lib/api/webhooks.d.ts +1 -14
  59. package/lib/api/webhooks.js +5 -4
  60. package/lib/ask.js +7 -4
  61. package/lib/automations.d.ts +5 -4
  62. package/lib/automations.js +95 -74
  63. package/lib/back.js +10 -4
  64. package/lib/builder.js +7 -5
  65. package/lib/carry.js +20 -16
  66. package/lib/customize/agents.d.ts +3 -0
  67. package/lib/customize/agents.js +152 -55
  68. package/lib/customize/connectors.js +62 -48
  69. package/lib/customize/index.js +45 -14
  70. package/lib/customize/plugins.js +34 -22
  71. package/lib/customize/say.d.ts +13 -1
  72. package/lib/customize/say.js +15 -21
  73. package/lib/customize/skills.js +31 -22
  74. package/lib/customize/ui.d.ts +5 -9
  75. package/lib/customize/ui.js +26 -16
  76. package/lib/data.d.ts +1 -1
  77. package/lib/data.js +3 -2
  78. package/lib/desk.js +45 -33
  79. package/lib/door.js +35 -10
  80. package/lib/environment.js +25 -19
  81. package/lib/files.js +43 -34
  82. package/lib/find.js +12 -9
  83. package/lib/foot.js +7 -4
  84. package/lib/forge.js +61 -40
  85. package/lib/gear.d.ts +2 -1
  86. package/lib/gear.js +6 -4
  87. package/lib/git.js +29 -19
  88. package/lib/host.d.ts +3 -1
  89. package/lib/landing.d.ts +5 -5
  90. package/lib/landing.js +52 -44
  91. package/lib/library.js +73 -51
  92. package/lib/meter.d.ts +1 -1
  93. package/lib/meter.js +14 -5
  94. package/lib/mic.js +12 -5
  95. package/lib/mind.d.ts +1 -0
  96. package/lib/mind.js +5 -3
  97. package/lib/nav.d.ts +6 -5
  98. package/lib/nav.js +37 -30
  99. package/lib/panel.d.ts +2 -1
  100. package/lib/panel.js +52 -36
  101. package/lib/plan.d.ts +4 -20
  102. package/lib/plan.js +26 -10
  103. package/lib/plans.js +49 -30
  104. package/lib/plugins/design.js +3 -2
  105. package/lib/plugins/index.d.ts +23 -4
  106. package/lib/plugins/index.js +11 -26
  107. package/lib/plugins/pdf.js +2 -1
  108. package/lib/plugins/project.js +6 -3
  109. package/lib/plugins/research.js +3 -2
  110. package/lib/plugins/sketch.js +6 -3
  111. package/lib/plugins/slides.js +3 -2
  112. package/lib/plugins/template.js +6 -3
  113. package/lib/plus.js +25 -13
  114. package/lib/prefs.d.ts +0 -14
  115. package/lib/prefs.js +2 -1
  116. package/lib/project.js +69 -62
  117. package/lib/prompt.d.ts +12 -11
  118. package/lib/prompt.js +38 -20
  119. package/lib/publish.js +17 -12
  120. package/lib/reply.js +6 -3
  121. package/lib/run.js +72 -54
  122. package/lib/say.d.ts +2 -0
  123. package/lib/say.js +7 -0
  124. package/lib/scheduled.js +54 -43
  125. package/lib/section.d.ts +1 -0
  126. package/lib/section.js +8 -2
  127. package/lib/settings/account.d.ts +1 -0
  128. package/lib/settings/account.js +31 -21
  129. package/lib/settings/billing.js +55 -28
  130. package/lib/settings/capabilities.js +26 -15
  131. package/lib/settings/card.js +19 -12
  132. package/lib/settings/code.js +22 -11
  133. package/lib/settings/credits.d.ts +4 -4
  134. package/lib/settings/credits.js +34 -21
  135. package/lib/settings/environments.js +21 -14
  136. package/lib/settings/general.js +26 -14
  137. package/lib/settings/index.js +6 -3
  138. package/lib/settings/integrations.js +42 -28
  139. package/lib/settings/keys.js +37 -19
  140. package/lib/settings/list.d.ts +0 -5
  141. package/lib/settings/list.js +24 -15
  142. package/lib/settings/machines.d.ts +3 -0
  143. package/lib/settings/machines.js +63 -38
  144. package/lib/settings/members.js +23 -14
  145. package/lib/settings/memory.js +12 -6
  146. package/lib/settings/notifications.js +32 -19
  147. package/lib/settings/plan.d.ts +1 -1
  148. package/lib/settings/plan.js +40 -17
  149. package/lib/settings/privacy.js +26 -13
  150. package/lib/settings/ui.d.ts +3 -2
  151. package/lib/settings/ui.js +9 -3
  152. package/lib/settings/usage.js +7 -3
  153. package/lib/shelf.js +18 -15
  154. package/lib/side.d.ts +1 -26
  155. package/lib/side.js +11 -5
  156. package/lib/standing.d.ts +2 -10
  157. package/lib/standing.js +5 -3
  158. package/lib/suggest.d.ts +8 -28
  159. package/lib/suggest.js +39 -4
  160. package/lib/suggestions.js +14 -5
  161. package/lib/summary.d.ts +1 -1
  162. package/lib/summary.js +4 -1
  163. package/lib/sync.js +22 -12
  164. package/lib/tools.d.ts +4 -3
  165. package/lib/tools.js +10 -7
  166. package/lib/transcript.js +10 -8
  167. package/package.json +4 -2
package/lib/tools.d.ts CHANGED
@@ -1,16 +1,17 @@
1
+ import { type Say } from '@hanzo/i18n/react';
1
2
  export interface Attached {
2
3
  name: string;
3
4
  text: string;
4
5
  }
5
6
  /** The ask with its attachments appended as fenced text. */
6
7
  export declare function compose(prompt: string, files: Attached[]): string;
7
- /** Read `list` into `have`, within the caps; answers the new list and what was refused. */
8
- export declare function read(have: Attached[], list: FileList): Promise<{
8
+ /** Read `list` into `have`, within the caps; answers the new list and what was refused, in the language of `t`. */
9
+ export declare function read(have: Attached[], list: FileList, t?: Say): Promise<{
9
10
  files: Attached[];
10
11
  note: string;
11
12
  }>;
12
13
  /** Ask the browser for files and read them in, within the caps; the picker is minted per press. */
13
- export declare function pick(have: Attached[], onFiles: (f: Attached[]) => void, onNote: (n: string) => void): void;
14
+ export declare function pick(have: Attached[], onFiles: (f: Attached[]) => void, onNote: (n: string) => void, t?: Say): void;
14
15
  /** The attached files as small removable marks. */
15
16
  export declare function Files({ files, onFiles }: {
16
17
  files: Attached[];
package/lib/tools.js CHANGED
@@ -5,8 +5,10 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
5
5
  * composer's (prompt.tsx); this reads what it picks and draws the chips.
6
6
  */
7
7
  import { SizableText, XStack } from '@hanzo/gui';
8
+ import { useI18n } from '@hanzo/i18n/react';
8
9
  import { Paperclip, X } from '@hanzogui/lucide-icons-2';
9
10
  import { ComposerTool } from '@hanzo/ui/chat';
11
+ import { english } from './say.js';
10
12
  const EACH = 100_000;
11
13
  const ALL = 200_000;
12
14
  /** The ask with its attachments appended as fenced text. */
@@ -15,19 +17,19 @@ export function compose(prompt, files) {
15
17
  return prompt;
16
18
  return prompt + files.map((f) => `\n\n\`${f.name}\`:\n\`\`\`\n${f.text}\n\`\`\``).join('');
17
19
  }
18
- /** Read `list` into `have`, within the caps; answers the new list and what was refused. */
19
- export async function read(have, list) {
20
+ /** Read `list` into `have`, within the caps; answers the new list and what was refused, in the language of `t`. */
21
+ export async function read(have, list, t = english) {
20
22
  const files = [...have];
21
23
  let total = files.reduce((n, f) => n + f.text.length, 0);
22
24
  let note = '';
23
25
  for (const file of Array.from(list)) {
24
26
  if (file.size > EACH) {
25
- note = `${file.name} is over 100 KB; attach a smaller file or point the run at the repository.`;
27
+ note = t('{file} is over 100 KB; attach a smaller file or point the run at the repository.', { file: file.name });
26
28
  continue;
27
29
  }
28
30
  const text = await file.text();
29
31
  if (total + text.length > ALL) {
30
- note = 'Attachments are capped at 200 KB in all.';
32
+ note = t('Attachments are capped at 200 KB in all.');
31
33
  break;
32
34
  }
33
35
  total += text.length;
@@ -36,7 +38,7 @@ export async function read(have, list) {
36
38
  return { files, note };
37
39
  }
38
40
  /** Ask the browser for files and read them in, within the caps; the picker is minted per press. */
39
- export function pick(have, onFiles, onNote) {
41
+ export function pick(have, onFiles, onNote, t = english) {
40
42
  if (typeof document === 'undefined')
41
43
  return;
42
44
  const ask = document.createElement('input');
@@ -45,7 +47,7 @@ export function pick(have, onFiles, onNote) {
45
47
  ask.onchange = () => {
46
48
  if (!ask.files?.length)
47
49
  return;
48
- void read(have, ask.files).then(({ files, note }) => {
50
+ void read(have, ask.files, t).then(({ files, note }) => {
49
51
  onFiles(files);
50
52
  onNote(note);
51
53
  });
@@ -54,5 +56,6 @@ export function pick(have, onFiles, onNote) {
54
56
  }
55
57
  /** The attached files as small removable marks. */
56
58
  export function Files({ files, onFiles }) {
57
- return (_jsx(_Fragment, { children: files.map((f) => (_jsxs(XStack, { items: "center", gap: "$1", px: "$2", height: 24, rounded: "$2", bg: "$raised", children: [_jsx(Paperclip, { size: 12 }), _jsx(SizableText, { size: "$1", color: "$ink", numberOfLines: 1, maxW: 140, children: f.name }), _jsx(ComposerTool, { label: `Remove ${f.name}`, icon: _jsx(X, { size: 12 }), onPress: () => onFiles(files.filter((x) => x !== f)) })] }, f.name))) }));
59
+ const { t } = useI18n();
60
+ return (_jsx(_Fragment, { children: files.map((f) => (_jsxs(XStack, { items: "center", gap: "$1", px: "$2", height: 24, rounded: "$2", bg: "$raised", children: [_jsx(Paperclip, { size: 12 }), _jsx(SizableText, { size: "$1", color: "$ink", numberOfLines: 1, maxW: 140, children: f.name }), _jsx(ComposerTool, { label: t('Remove {name}', { name: f.name }), icon: _jsx(X, { size: 12 }), onPress: () => onFiles(files.filter((x) => x !== f)) })] }, f.name))) }));
58
61
  }
package/lib/transcript.js CHANGED
@@ -17,6 +17,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
17
  * commands, edits and steps — are cards of their own between the turns.
18
18
  */
19
19
  import { SizableText, XStack, YStack } from '@hanzo/gui';
20
+ import { useI18n } from '@hanzo/i18n/react';
20
21
  import { Button } from '@hanzo/ui';
21
22
  import { Feedback } from '@hanzo/ui/agents';
22
23
  import { Code, Message, Step, Thread } from '@hanzo/ui/chat';
@@ -31,11 +32,12 @@ const mono = { fontFamily: 'var(--f-mono, ui-monospace, monospace)' };
31
32
  /** What a thought is about: its first line, without the markdown that bolds it. */
32
33
  const firstLine = (text) => text.trim().split('\n')[0].replace(/[*_#`]/g, '').slice(0, 120);
33
34
  export function Transcript({ cards, live, empty, header, onApprove, approving = false, onVerdict, onOpen, onDiff, listen, end, }) {
35
+ const { t } = useI18n();
34
36
  // A card the run never finished is cut off once the run has ended, not still going.
35
37
  const state = (ran) => (ran === 'running' && !live ? 'cancelled' : ran);
36
38
  // The answer still arriving: the last thing the agent said while the run works.
37
39
  const last = live ? [...cards].reverse().find((c) => c.kind === 'said' && c.who === 'agent')?.key : undefined;
38
- return (_jsxs(Thread, { gap: GAP, column: { maxW: MEASURE }, "aria-label": "Transcript", children: [header, cards.length === 0 ? _jsx(YStack, { py: "$2", children: empty }) : null, cards.map((c) => {
40
+ return (_jsxs(Thread, { gap: GAP, column: { maxW: MEASURE }, "aria-label": t('Transcript'), children: [header, cards.length === 0 ? _jsx(YStack, { py: "$2", children: empty }) : null, cards.map((c) => {
39
41
  switch (c.kind) {
40
42
  case 'said': {
41
43
  if (c.who === 'person')
@@ -45,19 +47,19 @@ export function Transcript({ cards, live, empty, header, onApprove, approving =
45
47
  return (_jsx(Message, { role: "assistant", busy: c.key === last, children: _jsxs(YStack, { gap: "$1", children: [_jsx(Prose, { text: c.text }), c.key === last ? null : (_jsx(Reply, { text: c.text, listen: listen, onOpen: first && onOpen ? () => onOpen(first) : undefined, children: _jsx(Judge, { onVerdict: onVerdict }) }))] }) }, c.key));
46
48
  }
47
49
  case 'think':
48
- return (_jsx(Step, { name: "Thought", detail: firstLine(c.text), status: "done", "aria-label": "Thought", children: _jsx(Prose, { text: c.text }) }, c.key));
50
+ return (_jsx(Step, { name: t('Thought'), detail: firstLine(c.text), status: "done", "aria-label": t('Thought'), children: _jsx(Prose, { text: c.text }) }, c.key));
49
51
  case 'todo':
50
- return (_jsx(YStack, { gap: "$1", px: "$3", py: "$2", rounded: "$3", borderWidth: 1, borderColor: "$borderColor", "aria-label": "Plan checklist", children: c.items.map((x, i) => (_jsxs(XStack, { gap: "$2", items: "flex-start", children: [_jsx(SizableText, { size: "$2", color: x.done ? '$ink' : '$soft', children: x.done ? '✓' : '○' }), _jsx(SizableText, { flex: 1, size: "$2", color: x.done ? '$soft' : '$ink', children: x.text })] }, i))) }, c.key));
52
+ return (_jsx(YStack, { gap: "$1", px: "$3", py: "$2", rounded: "$3", borderWidth: 1, borderColor: "$borderColor", "aria-label": t('Plan checklist'), children: c.items.map((x, i) => (_jsxs(XStack, { gap: "$2", items: "flex-start", children: [_jsx(SizableText, { size: "$2", color: x.done ? '$ink' : '$soft', children: x.done ? '✓' : '○' }), _jsx(SizableText, { flex: 1, size: "$2", color: x.done ? '$soft' : '$ink', children: x.text })] }, i))) }, c.key));
51
53
  case 'shell':
52
- return (_jsx(Step, { name: "Shell", detail: c.command, status: state(c.ran), "aria-label": `Command ${c.command}`, children: _jsx(Code, { language: "shell", value: c.output ? `$ ${c.command}\n${c.output}` : `$ ${c.command}`, children: c.output ? `$ ${c.command}\n${tail(c.output)}` : `$ ${c.command}` }) }, c.key));
54
+ return (_jsx(Step, { name: t('Shell'), detail: c.command, status: state(c.ran), "aria-label": t('Command {command}', { command: c.command }), children: _jsx(Code, { language: "shell", value: c.output ? `$ ${c.command}\n${c.output}` : `$ ${c.command}`, children: c.output ? `$ ${c.command}\n${tail(c.output)}` : `$ ${c.command}` }) }, c.key));
53
55
  case 'edit':
54
- return (_jsx(Step, { name: c.files.length === 1 ? 'Edited' : c.files.length ? `Edited ${c.files.length} files` : 'Edited files', detail: c.files.join(', '), status: state(c.ran), "aria-label": `Edited ${c.files.join(', ') || 'files'}`, children: _jsxs(YStack, { gap: "$2", items: "flex-start", children: [_jsx(SizableText, { size: "$1", color: "$soft", style: { whiteSpace: 'pre-wrap' }, children: c.files.length ? c.files.join('\n') : 'The agent named no files.' }), onDiff ? (_jsx(Button, { size: "sm", variant: "outline", onPress: onDiff, children: "Open the diff" })) : null] }) }, c.key));
56
+ return (_jsx(Step, { name: c.files.length === 1 ? t('Edited') : c.files.length ? t('Edited {n} files', { n: c.files.length }) : t('Edited files'), detail: c.files.join(', '), status: state(c.ran), "aria-label": c.files.length ? t('Edited {files}', { files: c.files.join(', ') }) : t('Edited files'), children: _jsxs(YStack, { gap: "$2", items: "flex-start", children: [_jsx(SizableText, { size: "$1", color: "$soft", style: { whiteSpace: 'pre-wrap' }, children: c.files.length ? c.files.join('\n') : t('The agent named no files.') }), onDiff ? (_jsx(Button, { size: "sm", variant: "outline", onPress: onDiff, children: t('Open the diff') })) : null] }) }, c.key));
55
57
  case 'step':
56
- return (_jsx(Step, { name: c.name, detail: c.detail, status: state(c.ran), defaultOpen: c.name === 'Error', "aria-label": `${c.name} ${c.detail}`.trim(), children: c.name === 'Error' ? (_jsx(SizableText, { size: "$2", color: "$ink", style: { ...mono, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }, children: c.output })) : c.output.trim() ? (_jsx(Code, { language: "output", value: c.output, children: tail(c.output.replace(/\n+$/, '')) })) : undefined }, c.key));
58
+ return (_jsx(Step, { name: t(c.name), detail: c.detail, status: state(c.ran), defaultOpen: c.name === 'Error', "aria-label": `${t(c.name)} ${c.detail}`.trim(), children: c.name === 'Error' ? (_jsx(SizableText, { size: "$2", color: "$ink", style: { ...mono, whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' }, children: c.output })) : c.output.trim() ? (_jsx(Code, { language: "output", value: c.output, children: tail(c.output.replace(/\n+$/, '')) })) : undefined }, c.key));
57
59
  case 'note':
58
- return (_jsx(SizableText, { size: "$1", color: "$soft", role: "note", children: c.text }, c.key));
60
+ return (_jsx(SizableText, { size: "$1", color: "$soft", role: "note", children: t(c.text) }, c.key));
59
61
  case 'plan':
60
- return (_jsxs(YStack, { gap: "$3", p: "$4", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", "aria-label": "Plan", children: [_jsx(SizableText, { size: "$2", color: "$soft", children: "Plan" }), _jsx(Prose, { text: c.text }), _jsxs(XStack, { items: "center", gap: "$2", flexWrap: "wrap", children: [_jsx(Reply, { text: c.text, listen: listen }), onApprove ? (_jsx(Button, { size: "sm", disabled: approving, onPress: () => onApprove(c.text), children: approving ? 'Starting the build…' : 'Approve and build' })) : null, _jsx(Judge, { onVerdict: onVerdict })] })] }, c.key));
62
+ return (_jsxs(YStack, { gap: "$3", p: "$4", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", "aria-label": t('Plan'), children: [_jsx(SizableText, { size: "$2", color: "$soft", children: t('Plan') }), _jsx(Prose, { text: c.text }), _jsxs(XStack, { items: "center", gap: "$2", flexWrap: "wrap", children: [_jsx(Reply, { text: c.text, listen: listen }), onApprove ? (_jsx(Button, { size: "sm", disabled: approving, onPress: () => onApprove(c.text), children: approving ? t('Starting the build…') : t('Approve and build') })) : null, _jsx(Judge, { onVerdict: onVerdict })] })] }, c.key));
61
63
  }
62
64
  }), end] }));
63
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/build",
3
- "version": "0.2.79",
3
+ "version": "0.2.81",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "description": "Hanzo Build — say what you want, watch it built, deployed and running. The builder as a component, mounted by the Hanzo app at hanzo.ai.",
@@ -11,6 +11,7 @@
11
11
  "@hanzo/composer": "0.2.0",
12
12
  "@hanzo/font": "1.9.3",
13
13
  "@hanzo/gui": "8.3.5",
14
+ "@hanzo/i18n": "0.4.0",
14
15
  "@hanzo/iam": "0.21.28",
15
16
  "@hanzo/ui": "8.29.0",
16
17
  "@hanzo/vite": "0.1.4",
@@ -76,7 +77,8 @@
76
77
  "@hanzogui/lucide-icons-2": ">=8.3.5",
77
78
  "react": ">=19.2.8",
78
79
  "@hanzo/voice": ">=0.1.19",
79
- "@hanzo/composer": ">=0.2.0"
80
+ "@hanzo/composer": ">=0.2.0",
81
+ "@hanzo/i18n": ">=0.4.0"
80
82
  },
81
83
  "scripts": {
82
84
  "dev": "vite",