@hitch42/applet 0.1.1-beta.7 → 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 (49) hide show
  1. package/dist/_internal/server.d.ts +14 -1
  2. package/dist/_internal/server.js +23 -74
  3. package/dist/applet.js +22 -11
  4. package/dist/build-CFCKKMn7.js +2 -0
  5. package/dist/{build-DauirTcY.js → build-DANx9Hgg.js} +1 -1
  6. package/dist/{ci-gPrwo6C0.js → ci-5qWl7lT3.js} +1 -1
  7. package/dist/client.d.ts +2 -2
  8. package/dist/{contract-DB9QQhD9.d.ts → contract-rP_eV9PK.d.ts} +1 -1
  9. package/dist/{deploy-CqrtNJ1x.js → deploy-MQWLG2EA.js} +3 -3
  10. package/dist/email-DBTVhNB_.js +62 -0
  11. package/dist/{generate-BIifT6PK.js → generate-BxYHdoAQ.js} +9 -8
  12. package/dist/generate-CQ07Hdpo.js +2 -0
  13. package/dist/index.d.ts +114 -3
  14. package/dist/index.js +141 -26
  15. package/dist/{init-Wu6XmyVc.js → init-jDEgYIXg.js} +5 -5
  16. package/dist/{load-config-BknBkdRs.js → load-config-BYSxDVAl.js} +2 -2
  17. package/dist/{login-iT9MRuaw.js → login-C7RKmmTe.js} +1 -1
  18. package/dist/{logs-B-qZGXSK.js → logs-DgjgAxj2.js} +3 -3
  19. package/dist/{manifest-Bd04cWhu.js → manifest-Bp87Uz0a.js} +3 -0
  20. package/dist/{manifest-C489nYUy.d.ts → manifest-DD_SGkS6.d.ts} +3 -0
  21. package/dist/me-BW7Paary.js +32 -0
  22. package/dist/{project-C_rtpjp8.js → project-CbYPtpPq.js} +6 -5
  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-DcwMeIau.js → variables-Bwnr7oxf.js} +3 -28
  30. package/dist/vite.d.ts +1 -1
  31. package/dist/vite.js +457 -22
  32. package/dist/workflow-engine-MogejNfF.js +117 -0
  33. package/dist/{workspace-B6lenAS5.js → workspace-XVtM12ZC.js} +5 -2
  34. package/package.json +6 -1
  35. package/scaffold/.agents/skills/hitch-applets/SKILL.md +24 -18
  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 +4 -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 +20 -20
  45. package/scaffold/.agents/skills/hitch-data/SKILL.md +1 -1
  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/dist/build-DhNDp7ji.js +0 -2
  49. package/dist/generate-DSk8ihsC.js +0 -2
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-Bd04cWhu.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-Bd04cWhu.js";
2
- import { c as resolveAuthForOrg, i as readWorkspaceConfig, l as resolveInstanceUrl } from "./workspace-B6lenAS5.js";
3
- import { n as runGenerate } from "./generate-BIifT6PK.js";
4
- import { n as loadAppletSourceDefinition } from "./load-config-BknBkdRs.js";
5
- import { a as writeAppletSupport, n as loadCliManifest, o as writeWorkspaceSupport, t as assertWorkspaceCli } from "./project-C_rtpjp8.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";
@@ -1,5 +1,5 @@
1
- import { r as appletSourceDefinitionSchema } from "./manifest-Bd04cWhu.js";
2
- import { t as resolveWorkspaceOrg } from "./workspace-B6lenAS5.js";
1
+ import { r as appletSourceDefinitionSchema } from "./manifest-Bp87Uz0a.js";
2
+ import { t as resolveWorkspaceOrg } from "./workspace-XVtM12ZC.js";
3
3
  import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { loadConfigFromFile } from "vite";
@@ -1,4 +1,4 @@
1
- import { a as loginWithDevice, l as resolveInstanceUrl, o as AuthenticationError, r as findWorkspaceConfig } from "./workspace-B6lenAS5.js";
1
+ import { a as loginWithDevice, d as resolveInstanceUrl, o as AuthenticationError, r as findWorkspaceConfig } from "./workspace-XVtM12ZC.js";
2
2
  //#region src/login.ts
3
3
  async function runLogin(options) {
4
4
  if (process.env.HITCH_API_KEY !== void 0) throw new AuthenticationError("HITCH_API_KEY is set — unset it to manage stored logins.");
@@ -1,6 +1,6 @@
1
- import { i as APPLET_CODE_PATTERN } from "./manifest-Bd04cWhu.js";
2
- import { i as readWorkspaceConfig, n as fetchWithOrgAuth, t as resolveWorkspaceOrg } from "./workspace-B6lenAS5.js";
3
- import { t as loadAppletConfig } from "./load-config-BknBkdRs.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 = [
@@ -64,6 +64,7 @@ const appletManifestShape = {
64
64
  name: nameSchema,
65
65
  code: codeSchema,
66
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(),
67
68
  schedules: appletManifestSchedulesSchema.optional(),
68
69
  variables: appletManifestVariablesSchema.optional(),
69
70
  objects: appletManifestObjectsSchema
@@ -96,6 +97,7 @@ const appletDefinitionSchema = z.strictObject({
96
97
  name: appletManifestShape.name,
97
98
  code: appletManifestShape.code,
98
99
  requiresChangeset: appletManifestShape.requiresChangeset,
100
+ telephony: appletManifestShape.telephony,
99
101
  schedules: appletManifestShape.schedules,
100
102
  variables: appletManifestShape.variables,
101
103
  objects: appletManifestShape.objects
@@ -164,6 +166,7 @@ const appletSourceDefinitionSchema = z.strictObject({
164
166
  name: appletManifestShape.name,
165
167
  code: appletManifestShape.code,
166
168
  requiresChangeset: appletManifestShape.requiresChangeset,
169
+ telephony: appletManifestShape.telephony,
167
170
  schedules: appletManifestShape.schedules,
168
171
  variables: appletManifestShape.variables,
169
172
  objects: appletManifestShape.objects,
@@ -34,6 +34,9 @@ interface AppletManifest {
34
34
  code: string;
35
35
  /** This code needs the schema as of this changeset. */
36
36
  requiresChangeset?: string;
37
+ telephony?: {
38
+ events: readonly "message.received"[];
39
+ };
37
40
  schedules?: readonly {
38
41
  code: string;
39
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 };
@@ -1,5 +1,5 @@
1
- import { i as readWorkspaceConfig } from "./workspace-B6lenAS5.js";
2
- import { n as loadAppletSourceDefinition } from "./load-config-BknBkdRs.js";
1
+ import { i as readWorkspaceConfig } from "./workspace-XVtM12ZC.js";
2
+ import { n as loadAppletSourceDefinition } from "./load-config-BYSxDVAl.js";
3
3
  import { z } from "zod";
4
4
  import { existsSync } from "node:fs";
5
5
  import { cp, mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
@@ -131,7 +131,8 @@ const GITIGNORE_END = "# END Hitch generated files";
131
131
  const SKILLS = [
132
132
  "hitch-applets",
133
133
  "hitch-cli",
134
- "hitch-data"
134
+ "hitch-data",
135
+ "hitch-theory"
135
136
  ];
136
137
  const GITIGNORE = `${GITIGNORE_START}
137
138
  ${SKILLS.map((skill) => `/.agents/skills/${skill}/`).join("\n")}
@@ -179,7 +180,7 @@ async function writeWorkspaceSupport(root, config, cli) {
179
180
  const agents = await readFile(new URL("../scaffold/AGENTS.md", import.meta.url), "utf8");
180
181
  await Promise.all([
181
182
  mkdir(resolve(root, ".agents/skills"), { recursive: true }),
182
- mkdir(resolve(root, ".github/workflows"), { recursive: true }),
183
+ config.githubWorkflow === false ? void 0 : mkdir(resolve(root, ".github/workflows"), { recursive: true }),
183
184
  ...SKILLS.map((skill) => rm(resolve(root, ".agents/skills", skill), {
184
185
  force: true,
185
186
  recursive: true
@@ -189,7 +190,7 @@ async function writeWorkspaceSupport(root, config, cli) {
189
190
  ...SKILLS.map((skill) => cp(new URL(`../scaffold/.agents/skills/${skill}`, import.meta.url), resolve(root, ".agents/skills", skill), { recursive: true })),
190
191
  writeFile(resolve(root, "package.json"), `${JSON.stringify(workspacePackage(config.org), null, 2)}\n`),
191
192
  writeFile(resolve(root, "pnpm-workspace.yaml"), workspaceFile(resolvedCli)),
192
- existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
193
+ config.githubWorkflow === false || existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
193
194
  writeFile(resolve(root, ".node-version"), "24\n"),
194
195
  writeGitignore(root),
195
196
  writeFile(resolve(root, "AGENTS.md"), agents)
@@ -0,0 +1,29 @@
1
+ import { Writable } from "node:stream";
2
+ import { createInterface } from "node:readline";
3
+ //#region src/prompt.ts
4
+ function question(prompt, hidden = false) {
5
+ return new Promise((resolveAnswer, rejectAnswer) => {
6
+ let muted = false;
7
+ const output = hidden ? new Writable({ write(chunk, encoding, callback) {
8
+ if (!muted) process.stdout.write(chunk, encoding);
9
+ callback();
10
+ } }) : process.stdout;
11
+ const readline = createInterface({
12
+ input: process.stdin,
13
+ output,
14
+ terminal: true
15
+ });
16
+ readline.once("error", rejectAnswer);
17
+ if (hidden) {
18
+ process.stdout.write(prompt);
19
+ muted = true;
20
+ }
21
+ readline.question(hidden ? "" : prompt, (answer) => {
22
+ readline.close();
23
+ if (hidden) process.stdout.write("\n");
24
+ resolveAnswer(answer);
25
+ });
26
+ });
27
+ }
28
+ //#endregion
29
+ export { question as t };
@@ -0,0 +1,42 @@
1
+ import { t as loadAppletConfig } from "./load-config-BYSxDVAl.js";
2
+ import { t as question } from "./prompt-ChS-grYO.js";
3
+ import { RPCLink } from "@orpc/client/fetch";
4
+ import { readFile } from "node:fs/promises";
5
+ import { resolve } from "node:path";
6
+ //#region src/schedules.ts
7
+ async function runSchedule(options) {
8
+ const manifest = await loadAppletConfig(process.cwd());
9
+ const schedules = manifest.schedules ?? [];
10
+ if (schedules.length === 0) throw new Error("This applet has no schedules.");
11
+ const schedule = schedules.find(({ code }) => code === options.code);
12
+ if (schedule === void 0) throw new Error(`Unknown schedule "${options.code}". Valid codes: ${schedules.map(({ code }) => code).join(", ")}.`);
13
+ const unavailable = "The dev server is not running. Start it with pnpm dev.";
14
+ let url;
15
+ try {
16
+ const file = JSON.parse(await readFile(resolve(process.cwd(), ".hitch/dev-server.json"), "utf8"));
17
+ if (file === null || typeof file !== "object" || !("url" in file) || typeof file.url !== "string" || !("pid" in file) || typeof file.pid !== "number" || !Number.isInteger(file.pid) || file.pid < 1) throw new Error(unavailable);
18
+ try {
19
+ process.kill(file.pid, 0);
20
+ } catch (error) {
21
+ if (!(error instanceof Error && "code" in error && error.code === "EPERM")) throw error;
22
+ }
23
+ url = new URL(file.url).origin;
24
+ } catch {
25
+ throw new Error(unavailable);
26
+ }
27
+ if (options.yes !== true) {
28
+ if (process.stdin.isTTY !== true) throw new Error("Pass --yes to run a schedule without a terminal.");
29
+ const answer = await question(`Run schedule "${options.code}" (${schedule.path}) now? It runs your local code as you in production org "${manifest.org}". [y/N] `);
30
+ if (!["y", "yes"].includes(answer.trim().toLowerCase())) throw new Error("Schedule run cancelled.");
31
+ }
32
+ await new RPCLink({
33
+ url: `${url}/${manifest.code}/api`,
34
+ fetch
35
+ }).call(schedule.path.split("/").filter(Boolean), {}, { context: {} }).catch((error) => {
36
+ if (error instanceof TypeError && error.message === "fetch failed") throw new Error(unavailable);
37
+ throw error;
38
+ });
39
+ console.log(`Schedule "${options.code}" finished.`);
40
+ }
41
+ //#endregion
42
+ export { runSchedule };
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as createWorkflow, i as WorkflowStep, n as WorkflowDefinition, r as WorkflowDuration } from "./workflow-DurM6Fwx.js";
2
- import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-C489nYUy.js";
3
- import { t as NarrowContract } from "./contract-DB9QQhD9.js";
2
+ import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-DD_SGkS6.js";
3
+ import { t as NarrowContract } from "./contract-rP_eV9PK.js";
4
4
  import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
5
5
  import { o as WithFilesUpload } from "./upload-YbRKEqR6.js";
6
6
  import { ContractRouterClient } from "@orpc/contract";
@@ -0,0 +1,74 @@
1
+ import { ContractProcedure, Meta } from "@orpc/contract";
2
+ import { z } from "zod";
3
+ //#region src/hitch/email.d.ts
4
+ type EmailTags = Record<string, string>;
5
+ type CreateEmailPixelInput = {
6
+ tags?: EmailTags;
7
+ };
8
+ type CreateEmailPixelOutput = {
9
+ id: string;
10
+ url: string;
11
+ };
12
+ type GetEmailTrackerInput = {
13
+ id: string;
14
+ };
15
+ type MarkEmailTrackerSentInput = {
16
+ id: string;
17
+ sentAt?: string;
18
+ };
19
+ type EmailTracker = {
20
+ id: string;
21
+ url: string;
22
+ tags: EmailTags;
23
+ createdAt: string;
24
+ sentAt: string | null;
25
+ firstHitAt: string | null;
26
+ lastHitAt: string | null;
27
+ };
28
+ type ListEmailTrackersInput = {
29
+ filter?: EmailTags;
30
+ sentAt?: {
31
+ $gte?: string;
32
+ $lt?: string;
33
+ };
34
+ cursor?: string;
35
+ limit?: number;
36
+ };
37
+ type ListEmailTrackersOutput = {
38
+ trackers: EmailTracker[];
39
+ nextCursor: string | null;
40
+ };
41
+ declare const emailTagKeySchema: z.ZodType<string>;
42
+ declare const emailTagsSchema: z.ZodType<EmailTags>;
43
+ declare const createEmailPixelInputSchema: z.ZodType<CreateEmailPixelInput>;
44
+ declare const createEmailPixelOutputSchema: z.ZodType<CreateEmailPixelOutput>;
45
+ declare const getEmailTrackerInputSchema: z.ZodType<GetEmailTrackerInput>;
46
+ declare const markEmailTrackerSentInputSchema: z.ZodType<MarkEmailTrackerSentInput>;
47
+ declare const markEmailTrackerSentBodySchema: z.ZodType<{
48
+ sentAt?: string;
49
+ }>;
50
+ declare const emailTrackerSchema: z.ZodType<EmailTracker>;
51
+ declare const listEmailTrackersInputSchema: z.ZodType<ListEmailTrackersInput>;
52
+ declare const listEmailTrackersOutputSchema: z.ZodType<ListEmailTrackersOutput>;
53
+ type EmailContract = {
54
+ tracking: {
55
+ createPixel: ContractProcedure<z.ZodType<CreateEmailPixelInput | undefined>, z.ZodType<CreateEmailPixelOutput>, Record<never, never>, Meta>;
56
+ markSent: ContractProcedure<z.ZodType<MarkEmailTrackerSentInput>, z.ZodType<EmailTracker>, Record<never, never>, Meta>;
57
+ get: ContractProcedure<z.ZodType<GetEmailTrackerInput>, z.ZodType<EmailTracker>, Record<never, never>, Meta>;
58
+ list: ContractProcedure<z.ZodType<ListEmailTrackersInput | undefined>, z.ZodType<ListEmailTrackersOutput>, Record<never, never>, Meta>;
59
+ };
60
+ };
61
+ declare function emailContract(appletCode: string): EmailContract;
62
+ //#endregion
63
+ //#region src/server/telephony-protocol.d.ts
64
+ /** Handle events at least once and without order. Use eventId for idempotency.
65
+ * Read the message with hitch.telephony.messages.get({ id: messageId }). */
66
+ type TelephonyMessageReceivedEvent = {
67
+ eventId: string;
68
+ type: "message.received";
69
+ messageId: string;
70
+ numberId: string;
71
+ occurredAt: string;
72
+ };
73
+ //#endregion
74
+ export { createEmailPixelOutputSchema as a, emailTagsSchema as c, listEmailTrackersInputSchema as d, listEmailTrackersOutputSchema as f, createEmailPixelInputSchema as i, emailTrackerSchema as l, markEmailTrackerSentInputSchema as m, EmailTracker as n, emailContract as o, markEmailTrackerSentBodySchema as p, ListEmailTrackersOutput as r, emailTagKeySchema as s, TelephonyMessageReceivedEvent as t, getEmailTrackerInputSchema as u };
@@ -0,0 +1,77 @@
1
+ //#region src/telephony/phone.d.ts
2
+ type PhoneState = {
3
+ status: "off" | "connecting" | "ready" | "error";
4
+ error: string | null;
5
+ active: null | {
6
+ callId: string;
7
+ to: string;
8
+ from: string;
9
+ state: "connecting" | "ringing" | "active" | "held" | "ended";
10
+ muted: boolean;
11
+ startedAt: number;
12
+ recording: boolean;
13
+ };
14
+ };
15
+ type CallInput = {
16
+ numberId: string;
17
+ to: string;
18
+ };
19
+ type Listener = () => void;
20
+ type ActiveControls = {
21
+ hangup: () => Promise<void>;
22
+ mute: () => void;
23
+ unmute: () => void;
24
+ hold: () => Promise<unknown>;
25
+ unhold: () => Promise<unknown>;
26
+ dtmf: (digit: string) => void;
27
+ };
28
+ declare class Phone {
29
+ state: PhoneState;
30
+ private readonly listeners;
31
+ private readonly api;
32
+ private client;
33
+ private currentCall;
34
+ private connectPromise;
35
+ private releaseLock;
36
+ private lockAbortController;
37
+ private channel;
38
+ private ownsPhone;
39
+ private connectResolve;
40
+ private readonly pendingCommands;
41
+ private pollTimer;
42
+ private stopRecording;
43
+ private recordingPromise;
44
+ private audio;
45
+ private firstLogin;
46
+ private callStarting;
47
+ constructor(options?: {
48
+ baseUrl?: string;
49
+ });
50
+ subscribe: (listener: Listener) => (() => void);
51
+ getSnapshot: () => PhoneState;
52
+ private update;
53
+ get active(): ActiveControls | null;
54
+ connect: () => Promise<void>;
55
+ private connectInternal;
56
+ private connectOwned;
57
+ disconnect: () => void;
58
+ private beforeUnload;
59
+ call: ({ numberId, to }: CallInput) => Promise<void>;
60
+ private sendCommand;
61
+ private onChannelMessage;
62
+ private runCommand;
63
+ private pollCall;
64
+ private onCallUpdate;
65
+ }
66
+ declare const createPhone: (options?: {
67
+ baseUrl?: string;
68
+ }) => Phone;
69
+ //#endregion
70
+ //#region src/telephony/use-phone.d.ts
71
+ declare const usePhone: () => {
72
+ state: PhoneState;
73
+ call: Phone["call"];
74
+ active: Phone["active"];
75
+ };
76
+ //#endregion
77
+ export { type Phone, type PhoneState, createPhone, usePhone };