@tangle-network/agent-app 0.60.177 → 0.60.179

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 (59) hide show
  1. package/dist/agent-profiles/d1.js +3 -3
  2. package/dist/agent-profiles/index.js +11 -3
  3. package/dist/agent-profiles/self-management.d.ts +82 -0
  4. package/dist/assistant/index.js +5 -5
  5. package/dist/channels/index.js +1 -1
  6. package/dist/chat-routes/index.js +4 -4
  7. package/dist/{chunk-GIJY3YCH.js → chunk-3RHAF2P5.js} +11 -13
  8. package/dist/chunk-3RHAF2P5.js.map +1 -0
  9. package/dist/{chunk-ER3KSBA4.js → chunk-75ZIWV4U.js} +4 -4
  10. package/dist/{chunk-7PSYT35Z.js → chunk-7BYY7QKC.js} +5 -5
  11. package/dist/{chunk-7PSYT35Z.js.map → chunk-7BYY7QKC.js.map} +1 -1
  12. package/dist/chunk-A2GG4D4A.js +43 -0
  13. package/dist/chunk-A2GG4D4A.js.map +1 -0
  14. package/dist/{chunk-6CKNC32J.js → chunk-AJZ3EJB5.js} +2 -2
  15. package/dist/{chunk-MCAIZKQ5.js → chunk-CPNJRLPN.js} +15 -4
  16. package/dist/chunk-CPNJRLPN.js.map +1 -0
  17. package/dist/{chunk-4WEUWCA4.js → chunk-EQRVOMMS.js} +2 -2
  18. package/dist/{chunk-6VXBUIM5.js → chunk-KOTNMTHV.js} +65 -8
  19. package/dist/{chunk-6VXBUIM5.js.map → chunk-KOTNMTHV.js.map} +1 -1
  20. package/dist/{chunk-LSUELMHY.js → chunk-LN5RBVGP.js} +6 -33
  21. package/dist/{chunk-LSUELMHY.js.map → chunk-LN5RBVGP.js.map} +1 -1
  22. package/dist/{chunk-IAFPBYQQ.js → chunk-QGOGX3DL.js} +52 -67
  23. package/dist/chunk-QGOGX3DL.js.map +1 -0
  24. package/dist/{chunk-NO2YNV5C.js → chunk-YXLN4PXK.js} +2 -2
  25. package/dist/hub-approvals/index.js +1 -1
  26. package/dist/hub-approvals/present.d.ts +1 -1
  27. package/dist/hub-approvals/types.d.ts +35 -0
  28. package/dist/hub-approvals-react/dock.d.ts +3 -2
  29. package/dist/hub-approvals-react/email.d.ts +13 -0
  30. package/dist/hub-approvals-react/feedback.d.ts +20 -0
  31. package/dist/hub-approvals-react/index.d.ts +1 -0
  32. package/dist/hub-approvals-react/index.js +535 -286
  33. package/dist/hub-approvals-react/index.js.map +1 -1
  34. package/dist/hub-approvals-react/parts.d.ts +1 -1
  35. package/dist/hub-approvals-react/row.d.ts +3 -2
  36. package/dist/integrations-react/index.js +1 -1
  37. package/dist/preset-cloudflare/index.js +2 -2
  38. package/dist/sandbox/index.js +4 -4
  39. package/dist/stories/app-shell/interaction-evidence.d.ts +31 -0
  40. package/dist/studio-react/index.js +2 -2
  41. package/dist/theme/tokens.css +158 -0
  42. package/dist/tools/index.js +4 -4
  43. package/dist/web-react/action-dialog.d.ts +2 -2
  44. package/dist/web-react/agent-profile-editor.js +1 -1
  45. package/dist/web-react/agent-profile-form-kit.d.ts +1 -1
  46. package/dist/web-react/async/index.js +1 -1
  47. package/dist/web-react/index.js +5 -5
  48. package/dist/work-product/index.js +2 -2
  49. package/dist/workspace-react/index.js +1 -1
  50. package/package.json +2 -2
  51. package/dist/chunk-GIJY3YCH.js.map +0 -1
  52. package/dist/chunk-IAFPBYQQ.js.map +0 -1
  53. package/dist/chunk-MCAIZKQ5.js.map +0 -1
  54. package/dist/chunk-QJYJOMMO.js +0 -78
  55. package/dist/chunk-QJYJOMMO.js.map +0 -1
  56. /package/dist/{chunk-ER3KSBA4.js.map → chunk-75ZIWV4U.js.map} +0 -0
  57. /package/dist/{chunk-6CKNC32J.js.map → chunk-AJZ3EJB5.js.map} +0 -0
  58. /package/dist/{chunk-4WEUWCA4.js.map → chunk-EQRVOMMS.js.map} +0 -0
  59. /package/dist/{chunk-NO2YNV5C.js.map → chunk-YXLN4PXK.js.map} +0 -0
@@ -0,0 +1,43 @@
1
+ // src/web-react/action-dialog.tsx
2
+ import { useRef } from "react";
3
+ import { Button, Dialog, DialogContent, DialogFooter, DialogTitle } from "@tangle-network/ui/primitives";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ function ActionDialogButton({ children, onClick, disabled, variant = "primary" }) {
6
+ return /* @__PURE__ */ jsx(Button, { type: "button", onClick, disabled, variant: variant === "primary" ? "default" : variant, children });
7
+ }
8
+ function ActionDialog({ title, children, footer, onClose, busy, error }) {
9
+ const opener = useRef(typeof document !== "undefined" && document.activeElement instanceof HTMLElement ? document.activeElement : null);
10
+ return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
11
+ if (!open && !busy) onClose();
12
+ }, children: /* @__PURE__ */ jsxs(
13
+ DialogContent,
14
+ {
15
+ hideCloseButton: true,
16
+ "aria-busy": busy,
17
+ "aria-describedby": void 0,
18
+ className: "max-w-sm gap-0 p-5",
19
+ onEscapeKeyDown: (event) => {
20
+ if (busy) event.preventDefault();
21
+ },
22
+ onInteractOutside: (event) => {
23
+ if (busy) event.preventDefault();
24
+ },
25
+ onCloseAutoFocus: (event) => {
26
+ event.preventDefault();
27
+ opener.current?.focus();
28
+ },
29
+ children: [
30
+ /* @__PURE__ */ jsx(DialogTitle, { className: "text-sm", children: title }),
31
+ /* @__PURE__ */ jsx("div", { className: "mt-3", children }),
32
+ error && /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-3 rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
33
+ /* @__PURE__ */ jsx(DialogFooter, { className: "mt-5", children: footer })
34
+ ]
35
+ }
36
+ ) });
37
+ }
38
+
39
+ export {
40
+ ActionDialogButton,
41
+ ActionDialog
42
+ };
43
+ //# sourceMappingURL=chunk-A2GG4D4A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/web-react/action-dialog.tsx"],"sourcesContent":["import { useRef, type ReactNode } from 'react'\nimport { Button, Dialog, DialogContent, DialogFooter, DialogTitle } from '@tangle-network/ui/primitives'\n\n// The shell owns mutation state; the shared primitives own controls and focus.\nexport function ActionDialogButton({ children, onClick, disabled, variant = 'primary' }: {\n children: ReactNode\n onClick: () => void\n disabled?: boolean\n variant?: 'primary' | 'ghost' | 'destructive'\n}) {\n return <Button type=\"button\" onClick={onClick} disabled={disabled} variant={variant === 'primary' ? 'default' : variant}>{children}</Button>\n}\n\nexport function ActionDialog({ title, children, footer, onClose, busy, error }: {\n title: string\n children: ReactNode\n footer: ReactNode\n onClose: () => void\n busy: boolean\n error: string | null\n}) {\n // These dialogs mount without a DialogTrigger: retain the shell's opener.\n const opener = useRef(typeof document !== 'undefined' && document.activeElement instanceof HTMLElement ? document.activeElement : null)\n return <Dialog open onOpenChange={open => { if (!open && !busy) onClose() }}>\n <DialogContent hideCloseButton aria-busy={busy} aria-describedby={undefined} className=\"max-w-sm gap-0 p-5\"\n onEscapeKeyDown={event => { if (busy) event.preventDefault() }}\n onInteractOutside={event => { if (busy) event.preventDefault() }}\n onCloseAutoFocus={event => { event.preventDefault(); opener.current?.focus() }}>\n <DialogTitle className=\"text-sm\">{title}</DialogTitle>\n <div className=\"mt-3\">{children}</div>\n {error && <p role=\"alert\" className=\"mt-3 rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive\">{error}</p>}\n <DialogFooter className=\"mt-5\">{footer}</DialogFooter>\n </DialogContent>\n </Dialog>\n}\n"],"mappings":";AAAA,SAAS,cAA8B;AACvC,SAAS,QAAQ,QAAQ,eAAe,cAAc,mBAAmB;AAShE,cAcL,YAdK;AANF,SAAS,mBAAmB,EAAE,UAAU,SAAS,UAAU,UAAU,UAAU,GAKnF;AACD,SAAO,oBAAC,UAAO,MAAK,UAAS,SAAkB,UAAoB,SAAS,YAAY,YAAY,YAAY,SAAU,UAAS;AACrI;AAEO,SAAS,aAAa,EAAE,OAAO,UAAU,QAAQ,SAAS,MAAM,MAAM,GAO1E;AAED,QAAM,SAAS,OAAO,OAAO,aAAa,eAAe,SAAS,yBAAyB,cAAc,SAAS,gBAAgB,IAAI;AACtI,SAAO,oBAAC,UAAO,MAAI,MAAC,cAAc,UAAQ;AAAE,QAAI,CAAC,QAAQ,CAAC,KAAM,SAAQ;AAAA,EAAE,GACxE;AAAA,IAAC;AAAA;AAAA,MAAc,iBAAe;AAAA,MAAC,aAAW;AAAA,MAAM,oBAAkB;AAAA,MAAW,WAAU;AAAA,MACrF,iBAAiB,WAAS;AAAE,YAAI,KAAM,OAAM,eAAe;AAAA,MAAE;AAAA,MAC7D,mBAAmB,WAAS;AAAE,YAAI,KAAM,OAAM,eAAe;AAAA,MAAE;AAAA,MAC/D,kBAAkB,WAAS;AAAE,cAAM,eAAe;AAAG,eAAO,SAAS,MAAM;AAAA,MAAE;AAAA,MAC7E;AAAA,4BAAC,eAAY,WAAU,WAAW,iBAAM;AAAA,QACxC,oBAAC,SAAI,WAAU,QAAQ,UAAS;AAAA,QAC/B,SAAS,oBAAC,OAAE,MAAK,SAAQ,WAAU,wEAAwE,iBAAM;AAAA,QAClH,oBAAC,gBAAa,WAAU,QAAQ,kBAAO;AAAA;AAAA;AAAA,EACzC,GACF;AACF;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  OPENUI_NODE_JSON_SCHEMA,
6
6
  OPENUI_NODE_TYPES
7
- } from "./chunk-7PSYT35Z.js";
7
+ } from "./chunk-7BYY7QKC.js";
8
8
 
9
9
  // src/tools/openai.ts
10
10
  var APP_TOOL_NAMES = ["submit_proposal", "schedule_followup", "render_ui", "add_citation"];
@@ -112,4 +112,4 @@ export {
112
112
  customToolToOpenAI,
113
113
  findCustomTool
114
114
  };
115
- //# sourceMappingURL=chunk-6CKNC32J.js.map
115
+ //# sourceMappingURL=chunk-AJZ3EJB5.js.map
@@ -249,13 +249,19 @@ function mergedFiles(declared, counted) {
249
249
  return declared.map((file) => byPath.get(file.path) ?? file);
250
250
  }
251
251
  function emailPreview(input, reply) {
252
+ const from = asRecord(input.from);
253
+ const htmlBody = typeof input.html === "string" ? input.html : void 0;
252
254
  return {
253
255
  kind: "email",
254
256
  to: list(input.to ?? input.recipients),
255
257
  cc: list(input.cc),
256
258
  bcc: list(input.bcc),
257
259
  subject: text(input.subject),
258
- body: text(input.body) ?? text(input.text) ?? text(input.html) ?? text(input.comment),
260
+ from: text(input.from) ?? text(from.email) ?? text(from.address),
261
+ fromName: text(input.fromName) ?? text(input.from_name) ?? text(from.name),
262
+ previewText: text(input.previewText) ?? text(input.preview_text) ?? text(input.preheader),
263
+ // The payload is evidence: retain whitespace and prefer the actual HTML part.
264
+ body: htmlBody ?? [input.body, input.text, input.comment].find((value) => typeof value === "string"),
259
265
  html: input.html === true || text(input.bodyType)?.toLowerCase() === "html" || typeof input.html === "string",
260
266
  reply
261
267
  };
@@ -349,7 +355,7 @@ function sendEmail(verb, reply = false) {
349
355
  }
350
356
  function post(channel, reply = false) {
351
357
  return (input) => {
352
- const body = text(input.text) ?? text(input.commentary) ?? "";
358
+ const body = typeof input.text === "string" ? input.text : typeof input.commentary === "string" ? input.commentary : "";
353
359
  const url = text(input.url);
354
360
  const where = channel === "x" ? "X" : "LinkedIn";
355
361
  return {
@@ -360,6 +366,11 @@ function post(channel, reply = false) {
360
366
  kind: "post",
361
367
  channel,
362
368
  text: body,
369
+ images: (Array.isArray(input.images) ? input.images : input.image ? [input.image] : []).flatMap((image) => {
370
+ const record = asRecord(image);
371
+ const url2 = text(image) ?? text(record.url);
372
+ return url2 ? [{ url: url2, alt: text(record.alt) }] : [];
373
+ }),
363
374
  ...url ? { link: { url, title: text(input.title), description: text(input.description) } } : {}
364
375
  }
365
376
  };
@@ -534,7 +545,7 @@ function presentHubAction(item) {
534
545
  preview: { kind: "fields", fields: scalarFields(input) }
535
546
  };
536
547
  })();
537
- return { provider, ...presented, ...item.bundle ? { title: item.bundle.title } : {} };
548
+ return { provider, ...presented, ...item.preview ? { preview: item.preview } : {}, ...item.bundle ? { title: item.bundle.title } : {} };
538
549
  }
539
550
  function prField(result) {
540
551
  const pull = asRecord(result.pullRequest);
@@ -763,4 +774,4 @@ export {
763
774
  HUB_APPROVAL_RESUME_PART,
764
775
  hubApprovalResumePart
765
776
  };
766
- //# sourceMappingURL=chunk-MCAIZKQ5.js.map
777
+ //# sourceMappingURL=chunk-CPNJRLPN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hub-approvals/types.ts","../src/hub-approvals/result.ts","../src/hub-approvals/unknown.ts","../src/hub-approvals/present.ts","../src/hub-approvals/index.ts"],"sourcesContent":["/**\n * The vocabulary of a Hub action that waits on a person: where it stands, what\n * it will do in the owner's words, and what it did once it ran.\n */\n\n/** Where one held action stands, as the dock, the list and the transcript show it. */\nexport type HubApprovalPhase =\n /** Held by Hub; the viewer can decide it. */\n | 'waiting'\n /** Held by Hub; someone else (the workspace owner) decides it. */\n | 'blocked'\n /** Approved here; the run has not started. */\n | 'queued'\n /** Approved; Hub is running the call. */\n | 'running'\n | 'done'\n /** Approved, but Hub could not run it. */\n | 'failed'\n /** The provider may have acted; verify there before requesting it again. */\n | 'unknown'\n | 'denied'\n | 'expired'\n\n/** Phases that still need someone's decision. */\nexport const HUB_APPROVAL_OPEN_PHASES: ReadonlySet<HubApprovalPhase> = new Set(['waiting', 'blocked'])\n/** Phases between a decision and its result. */\nexport const HUB_APPROVAL_ACTIVE_PHASES: ReadonlySet<HubApprovalPhase> = new Set(['queued', 'running'])\n\n/** A file a held write changes. Counts stay undefined until someone has read them. */\nexport interface HubActionFile {\n path: string\n /** A rename reads as a modification of its new path. */\n change: 'added' | 'modified' | 'deleted'\n additions?: number\n deletions?: number\n}\n\n/**\n * The change a held call serves, when it is one step of a larger change such\n * as a pull request. The dock then names the change rather than the step.\n */\nexport interface HubActionBundle {\n /** What the whole change does, e.g. `Open PR: Fix the hero on acme/site`. */\n title: string\n steps?: ReadonlyArray<{ label: string; state: 'done' | 'current' | 'upcoming' }>\n}\n\n/** Whether an open call waits for the owner, in the owner's words. */\nexport interface HubApprovalWait {\n /** True when nothing runs until the owner decides; false when a permission runs it. */\n owner: boolean\n /** One sentence: `Publishing always needs your approval.` or `Runs under this conversation’s auto-approve.` */\n reason: string\n /** A stable cause the host can test, e.g. `never_grantable`, `loop_guard`, `daily_cap`. */\n code?: string\n}\n\n/** One held Hub action and its decision, in the form every surface renders. */\nexport interface HubApprovalItem {\n /** Stable within a conversation, such as `<messageId>:<partId>`. */\n id: string\n /** `provider.action`, e.g. `github.pulls.propose`. */\n actionPath: string\n providerId: string\n /** The call's input as Hub received it. */\n input: unknown\n phase: HubApprovalPhase\n /** The connected account the action runs as, e.g. `octocat` or `ops@acme.com`. */\n account?: string | null\n requestedAt?: string | null\n /** When the decision window closes. */\n expiresAt?: string | null\n /** Hub's result, or a bounded projection of it from {@link summarizeHubResult}. */\n result?: unknown\n error?: string | null\n /** The standing permission granted with the approval. */\n grant?: { scope: string; expiresAt: string | null } | null\n /** Set when a permissions mode, not a person, approved it. */\n autoApproved?: string | null\n /**\n * For an open call, what happens next without the viewer: it waits for the\n * owner, and why, or it runs on its own once the agent's reply finishes.\n */\n wait?: HubApprovalWait | null\n /** Files with line counts read by the host, replacing those the input declares. */\n files?: readonly HubActionFile[]\n bundle?: HubActionBundle | null\n /** Previewing and teaching never execute a call. Live approval remains a separate action. */\n executionMode?: 'dry-run' | 'live'\n feedback?: HubApprovalFeedback & { savedAt?: string }\n /** Host-resolved presentation, e.g. a retained page screenshot or ad creative. No remote fetches. */\n preview?: HubActionPreview\n}\n\n/** The host authenticates the reviewer, binds provenance and computes the edit diff. */\nexport interface HubApprovalFeedback {\n score: number\n comment: string\n /** A teaching example only; never replaces the held input or authorizes execution. */\n editedInput?: unknown\n}\n\n/** A labelled value on a preview or a receipt. */\nexport interface HubActionField {\n label: string\n value: string\n href?: string\n /** Render in the monospace face: shas, ids, paths. */\n mono?: boolean\n}\n\n/** What a held call will do, shaped for its integration's renderer. */\nexport type HubActionPreview =\n | {\n kind: 'pull-request'\n repository?: string\n title?: string\n body?: string\n head?: string\n base?: string\n draft?: boolean\n files: readonly HubActionFile[]\n }\n | { kind: 'commit'; repository?: string; message?: string; tree?: string; parents: readonly string[] }\n | { kind: 'branch'; repository?: string; branch?: string; sha?: string }\n | { kind: 'files'; repository?: string; files: readonly HubActionFile[] }\n | { kind: 'issue'; repository?: string; number?: number; title?: string; body?: string; verdict?: string }\n | {\n kind: 'email'\n to: readonly string[]\n cc: readonly string[]\n bcc: readonly string[]\n subject?: string\n from?: string\n fromName?: string\n previewText?: string\n body?: string\n html: boolean\n reply: boolean\n }\n | {\n kind: 'post'\n channel: 'x' | 'linkedin' | 'slack'\n text: string\n /** The post's place, such as a Slack channel. */\n where?: string\n link?: { url: string; title?: string; description?: string }\n images?: readonly { url: string; alt?: string }[]\n }\n | { kind: 'ad'; placement: string; advertiser?: string; headline?: string; text?: string; image?: string; destination?: string; callToAction?: string }\n | { kind: 'page'; title?: string; url?: string; screenshot?: string }\n | { kind: 'payment'; label: string; amount?: number; currency?: string; customer?: string; description?: string }\n | { kind: 'speech'; text: string; voice?: string; seconds?: number }\n | { kind: 'call'; to?: string; from?: string; purpose?: string }\n | {\n kind: 'event'\n title?: string\n start?: string\n end?: string\n location?: string\n attendees: readonly string[]\n description?: string\n }\n | { kind: 'fields'; fields: readonly HubActionField[] }\n\n/** A held call in the owner's words. */\nexport interface HubActionPresentation {\n provider: { id: string; name: string }\n /** The imperative, e.g. `Open pull request`. */\n action: string\n /** One line naming the action and its object, e.g. `Open PR: Fix the hero on acme/site`. */\n title: string\n /** Where it acts: a repository, recipients, a channel or a customer. */\n target?: string\n preview: HubActionPreview\n}\n\n/** What a decided call did, as its receipt shows it. */\nexport interface HubActionReceipt {\n provider: { id: string; name: string }\n /** The result in past tense, e.g. `Opened PR #123` or `Sent email to ada@acme.com`. */\n title: string\n /** The result's own page, when it has one: the pull request, the post, the event. */\n href?: string\n status: 'done' | 'unknown' | 'failed' | 'denied' | 'expired' | 'running' | 'waiting'\n fields: readonly HubActionField[]\n files?: readonly HubActionFile[]\n media?: { kind: 'audio'; src: string; seconds?: number }\n error?: string\n /** Guidance for an uncertain outcome, separate from a confirmed failure. */\n warning?: string\n}\n","/**\n * Hub results, read the same way by every receipt: unwrapped from Hub's\n * envelope and bounded before a host persists them.\n */\n\nconst MAX_DEPTH = 4\nconst MAX_KEYS = 24\nconst MAX_ITEMS = 50\nconst MAX_STRING = 600\n\nexport function asRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n}\n\n/**\n * The provider's own result inside Hub's envelopes. `tools.invoke` answers\n * `{ result: … }` and a connector may wrap its body in `data`; a JSON string,\n * as an older host stored it, is parsed first.\n */\nexport function unwrapHubResult(value: unknown): unknown {\n let current: unknown = value\n if (typeof current === 'string') {\n const text = current\n try {\n current = JSON.parse(text)\n } catch {\n // An older host stored `Hub result: {…}`-style text with a JSON tail.\n const start = text.indexOf('{')\n if (start < 0) return value\n try {\n current = JSON.parse(text.slice(start))\n } catch {\n return value\n }\n }\n }\n for (let depth = 0; depth < 3; depth++) {\n const record = asRecord(current)\n const keys = Object.keys(record)\n const inner = keys.find((key) => key === 'result' || key === 'data')\n // Only a thin envelope is unwrapped; a body that happens to carry a `data`\n // field among its own fields is the result itself.\n if (!inner || keys.length > 3 || record[inner] === null || typeof record[inner] !== 'object') break\n current = record[inner]\n }\n return current\n}\n\nfunction bounded(value: unknown, depth: number): unknown {\n if (value === null || typeof value === 'boolean') return value\n if (typeof value === 'number') return Number.isFinite(value) ? value : null\n if (typeof value === 'string') return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING - 1)}…` : value\n if (depth >= MAX_DEPTH) return undefined\n if (Array.isArray(value)) {\n return value.slice(0, MAX_ITEMS).map((item) => bounded(item, depth + 1)).filter((item) => item !== undefined)\n }\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [key, entry] of Object.entries(value as Record<string, unknown>).slice(0, MAX_KEYS)) {\n const kept = bounded(entry, depth + 1)\n if (kept !== undefined) out[key] = kept\n }\n return out\n }\n return undefined\n}\n\n/**\n * A bounded copy of a Hub result for a host to store with the decision: the\n * envelope removed, strings, arrays and nesting capped. Receipts read it in\n * place of the full result.\n */\nexport function summarizeHubResult(result: unknown): unknown {\n return bounded(unwrapHubResult(result), 0)\n}\n\n/** The first non-empty string among `keys`, searched one level into nested records. */\nexport function readText(value: unknown, ...keys: string[]): string | undefined {\n const record = asRecord(value)\n for (const key of keys) {\n const found = record[key]\n if (typeof found === 'string' && found.trim()) return found.trim()\n if (typeof found === 'number' && Number.isFinite(found)) return String(found)\n }\n return undefined\n}\n\nexport function readNumber(value: unknown, ...keys: string[]): number | undefined {\n const record = asRecord(value)\n for (const key of keys) {\n const found = record[key]\n if (typeof found === 'number' && Number.isFinite(found)) return found\n }\n return undefined\n}\n\n/** A link a result names for itself, in the order providers use them. */\nexport function resultLink(value: unknown): string | undefined {\n const url = readText(value, 'html_url', 'htmlLink', 'webLink', 'web_url', 'permalink', 'hosted_invoice_url', 'url', 'link')\n return url && /^https:\\/\\//.test(url) ? url : undefined\n}\n","/** Internal safety copy shared by uncertain-outcome surfaces. */\nexport const HUB_APPROVAL_UNKNOWN_WARNING = 'Check the provider before requesting it again'\n","/**\n * Hub actions in an owner's words. Known integrations read as what they do —\n * `github.pulls.propose` is \"Open PR: Fix the hero on acme/site\", `gmail.send`\n * is \"Send email to ada@acme.com\" — and any other Hub action falls back to its\n * own name and its input's scalar fields.\n */\n\nimport { asRecord, readNumber, readText, resultLink, unwrapHubResult } from './result'\nimport { HUB_APPROVAL_UNKNOWN_WARNING } from './unknown'\nimport type {\n HubActionField,\n HubActionFile,\n HubActionPresentation,\n HubActionPreview,\n HubActionReceipt,\n HubApprovalItem,\n} from './types'\n\nconst PROVIDER_NAMES: Record<string, string> = {\n github: 'GitHub',\n gitlab: 'GitLab',\n gmail: 'Gmail',\n google: 'Google',\n 'google-calendar': 'Google Calendar',\n 'microsoft-calendar': 'Outlook Calendar',\n 'outlook-mail': 'Outlook',\n outlook: 'Outlook',\n twitter: 'X',\n x: 'X',\n linkedin: 'LinkedIn',\n stripe: 'Stripe',\n phony: 'ph0ny',\n slack: 'Slack',\n notion: 'Notion',\n hubspot: 'HubSpot',\n linear: 'Linear',\n inkbox: 'Inkbox',\n resend: 'Resend',\n}\n\n/** A provider's display name: `github` is GitHub, `outlook-mail` is Outlook. */\nexport function hubProviderName(id: string): string {\n if (PROVIDER_NAMES[id]) return PROVIDER_NAMES[id]\n const words = id.split(/[-_\\s]+/).filter(Boolean)\n return words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ') || id\n}\n\n/** `provider.action` split at the first dot. */\nexport function splitHubActionPath(actionPath: string): { provider: string; action: string } {\n const separator = actionPath.indexOf('.')\n return separator < 0 ? { provider: '', action: actionPath } : { provider: actionPath.slice(0, separator), action: actionPath.slice(separator + 1) }\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction clipped(value: string, max = 80): string {\n const single = value.replace(/\\s+/g, ' ').trim()\n return single.length > max ? `${single.slice(0, max - 1).trimEnd()}…` : single\n}\n\nfunction list(value: unknown): string[] {\n if (typeof value === 'string') return value.split(/[,;]/).map((entry) => entry.trim()).filter(Boolean)\n if (!Array.isArray(value)) return []\n return value.flatMap((entry) => {\n if (typeof entry === 'string' && entry.trim()) return [entry.trim()]\n const record = asRecord(entry)\n const address = text(record.email) ?? text(record.address) ?? text(asRecord(record.emailAddress).address)\n return address ? [address] : []\n })\n}\n\nfunction people(addresses: readonly string[]): string {\n if (addresses.length === 0) return ''\n if (addresses.length === 1) return addresses[0]!\n return `${addresses[0]} and ${addresses.length - 1} more`\n}\n\nfunction shortSha(sha: string | undefined): string | undefined {\n return sha && /^[0-9a-f]{7,}$/i.test(sha) ? sha.slice(0, 7) : sha\n}\n\n// ---------- verbs ----------\n\nconst PAST: Record<string, string> = {\n add: 'added', approve: 'approved', archive: 'archived', assign: 'assigned', book: 'booked', cancel: 'canceled',\n capture: 'captured', charge: 'charged', clone: 'cloned', close: 'closed', comment: 'commented', create: 'created',\n deactivate: 'deactivated', delete: 'deleted', enroll: 'enrolled', export: 'exported', finalize: 'finalized',\n forward: 'forwarded', import: 'imported', ingest: 'ingested', invite: 'invited', like: 'liked', make: 'made',\n merge: 'merged', move: 'moved', open: 'opened', pay: 'paid', place: 'placed', post: 'posted', provision: 'provisioned',\n publish: 'published', put: 'put', react: 'reacted', refund: 'refunded', remove: 'removed', reply: 'replied',\n retweet: 'reposted', review: 'reviewed', run: 'ran', save: 'saved', schedule: 'scheduled', send: 'sent', set: 'set',\n share: 'shared', start: 'started', stop: 'stopped', submit: 'submitted', subscribe: 'subscribed',\n synthesize: 'synthesized', transfer: 'transferred', translate: 'translated', update: 'updated', upload: 'uploaded',\n upsert: 'saved', void: 'voided', watch: 'watched', write: 'wrote',\n}\n\n/** The past tense of an English verb this vocabulary uses. */\nexport function pastTense(verb: string): string {\n const lower = verb.toLowerCase()\n const past = PAST[lower] ?? (lower.endsWith('e') ? `${lower}d` : `${lower}ed`)\n return verb.charAt(0) === verb.charAt(0).toUpperCase() ? past.charAt(0).toUpperCase() + past.slice(1) : past\n}\n\nfunction words(action: string): string[] {\n return action\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(/[._\\-\\s]+/)\n .map((word) => word.toLowerCase())\n .filter(Boolean)\n}\n\nfunction singular(word: string): string {\n if (word.endsWith('ies')) return `${word.slice(0, -3)}y`\n if (word.endsWith('sses') || word.endsWith('ss')) return word\n return word.endsWith('s') && word.length > 3 ? word.slice(0, -1) : word\n}\n\n/** A Hub action's own name as a sentence: `payment-intents.create` is \"Create payment intent\". */\nfunction genericVerb(action: string): { verb: string; noun: string } {\n const parts = words(action)\n const index = parts.findIndex((word) => word in PAST)\n if (index < 0) return { verb: '', noun: parts.join(' ') }\n const noun = [...parts.slice(0, index), ...parts.slice(index + 1)].map(singular).join(' ')\n return { verb: parts[index]!, noun }\n}\n\nfunction sentence(verb: string, noun: string): string {\n const phrase = [verb, noun].filter(Boolean).join(' ')\n return phrase.charAt(0).toUpperCase() + phrase.slice(1)\n}\n\n// ---------- inputs ----------\n\nfunction repository(input: Record<string, unknown>): string | undefined {\n const owner = text(input.owner)\n const repo = text(input.repo)\n if (owner && repo) return `${owner}/${repo}`\n return repo ?? text(input.repository)\n}\n\nfunction branchOf(ref: unknown): string | undefined {\n return text(ref)?.replace(/^refs\\/heads\\//, '')\n}\n\n/** The files a call writes, as its input declares them. */\nexport function hubActionFiles(actionPath: string, input: unknown): HubActionFile[] {\n const fields = asRecord(input)\n const { action } = splitHubActionPath(actionPath)\n const entries = action === 'git.createTree' ? fields.tree : fields.files\n if (!Array.isArray(entries)) return []\n return entries.flatMap((entry): HubActionFile[] => {\n const item = asRecord(entry)\n const path = text(item.path)\n if (!path) return []\n const deleted = item.delete === true || (item.sha === null && item.content === undefined)\n return [{ path, change: deleted ? 'deleted' : 'modified' }]\n })\n}\n\n/** Counted files replace declared ones by path; the declared order stays. */\nfunction mergedFiles(declared: readonly HubActionFile[], counted: readonly HubActionFile[] | undefined): HubActionFile[] {\n if (!counted || counted.length === 0) return [...declared]\n if (declared.length === 0) return [...counted]\n const byPath = new Map(counted.map((file) => [file.path, file]))\n return declared.map((file) => byPath.get(file.path) ?? file)\n}\n\nfunction emailPreview(input: Record<string, unknown>, reply: boolean): HubActionPreview {\n const from = asRecord(input.from)\n const htmlBody = typeof input.html === 'string' ? input.html : undefined\n return {\n kind: 'email',\n to: list(input.to ?? input.recipients),\n cc: list(input.cc),\n bcc: list(input.bcc),\n subject: text(input.subject),\n from: text(input.from) ?? text(from.email) ?? text(from.address),\n fromName: text(input.fromName) ?? text(input.from_name) ?? text(from.name),\n previewText: text(input.previewText) ?? text(input.preview_text) ?? text(input.preheader),\n // The payload is evidence: retain whitespace and prefer the actual HTML part.\n body: htmlBody ?? [input.body, input.text, input.comment].find((value): value is string => typeof value === 'string'),\n html: input.html === true || text(input.bodyType)?.toLowerCase() === 'html' || typeof input.html === 'string',\n reply,\n }\n}\n\nfunction speechSeconds(input: Record<string, unknown>): number | undefined {\n const spoken = text(input.text)\n if (!spoken) return undefined\n const speed = typeof input.speed === 'number' && input.speed > 0 ? input.speed : 1\n // About 2.5 spoken words a second at normal speed.\n return Math.max(1, Math.round(spoken.split(/\\s+/).length / 2.5 / speed))\n}\n\nfunction voiceName(input: Record<string, unknown>): string | undefined {\n const voice = text(input.voiceId)\n // An opaque provider id says nothing to an owner; a named voice does.\n if (voice && !/^[0-9a-f-]{16,}$/i.test(voice) && voice.length <= 32) return voice.charAt(0).toUpperCase() + voice.slice(1)\n return text(input.provider)\n}\n\nconst CURRENCY_DIGITS: Record<string, number> = { jpy: 0, krw: 0, vnd: 0, clp: 0, bhd: 3, kwd: 3, omr: 3 }\n\n/** A Stripe minor-unit amount in its currency: `4900` USD is `$49.00`. */\nexport function formatMinorAmount(amount: number, currency = 'usd'): string {\n const code = currency.toLowerCase()\n const digits = CURRENCY_DIGITS[code] ?? 2\n try {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency: code.toUpperCase(), minimumFractionDigits: digits })\n .format(amount / 10 ** digits)\n } catch {\n return `${(amount / 10 ** digits).toFixed(digits)} ${code.toUpperCase()}`\n }\n}\n\n/** Scalar input fields, for an action no renderer knows. */\nfunction scalarFields(input: Record<string, unknown>, max = 6): HubActionField[] {\n return Object.entries(input).flatMap(([key, value]): HubActionField[] => {\n if (key.startsWith('__')) return []\n if (typeof value === 'string' && value.trim()) return [{ label: labelOf(key), value: clipped(value, 160) }]\n if (typeof value === 'number' || typeof value === 'boolean') return [{ label: labelOf(key), value: String(value) }]\n const strings = Array.isArray(value) ? value.filter((entry): entry is string => typeof entry === 'string') : []\n return strings.length > 0 ? [{ label: labelOf(key), value: clipped(strings.join(', '), 160) }] : []\n }).slice(0, max)\n}\n\nfunction labelOf(key: string): string {\n const spaced = key.replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/[_-]+/g, ' ').trim().toLowerCase()\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n\n// ---------- presentation ----------\n\ntype Presenter = (input: Record<string, unknown>, item: Pick<HubApprovalItem, 'actionPath' | 'files'>) => Omit<HubActionPresentation, 'provider'>\n\nfunction pullRequest(input: Record<string, unknown>, item: Pick<HubApprovalItem, 'actionPath' | 'files'>): Omit<HubActionPresentation, 'provider'> {\n const repo = repository(input)\n const title = text(input.title) ?? 'Untitled change'\n return {\n action: 'Open pull request',\n title: `Open PR: ${clipped(title)}${repo ? ` on ${repo}` : ''}`,\n ...(repo ? { target: repo } : {}),\n preview: {\n kind: 'pull-request',\n repository: repo,\n title,\n body: text(input.body),\n head: branchOf(input.branch ?? input.head),\n base: text(input.base),\n draft: item.actionPath.endsWith('.propose') ? true : input.draft === true,\n files: mergedFiles(hubActionFiles(item.actionPath, input), item.files),\n },\n }\n}\n\nfunction issueLike(verb: string, noun: string): Presenter {\n return (input) => {\n const repo = repository(input)\n const number = readNumber(input, 'issue_number', 'pull_number', 'number')\n const title = text(input.title)\n const object = number !== undefined ? `${noun} #${number}` : title ? `${noun}: ${clipped(title)}` : noun\n return {\n action: sentence(verb, noun.toLowerCase()),\n title: `${sentence(verb, object)}${repo ? ` on ${repo}` : ''}`,\n ...(repo ? { target: repo } : {}),\n preview: {\n kind: 'issue',\n repository: repo,\n number,\n title,\n body: text(input.body),\n verdict: text(input.event)?.toLowerCase().replace(/_/g, ' '),\n },\n }\n }\n}\n\nfunction sendEmail(verb: 'Send' | 'Save draft', reply = false): Presenter {\n return (input) => {\n const preview = emailPreview(input, reply)\n const recipients = preview.kind === 'email' ? people(preview.to) : ''\n const action = reply ? 'Send reply' : verb === 'Send' ? 'Send email' : 'Save draft'\n return {\n action,\n title: reply ? 'Send reply' : `${action}${recipients ? ` to ${recipients}` : ''}`,\n ...(recipients ? { target: recipients } : {}),\n preview,\n }\n }\n}\n\nfunction post(channel: 'x' | 'linkedin', reply = false): Presenter {\n return (input) => {\n const body = typeof input.text === 'string' ? input.text : typeof input.commentary === 'string' ? input.commentary : ''\n const url = text(input.url)\n const where = channel === 'x' ? 'X' : 'LinkedIn'\n return {\n action: reply ? `Reply on ${where}` : `Post on ${where}`,\n title: `${reply ? 'Reply' : 'Post'} on ${where}${body ? `: “${clipped(body, 60)}”` : ''}`,\n target: where,\n preview: {\n kind: 'post',\n channel,\n text: body,\n images: (Array.isArray(input.images) ? input.images : input.image ? [input.image] : []).flatMap((image) => {\n const record = asRecord(image)\n const url = text(image) ?? text(record.url)\n return url ? [{ url, alt: text(record.alt) }] : []\n }),\n ...(url ? { link: { url, title: text(input.title), description: text(input.description) } } : {}),\n },\n }\n }\n}\n\nfunction payment(label: string): Presenter {\n return (input) => {\n const amount = readNumber(input, 'amount')\n const currency = text(input.currency)\n const customer = text(input.customerId) ?? text(input.customer) ?? text(input.email)\n const formatted = amount !== undefined ? formatMinorAmount(amount, currency) : undefined\n const object = formatted ? `${label} of ${formatted}` : label\n return {\n action: sentence('create', label),\n title: `${sentence('create', object)}${customer ? ` for ${customer}` : ''}`,\n ...(customer ? { target: customer } : {}),\n preview: { kind: 'payment', label, amount, currency, customer, description: text(input.description) },\n }\n }\n}\n\nfunction calendarEvent(input: Record<string, unknown>, _item?: Pick<HubApprovalItem, 'actionPath' | 'files'>): Omit<HubActionPresentation, 'provider'> {\n const title = text(input.summary) ?? text(input.title) ?? text(input.subject)\n return {\n action: 'Book event',\n title: title ? `Book “${clipped(title, 60)}”` : 'Book an event',\n preview: {\n kind: 'event',\n title,\n start: text(input.start) ?? text(asRecord(input.start).dateTime),\n end: text(input.end) ?? text(asRecord(input.end).dateTime),\n location: text(input.location) ?? text(asRecord(input.location).displayName),\n attendees: list(input.attendees),\n description: text(input.description),\n },\n }\n}\n\nconst PRESENTERS: Record<string, Presenter> = {\n 'github.pulls.propose': pullRequest,\n 'github.pulls.create': pullRequest,\n 'github.git.createTree': (input, item) => {\n const repo = repository(input)\n const files = mergedFiles(hubActionFiles(item.actionPath, input), item.files)\n return {\n action: 'Write files',\n title: `Write ${files.length === 1 ? files[0]!.path : `${files.length} files`}${repo ? ` to ${repo}` : ''}`,\n ...(repo ? { target: repo } : {}),\n preview: { kind: 'files', repository: repo, files },\n }\n },\n 'github.git.createCommit': (input) => {\n const repo = repository(input)\n const message = text(input.message)\n return {\n action: 'Create commit',\n title: `Commit${message ? ` “${clipped(message, 60)}”` : ''}${repo ? ` to ${repo}` : ''}`,\n ...(repo ? { target: repo } : {}),\n preview: { kind: 'commit', repository: repo, message, tree: text(input.tree), parents: list(input.parents) },\n }\n },\n 'github.git.createRef': (input) => {\n const repo = repository(input)\n const branch = branchOf(input.ref)\n return {\n action: 'Create branch',\n title: `Create branch ${branch ?? ''}${repo ? ` in ${repo}` : ''}`.replace(/\\s+/g, ' ').trim(),\n ...(repo ? { target: repo } : {}),\n preview: { kind: 'branch', repository: repo, branch, sha: text(input.sha) },\n }\n },\n 'github.pulls.merge': issueLike('merge', 'PR'),\n 'github.pulls.reviews.create': issueLike('review', 'PR'),\n 'github.issues.create': issueLike('open', 'Issue'),\n 'github.issues.update': issueLike('update', 'Issue'),\n 'github.issues.createComment': issueLike('comment on', 'Issue'),\n 'gmail.send': sendEmail('Send'),\n 'gmail.send_reply': sendEmail('Send', true),\n 'outlook-mail.send_message': sendEmail('Send'),\n 'outlook-mail.send_draft': sendEmail('Send'),\n 'outlook-mail.create_draft': sendEmail('Save draft'),\n 'outlook-mail.send_reply': sendEmail('Send', true),\n 'inkbox.email.send': sendEmail('Send'),\n 'resend.emails.send': sendEmail('Send'),\n 'resend.emails.reply': sendEmail('Send', true),\n 'twitter.tweets.create': post('x'),\n 'twitter.tweets.reply': post('x', true),\n 'x.tweets.create': post('x'),\n 'linkedin.posts.create': post('linkedin'),\n 'linkedin.shares.create': post('linkedin'),\n 'slack.post_message': (input) => {\n const channel = text(input.channel) ?? text(input.channelId)\n const where = channel ? (channel.startsWith('#') || /^[CDG][A-Z0-9]{6,}$/.test(channel) ? channel : `#${channel}`) : undefined\n return {\n action: 'Post in Slack',\n title: `Post in ${where ?? 'Slack'}`,\n ...(where ? { target: where } : {}),\n preview: { kind: 'post', channel: 'slack', text: text(input.text) ?? '', where },\n }\n },\n 'stripe.payment-intents.create': payment('payment'),\n 'stripe.payment-links.create': payment('payment link'),\n 'stripe.invoices.create': payment('invoice'),\n 'stripe.refunds.create': payment('refund'),\n 'stripe.subscriptions.create': payment('subscription'),\n 'phony.synthesize_speech': (input) => {\n const seconds = speechSeconds(input)\n const voice = voiceName(input)\n const detail = [voice, seconds ? `${seconds} s` : undefined].filter(Boolean)\n return {\n action: 'Create voice memo',\n title: `Create voice memo${detail.length ? ` (${detail.join(', ')})` : ''}`,\n preview: { kind: 'speech', text: text(input.text) ?? '', voice, seconds },\n }\n },\n 'phony.start_outbound_call': (input) => {\n const to = text(input.toNumber) ?? text(input.to)\n const mission = asRecord(input.mission)\n return {\n action: 'Start call',\n title: to ? `Call ${to}` : 'Start an outbound call',\n ...(to ? { target: to } : {}),\n preview: {\n kind: 'call',\n to,\n from: text(input.fromNumber),\n purpose: text(mission.goal) ?? text(mission.objective) ?? text(mission.summary) ?? text(input.missionId),\n },\n }\n },\n 'phony.create_agent': (input) => {\n const name = text(input.name)\n return {\n action: 'Create voice agent',\n title: `Create voice agent${name ? ` “${clipped(name, 60)}”` : ''}`,\n preview: { kind: 'fields', fields: scalarFields(input) },\n }\n },\n 'phony.update_agent': (input) => ({\n action: 'Update voice agent',\n title: 'Update a voice agent',\n preview: { kind: 'fields', fields: scalarFields(input) },\n }),\n 'phony.clone_voice': (input) => {\n const name = text(input.name)\n return {\n action: 'Clone voice',\n title: `Clone your voice${name ? ` as “${clipped(name, 60)}”` : ''}`,\n preview: { kind: 'fields', fields: scalarFields(input) },\n }\n },\n 'google-calendar.create_event': calendarEvent,\n 'google-calendar.book_slot': calendarEvent,\n 'google-calendar.update_event': (input, item) => {\n const event = calendarEvent(input, item)\n const title = event.preview.kind === 'event' ? event.preview.title : undefined\n return { ...event, action: 'Update event', title: title ? `Update “${clipped(title, 60)}”` : 'Update an event' }\n },\n 'microsoft-calendar.book_slot': calendarEvent,\n}\n\n/** A held call in the owner's words, with the preview its integration renders. */\nexport function presentHubAction(item: Pick<HubApprovalItem, 'actionPath' | 'providerId' | 'input' | 'files' | 'bundle' | 'preview'>): HubActionPresentation {\n const { provider: pathProvider, action } = splitHubActionPath(item.actionPath)\n const providerId = item.providerId || pathProvider\n const provider = { id: providerId, name: hubProviderName(providerId) }\n const input = asRecord(item.input)\n const known = PRESENTERS[item.actionPath]\n const presented = known\n ? known(input, item)\n : (() => {\n const { verb, noun } = genericVerb(action)\n const phrase = sentence(verb, noun) || action\n const object = text(input.name) ?? text(input.title) ?? text(input.subject) ?? text(input.label)\n return {\n action: phrase,\n title: object ? `${phrase} “${clipped(object, 60)}”` : phrase,\n preview: { kind: 'fields', fields: scalarFields(input) } as HubActionPreview,\n }\n })()\n return { provider, ...presented, ...(item.preview ? { preview: item.preview } : {}), ...(item.bundle ? { title: item.bundle.title } : {}) }\n}\n\n// ---------- receipts ----------\n\nfunction prField(result: Record<string, unknown>): HubActionField | undefined {\n const pull = asRecord(result.pullRequest)\n const number = readNumber(pull, 'number') ?? readNumber(result, 'number')\n if (number === undefined) return undefined\n return { label: 'Pull request', value: `#${number}`, href: resultLink(pull) ?? resultLink(result) }\n}\n\nfunction receiptTitle(item: HubApprovalItem, presentation: HubActionPresentation, result: Record<string, unknown>): string {\n const { action } = splitHubActionPath(item.actionPath)\n const input = asRecord(item.input)\n const pull = asRecord(result.pullRequest)\n const number = readNumber(pull, 'number') ?? readNumber(result, 'number')\n switch (item.actionPath) {\n case 'github.pulls.propose':\n case 'github.pulls.create':\n return number !== undefined ? `Opened PR #${number}` : 'Opened pull request'\n case 'github.git.createCommit': {\n const sha = shortSha(readText(result, 'sha'))\n return sha ? `Created commit ${sha}` : 'Created commit'\n }\n case 'github.git.createTree': {\n const files = hubActionFiles(item.actionPath, input).length\n return `Wrote ${files === 1 ? '1 file' : `${files} files`}`\n }\n case 'github.git.createRef':\n return `Created branch ${branchOf(readText(result, 'ref') ?? input.ref) ?? ''}`.trim()\n case 'github.issues.create':\n return number !== undefined ? `Opened issue #${number}` : 'Opened issue'\n case 'github.issues.createComment': {\n const on = readNumber(input, 'issue_number')\n return on !== undefined ? `Commented on #${on}` : 'Commented'\n }\n case 'github.pulls.reviews.create': {\n const on = readNumber(input, 'pull_number')\n return on !== undefined ? `Reviewed PR #${on}` : 'Reviewed pull request'\n }\n case 'github.pulls.merge': {\n const on = readNumber(input, 'pull_number')\n return on !== undefined ? `Merged PR #${on}` : 'Merged pull request'\n }\n case 'phony.synthesize_speech':\n return 'Created voice memo'\n }\n if (presentation.preview.kind === 'email') {\n const to = people(presentation.preview.to)\n if (presentation.preview.reply) return 'Sent reply'\n return action.includes('draft') && !action.startsWith('send') ? `Saved draft${to ? ` to ${to}` : ''}` : `Sent email${to ? ` to ${to}` : ''}`\n }\n if (presentation.preview.kind === 'post') {\n return presentation.preview.channel === 'slack' ? `Posted in ${presentation.preview.where ?? 'Slack'}` : `Posted on ${presentation.target ?? presentation.provider.name}`\n }\n if (presentation.preview.kind === 'event') {\n const verb = presentation.action === 'Update event' ? 'Updated' : 'Booked'\n return presentation.preview.title ? `${verb} “${clipped(presentation.preview.title, 60)}”` : `${verb} event`\n }\n if (presentation.preview.kind === 'call') return presentation.preview.to ? `Started call to ${presentation.preview.to}` : 'Started call'\n const [first = '', ...rest] = presentation.action.split(' ')\n return [pastTense(first), ...rest].join(' ')\n}\n\nfunction postLink(item: HubApprovalItem, result: Record<string, unknown>): string | undefined {\n const id = readText(result, 'id', 'urn', 'postUrn')\n if (!id) return resultLink(result)\n if (item.providerId === 'twitter' || item.providerId === 'x') return /^\\d+$/.test(id) ? `https://x.com/i/web/status/${id}` : resultLink(result)\n if (item.providerId === 'linkedin') return id.startsWith('urn:li:') ? `https://www.linkedin.com/feed/update/${id}/` : resultLink(result)\n return resultLink(result)\n}\n\nfunction receiptFields(item: HubApprovalItem, presentation: HubActionPresentation, result: Record<string, unknown>): HubActionField[] {\n const fields: HubActionField[] = []\n const preview = presentation.preview\n switch (preview.kind) {\n case 'pull-request': {\n const pr = prField(result)\n if (pr) fields.push(pr)\n const head = readText(result, 'branch') ?? preview.head\n const base = readText(result, 'base') ?? preview.base\n if (head && base) fields.push({ label: 'Branch', value: `${head} → ${base}`, mono: true })\n const commit = asRecord(result.commit)\n const sha = readText(commit, 'sha')\n if (sha) fields.push({ label: 'Commit', value: shortSha(sha)!, href: resultLink(commit), mono: true })\n const repo = readText(result, 'repository') ?? preview.repository\n if (repo) fields.push({ label: 'Repository', value: repo, href: `https://github.com/${repo}` })\n return fields\n }\n case 'commit': {\n const sha = readText(result, 'sha')\n if (sha) fields.push({ label: 'Commit', value: shortSha(sha)!, href: resultLink(result)?.includes('api.github.com') ? undefined : resultLink(result), mono: true })\n if (preview.message) fields.push({ label: 'Message', value: clipped(preview.message, 120) })\n return fields\n }\n case 'branch': {\n const branch = branchOf(readText(result, 'ref')) ?? preview.branch\n if (branch && preview.repository) fields.push({ label: 'Branch', value: branch, href: `https://github.com/${preview.repository}/tree/${branch}`, mono: true })\n return fields\n }\n case 'files': {\n const sha = readText(result, 'sha')\n if (sha) fields.push({ label: 'Tree', value: shortSha(sha)!, mono: true })\n return fields\n }\n case 'email': {\n if (preview.subject) fields.push({ label: 'Subject', value: clipped(preview.subject, 120) })\n if (preview.cc.length) fields.push({ label: 'Cc', value: preview.cc.join(', ') })\n return fields\n }\n case 'payment': {\n const amount = readNumber(result, 'amount', 'amount_total', 'total') ?? preview.amount\n const currency = readText(result, 'currency') ?? preview.currency\n if (amount !== undefined) fields.push({ label: 'Amount', value: formatMinorAmount(amount, currency) })\n const customer = readText(result, 'customer_email', 'customer') ?? preview.customer\n if (customer) fields.push({ label: 'Customer', value: customer, mono: customer.startsWith('cus_') })\n const status = readText(result, 'status')\n if (status) fields.push({ label: 'Status', value: status })\n return fields\n }\n case 'speech': {\n const seconds = readNumber(result, 'durationSeconds', 'duration')\n if (seconds !== undefined) fields.push({ label: 'Length', value: `${Math.round(seconds * 10) / 10} s` })\n if (preview.voice) fields.push({ label: 'Voice', value: preview.voice })\n return fields\n }\n case 'event': {\n if (preview.start) fields.push({ label: 'When', value: formatWhen(preview.start, preview.end) })\n if (preview.attendees.length) fields.push({ label: 'Guests', value: people(preview.attendees) })\n return fields\n }\n case 'call': {\n const status = readText(asRecord(result.call), 'status') ?? readText(result, 'status')\n if (status) fields.push({ label: 'Status', value: status })\n return fields\n }\n default: {\n const id = readText(result, 'id', 'number', 'key')\n if (id) fields.push({ label: 'ID', value: id, mono: true })\n const status = readText(result, 'status', 'state')\n if (status) fields.push({ label: 'Status', value: status })\n const name = readText(result, 'name', 'title')\n if (name) fields.push({ label: 'Name', value: clipped(name, 80) })\n return fields\n }\n }\n}\n\n/** A start and optional end in the viewer's locale: `Tue, Oct 14, 3:00 – 3:30 PM`. */\nexport function formatWhen(start: string, end?: string): string {\n const from = new Date(start)\n if (Number.isNaN(from.getTime())) return end ? `${start} – ${end}` : start\n const day = from.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' })\n const time = (date: Date) => date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' })\n const to = end ? new Date(end) : null\n if (!to || Number.isNaN(to.getTime())) return `${day}, ${time(from)}`\n return to.toDateString() === from.toDateString() ? `${day}, ${time(from)} – ${time(to)}` : `${day}, ${time(from)} – ${to.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}, ${time(to)}`\n}\n\nfunction receiptFiles(result: Record<string, unknown>): HubActionFile[] | undefined {\n if (!Array.isArray(result.files)) return undefined\n return result.files.flatMap((entry): HubActionFile[] => {\n const file = asRecord(entry)\n const path = text(file.path) ?? text(file.filename)\n if (!path) return []\n const status = text(file.status)\n const change = status === 'added' ? 'added' : status === 'removed' || status === 'deleted' ? 'deleted' : 'modified'\n return [{ path, change, additions: readNumber(file, 'additions'), deletions: readNumber(file, 'deletions') }]\n })\n}\n\n/** What a decided call did: its past-tense title, key fields, link, media and files. */\nexport function hubActionReceipt(item: HubApprovalItem): HubActionReceipt {\n const presentation = presentHubAction(item)\n const result = asRecord(unwrapHubResult(item.result))\n const status: HubActionReceipt['status'] = item.phase === 'done' || item.phase === 'unknown' || item.phase === 'failed' || item.phase === 'denied' || item.phase === 'expired'\n ? item.phase\n : item.phase === 'queued' || item.phase === 'running' ? 'running' : 'waiting'\n const base = { provider: presentation.provider, status }\n if (status === 'denied') return { ...base, title: `Denied: ${presentation.title}`, fields: [] }\n if (status === 'expired') return { ...base, title: `Expired: ${presentation.title}`, fields: [] }\n if (status === 'unknown') return { ...base, title: `May have run: ${presentation.title}`, fields: [], warning: HUB_APPROVAL_UNKNOWN_WARNING }\n if (status === 'failed') return { ...base, title: `Could not ${presentation.action.charAt(0).toLowerCase()}${presentation.action.slice(1)}`, fields: [], ...(item.error ? { error: item.error } : {}) }\n if (status !== 'done') return { ...base, title: presentation.title, fields: [] }\n const title = receiptTitle(item, presentation, result)\n const fields = receiptFields(item, presentation, result)\n const pull = asRecord(result.pullRequest)\n const href = presentation.preview.kind === 'post'\n ? postLink(item, result)\n : resultLink(pull) ?? (item.actionPath.startsWith('github.git.') ? undefined : resultLink(result))\n const audio = readText(result, 'audioUrl')\n const seconds = readNumber(result, 'durationSeconds', 'duration')\n const files = receiptFiles(result)\n return {\n ...base,\n title,\n ...(href ? { href } : {}),\n fields,\n ...(files && files.length ? { files } : {}),\n ...(audio && /^https:\\/\\//.test(audio) ? { media: { kind: 'audio' as const, src: audio, ...(seconds !== undefined ? { seconds } : {}) } } : {}),\n }\n}\n","/**\n * `./hub-approvals` — Hub actions that wait on a person, in the owner's words.\n *\n * Pure and browser-safe: a host maps its held calls into {@link HubApprovalItem}s\n * and every surface — the approval dock above the composer, the Approvals list\n * beside the conversation, and the receipts in the transcript — renders the\n * same presentation from them. Servers use {@link summarizeHubResult} to store\n * a bounded result with the decision.\n */\n\nimport type { HubApprovalPhase } from './types'\n\nexport * from './types'\nexport {\n formatMinorAmount,\n formatWhen,\n hubActionFiles,\n hubActionReceipt,\n hubProviderName,\n pastTense,\n presentHubAction,\n splitHubActionPath,\n} from './present'\nexport { summarizeHubResult, unwrapHubResult } from './result'\n\n/** A phase as a status label. */\nexport const HUB_APPROVAL_PHASE_LABELS: Record<HubApprovalPhase, string> = {\n waiting: 'Waiting for you',\n blocked: 'Waiting for the owner',\n queued: 'Queued',\n running: 'Running',\n done: 'Done',\n failed: 'Failed',\n unknown: 'May have run',\n denied: 'Denied',\n expired: 'Expired',\n}\n\n/**\n * The part type marking a user message that resumes the agent after a\n * decision. The message's text goes to the agent unchanged; a transcript\n * renders the decided actions' receipts in its place, never a chat bubble.\n */\nexport const HUB_APPROVAL_RESUME_PART = 'hub-approval-resume'\n\nexport interface HubApprovalResumePart {\n type: typeof HUB_APPROVAL_RESUME_PART\n /** The assistant message whose held calls this resume reports. */\n messageId: string\n}\n\n/** The resume marker among a message's parts, if it carries one. */\nexport function hubApprovalResumePart(parts: ReadonlyArray<Record<string, unknown>> | null | undefined): HubApprovalResumePart | null {\n for (const part of parts ?? []) {\n if (part?.type === HUB_APPROVAL_RESUME_PART && typeof part.messageId === 'string' && part.messageId) {\n return { type: HUB_APPROVAL_RESUME_PART, messageId: part.messageId }\n }\n }\n return null\n}\n"],"mappings":"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","names":["text","words","url"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ActionDialog,
3
3
  ActionDialogButton
4
- } from "./chunk-QJYJOMMO.js";
4
+ } from "./chunk-A2GG4D4A.js";
5
5
  import {
6
6
  UNTITLED_SESSION_LABEL,
7
7
  mergeSessionPages,
@@ -746,4 +746,4 @@ export {
746
746
  formatSessionTimestamp,
747
747
  SessionHistoryPanel
748
748
  };
749
- //# sourceMappingURL=chunk-4WEUWCA4.js.map
749
+ //# sourceMappingURL=chunk-EQRVOMMS.js.map
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-I6BZVIRH.js";
5
5
  import {
6
6
  defineAppTool
7
- } from "./chunk-6CKNC32J.js";
7
+ } from "./chunk-AJZ3EJB5.js";
8
8
  import {
9
9
  ToolInputError
10
- } from "./chunk-7PSYT35Z.js";
10
+ } from "./chunk-7BYY7QKC.js";
11
11
 
12
12
  // src/agent-profiles/index.ts
13
13
  import {
@@ -19,6 +19,8 @@ import {
19
19
  import { z } from "zod";
20
20
 
21
21
  // src/agent-profiles/self-management.ts
22
+ import { eq } from "drizzle-orm";
23
+ import { sqliteTable, text } from "drizzle-orm/sqlite-core";
22
24
  var PERMITTED_SELF_MOUNT_DIMENSIONS = ["skills"];
23
25
  function createInMemorySelfMountStorage() {
24
26
  const state = /* @__PURE__ */ new Map();
@@ -125,6 +127,57 @@ function createMountProfileChangeTool(deps) {
125
127
  }
126
128
  });
127
129
  }
130
+ function selfMountTable(tableName) {
131
+ return sqliteTable(tableName, {
132
+ scope: text("scope").primaryKey(),
133
+ mounted: text("mounted").notNull()
134
+ });
135
+ }
136
+ function createDrizzleSelfMountStorage(db, table, baseline) {
137
+ return {
138
+ async get(scope) {
139
+ const rows = await db.select({ mounted: table.mounted }).from(table).where(eq(table.scope, scope)).limit(1);
140
+ try {
141
+ return rows[0] ? JSON.parse(rows[0].mounted) : [baseline];
142
+ } catch {
143
+ return [baseline];
144
+ }
145
+ },
146
+ async set(scope, ids) {
147
+ await db.insert(table).values({ scope, mounted: JSON.stringify(ids) }).onConflictDoUpdate({
148
+ target: table.scope,
149
+ set: { mounted: JSON.stringify(ids) }
150
+ });
151
+ }
152
+ };
153
+ }
154
+ function createKVSelfMountStorage(kv, prefix, baseline) {
155
+ const key = (scope) => `${prefix}:${scope}`;
156
+ return {
157
+ async get(scope) {
158
+ const raw = await kv.get(key(scope));
159
+ try {
160
+ return raw ? JSON.parse(raw) : [baseline];
161
+ } catch {
162
+ return [baseline];
163
+ }
164
+ },
165
+ async set(scope, ids) {
166
+ await kv.put(key(scope), JSON.stringify(ids));
167
+ }
168
+ };
169
+ }
170
+ function createProductSelfMount(config) {
171
+ const storage = config.db ? createDrizzleSelfMountStorage(config.db, selfMountTable(config.tableName ?? "agent_self_mounts"), config.baseline) : config.kv ? createKVSelfMountStorage(config.kv, config.kvPrefix ?? "self-mount", config.baseline) : void 0;
172
+ if (!storage) throw new Error("createProductSelfMount needs db or kv");
173
+ return createMountProfileChangeTool({
174
+ skills: config.skills,
175
+ storage,
176
+ scopeKey: (ctx) => ctx.workspaceId ?? ctx.threadId ?? "",
177
+ baseline: config.baseline,
178
+ maxMounted: config.maxMounted ?? 12
179
+ });
180
+ }
128
181
 
129
182
  // src/agent-profiles/index.ts
130
183
  var PROFILE_CHANGE_POLICY = {
@@ -621,9 +674,9 @@ function profileTools(context) {
621
674
  const turn = await context.activeTurn();
622
675
  if (turn.role !== "owner" && turn.role !== "manager") throw new ProfileAccessError("Profile management is required");
623
676
  if (context.memory) {
624
- const text = fact.replace(/\s+/g, " ");
625
- const known = (await context.memory.list(turn.workspaceId, PROFILE_MEMORY_PREFIX)).find((entry) => entry.content?.trim() === text);
626
- if (known) return { memoryId: known.id, saved: true, alreadyKnown: true, line: `- ${text}`, appliesTo: "next_message" };
677
+ const text2 = fact.replace(/\s+/g, " ");
678
+ const known = (await context.memory.list(turn.workspaceId, PROFILE_MEMORY_PREFIX)).find((entry) => entry.content?.trim() === text2);
679
+ if (known) return { memoryId: known.id, saved: true, alreadyKnown: true, line: `- ${text2}`, appliesTo: "next_message" };
627
680
  const id = crypto.randomUUID();
628
681
  const saved = await context.memory.put({
629
682
  workspaceId: turn.workspaceId,
@@ -631,10 +684,10 @@ function profileTools(context) {
631
684
  kind: "fact",
632
685
  ifRevision: null,
633
686
  actor: turn.memberId,
634
- content: text,
687
+ content: text2,
635
688
  id
636
689
  });
637
- return { memoryId: saved.id, saved: true, alreadyKnown: false, line: `- ${text}`, appliesTo: "next_message" };
690
+ return { memoryId: saved.id, saved: true, alreadyKnown: false, line: `- ${text2}`, appliesTo: "next_message" };
638
691
  }
639
692
  const line = `- ${fact.replace(/\s+/g, " ")}`;
640
693
  for (let attempt = 0; ; attempt++) {
@@ -689,6 +742,10 @@ export {
689
742
  PERMITTED_SELF_MOUNT_DIMENSIONS,
690
743
  createInMemorySelfMountStorage,
691
744
  createMountProfileChangeTool,
745
+ selfMountTable,
746
+ createDrizzleSelfMountStorage,
747
+ createKVSelfMountStorage,
748
+ createProductSelfMount,
692
749
  PROFILE_CHANGE_POLICY,
693
750
  ProfileConflictError,
694
751
  ProfileAccessError,
@@ -715,4 +772,4 @@ export {
715
772
  PROFILE_MEMORY_PREFIX,
716
773
  profileTools
717
774
  };
718
- //# sourceMappingURL=chunk-6VXBUIM5.js.map
775
+ //# sourceMappingURL=chunk-KOTNMTHV.js.map