@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 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
@@ -0,0 +1,2 @@
1
+ Independently authored for Teal Brick. Uses the existing Teal Brick capability
2
+ packages; no upstream package implementation is copied. Eve compatibility 0.49.0.
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
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
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; });