@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
@@ -1,4 +1,5 @@
1
- import { n as loadAppletSourceDefinition, r as readWorkspaceConfig } from "./load-config-BnxocLAQ.js";
1
+ import { i as readWorkspaceConfig } from "./workspace-XVtM12ZC.js";
2
+ import { n as loadAppletSourceDefinition } from "./load-config-BYSxDVAl.js";
2
3
  import { z } from "zod";
3
4
  import { existsSync } from "node:fs";
4
5
  import { cp, mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
@@ -130,7 +131,8 @@ const GITIGNORE_END = "# END Hitch generated files";
130
131
  const SKILLS = [
131
132
  "hitch-applets",
132
133
  "hitch-cli",
133
- "hitch-data"
134
+ "hitch-data",
135
+ "hitch-theory"
134
136
  ];
135
137
  const GITIGNORE = `${GITIGNORE_START}
136
138
  ${SKILLS.map((skill) => `/.agents/skills/${skill}/`).join("\n")}
@@ -178,7 +180,7 @@ async function writeWorkspaceSupport(root, config, cli) {
178
180
  const agents = await readFile(new URL("../scaffold/AGENTS.md", import.meta.url), "utf8");
179
181
  await Promise.all([
180
182
  mkdir(resolve(root, ".agents/skills"), { recursive: true }),
181
- mkdir(resolve(root, ".github/workflows"), { recursive: true }),
183
+ config.githubWorkflow === false ? void 0 : mkdir(resolve(root, ".github/workflows"), { recursive: true }),
182
184
  ...SKILLS.map((skill) => rm(resolve(root, ".agents/skills", skill), {
183
185
  force: true,
184
186
  recursive: true
@@ -188,7 +190,7 @@ async function writeWorkspaceSupport(root, config, cli) {
188
190
  ...SKILLS.map((skill) => cp(new URL(`../scaffold/.agents/skills/${skill}`, import.meta.url), resolve(root, ".agents/skills", skill), { recursive: true })),
189
191
  writeFile(resolve(root, "package.json"), `${JSON.stringify(workspacePackage(config.org), null, 2)}\n`),
190
192
  writeFile(resolve(root, "pnpm-workspace.yaml"), workspaceFile(resolvedCli)),
191
- 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),
192
194
  writeFile(resolve(root, ".node-version"), "24\n"),
193
195
  writeGitignore(root),
194
196
  writeFile(resolve(root, "AGENTS.md"), agents)
@@ -340,17 +342,17 @@ export default defineConfig({
340
342
  hasClient ? writeFile(resolve(root, "components.json"), await readFile(new URL("../scaffold/applet/components.json", import.meta.url), "utf8")) : void 0
341
343
  ]);
342
344
  }
343
- async function prepareAppletProject(appletRoot = process.cwd()) {
344
- const definition = await loadAppletSourceDefinition(appletRoot);
345
- const workspaceRoot = dirname(dirname(resolve(appletRoot)));
345
+ async function prepareAppletProjects(workspaceRoot, appletRoots) {
346
+ const definitions = await Promise.all(appletRoots.map((root) => loadAppletSourceDefinition(root)));
346
347
  const workspace = readWorkspaceConfig(workspaceRoot);
347
- if (workspace === void 0) throw new Error(`No Hitch workspace found for ${appletRoot}.`);
348
+ if (workspace === void 0) throw new Error(`No Hitch workspace found at ${workspaceRoot}.`);
348
349
  const cli = await loadCliManifest({ allowDevelopment: true });
349
- await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), writeAppletSupport(appletRoot, definition)]);
350
- return {
351
- definition,
352
- workspaceRoot
353
- };
350
+ await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), ...appletRoots.map((root, index) => writeAppletSupport(root, definitions[index]))]);
351
+ }
352
+ async function prepareAppletProject(appletRoot = process.cwd()) {
353
+ const workspaceRoot = dirname(dirname(resolve(appletRoot)));
354
+ await prepareAppletProjects(workspaceRoot, [appletRoot]);
355
+ return workspaceRoot;
354
356
  }
355
357
  //#endregion
356
- export { writeWorkspaceSupport as a, writeAppletSupport as i, loadCliManifest as n, prepareAppletProject as r, assertWorkspaceCli as t };
358
+ export { writeAppletSupport as a, prepareAppletProjects as i, loadCliManifest as n, writeWorkspaceSupport as o, prepareAppletProject as r, assertWorkspaceCli as t };
@@ -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-BQCAxATS.js";
3
- import { t as NarrowContract } from "./contract-DMrpbaLJ.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 };