@voicethere/cli 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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +130 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/build/list.d.ts +5 -0
  8. package/dist/commands/build/list.d.ts.map +1 -0
  9. package/dist/commands/build/list.js +33 -0
  10. package/dist/commands/build/list.js.map +1 -0
  11. package/dist/commands/build/promote.d.ts +10 -0
  12. package/dist/commands/build/promote.d.ts.map +1 -0
  13. package/dist/commands/build/promote.js +21 -0
  14. package/dist/commands/build/promote.js.map +1 -0
  15. package/dist/commands/build/upload.d.ts +8 -0
  16. package/dist/commands/build/upload.d.ts.map +1 -0
  17. package/dist/commands/build/upload.js +23 -0
  18. package/dist/commands/build/upload.js.map +1 -0
  19. package/dist/commands/build/validate.d.ts +6 -0
  20. package/dist/commands/build/validate.d.ts.map +1 -0
  21. package/dist/commands/build/validate.js +38 -0
  22. package/dist/commands/build/validate.js.map +1 -0
  23. package/dist/commands/deploy.d.ts +5 -0
  24. package/dist/commands/deploy.d.ts.map +1 -0
  25. package/dist/commands/deploy.js +9 -0
  26. package/dist/commands/deploy.js.map +1 -0
  27. package/dist/commands/login.d.ts +6 -0
  28. package/dist/commands/login.d.ts.map +1 -0
  29. package/dist/commands/login.js +14 -0
  30. package/dist/commands/login.js.map +1 -0
  31. package/dist/commands/projects/create.d.ts +10 -0
  32. package/dist/commands/projects/create.d.ts.map +1 -0
  33. package/dist/commands/projects/create.js +36 -0
  34. package/dist/commands/projects/create.js.map +1 -0
  35. package/dist/commands/projects/list.d.ts +2 -0
  36. package/dist/commands/projects/list.d.ts.map +1 -0
  37. package/dist/commands/projects/list.js +16 -0
  38. package/dist/commands/projects/list.js.map +1 -0
  39. package/dist/commands/projects/show.d.ts +2 -0
  40. package/dist/commands/projects/show.d.ts.map +1 -0
  41. package/dist/commands/projects/show.js +18 -0
  42. package/dist/commands/projects/show.js.map +1 -0
  43. package/dist/commands/projects/use.d.ts +8 -0
  44. package/dist/commands/projects/use.d.ts.map +1 -0
  45. package/dist/commands/projects/use.js +15 -0
  46. package/dist/commands/projects/use.js.map +1 -0
  47. package/dist/lib/api.d.ts +51 -0
  48. package/dist/lib/api.d.ts.map +1 -0
  49. package/dist/lib/api.js +90 -0
  50. package/dist/lib/api.js.map +1 -0
  51. package/dist/lib/config.d.ts +10 -0
  52. package/dist/lib/config.d.ts.map +1 -0
  53. package/dist/lib/config.js +51 -0
  54. package/dist/lib/config.js.map +1 -0
  55. package/dist/lib/project-config.d.ts +36 -0
  56. package/dist/lib/project-config.d.ts.map +1 -0
  57. package/dist/lib/project-config.js +113 -0
  58. package/dist/lib/project-config.js.map +1 -0
  59. package/package.json +49 -0
@@ -0,0 +1,36 @@
1
+ import { createApi } from "../../lib/api.js";
2
+ import { requireCredentials } from "../../lib/config.js";
3
+ import { writeProjectConfig } from "../../lib/project-config.js";
4
+ export function slugifyName(name) {
5
+ return name
6
+ .trim()
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9]+/g, "-")
9
+ .replace(/^-+|-+$/g, "")
10
+ .slice(0, 64);
11
+ }
12
+ export async function runProjectsCreate(options) {
13
+ const name = options.name.trim();
14
+ if (!name) {
15
+ throw new Error("--name is required");
16
+ }
17
+ const slug = (options.slug?.trim() || slugifyName(name)).replace(/^-+|-+$/g, "");
18
+ if (!slug) {
19
+ throw new Error("Could not derive a valid slug; pass --slug explicitly");
20
+ }
21
+ const credentials = await requireCredentials();
22
+ const api = createApi(credentials.api_key, credentials.api_base);
23
+ const project = await api.createProject(name, slug);
24
+ const shouldLink = options.link !== false;
25
+ if (shouldLink) {
26
+ const configPath = await writeProjectConfig({
27
+ project_id: project.id,
28
+ project_slug: project.slug,
29
+ name: project.name,
30
+ bundle: options.bundle?.trim() || undefined,
31
+ });
32
+ console.error(`Linked ${configPath} (commit this file to version control)`);
33
+ }
34
+ console.log(JSON.stringify(project, null, 2));
35
+ }
36
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/projects/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAUjE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI;SACR,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA8B;IAE9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAC9D,UAAU,EACV,EAAE,CACH,CAAC;IACF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,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,OAAO,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC;IAC1C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC;YAC1C,UAAU,EAAE,OAAO,CAAC,EAAE;YACtB,YAAY,EAAE,OAAO,CAAC,IAAI;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS;SAC5C,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,wCAAwC,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runProjectsList(): Promise<void>;
2
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/list.ts"],"names":[],"mappings":"AAGA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBrD"}
@@ -0,0 +1,16 @@
1
+ import { createApi } from "../../lib/api.js";
2
+ import { requireCredentials } from "../../lib/config.js";
3
+ export async function runProjectsList() {
4
+ const credentials = await requireCredentials();
5
+ const api = createApi(credentials.api_key, credentials.api_base);
6
+ const projects = await api.listProjects();
7
+ if (projects.length === 0) {
8
+ console.log("No projects found.");
9
+ return;
10
+ }
11
+ for (const project of projects) {
12
+ const active = project.active_build_id ?? "none";
13
+ console.log(`${project.id}\t${project.slug}\t${project.name}\tactive_build=${active}`);
14
+ }
15
+ }
16
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/projects/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,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,QAAQ,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;IAE1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,IAAI,MAAM,CAAC;QACjD,OAAO,CAAC,GAAG,CACT,GAAG,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,kBAAkB,MAAM,EAAE,CAC1E,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runProjectsShow(): Promise<void>;
2
+ //# sourceMappingURL=show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/show.ts"],"names":[],"mappings":"AAEA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBrD"}
@@ -0,0 +1,18 @@
1
+ import { findProjectConfigPath, readProjectConfig } from "../../lib/project-config.js";
2
+ export async function runProjectsShow() {
3
+ const path = await findProjectConfigPath();
4
+ if (!path) {
5
+ console.log("No .voicethere/config.json found in this directory or parents.");
6
+ console.log("Run: voicethere projects use --project <uuid>");
7
+ return;
8
+ }
9
+ const linked = await readProjectConfig();
10
+ if (!linked) {
11
+ throw new Error(`Failed to read ${path}`);
12
+ }
13
+ console.log(JSON.stringify({
14
+ path: linked.path,
15
+ ...linked.config,
16
+ }, null, 2));
17
+ }
18
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/projects/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEvF,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,IAAI,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;QACE,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,MAAM,CAAC,MAAM;KACjB,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface ProjectsUseOptions {
2
+ project: string;
3
+ slug?: string;
4
+ name?: string;
5
+ bundle?: string;
6
+ }
7
+ export declare function runProjectsUse(options: ProjectsUseOptions): Promise<void>;
8
+ //# sourceMappingURL=use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.d.ts","sourceRoot":"","sources":["../../../src/commands/projects/use.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAcf"}
@@ -0,0 +1,15 @@
1
+ import { writeProjectConfig } from "../../lib/project-config.js";
2
+ export async function runProjectsUse(options) {
3
+ const projectId = options.project.trim();
4
+ if (!projectId) {
5
+ throw new Error("--project is required");
6
+ }
7
+ const path = await writeProjectConfig({
8
+ project_id: projectId,
9
+ project_slug: options.slug?.trim() || undefined,
10
+ name: options.name?.trim() || undefined,
11
+ bundle: options.bundle?.trim() || undefined,
12
+ });
13
+ console.log(`Linked ${path} → project_id=${projectId}`);
14
+ }
15
+ //# sourceMappingURL=use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.js","sourceRoot":"","sources":["../../../src/commands/projects/use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AASjE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA2B;IAE3B,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC;QACpC,UAAU,EAAE,SAAS;QACrB,YAAY,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;QAC/C,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;QACvC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS;KAC5C,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,iBAAiB,SAAS,EAAE,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,51 @@
1
+ export interface ApiErrorBody {
2
+ error?: {
3
+ code?: string;
4
+ message?: string;
5
+ request_id?: string;
6
+ };
7
+ }
8
+ export declare class ApiError extends Error {
9
+ readonly status: number;
10
+ readonly code?: string;
11
+ readonly requestId?: string;
12
+ constructor(status: number, message: string, body?: ApiErrorBody);
13
+ }
14
+ export interface Project {
15
+ id: string;
16
+ org_id: string;
17
+ name: string;
18
+ slug: string;
19
+ active_build_id: string | null;
20
+ created_at: string;
21
+ }
22
+ export interface Build {
23
+ id: string;
24
+ project_id: string;
25
+ storage_path?: string;
26
+ size_bytes: number;
27
+ checksum_sha256: string;
28
+ validation_status: string;
29
+ message?: string | null;
30
+ created_at: string;
31
+ }
32
+ export interface PromoteResult {
33
+ project_id: string;
34
+ active_build_id: string;
35
+ active_storage_path: string;
36
+ }
37
+ export declare class VoicethereApi {
38
+ private readonly apiKey;
39
+ private readonly apiBase;
40
+ constructor(apiKey: string, apiBase: string);
41
+ listProjects(): Promise<Project[]>;
42
+ createProject(name: string, slug: string): Promise<Project>;
43
+ getProject(projectId: string): Promise<Project>;
44
+ listBuilds(projectId: string): Promise<Build[]>;
45
+ uploadBuild(projectId: string, bundlePath: string, message?: string): Promise<Build>;
46
+ promote(projectId: string, buildId?: string): Promise<PromoteResult>;
47
+ rollback(projectId: string, buildId?: string): Promise<PromoteResult>;
48
+ private request;
49
+ }
50
+ export declare function createApi(apiKey: string, apiBase: string): VoicethereApi;
51
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;gBAEhB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAOjE;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,qBAAa,aAAa;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;IAG5B,YAAY,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAQlC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM3D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAQ/C,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC;IAmBX,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAUpE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAU7D,OAAO;CA0CtB;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAExE"}
@@ -0,0 +1,90 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ export class ApiError extends Error {
4
+ status;
5
+ code;
6
+ requestId;
7
+ constructor(status, message, body) {
8
+ super(message);
9
+ this.name = "ApiError";
10
+ this.status = status;
11
+ this.code = body?.error?.code;
12
+ this.requestId = body?.error?.request_id;
13
+ }
14
+ }
15
+ export class VoicethereApi {
16
+ apiKey;
17
+ apiBase;
18
+ constructor(apiKey, apiBase) {
19
+ this.apiKey = apiKey;
20
+ this.apiBase = apiBase;
21
+ }
22
+ async listProjects() {
23
+ const response = await this.request("GET", "/projects");
24
+ return Array.isArray(response) ? response : response.projects;
25
+ }
26
+ async createProject(name, slug) {
27
+ return this.request("POST", "/projects", {
28
+ json: { name, slug },
29
+ });
30
+ }
31
+ async getProject(projectId) {
32
+ return this.request("GET", `/projects/${projectId}`);
33
+ }
34
+ async listBuilds(projectId) {
35
+ const response = await this.request("GET", `/projects/${projectId}/builds`);
36
+ return response.builds;
37
+ }
38
+ async uploadBuild(projectId, bundlePath, message) {
39
+ const buffer = await readFile(bundlePath);
40
+ const form = new FormData();
41
+ form.append("bundle", new Blob([buffer], { type: "application/javascript" }), basename(bundlePath));
42
+ const trimmedMessage = message?.trim();
43
+ if (trimmedMessage) {
44
+ form.append("message", trimmedMessage);
45
+ }
46
+ return this.request("POST", `/projects/${projectId}/builds`, {
47
+ body: form,
48
+ });
49
+ }
50
+ async promote(projectId, buildId) {
51
+ return this.request("POST", `/projects/${projectId}/promote`, {
52
+ json: buildId ? { build_id: buildId } : {},
53
+ });
54
+ }
55
+ async rollback(projectId, buildId) {
56
+ return this.request("POST", `/projects/${projectId}/rollback`, {
57
+ json: buildId ? { build_id: buildId } : {},
58
+ });
59
+ }
60
+ async request(method, path, options) {
61
+ const url = new URL(path.replace(/^\//, ""), `${this.apiBase.replace(/\/$/, "")}/`);
62
+ const headers = {
63
+ Authorization: `Bearer ${this.apiKey}`,
64
+ };
65
+ let body;
66
+ if (options?.json !== undefined) {
67
+ headers["Content-Type"] = "application/json";
68
+ body = JSON.stringify(options.json);
69
+ }
70
+ else if (options?.body) {
71
+ body = options.body;
72
+ }
73
+ const response = await fetch(url, { method, headers, body });
74
+ const text = await response.text();
75
+ const payload = text.length > 0 ? JSON.parse(text) : null;
76
+ if (!response.ok) {
77
+ const errorBody = payload && typeof payload === "object" && "error" in payload
78
+ ? payload
79
+ : undefined;
80
+ const message = errorBody?.error?.message ??
81
+ `Request failed: ${method} ${url.pathname} (${response.status})`;
82
+ throw new ApiError(response.status, message, errorBody);
83
+ }
84
+ return (payload ?? {});
85
+ }
86
+ }
87
+ export function createApi(apiKey, apiBase) {
88
+ return new VoicethereApi(apiKey, apiBase);
89
+ }
90
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAUrC,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,MAAM,CAAS;IACf,IAAI,CAAU;IACd,SAAS,CAAU;IAE5B,YAAY,MAAc,EAAE,OAAe,EAAE,IAAmB;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC;IAC3C,CAAC;CACF;AA4BD,MAAM,OAAO,aAAa;IAEL;IACA;IAFnB,YACmB,MAAc,EACd,OAAe;QADf,WAAM,GAAN,MAAM,CAAQ;QACd,YAAO,GAAP,OAAO,CAAQ;IAC/B,CAAC;IAEJ,KAAK,CAAC,YAAY;QAChB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,KAAK,EACL,WAAW,CACZ,CAAC;QACF,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,IAAY;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAU,MAAM,EAAE,WAAW,EAAE;YAChD,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACrB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAU,KAAK,EAAE,aAAa,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CACjC,KAAK,EACL,aAAa,SAAS,SAAS,CAChC,CAAC;QACF,OAAO,QAAQ,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,WAAW,CACf,SAAiB,EACjB,UAAkB,EAClB,OAAgB;QAEhB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CACT,QAAQ,EACR,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC,EACtD,QAAQ,CAAC,UAAU,CAAC,CACrB,CAAC;QAEF,MAAM,cAAc,GAAG,OAAO,EAAE,IAAI,EAAE,CAAC;QACvC,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAQ,MAAM,EAAE,aAAa,SAAS,SAAS,EAAE;YAClE,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,OAAgB;QAC/C,OAAO,IAAI,CAAC,OAAO,CACjB,MAAM,EACN,aAAa,SAAS,UAAU,EAChC;YACE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;SAC3C,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,OAAgB;QAChD,OAAO,IAAI,CAAC,OAAO,CACjB,MAAM,EACN,aAAa,SAAS,WAAW,EACjC;YACE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;SAC3C,CACF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,MAAc,EACd,IAAY,EACZ,OAGC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EACvB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CACtC,CAAC;QACF,MAAM,OAAO,GAA2B;YACtC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;QAEF,IAAI,IAA0B,CAAC;QAC/B,IAAI,OAAO,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;YACzB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,OAAO,GACX,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;QAElE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GACb,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO;gBAC1D,CAAC,CAAE,OAAwB;gBAC3B,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,OAAO,GACX,SAAS,EAAE,KAAK,EAAE,OAAO;gBACzB,mBAAmB,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC;YACnE,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,CAAC,OAAO,IAAK,EAAQ,CAAM,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,OAAe;IACvD,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const DEFAULT_API_BASE = "https://app.voicethere.dev/api/v1";
2
+ export interface Credentials {
3
+ api_key: string;
4
+ api_base: string;
5
+ }
6
+ export declare function getCredentialsPath(): string;
7
+ export declare function readCredentials(): Promise<Credentials | null>;
8
+ export declare function writeCredentials(credentials: Credentials): Promise<void>;
9
+ export declare function requireCredentials(): Promise<Credentials>;
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,sCAAsC,CAAC;AAEpE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAM3C;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAuBnE;AAED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,WAAW,CAAC,CAQ/D"}
@@ -0,0 +1,51 @@
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+ export const DEFAULT_API_BASE = "https://app.voicethere.dev/api/v1";
5
+ export function getCredentialsPath() {
6
+ const override = process.env.VOICETHERE_CREDENTIALS_PATH?.trim();
7
+ if (override) {
8
+ return override;
9
+ }
10
+ return join(homedir(), ".config", "voicethere", "credentials.json");
11
+ }
12
+ export async function readCredentials() {
13
+ const path = getCredentialsPath();
14
+ try {
15
+ const raw = await readFile(path, "utf8");
16
+ const parsed = JSON.parse(raw);
17
+ if (typeof parsed.api_key !== "string" ||
18
+ parsed.api_key.length === 0 ||
19
+ typeof parsed.api_base !== "string" ||
20
+ parsed.api_base.length === 0) {
21
+ return null;
22
+ }
23
+ return {
24
+ api_key: parsed.api_key,
25
+ api_base: parsed.api_base,
26
+ };
27
+ }
28
+ catch (error) {
29
+ if (error.code === "ENOENT") {
30
+ return null;
31
+ }
32
+ throw error;
33
+ }
34
+ }
35
+ export async function writeCredentials(credentials) {
36
+ const path = getCredentialsPath();
37
+ await mkdir(dirname(path), { recursive: true });
38
+ await writeFile(path, `${JSON.stringify(credentials, null, 2)}\n`, {
39
+ encoding: "utf8",
40
+ mode: 0o600,
41
+ });
42
+ await chmod(path, 0o600);
43
+ }
44
+ export async function requireCredentials() {
45
+ const credentials = await readCredentials();
46
+ if (!credentials) {
47
+ throw new Error("Not logged in. Run: voicethere login --api-key <key> [--api-base <url>]");
48
+ }
49
+ return credentials;
50
+ }
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAOpE,MAAM,UAAU,kBAAkB;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,EAAE,CAAC;IACjE,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACvD,IACE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAClC,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAC3B,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;YACnC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAC5B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAwB;IAExB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;IAClC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACjE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,36 @@
1
+ export declare const PROJECT_CONFIG_DIR = ".voicethere";
2
+ export declare const PROJECT_CONFIG_FILENAME = "config.json";
3
+ export interface ProjectConfig {
4
+ /** Platform project UUID — safe to commit; links this repo to a cloud project. */
5
+ project_id: string;
6
+ project_slug?: string;
7
+ name?: string;
8
+ /** Default bundle path for build validate/upload (relative to repo root). */
9
+ bundle?: string;
10
+ }
11
+ export interface ProjectConfigFile {
12
+ version?: number;
13
+ project_id: string;
14
+ project_slug?: string;
15
+ name?: string;
16
+ bundle?: string;
17
+ }
18
+ export declare function getProjectConfigOverridePath(): string | null;
19
+ /** Walk upward from startDir to find `.voicethere/config.json`. */
20
+ export declare function findProjectConfigPath(startDir?: string): Promise<string | null>;
21
+ export declare function parseProjectConfig(raw: string): ProjectConfig;
22
+ export declare function readProjectConfig(startDir?: string): Promise<{
23
+ config: ProjectConfig;
24
+ path: string;
25
+ } | null>;
26
+ export declare function requireProjectId(options: {
27
+ projectFlag?: string;
28
+ startDir?: string;
29
+ }): Promise<string>;
30
+ export declare function writeProjectConfig(config: ProjectConfig, options?: {
31
+ startDir?: string;
32
+ path?: string;
33
+ }): Promise<string>;
34
+ /** Bundle path: CLI flag → `.voicethere/config.json` → default. */
35
+ export declare function resolveBundlePath(fileFlag?: string, startDir?: string): Promise<string>;
36
+ //# sourceMappingURL=project-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../../src/lib/project-config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,eAAO,MAAM,uBAAuB,gBAAgB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CAG5D;AAED,mEAAmE;AACnE,wBAAsB,qBAAqB,CACzC,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4BxB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAyB7D;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAQzD;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAclB;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAID,mEAAmE;AACnE,wBAAsB,iBAAiB,CACrC,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAYjB"}
@@ -0,0 +1,113 @@
1
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ export const PROJECT_CONFIG_DIR = ".voicethere";
4
+ export const PROJECT_CONFIG_FILENAME = "config.json";
5
+ export function getProjectConfigOverridePath() {
6
+ const override = process.env.VOICETHERE_PROJECT_CONFIG?.trim();
7
+ return override || null;
8
+ }
9
+ /** Walk upward from startDir to find `.voicethere/config.json`. */
10
+ export async function findProjectConfigPath(startDir = process.cwd()) {
11
+ const override = getProjectConfigOverridePath();
12
+ if (override) {
13
+ try {
14
+ await access(override);
15
+ return resolve(override);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ let dir = resolve(startDir);
22
+ const root = resolve("/");
23
+ while (true) {
24
+ const candidate = join(dir, PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILENAME);
25
+ try {
26
+ await access(candidate);
27
+ return candidate;
28
+ }
29
+ catch {
30
+ // continue upward
31
+ }
32
+ if (dir === root) {
33
+ return null;
34
+ }
35
+ dir = dirname(dir);
36
+ }
37
+ }
38
+ export function parseProjectConfig(raw) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(raw);
42
+ }
43
+ catch {
44
+ throw new Error("Invalid JSON in .voicethere/config.json");
45
+ }
46
+ if (!parsed || typeof parsed !== "object") {
47
+ throw new Error(".voicethere/config.json must be a JSON object");
48
+ }
49
+ const record = parsed;
50
+ const projectId = record.project_id?.trim();
51
+ if (!projectId) {
52
+ throw new Error(".voicethere/config.json requires project_id");
53
+ }
54
+ return {
55
+ project_id: projectId,
56
+ project_slug: record.project_slug?.trim() || undefined,
57
+ name: record.name?.trim() || undefined,
58
+ bundle: record.bundle?.trim() || undefined,
59
+ };
60
+ }
61
+ export async function readProjectConfig(startDir) {
62
+ const path = await findProjectConfigPath(startDir);
63
+ if (!path) {
64
+ return null;
65
+ }
66
+ const raw = await readFile(path, "utf8");
67
+ return { config: parseProjectConfig(raw), path };
68
+ }
69
+ export async function requireProjectId(options) {
70
+ const fromFlag = options.projectFlag?.trim();
71
+ if (fromFlag) {
72
+ return fromFlag;
73
+ }
74
+ const linked = await readProjectConfig(options.startDir);
75
+ if (linked?.config.project_id) {
76
+ return linked.config.project_id;
77
+ }
78
+ throw new Error("No project selected. Pass --project <id> or run: voicethere projects use --project <id>");
79
+ }
80
+ export async function writeProjectConfig(config, options = {}) {
81
+ const dir = resolve(options.startDir ?? process.cwd());
82
+ const path = options.path ?? join(dir, PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILENAME);
83
+ const payload = {
84
+ version: 1,
85
+ project_id: config.project_id,
86
+ };
87
+ if (config.project_slug) {
88
+ payload.project_slug = config.project_slug;
89
+ }
90
+ if (config.name) {
91
+ payload.name = config.name;
92
+ }
93
+ if (config.bundle) {
94
+ payload.bundle = config.bundle;
95
+ }
96
+ await mkdir(dirname(path), { recursive: true });
97
+ await writeFile(path, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
98
+ return path;
99
+ }
100
+ const DEFAULT_BUNDLE = "dist/agent.js";
101
+ /** Bundle path: CLI flag → `.voicethere/config.json` → default. */
102
+ export async function resolveBundlePath(fileFlag, startDir) {
103
+ const fromFlag = fileFlag?.trim();
104
+ if (fromFlag) {
105
+ return fromFlag;
106
+ }
107
+ const linked = await readProjectConfig(startDir);
108
+ if (linked?.config.bundle) {
109
+ return linked.config.bundle;
110
+ }
111
+ return DEFAULT_BUNDLE;
112
+ }
113
+ //# sourceMappingURL=project-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/lib/project-config.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@voicethere/cli",
3
+ "version": "0.1.0",
4
+ "description": "VoiceThere cloud CLI — login, projects, and agent bundle upload",
5
+ "type": "module",
6
+ "bin": {
7
+ "voicethere": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc -p tsconfig.json",
16
+ "typecheck": "tsc --noEmit -p tsconfig.json",
17
+ "test": "vitest run",
18
+ "test:ci": "npm run typecheck && npm run test && npm run build"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/voicethere/cli.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/voicethere/cli/issues"
26
+ },
27
+ "homepage": "https://github.com/voicethere/cli#readme",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "keywords": [
32
+ "voicethere",
33
+ "voice-agent",
34
+ "cli"
35
+ ],
36
+ "engines": {
37
+ "node": ">=22"
38
+ },
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "commander": "^13.1.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.10.0",
45
+ "@voicethere/agent": "^0.1.4",
46
+ "typescript": "^5.7.0",
47
+ "vitest": "^2.1.8"
48
+ }
49
+ }