@hitch42/applet 0.1.1-beta.8 → 0.1.1-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 (167) hide show
  1. package/dist/_internal/client.js +120 -11
  2. package/dist/_internal/log-context.d.ts +34 -0
  3. package/dist/_internal/log-context.js +2 -0
  4. package/dist/_internal/server.d.ts +1 -1
  5. package/dist/_internal/server.js +112 -57
  6. package/dist/applet.js +12 -12
  7. package/dist/build-Bh_S5BUv.js +2 -0
  8. package/dist/{build-DANx9Hgg.js → build-CEfFoIZZ.js} +1 -1
  9. package/dist/{ci-5qWl7lT3.js → ci-BKw14X2h.js} +14 -13
  10. package/dist/client.d.ts +3 -3
  11. package/dist/{contract-rP_eV9PK.d.ts → contract-CsUpTBe0.d.ts} +1 -1
  12. package/dist/{deploy-MQWLG2EA.js → deploy-wGYjwXrx.js} +139 -88
  13. package/dist/{generate-BxYHdoAQ.js → generate-BEIYs17x.js} +65 -28
  14. package/dist/generate-Dox-OYt6.js +2 -0
  15. package/dist/headers-DkNr9MLJ.js +17 -0
  16. package/dist/index.d.ts +23 -22
  17. package/dist/index.js +2 -1
  18. package/dist/{init-jDEgYIXg.js → init-6oGPM46R.js} +15 -17
  19. package/dist/{load-config-BYSxDVAl.js → load-config-xEdTXs0y.js} +2 -2
  20. package/dist/log-context-zu8U9Sjm.js +73 -0
  21. package/dist/{login-C7RKmmTe.js → login-CUx3TmFQ.js} +1 -1
  22. package/dist/{logs-DgjgAxj2.js → logs-DSjuEN0Q.js} +20 -22
  23. package/dist/{manifest-DD_SGkS6.d.ts → manifest-C6_F4bL8.d.ts} +5 -1
  24. package/dist/{manifest-Bp87Uz0a.js → manifest-CJSL9GuC.js} +20 -4
  25. package/dist/{project-CbYPtpPq.js → project-BRZGd6xq.js} +199 -18
  26. package/dist/query-cache-CXmAyLv3.js +82 -0
  27. package/dist/react.d.ts +3 -2
  28. package/dist/react.js +98 -80
  29. package/dist/{schedules-dhU1yyFr.js → schedules-C8_Svr4h.js} +1 -1
  30. package/dist/server.d.ts +9 -4
  31. package/dist/server.js +29 -8
  32. package/dist/{telephony-protocol-DRgiYjqQ.d.ts → telephony-protocol-D-nf3Gca.d.ts} +15 -13
  33. package/dist/telephony.d.ts +24 -4
  34. package/dist/telephony.js +135 -16
  35. package/dist/{upload-YbRKEqR6.d.ts → upload-DKZzz5kW.d.ts} +6 -6
  36. package/dist/{variables-Bwnr7oxf.js → variables-DT5RyHdH.js} +13 -13
  37. package/dist/vite.d.ts +3 -60
  38. package/dist/vite.js +50 -15
  39. package/dist/{workflow-engine-MogejNfF.js → workflow-engine-BOTzURKM.js} +1 -7
  40. package/dist/{workspace-XVtM12ZC.js → workspace-D0dnnlxL.js} +33 -38
  41. package/package.json +13 -5
  42. package/scaffold/.agents/skills/hitch-applets/SKILL.md +30 -4
  43. package/scaffold/.agents/skills/hitch-applets/references/manifest.md +8 -0
  44. package/scaffold/.agents/skills/hitch-applets/references/markdown.md +2 -0
  45. package/scaffold/.agents/skills/hitch-applets/references/records.md +23 -1
  46. package/scaffold/.agents/skills/hitch-data/SKILL.md +2 -1
  47. package/scaffold/.agents/skills/hitch-data/references/attributes.md +7 -1
  48. package/scaffold/.agents/skills/hitch-data/references/limits.md +13 -13
  49. package/scaffold/.agents/skills/hitch-theory/SKILL.md +3 -2
  50. package/scaffold/.agents/skills/react-best-practices/SKILL.md +127 -0
  51. package/scaffold/.agents/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
  52. package/scaffold/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  53. package/scaffold/.agents/skills/react-best-practices/rules/advanced-init-once.md +42 -0
  54. package/scaffold/.agents/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
  55. package/scaffold/.agents/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  56. package/scaffold/.agents/skills/react-best-practices/rules/async-defer-await.md +82 -0
  57. package/scaffold/.agents/skills/react-best-practices/rules/async-dependencies.md +48 -0
  58. package/scaffold/.agents/skills/react-best-practices/rules/async-parallel.md +24 -0
  59. package/scaffold/.agents/skills/react-best-practices/rules/bundle-analyzable-paths.md +42 -0
  60. package/scaffold/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +39 -0
  61. package/scaffold/.agents/skills/react-best-practices/rules/bundle-conditional.md +35 -0
  62. package/scaffold/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +46 -0
  63. package/scaffold/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +38 -0
  64. package/scaffold/.agents/skills/react-best-practices/rules/bundle-preload.md +40 -0
  65. package/scaffold/.agents/skills/react-best-practices/rules/client-event-listeners.md +78 -0
  66. package/scaffold/.agents/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
  67. package/scaffold/.agents/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  68. package/scaffold/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
  69. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-function-results.md +58 -0
  70. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  71. package/scaffold/.agents/skills/react-best-practices/rules/js-cache-storage.md +56 -0
  72. package/scaffold/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  73. package/scaffold/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
  74. package/scaffold/.agents/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
  75. package/scaffold/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  76. package/scaffold/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
  77. package/scaffold/.agents/skills/react-best-practices/rules/js-length-check-first.md +50 -0
  78. package/scaffold/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  79. package/scaffold/.agents/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
  80. package/scaffold/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  81. package/scaffold/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  82. package/scaffold/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
  83. package/scaffold/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
  84. package/scaffold/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
  85. package/scaffold/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  86. package/scaffold/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
  87. package/scaffold/.agents/skills/react-best-practices/rules/rendering-resource-hints.md +81 -0
  88. package/scaffold/.agents/skills/react-best-practices/rules/rendering-script-defer-async.md +36 -0
  89. package/scaffold/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  90. package/scaffold/.agents/skills/react-best-practices/rules/rendering-usetransition-loading.md +43 -0
  91. package/scaffold/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  92. package/scaffold/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  93. package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  94. package/scaffold/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  95. package/scaffold/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
  96. package/scaffold/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
  97. package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
  98. package/scaffold/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
  99. package/scaffold/.agents/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  100. package/scaffold/.agents/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
  101. package/scaffold/.agents/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  102. package/scaffold/.agents/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  103. package/scaffold/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  104. package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  105. package/scaffold/.agents/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  106. package/scaffold/.agents/skills/tanstack-query/SKILL.md +136 -0
  107. package/scaffold/.agents/skills/tanstack-query/references/compositions/automatic-invalidation-after-mutations.md +124 -0
  108. package/scaffold/.agents/skills/tanstack-query/references/compositions/broadcast-realtime-and-multi-tab-synchronization.md +150 -0
  109. package/scaffold/.agents/skills/tanstack-query/references/compositions/compose-query-with-tanstack-router-and-start.md +248 -0
  110. package/scaffold/.agents/skills/tanstack-query/references/compositions/enforce-query-best-practices-with-eslint.md +167 -0
  111. package/scaffold/.agents/skills/tanstack-query/references/compositions/persist-offline-and-restore-caches.md +181 -0
  112. package/scaffold/.agents/skills/tanstack-query/references/compositions/query-data-and-forms.md +156 -0
  113. package/scaffold/.agents/skills/tanstack-query/references/core/build-query-abstractions.md +130 -0
  114. package/scaffold/.agents/skills/tanstack-query/references/core/cancel-queries-and-consume-abort-signals.md +176 -0
  115. package/scaffold/.agents/skills/tanstack-query/references/core/concurrent-optimistic-updates.md +135 -0
  116. package/scaffold/.agents/skills/tanstack-query/references/core/coordinate-query-execution.md +188 -0
  117. package/scaffold/.agents/skills/tanstack-query/references/core/design-query-keys-and-options.md +182 -0
  118. package/scaffold/.agents/skills/tanstack-query/references/core/fetch-and-observe-queries.md +193 -0
  119. package/scaffold/.agents/skills/tanstack-query/references/core/implement-optimistic-updates-and-cache-writes.md +168 -0
  120. package/scaffold/.agents/skills/tanstack-query/references/core/paginate-and-build-infinite-queries.md +188 -0
  121. package/scaffold/.agents/skills/tanstack-query/references/core/seed-placeholder-select-and-transform-data.md +188 -0
  122. package/scaffold/.agents/skills/tanstack-query/references/core/selectors-and-derived-state.md +145 -0
  123. package/scaffold/.agents/skills/tanstack-query/references/core/tune-defaults-freshness-retries-and-refetching.md +172 -0
  124. package/scaffold/.agents/skills/tanstack-query/references/core/understand-query-internals-and-observers.md +104 -0
  125. package/scaffold/.agents/skills/tanstack-query/references/core/write-mutations-and-invalidate-related-queries.md +183 -0
  126. package/scaffold/.agents/skills/tanstack-query/references/framework/debug-with-devtools.md +169 -0
  127. package/scaffold/.agents/skills/tanstack-query/references/framework/handle-status-and-errors.md +119 -0
  128. package/scaffold/.agents/skills/tanstack-query/references/framework/shape-data-and-render-efficiently.md +184 -0
  129. package/scaffold/.agents/skills/tanstack-query/references/framework/use-framework-adapter-reactivity.md +185 -0
  130. package/scaffold/.agents/skills/tanstack-query/references/framework/use-suspense-and-error-boundaries.md +208 -0
  131. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/migrate-major-versions-and-codemods.md +169 -0
  132. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/prefetch-and-remove-request-waterfalls.md +228 -0
  133. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/setup-query-client-and-providers.md +161 -0
  134. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/ssr-hydration-and-streaming.md +209 -0
  135. package/scaffold/.agents/skills/tanstack-query/references/lifecycle/test-query-code.md +160 -0
  136. package/scaffold/.agents/skills/tanstack-router/SKILL.md +134 -0
  137. package/scaffold/.agents/skills/tanstack-router/references/compositions/router-query.md +412 -0
  138. package/scaffold/.agents/skills/tanstack-router/references/react-router.md +495 -0
  139. package/scaffold/.agents/skills/tanstack-router/references/router-core/auth-and-guards.md +495 -0
  140. package/scaffold/.agents/skills/tanstack-router/references/router-core/code-splitting.md +318 -0
  141. package/scaffold/.agents/skills/tanstack-router/references/router-core/data-loading.md +490 -0
  142. package/scaffold/.agents/skills/tanstack-router/references/router-core/index.md +158 -0
  143. package/scaffold/.agents/skills/tanstack-router/references/router-core/navigation.md +433 -0
  144. package/scaffold/.agents/skills/tanstack-router/references/router-core/not-found-and-errors.md +436 -0
  145. package/scaffold/.agents/skills/tanstack-router/references/router-core/path-params.md +383 -0
  146. package/scaffold/.agents/skills/tanstack-router/references/router-core/search-params.md +343 -0
  147. package/scaffold/.agents/skills/tanstack-router/references/router-core/ssr.md +462 -0
  148. package/scaffold/.agents/skills/tanstack-router/references/router-core/type-safety.md +493 -0
  149. package/scaffold/.agents/skills/tanstack-router/references/router-plugin.md +250 -0
  150. package/scaffold/.agents/skills/tanstack-router/references/virtual-file-routes.md +215 -0
  151. package/scaffold/.agents/skills/web-design-guidelines/SKILL.md +184 -0
  152. package/scaffold/.github/workflows/hitch.yml +1 -1
  153. package/scaffold/AGENTS.md +2 -2
  154. package/scaffold/applet/src/client/components/ui/alert.tsx +1 -1
  155. package/scaffold/applet/src/client/components/ui/button.tsx +1 -1
  156. package/scaffold/applet/src/client/components/ui/checkbox.tsx +1 -1
  157. package/scaffold/applet/src/client/components/ui/dialog.tsx +2 -2
  158. package/scaffold/applet/src/client/components/ui/dropdown-menu.tsx +2 -2
  159. package/scaffold/applet/src/client/components/ui/input-group.tsx +2 -2
  160. package/scaffold/applet/src/client/components/ui/select.tsx +2 -2
  161. package/scaffold/applet/src/client/components/ui/sheet.tsx +2 -2
  162. package/scaffold/applet/src/client/components/ui/spinner.tsx +2 -1
  163. package/scaffold/applet/src/client/components/ui/tabs.tsx +1 -1
  164. package/scaffold/applet/src/client/lib/utils.ts +1 -6
  165. package/scaffold/applet/src/client/styles/globals.css +2 -0
  166. package/dist/build-CFCKKMn7.js +0 -2
  167. package/dist/generate-CQ07Hdpo.js +0 -2
package/dist/react.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { useEffect, useMemo, useRef, useState } from "react";
2
- import { Streamdown, defaultRehypePlugins, defaultUrlTransform } from "streamdown";
2
+ import { BetweenHorizontalEnd, BetweenVerticalEnd, Bold, Code, Heading, Italic, Link, List, ListMinus, ListOrdered, ListTodo, Quote, Strikethrough, Table, Trash2, X } from "lucide-react";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { Streamdown, defaultRehypePlugins, defaultUrlTransform } from "streamdown";
5
+ import { GapCursor } from "@tiptap/pm/gapcursor";
6
+ import { NodeSelection } from "@tiptap/pm/state";
4
7
  import { EditorContent, NodeViewWrapper, ReactNodeViewRenderer, useEditor, useEditorState } from "@tiptap/react";
5
- import { BetweenHorizontalEnd, BetweenVerticalEnd, Bold, Code, Heading, Italic, Link, List, ListMinus, ListOrdered, ListTodo, Quote, Strikethrough, Table, Trash2 } from "lucide-react";
6
8
  import { Button, Toolbar } from "react-aria-components";
7
- import { twMerge } from "tailwind-merge";
9
+ import { twMerge } from "cn";
8
10
  import { generateHTML } from "@tiptap/core";
9
11
  import Image from "@tiptap/extension-image";
10
12
  import { TaskItem, TaskList } from "@tiptap/extension-list";
@@ -123,11 +125,14 @@ function Markdown({ children, files, className }) {
123
125
  function sanitizeAltText(text) {
124
126
  return text.replaceAll(/[[\]()\\]/g, "").replaceAll(/\s+/g, " ");
125
127
  }
128
+ function editorMarkdown(editor) {
129
+ return editor.getMarkdown().trimEnd();
130
+ }
126
131
  function tableHasBlockCells(node) {
127
132
  return (node.content ?? []).some((row) => (row.content ?? []).some((cell) => cell.content?.length !== 1 || cell.content[0]?.type !== "paragraph"));
128
133
  }
129
134
  function hitchImageNode(files) {
130
- return function HitchImageNode({ node }) {
135
+ return function HitchImageNode({ node, selected, editor, deleteNode }) {
131
136
  const src = String(node.attrs.src);
132
137
  const alt = typeof node.attrs.alt === "string" ? node.attrs.alt : void 0;
133
138
  const id = src.startsWith("hitch-file://") ? src.slice(13) : void 0;
@@ -152,42 +157,46 @@ function hitchImageNode(files) {
152
157
  active = false;
153
158
  };
154
159
  }, [files, id]);
155
- if (id === void 0) return /* @__PURE__ */ jsx(NodeViewWrapper, {
156
- as: "span",
157
- children: /* @__PURE__ */ jsx("img", {
158
- src,
159
- alt,
160
- className: "max-w-full rounded-lg",
161
- "data-drag-handle": true
162
- })
163
- });
164
- if (files === void 0 || state.error !== void 0) return /* @__PURE__ */ jsx(NodeViewWrapper, {
165
- as: "span",
160
+ const content = id === void 0 ? /* @__PURE__ */ jsx("img", {
161
+ src,
162
+ alt,
163
+ className: "max-w-full rounded-lg",
164
+ "data-drag-handle": true
165
+ }) : files === void 0 || state.error !== void 0 ? /* @__PURE__ */ jsx("span", {
166
166
  className: "text-muted-foreground text-sm",
167
167
  children: alt ?? "Image unavailable"
168
- });
169
- if (state.id !== id || state.url === void 0) return /* @__PURE__ */ jsx(NodeViewWrapper, {
170
- as: "span",
168
+ }) : state.id !== id || state.url === void 0 ? /* @__PURE__ */ jsx("span", {
171
169
  className: "inline-block min-h-16 min-w-32 animate-pulse rounded-md bg-muted p-3 text-muted-foreground text-sm",
172
170
  role: "img",
173
171
  "aria-label": alt ?? "Loading image",
174
172
  children: alt ?? "Loading image"
173
+ }) : /* @__PURE__ */ jsx("img", {
174
+ src: state.url,
175
+ alt,
176
+ className: "max-w-full rounded-lg",
177
+ "data-drag-handle": true,
178
+ onError: () => {
179
+ invalidateDownloadUrl(id);
180
+ setState({
181
+ id,
182
+ error: /* @__PURE__ */ new Error("image failed to load")
183
+ });
184
+ }
175
185
  });
176
- return /* @__PURE__ */ jsx(NodeViewWrapper, {
186
+ return /* @__PURE__ */ jsxs(NodeViewWrapper, {
177
187
  as: "span",
178
- children: /* @__PURE__ */ jsx("img", {
179
- src: state.url,
180
- alt,
181
- className: "max-w-full rounded-lg",
182
- "data-drag-handle": true,
183
- onError: () => {
184
- invalidateDownloadUrl(id);
185
- setState({
186
- id,
187
- error: /* @__PURE__ */ new Error("image failed to load")
188
- });
189
- }
190
- })
188
+ className: twMerge("relative inline-block max-w-full rounded-lg", selected && "in-[.ProseMirror[contenteditable=true]:focus-within]:ring-2 in-[.ProseMirror[contenteditable=true]:focus-within]:ring-ring"),
189
+ children: [content, selected && /* @__PURE__ */ jsx("button", {
190
+ type: "button",
191
+ contentEditable: false,
192
+ "aria-label": "Remove image",
193
+ className: "absolute top-1.5 right-1.5 hidden size-6 in-[.ProseMirror[contenteditable=true]:focus-within]:inline-flex items-center justify-center rounded-full bg-background/90 text-foreground shadow-sm outline-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring/30 [&_svg]:size-3.5",
194
+ onClick: () => {
195
+ deleteNode();
196
+ editor.commands.focus();
197
+ },
198
+ children: /* @__PURE__ */ jsx(X, {})
199
+ })]
191
200
  });
192
201
  };
193
202
  }
@@ -223,7 +232,7 @@ function findImage(view, src) {
223
232
  });
224
233
  return found;
225
234
  }
226
- function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, className, onUploadError }) {
235
+ function MarkdownEditor({ value, onChange, files, id, placeholder, required, minLength, maxLength, disabled, autoFocus, className, onUploadError }) {
227
236
  const validationRef = useRef(null);
228
237
  const lastEmittedRef = useRef(value);
229
238
  const filesRef = useRef(files);
@@ -260,6 +269,7 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
260
269
  content: value,
261
270
  contentType: "markdown",
262
271
  editable: !disabled,
272
+ autofocus: autoFocus ? "end" : false,
263
273
  editorProps: {
264
274
  attributes: { class: editorClassName },
265
275
  handlePaste: (view, event) => {
@@ -280,8 +290,17 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
280
290
  return true;
281
291
  }
282
292
  },
283
- onUpdate: ({ editor: updatedEditor }) => {
284
- const markdown = updatedEditor.getMarkdown();
293
+ onCreate: ({ editor: createdEditor }) => {
294
+ if (autoFocus) createdEditor.commands.focus("end");
295
+ else if (createdEditor.state.selection instanceof NodeSelection) {
296
+ const { state, view } = createdEditor;
297
+ view.dispatch(state.tr.setSelection(new GapCursor(state.doc.resolve(0))));
298
+ }
299
+ },
300
+ onUpdate: ({ editor: updatedEditor, transaction }) => {
301
+ if (!transaction.docChanged) return;
302
+ const markdown = editorMarkdown(updatedEditor);
303
+ if (markdown === lastEmittedRef.current) return;
285
304
  lastEmittedRef.current = markdown;
286
305
  onChange(markdown);
287
306
  }
@@ -327,30 +346,30 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
327
346
  }
328
347
  }
329
348
  useEffect(() => {
330
- if (editor !== null && value !== lastEmittedRef.current && value !== editor.getMarkdown()) editor.commands.setContent(value, {
349
+ if (value !== lastEmittedRef.current && value !== editorMarkdown(editor)) editor.commands.setContent(value, {
331
350
  contentType: "markdown",
332
351
  emitUpdate: false
333
352
  });
353
+ lastEmittedRef.current = value;
334
354
  }, [editor, value]);
335
- useEffect(() => editor?.setEditable(!disabled, false), [disabled, editor]);
355
+ useEffect(() => editor.setEditable(!disabled, false), [disabled, editor]);
336
356
  const active = useEditorState({
337
357
  editor,
338
358
  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
359
+ heading: current.isActive("heading"),
360
+ bold: current.isActive("bold"),
361
+ italic: current.isActive("italic"),
362
+ strike: current.isActive("strike"),
363
+ code: current.isActive("code"),
364
+ link: current.isActive("link"),
365
+ bulletList: current.isActive("bulletList"),
366
+ orderedList: current.isActive("orderedList"),
367
+ taskList: current.isActive("taskList"),
368
+ blockquote: current.isActive("blockquote"),
369
+ table: current.isActive("table")
350
370
  })
351
371
  });
352
372
  const cycleHeading = () => {
353
- if (editor === null) return;
354
373
  const level = [
355
374
  1,
356
375
  2,
@@ -361,7 +380,6 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
361
380
  else editor.chain().focus().setParagraph().run();
362
381
  };
363
382
  const toggleLink = () => {
364
- if (editor === null) return;
365
383
  if (editor.isActive("link")) return void editor.chain().focus().unsetLink().run();
366
384
  const url = window.prompt("Link URL");
367
385
  if (!url) return;
@@ -378,69 +396,69 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
378
396
  const items = [
379
397
  {
380
398
  title: "Heading",
381
- active: active?.heading,
399
+ active: active.heading,
382
400
  icon: Heading,
383
401
  command: cycleHeading
384
402
  },
385
403
  {
386
404
  title: "Bold",
387
- active: active?.bold,
405
+ active: active.bold,
388
406
  icon: Bold,
389
- command: () => editor?.chain().focus().toggleBold().run()
407
+ command: () => editor.chain().focus().toggleBold().run()
390
408
  },
391
409
  {
392
410
  title: "Italic",
393
- active: active?.italic,
411
+ active: active.italic,
394
412
  icon: Italic,
395
- command: () => editor?.chain().focus().toggleItalic().run()
413
+ command: () => editor.chain().focus().toggleItalic().run()
396
414
  },
397
415
  {
398
416
  title: "Strikethrough",
399
- active: active?.strike,
417
+ active: active.strike,
400
418
  icon: Strikethrough,
401
- command: () => editor?.chain().focus().toggleStrike().run()
419
+ command: () => editor.chain().focus().toggleStrike().run()
402
420
  },
403
421
  {
404
422
  title: "Inline code",
405
- active: active?.code,
423
+ active: active.code,
406
424
  icon: Code,
407
- command: () => editor?.chain().focus().toggleCode().run()
425
+ command: () => editor.chain().focus().toggleCode().run()
408
426
  },
409
427
  {
410
428
  title: "Link",
411
- active: active?.link,
429
+ active: active.link,
412
430
  icon: Link,
413
431
  command: toggleLink
414
432
  },
415
433
  {
416
434
  title: "Bulleted list",
417
- active: active?.bulletList,
435
+ active: active.bulletList,
418
436
  icon: List,
419
- command: () => editor?.chain().focus().toggleBulletList().run()
437
+ command: () => editor.chain().focus().toggleBulletList().run()
420
438
  },
421
439
  {
422
440
  title: "Numbered list",
423
- active: active?.orderedList,
441
+ active: active.orderedList,
424
442
  icon: ListOrdered,
425
- command: () => editor?.chain().focus().toggleOrderedList().run()
443
+ command: () => editor.chain().focus().toggleOrderedList().run()
426
444
  },
427
445
  {
428
446
  title: "Task list",
429
- active: active?.taskList,
447
+ active: active.taskList,
430
448
  icon: ListTodo,
431
- command: () => editor?.chain().focus().toggleTaskList().run()
449
+ command: () => editor.chain().focus().toggleTaskList().run()
432
450
  },
433
451
  {
434
452
  title: "Quote",
435
- active: active?.blockquote,
453
+ active: active.blockquote,
436
454
  icon: Quote,
437
- command: () => editor?.chain().focus().toggleBlockquote().run()
455
+ command: () => editor.chain().focus().toggleBlockquote().run()
438
456
  },
439
457
  {
440
458
  title: "Table",
441
- active: active?.table,
459
+ active: active.table,
442
460
  icon: Table,
443
- command: () => editor?.chain().focus().insertTable({
461
+ command: () => editor.chain().focus().insertTable({
444
462
  rows: 3,
445
463
  cols: 3,
446
464
  withHeaderRow: true
@@ -451,35 +469,36 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
451
469
  {
452
470
  title: "Add row below",
453
471
  icon: BetweenHorizontalEnd,
454
- command: () => editor?.chain().focus().addRowAfter().run()
472
+ command: () => editor.chain().focus().addRowAfter().run()
455
473
  },
456
474
  {
457
475
  title: "Add column right",
458
476
  icon: BetweenVerticalEnd,
459
- command: () => editor?.chain().focus().addColumnAfter().run()
477
+ command: () => editor.chain().focus().addColumnAfter().run()
460
478
  },
461
479
  {
462
480
  title: "Delete row",
463
481
  icon: ListMinus,
464
- command: () => editor?.chain().focus().deleteRow().run()
482
+ command: () => editor.chain().focus().deleteRow().run()
465
483
  },
466
484
  {
467
485
  title: "Delete column",
468
486
  icon: ListMinus,
469
487
  iconClassName: "rotate-90",
470
- command: () => editor?.chain().focus().deleteColumn().run()
488
+ command: () => editor.chain().focus().deleteColumn().run()
471
489
  },
472
490
  {
473
491
  title: "Delete table",
474
492
  icon: Trash2,
475
- command: () => editor?.chain().focus().deleteTable().run()
493
+ command: () => editor.chain().focus().deleteTable().run()
476
494
  }
477
495
  ];
478
496
  return /* @__PURE__ */ jsxs("div", {
479
- className: twMerge("overflow-hidden rounded-2xl border border-input bg-background", className),
497
+ className: twMerge("flex flex-col overflow-hidden rounded-2xl border border-input bg-background", className),
480
498
  children: [
499
+ /* @__PURE__ */ jsx(EditorContent, { editor }),
481
500
  /* @__PURE__ */ jsxs(Toolbar, {
482
- className: "flex flex-wrap gap-1 border-b border-input p-1",
501
+ className: "order-first flex flex-wrap gap-1 border-b border-input p-1",
483
502
  "aria-label": "Markdown formatting",
484
503
  children: [items.map(({ title, active: isActive, icon: Icon, command }) => /* @__PURE__ */ jsx(Button, {
485
504
  className: twMerge(buttonClassName, isActive && "bg-muted text-foreground"),
@@ -487,7 +506,7 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
487
506
  isDisabled: disabled,
488
507
  onPress: command,
489
508
  children: /* @__PURE__ */ jsx(Icon, {})
490
- }, title)), active?.table && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
509
+ }, title)), active.table && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
491
510
  "aria-hidden": true,
492
511
  className: "mx-1 w-px self-stretch bg-border"
493
512
  }), tableItems.map(({ title, icon: Icon, iconClassName, command }) => /* @__PURE__ */ jsx(Button, {
@@ -498,7 +517,6 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
498
517
  children: /* @__PURE__ */ jsx(Icon, { className: iconClassName })
499
518
  }, title))] })]
500
519
  }),
501
- /* @__PURE__ */ jsx(EditorContent, { editor }),
502
520
  /* @__PURE__ */ jsx("textarea", {
503
521
  ref: validationRef,
504
522
  id,
@@ -508,7 +526,7 @@ function MarkdownEditor({ value, onChange, files, id, placeholder, required, min
508
526
  required,
509
527
  disabled,
510
528
  onChange: () => void 0,
511
- onFocus: () => editor?.commands.focus()
529
+ onFocus: () => editor.commands.focus()
512
530
  })
513
531
  ]
514
532
  });
@@ -1,4 +1,4 @@
1
- import { t as loadAppletConfig } from "./load-config-BYSxDVAl.js";
1
+ import { t as loadAppletConfig } from "./load-config-xEdTXs0y.js";
2
2
  import { t as question } from "./prompt-ChS-grYO.js";
3
3
  import { RPCLink } from "@orpc/client/fetch";
4
4
  import { readFile } from "node:fs/promises";
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-DD_SGkS6.js";
3
- import { t as NarrowContract } from "./contract-rP_eV9PK.js";
2
+ import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-C6_F4bL8.js";
3
+ import { t as NarrowContract } from "./contract-CsUpTBe0.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> = {
@@ -36,6 +36,11 @@ type AppletManifestVariables = Readonly<Record<string, {
36
36
  }>>;
37
37
  declare const env: AppletEnv;
38
38
  //#endregion
39
+ //#region src/server/log.d.ts
40
+ declare const log: {
41
+ set(fields: Record<string, unknown>): void;
42
+ };
43
+ //#endregion
39
44
  //#region src/author/server.d.ts
40
45
  type AuthorContract = NarrowContract<RegisteredContract, RegisteredManifest>;
41
46
  type AuthorHitchClient = WithBatchRecorder<ContractRouterClient<AuthorContract>>;
@@ -43,4 +48,4 @@ declare const hitch: WithFilesUpload<AuthorHitchClient> & {
43
48
  workflows: WorkflowsClient<RegisteredWorkflows>;
44
49
  };
45
50
  //#endregion
46
- export { type AppletEnv, type WorkflowDefinition, type WorkflowDuration, type WorkflowStep, createWorkflow, env, hitch };
51
+ export { type AppletEnv, type WorkflowDefinition, type WorkflowDuration, type WorkflowStep, createWorkflow, env, hitch, log };
package/dist/server.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { n as withFilesUpload, r as getRegisteredHitchContract } from "./upload-DRbVhuDm.js";
2
+ import { t as HITCH_APPLET_CODE_HEADER } from "./headers-DkNr9MLJ.js";
2
3
  import { a as getRequestContext, i as getIdentityBearer, n as createWorkflow, s as tryGetRequestContext } from "./workflow-CTo2kZF1.js";
4
+ import { s as publishNote, t as APP_CONTEXT_CHANNEL } from "./log-context-zu8U9Sjm.js";
3
5
  import { n as withBatchRecorder, t as createLazyClientProxy } from "./lazy-client-x0DCI98S.js";
4
6
  import { createORPCClient } from "@orpc/client";
5
7
  import { OpenAPILink } from "@orpc/openapi-client/fetch";
@@ -7,18 +9,27 @@ import { OpenAPILink } from "@orpc/openapi-client/fetch";
7
9
  const DEFAULT_API_URL = "https://app.hitch42.com";
8
10
  const resolveTransport = () => {
9
11
  const context = tryGetRequestContext();
10
- if (context !== void 0) return {
11
- baseUrl: context.api.baseUrl,
12
- fetch: context.api.fetch,
13
- authorization: `Bearer ${getIdentityBearer(context.identity)}`
14
- };
12
+ if (context !== void 0) {
13
+ const requestId = context.requestId;
14
+ const traceparent = context.log.getContext().traceparent;
15
+ return {
16
+ baseUrl: context.api.baseUrl,
17
+ fetch: context.api.fetch,
18
+ headers: {
19
+ authorization: `Bearer ${getIdentityBearer(context.identity)}`,
20
+ [HITCH_APPLET_CODE_HEADER]: context.appletCode,
21
+ ...typeof requestId === "string" ? { "x-request-id": requestId } : {},
22
+ ...typeof traceparent === "string" ? { traceparent } : {}
23
+ }
24
+ };
25
+ }
15
26
  const apiKey = process.env.HITCH_API_KEY;
16
27
  if (apiKey !== void 0 && apiKey !== "") {
17
28
  const apiUrl = process.env.HITCH_API_URL;
18
29
  return {
19
30
  baseUrl: apiUrl !== void 0 && apiUrl !== "" ? apiUrl : DEFAULT_API_URL,
20
31
  fetch: (request, init) => globalThis.fetch(request, init),
21
- authorization: `Bearer ${apiKey}`
32
+ headers: { authorization: `Bearer ${apiKey}` }
22
33
  };
23
34
  }
24
35
  throw new Error("Hitch request context is unavailable outside a request. Set HITCH_API_KEY to call the API with an API key.");
@@ -27,7 +38,7 @@ function createHitchClient(contract) {
27
38
  return createORPCClient(new OpenAPILink(contract, {
28
39
  url: () => resolveTransport().baseUrl,
29
40
  fetch: (request, init) => resolveTransport().fetch(request, init),
30
- headers: () => ({ authorization: resolveTransport().authorization })
41
+ headers: () => resolveTransport().headers
31
42
  }));
32
43
  }
33
44
  //#endregion
@@ -88,6 +99,16 @@ function createWorkflowsClient() {
88
99
  //#region src/server/env.ts
89
100
  const env = process.env;
90
101
  //#endregion
102
+ //#region src/server/log.ts
103
+ const log = { set(fields) {
104
+ const context = tryGetRequestContext();
105
+ if (context === void 0) {
106
+ console.warn("log.set() was called outside a request; the fields were dropped.");
107
+ return;
108
+ }
109
+ publishNote(context.requestId, fields, APP_CONTEXT_CHANNEL);
110
+ } };
111
+ //#endregion
91
112
  //#region src/author/server.ts
92
113
  function buildHitchClient() {
93
114
  const contract = getRegisteredHitchContract();
@@ -101,4 +122,4 @@ const hitch = new Proxy(filesClient, { get(target, property, receiver) {
101
122
  return property === "workflows" ? workflows : Reflect.get(target, property, receiver);
102
123
  } });
103
124
  //#endregion
104
- export { createWorkflow, env, hitch };
125
+ export { createWorkflow, env, hitch, log };
@@ -38,24 +38,26 @@ type ListEmailTrackersOutput = {
38
38
  trackers: EmailTracker[];
39
39
  nextCursor: string | null;
40
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>;
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
47
  declare const markEmailTrackerSentBodySchema: z.ZodType<{
48
48
  sentAt?: string;
49
+ }, {
50
+ sentAt?: string;
49
51
  }>;
50
- declare const emailTrackerSchema: z.ZodType<EmailTracker>;
51
- declare const listEmailTrackersInputSchema: z.ZodType<ListEmailTrackersInput>;
52
- declare const listEmailTrackersOutputSchema: z.ZodType<ListEmailTrackersOutput>;
52
+ declare const emailTrackerSchema: z.ZodType<EmailTracker, EmailTracker>;
53
+ declare const listEmailTrackersInputSchema: z.ZodType<ListEmailTrackersInput, ListEmailTrackersInput>;
54
+ declare const listEmailTrackersOutputSchema: z.ZodType<ListEmailTrackersOutput, ListEmailTrackersOutput>;
53
55
  type EmailContract = {
54
56
  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>;
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>;
59
61
  };
60
62
  };
61
63
  declare function emailContract(appletCode: string): EmailContract;
@@ -1,16 +1,26 @@
1
1
  //#region src/telephony/phone.d.ts
2
2
  type PhoneState = {
3
+ owner: boolean;
3
4
  status: "off" | "connecting" | "ready" | "error";
4
5
  error: string | null;
5
- active: null | {
6
- callId: string;
7
- to: string;
6
+ incoming: null | {
7
+ id: string;
8
+ from: string;
9
+ };
10
+ active: null | ({
8
11
  from: string;
9
12
  state: "connecting" | "ringing" | "active" | "held" | "ended";
10
13
  muted: boolean;
11
14
  startedAt: number;
15
+ } & ({
16
+ direction: "outbound";
17
+ callId: string;
18
+ to: string;
12
19
  recording: boolean;
13
- };
20
+ } | {
21
+ direction: "inbound";
22
+ recording: false;
23
+ }));
14
24
  };
15
25
  type CallInput = {
16
26
  numberId: string;
@@ -31,6 +41,8 @@ declare class Phone {
31
41
  private readonly api;
32
42
  private client;
33
43
  private currentCall;
44
+ private incomingCall;
45
+ private readonly acceptsCalls;
34
46
  private connectPromise;
35
47
  private releaseLock;
36
48
  private lockAbortController;
@@ -44,8 +56,11 @@ declare class Phone {
44
56
  private audio;
45
57
  private firstLogin;
46
58
  private callStarting;
59
+ private reconnectOnPageShow;
60
+ private connectionRequested;
47
61
  constructor(options?: {
48
62
  baseUrl?: string;
63
+ acceptsCalls?: boolean;
49
64
  });
50
65
  subscribe: (listener: Listener) => (() => void);
51
66
  getSnapshot: () => PhoneState;
@@ -55,8 +70,12 @@ declare class Phone {
55
70
  private connectInternal;
56
71
  private connectOwned;
57
72
  disconnect: () => void;
73
+ private pageHide;
74
+ private pageShow;
58
75
  private beforeUnload;
59
76
  call: ({ numberId, to }: CallInput) => Promise<void>;
77
+ answer: () => Promise<void>;
78
+ decline: () => Promise<void>;
60
79
  private sendCommand;
61
80
  private onChannelMessage;
62
81
  private runCommand;
@@ -65,6 +84,7 @@ declare class Phone {
65
84
  }
66
85
  declare const createPhone: (options?: {
67
86
  baseUrl?: string;
87
+ acceptsCalls?: boolean;
68
88
  }) => Phone;
69
89
  //#endregion
70
90
  //#region src/telephony/use-phone.d.ts