@hitch42/applet 0.1.0-beta.2 → 0.1.0-beta.9

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 (55) hide show
  1. package/dist/_internal/server.d.ts +14 -1
  2. package/dist/_internal/server.js +23 -74
  3. package/dist/applet.js +53 -29
  4. package/dist/build-BfbTbt_r.js +2 -0
  5. package/dist/{build-BRkmrUcj.js → build-CAb26kMY.js} +30 -14
  6. package/dist/ci-5qWl7lT3.js +68 -0
  7. package/dist/client.d.ts +3 -3
  8. package/dist/{contract-DMrpbaLJ.d.ts → contract-rP_eV9PK.d.ts} +1 -1
  9. package/dist/{deploy-DKB-Tef7.js → deploy-D_OFJ6-Q.js} +193 -30
  10. package/dist/email-DBTVhNB_.js +62 -0
  11. package/dist/generate-BgepN4-b.js +2 -0
  12. package/dist/{generate-BFmIzHaR.js → generate-CBPnHoqX.js} +40 -18
  13. package/dist/index.d.ts +122 -11
  14. package/dist/index.js +141 -26
  15. package/dist/{init-CQRsnd3i.js → init-tfzwuYnk.js} +12 -8
  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-CEmDnlKa.js → project-D6XHllmC.js} +32 -20
  23. package/dist/prompt-ChS-grYO.js +29 -0
  24. package/dist/react.d.ts +1 -1
  25. package/dist/react.js +40 -42
  26. package/dist/schedules-dhU1yyFr.js +42 -0
  27. package/dist/server.d.ts +3 -3
  28. package/dist/telephony-protocol-D-nf3Gca.d.ts +76 -0
  29. package/dist/telephony.d.ts +77 -0
  30. package/dist/telephony.js +607 -0
  31. package/dist/{upload-YbRKEqR6.d.ts → upload-DKZzz5kW.d.ts} +6 -6
  32. package/dist/{variables-CP7Ce3Np.js → variables-Bwnr7oxf.js} +3 -28
  33. package/dist/vite.d.ts +1 -1
  34. package/dist/vite.js +464 -30
  35. package/dist/workflow-engine-MogejNfF.js +117 -0
  36. package/dist/{auth-DaVK0k5R.js → workspace-XVtM12ZC.js} +44 -4
  37. package/package.json +7 -1
  38. package/scaffold/.agents/skills/hitch-applets/SKILL.md +34 -15
  39. package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
  40. package/scaffold/.agents/skills/hitch-applets/references/files.md +3 -3
  41. package/scaffold/.agents/skills/hitch-applets/references/manifest.md +21 -2
  42. package/scaffold/.agents/skills/hitch-applets/references/performance.md +74 -0
  43. package/scaffold/.agents/skills/hitch-applets/references/records.md +30 -8
  44. package/scaffold/.agents/skills/hitch-applets/references/schedules.md +7 -2
  45. package/scaffold/.agents/skills/hitch-applets/references/server.md +0 -3
  46. package/scaffold/.agents/skills/hitch-applets/references/workflows.md +11 -3
  47. package/scaffold/.agents/skills/hitch-cli/SKILL.md +129 -0
  48. package/scaffold/.agents/skills/hitch-data/SKILL.md +51 -0
  49. package/scaffold/.agents/skills/hitch-data/references/attributes.md +121 -0
  50. package/scaffold/.agents/skills/hitch-data/references/limits.md +64 -0
  51. package/scaffold/.agents/skills/hitch-theory/SKILL.md +150 -0
  52. package/scaffold/.github/workflows/hitch.yml +15 -0
  53. package/dist/build-CMluoV6q.js +0 -2
  54. package/dist/generate-CefnB-bp.js +0 -2
  55. package/dist/load-config-BnxocLAQ.js +0 -56
package/dist/react.js CHANGED
@@ -327,30 +327,29 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
327
327
  }
328
328
  }
329
329
  useEffect(() => {
330
- if (editor !== null && value !== lastEmittedRef.current && value !== editor.getMarkdown()) editor.commands.setContent(value, {
330
+ if (value !== lastEmittedRef.current && value !== editor.getMarkdown()) editor.commands.setContent(value, {
331
331
  contentType: "markdown",
332
332
  emitUpdate: false
333
333
  });
334
334
  }, [editor, value]);
335
- useEffect(() => editor?.setEditable(!disabled, false), [disabled, editor]);
335
+ useEffect(() => editor.setEditable(!disabled, false), [disabled, editor]);
336
336
  const active = useEditorState({
337
337
  editor,
338
338
  selector: ({ editor: current }) => ({
339
- heading: current?.isActive("heading") ?? false,
340
- bold: current?.isActive("bold") ?? false,
341
- italic: current?.isActive("italic") ?? false,
342
- strike: current?.isActive("strike") ?? false,
343
- code: current?.isActive("code") ?? false,
344
- link: current?.isActive("link") ?? false,
345
- bulletList: current?.isActive("bulletList") ?? false,
346
- orderedList: current?.isActive("orderedList") ?? false,
347
- taskList: current?.isActive("taskList") ?? false,
348
- blockquote: current?.isActive("blockquote") ?? false,
349
- table: current?.isActive("table") ?? false
339
+ heading: current.isActive("heading"),
340
+ bold: current.isActive("bold"),
341
+ italic: current.isActive("italic"),
342
+ strike: current.isActive("strike"),
343
+ code: current.isActive("code"),
344
+ link: current.isActive("link"),
345
+ bulletList: current.isActive("bulletList"),
346
+ orderedList: current.isActive("orderedList"),
347
+ taskList: current.isActive("taskList"),
348
+ blockquote: current.isActive("blockquote"),
349
+ table: current.isActive("table")
350
350
  })
351
351
  });
352
352
  const cycleHeading = () => {
353
- if (editor === null) return;
354
353
  const level = [
355
354
  1,
356
355
  2,
@@ -361,7 +360,6 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
361
360
  else editor.chain().focus().setParagraph().run();
362
361
  };
363
362
  const toggleLink = () => {
364
- if (editor === null) return;
365
363
  if (editor.isActive("link")) return void editor.chain().focus().unsetLink().run();
366
364
  const url = window.prompt("Link URL");
367
365
  if (!url) return;
@@ -378,69 +376,69 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
378
376
  const items = [
379
377
  {
380
378
  title: "Heading",
381
- active: active?.heading,
379
+ active: active.heading,
382
380
  icon: Heading,
383
381
  command: cycleHeading
384
382
  },
385
383
  {
386
384
  title: "Bold",
387
- active: active?.bold,
385
+ active: active.bold,
388
386
  icon: Bold,
389
- command: () => editor?.chain().focus().toggleBold().run()
387
+ command: () => editor.chain().focus().toggleBold().run()
390
388
  },
391
389
  {
392
390
  title: "Italic",
393
- active: active?.italic,
391
+ active: active.italic,
394
392
  icon: Italic,
395
- command: () => editor?.chain().focus().toggleItalic().run()
393
+ command: () => editor.chain().focus().toggleItalic().run()
396
394
  },
397
395
  {
398
396
  title: "Strikethrough",
399
- active: active?.strike,
397
+ active: active.strike,
400
398
  icon: Strikethrough,
401
- command: () => editor?.chain().focus().toggleStrike().run()
399
+ command: () => editor.chain().focus().toggleStrike().run()
402
400
  },
403
401
  {
404
402
  title: "Inline code",
405
- active: active?.code,
403
+ active: active.code,
406
404
  icon: Code,
407
- command: () => editor?.chain().focus().toggleCode().run()
405
+ command: () => editor.chain().focus().toggleCode().run()
408
406
  },
409
407
  {
410
408
  title: "Link",
411
- active: active?.link,
409
+ active: active.link,
412
410
  icon: Link,
413
411
  command: toggleLink
414
412
  },
415
413
  {
416
414
  title: "Bulleted list",
417
- active: active?.bulletList,
415
+ active: active.bulletList,
418
416
  icon: List,
419
- command: () => editor?.chain().focus().toggleBulletList().run()
417
+ command: () => editor.chain().focus().toggleBulletList().run()
420
418
  },
421
419
  {
422
420
  title: "Numbered list",
423
- active: active?.orderedList,
421
+ active: active.orderedList,
424
422
  icon: ListOrdered,
425
- command: () => editor?.chain().focus().toggleOrderedList().run()
423
+ command: () => editor.chain().focus().toggleOrderedList().run()
426
424
  },
427
425
  {
428
426
  title: "Task list",
429
- active: active?.taskList,
427
+ active: active.taskList,
430
428
  icon: ListTodo,
431
- command: () => editor?.chain().focus().toggleTaskList().run()
429
+ command: () => editor.chain().focus().toggleTaskList().run()
432
430
  },
433
431
  {
434
432
  title: "Quote",
435
- active: active?.blockquote,
433
+ active: active.blockquote,
436
434
  icon: Quote,
437
- command: () => editor?.chain().focus().toggleBlockquote().run()
435
+ command: () => editor.chain().focus().toggleBlockquote().run()
438
436
  },
439
437
  {
440
438
  title: "Table",
441
- active: active?.table,
439
+ active: active.table,
442
440
  icon: Table,
443
- command: () => editor?.chain().focus().insertTable({
441
+ command: () => editor.chain().focus().insertTable({
444
442
  rows: 3,
445
443
  cols: 3,
446
444
  withHeaderRow: true
@@ -451,28 +449,28 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
451
449
  {
452
450
  title: "Add row below",
453
451
  icon: BetweenHorizontalEnd,
454
- command: () => editor?.chain().focus().addRowAfter().run()
452
+ command: () => editor.chain().focus().addRowAfter().run()
455
453
  },
456
454
  {
457
455
  title: "Add column right",
458
456
  icon: BetweenVerticalEnd,
459
- command: () => editor?.chain().focus().addColumnAfter().run()
457
+ command: () => editor.chain().focus().addColumnAfter().run()
460
458
  },
461
459
  {
462
460
  title: "Delete row",
463
461
  icon: ListMinus,
464
- command: () => editor?.chain().focus().deleteRow().run()
462
+ command: () => editor.chain().focus().deleteRow().run()
465
463
  },
466
464
  {
467
465
  title: "Delete column",
468
466
  icon: ListMinus,
469
467
  iconClassName: "rotate-90",
470
- command: () => editor?.chain().focus().deleteColumn().run()
468
+ command: () => editor.chain().focus().deleteColumn().run()
471
469
  },
472
470
  {
473
471
  title: "Delete table",
474
472
  icon: Trash2,
475
- command: () => editor?.chain().focus().deleteTable().run()
473
+ command: () => editor.chain().focus().deleteTable().run()
476
474
  }
477
475
  ];
478
476
  return /* @__PURE__ */ jsxs("div", {
@@ -487,7 +485,7 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
487
485
  isDisabled: disabled,
488
486
  onPress: command,
489
487
  children: /* @__PURE__ */ jsx(Icon, {})
490
- }, title)), active?.table && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
488
+ }, title)), active.table && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
491
489
  "aria-hidden": true,
492
490
  className: "mx-1 w-px self-stretch bg-border"
493
491
  }), tableItems.map(({ title, icon: Icon, iconClassName, command }) => /* @__PURE__ */ jsx(Button, {
@@ -508,7 +506,7 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
508
506
  required,
509
507
  disabled,
510
508
  onChange: () => void 0,
511
- onFocus: () => editor?.commands.focus()
509
+ onFocus: () => editor.commands.focus()
512
510
  })
513
511
  ]
514
512
  });
@@ -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,8 +1,8 @@
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
- import { o as WithFilesUpload } from "./upload-YbRKEqR6.js";
5
+ import { o as WithFilesUpload } from "./upload-DKZzz5kW.js";
6
6
  import { ContractRouterClient } from "@orpc/contract";
7
7
  //#region src/server/workflows-client.d.ts
8
8
  type WorkflowRunStatus<Result> = {
@@ -0,0 +1,76 @@
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, string>;
42
+ declare const emailTagsSchema: z.ZodType<EmailTags, EmailTags>;
43
+ declare const createEmailPixelInputSchema: z.ZodType<CreateEmailPixelInput, CreateEmailPixelInput>;
44
+ declare const createEmailPixelOutputSchema: z.ZodType<CreateEmailPixelOutput, CreateEmailPixelOutput>;
45
+ declare const getEmailTrackerInputSchema: z.ZodType<GetEmailTrackerInput, GetEmailTrackerInput>;
46
+ declare const markEmailTrackerSentInputSchema: z.ZodType<MarkEmailTrackerSentInput, MarkEmailTrackerSentInput>;
47
+ declare const markEmailTrackerSentBodySchema: z.ZodType<{
48
+ sentAt?: string;
49
+ }, {
50
+ sentAt?: string;
51
+ }>;
52
+ declare const emailTrackerSchema: z.ZodType<EmailTracker, EmailTracker>;
53
+ declare const listEmailTrackersInputSchema: z.ZodType<ListEmailTrackersInput, ListEmailTrackersInput>;
54
+ declare const listEmailTrackersOutputSchema: z.ZodType<ListEmailTrackersOutput, ListEmailTrackersOutput>;
55
+ type EmailContract = {
56
+ tracking: {
57
+ createPixel: ContractProcedure<z.ZodType<CreateEmailPixelInput | undefined, CreateEmailPixelInput | undefined>, z.ZodType<CreateEmailPixelOutput, CreateEmailPixelOutput>, Record<never, never>, Meta>;
58
+ markSent: ContractProcedure<z.ZodType<MarkEmailTrackerSentInput, MarkEmailTrackerSentInput>, z.ZodType<EmailTracker, EmailTracker>, Record<never, never>, Meta>;
59
+ get: ContractProcedure<z.ZodType<GetEmailTrackerInput, GetEmailTrackerInput>, z.ZodType<EmailTracker, EmailTracker>, Record<never, never>, Meta>;
60
+ list: ContractProcedure<z.ZodType<ListEmailTrackersInput | undefined, ListEmailTrackersInput | undefined>, z.ZodType<ListEmailTrackersOutput, ListEmailTrackersOutput>, Record<never, never>, Meta>;
61
+ };
62
+ };
63
+ declare function emailContract(appletCode: string): EmailContract;
64
+ //#endregion
65
+ //#region src/server/telephony-protocol.d.ts
66
+ /** Handle events at least once and without order. Use eventId for idempotency.
67
+ * Read the message with hitch.telephony.messages.get({ id: messageId }). */
68
+ type TelephonyMessageReceivedEvent = {
69
+ eventId: string;
70
+ type: "message.received";
71
+ messageId: string;
72
+ numberId: string;
73
+ occurredAt: string;
74
+ };
75
+ //#endregion
76
+ 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 };