@tealbrick/kit 0.1.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/BOOTSTRAP.md +252 -0
- package/LICENSE +21 -0
- package/NOTICE +2 -0
- package/README.md +91 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +97 -0
- package/dist/index.d.ts +926 -0
- package/dist/index.js +180 -0
- package/dist/onboarding.d.ts +32 -0
- package/dist/onboarding.js +105 -0
- package/dist/secrets.d.ts +3 -0
- package/dist/secrets.js +25 -0
- package/package.json +64 -0
package/BOOTSTRAP.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Bootstrap an Eve agent with Teal Brick
|
|
2
|
+
|
|
3
|
+
This guide installs the seven implemented packages through one kit and activates
|
|
4
|
+
only the capabilities you select. The supported harness line is **Eve 0.55.x**;
|
|
5
|
+
**0.55.0** and **AI SDK 7.0.93** are the current tested versions. Use Node **24**.
|
|
6
|
+
|
|
7
|
+
**Release status:** the npm installation in step 3 becomes available once
|
|
8
|
+
`@tealbrick/kit@0.1.0` is published. Until then, use the local-tarball alternative
|
|
9
|
+
below. Do not substitute an unrelated unscoped `tealbrick` npm package.
|
|
10
|
+
|
|
11
|
+
## 1. Install Node and npm
|
|
12
|
+
|
|
13
|
+
Install Node 24 using the [official Node.js installer or installation instructions](https://nodejs.org/en/download).
|
|
14
|
+
Then open a terminal and check:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node --version
|
|
18
|
+
npm --version
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The first command should report `v24.x`. Run the remaining commands as the account
|
|
22
|
+
that will own the new agent project. For our deployment this account runs on
|
|
23
|
+
Nucbox/Fedora N150. This package guide does not provision a VM or install AVMM.
|
|
24
|
+
|
|
25
|
+
## 2. Create a fresh Eve project
|
|
26
|
+
|
|
27
|
+
Choose an unused project directory, outside any existing live agent:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx --yes eve@0.55.0 init tealbrick-agent --model openai/gpt-5.6-terra
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Finish scaffolding and return to the terminal before continuing. If Eve starts
|
|
34
|
+
`eve dev` automatically, press Ctrl+C to stop it. Then run:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd tealbrick-agent
|
|
38
|
+
npm install --save-exact eve@0.55.0 ai@7.0.93
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Keep `package-lock.json` under version control.
|
|
42
|
+
The exact Eve pin is intentional: the compatibility workflow validates patches
|
|
43
|
+
before advancing it and will not cross into 0.56 automatically.
|
|
44
|
+
|
|
45
|
+
The example model uses the Vercel AI Gateway. To supply its key for this terminal
|
|
46
|
+
without putting the key in shell history, in Bash run:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
read -r -s -p 'AI Gateway API key: ' AI_GATEWAY_API_KEY
|
|
50
|
+
export AI_GATEWAY_API_KEY
|
|
51
|
+
printf '\n'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For an existing AVMM model broker, Codex subscription or direct model provider,
|
|
55
|
+
configure Eve's model through that provider's supported path instead. Teal Brick
|
|
56
|
+
Portal authentication and voice/vision keys do not authenticate the primary LLM.
|
|
57
|
+
Never copy a host's provider login files into a worker to make this step work.
|
|
58
|
+
|
|
59
|
+
## 3. Install the complete kit
|
|
60
|
+
|
|
61
|
+
**After npm publication:**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm install --save-exact @tealbrick/kit@0.1.0
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This installs Portal, AVM, Voice, Vision, Deliver and the shared provider transport
|
|
68
|
+
as dependencies. You do not install or select provider transport separately.
|
|
69
|
+
Installation alone exposes no Teal Brick tools or routes.
|
|
70
|
+
|
|
71
|
+
If the package is not yet available, perform the tarball installation below, then
|
|
72
|
+
continue with step 4. An npm 404 is not a reason to install a different package.
|
|
73
|
+
|
|
74
|
+
## 4. Run Teal Brick setup
|
|
75
|
+
|
|
76
|
+
From the new Eve project root:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx --no-install tealbrick setup
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This is the real CLI command: `tealbrick` belongs to the installed kit. There is
|
|
83
|
+
no `eve tealbrick setup` subcommand. `--no-install` ensures npm uses the local
|
|
84
|
+
binary rather than downloading a similarly named package.
|
|
85
|
+
|
|
86
|
+
Use Space to select capabilities, Enter to continue, and review the selection
|
|
87
|
+
before applying it. Voice, Vision, Deliver and AVM start unchecked. Portal sign-in
|
|
88
|
+
and its authenticated Eve channel are required by the interactive setup.
|
|
89
|
+
|
|
90
|
+
| Select | What setup asks for | What becomes available |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| Portal (required) | Issuer URL, browser sign-in, workspace, agent name and reachable agent origin | Authenticated Eve channel, owned agent registration and workspace card |
|
|
93
|
+
| Voice | Live voice, STT and/or TTS; endpoint URL, model, API token where needed, voice for synthesis/live | Only the configured voice routes |
|
|
94
|
+
| Vision | Endpoint protocol, URL, model and API token | Vision HTTP routes; native tool requires an additional trusted auth adapter |
|
|
95
|
+
| Deliver | Storage provider, bucket/target, credentials, link access and prefix | A `deliver` tool for sandbox files |
|
|
96
|
+
| AVM | Paired or operator transport, SSH target, key path, optional operator sudo | Inspection; mutations require separately configured exact grants |
|
|
97
|
+
|
|
98
|
+
### Portal
|
|
99
|
+
|
|
100
|
+
Setup shows a Portal verification URL and code. Open it in your browser, sign in
|
|
101
|
+
and approve the device request. Setup obtains your organization from the signed-in
|
|
102
|
+
account; you do not enter organization IDs or copy tokens.
|
|
103
|
+
|
|
104
|
+
Select an existing Portal workspace, enter the agent name and provide its origin
|
|
105
|
+
(e.g. `https://agent.example.com`). The URL must be reachable from your desktop;
|
|
106
|
+
it cannot contain credentials, query parameters or a path prefix. Create a workspace
|
|
107
|
+
in Portal first if your account has none. An existing agent name updates that owned
|
|
108
|
+
agent; use a distinct name for a different agent.
|
|
109
|
+
|
|
110
|
+
After the configuration is applied, setup registers the owned agent, adds or updates
|
|
111
|
+
its identity-bound canvas card, and verifies it appears in that workspace's desktop
|
|
112
|
+
agent directory. It preserves other cards and edges, retries canvas revision
|
|
113
|
+
conflicts, and does not create duplicate cards on a repeat setup with the same name.
|
|
114
|
+
Select that same workspace in desktop and refresh discovery if needed.
|
|
115
|
+
|
|
116
|
+
If registration or verification fails, setup exits unsuccessfully. Local settings
|
|
117
|
+
may already be applied and the remote agent may already exist. Retry with the same
|
|
118
|
+
name, issuer and workspace after resolving the error; do not assume the operation
|
|
119
|
+
was rolled back. Setup never automatically retries an uncertain registration write.
|
|
120
|
+
|
|
121
|
+
Portal currently stores the card's name, Eve harness, identity, agent URL and auth
|
|
122
|
+
method. Its API does not accept provider/model/voice/vision configuration metadata;
|
|
123
|
+
those settings remain in the local kit configuration. Raw keys are never uploaded.
|
|
124
|
+
Browser login/refresh tokens remain in memory only for setup.
|
|
125
|
+
|
|
126
|
+
If an existing `agent/channels/eve.ts` is already present, setup stops rather than
|
|
127
|
+
replacing its authentication. Review and deliberately integrate that existing
|
|
128
|
+
channel before retrying. A fresh project is the simplest first-run path.
|
|
129
|
+
|
|
130
|
+
### Voice and Vision
|
|
131
|
+
|
|
132
|
+
STT and TTS can use **different servers and separate API keys**. Their endpoints
|
|
133
|
+
must implement the supported `openai-audio-v1` contract. Live voice uses a
|
|
134
|
+
`live-json-v1` session endpoint; an arbitrary provider WebSocket URL is not a
|
|
135
|
+
drop-in replacement. A live-voice client still has to negotiate/play the session.
|
|
136
|
+
|
|
137
|
+
Vision supports OpenAI-compatible chat-completions or responses protocols. Start
|
|
138
|
+
with the HTTP channel. Enable the optional native vision tool only when you have
|
|
139
|
+
an existing trusted `agent/lib/...` module that supplies signed authorization for
|
|
140
|
+
the current turn. Static owner tokens are not an acceptable substitute.
|
|
141
|
+
|
|
142
|
+
### Document delivery with R2, S3 or a self-hosted bucket
|
|
143
|
+
|
|
144
|
+
Choose the provider first. For Cloudflare R2, prepare the bucket and enter its S3
|
|
145
|
+
API endpoint (`https://<account-id>.r2.cloudflarestorage.com`), bucket name and
|
|
146
|
+
access key pair when prompted. AWS S3 and S3-compatible services such as MinIO have
|
|
147
|
+
their own region/endpoint settings. Vercel Blob and an already-served directory
|
|
148
|
+
are also supported; Vercel Blob is not required.
|
|
149
|
+
|
|
150
|
+
Choose signed, expiring links where available, or public links deliberately.
|
|
151
|
+
A public bucket option needs a working public HTTPS base URL. Directory delivery
|
|
152
|
+
requires an existing writable directory and a separately configured HTTPS file
|
|
153
|
+
server. Setup does not create buckets, configure DNS or start a file server.
|
|
154
|
+
|
|
155
|
+
The resulting URL must be reachable by the intended desktop, mobile or Telegram
|
|
156
|
+
client. A successful upload does not make a private LAN URL reachable externally.
|
|
157
|
+
|
|
158
|
+
### AVM / AVMM
|
|
159
|
+
|
|
160
|
+
Skip this checkbox if the agent does not need AVM inspection. Installing the kit
|
|
161
|
+
does not install AVMM or grant VM administration.
|
|
162
|
+
|
|
163
|
+
For a paired connection use `agentvm-client@<resolvable-hostname>` and the path to
|
|
164
|
+
that paired user's dedicated SSH key. The host must already be enrolled and its
|
|
165
|
+
SSH host key trusted. AVMM binds the key to its user/workspace. For our host, the
|
|
166
|
+
hostname is `fedora-n150.taild2144d.ts.net`. Paired mode does not read SSH aliases.
|
|
167
|
+
Operator mode can use the configured `nucbox` alias and has that account's authority.
|
|
168
|
+
|
|
169
|
+
Named profiles and exact mutation grants can be supplied through a reviewed
|
|
170
|
+
configuration file using `npx --no-install tealbrick apply config.json`. Follow the
|
|
171
|
+
AVM package README; workspace labels do not replace authenticated identities.
|
|
172
|
+
|
|
173
|
+
## 5. Check and run
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npx --no-install tealbrick status
|
|
177
|
+
npx --no-install eve info --json
|
|
178
|
+
npx --no-install eve build
|
|
179
|
+
npx --no-install eve dev
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Check that Eve reports ready with no errors, and that only the selected Teal Brick
|
|
183
|
+
contributions appear. Eve's built-in tools are separate from the kit selection.
|
|
184
|
+
`eve build` proves compilation; it does not verify your provider keys or endpoints.
|
|
185
|
+
|
|
186
|
+
For a long-running deployment, stop development mode, build, then start the built
|
|
187
|
+
agent with a process manager under the project owner's account:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npx --no-install eve build
|
|
191
|
+
npx --no-install eve start --host 127.0.0.1 --port 2000
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Choose an unused port. Put authenticated ingress in front of it when remote access
|
|
195
|
+
is required. Portal registration is performed by setup; starting Eve does not enroll an AVMM host.
|
|
196
|
+
|
|
197
|
+
## 6. Confirm the selected capabilities
|
|
198
|
+
|
|
199
|
+
- Send one ordinary message and check that the configured primary model replies.
|
|
200
|
+
- Deliver a disposable sandbox document, open its URL from the intended client,
|
|
201
|
+
and check public/signed access and expiry.
|
|
202
|
+
- Exercise each selected voice endpoint separately, including separate STT/TTS
|
|
203
|
+
credentials. Check a live-voice session using its actual client.
|
|
204
|
+
- Send an authorized image-analysis request and verify unauthorized callers are denied.
|
|
205
|
+
- For AVM, begin with an allowed read. VM creation or lifecycle changes require an
|
|
206
|
+
explicit policy and their own acceptance checks.
|
|
207
|
+
|
|
208
|
+
These are your deployment checks. Our automated suite uses deterministic models,
|
|
209
|
+
fixture providers and disposable storage; it cannot prove your credentials work.
|
|
210
|
+
|
|
211
|
+
## Change or disable a capability
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
npx --no-install tealbrick setup
|
|
215
|
+
npx --no-install tealbrick status
|
|
216
|
+
npx --no-install eve build
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Restart the running Eve process after the rebuild. Deselecting a capability removes
|
|
220
|
+
its kit-owned mounts. Setup refuses to overwrite hand-edited mounts. Saved settings
|
|
221
|
+
and optional local secrets live under ignored `.tealbrick/`; secrets are not embedded
|
|
222
|
+
in generated source. Disabling a capability does not revoke or delete its credentials.
|
|
223
|
+
|
|
224
|
+
## Local-tarball installation before publication
|
|
225
|
+
|
|
226
|
+
You need read access to the private package repository. On a development/build
|
|
227
|
+
machine with Node 24:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
git clone https://github.com/Doppelabs/tealbrick-packages.git
|
|
231
|
+
cd tealbrick-packages
|
|
232
|
+
npm ci --ignore-scripts
|
|
233
|
+
npm run compatibility:validate
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
This produces verified `.tgz` files under `artifacts/packages/`. Copy all seven
|
|
237
|
+
files together to the deployment account on Nucbox. From the fresh Eve project
|
|
238
|
+
created in step 2, use the **absolute path** to that tarball directory:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
TEALBRICK_TARBALLS=/absolute/path/to/tarballs
|
|
242
|
+
for package in provider-transport portal avm voice vision deliver; do
|
|
243
|
+
npm pkg set "overrides.@tealbrick/$package=file:$TEALBRICK_TARBALLS/tealbrick-$package-0.1.0.tgz"
|
|
244
|
+
done
|
|
245
|
+
npm install --save-exact "$TEALBRICK_TARBALLS/tealbrick-kit-0.1.0.tgz"
|
|
246
|
+
npx --no-install tealbrick setup
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The overrides prevent npm from looking up unpublished internal dependencies.
|
|
250
|
+
Keep the tarballs available while using these local overrides. When migrating to
|
|
251
|
+
the public npm release, remove only these six Teal Brick override entries and
|
|
252
|
+
replace the kit's file dependency with `@tealbrick/kit@0.1.0`, then run `npm install`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tealbrick contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# @tealbrick/kit
|
|
2
|
+
|
|
3
|
+
One installation, explicitly selected capabilities. The kit includes the currently
|
|
4
|
+
implemented Portal, Voice, Vision, Deliver and AVM packages. Dependencies are code
|
|
5
|
+
availability, not agent permissions. Nothing is mounted by installing the kit.
|
|
6
|
+
|
|
7
|
+
Once published, the consumer workflow is:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @tealbrick/kit
|
|
11
|
+
npx --no-install tealbrick setup
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The package is currently local/unpublished. Install the locally packed suite
|
|
15
|
+
artifacts together until the npm scope is published. Eve 0.55.0 and Node 24 are the
|
|
16
|
+
validated host versions; VM provisioning and Eve installation remain host setup.
|
|
17
|
+
|
|
18
|
+
See [BOOTSTRAP.md](BOOTSTRAP.md) for the complete first-run guide, provider prompts, verification and pre-publication tarball installation.
|
|
19
|
+
|
|
20
|
+
## Activation
|
|
21
|
+
|
|
22
|
+
`tealbrick setup` presents unchecked capability choices for a fresh project. It
|
|
23
|
+
requires Portal device sign-in and workspace selection, then asks for optional capability settings. Review and apply the selection, then
|
|
24
|
+
rebuild/restart Eve. `tealbrick status` reports the saved selection and mount paths.
|
|
25
|
+
|
|
26
|
+
| Choice | Exposed only when selected |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Portal (required by setup) | Authenticated Eve channel and owned workspace agent card |
|
|
29
|
+
| Voice | Voice manifest/session/transcribe/speak routes |
|
|
30
|
+
| Vision | Vision manifest/analyze routes; optional native tool with trusted turn-auth module |
|
|
31
|
+
| Deliver | Root deliver tool |
|
|
32
|
+
| AVM | SSH inspection extension; no lifecycle mutation policy granted by setup |
|
|
33
|
+
|
|
34
|
+
Interactive setup always binds Portal identity; offline `apply` retains explicit configuration control.
|
|
35
|
+
Native Vision needs an existing module under `agent/lib/` default-exporting signed
|
|
36
|
+
current-turn authorization headers. Setup never substitutes an owner token.
|
|
37
|
+
Setup now registers and binds an agent card through existing Portal APIs and verifies
|
|
38
|
+
workspace desktop discovery. Provider metadata synchronization and full live-voice
|
|
39
|
+
client orchestration remain pending. The kit does not claim all planned Buzz/Knowledge/etc. work exists.
|
|
40
|
+
|
|
41
|
+
Deselecting a capability removes its kit-owned mounts. Unselected capabilities add
|
|
42
|
+
no tools, instructions, skills, hooks, channels, connections or schedules. Existing
|
|
43
|
+
Eve built-ins and separately installed extensions remain the host's responsibility.
|
|
44
|
+
The running process must be rebuilt/reloaded before removal takes effect there.
|
|
45
|
+
|
|
46
|
+
## Ownership and credentials
|
|
47
|
+
|
|
48
|
+
State lives in `.tealbrick/kit-state.json`. Generated mounts contain settings and
|
|
49
|
+
secret references only. Optional local credentials go to owner-only
|
|
50
|
+
`.tealbrick/kit.credentials.json`; `/.tealbrick/` is added to `.gitignore`.
|
|
51
|
+
Runtime environment values take precedence. Secrets are loaded lazily during
|
|
52
|
+
requests, never to discover/build disabled features. Deploy credentials using the
|
|
53
|
+
host's secret facility and keep the runtime working directory at the project root.
|
|
54
|
+
On Windows, configure account ACLs as well as the file permissions.
|
|
55
|
+
|
|
56
|
+
Activation refuses to overwrite existing or operator-edited mounts. In particular,
|
|
57
|
+
an existing `agent/channels/eve.ts` must be deliberately reconciled with Portal
|
|
58
|
+
before kit management can own it. It never silently replaces another auth setup.
|
|
59
|
+
Conflicting legacy standalone deliver mounts are likewise preserved. Deactivation
|
|
60
|
+
keeps saved credentials; remove/revoke unused credentials separately when desired.
|
|
61
|
+
A lock serializes kit operations; after a crashed operation inspect state/files
|
|
62
|
+
before manually removing a stale `.tealbrick/kit.lock`.
|
|
63
|
+
|
|
64
|
+
The internal `@tealbrick/provider-transport` is installed automatically through
|
|
65
|
+
Voice/Vision/Deliver. npm deduplicates compatible versions. It is never a setup
|
|
66
|
+
checkbox, running service or model-provider registry. The former unpublished
|
|
67
|
+
`provider-runtime` name has been replaced.
|
|
68
|
+
|
|
69
|
+
## Reproducible configuration
|
|
70
|
+
|
|
71
|
+
`tealbrick apply config.json` applies a reviewed config; secrets must already be
|
|
72
|
+
provided by runtime environment or the protected secret file. Empty config disables
|
|
73
|
+
all kit-owned contributions:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{"version":1}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Programmatic `planKit(config)` returns exactly which files would be mounted.
|
|
80
|
+
`applyKit(projectRoot, config, credentials?)` checks ownership before changes,
|
|
81
|
+
rolls back ordinary write failures and reports the required reload. No remote
|
|
82
|
+
writes, service restarts or provider calls occur on installation or activation.
|
|
83
|
+
|
|
84
|
+
Provider checks and native delivery-channel acceptance are separate. The terminal
|
|
85
|
+
wizard can configure delivery storage but does not provision buckets or web servers.
|
|
86
|
+
Tests validate empty/selected/deactivated discovery in a fresh packed Eve consumer,
|
|
87
|
+
including a single deduplicated provider-transport installation.
|
|
88
|
+
|
|
89
|
+
## AVMM profiles
|
|
90
|
+
|
|
91
|
+
The `avm` selection accepts the [AVM package connection/policy schema](../avm/README.md): either `{target,sudo}` or `{selectedProfile,profiles}`. Setup can select a saved profile and preserves its grants. New connections can use paired AVMM users or operator SSH. Paired mode requires a dedicated SSH identity path and a resolvable hostname; no credentials are copied. Use `tealbrick apply config.json` for full workspace, ownership, sharing, pool and ingress grants. Disabling AVM removes its entire mount.
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { checkbox, input, password, select, confirm } from '@inquirer/prompts';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { loginPortal, registerPortalCard, portalOrigin, agentOrigin } from './onboarding.js';
|
|
5
|
+
import { collectSetup } from '@tealbrick/deliver/setup';
|
|
6
|
+
import { applyKit, planKit, readKit } from './index.js';
|
|
7
|
+
async function main() {
|
|
8
|
+
const command = process.argv[2], root = process.cwd();
|
|
9
|
+
if (command === 'status') {
|
|
10
|
+
const p = planKit(await readKit(root));
|
|
11
|
+
console.log(JSON.stringify({ enabled: p.enabled, mounts: Object.keys(p.files) }, null, 2));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (command === 'apply') {
|
|
15
|
+
const path = process.argv[3];
|
|
16
|
+
if (!path)
|
|
17
|
+
throw Error('kit_config_file_required');
|
|
18
|
+
console.log(JSON.stringify(await applyKit(root, JSON.parse(await readFile(path, 'utf8'))), null, 2));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (command !== 'setup') {
|
|
22
|
+
console.log('Usage: tealbrick setup | status | apply <config.json>\nInstalled dependencies expose nothing until activated. Rebuild/restart Eve after changing selection.');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log('Setup requires Portal sign-in and saves an agent card in your chosen workspace. Other capabilities are optional.');
|
|
26
|
+
const old = await readKit(root);
|
|
27
|
+
const selected = await checkbox({ message: 'Activate capabilities (Space to select; everything else stays unmounted)', choices: [
|
|
28
|
+
{ name: 'Voice: live-session / STT / TTS endpoints', value: 'voice', checked: !!old.voice },
|
|
29
|
+
{ name: 'Vision API (native tool requires a trusted turn-auth adapter)', value: 'vision', checked: !!old.vision },
|
|
30
|
+
{ name: 'Deliver files to chat', value: 'deliver', checked: old.deliver !== undefined },
|
|
31
|
+
{ name: 'AVM inspection over SSH', value: 'avm', checked: !!old.avm },
|
|
32
|
+
] });
|
|
33
|
+
const config = { version: 1 }, credentials = {};
|
|
34
|
+
const issuer = portalOrigin(await input({ message: 'Portal issuer URL', default: old.portal?.issuer ?? 'https://portal.tealbrick.com' }));
|
|
35
|
+
const login = await loginPortal(issuer, (url, code) => console.log(`Sign in and approve this setup in your browser: ${url}\nVerification code: ${code}`));
|
|
36
|
+
if (!login.workspaces.length)
|
|
37
|
+
throw Error('kit_portal_create_workspace_then_retry');
|
|
38
|
+
const workspaceId = await select({ message: 'Portal workspace for this agent card', choices: login.workspaces.map(w => ({ name: w.name, value: w.id })) });
|
|
39
|
+
const name = (await input({ message: 'Agent name (unique in your organization)', default: old.portal?.agent })).trim();
|
|
40
|
+
const url = agentOrigin(await input({ message: 'Agent origin reachable from your desktop (https://agent.example.com)' }));
|
|
41
|
+
config.portal = { issuer, org: login.org, agent: name };
|
|
42
|
+
async function endpoint(label, protocol, spoken = false) {
|
|
43
|
+
const url = await input({ message: `${label} endpoint URL` }), model = await input({ message: `${label} model` });
|
|
44
|
+
const anonymous = await confirm({ message: `${label}: endpoint needs no API token?`, default: false });
|
|
45
|
+
const credentialRef = `TEALBRICK_${label.toUpperCase().replace(/[^A-Z0-9]/g, '_')}_TOKEN`;
|
|
46
|
+
if (!anonymous) {
|
|
47
|
+
const value = await password({ message: `${label} API token (blank to use existing runtime secret ${credentialRef})`, mask: '*' });
|
|
48
|
+
if (value)
|
|
49
|
+
credentials[credentialRef] = value;
|
|
50
|
+
}
|
|
51
|
+
return { url, model, protocol, ...(!anonymous ? { credentialRef } : {}), ...(spoken ? { voice: await input({ message: `${label} voice` }) } : {}) };
|
|
52
|
+
}
|
|
53
|
+
if (selected.includes('voice')) {
|
|
54
|
+
const modes = await checkbox({ message: 'Voice capabilities', choices: [{ name: 'Live voice (live-json-v1 session API)', value: 'realtime' }, { name: 'Speech to text', value: 'transcription' }, { name: 'Text to speech', value: 'synthesis' }] });
|
|
55
|
+
if (!modes.length)
|
|
56
|
+
throw Error('kit_select_voice_mode');
|
|
57
|
+
const settings = { version: 1, enabled: true, displayName: 'Voice' };
|
|
58
|
+
for (const mode of modes)
|
|
59
|
+
settings[mode] = await endpoint(mode, mode === 'realtime' ? 'live-json-v1' : 'openai-audio-v1', mode !== 'transcription');
|
|
60
|
+
config.voice = { settings };
|
|
61
|
+
}
|
|
62
|
+
if (selected.includes('vision')) {
|
|
63
|
+
const protocol = await select({ message: 'Vision API protocol', choices: ['openai-chat-completions', 'openai-responses'] });
|
|
64
|
+
config.vision = { settings: { version: 1, enabled: true, displayName: 'Vision', endpoint: await endpoint('vision', protocol) } };
|
|
65
|
+
if (await confirm({ message: 'Also expose the native Vision tool? Requires an existing trusted turn-auth module.', default: false }))
|
|
66
|
+
config.vision.authorizationModule = await input({ message: 'Module exporting getAuthorization(context), under agent/lib/ (no static owner token)' });
|
|
67
|
+
}
|
|
68
|
+
if (selected.includes('deliver')) {
|
|
69
|
+
const result = await collectSetup({ select: (message, choices) => select({ message, choices }), input: (message, value) => input({ message, default: value }), password: message => password({ message, mask: '*' }), confirm: message => confirm({ message, default: false }) });
|
|
70
|
+
config.deliver = result.config;
|
|
71
|
+
Object.assign(credentials, result.credentials);
|
|
72
|
+
}
|
|
73
|
+
if (selected.includes('avm')) {
|
|
74
|
+
if (old.avm && 'profiles' in old.avm) {
|
|
75
|
+
const selectedProfile = await select({ message: 'AVM connection profile (paired identity and grants stay bound to this profile)', choices: Object.keys(old.avm.profiles), default: old.avm.selectedProfile });
|
|
76
|
+
config.avm = { ...old.avm, selectedProfile };
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const previous = old.avm;
|
|
80
|
+
const mode = await select({ message: 'AVM SSH transport', choices: [{ name: 'Paired AVMM user (workspace isolation)', value: 'paired' }, { name: 'Operator SSH account (host administration)', value: 'operator' }], default: previous?.mode ?? 'paired' });
|
|
81
|
+
const target = await input({ message: mode === 'paired' ? 'AVMM paired target (agentvm-client@hostname)' : 'SSH target for AVM', default: previous?.target });
|
|
82
|
+
const identityFile = await input({ message: 'Absolute path to SSH identity file (required for paired user)', default: previous?.identityFile });
|
|
83
|
+
const sudo = mode === 'operator' && await confirm({ message: 'Use sudo -n on that host?', default: previous?.sudo ?? false });
|
|
84
|
+
config.avm = { ...previous, target, mode, sudo, ...(identityFile ? { identityFile } : {}) };
|
|
85
|
+
if (mode === 'paired')
|
|
86
|
+
delete config.avm.identityTokenFile;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
console.log(JSON.stringify({ enabled: planKit(config).enabled, mounts: Object.keys(planKit(config).files) }, null, 2));
|
|
90
|
+
if (!await confirm({ message: 'Apply settings and register this agent in the selected Portal workspace? Rebuild/restart Eve afterward.', default: false }))
|
|
91
|
+
return;
|
|
92
|
+
console.log(JSON.stringify(await applyKit(root, config, credentials), null, 2));
|
|
93
|
+
console.log(JSON.stringify(await registerPortalCard(login, { workspaceId, name, url }), null, 2));
|
|
94
|
+
console.log('Portal agent card saved and confirmed in workspace discovery. Rebuild/restart Eve to connect.');
|
|
95
|
+
console.log('Local credentials stay in .tealbrick/kit.credentials.json (owner-only). Supply them as runtime secrets when deploying. Provider connectivity has not been tested.');
|
|
96
|
+
}
|
|
97
|
+
main().catch(error => { const message = error instanceof Error ? error.message : ''; console.error(/^kit_[a-z_]+(?::agent\/[a-zA-Z0-9_./-]+)?$/.test(message) ? message : 'Kit setup failed; check configuration and permissions. Credentials omitted.'); process.exitCode = 1; });
|