@voicethere/cli 0.1.0 → 0.2.2

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.
Files changed (56) hide show
  1. package/README.md +105 -50
  2. package/dist/cli.js +41 -30
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/build/list.d.ts +3 -2
  5. package/dist/commands/build/list.d.ts.map +1 -1
  6. package/dist/commands/build/list.js +12 -7
  7. package/dist/commands/build/list.js.map +1 -1
  8. package/dist/commands/build/promote.d.ts +1 -2
  9. package/dist/commands/build/promote.d.ts.map +1 -1
  10. package/dist/commands/build/promote.js +48 -7
  11. package/dist/commands/build/promote.js.map +1 -1
  12. package/dist/commands/build/upload.d.ts +0 -1
  13. package/dist/commands/build/upload.d.ts.map +1 -1
  14. package/dist/commands/build/upload.js +18 -5
  15. package/dist/commands/build/upload.js.map +1 -1
  16. package/dist/commands/build/validate.d.ts +2 -0
  17. package/dist/commands/build/validate.d.ts.map +1 -1
  18. package/dist/commands/build/validate.js +11 -14
  19. package/dist/commands/build/validate.js.map +1 -1
  20. package/dist/commands/login.d.ts.map +1 -1
  21. package/dist/commands/login.js +7 -2
  22. package/dist/commands/login.js.map +1 -1
  23. package/dist/commands/projects/create.d.ts.map +1 -1
  24. package/dist/commands/projects/create.js +7 -2
  25. package/dist/commands/projects/create.js.map +1 -1
  26. package/dist/commands/projects/delete.d.ts +6 -0
  27. package/dist/commands/projects/delete.d.ts.map +1 -0
  28. package/dist/commands/projects/delete.js +39 -0
  29. package/dist/commands/projects/delete.js.map +1 -0
  30. package/dist/commands/projects/list.d.ts.map +1 -1
  31. package/dist/commands/projects/list.js +3 -0
  32. package/dist/commands/projects/list.js.map +1 -1
  33. package/dist/commands/projects/show.d.ts.map +1 -1
  34. package/dist/commands/projects/show.js +3 -1
  35. package/dist/commands/projects/show.js.map +1 -1
  36. package/dist/commands/projects/use.d.ts +2 -1
  37. package/dist/commands/projects/use.d.ts.map +1 -1
  38. package/dist/commands/projects/use.js +70 -10
  39. package/dist/commands/projects/use.js.map +1 -1
  40. package/dist/lib/api.d.ts +4 -0
  41. package/dist/lib/api.d.ts.map +1 -1
  42. package/dist/lib/api.js +21 -0
  43. package/dist/lib/api.js.map +1 -1
  44. package/dist/lib/command-log.d.ts +19 -0
  45. package/dist/lib/command-log.d.ts.map +1 -0
  46. package/dist/lib/command-log.js +60 -0
  47. package/dist/lib/command-log.js.map +1 -0
  48. package/dist/lib/project-config.d.ts +26 -4
  49. package/dist/lib/project-config.d.ts.map +1 -1
  50. package/dist/lib/project-config.js +49 -17
  51. package/dist/lib/project-config.js.map +1 -1
  52. package/dist/lib/prompt.d.ts +9 -0
  53. package/dist/lib/prompt.d.ts.map +1 -0
  54. package/dist/lib/prompt.js +49 -0
  55. package/dist/lib/prompt.js.map +1 -0
  56. package/package.json +1 -1
package/README.md CHANGED
@@ -18,6 +18,29 @@ Or run without a global install:
18
18
  npx @voicethere/cli <command>
19
19
  ```
20
20
 
21
+ ## Debugging
22
+
23
+ Commands print resolved paths on **stderr** at startup:
24
+
25
+ ```text
26
+ [voicethere] project: 550e8400-… (project config (/path/.voicethere/config.json))
27
+ [voicethere] bundle: /path/to/dist/agent.js (project config (/path/.voicethere/config.json))
28
+ ```
29
+
30
+ Use this when a command fails to confirm which project and bundle file were picked up.
31
+
32
+ ## Project selection
33
+
34
+ The CLI remembers the **active project** in **`.voicethere/config.json`** (safe to commit — no API keys).
35
+
36
+ | Situation | What happens |
37
+ | --------- | -------------- |
38
+ | Config file present | `build upload`, `build list`, `build promote` use its `project_id` automatically |
39
+ | No config, interactive terminal | `projects use` shows a numbered project picker |
40
+ | No config, CI / script | Run `voicethere projects use <projectId>` once (or commit config from `projects create`) |
41
+
42
+ You do **not** need to run `projects use` on every command when the config file is already in the repo.
43
+
21
44
  ## Typical workflow
22
45
 
23
46
  ### 1. One-time login (per machine)
@@ -32,7 +55,7 @@ voicethere login --api-key "$VOICETHERE_API_KEY" --api-base http://localhost:300
32
55
 
33
56
  Default API base: `https://app.voicethere.dev/api/v1`
34
57
 
35
- ### 2. New agent repo — create project and link via git
58
+ ### 2. New agent repo — create project and commit config
36
59
 
37
60
  From your agent project root (where you build `dist/agent.js`):
38
61
 
@@ -40,37 +63,34 @@ From your agent project root (where you build `dist/agent.js`):
40
63
  npm install @voicethere/agent
41
64
  npx @voicethere/agent build
42
65
 
43
- # Creates the cloud project and writes .voicethere/config.json
44
- voicethere projects create --name "My Voice Agent"
66
+ # Creates the cloud project and uses it (.voicethere/config.json)
67
+ voicethere projects create "My Voice Agent"
45
68
 
46
69
  git add .voicethere/config.json
47
- git commit -m "chore: link VoiceThere project"
70
+ git commit -m "chore: use VoiceThere project"
48
71
  ```
49
72
 
50
- `.voicethere/config.json` holds the **project id** and default **bundle** path. Commit it so teammates and CI use the same project without passing `--project` every time.
51
-
52
73
  ### 3. Upload a build (store artifact)
53
74
 
54
75
  Upload **stores** a new immutable build in history — it does **not** go live yet.
55
76
 
56
77
  ```bash
57
- voicethere build validate # optional but recommended
78
+ voicethere build validate # optional; uses config bundle or dist/agent.js
58
79
  voicethere build upload -m "Add Spanish greeting and fix barge-in"
59
80
  ```
60
81
 
61
82
  `-m` / `--message` is like a git commit message: a short label so you can tell builds apart in `build list` and the dashboard.
62
83
 
63
- `build upload` reads `project_id` and `bundle` from `.voicethere/config.json` when flags are omitted.
64
-
65
84
  ### 4. Promote a build (set active in control plane)
66
85
 
67
86
  **Promote** sets the **active** build in the VoiceThere control plane. It does **not** roll out to cloud runners yet — use **`voicethere deploy`** when that command ships.
68
87
 
69
- Pass the build UUID from **`build list`** or from the **`build upload`** output:
88
+ Pass the build UUID from **`build upload`** or **`build list`**, or omit it in an interactive terminal to pick from a list:
70
89
 
71
90
  ```bash
72
91
  voicethere build list
73
92
  voicethere build promote <build-uuid>
93
+ # interactive: voicethere build promote
74
94
  ```
75
95
 
76
96
  Typical release loop:
@@ -94,19 +114,19 @@ voicethere build list
94
114
  voicethere build promote <build-uuid>
95
115
  ```
96
116
 
97
- No `projects create` needed — the linked project travels with the repo.
98
-
99
- ### 6. Link an existing cloud project (no create)
117
+ No `projects use` needed — the active project travels with the repo.
100
118
 
101
- If the project already exists in the dashboard:
119
+ ### 6. Use a different cloud project
102
120
 
103
121
  ```bash
104
122
  voicethere projects list
105
- voicethere projects use --project <uuid> --slug my-agent --bundle dist/agent.js
106
- git add .voicethere/config.json && git commit -m "chore: link VoiceThere project"
123
+ voicethere projects use <uuid> --slug my-agent --bundle dist/agent.js
124
+ git add .voicethere/config.json && git commit -m "chore: use VoiceThere project"
107
125
  ```
108
126
 
109
- Inspect the link anytime:
127
+ Re-run `voicethere projects use` with no args to confirm the current project (reads existing config).
128
+
129
+ Inspect the selection anytime:
110
130
 
111
131
  ```bash
112
132
  voicethere projects show
@@ -114,18 +134,33 @@ voicethere projects show
114
134
 
115
135
  ### 7. CI / automation
116
136
 
117
- - **Credentials:** inject `VOICETHERE_API_KEY` and run `voicethere login` (or set `VOICETHERE_CREDENTIALS_PATH` in tests).
118
- - **Project:** rely on committed `.voicethere/config.json` — no `--project` in the pipeline.
119
- - **Override config path:** `VOICETHERE_PROJECT_CONFIG=/path/to/config.json`
137
+ **With committed `.voicethere/config.json`** (typical agent repo):
120
138
 
121
139
  ```bash
122
140
  voicethere login --api-key "$VOICETHERE_API_KEY"
123
141
  npx @voicethere/agent build
124
142
  voicethere build upload -m "$GITHUB_SHA — $GITHUB_REF_NAME" --skip-validate
125
- voicethere build promote <build-uuid>
143
+ voicethere build promote <build-uuid-from-upload>
144
+ ```
145
+
146
+ No `projects use` step — the config file is the active project.
147
+
148
+ **Without a config file** (one-off job cwd):
149
+
150
+ ```bash
151
+ voicethere login --api-key "$VOICETHERE_API_KEY"
152
+ voicethere projects use <project-uuid>
153
+ npx @voicethere/agent build
154
+ voicethere build upload --skip-validate
155
+ voicethere build promote <build-uuid-from-upload>
126
156
  ```
127
157
 
128
- Split upload and promote in separate jobs if you want a human approval gate between them.
158
+ Other CI notes:
159
+
160
+ - **Credentials:** `VOICETHERE_CREDENTIALS_PATH` for isolated test runs
161
+ - **Config override:** `VOICETHERE_PROJECT_CONFIG=/path/to/config.json`
162
+
163
+ Split upload and promote across jobs if you want a human approval gate between them.
129
164
 
130
165
  ### 8. `deploy` (coming soon)
131
166
 
@@ -133,41 +168,61 @@ Split upload and promote in separate jobs if you want a human approval gate betw
133
168
 
134
169
  ## Repo config (version control)
135
170
 
136
- Per-agent-repo link file: **`.voicethere/config.json`** (safe to commit — no API keys).
171
+ Per-agent-repo file: **`.voicethere/config.json`**
137
172
 
138
- | Field | Purpose |
139
- | ---------------------- | ---------------------------------------------------------- |
140
- | `project_id` | Platform project UUID — used as default for `build upload` |
141
- | `project_slug`, `name` | Human-readable metadata (optional) |
142
- | `bundle` | Default bundle path (default `dist/agent.js`) |
143
-
144
- ```bash
145
- # Link an existing cloud project
146
- voicethere projects use --project <uuid> --slug my-agent --bundle dist/agent.js
147
-
148
- # Override path for tests
149
- export VOICETHERE_PROJECT_CONFIG=/path/to/config.json
150
- ```
173
+ | Field | Purpose |
174
+ | ---------------------- | ---------------------------------------------------- |
175
+ | `project_id` | Active platform project UUID |
176
+ | `project_slug`, `name` | Human-readable metadata (optional) |
177
+ | `bundle` | Default bundle path (default `dist/agent.js`) |
151
178
 
152
- **Secrets stay global:** `~/.config/voicethere/credentials.json` (from `voicethere login`).
153
- Optional gitignored overrides: `.voicethere/local.json` (reserved for future use).
179
+ **Secrets stay global:** `~/.config/voicethere/credentials.json` (from `voicethere login`).
154
180
 
155
181
  Example: [`.voicethere/config.json.example`](./.voicethere/config.json.example)
156
182
 
157
183
  ## Commands
158
184
 
159
- | Command | Description |
160
- | ----------------------------------------------------- | -------------------------------------------------------- |
161
- | `login --api-key <key> [--api-base <url>]` | Save credentials |
162
- | `projects list` | List org projects |
163
- | `projects create --name <name> [--slug <slug>]` | Create project; writes `.voicethere/config.json` |
164
- | `projects use --project <id>` | Link repo to existing project |
165
- | `projects show` | Print linked `.voicethere/config.json` |
166
- | `build list [--project <id>]` | Uploaded builds: id, time, message, active flag |
167
- | `build validate [--file dist/agent.js]` | Run `@voicethere/agent verify --no-build --bundle` |
168
- | `build upload [-m <msg>] [--project <id>] [--file]` | Store build in history (does not promote) |
169
- | `build promote <buildId> [--project <id>]` | Set active build in the control plane |
170
- | `deploy` | **Coming soon** promote + cloud rollout + wait |
185
+ | Command | Description |
186
+ | ---------------------------------------------- | -------------------------------------------------------- |
187
+ | `login --api-key <key> [--api-base <url>]` | Save credentials |
188
+ | `projects list` | List org projects |
189
+ | `projects create <name> [--slug <slug>]` | Create project; uses it (writes config) |
190
+ | `projects use [projectId]` | Use project (picker or existing config when omitted) |
191
+ | `projects show` | Print `.voicethere/config.json` |
192
+ | `projects delete [projectId] [--force]` | Delete project + builds (type name to confirm, or `--force`) |
193
+ | `build list` | Builds for the active project |
194
+ | `build validate [file]` | Sandbox verify (default bundle from config) |
195
+ | `build upload [file] [-m <msg>]` | Upload to active project |
196
+ | `build promote [buildId]` | Promote on active project (picker when omitted in TTY) |
197
+ | `deploy` | **Coming soon** — promote + cloud rollout + wait |
198
+
199
+ ## Logging
200
+
201
+ Progress and resolved paths go to **stderr** as `[voicethere] …` so **stdout** stays clean for JSON/tables (scripts can pipe stdout).
202
+
203
+ | Mode | Flag / env | What you get |
204
+ | ---- | ---------- | ------------ |
205
+ | **Default** | *(always on)* | High-level steps: “Creating project…”, “Uploading bundle…”, resolved project/bundle paths |
206
+ | **Verbose** | `-v` / `--verbose` or `VOICETHERE_VERBOSE=1` | API method + path, request bodies (no secrets), response status + timing, counts |
207
+
208
+ Examples:
209
+
210
+ ```bash
211
+ voicethere build upload
212
+ # stderr: [voicethere] Uploading agent bundle
213
+ # [voicethere] project: …
214
+ # [voicethere] bundle: …
215
+ # [voicethere] Validating bundle locally before upload
216
+ # [voicethere] Running @voicethere/agent verify on bundle
217
+ # [voicethere] Uploading bundle to control plane API
218
+
219
+ voicethere -v build upload
220
+ # …plus [voicethere:verbose] api: https://…
221
+ # [voicethere:verbose] POST /projects/…/builds
222
+ # [voicethere:verbose] response: 201 (842ms)
223
+ ```
224
+
225
+ Global `-v` works on any subcommand: `voicethere -v projects list`.
171
226
 
172
227
  ## Development
173
228
 
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { Command } from "commander";
3
3
  import { runLogin } from "./commands/login.js";
4
4
  import { runProjectsCreate } from "./commands/projects/create.js";
5
+ import { runProjectsDelete } from "./commands/projects/delete.js";
5
6
  import { runProjectsList } from "./commands/projects/list.js";
6
7
  import { runProjectsShow } from "./commands/projects/show.js";
7
8
  import { runProjectsUse } from "./commands/projects/use.js";
@@ -10,13 +11,19 @@ import { runBuildList } from "./commands/build/list.js";
10
11
  import { runBuildUpload } from "./commands/build/upload.js";
11
12
  import { runBuildValidate } from "./commands/build/validate.js";
12
13
  import { runDeployReserved } from "./commands/deploy.js";
14
+ import { configureLogging } from "./lib/command-log.js";
13
15
  import { DEFAULT_API_BASE } from "./lib/config.js";
14
16
  async function main() {
17
+ configureLogging();
15
18
  const program = new Command();
16
19
  program
17
20
  .name("voicethere")
18
21
  .description("VoiceThere cloud CLI")
19
- .version("0.1.0");
22
+ .version("0.2.2")
23
+ .option("-v, --verbose", "Detailed logs on stderr (API calls, timings)")
24
+ .hook("preAction", (_thisCommand, actionCommand) => {
25
+ configureLogging({ verbose: actionCommand.optsWithGlobals().verbose });
26
+ });
20
27
  program
21
28
  .command("login")
22
29
  .description("Store API key and API base URL")
@@ -40,13 +47,13 @@ async function main() {
40
47
  projects
41
48
  .command("create")
42
49
  .description("Create a new project")
43
- .requiredOption("--name <name>", "Project display name")
50
+ .argument("<name>", "Project display name")
44
51
  .option("--slug <slug>", "URL-safe slug (derived from name when omitted)")
45
52
  .option("--no-link", "Do not write .voicethere/config.json in the current repo")
46
53
  .option("--bundle <path>", "Default bundle path stored in .voicethere/config.json", "dist/agent.js")
47
- .action(async (options) => {
54
+ .action(async (name, options) => {
48
55
  await runProjectsCreate({
49
- name: options.name,
56
+ name,
50
57
  slug: options.slug,
51
58
  link: !options.noLink,
52
59
  bundle: options.bundle,
@@ -54,14 +61,14 @@ async function main() {
54
61
  });
55
62
  projects
56
63
  .command("use")
57
- .description("Link this repo to a platform project (.voicethere/config.json)")
58
- .requiredOption("--project <id>", "Project UUID")
59
- .option("--slug <slug>", "Project slug (metadata only)")
60
- .option("--name <name>", "Project display name (metadata only)")
64
+ .description("Use a project for this repo (.voicethere/config.json)")
65
+ .argument("[projectId]", "Project UUID (interactive picker when omitted in a TTY)")
66
+ .option("--slug <slug>", "Override project slug in local config")
67
+ .option("--name <name>", "Override display name in local config")
61
68
  .option("--bundle <path>", "Default bundle path", "dist/agent.js")
62
- .action(async (options) => {
69
+ .action(async (projectId, options) => {
63
70
  await runProjectsUse({
64
- project: options.project,
71
+ projectId,
65
72
  slug: options.slug,
66
73
  name: options.name,
67
74
  bundle: options.bundle,
@@ -69,36 +76,44 @@ async function main() {
69
76
  });
70
77
  projects
71
78
  .command("show")
72
- .description("Show linked .voicethere/config.json for this repo")
79
+ .description("Show the active project (.voicethere/config.json)")
73
80
  .action(async () => {
74
81
  await runProjectsShow();
75
82
  });
83
+ projects
84
+ .command("delete")
85
+ .description("Delete a project and all its builds")
86
+ .argument("[projectId]", "Project UUID (default: active project from .voicethere/config.json)")
87
+ .option("--force", "Skip interactive name confirmation")
88
+ .action(async (projectId, options) => {
89
+ await runProjectsDelete({
90
+ projectId,
91
+ force: options.force,
92
+ });
93
+ });
76
94
  const build = program.command("build").description("Agent bundle operations");
77
95
  build
78
96
  .command("validate")
79
97
  .description("Run @voicethere/agent sandbox verify on a bundle")
80
- .option("--file <path>", "Bundle path (default: config bundle or dist/agent.js)")
81
- .action(async (options) => {
82
- await runBuildValidate({ file: options.file });
98
+ .argument("[file]", "Bundle path (default: config bundle or dist/agent.js)")
99
+ .action(async (file) => {
100
+ await runBuildValidate({ file });
83
101
  });
84
102
  build
85
103
  .command("list")
86
- .description("List uploaded builds (newest first)")
87
- .option("--project <id>", "Project UUID (default: .voicethere/config.json project_id)")
88
- .action(async (options) => {
89
- await runBuildList({ project: options.project });
104
+ .description("List uploaded builds for the active project (newest first)")
105
+ .action(async () => {
106
+ await runBuildList();
90
107
  });
91
108
  build
92
109
  .command("upload")
93
110
  .description("Validate (unless skipped) and upload a bundle")
94
- .option("--project <id>", "Project UUID (default: .voicethere/config.json project_id)")
95
- .option("--file <path>", "Bundle path (default: config bundle or dist/agent.js)")
111
+ .argument("[file]", "Bundle path (default: config bundle or dist/agent.js)")
96
112
  .option("-m, --message <text>", "Build label (like a git commit message)")
97
113
  .option("--skip-validate", "Upload without local sandbox verify")
98
- .action(async (options) => {
114
+ .action(async (file, options) => {
99
115
  await runBuildUpload({
100
- project: options.project,
101
- file: options.file,
116
+ file,
102
117
  message: options.message,
103
118
  skipValidate: options.skipValidate,
104
119
  });
@@ -106,13 +121,9 @@ async function main() {
106
121
  build
107
122
  .command("promote")
108
123
  .description("Set active build in the control plane (platform promote API; no cluster rollout)")
109
- .argument("<buildId>", "Build UUID to promote (from build list or upload output)")
110
- .option("--project <id>", "Project UUID (default: .voicethere/config.json project_id)")
111
- .action(async (buildId, options) => {
112
- await runBuildPromote({
113
- project: options.project,
114
- buildId,
115
- });
124
+ .argument("[buildId]", "Build UUID (interactive picker when omitted in a TTY)")
125
+ .action(async (buildId) => {
126
+ await runBuildPromote({ buildId });
116
127
  });
117
128
  program
118
129
  .command("deploy")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export interface BuildListOptions {
2
- project?: string;
2
+ /** Reserved for tests. */
3
+ startDir?: string;
3
4
  }
4
- export declare function runBuildList(options: BuildListOptions): Promise<void>;
5
+ export declare function runBuildList(options?: BuildListOptions): Promise<void>;
5
6
  //# sourceMappingURL=list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3E"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAaD,wBAAsB,YAAY,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BhF"}
@@ -1,6 +1,7 @@
1
1
  import { createApi } from "../../lib/api.js";
2
+ import { logResolvedProject, logStep, logVerbose } from "../../lib/command-log.js";
2
3
  import { requireCredentials } from "../../lib/config.js";
3
- import { requireProjectId } from "../../lib/project-config.js";
4
+ import { resolveProjectId } from "../../lib/project-config.js";
4
5
  function formatUploadedAt(iso) {
5
6
  const date = new Date(iso);
6
7
  if (Number.isNaN(date.getTime())) {
@@ -11,21 +12,25 @@ function formatUploadedAt(iso) {
11
12
  .replace("T", " ")
12
13
  .replace(/\.\d{3}Z$/, " UTC");
13
14
  }
14
- export async function runBuildList(options) {
15
- const projectId = await requireProjectId({ projectFlag: options.project });
15
+ export async function runBuildList(options = {}) {
16
+ logStep("Listing builds for active project");
17
+ const project = await resolveProjectId({ startDir: options.startDir });
18
+ logResolvedProject(project);
16
19
  const credentials = await requireCredentials();
17
20
  const api = createApi(credentials.api_key, credentials.api_base);
18
- const [project, builds] = await Promise.all([
19
- api.getProject(projectId),
20
- api.listBuilds(projectId),
21
+ logVerbose("fetching project and build history");
22
+ const [platformProject, builds] = await Promise.all([
23
+ api.getProject(project.projectId),
24
+ api.listBuilds(project.projectId),
21
25
  ]);
26
+ logVerbose(`found ${builds.length} build(s)`);
22
27
  if (builds.length === 0) {
23
28
  console.log("No builds uploaded yet.");
24
29
  return;
25
30
  }
26
31
  console.log("build_id\tuploaded_at\tstatus\tactive\tmessage");
27
32
  for (const build of builds) {
28
- const active = project.active_build_id === build.id ? "yes" : "";
33
+ const active = platformProject.active_build_id === build.id ? "yes" : "";
29
34
  const message = build.message?.replace(/\s+/g, " ").trim() ?? "";
30
35
  console.log(`${build.id}\t${formatUploadedAt(build.created_at)}\t${build.validation_status}\t${active}\t${message}`);
31
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAM/D,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;SACjB,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB;IAC1D,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEjE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC1C,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACzB,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;KAC1B,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAE9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACjE,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,CAAC,EAAE,KAAK,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,iBAAiB,KAAK,MAAM,KAAK,OAAO,EAAE,CACxG,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/build/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAO/D,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;SACjB,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAA4B,EAAE;IAC/D,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACvE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE5B,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEjE,UAAU,CAAC,oCAAoC,CAAC,CAAC;IACjD,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;QACjC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;KAClC,CAAC,CAAC;IAEH,UAAU,CAAC,SAAS,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAE9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GACV,eAAe,CAAC,eAAe,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACjE,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,CAAC,EAAE,KAAK,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,iBAAiB,KAAK,MAAM,KAAK,OAAO,EAAE,CACxG,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,6 +1,5 @@
1
1
  export interface BuildPromoteOptions {
2
- project?: string;
3
- buildId: string;
2
+ buildId?: string;
4
3
  }
5
4
  /**
6
5
  * Promote sets the active build in the control plane (platform `POST …/promote`).
@@ -1 +1 @@
1
- {"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../../src/commands/build/promote.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBjF"}
1
+ {"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../../src/commands/build/promote.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0DD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -1,19 +1,60 @@
1
1
  import { createApi } from "../../lib/api.js";
2
+ import { logBuildPromoteContext, logStep, logVerbose } from "../../lib/command-log.js";
2
3
  import { requireCredentials } from "../../lib/config.js";
3
- import { requireProjectId } from "../../lib/project-config.js";
4
+ import { isInteractive, promptChoice } from "../../lib/prompt.js";
5
+ import { resolveProjectId } from "../../lib/project-config.js";
6
+ function formatUploadedAt(iso) {
7
+ const date = new Date(iso);
8
+ if (Number.isNaN(date.getTime())) {
9
+ return iso;
10
+ }
11
+ return date
12
+ .toISOString()
13
+ .replace("T", " ")
14
+ .replace(/\.\d{3}Z$/, " UTC");
15
+ }
16
+ function formatBuildChoice(build, activeBuildId) {
17
+ const active = activeBuildId === build.id ? " [active]" : "";
18
+ const message = build.message?.replace(/\s+/g, " ").trim();
19
+ const label = message ? `${message} — ` : "";
20
+ return `${label}${build.id} — ${formatUploadedAt(build.created_at)}${active}`;
21
+ }
22
+ async function resolveBuildId(projectId, buildIdArg) {
23
+ const trimmed = buildIdArg?.trim();
24
+ if (trimmed) {
25
+ return trimmed;
26
+ }
27
+ const credentials = await requireCredentials();
28
+ const api = createApi(credentials.api_key, credentials.api_base);
29
+ logVerbose(`loading builds for project ${projectId}`);
30
+ const [project, builds] = await Promise.all([
31
+ api.getProject(projectId),
32
+ api.listBuilds(projectId),
33
+ ]);
34
+ if (builds.length === 0) {
35
+ throw new Error("No builds uploaded yet. Run: voicethere build upload");
36
+ }
37
+ if (!isInteractive()) {
38
+ throw new Error("Build id required in non-interactive mode. Run: voicethere build promote <buildId>");
39
+ }
40
+ return promptChoice("Select a build to promote", builds.map((build) => ({
41
+ label: formatBuildChoice(build, project.active_build_id),
42
+ value: build.id,
43
+ })));
44
+ }
4
45
  /**
5
46
  * Promote sets the active build in the control plane (platform `POST …/promote`).
6
47
  * Does not roll out to cloud runners — use `voicethere deploy` when available.
7
48
  */
8
49
  export async function runBuildPromote(options) {
9
- const buildId = options.buildId.trim();
10
- if (!buildId) {
11
- throw new Error("Build ID is required. Usage: voicethere build promote <buildId>");
12
- }
13
- const projectId = await requireProjectId({ projectFlag: options.project });
50
+ logStep("Promoting build to active");
51
+ const project = await resolveProjectId();
52
+ const buildId = await resolveBuildId(project.projectId, options.buildId);
53
+ logBuildPromoteContext(buildId, project);
14
54
  const credentials = await requireCredentials();
15
55
  const api = createApi(credentials.api_key, credentials.api_base);
16
- const result = await api.promote(projectId, buildId);
56
+ logStep("Calling control plane promote API");
57
+ const result = await api.promote(project.projectId, buildId);
17
58
  console.log(`Promoted build ${result.active_build_id} for project ${result.project_id}`);
18
59
  console.log(`Active artifact: ${result.active_storage_path}`);
19
60
  console.log("Control plane updated — cloud runner rollout is not available yet (future: voicethere deploy --wait).");
@@ -1 +1 @@
1
- {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../src/commands/build/promote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAO/D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA4B;IAChE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAErD,OAAO,CAAC,GAAG,CACT,kBAAkB,MAAM,CAAC,eAAe,gBAAgB,MAAM,CAAC,UAAU,EAAE,CAC5E,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CACT,uGAAuG,CACxG,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"promote.js","sourceRoot":"","sources":["../../../src/commands/build/promote.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { type BuildValidateOptions } from "./validate.js";
2
2
  export interface BuildUploadOptions extends BuildValidateOptions {
3
- project?: string;
4
3
  message?: string;
5
4
  skipValidate?: boolean;
6
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/commands/build/upload.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/commands/build/upload.ts"],"names":[],"mappings":"AAeA,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE5E,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
@@ -1,16 +1,29 @@
1
+ import { stat } from "node:fs/promises";
1
2
  import { createApi } from "../../lib/api.js";
3
+ import { logResolvedBundle, logResolvedProject, logStep, logVerbose, } from "../../lib/command-log.js";
2
4
  import { requireCredentials } from "../../lib/config.js";
3
- import { requireProjectId, resolveBundlePath } from "../../lib/project-config.js";
5
+ import { assertBundleExists, resolveBundlePathDetailed, resolveProjectId, } from "../../lib/project-config.js";
4
6
  import { runBuildValidate } from "./validate.js";
5
7
  export async function runBuildUpload(options) {
6
- const projectId = await requireProjectId({ projectFlag: options.project });
7
- const bundlePath = await resolveBundlePath(options.file);
8
+ logStep("Uploading agent bundle");
9
+ const project = await resolveProjectId();
10
+ const bundle = await resolveBundlePathDetailed(options.file);
11
+ logResolvedProject(project);
12
+ logResolvedBundle(bundle);
8
13
  if (!options.skipValidate) {
9
- await runBuildValidate({ file: bundlePath });
14
+ logStep("Validating bundle locally before upload");
15
+ await runBuildValidate({ file: options.file, logContext: false });
10
16
  }
17
+ else {
18
+ logVerbose("skipping local validation (--skip-validate)");
19
+ await assertBundleExists(bundle.absolutePath);
20
+ }
21
+ const bundleStat = await stat(bundle.absolutePath);
22
+ logVerbose(`bundle size: ${bundleStat.size} bytes`);
23
+ logStep("Uploading bundle to control plane API");
11
24
  const credentials = await requireCredentials();
12
25
  const api = createApi(credentials.api_key, credentials.api_base);
13
- const build = await api.uploadBuild(projectId, bundlePath, options.message);
26
+ const build = await api.uploadBuild(project.projectId, bundle.absolutePath, options.message);
14
27
  console.log(`Uploaded build ${build.id}`);
15
28
  if (build.message) {
16
29
  console.log(`Message: ${build.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/commands/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAA6B,MAAM,eAAe,CAAC;AAQ5E,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA2B;IAE3B,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1B,MAAM,gBAAgB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5E,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/commands/build/upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,OAAO,EACP,UAAU,GACX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAA6B,MAAM,eAAe,CAAC;AAO5E,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA2B;IAE3B,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,yCAAyC,CAAC,CAAC;QACnD,MAAM,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,6CAA6C,CAAC,CAAC;QAC1D,MAAM,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACnD,UAAU,CAAC,gBAAgB,UAAU,CAAC,IAAI,QAAQ,CAAC,CAAC;IAEpD,OAAO,CAAC,uCAAuC,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,WAAW,CACjC,OAAO,CAAC,SAAS,EACjB,MAAM,CAAC,YAAY,EACnB,OAAO,CAAC,OAAO,CAChB,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,8BAA8B,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC"}