@hitch42/applet 0.1.1-beta.6 → 0.1.1-beta.8

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 (51) hide show
  1. package/dist/_internal/server.d.ts +14 -1
  2. package/dist/_internal/server.js +23 -74
  3. package/dist/applet.js +50 -29
  4. package/dist/build-CFCKKMn7.js +2 -0
  5. package/dist/{build-DIsKQQT0.js → build-DANx9Hgg.js} +28 -13
  6. package/dist/{ci-D0nC_Ho7.js → ci-5qWl7lT3.js} +20 -4
  7. package/dist/client.d.ts +2 -2
  8. package/dist/{contract-DMrpbaLJ.d.ts → contract-rP_eV9PK.d.ts} +1 -1
  9. package/dist/{deploy-0dlUvCt3.js → deploy-MQWLG2EA.js} +130 -15
  10. package/dist/email-DBTVhNB_.js +62 -0
  11. package/dist/{generate-C6eAL5eo.js → generate-BxYHdoAQ.js} +18 -17
  12. package/dist/generate-CQ07Hdpo.js +2 -0
  13. package/dist/index.d.ts +115 -4
  14. package/dist/index.js +141 -26
  15. package/dist/{init-tEMeys9M.js → init-jDEgYIXg.js} +5 -5
  16. package/dist/load-config-BYSxDVAl.js +27 -0
  17. package/dist/login-C7RKmmTe.js +12 -0
  18. package/dist/{logs-m00pzr_O.js → logs-DgjgAxj2.js} +3 -3
  19. package/dist/{manifest-DyoJ1MIL.js → manifest-Bp87Uz0a.js} +6 -0
  20. package/dist/{manifest-BQCAxATS.d.ts → manifest-DD_SGkS6.d.ts} +5 -0
  21. package/dist/me-BW7Paary.js +32 -0
  22. package/dist/{project-mW0vsN8A.js → project-CbYPtpPq.js} +16 -14
  23. package/dist/prompt-ChS-grYO.js +29 -0
  24. package/dist/schedules-dhU1yyFr.js +42 -0
  25. package/dist/server.d.ts +2 -2
  26. package/dist/telephony-protocol-DRgiYjqQ.d.ts +74 -0
  27. package/dist/telephony.d.ts +77 -0
  28. package/dist/telephony.js +607 -0
  29. package/dist/{variables-CP7Ce3Np.js → variables-Bwnr7oxf.js} +3 -28
  30. package/dist/vite.d.ts +1 -1
  31. package/dist/vite.js +458 -27
  32. package/dist/workflow-engine-MogejNfF.js +117 -0
  33. package/dist/{auth-DaVK0k5R.js → workspace-XVtM12ZC.js} +44 -4
  34. package/package.json +6 -1
  35. package/scaffold/.agents/skills/hitch-applets/SKILL.md +32 -16
  36. package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
  37. package/scaffold/.agents/skills/hitch-applets/references/files.md +3 -3
  38. package/scaffold/.agents/skills/hitch-applets/references/manifest.md +21 -2
  39. package/scaffold/.agents/skills/hitch-applets/references/performance.md +1 -1
  40. package/scaffold/.agents/skills/hitch-applets/references/records.md +4 -3
  41. package/scaffold/.agents/skills/hitch-applets/references/schedules.md +7 -2
  42. package/scaffold/.agents/skills/hitch-applets/references/server.md +0 -3
  43. package/scaffold/.agents/skills/hitch-applets/references/workflows.md +11 -3
  44. package/scaffold/.agents/skills/hitch-cli/SKILL.md +24 -22
  45. package/scaffold/.agents/skills/hitch-data/SKILL.md +2 -2
  46. package/scaffold/.agents/skills/hitch-data/references/limits.md +10 -10
  47. package/scaffold/.agents/skills/hitch-theory/SKILL.md +150 -0
  48. package/scaffold/.github/workflows/hitch.yml +0 -6
  49. package/dist/build-B70gkDi5.js +0 -2
  50. package/dist/generate-D5rSXXa-.js +0 -2
  51. package/dist/load-config-BnxocLAQ.js +0 -56
@@ -0,0 +1,62 @@
1
+ import { oc } from "@orpc/contract";
2
+ import { z } from "zod";
3
+ //#region src/hitch/email.ts
4
+ const emailTagKeySchema = z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/);
5
+ const emailTagsSchema = z.record(emailTagKeySchema, z.string().min(1).max(200)).refine((tags) => Object.keys(tags).length <= 10);
6
+ const createEmailPixelInputSchema = z.object({ tags: emailTagsSchema.optional() }).strict();
7
+ const createEmailPixelOutputSchema = z.object({
8
+ id: z.uuid(),
9
+ url: z.url()
10
+ });
11
+ const getEmailTrackerInputSchema = z.object({ id: z.uuid() });
12
+ const markEmailTrackerSentInputSchema = z.object({
13
+ id: z.uuid(),
14
+ sentAt: z.iso.datetime({ offset: true }).optional()
15
+ }).strict();
16
+ const markEmailTrackerSentBodySchema = z.object({ sentAt: z.iso.datetime({ offset: true }).optional() }).strict();
17
+ const emailTrackerSchema = z.object({
18
+ id: z.uuid(),
19
+ url: z.url(),
20
+ tags: emailTagsSchema,
21
+ createdAt: z.iso.datetime(),
22
+ sentAt: z.iso.datetime().nullable(),
23
+ firstHitAt: z.iso.datetime().nullable(),
24
+ lastHitAt: z.iso.datetime().nullable()
25
+ });
26
+ const listEmailTrackersInputSchema = z.object({
27
+ filter: emailTagsSchema.optional(),
28
+ sentAt: z.object({
29
+ $gte: z.iso.datetime({ offset: true }).optional(),
30
+ $lt: z.iso.datetime({ offset: true }).optional()
31
+ }).strict().optional(),
32
+ cursor: z.uuid().optional(),
33
+ limit: z.number().int().min(1).max(200).optional()
34
+ }).strict();
35
+ const listEmailTrackersOutputSchema = z.object({
36
+ trackers: z.array(emailTrackerSchema),
37
+ nextCursor: z.uuid().nullable()
38
+ });
39
+ function emailContract(appletCode) {
40
+ const path = `/v1/applets/${encodeURIComponent(appletCode)}/email/tracking`;
41
+ return { tracking: {
42
+ createPixel: oc.route({
43
+ method: "POST",
44
+ path: `${path}/pixels`,
45
+ successStatus: 201
46
+ }).input(createEmailPixelInputSchema.optional()).output(createEmailPixelOutputSchema),
47
+ markSent: oc.route({
48
+ method: "POST",
49
+ path: `${path}/{id}/sent`
50
+ }).input(markEmailTrackerSentInputSchema).output(emailTrackerSchema),
51
+ get: oc.route({
52
+ method: "GET",
53
+ path: `${path}/{id}`
54
+ }).input(getEmailTrackerInputSchema).output(emailTrackerSchema),
55
+ list: oc.route({
56
+ method: "POST",
57
+ path: `${path}/list`
58
+ }).input(listEmailTrackersInputSchema.optional()).output(listEmailTrackersOutputSchema)
59
+ } };
60
+ }
61
+ //#endregion
62
+ export { emailTagsSchema as a, listEmailTrackersInputSchema as c, markEmailTrackerSentInputSchema as d, emailTagKeySchema as i, listEmailTrackersOutputSchema as l, createEmailPixelOutputSchema as n, emailTrackerSchema as o, emailContract as r, getEmailTrackerInputSchema as s, createEmailPixelInputSchema as t, markEmailTrackerSentBodySchema as u };
@@ -1,7 +1,7 @@
1
- import { i as resolveInstanceUrl, n as organizationInstanceUrl, t as fetchWithOrgAuth } from "./auth-DaVK0k5R.js";
2
- import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-D0nC_Ho7.js";
3
- import { t as loadAppletConfig } from "./load-config-BnxocLAQ.js";
4
- import { r as prepareAppletProject } from "./project-mW0vsN8A.js";
1
+ import { c as organizationInstanceUrl, d as resolveInstanceUrl, n as fetchWithOrgAuth } from "./workspace-XVtM12ZC.js";
2
+ import { i as loadGitHubActionsBuildInputs, n as githubActionsContext } from "./ci-5qWl7lT3.js";
3
+ import { t as loadAppletConfig } from "./load-config-BYSxDVAl.js";
4
+ import { r as prepareAppletProject } from "./project-CbYPtpPq.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { existsSync } from "node:fs";
7
7
  import { access, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
@@ -274,7 +274,7 @@ ${Object.entries(catalog).map(([objectCode, attributeCodes]) => ` ${JSON.string
274
274
  };`;
275
275
  return `// Generated by @hitch42/applet — do not edit.
276
276
  import type manifest from "./manifest.gen.ts";
277
- ${options.hasServer ? "import type server from \"../src/server/main.ts\";\nimport type * as serverModule from \"../src/server/main.ts\";\n" : ""}${options.hasClient ? "import type { Route as indexRoute } from \"../src/client/routes/index.tsx\";\n" : ""}${options.hasServer ? "import type { AnyRouter } from \"@orpc/server\";\n" : ""}${options.hasClient ? "import type { AnyRoute } from \"@tanstack/react-router\";\n" : ""}${options.hasServer ? "import type { WorkflowDefinition } from \"@hitch42/applet/server\";\n" : ""}
277
+ ${options.hasServer ? "import type server from \"../src/server/main.ts\";\nimport type * as serverModule from \"../src/server/main.ts\";\n" : ""}${options.hasClient ? "import type { Route as indexRoute } from \"../src/client/routes/index.tsx\";\n" : ""}${options.hasServer ? "import type { AnyRouter } from \"@orpc/server\";\n" : ""}${options.hasClient ? "import type { AnyRoute } from \"@tanstack/react-router\";\n" : ""}${options.hasServer ? "import type { WorkflowDefinition } from \"@hitch42/applet/server\";\nimport type { TelephonyMessageReceivedEvent } from \"@hitch42/applet\";\n" : ""}
278
278
  ${catalogType}
279
279
 
280
280
  type Expect<T extends true> = T;
@@ -287,6 +287,7 @@ type _SrcServerMainMustDefaultExportRouterAndValidWorkflows = Expect<
287
287
  typeof server extends {
288
288
  router: AnyRouter;
289
289
  workflows?: Record<string, WorkflowDefinition<any, any>>;
290
+ telephony?: { onMessageReceived?: (event: TelephonyMessageReceivedEvent) => void | Promise<void> };
290
291
  }
291
292
  ? true
292
293
  : false
@@ -352,11 +353,11 @@ async function responseJson(response) {
352
353
  throw new Error("Failed to parse the organization's OpenAPI spec.", { cause: error });
353
354
  }
354
355
  }
355
- async function loadAuthenticatedSpec(orgCode, options) {
356
+ async function loadAuthenticatedSpec(manifest, options) {
356
357
  const github = githubActionsContext(options.store?.env ?? process.env);
357
- if (github !== void 0) return (await loadGitHubActionsBuildInputs(github, options)).openapi;
358
+ if (github !== void 0) return (await loadGitHubActionsBuildInputs(github, options, manifest.requiresChangeset)).openapi;
358
359
  const fetcher = options.fetch ?? globalThis.fetch;
359
- const response = await fetchWithOrgAuth(orgCode, options, (instanceUrl, accessToken) => fetcher(`${instanceUrl}/api/v1/openapi.json${options.changesetId === void 0 ? "" : `?changeset_id=${encodeURIComponent(options.changesetId)}`}`, { headers: { Authorization: `Bearer ${accessToken}` } }));
360
+ const response = await fetchWithOrgAuth(manifest.org, options, (instanceUrl, accessToken) => fetcher(`${instanceUrl}/api/v1/openapi.json${manifest.requiresChangeset === void 0 ? "" : `?changeset_id=${encodeURIComponent(manifest.requiresChangeset)}`}`, { headers: { Authorization: `Bearer ${accessToken}` } }));
360
361
  if (!response.ok) throw new Error(`Failed to load the organization's OpenAPI spec (${response.status}).`);
361
362
  return responseJson(response);
362
363
  }
@@ -367,18 +368,18 @@ async function loadThemeStylesheet(orgCode, options) {
367
368
  if (!response.ok) throw new Error(`Failed to load the organization's theme (${response.status}).`);
368
369
  return response.text();
369
370
  }
370
- async function loadBuildInputs(orgCode, options) {
371
+ async function loadBuildInputs(manifest, options) {
371
372
  const github = githubActionsContext(options.store?.env ?? process.env);
372
373
  if (github !== void 0) {
373
- const inputs = await loadGitHubActionsBuildInputs(github, options);
374
+ const inputs = await loadGitHubActionsBuildInputs(github, options, manifest.requiresChangeset);
374
375
  return {
375
376
  spec: inputs.openapi,
376
377
  theme: inputs.theme
377
378
  };
378
379
  }
379
380
  return {
380
- spec: await loadAuthenticatedSpec(orgCode, options),
381
- theme: await loadThemeStylesheet(orgCode, options)
381
+ spec: await loadAuthenticatedSpec(manifest, options),
382
+ theme: await loadThemeStylesheet(manifest.org, options)
382
383
  };
383
384
  }
384
385
  async function generateContract(spec, outDir) {
@@ -420,16 +421,16 @@ async function writeContractFiles(outDir, manifest, spec) {
420
421
  await writeManifestGen(outDir, manifest);
421
422
  await writeRegisterDeclaration(outDir, catalog);
422
423
  await writeFile(resolve(outDir, "index.ts"), `// Generated by applet generate — do not edit.
423
- import { filesContract as files, meContract as me, pruneContract, registerHitchContract, teamsContract as teams } from "@hitch42/applet";
424
+ import { emailContract, filesContract as files, meContract as me, pruneContract, registerHitchContract, teamsContract as teams, telephonyContract as telephony } from "@hitch42/applet";
424
425
  import manifest from "./manifest.gen.ts";
425
426
 
426
427
  ${Object.hasOwn(preparedSpec.paths, "/v1/batch") ? `import { contract as generated } from "./orpc.gen.ts";
427
428
 
428
429
  const { batch, ...records } = generated;
429
430
 
430
- export const contract = { records, batch, files, me, teams } as const;` : `import { contract as records } from "./orpc.gen.ts";
431
+ export const contract = { records, batch, email: emailContract(manifest.code), files, me, teams, telephony } as const;` : `import { contract as records } from "./orpc.gen.ts";
431
432
 
432
- export const contract = { records, files, me, teams } as const;`}
433
+ export const contract = { records, email: emailContract(manifest.code), files, me, teams, telephony } as const;`}
433
434
  registerHitchContract(pruneContract(contract, manifest));
434
435
 
435
436
  declare module "@hitch42/applet" {
@@ -442,14 +443,14 @@ export type * from "./zod.gen.ts";
442
443
  `);
443
444
  }
444
445
  async function syncContract(outDir, manifest, options = {}) {
445
- await writeContractFiles(outDir, manifest, await loadAuthenticatedSpec(manifest.org, options));
446
+ await writeContractFiles(outDir, manifest, await loadAuthenticatedSpec(manifest, options));
446
447
  }
447
448
  async function runGenerate(options) {
448
449
  await prepareAppletProject();
449
450
  const root = process.cwd();
450
451
  const outDir = resolve("./.hitch");
451
452
  const manifest = await loadAppletConfig(process.cwd());
452
- const { spec, theme: themeStylesheet } = await loadBuildInputs(manifest.org, options);
453
+ const { spec, theme: themeStylesheet } = await loadBuildInputs(manifest, options);
453
454
  const stagedDir = await mkdtemp(resolve("./.hitch.tmp-"));
454
455
  const backupDir = `${stagedDir}.backup`;
455
456
  let staged = true;
@@ -0,0 +1,2 @@
1
+ import { n as runGenerate } from "./generate-BxYHdoAQ.js";
2
+ export { runGenerate };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,14 @@
1
- import { _ as RegisteredWorkflows, a as AppletSourceDefinition, c as appletManifestSchema, d as RegisteredCatalog, f as RegisteredContract, g as RegisteredVariables, h as RegisteredVariableKeys, i as AppletPackages, l as appletSourceDefinitionSchema, m as RegisteredRouter, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredManifest, r as AppletManifestObject, s as appletDefinitionSchema, t as AppletDefinition, u as HitchRegister, v as registerHitchContract } from "./manifest-BQCAxATS.js";
2
- import { n as pruneContract, t as NarrowContract } from "./contract-DMrpbaLJ.js";
1
+ import { _ as RegisteredWorkflows, a as AppletSourceDefinition, c as appletManifestSchema, d as RegisteredCatalog, f as RegisteredContract, g as RegisteredVariables, h as RegisteredVariableKeys, i as AppletPackages, l as appletSourceDefinitionSchema, m as RegisteredRouter, n as AppletManifest, o as RegisteredAppletSourceDefinition, p as RegisteredManifest, r as AppletManifestObject, s as appletDefinitionSchema, t as AppletDefinition, u as HitchRegister, v as registerHitchContract } from "./manifest-DD_SGkS6.js";
2
+ import { n as pruneContract, t as NarrowContract } from "./contract-rP_eV9PK.js";
3
3
  import { a as UploadedHitchFile, c as createFileOutputSchema, d as getFileOutputSchema, i as UploadProgress, l as fileSchema, n as FilesUpload, r as UploadFileOptions, s as uploadFile, t as FilesClient, u as filesContract } from "./upload-YbRKEqR6.js";
4
+ import { a as createEmailPixelOutputSchema, c as emailTagsSchema, d as listEmailTrackersInputSchema, f as listEmailTrackersOutputSchema, i as createEmailPixelInputSchema, l as emailTrackerSchema, m as markEmailTrackerSentInputSchema, n as EmailTracker, o as emailContract, r as ListEmailTrackersOutput, s as emailTagKeySchema, t as TelephonyMessageReceivedEvent, u as getEmailTrackerInputSchema } from "./telephony-protocol-DRgiYjqQ.js";
4
5
  import { ContractProcedure, Meta } from "@orpc/contract";
5
6
  import { z } from "zod";
6
- //#region src/workspace.d.ts
7
+ //#region ../shared/auth/src/workspace.d.mts
7
8
  interface HitchConfig {
8
9
  sdk: string;
9
10
  org: string;
11
+ githubWorkflow?: boolean;
10
12
  }
11
13
  //#endregion
12
14
  //#region src/hitch/me.d.ts
@@ -39,6 +41,115 @@ type MeContract = {
39
41
  };
40
42
  declare const meContract: MeContract;
41
43
  //#endregion
44
+ //#region src/hitch/telephony.d.ts
45
+ type HitchPhoneNumber = {
46
+ id: string;
47
+ e164: string;
48
+ label: string;
49
+ enabled: boolean;
50
+ canRead: boolean;
51
+ canSend: boolean;
52
+ canCall: boolean;
53
+ voiceEnabled: boolean;
54
+ };
55
+ type HitchCall = {
56
+ id: string;
57
+ numberId: string;
58
+ direction: "inbound" | "outbound";
59
+ status: "starting" | "ringing" | "active" | "ended" | "missed" | "failed";
60
+ from: string;
61
+ to: string;
62
+ userId: string | null;
63
+ answeredAt: string | null;
64
+ endedAt: string | null;
65
+ durationSeconds: number | null;
66
+ voicemailSeconds: number | null;
67
+ hangupCause: string | null;
68
+ record: boolean;
69
+ hasRecording: boolean;
70
+ transcriptStatus: "pending" | "done" | "failed" | null;
71
+ transcript: {
72
+ segments: {
73
+ side: "member" | "customer";
74
+ speaker: number;
75
+ start: number;
76
+ end: number;
77
+ text: string;
78
+ }[];
79
+ } | null;
80
+ createdAt: string;
81
+ };
82
+ type ListHitchCallsInput = ListHitchMessagesInput & {
83
+ status?: HitchCall["status"];
84
+ };
85
+ type HitchMessage = {
86
+ id: string;
87
+ numberId: string;
88
+ direction: "inbound" | "outbound";
89
+ status: "pending" | "unknown" | "accepted" | "sent" | "delivered" | "unconfirmed" | "failed" | "received";
90
+ from: string;
91
+ to: string;
92
+ body: string | null;
93
+ redacted: boolean;
94
+ userId: string | null;
95
+ appletId: string | null;
96
+ requestId: string | null;
97
+ errorCode: string | null;
98
+ errorDetail: string | null;
99
+ statusAt: string | null;
100
+ createdAt: string;
101
+ };
102
+ type ListHitchMessagesInput = {
103
+ numberId?: string;
104
+ userId?: string;
105
+ direction?: "inbound" | "outbound";
106
+ since?: string;
107
+ until?: string;
108
+ cursor?: string;
109
+ limit?: number;
110
+ };
111
+ type SendHitchMessageInput = {
112
+ numberId: string;
113
+ to: string;
114
+ body: string;
115
+ requestId?: string;
116
+ };
117
+ type MessageIdInput = {
118
+ id: string;
119
+ };
120
+ type NumbersOutput = {
121
+ data: HitchPhoneNumber[];
122
+ };
123
+ type MessagesOutput = {
124
+ data: HitchMessage[];
125
+ nextCursor: string | null;
126
+ };
127
+ type CallsOutput = {
128
+ data: HitchCall[];
129
+ nextCursor: string | null;
130
+ };
131
+ declare const hitchPhoneNumberSchema: z.ZodType<HitchPhoneNumber>;
132
+ declare const hitchMessageSchema: z.ZodType<HitchMessage>;
133
+ declare const listHitchNumbersOutputSchema: z.ZodType<NumbersOutput>;
134
+ declare const listHitchMessagesOutputSchema: z.ZodType<MessagesOutput>;
135
+ declare const listHitchMessagesInputSchema: z.ZodType<ListHitchMessagesInput>;
136
+ declare const sendHitchMessageInputSchema: z.ZodType<SendHitchMessageInput>;
137
+ type TelephonyContract = {
138
+ calls: {
139
+ get: ContractProcedure<z.ZodType<MessageIdInput>, z.ZodType<HitchCall>, Record<never, never>, Meta>;
140
+ list: ContractProcedure<z.ZodType<ListHitchCallsInput>, z.ZodType<CallsOutput>, Record<never, never>, Meta>;
141
+ };
142
+ numbers: {
143
+ list: ContractProcedure<z.ZodType<void>, z.ZodType<NumbersOutput>, Record<never, never>, Meta>;
144
+ };
145
+ messages: {
146
+ get: ContractProcedure<z.ZodType<MessageIdInput>, z.ZodType<HitchMessage>, Record<never, never>, Meta>;
147
+ list: ContractProcedure<z.ZodType<ListHitchMessagesInput>, z.ZodType<MessagesOutput>, Record<never, never>, Meta>;
148
+ send: ContractProcedure<z.ZodType<SendHitchMessageInput>, z.ZodType<HitchMessage>, Record<never, never>, Meta>;
149
+ };
150
+ };
151
+ declare const telephonyContract: TelephonyContract;
152
+ //#endregion
42
153
  //#region src/hitch/teams.d.ts
43
154
  type HitchTeam = {
44
155
  id: string;
@@ -71,4 +182,4 @@ type TeamsContract = {
71
182
  };
72
183
  declare const teamsContract: TeamsContract;
73
184
  //#endregion
74
- export { type AppletDefinition, type AppletManifest, type AppletManifestObject, type AppletPackages, type AppletSourceDefinition, type FilesClient, type FilesUpload, type HitchConfig, type HitchMe, type HitchRegister, type HitchTeam, type HitchTeamMember, type NarrowContract, type RegisteredAppletSourceDefinition, type RegisteredCatalog, type RegisteredContract, type RegisteredManifest, type RegisteredRouter, type RegisteredVariableKeys, type RegisteredVariables, type RegisteredWorkflows, type UploadFileOptions, type UploadProgress, type UploadedHitchFile, appletDefinitionSchema, appletManifestSchema, appletSourceDefinitionSchema, createFileOutputSchema, fileSchema, filesContract, getFileOutputSchema, meContract, meSchema, pruneContract, registerHitchContract, teamMemberSchema, teamSchema, teamsContract, uploadFile };
185
+ export { type AppletDefinition, type AppletManifest, type AppletManifestObject, type AppletPackages, type AppletSourceDefinition, type EmailTracker, type FilesClient, type FilesUpload, type HitchConfig, type HitchMe, type HitchMessage, type HitchPhoneNumber, type HitchRegister, type HitchTeam, type HitchTeamMember, type ListEmailTrackersOutput, type ListHitchMessagesInput, type NarrowContract, type RegisteredAppletSourceDefinition, type RegisteredCatalog, type RegisteredContract, type RegisteredManifest, type RegisteredRouter, type RegisteredVariableKeys, type RegisteredVariables, type RegisteredWorkflows, type SendHitchMessageInput, type TelephonyContract, type TelephonyMessageReceivedEvent, type UploadFileOptions, type UploadProgress, type UploadedHitchFile, appletDefinitionSchema, appletManifestSchema, appletSourceDefinitionSchema, createEmailPixelInputSchema, createEmailPixelOutputSchema, createFileOutputSchema, emailContract, emailTagKeySchema, emailTagsSchema, emailTrackerSchema, fileSchema, filesContract, getEmailTrackerInputSchema, getFileOutputSchema, hitchMessageSchema, hitchPhoneNumberSchema, listEmailTrackersInputSchema, listEmailTrackersOutputSchema, listHitchMessagesInputSchema, listHitchMessagesOutputSchema, listHitchNumbersOutputSchema, markEmailTrackerSentInputSchema, meContract, meSchema, pruneContract, registerHitchContract, sendHitchMessageInputSchema, teamMemberSchema, teamSchema, teamsContract, telephonyContract, uploadFile };
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { i as registerHitchContract, t as uploadFile } from "./upload-DRbVhuDm.js";
2
- import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-DyoJ1MIL.js";
2
+ import { a as emailTagsSchema, c as listEmailTrackersInputSchema, d as markEmailTrackerSentInputSchema, i as emailTagKeySchema, l as listEmailTrackersOutputSchema, n as createEmailPixelOutputSchema, o as emailTrackerSchema, r as emailContract, s as getEmailTrackerInputSchema, t as createEmailPixelInputSchema } from "./email-DBTVhNB_.js";
3
+ import { n as meSchema, t as meContract } from "./me-BW7Paary.js";
4
+ import { n as appletManifestSchema, r as appletSourceDefinitionSchema, t as appletDefinitionSchema } from "./manifest-Bp87Uz0a.js";
3
5
  import { oc } from "@orpc/contract";
4
6
  import { z } from "zod";
5
7
  //#region src/hitch/contract.ts
@@ -78,34 +80,147 @@ const filesContract = {
78
80
  }).input(fileIdInputSchema).output(getFileOutputSchema)
79
81
  };
80
82
  //#endregion
81
- //#region src/hitch/me.ts
82
- const personSchema = z.object({
83
+ //#region src/hitch/telephony.ts
84
+ const hitchPhoneNumberSchema = z.object({
83
85
  id: z.uuid(),
84
- firstName: z.string(),
85
- lastName: z.string(),
86
- email: z.email()
86
+ e164: z.string(),
87
+ label: z.string(),
88
+ enabled: z.boolean(),
89
+ canRead: z.boolean(),
90
+ canSend: z.boolean(),
91
+ canCall: z.boolean(),
92
+ voiceEnabled: z.boolean()
93
+ });
94
+ const hitchCallSchema = z.object({
95
+ id: z.uuid(),
96
+ numberId: z.uuid(),
97
+ direction: z.enum(["inbound", "outbound"]),
98
+ status: z.enum([
99
+ "starting",
100
+ "ringing",
101
+ "active",
102
+ "ended",
103
+ "missed",
104
+ "failed"
105
+ ]),
106
+ from: z.string(),
107
+ to: z.string(),
108
+ userId: z.uuid().nullable(),
109
+ answeredAt: z.string().nullable(),
110
+ endedAt: z.string().nullable(),
111
+ durationSeconds: z.number().nullable(),
112
+ voicemailSeconds: z.number().nullable(),
113
+ hangupCause: z.string().nullable(),
114
+ record: z.boolean(),
115
+ hasRecording: z.boolean(),
116
+ transcriptStatus: z.enum([
117
+ "pending",
118
+ "done",
119
+ "failed"
120
+ ]).nullable(),
121
+ transcript: z.object({ segments: z.array(z.object({
122
+ side: z.enum(["member", "customer"]),
123
+ speaker: z.number(),
124
+ start: z.number(),
125
+ end: z.number(),
126
+ text: z.string()
127
+ })) }).nullable(),
128
+ createdAt: z.string()
129
+ });
130
+ const hitchMessageSchema = z.object({
131
+ id: z.uuid(),
132
+ numberId: z.uuid(),
133
+ direction: z.enum(["inbound", "outbound"]),
134
+ status: z.enum([
135
+ "pending",
136
+ "unknown",
137
+ "accepted",
138
+ "sent",
139
+ "delivered",
140
+ "unconfirmed",
141
+ "failed",
142
+ "received"
143
+ ]),
144
+ from: z.string(),
145
+ to: z.string(),
146
+ body: z.string().nullable(),
147
+ redacted: z.boolean(),
148
+ userId: z.uuid().nullable(),
149
+ appletId: z.uuid().nullable(),
150
+ requestId: z.string().nullable(),
151
+ errorCode: z.string().nullable(),
152
+ errorDetail: z.string().nullable(),
153
+ statusAt: z.string().nullable(),
154
+ createdAt: z.string()
155
+ });
156
+ const listHitchNumbersOutputSchema = z.object({ data: z.array(hitchPhoneNumberSchema) });
157
+ const listHitchMessagesOutputSchema = z.object({
158
+ data: z.array(hitchMessageSchema),
159
+ nextCursor: z.string().nullable()
160
+ });
161
+ const listHitchCallsOutputSchema = z.object({
162
+ data: z.array(hitchCallSchema),
163
+ nextCursor: z.string().nullable()
87
164
  });
88
- const membershipSchema = z.object({
89
- orgId: z.uuid(),
90
- code: z.string(),
91
- name: z.string(),
92
- iconFileId: z.uuid().nullable(),
93
- role: z.enum(["member", "owner"]),
94
- capabilities: z.array(z.string())
165
+ const idInputSchema = z.object({ id: z.uuid() });
166
+ const listInputFields = {
167
+ numberId: z.uuid().optional(),
168
+ userId: z.uuid().optional(),
169
+ direction: z.enum(["inbound", "outbound"]).optional(),
170
+ since: z.iso.datetime().optional(),
171
+ until: z.iso.datetime().optional(),
172
+ cursor: z.string().optional(),
173
+ limit: z.number().int().min(1).max(200).optional()
174
+ };
175
+ const listHitchMessagesInputSchema = z.object(listInputFields);
176
+ const listHitchCallsInputSchema = z.object({
177
+ ...listInputFields,
178
+ status: z.enum([
179
+ "starting",
180
+ "ringing",
181
+ "active",
182
+ "ended",
183
+ "missed",
184
+ "failed"
185
+ ]).optional()
95
186
  });
96
- const meSchema = z.object({
97
- person: personSchema,
98
- memberships: z.array(membershipSchema),
99
- organization: z.object({
100
- id: z.uuid(),
101
- code: z.string()
102
- }).nullable(),
103
- multiOrg: z.boolean()
187
+ const sendHitchMessageInputSchema = z.object({
188
+ numberId: z.uuid(),
189
+ to: z.string(),
190
+ body: z.string().min(1).max(1600),
191
+ requestId: z.string().min(1).max(200).optional()
104
192
  });
105
- const meContract = { get: oc.route({
106
- method: "GET",
107
- path: "/v1/me"
108
- }).input(z.void()).output(meSchema) };
193
+ const telephonyContract = {
194
+ calls: {
195
+ get: oc.route({
196
+ method: "GET",
197
+ path: "/v1/telephony/calls/{id}"
198
+ }).input(idInputSchema).output(hitchCallSchema),
199
+ list: oc.route({
200
+ method: "GET",
201
+ path: "/v1/telephony/calls"
202
+ }).input(listHitchCallsInputSchema).output(listHitchCallsOutputSchema)
203
+ },
204
+ numbers: { list: oc.route({
205
+ method: "GET",
206
+ path: "/v1/telephony/numbers"
207
+ }).input(z.void()).output(listHitchNumbersOutputSchema) },
208
+ messages: {
209
+ get: oc.route({
210
+ method: "GET",
211
+ path: "/v1/telephony/messages/{id}"
212
+ }).input(idInputSchema).output(hitchMessageSchema),
213
+ list: oc.route({
214
+ method: "GET",
215
+ path: "/v1/telephony/messages"
216
+ }).input(listHitchMessagesInputSchema).output(listHitchMessagesOutputSchema),
217
+ send: oc.route({
218
+ method: "POST",
219
+ path: "/v1/telephony/messages",
220
+ successStatus: 201
221
+ }).input(sendHitchMessageInputSchema).output(hitchMessageSchema)
222
+ }
223
+ };
109
224
  //#endregion
110
225
  //#region src/hitch/teams.ts
111
226
  const teamSchema = z.object({
@@ -133,4 +248,4 @@ const teamsContract = {
133
248
  }).input(teamIdInputSchema).output(teamMembersOutputSchema) }
134
249
  };
135
250
  //#endregion
136
- export { appletDefinitionSchema, appletManifestSchema, appletSourceDefinitionSchema, createFileOutputSchema, fileSchema, filesContract, getFileOutputSchema, meContract, meSchema, pruneContract, registerHitchContract, teamMemberSchema, teamSchema, teamsContract, uploadFile };
251
+ export { appletDefinitionSchema, appletManifestSchema, appletSourceDefinitionSchema, createEmailPixelInputSchema, createEmailPixelOutputSchema, createFileOutputSchema, emailContract, emailTagKeySchema, emailTagsSchema, emailTrackerSchema, fileSchema, filesContract, getEmailTrackerInputSchema, getFileOutputSchema, hitchMessageSchema, hitchPhoneNumberSchema, listEmailTrackersInputSchema, listEmailTrackersOutputSchema, listHitchMessagesInputSchema, listHitchMessagesOutputSchema, listHitchNumbersOutputSchema, markEmailTrackerSentInputSchema, meContract, meSchema, pruneContract, registerHitchContract, sendHitchMessageInputSchema, teamMemberSchema, teamSchema, teamsContract, telephonyContract, uploadFile };
@@ -1,8 +1,8 @@
1
- import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-DyoJ1MIL.js";
2
- import { i as resolveInstanceUrl, r as resolveAuthForOrg } from "./auth-DaVK0k5R.js";
3
- import { n as runGenerate } from "./generate-C6eAL5eo.js";
4
- import { n as loadAppletSourceDefinition, r as readWorkspaceConfig } from "./load-config-BnxocLAQ.js";
5
- import { a as writeWorkspaceSupport, i as writeAppletSupport, n as loadCliManifest, t as assertWorkspaceCli } from "./project-mW0vsN8A.js";
1
+ import { a as ORG_CODE_PATTERN, i as APPLET_CODE_PATTERN } from "./manifest-Bp87Uz0a.js";
2
+ import { d as resolveInstanceUrl, i as readWorkspaceConfig, u as resolveAuthForOrg } from "./workspace-XVtM12ZC.js";
3
+ import { n as runGenerate } from "./generate-BxYHdoAQ.js";
4
+ import { n as loadAppletSourceDefinition } from "./load-config-BYSxDVAl.js";
5
+ import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-CbYPtpPq.js";
6
6
  import { access, cp, mkdir, readdir, writeFile } from "node:fs/promises";
7
7
  import { relative, resolve } from "node:path";
8
8
  import { spawn } from "node:child_process";
@@ -0,0 +1,27 @@
1
+ import { r as appletSourceDefinitionSchema } from "./manifest-Bp87Uz0a.js";
2
+ import { t as resolveWorkspaceOrg } from "./workspace-XVtM12ZC.js";
3
+ import { existsSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import { loadConfigFromFile } from "vite";
6
+ //#region src/typegen/load-config.ts
7
+ async function loadAppletSourceDefinition(root) {
8
+ const path = resolve(root, "applet.manifest.ts");
9
+ if (!existsSync(path)) throw new Error(`No applet manifest found at ${path}.`);
10
+ const loaded = await loadConfigFromFile({
11
+ command: "build",
12
+ mode: "production"
13
+ }, path, root);
14
+ if (loaded === null) throw new Error(`No applet manifest found at ${path}.`);
15
+ const parsed = appletSourceDefinitionSchema.safeParse(loaded.config);
16
+ if (!parsed.success) throw new Error(`Invalid applet manifest at ${loaded.path}: ${parsed.error.message}`);
17
+ return parsed.data;
18
+ }
19
+ async function loadAppletConfig(root) {
20
+ const { dependencies: _dependencies, devDependencies: _devDependencies, ...definition } = await loadAppletSourceDefinition(root);
21
+ return {
22
+ org: resolveWorkspaceOrg(root),
23
+ ...definition
24
+ };
25
+ }
26
+ //#endregion
27
+ export { loadAppletSourceDefinition as n, loadAppletConfig as t };
@@ -0,0 +1,12 @@
1
+ import { a as loginWithDevice, d as resolveInstanceUrl, o as AuthenticationError, r as findWorkspaceConfig } from "./workspace-XVtM12ZC.js";
2
+ //#region src/login.ts
3
+ async function runLogin(options) {
4
+ if (process.env.HITCH_API_KEY !== void 0) throw new AuthenticationError("HITCH_API_KEY is set — unset it to manage stored logins.");
5
+ const { me, membership } = await loginWithDevice(await resolveInstanceUrl(), {
6
+ expectedOrg: findWorkspaceConfig(process.cwd())?.org,
7
+ noBrowser: options.noBrowser
8
+ });
9
+ console.log(`Signed in as ${me.person.email} to ${membership.name}.`);
10
+ }
11
+ //#endregion
12
+ export { runLogin };
@@ -1,6 +1,6 @@
1
- import { i as APPLET_CODE_PATTERN } from "./manifest-DyoJ1MIL.js";
2
- import { t as fetchWithOrgAuth } from "./auth-DaVK0k5R.js";
3
- import { i as resolveWorkspaceOrg, r as readWorkspaceConfig, t as loadAppletConfig } from "./load-config-BnxocLAQ.js";
1
+ import { i as APPLET_CODE_PATTERN } from "./manifest-Bp87Uz0a.js";
2
+ import { i as readWorkspaceConfig, n as fetchWithOrgAuth, t as resolveWorkspaceOrg } from "./workspace-XVtM12ZC.js";
3
+ import { t as loadAppletConfig } from "./load-config-BYSxDVAl.js";
4
4
  import { z } from "zod";
5
5
  //#region src/logs.ts
6
6
  const LOG_LEVELS = [
@@ -63,6 +63,8 @@ const appletManifestShape = {
63
63
  org: z.string().regex(ORG_CODE_PATTERN, "must start with a lowercase letter, end with a letter or number, and contain only lowercase letters, numbers, and non-consecutive hyphens"),
64
64
  name: nameSchema,
65
65
  code: codeSchema,
66
+ requiresChangeset: z.uuid().optional(),
67
+ telephony: z.strictObject({ events: z.array(z.literal("message.received")).min(1).refine((events) => new Set(events).size === events.length).readonly() }).optional(),
66
68
  schedules: appletManifestSchedulesSchema.optional(),
67
69
  variables: appletManifestVariablesSchema.optional(),
68
70
  objects: appletManifestObjectsSchema
@@ -94,6 +96,8 @@ const appletManifestSchema = z.strictObject(appletManifestShape).superRefine(che
94
96
  const appletDefinitionSchema = z.strictObject({
95
97
  name: appletManifestShape.name,
96
98
  code: appletManifestShape.code,
99
+ requiresChangeset: appletManifestShape.requiresChangeset,
100
+ telephony: appletManifestShape.telephony,
97
101
  schedules: appletManifestShape.schedules,
98
102
  variables: appletManifestShape.variables,
99
103
  objects: appletManifestShape.objects
@@ -161,6 +165,8 @@ const checkSourcePackages = (manifest, context) => {
161
165
  const appletSourceDefinitionSchema = z.strictObject({
162
166
  name: appletManifestShape.name,
163
167
  code: appletManifestShape.code,
168
+ requiresChangeset: appletManifestShape.requiresChangeset,
169
+ telephony: appletManifestShape.telephony,
164
170
  schedules: appletManifestShape.schedules,
165
171
  variables: appletManifestShape.variables,
166
172
  objects: appletManifestShape.objects,
@@ -32,6 +32,11 @@ interface AppletManifest {
32
32
  org: string;
33
33
  name: string;
34
34
  code: string;
35
+ /** This code needs the schema as of this changeset. */
36
+ requiresChangeset?: string;
37
+ telephony?: {
38
+ events: readonly "message.received"[];
39
+ };
35
40
  schedules?: readonly {
36
41
  code: string;
37
42
  name: string;
@@ -0,0 +1,32 @@
1
+ import { oc } from "@orpc/contract";
2
+ import { z } from "zod";
3
+ //#region src/hitch/me.ts
4
+ const personSchema = z.object({
5
+ id: z.uuid(),
6
+ firstName: z.string(),
7
+ lastName: z.string(),
8
+ email: z.email()
9
+ });
10
+ const membershipSchema = z.object({
11
+ orgId: z.uuid(),
12
+ code: z.string(),
13
+ name: z.string(),
14
+ iconFileId: z.uuid().nullable(),
15
+ role: z.enum(["member", "owner"]),
16
+ capabilities: z.array(z.string())
17
+ });
18
+ const meSchema = z.object({
19
+ person: personSchema,
20
+ memberships: z.array(membershipSchema),
21
+ organization: z.object({
22
+ id: z.uuid(),
23
+ code: z.string()
24
+ }).nullable(),
25
+ multiOrg: z.boolean()
26
+ });
27
+ const meContract = { get: oc.route({
28
+ method: "GET",
29
+ path: "/v1/me"
30
+ }).input(z.void()).output(meSchema) };
31
+ //#endregion
32
+ export { meSchema as n, meContract as t };