Files
zeekay 0f5536b707 hanzo.ai reads in the reader's language, and Arabic right to left
Every word the landing, the header menus, the phone sheet, the footer,
the help corner and the way in (sign-in, sign-up, the reset, the
invitation, the callback, onboarding, the 404) write goes through
@hanzo/i18n's t(): one sentence is one message, its figures, names and
links arguments; copy written as data is phrase('…') where written and
t(label) where drawn. Plans, the chart, the API states and the lines
lib/kai and lib/enso build for the landing do the same.

Right to left: <html lang dir> is set before the first paint (the
package's bootScript first in the head); a figure, clock, range or
price outside a sentence is isolated; sides are logical gui props, the
layout's [data-join] corners logical, a bar grows from the start;
arrows along the line mirror (Onward for "words ->" links). The repo
dates read in the reader's language.

Gates select by slot, never by an English label (rtl, help). New gate
translated.spec.ts: in Arabic the landing at 1440 and 390, every menu
open, the phone sheet, sign-in, sign-up and the app signed in hold no
authored English, nothing scrolls sideways, every range is isolated;
French the same for English's commonest words. What another package
draws with no words prop is listed by name (@hanzo/ui's Footer label,
@hanzo/build's composer row and suggestions).

@hanzo/i18n 0.5.3 (the catalogs: 1,443 keys, every offered locale
complete), @hanzo/app 0.2.1 (the app's words). The link gate imports
the terms versions from @hanzo/app, the one SDK main now resolves.
2026-10-22 19:54:31 -07:00

116 lines
5.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { phrase } from '@hanzo/i18n'
/**
* WHAT A READER IS INVITED TO START, said once.
*
* Both composers on the apex draw from here — the one in the fold and the one
* that follows the page down — because they had a copy each and the copies had
* already drifted apart. A prompt is a promise about what this place is for, so
* two lists is two answers to the same question.
*
* EACH ONE IS A COMPANY, not a clever sentence about AI. The templates a new
* workspace can actually fork are small businesses with a crew — an automation
* agency with a sales agent and a client manager, a clipping channel with a
* clipper and a channel manager, a newsletter whose researcher, writer and
* growth agent hand off to a publisher — so these read in that register: who is
* on the crew, what they touch, and what waits for a person. A reader who
* presses enter on one of these should land somewhere that looks like it.
*
* THE APPROVAL IS PART OF THE PITCH, not a caveat bolted on. Several of these
* say plainly that nothing goes out until somebody says so, because the fear a
* founder brings to this page is an agent acting in their name — and answering
* it in the prompt is more convincing than a paragraph about it further down.
*/
/**
* What a reader's own coding agent is told, said once. Every copy control on
* the page puts THIS on the clipboard — the fold's Copy setup prompt, each
* "Open in" row under it, and the agent row's button — so the three cannot
* drift into three different instructions. It stays English on every page:
* it is an instruction for a coding agent, not copy a reader reads.
*
* `/skill.md` is the manual it points at, and every command here was run
* against the CLI hanzo.sh installs (8.5.732) before it was written down:
*
* `hanzo login` is a registered alias of `hanzo auth login`, which is the
* spelling /skill.md uses — one implementation, two names, and this is the
* one a person types.
* `hanzo template list` answers with the public starter catalog, the same
* catalog /templates reads (GET /v1/templates).
* `hanzo template get <slug>` answers with one kit, and its `source` is the
* repository to clone. `hanzo init --template <slug>` is NOT that: it
* accepts any string, validates nothing and writes a README and a
* .gitignore, so an agent told to clone with it would report success over
* an empty directory.
* `hanzo dev` starts a coding session in the directory it is run from: Hanzo's
* own agent, its model calls routed through api.hanzo.ai and metered to the
* reader's org once signed in. It wants a terminal (run by an agent it
* prints `stdin is not a terminal`), so the agent hands that step to the
* reader. `hanzo up` boots a local Kubernetes in a microVM, which no new
* project needs, so it is not a step here.
*
* /skill.md covers the credential, the API and the MCP server and says nothing
* about starters or the coding session, so for those two the CLI is the
* authority and this prompt follows it.
*/
export const SETUP = [
'Read https://hanzo.ai/skill.md and follow it to set up a Hanzo company in my project:',
'register or sign in with `hanzo login`, pick a starter with `hanzo template list`,',
'clone the repository `hanzo template get <slug>` names in its `source`, then tell me to run `hanzo dev` in it to start building.',
'Check you are in the project directory first — if not, ask me where it is.',
].join(' ')
/** The line that cycles in an empty field.
*
* SHORT ENOUGH TO FINISH. The field is about 500px, which is roughly 55
* characters; a longer line is cut off mid-word and an invitation that does not
* reach its own verb is worse than no invitation. Each of these names the
* company and one thing about how it runs, and stops. A field's hint, so each
* is authored copy (`phrase`): the composer draws it with `t()`. */
export const PROMPTS = [
phrase('Start an automation agency with a workspace per client…'),
phrase('Launch an SEO agency that ranks clients in AI answers…'),
phrase('Open a store whose agents write every listing…'),
phrase('Run a clipping channel: long-form in, shorts out…'),
phrase('Build a CRM with an agent working the pipeline…'),
phrase('Start a newsletter that never sends unapproved…'),
]
/**
* A named starter, for a reader who would rather press than type. The `label`
* is authored copy (`phrase`), drawn with `t()`; the `prompt` is what is sent to
* the agent, and stays as written.
*/
export const CHIPS: { label: string; prompt: string }[] = [
{
label: phrase('Automation agency'),
prompt:
'Start an AI automation agency: a CRM, a public site, and a workspace for each client, with a sales agent and a client manager working the pipeline through Gmail, GitHub and Vercel',
},
{
label: phrase('SEO agency'),
prompt:
'Launch an SEO agency that ranks clients in search and in AI answers, with a sales agent and a client manager reading Search Console and reporting by email every Monday',
},
{
label: phrase('Ecommerce store'),
prompt:
'Open an ecommerce store: a catalog, a checkout, and agents that write the listings, watch the stock and answer buyers before you are awake',
},
{
label: phrase('CRM'),
prompt:
'Build a CRM for my business: contacts, deals, and an agent that works the pipeline every morning and drafts the follow-ups for me to send',
},
{
label: phrase('Clipping channel'),
prompt:
'Run a clipping channel: a clipper cuts long-form into shorts and a channel manager posts them to TikTok, YouTube and Instagram on a schedule',
},
{
label: phrase('Recruiting desk'),
prompt:
'Open a recruiting desk: a sourcer finds candidates, a screener runs the first call, and an account manager books the shortlist onto the hiring manager’s calendar',
},
]