@hanzo/build 0.2.80 → 0.2.82
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/README.md +13 -0
- package/lib/activity.d.ts +3 -7
- package/lib/activity.js +18 -5
- package/lib/api/agents.d.ts +1 -20
- package/lib/api/agents.js +16 -8
- package/lib/api/auto.d.ts +3 -23
- package/lib/api/auto.js +39 -22
- package/lib/api/billing.d.ts +0 -35
- package/lib/api/billing.js +6 -5
- package/lib/api/call.d.ts +16 -8
- package/lib/api/call.js +32 -1
- package/lib/api/capabilities.d.ts +0 -11
- package/lib/api/capabilities.js +2 -1
- package/lib/api/codebases.d.ts +0 -10
- package/lib/api/codebases.js +3 -2
- package/lib/api/coding.d.ts +3 -32
- package/lib/api/coding.js +13 -7
- package/lib/api/connectors.d.ts +1 -17
- package/lib/api/connectors.js +5 -4
- package/lib/api/environment.d.ts +6 -20
- package/lib/api/environment.js +22 -19
- package/lib/api/github.d.ts +0 -22
- package/lib/api/github.js +3 -2
- package/lib/api/keys.d.ts +0 -14
- package/lib/api/keys.js +4 -3
- package/lib/api/library.d.ts +3 -17
- package/lib/api/library.js +23 -22
- package/lib/api/links.d.ts +1 -1
- package/lib/api/links.js +1 -1
- package/lib/api/machines.d.ts +0 -15
- package/lib/api/machines.js +6 -5
- package/lib/api/mcp.d.ts +0 -9
- package/lib/api/mcp.js +3 -2
- package/lib/api/members.d.ts +0 -15
- package/lib/api/members.js +4 -3
- package/lib/api/memory.d.ts +0 -11
- package/lib/api/memory.js +2 -1
- package/lib/api/places.d.ts +1 -9
- package/lib/api/places.js +12 -1
- package/lib/api/plugins.d.ts +1 -16
- package/lib/api/plugins.js +4 -3
- package/lib/api/profile.d.ts +0 -10
- package/lib/api/profile.js +5 -4
- package/lib/api/projects.d.ts +0 -14
- package/lib/api/projects.js +11 -10
- package/lib/api/provider.d.ts +2 -14
- package/lib/api/provider.js +12 -10
- package/lib/api/sandbox.d.ts +0 -17
- package/lib/api/sandbox.js +5 -4
- package/lib/api/sessions.d.ts +0 -17
- package/lib/api/sessions.js +5 -4
- package/lib/api/skills.d.ts +1 -15
- package/lib/api/skills.js +5 -4
- package/lib/api/studio.d.ts +0 -14
- package/lib/api/studio.js +6 -5
- package/lib/api/turn.d.ts +6 -28
- package/lib/api/turn.js +105 -49
- package/lib/api/verdict.d.ts +0 -9
- package/lib/api/verdict.js +2 -1
- package/lib/api/webhooks.d.ts +1 -14
- package/lib/api/webhooks.js +5 -4
- package/lib/ask.js +7 -4
- package/lib/automations.d.ts +5 -4
- package/lib/automations.js +95 -74
- package/lib/back.js +10 -4
- package/lib/builder.js +7 -5
- package/lib/carry.js +20 -16
- package/lib/customize/agents.js +78 -31
- package/lib/customize/connectors.js +62 -48
- package/lib/customize/index.js +43 -10
- package/lib/customize/plugins.js +34 -22
- package/lib/customize/say.d.ts +13 -1
- package/lib/customize/say.js +15 -21
- package/lib/customize/skills.js +31 -22
- package/lib/customize/ui.d.ts +5 -9
- package/lib/customize/ui.js +26 -16
- package/lib/data.d.ts +1 -1
- package/lib/data.js +3 -2
- package/lib/desk.js +45 -33
- package/lib/door.js +35 -10
- package/lib/environment.js +25 -19
- package/lib/files.js +43 -34
- package/lib/find.js +12 -9
- package/lib/foot.js +7 -4
- package/lib/forge.js +61 -40
- package/lib/gear.d.ts +2 -1
- package/lib/gear.js +6 -4
- package/lib/git.js +29 -19
- package/lib/landing.d.ts +5 -5
- package/lib/landing.js +52 -44
- package/lib/library.js +73 -51
- package/lib/merge.d.ts +2 -2
- package/lib/meter.d.ts +1 -1
- package/lib/meter.js +14 -5
- package/lib/mic.js +12 -5
- package/lib/mind.d.ts +1 -0
- package/lib/mind.js +5 -3
- package/lib/nav.d.ts +6 -5
- package/lib/nav.js +37 -30
- package/lib/panel.d.ts +2 -1
- package/lib/panel.js +52 -36
- package/lib/plan.d.ts +4 -20
- package/lib/plan.js +26 -10
- package/lib/plans.js +49 -30
- package/lib/plugins/design.js +3 -2
- package/lib/plugins/index.d.ts +23 -4
- package/lib/plugins/index.js +11 -26
- package/lib/plugins/pdf.js +2 -1
- package/lib/plugins/project.js +7 -4
- package/lib/plugins/research.js +3 -2
- package/lib/plugins/sketch.js +6 -3
- package/lib/plugins/slides.js +3 -2
- package/lib/plugins/template.js +6 -3
- package/lib/plus.js +25 -13
- package/lib/prefs.d.ts +0 -14
- package/lib/prefs.js +2 -1
- package/lib/project.js +69 -62
- package/lib/prompt.d.ts +12 -11
- package/lib/prompt.js +38 -20
- package/lib/publish.js +17 -12
- package/lib/reply.js +6 -3
- package/lib/run.js +72 -54
- package/lib/say.d.ts +2 -0
- package/lib/say.js +7 -0
- package/lib/scheduled.js +54 -43
- package/lib/section.d.ts +1 -0
- package/lib/section.js +8 -2
- package/lib/settings/account.d.ts +1 -0
- package/lib/settings/account.js +31 -21
- package/lib/settings/billing.js +55 -28
- package/lib/settings/capabilities.js +26 -15
- package/lib/settings/card.js +19 -12
- package/lib/settings/code.js +22 -11
- package/lib/settings/credits.d.ts +4 -4
- package/lib/settings/credits.js +34 -21
- package/lib/settings/environments.js +21 -14
- package/lib/settings/general.js +26 -14
- package/lib/settings/index.js +6 -3
- package/lib/settings/integrations.js +42 -28
- package/lib/settings/keys.js +37 -19
- package/lib/settings/list.d.ts +0 -5
- package/lib/settings/list.js +24 -15
- package/lib/settings/machines.d.ts +3 -0
- package/lib/settings/machines.js +63 -38
- package/lib/settings/members.js +23 -14
- package/lib/settings/memory.js +12 -6
- package/lib/settings/notifications.js +32 -19
- package/lib/settings/plan.d.ts +1 -1
- package/lib/settings/plan.js +40 -17
- package/lib/settings/privacy.js +26 -13
- package/lib/settings/ui.d.ts +3 -2
- package/lib/settings/ui.js +9 -3
- package/lib/settings/usage.js +7 -3
- package/lib/shelf.js +20 -17
- package/lib/side.d.ts +1 -26
- package/lib/side.js +11 -5
- package/lib/standing.d.ts +2 -10
- package/lib/standing.js +5 -3
- package/lib/suggest.d.ts +8 -28
- package/lib/suggest.js +39 -4
- package/lib/suggestions.js +14 -5
- package/lib/summary.d.ts +1 -1
- package/lib/summary.js +4 -1
- package/lib/sync.js +22 -12
- package/lib/tools.d.ts +4 -3
- package/lib/tools.js +10 -7
- package/lib/transcript.js +10 -8
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -100,6 +100,19 @@ nothing behind a More; `useSessions(host)` is the runs — the org's coding runs
|
|
|
100
100
|
kept live by the org's feed — for a host that draws the rows itself. `administers(token, org)` reads the org-admin bit off a
|
|
101
101
|
hanzo.id token for `Host.admin`. One left column, never two.
|
|
102
102
|
|
|
103
|
+
## Words
|
|
104
|
+
|
|
105
|
+
Every word the builder authors is said through @hanzo/i18n, a required peer
|
|
106
|
+
(`>=0.4.0`): the host's `I18nProvider` is the one asked, and without one the
|
|
107
|
+
builder reads in English, unchanged. A component asks `useI18n()`; copy held as
|
|
108
|
+
data is `phrase()` where it is written and drawn through `t`; a helper outside a
|
|
109
|
+
render (`nav()`, `own()`, `tabs()`, `library()`, turn.ts, the plan sentences)
|
|
110
|
+
takes the caller's `t` last and falls back to `say.ts`'s `english`. Names, model
|
|
111
|
+
ids, what a person typed, what the platform said and figures are drawn as given;
|
|
112
|
+
prompts sent to a model stay in English. `src/e2e/language*.spec.ts` and
|
|
113
|
+
`translated.spec.ts` hold the composer, Projects, Skills and the Library in
|
|
114
|
+
French and right to left in Arabic.
|
|
115
|
+
|
|
103
116
|
## The model, the composer, the panel
|
|
104
117
|
|
|
105
118
|
One of each, shared with Chat (@hanzo/rooms imports them):
|
package/lib/activity.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Activity's words: what a run's state is called and drawn as, how long it
|
|
3
|
-
* took, what it cost, and the one line under its title. Pure, so the screen and
|
|
4
|
-
* its tests read the same sentences.
|
|
5
|
-
*/
|
|
1
|
+
import type { Say } from '@hanzo/i18n/react';
|
|
6
2
|
import type { SessionStatus } from '@hanzo/ui/chat';
|
|
7
3
|
import type { Job, State } from './api/auto.ts';
|
|
8
4
|
/** A job's state as the rail's dot draws it, and in words. */
|
|
@@ -12,8 +8,8 @@ export declare const SAID: Record<State, string>;
|
|
|
12
8
|
export declare function lasted(started: string, finished: string | null, now?: number): string;
|
|
13
9
|
/** Cents as dollars. */
|
|
14
10
|
export declare const dollars: (cents: number) => string;
|
|
15
|
-
/** One line about a job: when it started, how long, what it cost, what it made. */
|
|
16
|
-
export declare function about(j: Job, now?: number): string;
|
|
11
|
+
/** One line about a job: when it started, how long, what it cost, what it made. Its words in the language of `t`. */
|
|
12
|
+
export declare function about(j: Job, now?: number, t?: Say): string;
|
|
17
13
|
/** The jobs, newest first, with `j` in its place. */
|
|
18
14
|
export declare function merged(list: Job[], j: Job): Job[];
|
|
19
15
|
/** A task's name from what it does: its first line, short. */
|
package/lib/activity.js
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity's words: what a run's state is called and drawn as, how long it
|
|
3
|
+
* took, what it cost, and the one line under its title. Pure, so the screen and
|
|
4
|
+
* its tests read the same sentences.
|
|
5
|
+
*/
|
|
6
|
+
import { phrase } from '@hanzo/i18n';
|
|
1
7
|
import { ago } from './ago.js';
|
|
2
8
|
import { SOURCE } from './api/library.js';
|
|
9
|
+
import { english } from './say.js';
|
|
3
10
|
/** A job's state as the rail's dot draws it, and in words. */
|
|
4
11
|
export const DOTS = { scheduled: 'idle', running: 'running', succeeded: 'done', failed: 'error', cancelled: 'stopped' };
|
|
5
|
-
export const SAID = {
|
|
12
|
+
export const SAID = {
|
|
13
|
+
scheduled: phrase('Scheduled'),
|
|
14
|
+
running: phrase('Running'),
|
|
15
|
+
succeeded: phrase('Succeeded'),
|
|
16
|
+
failed: phrase('Failed'),
|
|
17
|
+
cancelled: phrase('Cancelled'),
|
|
18
|
+
};
|
|
6
19
|
/** How long a run took, or has taken so far. */
|
|
7
20
|
export function lasted(started, finished, now = Date.now()) {
|
|
8
21
|
const a = Date.parse(started);
|
|
@@ -20,10 +33,10 @@ export function lasted(started, finished, now = Date.now()) {
|
|
|
20
33
|
}
|
|
21
34
|
/** Cents as dollars. */
|
|
22
35
|
export const dollars = (cents) => `$${(cents / 100).toFixed(2)}`;
|
|
23
|
-
/** One line about a job: when it started, how long, what it cost, what it made. */
|
|
24
|
-
export function about(j, now = Date.now()) {
|
|
25
|
-
const made = j.outputs.length ?
|
|
26
|
-
return [SOURCE[j.product], j.started ? ago(j.started) : '', lasted(j.started, j.finished, now), j.cost !== null ? dollars(j.cost) : '', made].filter(Boolean).join(' · ');
|
|
36
|
+
/** One line about a job: when it started, how long, what it cost, what it made. Its words in the language of `t`. */
|
|
37
|
+
export function about(j, now = Date.now(), t = english) {
|
|
38
|
+
const made = j.outputs.length ? (j.outputs.length === 1 ? t('{n} output', { n: 1 }) : t('{n} outputs', { n: j.outputs.length })) : '';
|
|
39
|
+
return [SOURCE[j.product] ? t(SOURCE[j.product]) : '', j.started ? ago(j.started) : '', lasted(j.started, j.finished, now), j.cost !== null ? dollars(j.cost) : '', made].filter(Boolean).join(' · ');
|
|
27
40
|
}
|
|
28
41
|
/** The jobs, newest first, with `j` in its place. */
|
|
29
42
|
export function merged(list, j) {
|
package/lib/api/agents.d.ts
CHANGED
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agents: the org's own — a model, instructions, the tools it may call, a
|
|
3
|
-
* budget and a face — and the templates one is made from.
|
|
4
|
-
*
|
|
5
|
-
* GET /v1/agent {agents: [agent]}, without instructions
|
|
6
|
-
* POST /v1/agent create → 201 agent
|
|
7
|
-
* GET /v1/agent/{ref} one, with its instructions
|
|
8
|
-
* PATCH /v1/agent/{ref} the fields sent change, the rest stay → agent
|
|
9
|
-
* DELETE /v1/agent/{ref} removes it and every run recorded against it → 204
|
|
10
|
-
* GET /v1/agent/chat/presets {presets: [{id, title, systemPrompt, serverExecuted}]}
|
|
11
|
-
*
|
|
12
|
-
* A ref is the agent's id or its name. A budget is required: the most it may
|
|
13
|
-
* spend in a period and in one run, in micro-USD, and the period — day, week or
|
|
14
|
-
* month. Tools are names from the tool plane; none grants none, and `*` is
|
|
15
|
-
* whatever the fleet's MCP server serves when it runs. An omitted model is the
|
|
16
|
-
* deployment's default. A preset whose tool calls run on the platform
|
|
17
|
-
* (`serverExecuted`) makes a working agent; the others hand their calls back to
|
|
18
|
-
* the client that asked, so they are not offered here.
|
|
19
|
-
*/
|
|
20
1
|
import { type Target } from './call.ts';
|
|
21
2
|
export type Period = 'day' | 'week' | 'month';
|
|
22
3
|
export declare const PERIODS: readonly Period[];
|
|
@@ -69,7 +50,7 @@ export declare function agent(raw: unknown): Agent;
|
|
|
69
50
|
/** A draft of an agent as it stands, to edit. */
|
|
70
51
|
export declare function draft(a: Agent): Draft;
|
|
71
52
|
export declare const EMPTY: Draft;
|
|
72
|
-
/** Why a draft cannot be saved as it stands, or '' when it can
|
|
53
|
+
/** Why a draft cannot be saved as it stands, or '' when it can: English, marked (`phrase`), so a screen says it through `t`. */
|
|
73
54
|
export declare function refuse(d: Draft): string;
|
|
74
55
|
export declare function agents(t: Target): Promise<Agent[]>;
|
|
75
56
|
export declare function one(t: Target, ref: string): Promise<Agent>;
|
package/lib/api/agents.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* (`serverExecuted`) makes a working agent; the others hand their calls back to
|
|
18
18
|
* the client that asked, so they are not offered here.
|
|
19
19
|
*/
|
|
20
|
+
import { phrase } from '@hanzo/i18n';
|
|
20
21
|
import { call, seg } from './call.js';
|
|
21
22
|
export const PERIODS = ['day', 'week', 'month'];
|
|
22
23
|
/** An agent's name, as the handler takes it. */
|
|
@@ -66,20 +67,27 @@ export function draft(a) {
|
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
export const EMPTY = { name: '', description: '', model: '', instructions: '', tools: [], cap: '', task: '', period: 'month', avatar: '' };
|
|
69
|
-
/**
|
|
70
|
+
/** What a budget left unset says, and one run that outspends its period, by the period: whole sentences, so a language says the period its own way. */
|
|
71
|
+
const UNSET = { day: phrase('Set what it may spend each day'), week: phrase('Set what it may spend each week'), month: phrase('Set what it may spend each month') };
|
|
72
|
+
const OVER = {
|
|
73
|
+
day: phrase('One run cannot spend more than the whole day'),
|
|
74
|
+
week: phrase('One run cannot spend more than the whole week'),
|
|
75
|
+
month: phrase('One run cannot spend more than the whole month'),
|
|
76
|
+
};
|
|
77
|
+
/** Why a draft cannot be saved as it stands, or '' when it can: English, marked (`phrase`), so a screen says it through `t`. */
|
|
70
78
|
export function refuse(d) {
|
|
71
79
|
if (!NAME.test(d.name))
|
|
72
|
-
return 'A name is letters, digits, . _ or -, starting with a letter or digit';
|
|
80
|
+
return phrase('A name is letters, digits, . _ or -, starting with a letter or digit');
|
|
73
81
|
if (new TextEncoder().encode(d.instructions).length > MAX)
|
|
74
|
-
return 'Instructions are at most 32 KB';
|
|
82
|
+
return phrase('Instructions are at most 32 KB');
|
|
75
83
|
const cap = micros(d.cap);
|
|
76
84
|
const task = micros(d.task);
|
|
77
85
|
if (!(cap > 0))
|
|
78
|
-
return
|
|
86
|
+
return UNSET[d.period];
|
|
79
87
|
if (!(task > 0))
|
|
80
|
-
return 'Set what one run may spend';
|
|
88
|
+
return phrase('Set what one run may spend');
|
|
81
89
|
if (task > cap)
|
|
82
|
-
return
|
|
90
|
+
return OVER[d.period];
|
|
83
91
|
return '';
|
|
84
92
|
}
|
|
85
93
|
export async function agents(t) {
|
|
@@ -142,7 +150,7 @@ export async function use(t, c, base) {
|
|
|
142
150
|
export function person(name, about, writing, avatar = '') {
|
|
143
151
|
const who = name.trim();
|
|
144
152
|
const lines = [`You are ${who}.`, about.trim(), writing.trim() && `Writing by ${who}:\n\n${writing.trim()}`];
|
|
145
|
-
return { name: who, title: who, description: about.trim(), category: 'Person', model: '', instructions: lines.filter(Boolean).join('\n\n'), avatar };
|
|
153
|
+
return { name: who, title: who, description: about.trim(), category: phrase('Person'), model: '', instructions: lines.filter(Boolean).join('\n\n'), avatar };
|
|
146
154
|
}
|
|
147
155
|
export async function create(t, d) {
|
|
148
156
|
const why = refuse(d);
|
|
@@ -204,5 +212,5 @@ export async function presets(t) {
|
|
|
204
212
|
}
|
|
205
213
|
/** A preset as a template. */
|
|
206
214
|
export function fromPreset(p) {
|
|
207
|
-
return { name: p.id, title: p.title || p.id, description: p.title, category: 'Preset', model: '', instructions: p.prompt };
|
|
215
|
+
return { name: p.id, title: p.title || p.id, description: p.title, category: phrase('Preset'), model: '', instructions: p.prompt };
|
|
208
216
|
}
|
package/lib/api/auto.d.ts
CHANGED
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Automations: a task that runs itself, on a schedule or when asked.
|
|
3
|
-
*
|
|
4
|
-
* GET /v1/auto/automations {data: [automation]}
|
|
5
|
-
* POST /v1/auto/automations create one: name and instructions
|
|
6
|
-
* GET /v1/auto/automations/{id} one
|
|
7
|
-
* PATCH /v1/auto/automations/{id} change it, or switch it on or off
|
|
8
|
-
* DELETE /v1/auto/automations/{id} delete it, its schedule and its runs
|
|
9
|
-
* POST /v1/auto/automations/{id}/run {run: {id, status}} one run, now
|
|
10
|
-
* GET /v1/auto/automations/{id}/runs {data: [run]} newest first
|
|
11
|
-
* POST /v1/auto/automations/{id}/runs/{run}/review {post} post a held post, or discard it
|
|
12
|
-
* GET /v1/auto/templates {data: [starter]} to start a new one from
|
|
13
|
-
* POST /v1/auto/cron {schedule, says, next} a schedule from a person's words
|
|
14
|
-
* GET /v1/auto/jobs {data: [job]} what runs without you, across products
|
|
15
|
-
* GET /v1/auto/jobs/{id} one job
|
|
16
|
-
* GET /v1/auto/events text/event-stream: `job` and `automation`, the reader's own
|
|
17
|
-
*
|
|
18
|
-
* Each run is one Dev run in this organization, started as the person who last
|
|
19
|
-
* saved what it does. A draft is a flow named and not yet told what to do: it
|
|
20
|
-
* runs once its instructions are saved.
|
|
21
|
-
*/
|
|
1
|
+
import type { Say } from '@hanzo/i18n/react';
|
|
22
2
|
import { type Target } from './call.ts';
|
|
23
3
|
import { type Source } from './library.ts';
|
|
24
4
|
export type { Source };
|
|
@@ -107,8 +87,8 @@ export declare function start(t: Target, id: string): Promise<{
|
|
|
107
87
|
export declare function runs(t: Target, id: string): Promise<Run[]>;
|
|
108
88
|
/** Post a held post to the automation's accounts, or discard it. */
|
|
109
89
|
export declare function review(t: Target, id: string, runId: string, post: boolean): Promise<Run>;
|
|
110
|
-
/** A schedule the way a person says it. */
|
|
111
|
-
export declare function words(s: Schedule): string;
|
|
90
|
+
/** A schedule the way a person says it, in the words of the `t` handed (English without one). */
|
|
91
|
+
export declare function words(s: Schedule, t?: Say): string;
|
|
112
92
|
/** A ready-made automation to start a new one from. Its schedule names no zone: the page fills in the person's. */
|
|
113
93
|
export interface Starter {
|
|
114
94
|
key: string;
|
package/lib/api/auto.js
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* saved what it does. A draft is a flow named and not yet told what to do: it
|
|
20
20
|
* runs once its instructions are saved.
|
|
21
21
|
*/
|
|
22
|
+
import { phrase } from '@hanzo/i18n';
|
|
23
|
+
import { english } from '../say.js';
|
|
22
24
|
import { call, headers, query, reason, Refusal, seg } from './call.js';
|
|
23
25
|
import { inApp } from './library.js';
|
|
24
26
|
import { read as stream } from './sse.js';
|
|
@@ -78,13 +80,13 @@ export async function automations(t) {
|
|
|
78
80
|
export async function automation(t, id) {
|
|
79
81
|
const a = read(await call(t, 'GET', `/v1/auto/automations/${seg(id)}`));
|
|
80
82
|
if (!a)
|
|
81
|
-
throw new Error('The automation came back without an id');
|
|
83
|
+
throw new Error(phrase('The automation came back without an id'));
|
|
82
84
|
return a;
|
|
83
85
|
}
|
|
84
86
|
export async function create(t, d) {
|
|
85
87
|
const a = read(await call(t, 'POST', '/v1/auto/automations', d));
|
|
86
88
|
if (!a)
|
|
87
|
-
throw new Error('The automation was created and came back without an id');
|
|
89
|
+
throw new Error(phrase('The automation was created and came back without an id'));
|
|
88
90
|
return a;
|
|
89
91
|
}
|
|
90
92
|
/** What changed between two drafts, field by field: what a save sends. */
|
|
@@ -100,7 +102,7 @@ export function changes(was, now) {
|
|
|
100
102
|
export async function save(t, id, change) {
|
|
101
103
|
const a = read(await call(t, 'PATCH', `/v1/auto/automations/${seg(id)}`, change));
|
|
102
104
|
if (!a)
|
|
103
|
-
throw new Error('The automation was saved and came back without an id');
|
|
105
|
+
throw new Error(phrase('The automation was saved and came back without an id'));
|
|
104
106
|
return a;
|
|
105
107
|
}
|
|
106
108
|
export async function remove(t, id) {
|
|
@@ -130,40 +132,55 @@ function run(o) {
|
|
|
130
132
|
export async function review(t, id, runId, post) {
|
|
131
133
|
return run(obj(await call(t, 'POST', `/v1/auto/automations/${seg(id)}/runs/${seg(runId)}/review`, { post })));
|
|
132
134
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
/** A weekly schedule's sentence by its day: one sentence each, so a language says the day its own way. */
|
|
136
|
+
const DAYS = {
|
|
137
|
+
mon: phrase('Mondays at {time} · {zone}'),
|
|
138
|
+
tue: phrase('Tuesdays at {time} · {zone}'),
|
|
139
|
+
wed: phrase('Wednesdays at {time} · {zone}'),
|
|
140
|
+
thu: phrase('Thursdays at {time} · {zone}'),
|
|
141
|
+
fri: phrase('Fridays at {time} · {zone}'),
|
|
142
|
+
sat: phrase('Saturdays at {time} · {zone}'),
|
|
143
|
+
sun: phrase('Sundays at {time} · {zone}'),
|
|
144
|
+
};
|
|
145
|
+
/** A once schedule's local date, as a person reads it, and its time. */
|
|
135
146
|
function once(at) {
|
|
136
147
|
const m = at.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/);
|
|
137
148
|
if (!m)
|
|
138
|
-
return
|
|
149
|
+
return null;
|
|
139
150
|
const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5]));
|
|
140
|
-
return
|
|
151
|
+
return { date: d.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' }), time: `${m[4]}:${m[5]}` };
|
|
141
152
|
}
|
|
142
|
-
/** A schedule the way a person says it. */
|
|
143
|
-
export function words(s) {
|
|
144
|
-
const zone =
|
|
153
|
+
/** A schedule the way a person says it, in the words of the `t` handed (English without one). */
|
|
154
|
+
export function words(s, t = english) {
|
|
155
|
+
const zone = s.tz || 'UTC';
|
|
145
156
|
switch (s.kind) {
|
|
146
157
|
case 'manual':
|
|
147
|
-
return 'When you run it';
|
|
148
|
-
case 'once':
|
|
149
|
-
|
|
158
|
+
return t('When you run it');
|
|
159
|
+
case 'once': {
|
|
160
|
+
if (!s.at)
|
|
161
|
+
return t('Once, now');
|
|
162
|
+
const when = once(s.at);
|
|
163
|
+
return when ? t('Once, {date} at {time} · {zone}', { ...when, zone }) : t('Once, {at} · {zone}', { at: s.at, zone });
|
|
164
|
+
}
|
|
150
165
|
case 'hourly':
|
|
151
|
-
return
|
|
166
|
+
return t('Every hour at :{minute}', { minute: (s.at ?? '00:00').slice(3) || '00' });
|
|
152
167
|
case 'daily':
|
|
153
|
-
return
|
|
168
|
+
return t('Every day at {time} · {zone}', { time: s.at ?? '', zone });
|
|
154
169
|
case 'weekdays':
|
|
155
|
-
return
|
|
156
|
-
case 'weekly':
|
|
157
|
-
|
|
170
|
+
return t('Weekdays at {time} · {zone}', { time: s.at ?? '', zone });
|
|
171
|
+
case 'weekly': {
|
|
172
|
+
const day = DAYS[s.day ?? ''];
|
|
173
|
+
return day ? t(day, { time: s.at ?? '', zone }) : t('{day} at {time} · {zone}', { day: s.day ?? '', time: s.at ?? '', zone });
|
|
174
|
+
}
|
|
158
175
|
case 'cron': {
|
|
159
176
|
// The two a person says most, in their words; any other expression as written.
|
|
160
177
|
const minutes = (s.cron ?? '').match(/^\*\/(\d+) \* \* \* \*$/);
|
|
161
178
|
if (minutes)
|
|
162
|
-
return
|
|
179
|
+
return t('Every {n} minutes · {zone}', { n: minutes[1], zone });
|
|
163
180
|
const hours = (s.cron ?? '').match(/^0 \*\/(\d+) \* \* \*$/);
|
|
164
181
|
if (hours)
|
|
165
|
-
return
|
|
166
|
-
return
|
|
182
|
+
return t('Every {n} hours · {zone}', { n: hours[1], zone });
|
|
183
|
+
return t('Cron {cron} · {zone}', { cron: s.cron ?? '', zone });
|
|
167
184
|
}
|
|
168
185
|
}
|
|
169
186
|
}
|
|
@@ -241,7 +258,7 @@ export async function jobs(t, f = {}) {
|
|
|
241
258
|
export async function one(t, id) {
|
|
242
259
|
const j = job(await call(t, 'GET', `/v1/auto/jobs/${seg(id)}`));
|
|
243
260
|
if (!j)
|
|
244
|
-
throw new Error('The job came back without an id');
|
|
261
|
+
throw new Error(phrase('The job came back without an id'));
|
|
245
262
|
return j;
|
|
246
263
|
}
|
|
247
264
|
/** One frame of /v1/auto/events, or null for one this page does not read. */
|
package/lib/api/billing.d.ts
CHANGED
|
@@ -1,38 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The organization's money: its plan, the cards it pays with, its invoices, its
|
|
3
|
-
* balance and credits, what it has spent this month, and the caps on that spend.
|
|
4
|
-
*
|
|
5
|
-
* GET /v1/billing/plans the catalog the serving brand sells (public)
|
|
6
|
-
* GET /v1/billing/subscriptions {count, subscriptions}
|
|
7
|
-
* POST /v1/billing/subscribe/card buy a plan with a saved card; one paid plan at a time (409)
|
|
8
|
-
* POST /v1/billing/subscriptions/{id}/cancel at the end of the paid period
|
|
9
|
-
* POST /v1/billing/subscriptions/{id}/reactivate
|
|
10
|
-
* GET /v1/billing/methods saved cards, newest first
|
|
11
|
-
* POST /v1/billing/methods save a card from the processor's single-use token
|
|
12
|
-
* DELETE /v1/billing/methods/{id}
|
|
13
|
-
* GET /v1/billing/settings the processor a browser tokenizes a card against
|
|
14
|
-
* GET /v1/billing/invoices {count, cursor, invoices}
|
|
15
|
-
* GET /v1/billing/invoices/{id}/pdf the invoice as a PDF
|
|
16
|
-
* GET /v1/billing/balance prepaid balance, whole cents
|
|
17
|
-
* GET /v1/billing/credit-balance granted credit, per currency
|
|
18
|
-
* GET /v1/billing/credits {grants}: every grant, spent and lapsed included
|
|
19
|
-
* GET /v1/billing/tier the rung served and its tier class
|
|
20
|
-
* GET /v1/billing/recharge the auto-reload rule
|
|
21
|
-
* PUT /v1/billing/recharge arm it (a card on file) or disarm it
|
|
22
|
-
* POST /v1/billing/topup charge a saved card into the balance
|
|
23
|
-
* GET /v1/billing/usage/rollup the plan's month: included spend and request windows
|
|
24
|
-
* GET /v1/usage/summary?range=month this month's spend, by category
|
|
25
|
-
* GET /v1/allowance the Free plan's allowance, and the pool it is served from
|
|
26
|
-
* GET /v1/billing/alerts spend caps (bare array)
|
|
27
|
-
* POST /v1/billing/alerts open a cap (org admin)
|
|
28
|
-
* PATCH /v1/billing/alerts/{id} change one (org admin)
|
|
29
|
-
* DELETE /v1/billing/alerts/{id} lift one (org admin)
|
|
30
|
-
*
|
|
31
|
-
* Every figure is whole cents. The wallet, the caps and the cards are the
|
|
32
|
-
* caller's own, resolved by the platform from the credential; nothing here names
|
|
33
|
-
* an org or a subject. No card number passes through this file: a card is saved
|
|
34
|
-
* from the token the processor's own form returns.
|
|
35
|
-
*/
|
|
36
1
|
import { type Target } from './call.ts';
|
|
37
2
|
/** `$1,234.56` from whole cents; whole dollars drop the cents. */
|
|
38
3
|
export declare function money(cents: number, currency?: string): string;
|
package/lib/api/billing.js
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* an org or a subject. No card number passes through this file: a card is saved
|
|
34
34
|
* from the token the processor's own form returns.
|
|
35
35
|
*/
|
|
36
|
+
import { phrase } from '@hanzo/i18n';
|
|
36
37
|
import { call, headers, reason, Refusal, seg } from './call.js';
|
|
37
38
|
const str = (v) => (typeof v === 'string' ? v : '');
|
|
38
39
|
const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0);
|
|
@@ -115,7 +116,7 @@ export async function subscriptions(t) {
|
|
|
115
116
|
/** Buy a plan. No amount is sent: the catalog prices it, and the platform charges that. */
|
|
116
117
|
export async function subscribe(t, p) {
|
|
117
118
|
if (!p.method)
|
|
118
|
-
throw new Error('Add a card before choosing a paid plan');
|
|
119
|
+
throw new Error(phrase('Add a card before choosing a paid plan'));
|
|
119
120
|
const raw = obj(await call(t, 'POST', '/v1/billing/subscribe/card', { planId: p.plan, paymentMethodId: p.method, interval: p.interval }));
|
|
120
121
|
return { subscription: str(raw.subscriptionId), charged: num(raw.amountCents) };
|
|
121
122
|
}
|
|
@@ -183,7 +184,7 @@ export function chosen(list) {
|
|
|
183
184
|
/** Save a card from the single-use token the processor's form returned, optionally with billing info. */
|
|
184
185
|
export async function save(t, token, billingAddress) {
|
|
185
186
|
if (!token)
|
|
186
|
-
throw new Error('The card form returned no token');
|
|
187
|
+
throw new Error(phrase('The card form returned no token'));
|
|
187
188
|
const body = { type: 'card', providerRef: token };
|
|
188
189
|
if (billingAddress && Object.values(billingAddress).some(Boolean)) {
|
|
189
190
|
body.billingAddress = billingAddress;
|
|
@@ -299,9 +300,9 @@ export async function arm(t, rule) {
|
|
|
299
300
|
/** Charge a saved card and add the amount to the balance; answers the balance after. */
|
|
300
301
|
export async function topup(t, amount, card) {
|
|
301
302
|
if (!Number.isInteger(amount) || amount <= 0)
|
|
302
|
-
throw new Error('Enter an amount to add');
|
|
303
|
+
throw new Error(phrase('Enter an amount to add'));
|
|
303
304
|
if (!card)
|
|
304
|
-
throw new Error('Add a card before buying more');
|
|
305
|
+
throw new Error(phrase('Add a card before buying more'));
|
|
305
306
|
const r = obj(await call(t, 'POST', '/v1/billing/topup', { amountCents: amount, paymentMethodId: card }));
|
|
306
307
|
return num(r.balanceCents);
|
|
307
308
|
}
|
|
@@ -371,7 +372,7 @@ export function monthly(list) {
|
|
|
371
372
|
/** Set the org's monthly cap: change the one there is, or open one that refuses spend past it. */
|
|
372
373
|
export async function limit(t, list, threshold) {
|
|
373
374
|
if (!Number.isInteger(threshold) || threshold <= 0)
|
|
374
|
-
throw new Error('Enter a monthly limit');
|
|
375
|
+
throw new Error(phrase('Enter a monthly limit'));
|
|
375
376
|
const was = monthly(list);
|
|
376
377
|
if (was)
|
|
377
378
|
return cap(await call(t, 'PATCH', `/v1/billing/alerts/${seg(was.id)}`, { threshold }));
|
package/lib/api/call.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* One request path to the platform.
|
|
3
|
-
*
|
|
4
|
-
* Every typed op below goes through `call`, so the bearer, the org scope, the
|
|
5
|
-
* no-store cache rule and the reading of a refusal are decided once. The
|
|
6
|
-
* platform answers a refusal as RFC 9457 problem details; older handlers still
|
|
7
|
-
* answer `{error:{message}}` or `{msg}`, and all three read the same way here.
|
|
8
|
-
*/
|
|
1
|
+
import type { Say } from '@hanzo/i18n/react';
|
|
9
2
|
/** Where the platform is and who is asking. The host supplies it. */
|
|
10
3
|
export interface Target {
|
|
11
4
|
/** The platform origin, no trailing slash: calls are `${api}/v1/…`. */
|
|
@@ -20,6 +13,21 @@ export declare class Refusal extends Error {
|
|
|
20
13
|
readonly status: number;
|
|
21
14
|
constructor(status: number, message: string);
|
|
22
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A sentence this client wrote with something of the moment in it (a file's
|
|
18
|
+
* name, an address), thrown where no `t` is at hand: its message is the
|
|
19
|
+
* English, filled, and a screen says it from its source and values.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Sentence extends Error {
|
|
22
|
+
readonly source: string;
|
|
23
|
+
readonly values: Readonly<Record<string, string | number>>;
|
|
24
|
+
constructor(source: string, values?: Readonly<Record<string, string | number>>);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An error's own sentence, as the screen that caught it says it: one this
|
|
28
|
+
* client wrote, in the reader's language; the platform's, which is no key, as given.
|
|
29
|
+
*/
|
|
30
|
+
export declare function told(e: unknown, t?: Say): string;
|
|
23
31
|
export type Query = Record<string, string | number | boolean | null | undefined>;
|
|
24
32
|
/** `?a=1&b=2` from the defined, non-empty entries of `q`, or ''. */
|
|
25
33
|
export declare function query(q?: Query): string;
|
package/lib/api/call.js
CHANGED
|
@@ -5,7 +5,15 @@
|
|
|
5
5
|
* no-store cache rule and the reading of a refusal are decided once. The
|
|
6
6
|
* platform answers a refusal as RFC 9457 problem details; older handlers still
|
|
7
7
|
* answer `{error:{message}}` or `{msg}`, and all three read the same way here.
|
|
8
|
+
*
|
|
9
|
+
* A sentence this client writes is English, marked (`phrase`) for the
|
|
10
|
+
* translator: a module is not a component and asks no `t`, so a screen says
|
|
11
|
+
* what a module threw through its own (`told`), and a module that builds text
|
|
12
|
+
* takes the screen's `t` as its last argument, English (../say.ts `english`)
|
|
13
|
+
* when none is handed.
|
|
8
14
|
*/
|
|
15
|
+
import { phrase, translate } from '@hanzo/i18n';
|
|
16
|
+
import { english } from '../say.js';
|
|
9
17
|
/** A refusal: the status, and the platform's own sentence for it. */
|
|
10
18
|
export class Refusal extends Error {
|
|
11
19
|
status;
|
|
@@ -15,6 +23,29 @@ export class Refusal extends Error {
|
|
|
15
23
|
this.name = 'Refusal';
|
|
16
24
|
}
|
|
17
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* A sentence this client wrote with something of the moment in it (a file's
|
|
28
|
+
* name, an address), thrown where no `t` is at hand: its message is the
|
|
29
|
+
* English, filled, and a screen says it from its source and values.
|
|
30
|
+
*/
|
|
31
|
+
export class Sentence extends Error {
|
|
32
|
+
source;
|
|
33
|
+
values;
|
|
34
|
+
constructor(source, values = {}) {
|
|
35
|
+
super(translate({}, source, values));
|
|
36
|
+
this.source = source;
|
|
37
|
+
this.values = values;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* An error's own sentence, as the screen that caught it says it: one this
|
|
42
|
+
* client wrote, in the reader's language; the platform's, which is no key, as given.
|
|
43
|
+
*/
|
|
44
|
+
export function told(e, t = english) {
|
|
45
|
+
if (e instanceof Sentence)
|
|
46
|
+
return t(e.source, e.values);
|
|
47
|
+
return t(e instanceof Error ? e.message : String(e));
|
|
48
|
+
}
|
|
18
49
|
/** `?a=1&b=2` from the defined, non-empty entries of `q`, or ''. */
|
|
19
50
|
export function query(q = {}) {
|
|
20
51
|
const s = new URLSearchParams();
|
|
@@ -81,6 +112,6 @@ export async function call(t, method, path, body, init) {
|
|
|
81
112
|
export function unwrap(raw) {
|
|
82
113
|
const r = (raw && typeof raw === 'object' ? raw : {});
|
|
83
114
|
if (r.status === 'error')
|
|
84
|
-
throw new Refusal(400, typeof r.msg === 'string' && r.msg ? r.msg : 'The platform refused that');
|
|
115
|
+
throw new Refusal(400, typeof r.msg === 'string' && r.msg ? r.msg : phrase('The platform refused that'));
|
|
85
116
|
return r.data;
|
|
86
117
|
}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What the agent may use: every tool the org can reach, and which of them are
|
|
3
|
-
* switched on.
|
|
4
|
-
*
|
|
5
|
-
* GET /v1/tool → {tools: [{name, source, description, dispatchable, activated}]}
|
|
6
|
-
* PUT /v1/tool/activation {activate: [], deactivate: []} → {enabled: []}
|
|
7
|
-
*
|
|
8
|
-
* Activation is per org (and project): a tool that is off is listed but
|
|
9
|
-
* refused when an agent calls it. At most 256 names go in one request, so a
|
|
10
|
-
* larger change is sent in turns.
|
|
11
|
-
*/
|
|
12
1
|
import { type Target } from './call.ts';
|
|
13
2
|
/** Where a tool comes from, in the order the platform ranks them. */
|
|
14
3
|
export declare const SOURCES: readonly ['connector', 'function', 'zap-service', 'agent', 'skill', 'mcp'];
|
package/lib/api/capabilities.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* refused when an agent calls it. At most 256 names go in one request, so a
|
|
10
10
|
* larger change is sent in turns.
|
|
11
11
|
*/
|
|
12
|
+
import { phrase } from '@hanzo/i18n';
|
|
12
13
|
import { call } from './call.js';
|
|
13
14
|
/** Where a tool comes from, in the order the platform ranks them. */
|
|
14
15
|
export const SOURCES = ['connector', 'function', 'zap-service', 'agent', 'skill', 'mcp'];
|
|
@@ -29,7 +30,7 @@ export async function tools(t) {
|
|
|
29
30
|
/** Switch every tool in `names` on (or off), and answer the org's activated set. */
|
|
30
31
|
export async function activate(t, names, on) {
|
|
31
32
|
if (!names.length)
|
|
32
|
-
throw new Error('There is nothing to switch');
|
|
33
|
+
throw new Error(phrase('There is nothing to switch'));
|
|
33
34
|
let enabled = [];
|
|
34
35
|
for (let i = 0; i < names.length; i += BATCH) {
|
|
35
36
|
const part = names.slice(i, i + BATCH);
|
package/lib/api/codebases.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codebases on the forge, the org's own git.
|
|
3
|
-
*
|
|
4
|
-
* GET /v1/git/repos {data: [repo]} most recently updated first
|
|
5
|
-
* GET /v1/git/repos/{name} one repo, with its branch names
|
|
6
|
-
*
|
|
7
|
-
* A coding run addresses a repository by its name. The org is the tenant on
|
|
8
|
-
* the request, so the name is the whole address — `owner/name` is a path the
|
|
9
|
-
* engine refuses.
|
|
10
|
-
*/
|
|
11
1
|
import { type Target } from './call.ts';
|
|
12
2
|
export interface Codebase {
|
|
13
3
|
org: string;
|
package/lib/api/codebases.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* the request, so the name is the whole address — `owner/name` is a path the
|
|
9
9
|
* engine refuses.
|
|
10
10
|
*/
|
|
11
|
+
import { phrase } from '@hanzo/i18n';
|
|
11
12
|
import { call, seg } from './call.js';
|
|
12
13
|
const str = (v) => (typeof v === 'string' ? v : '');
|
|
13
14
|
const obj = (v) => v && typeof v === 'object' ? v : {};
|
|
@@ -69,11 +70,11 @@ const NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
|
69
70
|
export async function create(t, name, description = '') {
|
|
70
71
|
const handle = name.trim().replace(/\.git$/, '');
|
|
71
72
|
if (!NAME.test(handle))
|
|
72
|
-
throw new Error('A repository name starts with a letter or number, and may contain letters, numbers, dots, underscores and hyphens.');
|
|
73
|
+
throw new Error(phrase('A repository name starts with a letter or number, and may contain letters, numbers, dots, underscores and hyphens.'));
|
|
73
74
|
const raw = await call(t, 'POST', '/v1/git/repos', { name: handle, description: description.trim() });
|
|
74
75
|
const row = codebase(raw, t.org ?? '');
|
|
75
76
|
if (!row)
|
|
76
|
-
throw new Error('The forge created a repository and did not name it');
|
|
77
|
+
throw new Error(phrase('The forge created a repository and did not name it'));
|
|
77
78
|
return row;
|
|
78
79
|
}
|
|
79
80
|
export async function codebases(t, q = '') {
|
package/lib/api/coding.d.ts
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
* Starting a coding run, and what it left.
|
|
3
|
-
*
|
|
4
|
-
* POST /v1/agent/coding → 202 {sessionId, repo, branch, routed, targetId}
|
|
5
|
-
* GET /v1/agent/coding/{session}/artifacts {session, saved, artifacts}
|
|
6
|
-
* GET /v1/agent/coding/{session}/artifacts/{name} one stored artifact's bytes
|
|
7
|
-
*
|
|
8
|
-
* 202 is ADMITTED, not finished: the answer is the session the run narrates
|
|
9
|
-
* itself in, and the session stream is how it is watched.
|
|
10
|
-
*
|
|
11
|
-
* Where it runs is one field. No `targetId` is the platform's sandbox; a target
|
|
12
|
-
* id routes it to one of the org's machines, and `routed` says whether it got
|
|
13
|
-
* there.
|
|
14
|
-
*
|
|
15
|
-
* `mode` is what the run may do: `build` edits, commits and pushes its branch;
|
|
16
|
-
* `plan` reads the repository with a credential that can only read and answers
|
|
17
|
-
* with a plan, as its final status. A plan runs in the platform's sandbox only —
|
|
18
|
-
* a claimed machine clones and pushes with its own credential — so a plan
|
|
19
|
-
* routed to one is refused, here before sending as on the platform.
|
|
20
|
-
*
|
|
21
|
-
* `model` and `effort` are taken by the dev harness the builder runs (and by
|
|
22
|
-
* codex); the builder names no other harness, so they are always honoured.
|
|
23
|
-
*
|
|
24
|
-
* `setup` is a plan's shape put to one question: how this codebase is installed,
|
|
25
|
-
* started and checked. Its agent may install and run things in its sandbox, and
|
|
26
|
-
* its answer is kept as the codebase's proposed environment (environment.ts).
|
|
27
|
-
*
|
|
28
|
-
* A sandbox run keeps its sandbox after it ends, so `after` continues the earlier
|
|
29
|
-
* run in that same sandbox and working tree, resumed if it parked.
|
|
30
|
-
*/
|
|
1
|
+
import type { Say } from '@hanzo/i18n/react';
|
|
31
2
|
import { type Target } from './call.ts';
|
|
32
3
|
export type Mode = 'build' | 'plan' | 'setup';
|
|
33
|
-
/** Why this mode cannot run where it is sent, or '' when it can. */
|
|
34
|
-
export declare const unhonoured: (mode: Mode | undefined, target?: string) => string;
|
|
4
|
+
/** Why this mode cannot run where it is sent, in the words of the `t` handed (English without one), or '' when it can. */
|
|
5
|
+
export declare const unhonoured: (mode: Mode | undefined, target?: string, t?: Say) => string;
|
|
35
6
|
export interface Ask {
|
|
36
7
|
/** The task, in the words you would use with a colleague. */
|
|
37
8
|
prompt: string;
|