@alexkroman1/aai-cli 13.3.0 → 15.0.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/dist/{_agent-Clbq3a4h.mjs → _agent-BzUeqOdj.mjs} +32 -9
- package/dist/_agent.d.ts +23 -0
- package/dist/_artifacts-BJOYGQPp.mjs +21 -0
- package/dist/_artifacts.d.ts +16 -0
- package/dist/_build-target.d.ts +172 -0
- package/dist/{_bundler-DEkjO1d8.mjs → _bundler-DM0d0M7m.mjs} +8 -7
- package/dist/_cli-common.d.ts +45 -6
- package/dist/{_config-ZY2euhdh.mjs → _config-DYzC6WMD.mjs} +2 -2
- package/dist/_dev-env.d.ts +1 -1
- package/dist/{_dev-server-C13xuGB1.mjs → _dev-server-BzWB6-4y.mjs} +25 -24
- package/dist/_dev-vite-config.d.ts +3 -3
- package/dist/_e2e-test-utils.d.ts +1 -1
- package/dist/{_init-Ci4QGjp8.mjs → _init-Bsi3DZNJ.mjs} +9 -23
- package/dist/{_output-DbJt9gsl.mjs → _output-DBP9Op_d.mjs} +22 -13
- package/dist/_output.d.ts +10 -9
- package/dist/{_preflight-B2laWPdU.mjs → _preflight-CcAR577V.mjs} +2 -2
- package/dist/_resource-commands.d.ts +9 -9
- package/dist/_server-common-De0haHr9.mjs +70 -0
- package/dist/_server-common.d.ts +20 -1
- package/dist/{_slug-api-DlKpj91X.mjs → _slug-api-CGvc2YSQ.mjs} +18 -9
- package/dist/_slug-api.d.ts +19 -0
- package/dist/{_studio-DTi3EdXQ.mjs → _studio-DnR_BqFp.mjs} +7 -3
- package/dist/_studio-commands.d.ts +13 -13
- package/dist/{_templates-V4l5sZJy.mjs → _templates-CIlJ3Vay.mjs} +4 -4
- package/dist/_templates.d.ts +1 -1
- package/dist/{_typecheck-gate-sV4N5F93.mjs → _typecheck-gate-U3jcil8L.mjs} +3 -2
- package/dist/_typecheck-gate.d.ts +3 -1
- package/dist/{_utils-Dhd058D9.mjs → _utils-D5JGcjiW.mjs} +43 -1
- package/dist/_utils.d.ts +35 -0
- package/dist/_vercel-output.d.ts +63 -0
- package/dist/{_workflow-determinism-C9l8uC2R.mjs → _workflow-determinism-CvpqMpdh.mjs} +18 -26
- package/dist/_workflow-determinism.d.ts +3 -3
- package/dist/build-BhEaxBPu.mjs +481 -0
- package/dist/build.d.ts +23 -10
- package/dist/cli.d.ts +1 -2
- package/dist/cli.mjs +155 -138
- package/dist/{client-bundler-CT-_26c5.mjs → client-bundler-6mTLs6ny.mjs} +5 -5
- package/dist/client-bundler.d.ts +1 -1
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-RqlQZ6Y_.mjs → delete-BdFnbnVR.mjs} +4 -4
- package/dist/{deploy-B7f3CK7v.mjs → deploy-CGqPU5U-.mjs} +11 -11
- package/dist/{dev-DamXieW_.mjs → dev-Bx9gYBHM.mjs} +3 -3
- package/dist/{eval-h3DTVfRw.mjs → eval-B3I7FqN9.mjs} +3 -3
- package/dist/{init-D-vFrV8h.mjs → init-CFyusRbq.mjs} +48 -20
- package/dist/init.d.ts +14 -0
- package/dist/{login-CDiemNmC.mjs → login-DaLrPOFg.mjs} +4 -6
- package/dist/{logs-DGwPNCzB.mjs → logs-7BRwq0cG.mjs} +21 -14
- package/dist/project-config.mjs +1 -1
- package/dist/scaffold/CLAUDE.md +155 -76
- package/dist/scaffold/package.json +6 -6
- package/dist/{secret-V1w7y9-j.mjs → secret-Cjp912yF.mjs} +5 -5
- package/dist/secret.d.ts +8 -6
- package/dist/start.d.ts +112 -0
- package/dist/start.mjs +156 -0
- package/dist/{studio-BpMCfUNx.mjs → studio-C_zuRC_z.mjs} +13 -15
- package/dist/templates/briefing-desk/agent.eval.test.ts +156 -0
- package/dist/templates/call-audit/agent.test.ts +11 -6
- package/dist/templates/call-audit/agent.ts +2 -2
- package/dist/templates/call-audit/client.tsx +27 -42
- package/dist/templates/call-audit/workflows/audit.ts +7 -5
- package/dist/templates/call-audit/workflows/ingest.ts +7 -7
- package/dist/templates/call-audit/workflows/media.ts +12 -37
- package/dist/templates/call-audit/workflows/summarize.ts +8 -8
- package/dist/templates/call-audit/workflows/sync-api.ts +3 -3
- package/dist/templates/code-interpreter/agent.test.ts +103 -0
- package/dist/templates/dispatch-center/agent.test.ts +7 -7
- package/dist/templates/dispatch-center/client.tsx +53 -61
- package/dist/templates/dispatch-center/shared.ts +0 -8
- package/dist/templates/dispatch-center/tools/ops_dashboard.ts +4 -1
- package/dist/templates/embedded-assets/agent.eval.test.ts +4 -2
- package/dist/templates/health-assistant/agent.eval.test.ts +4 -2
- package/dist/templates/infocom-adventure/client.tsx +40 -36
- package/dist/templates/link-digest/agent.test.ts +3 -3
- package/dist/templates/link-digest/agent.ts +2 -2
- package/dist/templates/link-digest/client.tsx +81 -19
- package/dist/templates/link-digest/workflows/digest.ts +13 -16
- package/dist/templates/math-buddy/agent.test.ts +126 -0
- package/dist/templates/night-owl/agent.eval.test.ts +4 -2
- package/dist/templates/night-owl/client.tsx +8 -2
- package/dist/templates/personal-finance/agent.test.ts +127 -0
- package/dist/templates/pipeline-simple/agent.test.ts +2 -2
- package/dist/templates/pizza-ordering/client.tsx +5 -4
- package/dist/templates/pizza-ordering/shared.ts +3 -8
- package/dist/templates/pizza-ordering/tools/add_pizza.ts +3 -2
- package/dist/templates/pizza-ordering/tools/place_order.ts +3 -2
- package/dist/templates/pizza-ordering/tools/remove_pizza.ts +3 -2
- package/dist/templates/pizza-ordering/tools/update_pizza.ts +3 -2
- package/dist/templates/pizza-ordering/tools/view_order.ts +3 -2
- package/dist/templates/plan-and-execute/agent.test.ts +10 -5
- package/dist/templates/plan-and-execute/client.tsx +2 -2
- package/dist/templates/podcast-digest/agent.test.ts +20 -11
- package/dist/templates/podcast-digest/client.tsx +16 -22
- package/dist/templates/podcast-digest/workflows/digest.ts +21 -19
- package/dist/templates/podcast-digest/workflows/feeds.ts +61 -33
- package/dist/templates/podcast-digest/workflows/slack.ts +7 -7
- package/dist/templates/recap-workflow/agent.eval.test.ts +21 -13
- package/dist/templates/recap-workflow/agent.test.ts +27 -23
- package/dist/templates/recap-workflow/workflows/recap.ts +24 -28
- package/dist/templates/redline/agent.eval.test.ts +5 -8
- package/dist/templates/redline/agent.test.ts +1 -1
- package/dist/templates/redline/client.tsx +36 -34
- package/dist/templates/redline/workflows/redline.ts +17 -17
- package/dist/templates/research-workflow/agent.eval.test.ts +5 -5
- package/dist/templates/research-workflow/agent.test.ts +10 -7
- package/dist/templates/research-workflow/workflows/research.ts +28 -30
- package/dist/templates/retail/agent.test.ts +17 -15
- package/dist/templates/retail/cancel.ts +7 -6
- package/dist/templates/retail/client.tsx +39 -58
- package/dist/templates/retail/payment.ts +4 -3
- package/dist/templates/retail/pending.test.ts +19 -19
- package/dist/templates/retail/store.test.ts +5 -5
- package/dist/templates/retail/swap.ts +8 -11
- package/dist/templates/solo-rpg/agent.eval.test.ts +2 -16
- package/dist/templates/solo-rpg/agent.test.ts +12 -12
- package/dist/templates/solo-rpg/client.tsx +3 -3
- package/dist/templates/spoken-summary/agent.test.ts +9 -9
- package/dist/templates/spoken-summary/agent.ts +3 -3
- package/dist/templates/spoken-summary/client.tsx +23 -30
- package/dist/templates/spoken-summary/workflows/summarize.ts +11 -11
- package/dist/templates/spoken-summary/workflows/transcribe.ts +14 -14
- package/dist/templates/support-line/agent.ts +8 -0
- package/dist/templates/support-line/client.tsx +4 -3
- package/dist/templates/support-line/prompts.ts +0 -2
- package/dist/templates/transcription-workflow/agent.test.ts +20 -12
- package/dist/templates/transcription-workflow/agent.ts +2 -2
- package/dist/templates/transcription-workflow/client.tsx +15 -14
- package/dist/templates/transcription-workflow/recover.ts +1 -1
- package/dist/templates/transcription-workflow/run-panel.tsx +34 -14
- package/dist/templates/transcription-workflow/total-latency.tsx +46 -20
- package/dist/templates/transcription-workflow/workflows/batch.ts +15 -15
- package/dist/templates/transcription-workflow/workflows/downsample.ts +1 -1
- package/dist/templates/transcription-workflow/workflows/normalize.ts +15 -19
- package/dist/templates/transcription-workflow/workflows/stream.ts +12 -12
- package/dist/templates/transcription-workflow/workflows/sync-api.ts +3 -3
- package/dist/templates/transcription-workflow/workflows/transcribe.ts +23 -34
- package/dist/templates/travel-concierge/agent.eval.test.ts +2 -2
- package/dist/templates/travel-concierge/agent.test.ts +15 -7
- package/dist/templates/travel-concierge/client.tsx +2 -2
- package/dist/templates/travel-concierge/routing.ts +64 -55
- package/dist/templates/travel-concierge/shared.ts +10 -14
- package/dist/templates/travel-concierge/tools/cancel_action.ts +3 -1
- package/dist/templates/travel-concierge/tools/complete_or_escalate.ts +3 -1
- package/dist/templates/travel-concierge/tools/confirm_action.ts +3 -1
- package/dist/templates/travel-concierge/tools/lookup_booking.ts +4 -3
- package/dist/templates/travel-concierge/tools/search_car_rentals.ts +3 -2
- package/dist/templates/travel-concierge/tools/search_excursions.ts +3 -2
- package/dist/templates/travel-concierge/tools/search_flights.ts +3 -2
- package/dist/templates/travel-concierge/tools/search_hotels.ts +3 -2
- package/dist/templates/web-researcher/agent.test.ts +130 -0
- package/dist/{test-guenJUxi.mjs → test-D032V2cA.mjs} +4 -17
- package/dist/typecheck.mjs +1 -1
- package/dist/worker-bundler.d.ts +1 -1
- package/dist/worker-bundler.mjs +8 -8
- package/dist/{workflow-BZyKLkhV.mjs → workflow-CVioyO3V.mjs} +6 -5
- package/package.json +9 -4
- package/dist/_server-common-BV4_CrP3.mjs +0 -43
- package/dist/build-CWyFGe-W.mjs +0 -69
- package/dist/scaffold/server.mjs +0 -204
package/dist/scaffold/CLAUDE.md
CHANGED
|
@@ -77,7 +77,8 @@ The fast loop: edit → `pnpm dev` (browser, talk to it) →
|
|
|
77
77
|
you stopped talking, barge-in, two sentences merging into one turn. Those
|
|
78
78
|
need `pnpm dev` and your own voice.
|
|
79
79
|
4. **Run `pnpm build` before declaring done** — bundles `agent.ts`,
|
|
80
|
-
type-checks,
|
|
80
|
+
type-checks, validates the manifest, and runs the WHOLE spec suite first.
|
|
81
|
+
Catches issues `dev` won't.
|
|
81
82
|
5. **Make small, focused changes** — verify each one before stacking the
|
|
82
83
|
next.
|
|
83
84
|
6. **Look at templates before writing custom code** — the CLI ships working
|
|
@@ -109,6 +110,7 @@ npx @alexkroman1/aai-cli init # Scaffold a new agent
|
|
|
109
110
|
npx @alexkroman1/aai-cli templates # List available templates
|
|
110
111
|
npx @alexkroman1/aai-cli dev # Start local dev server
|
|
111
112
|
npx @alexkroman1/aai-cli test # Run agent.test.ts via vitest
|
|
113
|
+
npx @alexkroman1/aai-cli test --all # ...or every spec in the project
|
|
112
114
|
npx @alexkroman1/aai-cli eval # Run agent.eval.test.ts against a model
|
|
113
115
|
npx @alexkroman1/aai-cli build # Bundle and validate
|
|
114
116
|
npx @alexkroman1/aai-cli deploy # Deploy to production
|
|
@@ -122,10 +124,17 @@ The scaffold's `package.json` exposes `dev`, `build`, `test`, `eval` and
|
|
|
122
124
|
`deploy` as `pnpm <name>` shortcuts. Other commands (`init`, `templates`,
|
|
123
125
|
`delete`, `secret`) are CLI-only.
|
|
124
126
|
|
|
127
|
+
**`aai test` targets `agent.test.ts` and nothing else**, which `--all` widens.
|
|
128
|
+
What matters is that a narrowed run does not report itself as a pass: when the
|
|
129
|
+
project holds spec files the run did not cover, it FAILS and names them rather
|
|
130
|
+
than printing a green line that says nothing about `tools/*.test.ts`. `pnpm
|
|
131
|
+
test` (the scaffold's own script) already runs the whole suite, and so does the
|
|
132
|
+
gate in front of `aai build`.
|
|
133
|
+
|
|
125
134
|
## Running it yourself (`npm start`)
|
|
126
135
|
|
|
127
|
-
`
|
|
128
|
-
|
|
136
|
+
`aai start` serves this agent from a plain Node process — no platform account,
|
|
137
|
+
nothing managed. It is the deployment counterpart of `aai dev`:
|
|
129
138
|
|
|
130
139
|
```sh
|
|
131
140
|
npm start # http://127.0.0.1:3000
|
|
@@ -133,11 +142,18 @@ PORT=8080 HOST=0.0.0.0 npm start # bind every interface, e.g. in a container
|
|
|
133
142
|
```
|
|
134
143
|
|
|
135
144
|
`npm start` **builds first** (that is the `prestart` script) and then serves
|
|
136
|
-
the result: `
|
|
145
|
+
the result: `aai start` boots `.aai/worker.mjs`, the same artifact
|
|
137
146
|
`aai publish` uploads. It serves your own `client.tsx` build when there is one
|
|
138
|
-
and falls back to
|
|
139
|
-
|
|
140
|
-
|
|
147
|
+
and falls back to the prebuilt default UI shipped inside `@alexkroman1/aai-ui`.
|
|
148
|
+
|
|
149
|
+
There is no server file in your project, and that is deliberate — the boot
|
|
150
|
+
belongs to the framework, so it improves when you update rather than being
|
|
151
|
+
frozen at the moment you scaffolded. When you need to own it, import
|
|
152
|
+
`createProjectServer` from `@alexkroman1/aai-cli/start`: it builds the server
|
|
153
|
+
and binds nothing, so you decide how it is served. Building one from scratch
|
|
154
|
+
instead, `defaultClientDir()` (`@alexkroman1/aai-ui/client-dir`) is where that
|
|
155
|
+
prebuilt UI lives — the only export of `aai-ui` that runs on Node rather than
|
|
156
|
+
in the browser.
|
|
141
157
|
|
|
142
158
|
The build is what makes `tools/` work — a tool is registered by existing, and
|
|
143
159
|
the enumeration happens where the bundle is assembled, so a server that loaded
|
|
@@ -152,9 +168,31 @@ One thing to know: it binds **loopback by default**, because this server has
|
|
|
152
168
|
no request authentication of its own; set `HOST=0.0.0.0` only behind your own
|
|
153
169
|
proxy or auth.
|
|
154
170
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
171
|
+
`run_code` is the one feature that does not follow — it needs the platform's
|
|
172
|
+
sandbox and refuses outside one.
|
|
173
|
+
|
|
174
|
+
### Deploying to a host that wants its own entry file
|
|
175
|
+
|
|
176
|
+
`aai build --target <host>` writes the deployment that host expects into the
|
|
177
|
+
build output. Nothing host-specific lives in your project: the files are
|
|
178
|
+
generated, gitignored, and rewritten by the host's own build.
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
aai build --target vercel # writes .vercel/output/ (Build Output API v3)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
You rarely type it. The target is detected from the host's own build
|
|
185
|
+
environment, so `vercel deploy` (or a git push) picks it up with nothing
|
|
186
|
+
configured; `--target node`, the default everywhere else, emits nothing extra
|
|
187
|
+
and is what `npm start` runs.
|
|
188
|
+
|
|
189
|
+
One thing to know before deploying a VOICE agent to a serverless host: the
|
|
190
|
+
session is a WebSocket, so the host has to support one. Vercel does — it hands
|
|
191
|
+
the function the raw upgrade, and the emitted entry passes it to the same
|
|
192
|
+
server `aai dev` runs. A host that serves only request/response still runs the
|
|
193
|
+
HTTP surface — `/health`, `/client-config`,
|
|
194
|
+
`/workflows/*` and your static assets — which is everything a workflow app
|
|
195
|
+
needs and none of what a voice agent needs.
|
|
158
196
|
|
|
159
197
|
## Project structure
|
|
160
198
|
|
|
@@ -416,14 +454,14 @@ below.
|
|
|
416
454
|
|
|
417
455
|
### Workflow bodies live in `workflows/`
|
|
418
456
|
|
|
419
|
-
A body is an ordinary exported async function of its input and a `
|
|
457
|
+
A body is an ordinary exported async function of its input and a `WorkflowContext`.
|
|
420
458
|
There is no directive and no compile step of its own — the agent bundle compiles
|
|
421
459
|
`workflows/` like any other source file — and durability is a method call:
|
|
422
460
|
|
|
423
461
|
```ts
|
|
424
|
-
import type {
|
|
462
|
+
import type { WorkflowContext } from "@alexkroman1/aai";
|
|
425
463
|
|
|
426
|
-
export async function digestFlow(input: { url: string }, ctx:
|
|
464
|
+
export async function digestFlow(input: { url: string }, ctx: WorkflowContext) {
|
|
427
465
|
const digest = await ctx.step("summarize", () => summarize(input.url));
|
|
428
466
|
|
|
429
467
|
// Suspended, not blocked: the container is free to exit here and the run
|
|
@@ -515,11 +553,11 @@ The three undurable reads a body most often wants, each journaled — read once
|
|
|
515
553
|
the first reach, and the same value on every later walk:
|
|
516
554
|
|
|
517
555
|
```ts
|
|
518
|
-
import type {
|
|
556
|
+
import type { WorkflowContext } from "@alexkroman1/aai";
|
|
519
557
|
|
|
520
558
|
declare function charge(amount: number, idempotencyKey: string, jitter: number): Promise<void>;
|
|
521
559
|
|
|
522
|
-
export async function chargeFlow(input: { amount: number }, ctx:
|
|
560
|
+
export async function chargeFlow(input: { amount: number }, ctx: WorkflowContext) {
|
|
523
561
|
const startedAt = await ctx.now(); // epoch ms, decided once
|
|
524
562
|
const idempotencyKey = await ctx.uuid(); // still the same id after a crash
|
|
525
563
|
const jitter = await ctx.random(); // one float in [0, 1), journaled per call
|
|
@@ -601,6 +639,22 @@ Five things worth knowing:
|
|
|
601
639
|
which is how a "send it now" tool cuts a scheduled wait short. Naming no ids
|
|
602
640
|
wakes every outstanding SLEEP and deliberately not a `waitFor` deadline, so
|
|
603
641
|
cutting a schedule short cannot also close an approval window.
|
|
642
|
+
- **A SUSPEND is not free, so `ctx.sleep` is not a `setTimeout`.** A wait costs
|
|
643
|
+
a journal write to record it, a queued delivery to bring the run back, and a
|
|
644
|
+
fresh WALK of the body — measured on a deployed agent at roughly a second of
|
|
645
|
+
overhead around the sleep itself, on top of whatever you asked for. There is a
|
|
646
|
+
cliff at the bottom of the range worth knowing about: a sleep shorter
|
|
647
|
+
than the round trip that records it never suspends AT ALL — `ctx.sleep("beat",
|
|
648
|
+
100)` and `ctx.sleep("beat", 0)` are both simply free — while anything longer
|
|
649
|
+
pays the whole cost. Measured, `nap(100)` and `nap(0)` came back within 30 ms
|
|
650
|
+
of each other on a run whose total was 2.1 s.
|
|
651
|
+
|
|
652
|
+
So a sub-second pause is not what this is for. For a short backoff inside a
|
|
653
|
+
step, use an ordinary timer (`sleep` from `@alexkroman1/aai/internal`) — a step
|
|
654
|
+
body may not call `ctx.sleep` anyway, and the engine refuses one that does. Use
|
|
655
|
+
`ctx.sleep` for a wait you want to SURVIVE the process, which is the thing a
|
|
656
|
+
timer cannot do. A body that polls in a loop pays the suspend per iteration,
|
|
657
|
+
which is the strongest argument for the next section: park on the callback.
|
|
604
658
|
|
|
605
659
|
#### A third-party callback is an OPTIMIZATION over a reconciling read
|
|
606
660
|
|
|
@@ -656,15 +710,15 @@ trap somebody has already paid for:
|
|
|
656
710
|
Steps are ordinary exported functions, so a spec imports and calls them. The
|
|
657
711
|
BODY needs an engine, and there are two, for two different questions.
|
|
658
712
|
|
|
659
|
-
**"What did the body ask for?"** — `
|
|
713
|
+
**"What did the body ask for?"** — `createWorkflowContext` from
|
|
660
714
|
`@alexkroman1/aai/testing`. It runs the steps and records the names, the retry
|
|
661
715
|
policies and the sleeps, over one walk with no journal. Nothing replays, so a
|
|
662
716
|
spec built on it must not claim to test durability.
|
|
663
717
|
|
|
664
718
|
```ts no-check
|
|
665
|
-
import {
|
|
719
|
+
import { createWorkflowContext } from "@alexkroman1/aai/testing";
|
|
666
720
|
|
|
667
|
-
const ctx =
|
|
721
|
+
const ctx = createWorkflowContext({ runSteps: false });
|
|
668
722
|
await digestFlow({ url: "https://example.com/a" }, ctx);
|
|
669
723
|
|
|
670
724
|
expect(ctx.steps.map((s) => s.name)).toEqual(["fetchArticle", "summarize", "file"]);
|
|
@@ -729,7 +783,7 @@ root barrel would drag the whole SDK into that bundle.
|
|
|
729
783
|
|
|
730
784
|
```ts
|
|
731
785
|
import { stepEnv } from "@alexkroman1/aai/step";
|
|
732
|
-
import {
|
|
786
|
+
import { stepGenerateOrFail } from "@alexkroman1/aai/step-errors";
|
|
733
787
|
|
|
734
788
|
async function summarize(text: string) {
|
|
735
789
|
// The agent's env by name — the same values a tool reads from `ctx.env`.
|
|
@@ -737,7 +791,7 @@ async function summarize(text: string) {
|
|
|
737
791
|
const style = stepEnv("DIGEST_STYLE") ?? "plain";
|
|
738
792
|
|
|
739
793
|
// One model call, on the agent's own ASSEMBLYAI_API_KEY and default model.
|
|
740
|
-
return await
|
|
794
|
+
return await stepGenerateOrFail(`${style} summary of:\n\n${text}`, {
|
|
741
795
|
system: "Reply with two sentences and nothing else.",
|
|
742
796
|
});
|
|
743
797
|
}
|
|
@@ -749,9 +803,9 @@ before and after a deploy. List what you read in `requiredEnv` and a deploy
|
|
|
749
803
|
checks it for you. And **`stepGenerate` is not `ctx.generate`**: it is one
|
|
750
804
|
request to the AssemblyAI LLM Gateway, with no tools and no structured output,
|
|
751
805
|
because bundling the AI SDK into a step artifact costs megabytes on every
|
|
752
|
-
deploy. Use `
|
|
806
|
+
deploy. Use `stepGenerateJsonOrFail` with a Zod `schema` if you need a shape.
|
|
753
807
|
|
|
754
|
-
### From a step, reach for the `
|
|
808
|
+
### From a step, reach for the `OrFail` call
|
|
755
809
|
|
|
756
810
|
`@alexkroman1/aai/step-errors` publishes a wrapper for every `/step` call that
|
|
757
811
|
can fail against a remote service, and **inside a step the wrapper is the one to
|
|
@@ -759,14 +813,14 @@ use**:
|
|
|
759
813
|
|
|
760
814
|
| Raw, on `@alexkroman1/aai/step` | Use this instead, on `@alexkroman1/aai/step-errors` |
|
|
761
815
|
| --- | --- |
|
|
762
|
-
| `stepGenerate` | `
|
|
763
|
-
| `stepGenerateJson` | `
|
|
764
|
-
| `stepFetch` | `
|
|
765
|
-
| `stepTranscribeSync` | `
|
|
766
|
-
| `stepTranscribeUpload` / `Submit` / `Poll` | the matching `*
|
|
767
|
-
| `sendToChannel` (`/channels`) | `
|
|
768
|
-
|
|
769
|
-
`
|
|
816
|
+
| `stepGenerate` | `stepGenerateOrFail` |
|
|
817
|
+
| `stepGenerateJson` | `stepGenerateJsonOrFail` |
|
|
818
|
+
| `stepFetch` | `stepFetchOrFail` |
|
|
819
|
+
| `stepTranscribeSync` | `stepTranscribeSyncOrFail` |
|
|
820
|
+
| `stepTranscribeUpload` / `Submit` / `Poll` | the matching `*OrFail` |
|
|
821
|
+
| `sendToChannel` (`/channels`) | `sendToChannelOrFail` |
|
|
822
|
+
|
|
823
|
+
`stepFetchOrFail` is the one that is not spelled `*OrFail`, and the name is the
|
|
770
824
|
difference: the others turn an already-thrown failure into a classified one,
|
|
771
825
|
while this also turns a NON-2XX RESPONSE into a throw — `stepFetch` resolves
|
|
772
826
|
with a `404` rather than raising it. Two changes, so two names.
|
|
@@ -804,7 +858,7 @@ bundling rule as `/step` — import them there, never through the root barrel:
|
|
|
804
858
|
recording, or `stepTranscribeUpload` → `stepTranscribeSubmit` →
|
|
805
859
|
`stepTranscribePoll` for a long one, plus `Transcript`, `TranscribeError` and
|
|
806
860
|
the `TRANSCRIBE_*` limits. (There is no `/transcribe` subpath; transcription
|
|
807
|
-
lives on `/step` with the other step primitives.) Use the `
|
|
861
|
+
lives on `/step` with the other step primitives.) Use the `OrFail`
|
|
808
862
|
wrappers above: a provider refusal — a container it will not read, a
|
|
809
863
|
recording with no speech — arrives
|
|
810
864
|
with `retryable: false`, and unclassified a step re-uploads the same bytes
|
|
@@ -841,19 +895,19 @@ export async function measure(uploadId: string) {
|
|
|
841
895
|
|
|
842
896
|
A run that finishes while nobody is on the line needs somewhere to put the
|
|
843
897
|
result. `slackChannel({ webhookUrl })` names a destination and
|
|
844
|
-
`
|
|
898
|
+
`sendToChannelOrFail(channel, message)` posts to it:
|
|
845
899
|
|
|
846
900
|
```ts no-check
|
|
847
901
|
import { type ChannelMessage, slackChannel } from "@alexkroman1/aai/channels";
|
|
848
902
|
import { requireStepEnv } from "@alexkroman1/aai/step";
|
|
849
|
-
import {
|
|
903
|
+
import { sendToChannelOrFail } from "@alexkroman1/aai/step-errors";
|
|
850
904
|
|
|
851
905
|
export async function announce(headline: string, points: string[]) {
|
|
852
906
|
const message: ChannelMessage = {
|
|
853
907
|
text: headline,
|
|
854
908
|
sections: points.map((point) => ({ text: point })),
|
|
855
909
|
};
|
|
856
|
-
return await
|
|
910
|
+
return await sendToChannelOrFail(slackChannel({ webhookUrl: requireStepEnv("SLACK_WEBHOOK_URL") }), message);
|
|
857
911
|
}
|
|
858
912
|
```
|
|
859
913
|
|
|
@@ -862,7 +916,7 @@ it with `aai secret put`. A channel's credential is its DESTINATION and is
|
|
|
862
916
|
passed in, which is why no channel reads an env var of its own. `ChannelMessage`
|
|
863
917
|
is rendered per platform, so the same message is legal on a channel kind added
|
|
864
918
|
later; `isSlackWebhookUrl` / `isSlackWorkflowTriggerUrl` validate a pasted URL
|
|
865
|
-
before a run depends on it, and `
|
|
919
|
+
before a run depends on it, and `explainChannelFailure` turns a refusal into a sentence
|
|
866
920
|
a person can act on. `podcast-digest` is the worked example.
|
|
867
921
|
|
|
868
922
|
### A step's HTTP: use `stepFetch`, not `fetch`
|
|
@@ -941,11 +995,11 @@ Both are on `@alexkroman1/aai/step`, and `spoken-summary` is the template that
|
|
|
941
995
|
shows the whole round trip.
|
|
942
996
|
|
|
943
997
|
```ts
|
|
944
|
-
import { stepSpeak,
|
|
998
|
+
import { stepSpeak, stepWriteUpload } from "@alexkroman1/aai/step";
|
|
945
999
|
|
|
946
1000
|
export async function narrate(script: string) {
|
|
947
1001
|
const spoken = await stepSpeak(script, { voice: "jane" });
|
|
948
|
-
const stored = await
|
|
1002
|
+
const stored = await stepWriteUpload(spoken.audio, { name: "summary.wav", type: "audio/wav" });
|
|
949
1003
|
return { audio: stored.id, durationMs: spoken.durationMs };
|
|
950
1004
|
}
|
|
951
1005
|
```
|
|
@@ -962,11 +1016,13 @@ opens and produces silence rather than an error. The `AssemblyAITtsVoice` type
|
|
|
962
1016
|
gives you autocomplete over it and nothing more: it accepts any string, so that
|
|
963
1017
|
a voice the service adds after this release still compiles.
|
|
964
1018
|
|
|
965
|
-
**`
|
|
966
|
-
output is read back as JSON, so audio cannot travel in one — the same rule
|
|
967
|
-
keeps an uploaded recording's bytes out of a run's INPUT, arriving at the
|
|
968
|
-
end of the run. Store the bytes, return the **id**, and let the page fetch
|
|
969
|
-
with `api.download(id)`.
|
|
1019
|
+
**`stepWriteUpload` is `stepReadUpload`'s other direction, and you need it.** A
|
|
1020
|
+
run's output is read back as JSON, so audio cannot travel in one — the same rule
|
|
1021
|
+
that keeps an uploaded recording's bytes out of a run's INPUT, arriving at the
|
|
1022
|
+
other end of the run. Store the bytes, return the **id**, and let the page fetch
|
|
1023
|
+
it with `api.download(id)`. A step that wants the record rather than the bytes
|
|
1024
|
+
reads it with `stepUploadInfo(id)`, which answers an `UploadInfo` — the name,
|
|
1025
|
+
the size stored so far, and whether that is all of it.
|
|
970
1026
|
|
|
971
1027
|
Three rules come with it:
|
|
972
1028
|
|
|
@@ -1020,12 +1076,13 @@ naming a shape is what asks the compiler to make you handle the failure.
|
|
|
1020
1076
|
|
|
1021
1077
|
### The page
|
|
1022
1078
|
|
|
1023
|
-
A workflow app's `client.tsx` mounts with `
|
|
1024
|
-
there is no session to build, so no socket, no audio graph
|
|
1025
|
-
request. Everything else is the same file, React and
|
|
1079
|
+
A workflow app's `client.tsx` mounts with `mountPage()` rather than
|
|
1080
|
+
`mountClient()` — there is no session to build, so no socket, no audio graph
|
|
1081
|
+
and no microphone request. Everything else is the same file, React and
|
|
1082
|
+
Tailwind included.
|
|
1026
1083
|
|
|
1027
1084
|
```tsx no-check
|
|
1028
|
-
import { createWorkflowApi,
|
|
1085
|
+
import { createWorkflowApi, mountPage, useWorkflowRun } from "@alexkroman1/aai-ui";
|
|
1029
1086
|
import "@alexkroman1/aai-ui/styles.css";
|
|
1030
1087
|
import type { WorkflowOutputOf } from "@alexkroman1/aai/workflow-api";
|
|
1031
1088
|
import { useState } from "react";
|
|
@@ -1053,7 +1110,7 @@ export function App() {
|
|
|
1053
1110
|
);
|
|
1054
1111
|
}
|
|
1055
1112
|
|
|
1056
|
-
|
|
1113
|
+
mountPage({ name: "Link Digest", component: App });
|
|
1057
1114
|
```
|
|
1058
1115
|
|
|
1059
1116
|
`api.start()` resolves as soon as the RUN EXISTS, not when it finishes — that
|
|
@@ -1171,11 +1228,23 @@ statement about pipeline mode, not about the SDK.
|
|
|
1171
1228
|
|
|
1172
1229
|
### Answering a phone call
|
|
1173
1230
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1231
|
+
**Say which carriers may call, and `WS /phone` is served for exactly those.**
|
|
1232
|
+
`telephony` is an allow-list on `agent()`, and it is the whole of the wiring:
|
|
1233
|
+
|
|
1234
|
+
```ts
|
|
1235
|
+
import { agent } from "@alexkroman1/aai";
|
|
1236
|
+
|
|
1237
|
+
export default agent({
|
|
1238
|
+
name: "Support",
|
|
1239
|
+
greeting: "Support line — what's happened?",
|
|
1240
|
+
// The carrier this agent's number is with. `true` admits every carrier this
|
|
1241
|
+
// build decodes; omit the field and `/phone` is not served at all.
|
|
1242
|
+
telephony: ["twilio"],
|
|
1243
|
+
});
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
Point the carrier at the deployed agent with a `carrier` query parameter naming
|
|
1247
|
+
who is dialling:
|
|
1179
1248
|
|
|
1180
1249
|
```text
|
|
1181
1250
|
wss://<your-agent-url>/phone?carrier=twilio
|
|
@@ -1183,15 +1252,25 @@ wss://<your-agent-url>/phone?carrier=telnyx
|
|
|
1183
1252
|
```
|
|
1184
1253
|
|
|
1185
1254
|
Twilio and Telnyx are the two carriers this build decodes (`CARRIER_CODECS`);
|
|
1186
|
-
an unknown `carrier` is declined at the upgrade
|
|
1187
|
-
|
|
1255
|
+
an unknown `carrier` is declined at the upgrade with a `400`, and a real one
|
|
1256
|
+
this agent did not declare with a `404`. Both speak 8 kHz mu-law, which the
|
|
1257
|
+
bridge transcodes in both directions, so the agent, its tools and its slots
|
|
1188
1258
|
behave exactly as they do in the browser — a phone call is a transport, not a
|
|
1189
|
-
mode. Nothing about `agent.ts` changes to support one.
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1259
|
+
mode. Nothing else about `agent.ts` changes to support one.
|
|
1260
|
+
|
|
1261
|
+
**An agent that declares nothing answers no carrier**, which is a change from
|
|
1262
|
+
earlier releases: every voice agent used to serve both carriers' framing from
|
|
1263
|
+
the moment it booted, whether or not it had a phone number. `/phone` is the one
|
|
1264
|
+
door dialled from OUTSIDE your deployment, by a carrier following a number, so
|
|
1265
|
+
it is opened by a sentence in `agent.ts` rather than inherited. `aai dev` and a
|
|
1266
|
+
deployed sandbox honour the same declaration, so a call refused after a deploy
|
|
1267
|
+
is refused on your laptop too.
|
|
1268
|
+
|
|
1269
|
+
`telephony: false` is the same refusal stated out loud, and an operator can pass
|
|
1270
|
+
`telephony` to `createAgentServer` to override one deployment of an agent that
|
|
1271
|
+
does declare a carrier. If you are embedding the runtime yourself rather than
|
|
1272
|
+
deploying, the pieces are `createTelephonyBridge`, `startTelephonySession`,
|
|
1273
|
+
`TELEPHONY_PATH` and `carrierByName`, all on `@alexkroman1/aai-runtime`.
|
|
1195
1274
|
|
|
1196
1275
|
**Silence nudge (pipeline only):** set `silenceTimeoutMs` to make the
|
|
1197
1276
|
assistant proactively take a turn after that much user silence (e.g.
|
|
@@ -1268,12 +1347,12 @@ API keys require it; the US endpoints reject them. Example:
|
|
|
1268
1347
|
| Factory | SDK package | Env var |
|
|
1269
1348
|
| --------------- | ------------------- | ------------------------------ |
|
|
1270
1349
|
| `anthropicLlm` | `@ai-sdk/anthropic` | `ANTHROPIC_API_KEY` |
|
|
1271
|
-
| `
|
|
1350
|
+
| `openAILlm` | `@ai-sdk/openai` | `OPENAI_API_KEY` |
|
|
1272
1351
|
| `googleLlm` | `@ai-sdk/google` | `GOOGLE_GENERATIVE_AI_API_KEY` |
|
|
1273
1352
|
| `mistralLlm` | `@ai-sdk/mistral` | `MISTRAL_API_KEY` |
|
|
1274
|
-
| `
|
|
1353
|
+
| `xAILlm` | `@ai-sdk/xai` | `XAI_API_KEY` |
|
|
1275
1354
|
| `groqLlm` | `@ai-sdk/groq` | `GROQ_API_KEY` |
|
|
1276
|
-
| `
|
|
1355
|
+
| `openRouterLlm` | `@ai-sdk/openai` | `OPENROUTER_API_KEY` |
|
|
1277
1356
|
| `gatewayLlm` | `ai` (built in) | `AI_GATEWAY_API_KEY` |
|
|
1278
1357
|
| `assemblyAILlm` | `@ai-sdk/openai` | `ASSEMBLYAI_API_KEY` |
|
|
1279
1358
|
|
|
@@ -1283,10 +1362,10 @@ shared by all of them except `assemblyAILlm`. Example:
|
|
|
1283
1362
|
because a third-party vendor's catalog is not this SDK's to default from;
|
|
1284
1363
|
`assemblyAILlm()` is the one bare call, since it has a default model.
|
|
1285
1364
|
|
|
1286
|
-
`
|
|
1365
|
+
`openRouterLlm` routes through [OpenRouter](https://openrouter.ai) — an
|
|
1287
1366
|
OpenAI-compatible endpoint fronting hundreds of models addressed as
|
|
1288
1367
|
`"creator/model"`, e.g.
|
|
1289
|
-
`
|
|
1368
|
+
`openRouterLlm({ model: "meta-llama/llama-3.3-70b-instruct" })`. It needs
|
|
1290
1369
|
no extra SDK install (it reuses the `@ai-sdk/openai` client).
|
|
1291
1370
|
|
|
1292
1371
|
`gatewayLlm` routes through the [Vercel AI
|
|
@@ -1947,7 +2026,7 @@ Those three cover almost everything an agent wants. A database is for data that
|
|
|
1947
2026
|
must outlive a session AND be queryable: a ledger, filed records, cross-session
|
|
1948
2027
|
saves.
|
|
1949
2028
|
|
|
1950
|
-
## Custom UI — `
|
|
2029
|
+
## Custom UI — `mountClient()`
|
|
1951
2030
|
|
|
1952
2031
|
File: `client.tsx` alongside `agent.ts`. Uses **React** (not Preact).
|
|
1953
2032
|
Always import `"@alexkroman1/aai-ui/styles.css"` first.
|
|
@@ -1957,9 +2036,9 @@ Always import `"@alexkroman1/aai-ui/styles.css"` first.
|
|
|
1957
2036
|
```tsx
|
|
1958
2037
|
/// <reference types="vite/client" />
|
|
1959
2038
|
import "@alexkroman1/aai-ui/styles.css";
|
|
1960
|
-
import {
|
|
2039
|
+
import { mountClient } from "@alexkroman1/aai-ui";
|
|
1961
2040
|
|
|
1962
|
-
|
|
2041
|
+
mountClient({ name: "My Agent" });
|
|
1963
2042
|
```
|
|
1964
2043
|
|
|
1965
2044
|
### Tier 1 with sidebar
|
|
@@ -1967,7 +2046,7 @@ client({ name: "My Agent" });
|
|
|
1967
2046
|
```tsx
|
|
1968
2047
|
/// <reference types="vite/client" />
|
|
1969
2048
|
import "@alexkroman1/aai-ui/styles.css";
|
|
1970
|
-
import {
|
|
2049
|
+
import { mountClient, useEvent } from "@alexkroman1/aai-ui";
|
|
1971
2050
|
import { useState } from "react";
|
|
1972
2051
|
|
|
1973
2052
|
function Sidebar() {
|
|
@@ -1982,7 +2061,7 @@ function Sidebar() {
|
|
|
1982
2061
|
);
|
|
1983
2062
|
}
|
|
1984
2063
|
|
|
1985
|
-
|
|
2064
|
+
mountClient({ name: "My Agent", sidebar: Sidebar });
|
|
1986
2065
|
```
|
|
1987
2066
|
|
|
1988
2067
|
### Tier 2 — full custom component
|
|
@@ -1990,7 +2069,7 @@ client({ name: "My Agent", sidebar: Sidebar });
|
|
|
1990
2069
|
```tsx
|
|
1991
2070
|
/// <reference types="vite/client" />
|
|
1992
2071
|
import "@alexkroman1/aai-ui/styles.css";
|
|
1993
|
-
import {
|
|
2072
|
+
import { mountClient, useSession } from "@alexkroman1/aai-ui";
|
|
1994
2073
|
|
|
1995
2074
|
function MyApp() {
|
|
1996
2075
|
const { messages, userTranscript, started, running, start, toggle, end } =
|
|
@@ -2011,10 +2090,10 @@ function MyApp() {
|
|
|
2011
2090
|
);
|
|
2012
2091
|
}
|
|
2013
2092
|
|
|
2014
|
-
|
|
2093
|
+
mountClient({ component: MyApp });
|
|
2015
2094
|
```
|
|
2016
2095
|
|
|
2017
|
-
### `
|
|
2096
|
+
### `mountClient()` config
|
|
2018
2097
|
|
|
2019
2098
|
| Field | Type | Default | Description |
|
|
2020
2099
|
| --- | --- | --- | --- |
|
|
@@ -2172,7 +2251,7 @@ Property 'children' is missing` build error:
|
|
|
2172
2251
|
```tsx
|
|
2173
2252
|
/// <reference types="vite/client" />
|
|
2174
2253
|
import "@alexkroman1/aai-ui/styles.css";
|
|
2175
|
-
import { ChatView,
|
|
2254
|
+
import { ChatView, mountClient, StartScreen } from "@alexkroman1/aai-ui";
|
|
2176
2255
|
|
|
2177
2256
|
function PizzaApp() {
|
|
2178
2257
|
return (
|
|
@@ -2182,7 +2261,7 @@ function PizzaApp() {
|
|
|
2182
2261
|
);
|
|
2183
2262
|
}
|
|
2184
2263
|
|
|
2185
|
-
|
|
2264
|
+
mountClient({ component: PizzaApp });
|
|
2186
2265
|
```
|
|
2187
2266
|
|
|
2188
2267
|
## Styling
|
|
@@ -2190,7 +2269,7 @@ client({ component: PizzaApp });
|
|
|
2190
2269
|
- **Tailwind CSS v4** — compiled at bundle time, configured via CSS.
|
|
2191
2270
|
Do NOT create `tailwind.config.js` — it will be ignored.
|
|
2192
2271
|
- Use Tailwind classes for layout, `useTheme()` for dynamic colors.
|
|
2193
|
-
- Set theme: `
|
|
2272
|
+
- Set theme: `mountClient({ theme: { bg, primary, text, surface, border } })`.
|
|
2194
2273
|
- Override CSS custom properties for extra tokens:
|
|
2195
2274
|
`--color-aai-*`, `--radius-aai`, `--font-aai`.
|
|
2196
2275
|
- Always import `"@alexkroman1/aai-ui/styles.css"` at the top of `client.tsx`.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"scripts": {
|
|
8
8
|
"dev": "aai dev",
|
|
9
9
|
"prestart": "aai build --skip-tests",
|
|
10
|
-
"start": "
|
|
10
|
+
"start": "aai start",
|
|
11
11
|
"build": "aai build",
|
|
12
12
|
"test": "vitest run --exclude \"**/*.eval.test.*\"",
|
|
13
13
|
"test:agent": "aai test",
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"publish:agent": "aai publish"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@alexkroman1/aai": "^
|
|
19
|
-
"@alexkroman1/aai-
|
|
20
|
-
"@alexkroman1/aai-
|
|
18
|
+
"@alexkroman1/aai": "^15.0.0",
|
|
19
|
+
"@alexkroman1/aai-cli": "^15.0.0",
|
|
20
|
+
"@alexkroman1/aai-runtime": "^15.0.0",
|
|
21
|
+
"@alexkroman1/aai-ui": "^15.0.0",
|
|
21
22
|
"react": "^19.2.8",
|
|
22
23
|
"react-dom": "^19.2.8",
|
|
23
24
|
"tailwindcss": "^4.0.0",
|
|
@@ -25,9 +26,8 @@
|
|
|
25
26
|
"zod": "^4.5.4"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@alexkroman1/aai-cli": "^13.3.0",
|
|
29
29
|
"@tailwindcss/vite": "^4.3.3",
|
|
30
|
-
"@types/node": "^
|
|
30
|
+
"@types/node": "^24.10.1",
|
|
31
31
|
"@types/react": "^19.2.18",
|
|
32
32
|
"@types/react-dom": "^19.2.5",
|
|
33
33
|
"@vitejs/plugin-react": "^6.1.1",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ok, n as fail, t as CliError } from "./_output-
|
|
2
|
+
import { a as ok, n as fail, t as CliError } from "./_output-DBP9Op_d.mjs";
|
|
3
3
|
import { n as log, s as unwrapCancel } from "./_ui-DCt4qZrk.mjs";
|
|
4
|
-
import { f as checkedResponse, p as isStringArray } from "./_studio-
|
|
5
|
-
import { t as secretRequest } from "./_slug-api-
|
|
6
|
-
import { isRecord } from "@alexkroman1/aai/utils";
|
|
4
|
+
import { f as checkedResponse, p as isStringArray } from "./_studio-DnR_BqFp.mjs";
|
|
5
|
+
import { t as secretRequest } from "./_slug-api-CGvc2YSQ.mjs";
|
|
6
|
+
import { isRecord, plural } from "@alexkroman1/aai/utils";
|
|
7
7
|
import * as p from "@clack/prompts";
|
|
8
8
|
import pTimeout from "p-timeout";
|
|
9
9
|
//#region src/secret.ts
|
|
@@ -153,7 +153,7 @@ async function executeSecretList(cwd, server) {
|
|
|
153
153
|
const { vars } = checkedResponse(data, (value) => isRecord(value) && isStringArray(value.vars), `the secret list for ${target}`);
|
|
154
154
|
if (vars.length === 0) log.info("No secrets set. Use `aai secret put <name>` to add one.");
|
|
155
155
|
else {
|
|
156
|
-
log.message(`${vars.length}
|
|
156
|
+
log.message(`${vars.length} ${plural(vars.length, "secret")}:`);
|
|
157
157
|
for (const v of vars) log.message(` ${v}`);
|
|
158
158
|
}
|
|
159
159
|
return ok({ secrets: vars });
|
package/dist/secret.d.ts
CHANGED
|
@@ -38,10 +38,12 @@ export type SecretValueIo = {
|
|
|
38
38
|
* sitting at a terminal has no reason to send.
|
|
39
39
|
*/
|
|
40
40
|
export declare function resolveSecretValue(name: string, mode: OutputMode, io?: SecretValueIo): Promise<string | undefined>;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Both the put and the delete result — one shape, so one name. They were two
|
|
43
|
+
* distinct aliases for `{ name: string }`, which implied a difference that does
|
|
44
|
+
* not exist and left "which alias meant the secret result" to be re-decided.
|
|
45
|
+
*/
|
|
46
|
+
type SecretNameData = {
|
|
45
47
|
name: string;
|
|
46
48
|
};
|
|
47
49
|
type SecretListData = {
|
|
@@ -52,7 +54,7 @@ type SecretListData = {
|
|
|
52
54
|
* path). If not, prompt for it — masked — which is what
|
|
53
55
|
* {@link resolveSecretValue} returning `undefined` asks for.
|
|
54
56
|
*/
|
|
55
|
-
export declare function executeSecretPut(cwd: string, name: string, value: string | undefined, server: string | undefined): Promise<CommandResult<
|
|
56
|
-
export declare function executeSecretDelete(cwd: string, name: string, server: string | undefined): Promise<CommandResult<
|
|
57
|
+
export declare function executeSecretPut(cwd: string, name: string, value: string | undefined, server: string | undefined): Promise<CommandResult<SecretNameData>>;
|
|
58
|
+
export declare function executeSecretDelete(cwd: string, name: string, server: string | undefined): Promise<CommandResult<SecretNameData>>;
|
|
57
59
|
export declare function executeSecretList(cwd: string, server: string | undefined): Promise<CommandResult<SecretListData>>;
|
|
58
60
|
export {};
|