@elizaos/app-core 2.0.0-alpha.335 → 2.0.0-alpha.337

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 (62) hide show
  1. package/apps/app-lifeops/src/routes/lifeops-routes.d.ts.map +1 -1
  2. package/apps/app-lifeops/src/routes/lifeops-routes.js +10 -1
  3. package/i18n/locales/en.json +5 -5
  4. package/package.json +5 -5
  5. package/packages/agent/src/runtime/eliza.d.ts.map +1 -1
  6. package/packages/agent/src/runtime/eliza.js +7 -2
  7. package/packages/app-core/src/api/automations-compat-routes.js +1 -1
  8. package/packages/app-core/src/api/client-n8n.d.ts +4 -1
  9. package/packages/app-core/src/api/client-n8n.d.ts.map +1 -1
  10. package/packages/app-core/src/api/client-n8n.js +18 -0
  11. package/packages/app-core/src/api/client-types-chat.d.ts +37 -0
  12. package/packages/app-core/src/api/client-types-chat.d.ts.map +1 -1
  13. package/packages/app-core/src/api/n8n-routes.d.ts +6 -0
  14. package/packages/app-core/src/api/n8n-routes.d.ts.map +1 -1
  15. package/packages/app-core/src/api/n8n-routes.js +334 -0
  16. package/packages/app-core/src/components/character/CharacterEditorPanels.d.ts.map +1 -1
  17. package/packages/app-core/src/components/character/CharacterEditorPanels.js +192 -85
  18. package/packages/app-core/src/components/character/CharacterExperienceWorkspace.d.ts.map +1 -1
  19. package/packages/app-core/src/components/character/CharacterExperienceWorkspace.js +182 -31
  20. package/packages/app-core/src/components/character/CharacterHubView.d.ts.map +1 -1
  21. package/packages/app-core/src/components/character/CharacterHubView.js +253 -23
  22. package/packages/app-core/src/components/character/CharacterOverviewSection.d.ts +14 -1
  23. package/packages/app-core/src/components/character/CharacterOverviewSection.d.ts.map +1 -1
  24. package/packages/app-core/src/components/character/CharacterOverviewSection.js +35 -8
  25. package/packages/app-core/src/components/character/character-hub-helpers.d.ts.map +1 -1
  26. package/packages/app-core/src/components/character/character-hub-helpers.js +3 -7
  27. package/packages/app-core/src/components/pages/AutomationsView.d.ts.map +1 -1
  28. package/packages/app-core/src/components/pages/AutomationsView.js +523 -274
  29. package/packages/app-core/src/components/pages/HeartbeatForm.d.ts.map +1 -1
  30. package/packages/app-core/src/components/pages/HeartbeatForm.js +11 -13
  31. package/packages/app-core/src/components/pages/KnowledgeView.d.ts.map +1 -1
  32. package/packages/app-core/src/components/pages/KnowledgeView.js +20 -6
  33. package/packages/app-core/src/components/pages/RelationshipsGraphPanel.d.ts +2 -1
  34. package/packages/app-core/src/components/pages/RelationshipsGraphPanel.d.ts.map +1 -1
  35. package/packages/app-core/src/components/pages/RelationshipsGraphPanel.js +3 -3
  36. package/packages/app-core/src/components/pages/WorkflowGraphViewer.d.ts +0 -9
  37. package/packages/app-core/src/components/pages/WorkflowGraphViewer.d.ts.map +1 -1
  38. package/packages/app-core/src/components/pages/WorkflowGraphViewer.js +52 -26
  39. package/packages/app-core/src/components/pages/knowledge-detail.d.ts.map +1 -1
  40. package/packages/app-core/src/components/pages/knowledge-detail.js +28 -2
  41. package/packages/app-core/src/components/pages/page-scoped-conversations.d.ts +1 -1
  42. package/packages/app-core/src/components/pages/page-scoped-conversations.js +4 -4
  43. package/packages/app-core/src/components/pages/relationships/RelationshipsPersonPanels.d.ts +2 -1
  44. package/packages/app-core/src/components/pages/relationships/RelationshipsPersonPanels.d.ts.map +1 -1
  45. package/packages/app-core/src/components/pages/relationships/RelationshipsPersonPanels.js +69 -32
  46. package/packages/app-core/src/components/pages/relationships/RelationshipsSidebar.d.ts +1 -6
  47. package/packages/app-core/src/components/pages/relationships/RelationshipsSidebar.d.ts.map +1 -1
  48. package/packages/app-core/src/components/pages/relationships/RelationshipsSidebar.js +4 -4
  49. package/packages/app-core/src/components/pages/relationships/RelationshipsWorkspaceView.d.ts +2 -1
  50. package/packages/app-core/src/components/pages/relationships/RelationshipsWorkspaceView.d.ts.map +1 -1
  51. package/packages/app-core/src/components/pages/relationships/RelationshipsWorkspaceView.js +25 -15
  52. package/packages/app-core/src/i18n/locales/en.json +5 -5
  53. package/packages/app-core/src/registry/generate-apps.js +2 -2
  54. package/packages/app-core/src/runtime/eliza.d.ts.map +1 -1
  55. package/packages/app-core/src/runtime/eliza.js +6 -1
  56. package/packages/app-core/src/services/n8n-dispatch.d.ts +10 -2
  57. package/packages/app-core/src/services/n8n-dispatch.d.ts.map +1 -1
  58. package/packages/app-core/src/services/n8n-dispatch.js +102 -8
  59. package/packages/shared/src/contracts/lifeops.d.ts +4 -0
  60. package/packages/shared/src/contracts/lifeops.d.ts.map +1 -1
  61. package/packages/typescript/src/features/advanced-capabilities/clipboard/services/clipboardService.d.ts.map +1 -1
  62. package/packages/typescript/src/features/advanced-capabilities/clipboard/services/clipboardService.js +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"HeartbeatForm.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/HeartbeatForm.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,IAAI,EAAE,gBAAgB,CAAC;IACvB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wDAAwD;IACxD,aAAa,EAAE,OAAO,CAAC;IACvB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qDAAqD;IACrD,cAAc,EAAE,OAAO,CAAC;IACxB,mCAAmC;IACnC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxE,4BAA4B;IAC5B,CAAC,EAAE,WAAW,CAAC;IACf,qCAAqC;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qCAAqC;IACrC,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACzC,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KACvB,IAAI,CAAC;IACV,qCAAqC;IACrC,OAAO,EAAE,CACP,IAAI,EAAE,gBAAgB,GAAG,CAAC,CAAC,IAAI,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,KACpE,IAAI,CAAC;IACV,8BAA8B;IAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,8BAA8B;IAC9B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,iCAAiC;IACjC,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,wCAAwC;IACxC,sBAAsB,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,OAAO,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,sCAAsC;IACtC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,aAAa,EACb,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,QAAQ,EACR,eAAe,EACf,CAAC,EACD,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,EAAE,kBAAkB,2CA0SpB"}
1
+ {"version":3,"file":"HeartbeatForm.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/HeartbeatForm.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAQL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAEtB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,IAAI,EAAE,gBAAgB,CAAC;IACvB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wDAAwD;IACxD,aAAa,EAAE,OAAO,CAAC;IACvB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qDAAqD;IACrD,cAAc,EAAE,OAAO,CAAC;IACxB,mCAAmC;IACnC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxE,4BAA4B;IAC5B,CAAC,EAAE,WAAW,CAAC;IACf,qCAAqC;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qCAAqC;IACrC,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,gBAAgB,EACzC,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KACvB,IAAI,CAAC;IACV,qCAAqC;IACrC,OAAO,EAAE,CACP,IAAI,EAAE,gBAAgB,GAAG,CAAC,CAAC,IAAI,EAAE,gBAAgB,KAAK,gBAAgB,CAAC,KACpE,IAAI,CAAC;IACV,8BAA8B;IAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,8BAA8B;IAC9B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,iCAAiC;IACjC,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,wCAAwC;IACxC,sBAAsB,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,OAAO,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,sCAAsC;IACtC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,aAAa,EACb,UAAU,EACV,SAAS,EACT,cAAc,EACd,cAAc,EACd,QAAQ,EACR,eAAe,EACf,CAAC,EACD,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,eAAe,GAChB,EAAE,kBAAkB,2CA6SpB"}
@@ -11,13 +11,11 @@ export function HeartbeatForm({ form, editingId, editorEnabled, modalTitle, form
11
11
  ? (kickerLabelEdit ?? t("heartbeatsview.editHeartbeat"))
12
12
  : (kickerLabelCreate ?? t("heartbeatsview.createHeartbeat")) }), _jsx("h2", { className: "text-2xl font-semibold text-txt", children: modalTitle })] }), _jsx("div", { className: "flex flex-wrap items-center gap-2 lg:justify-end", children: editingId && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "outline", size: "sm", className: "h-9 px-3 text-xs", disabled: triggersSaving, onClick: () => void onRunSelectedTrigger(editingId), children: t("triggersview.RunNow") }), _jsx(Button, { variant: "outline", size: "sm", className: "h-9 px-3 text-xs", onClick: () => void onToggleTriggerEnabled(editingId, editorEnabled), children: editorEnabled
13
13
  ? t("heartbeatsview.disable")
14
- : t("heartbeatsview.enable") }), _jsx("div", { className: "w-px h-6 bg-border/50 mx-1 hidden sm:block" }), _jsx(Button, { variant: "outline", size: "sm", className: "h-9 px-3 text-xs text-danger hover:border-danger hover:bg-danger/10 hover:text-danger", onClick: () => void onDelete(), children: t("triggersview.Delete") })] })) })] }), _jsxs("div", { className: "space-y-6", children: [formError && (_jsx(PagePanel.Notice, { tone: "danger", className: "text-sm", children: formError })), _jsxs(PagePanel, { variant: "padded", className: "grid gap-5", "data-testid": "heartbeats-editor-panel", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("wallet.name") }), _jsx(Input, { variant: "form", value: form.displayName, onChange: (event) => setField("displayName", event.target.value), placeholder: t("triggersview.eGDailyDigestH") })] }), _jsx(TriggerKindSection, { form: form, setField: setField, t: t, onGoToWorkflows: () => {
15
- // Switch the Automations view to the Workflows filter tab.
16
- // AutomationsLayout listens for this event via a useEffect to call setFilter("workflows").
17
- window.dispatchEvent(new CustomEvent("milady:automations:setFilter", {
18
- detail: { filter: "workflows" },
19
- }));
20
- } }), _jsxs("div", { className: "grid grid-cols-1 gap-5 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.ScheduleType") }), _jsxs(FormSelect, { value: form.triggerType, onValueChange: (value) => setField("triggerType", value), placeholder: t("triggersview.RepeatingInterval"), children: [_jsx(FormSelectItem, { value: "interval", children: t("triggersview.RepeatingInterval") }), _jsx(FormSelectItem, { value: "once", children: t("triggersview.OneTime") }), _jsx(FormSelectItem, { value: "cron", children: t("triggersview.CronSchedule") })] })] }), _jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.WakeMode") }), _jsxs(FormSelect, { value: form.wakeMode, onValueChange: (value) => setField("wakeMode", value), placeholder: t("triggersview.InjectAmpWakeIm"), children: [_jsx(FormSelectItem, { value: "inject_now", children: t("triggersview.InjectAmpWakeIm") }), _jsx(FormSelectItem, { value: "next_autonomy_cycle", children: t("triggersview.QueueForNextCycle") })] })] })] }), form.triggerType === "interval" && (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("heartbeatsview.interval") }), _jsxs("div", { className: "grid grid-cols-[140px_minmax(0,1fr)] gap-3", children: [_jsx(Input, { type: "number", min: "1", variant: "form", value: form.durationValue, onChange: (event) => setField("durationValue", event.target.value), placeholder: "1" }), _jsx(FormSelect, { value: form.durationUnit, onValueChange: (value) => setField("durationUnit", value), placeholder: durationUnitLabel(form.durationUnit, t), children: DURATION_UNITS.map((unit) => (_jsx(FormSelectItem, { value: unit.unit, children: durationUnitLabel(unit.unit, t) }, unit.unit))) })] })] })), form.triggerType === "once" && (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.ScheduledTimeISO") }), _jsx(Input, { type: "datetime-local", variant: "form", value: form.scheduledAtIso, onChange: (event) => setField("scheduledAtIso", event.target.value) })] })), form.triggerType === "cron" && (_jsx(CronInputSection, { form: form, setField: setField, t: t })), _jsx(SchedulePreview, { form: form, t: t }), _jsxs("div", { className: "grid grid-cols-1 gap-5 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.MaxRunsOptional") }), _jsx(Input, { variant: "form", value: form.maxRuns, onChange: (event) => setField("maxRuns", event.target.value), placeholder: "\\u221E" })] }), _jsx("div", { className: "flex items-end", children: _jsx(FieldSwitch, { checked: form.enabled, "aria-label": t("triggersview.StartEnabled"), className: "flex-1", label: t("triggersview.StartEnabled"), onCheckedChange: (checked) => setField("enabled", checked) }) })] })] }), _jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [form.displayName.trim() && (_jsx("button", { type: "button", className: "text-xs font-medium text-muted transition-colors hover:text-accent underline-offset-2 hover:underline", onClick: saveFormAsTemplate, children: t("heartbeatsview.SaveAsTemplate", {
14
+ : t("heartbeatsview.enable") }), _jsx("div", { className: "w-px h-6 bg-border/50 mx-1 hidden sm:block" }), _jsx(Button, { variant: "outline", size: "sm", className: "h-9 px-3 text-xs text-danger hover:border-danger hover:bg-danger/10 hover:text-danger", onClick: () => void onDelete(), children: t("triggersview.Delete") })] })) })] }), _jsxs("div", { className: "space-y-6", children: [formError && (_jsx(PagePanel.Notice, { tone: "danger", className: "text-sm", children: formError })), _jsxs(PagePanel, { variant: "padded", className: "grid gap-5", "data-testid": "heartbeats-editor-panel", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: form.kind === "workflow" ? "Schedule name" : "Task name" }), _jsx(Input, { variant: "form", value: form.displayName, onChange: (event) => setField("displayName", event.target.value), placeholder: t("triggersview.eGDailyDigestH") })] }), _jsxs("div", { className: "grid gap-4 rounded-xl border border-border/30 bg-bg/20 p-4", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted", children: "What it does" }), _jsx(TriggerKindSection, { form: form, setField: setField, t: t, onGoToWorkflows: () => {
15
+ window.dispatchEvent(new CustomEvent("milady:automations:setFilter", {
16
+ detail: { filter: "workflows" },
17
+ }));
18
+ } })] }), _jsxs("div", { className: "grid gap-4 rounded-xl border border-border/30 bg-bg/20 p-4", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted", children: "When it starts" }), _jsxs("div", { className: "grid grid-cols-1 gap-5 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "Trigger type" }), _jsxs(FormSelect, { value: form.triggerType, onValueChange: (value) => setField("triggerType", value), placeholder: "Repeating interval", children: [_jsx(FormSelectItem, { value: "interval", children: "Repeating interval" }), _jsx(FormSelectItem, { value: "once", children: "One time" }), _jsx(FormSelectItem, { value: "cron", children: "Cron schedule" })] })] }), _jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "When it fires" }), _jsxs(FormSelect, { value: form.wakeMode, onValueChange: (value) => setField("wakeMode", value), placeholder: "Interrupt and run now", children: [_jsx(FormSelectItem, { value: "inject_now", children: "Interrupt and run now" }), _jsx(FormSelectItem, { value: "next_autonomy_cycle", children: "Queue for next cycle" })] })] })] }), form.triggerType === "interval" && (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "Repeat every" }), _jsxs("div", { className: "grid grid-cols-[140px_minmax(0,1fr)] gap-3", children: [_jsx(Input, { type: "number", min: "1", variant: "form", value: form.durationValue, onChange: (event) => setField("durationValue", event.target.value), placeholder: "1" }), _jsx(FormSelect, { value: form.durationUnit, onValueChange: (value) => setField("durationUnit", value), placeholder: durationUnitLabel(form.durationUnit, t), children: DURATION_UNITS.map((unit) => (_jsx(FormSelectItem, { value: unit.unit, children: durationUnitLabel(unit.unit, t) }, unit.unit))) })] })] })), form.triggerType === "once" && (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "Run at" }), _jsx(Input, { type: "datetime-local", variant: "form", value: form.scheduledAtIso, onChange: (event) => setField("scheduledAtIso", event.target.value) })] })), form.triggerType === "cron" && (_jsx(CronInputSection, { form: form, setField: setField, t: t })), _jsx(SchedulePreview, { form: form, t: t })] }), _jsxs("div", { className: "grid gap-4 rounded-xl border border-border/30 bg-bg/20 p-4", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted", children: "Run behavior" }), _jsxs("div", { className: "grid grid-cols-1 gap-5 lg:grid-cols-2", children: [_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "Stop after" }), _jsx(Input, { variant: "form", value: form.maxRuns, onChange: (event) => setField("maxRuns", event.target.value), placeholder: "Unlimited" })] }), _jsx("div", { className: "flex items-end", children: _jsx(FieldSwitch, { checked: form.enabled, "aria-label": "Enabled", className: "flex-1", label: "Enabled", onCheckedChange: (checked) => setField("enabled", checked) }) })] })] })] }), _jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [form.displayName.trim() && (_jsx("button", { type: "button", className: "text-xs font-medium text-muted transition-colors hover:text-accent underline-offset-2 hover:underline", onClick: saveFormAsTemplate, children: t("heartbeatsview.SaveAsTemplate", {
21
19
  defaultValue: "Save as template",
22
20
  }) })), _jsxs("div", { className: "flex flex-wrap items-center gap-2.5", children: [_jsx(Button, { variant: "default", size: "sm", className: "h-10 px-6 text-sm text-white shadow-sm hover:text-white dark:text-white dark:hover:text-white", disabled: triggersSaving ||
23
21
  (form.kind === "workflow" && !form.workflowId) ||
@@ -71,12 +69,12 @@ function TriggerKindSection({ form, setField, t, onGoToWorkflows, }) {
71
69
  };
72
70
  }, [form.kind]);
73
71
  const toggleLabelId = "trigger-kind-toggle-label";
74
- return (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", id: toggleLabelId, children: t("triggers.whatToRun") }), _jsxs("div", { className: "mt-1.5 flex gap-2", children: [_jsx("button", { type: "button", "aria-pressed": form.kind === "text", onClick: () => setField("kind", "text"), className: `rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors ${form.kind === "text"
72
+ return (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", id: toggleLabelId, children: "Runs" }), _jsxs("div", { className: "mt-1.5 flex gap-2", children: [_jsx("button", { type: "button", "aria-pressed": form.kind === "text", onClick: () => setField("kind", "text"), className: `rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors ${form.kind === "text"
75
73
  ? "border-accent bg-accent/10 text-accent"
76
- : "border-border/40 text-muted hover:border-border hover:text-txt"}`, children: t("triggers.kindText") }), _jsx("button", { type: "button", "aria-pressed": form.kind === "workflow", onClick: () => setField("kind", "workflow"), className: `rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors ${form.kind === "workflow"
74
+ : "border-border/40 text-muted hover:border-border hover:text-txt"}`, children: "Prompt" }), _jsx("button", { type: "button", "aria-pressed": form.kind === "workflow", onClick: () => setField("kind", "workflow"), className: `rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors ${form.kind === "workflow"
77
75
  ? "border-accent bg-accent/10 text-accent"
78
- : "border-border/40 text-muted hover:border-border hover:text-txt"}`, children: t("triggers.kindWorkflow") })] }), form.kind === "text" && (_jsxs("div", { className: "mt-4", children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.Instructions") }), _jsx(Textarea, { variant: "form", value: form.instructions, onChange: (event) => setField("instructions", event.target.value), placeholder: t("triggersview.WhatShouldTheAgen") })] })), form.kind === "workflow" && (_jsx("div", { className: "mt-4", children: workflowsError === "unavailable" ||
79
- (!workflowsLoading && workflows.length === 0) ? (_jsxs("div", { role: "status", className: "rounded-lg border border-border/30 bg-bg/30 px-4 py-3 text-sm text-muted", children: [_jsx("p", { children: t("triggers.workflowUnavailable") }), _jsx("button", { type: "button", className: "mt-2 text-xs font-medium text-accent underline-offset-2 hover:underline", onClick: onGoToWorkflows, children: t("triggers.goToWorkflows") })] })) : (_jsxs(_Fragment, { children: [_jsx(FieldLabel, { variant: "form", htmlFor: "trigger-workflow-select", children: t("triggers.workflowLabel") }), _jsx(FormSelect, { value: form.workflowId, onValueChange: (value) => {
76
+ : "border-border/40 text-muted hover:border-border hover:text-txt"}`, children: "Workflow" })] }), form.kind === "text" && (_jsxs("div", { className: "mt-4", children: [_jsx(FieldLabel, { variant: "form", children: "Prompt" }), _jsx(Textarea, { variant: "form", value: form.instructions, onChange: (event) => setField("instructions", event.target.value), placeholder: t("triggersview.WhatShouldTheAgen") })] })), form.kind === "workflow" && (_jsx("div", { className: "mt-4", children: workflowsError === "unavailable" ||
77
+ (!workflowsLoading && workflows.length === 0) ? (_jsxs("div", { role: "status", className: "rounded-lg border border-border/30 bg-bg/30 px-4 py-3 text-sm text-muted", children: [_jsx("p", { children: t("triggers.workflowUnavailable") }), _jsx("button", { type: "button", className: "mt-2 text-xs font-medium text-accent underline-offset-2 hover:underline", onClick: onGoToWorkflows, children: t("triggers.goToWorkflows") })] })) : (_jsxs(_Fragment, { children: [_jsx(FieldLabel, { variant: "form", htmlFor: "trigger-workflow-select", children: "Workflow" }), _jsx(FormSelect, { value: form.workflowId, onValueChange: (value) => {
80
78
  const wf = workflows.find((w) => w.id === value);
81
79
  setField("workflowId", value);
82
80
  setField("workflowName", wf?.name ?? "");
@@ -94,7 +92,7 @@ function CronInputSection({ form, setField, t, }) {
94
92
  const cronErrorId = "cron-expression-error";
95
93
  const validationResult = validateCronExpression(form.cronExpression);
96
94
  const isInvalid = !validationResult.ok;
97
- return (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: t("triggersview.CronExpression5F") }), _jsx(Input, { variant: "form", className: "font-mono", value: form.cronExpression, onChange: (event) => setField("cronExpression", event.target.value), placeholder: "*/15 * * * *", "aria-invalid": isInvalid, "aria-describedby": isInvalid ? cronErrorId : undefined }), isInvalid ? (_jsxs("p", { id: cronErrorId, className: "mt-1.5 text-xs font-medium text-danger", role: "alert", children: [t("triggers.cronError"), " ", validationResult.message] })) : (_jsx("div", { className: "mt-2 text-xs-tight text-muted", children: t("triggersview.minuteHourDayMont") })), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "text-xs text-muted", children: t("triggers.cronExampleHint") }), CRON_EXAMPLES.map(({ expr, labelKey }) => (_jsx(Button, { variant: "outline", size: "sm", className: "h-6 px-2 py-0 text-xs font-mono", onClick: () => setField("cronExpression", expr), children: t(labelKey) }, expr)))] })] }));
95
+ return (_jsxs("div", { children: [_jsx(FieldLabel, { variant: "form", children: "Cron schedule" }), _jsx(Input, { variant: "form", className: "font-mono", value: form.cronExpression, onChange: (event) => setField("cronExpression", event.target.value), placeholder: "*/15 * * * *", "aria-invalid": isInvalid, "aria-describedby": isInvalid ? cronErrorId : undefined }), isInvalid ? (_jsxs("p", { id: cronErrorId, className: "mt-1.5 text-xs font-medium text-danger", role: "alert", children: [t("triggers.cronError"), " ", validationResult.message] })) : (_jsx("div", { className: "mt-2 text-xs-tight text-muted", children: "minute hour day month weekday" })), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("span", { className: "text-xs text-muted", children: t("triggers.cronExampleHint") }), CRON_EXAMPLES.map(({ expr, labelKey }) => (_jsx(Button, { variant: "outline", size: "sm", className: "h-6 px-2 py-0 text-xs font-mono", onClick: () => setField("cronExpression", expr), children: t(labelKey) }, expr)))] })] }));
98
96
  }
99
97
  // ── Schedule preview ("Next runs: …") ────────────────────────────
100
98
  function SchedulePreview({ form, t, }) {
@@ -142,7 +140,7 @@ function SchedulePreview({ form, t, }) {
142
140
  return null;
143
141
  return (_jsx("div", { role: "status", "aria-live": "polite", className: "rounded-lg border border-border/30 bg-bg/30 px-4 py-3 text-sm", children: preview.kind === "error" ? (_jsx("p", { className: "text-xs font-medium text-danger", children: preview.message })) : preview.kind === "once" ? (_jsxs("div", { children: [preview.isPast && (_jsx("p", { className: "mb-1 text-xs font-medium text-warning", children: t("triggers.scheduleOnceInPast") })), _jsx("p", { className: "text-xs text-muted", children: t("triggers.scheduleOnceLabel", {
144
142
  time: formatDateTime(preview.date),
145
- }) })] })) : (_jsxs("div", { children: [_jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted", children: t("triggers.schedulePreviewTitle") }), _jsx("ul", { className: "space-y-0.5", children: preview.dates.map((date) => (_jsx("li", { className: "text-xs text-txt/80 before:mr-1.5 before:content-['\u2022']", children: formatDateTime(date) }, date.getTime()))) })] })) }));
143
+ }) })] })) : (_jsxs("div", { children: [_jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted", children: "Next runs" }), _jsx("ul", { className: "space-y-0.5", children: preview.dates.map((date) => (_jsx("li", { className: "text-xs text-txt/80 before:mr-1.5 before:content-['\u2022']", children: formatDateTime(date) }, date.getTime()))) })] })) }));
146
144
  }
147
145
  // ── Run history sub-section (shown when editing) ───────────────────
148
146
  function HeartbeatRunHistory({ editingId, triggers, triggerRunsById, loadTriggerRuns, t, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"KnowledgeView.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/KnowledgeView.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,6BAA6B,CAAC;AA0BrC,OAAO,EACL,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAgH5B,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,OAAO,EACP,QAAgB,EAChB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,GACjB,GAAE;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAC7D,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,2CAwzBL"}
1
+ {"version":3,"file":"KnowledgeView.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/KnowledgeView.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,6BAA6B,CAAC;AA8BrC,OAAO,EACL,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAkI5B,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,OAAO,EACP,QAAgB,EAChB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,GACjB,GAAE;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAC7D,0BAA0B,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,2CAo1BL"}
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Button, PagePanel } from "@elizaos/ui";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
4
4
  import { client } from "../../api/client";
@@ -7,7 +7,7 @@ import { confirmDesktopAction } from "../../utils/desktop-dialogs";
7
7
  import { formatByteSize } from "../../utils/format";
8
8
  import { isKnowledgeImageFile, MAX_KNOWLEDGE_IMAGE_PROCESSING_BYTES, maybeCompressKnowledgeUploadImage, } from "../../utils/knowledge-upload-image";
9
9
  import { ConfirmDeleteControl } from "../shared/confirm-delete-control";
10
- import { DocumentViewer } from "./knowledge-detail";
10
+ import { DocumentViewer, getKnowledgeDocumentSummary, getKnowledgeTypeLabel, } from "./knowledge-detail";
11
11
  import { BULK_UPLOAD_TARGET_BYTES, getKnowledgeUploadFilename, isSupportedKnowledgeFile, KNOWLEDGE_UPLOAD_ACCEPT, LARGE_FILE_WARNING_BYTES, MAX_BULK_REQUEST_DOCUMENTS, MAX_UPLOAD_REQUEST_BYTES, shouldReadKnowledgeFileAsText, UploadZone, } from "./knowledge-upload";
12
12
  // Re-export public API used by tests and other modules
13
13
  export { getKnowledgeUploadFilename, shouldReadKnowledgeFileAsText, } from "./knowledge-upload";
@@ -27,7 +27,7 @@ function DocumentListItem({ doc, active, onSelect, onDelete, deleting, }) {
27
27
  return (_jsxs("div", { className: `group relative flex w-full transition-colors ${active ? "bg-transparent" : "bg-transparent hover:bg-white/[0.03]"}`, children: [_jsxs("button", { type: "button", onClick: () => onSelect(doc.id), "aria-label": t("knowledgeview.OpenDocument", {
28
28
  defaultValue: "Open {{filename}}",
29
29
  filename: doc.filename,
30
- }), "aria-current": active ? "page" : undefined, title: doc.filename, className: "flex min-w-0 flex-1 items-center gap-3 px-3.5 py-3 text-left", children: [_jsx("span", { className: `h-2.5 w-2.5 shrink-0 rounded-full ${active ? "bg-accent" : "bg-border"}` }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold leading-snug text-txt", children: doc.filename }), _jsxs("div", { className: "mt-1 truncate text-xs text-muted", children: [doc.provenance.label, doc.canEditText ? " editable" : ""] })] })] }), _jsx("span", { className: "absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100", children: _jsx(ConfirmDeleteControl, { triggerClassName: "h-7 rounded-lg border border-transparent px-2 text-2xs font-bold !bg-transparent text-danger/70 transition-all hover:!bg-danger/12 hover:border-danger/25 hover:text-danger", confirmClassName: "h-7 rounded-lg border border-danger/25 bg-danger/14 px-2 text-2xs font-bold text-danger transition-all hover:bg-danger/20", cancelClassName: "h-7 rounded-lg border border-border/35 px-2 text-2xs font-bold text-muted-strong transition-all hover:border-border-strong hover:text-txt", disabled: deleting || !doc.canDelete, busyLabel: "...", onConfirm: () => onDelete(doc.id) }) })] }));
30
+ }), "aria-current": active ? "page" : undefined, title: doc.filename, className: "flex min-w-0 flex-1 items-center gap-3 px-3.5 py-3 text-left", children: [_jsx("span", { className: `h-2.5 w-2.5 shrink-0 rounded-full ${active ? "bg-accent" : "bg-border"}` }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "truncate text-sm font-semibold leading-snug text-txt", children: doc.filename }), _jsx("div", { className: "mt-1 truncate text-xs text-muted", children: getKnowledgeDocumentSummary(doc, t) }), _jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5 text-2xs text-muted/70", children: [_jsx("span", { children: getKnowledgeTypeLabel(doc.contentType) }), doc.canEditText ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u2022" }), _jsx("span", { children: t("knowledgeview.Editable", { defaultValue: "editable" }) })] })) : null, !doc.canDelete ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u2022" }), _jsx("span", { children: t("knowledgeview.Locked", { defaultValue: "locked" }) })] })) : null] })] })] }), _jsx("span", { className: "absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100", children: _jsx(ConfirmDeleteControl, { triggerClassName: "h-7 rounded-lg border border-transparent px-2 text-2xs font-bold !bg-transparent text-danger/70 transition-all hover:!bg-danger/12 hover:border-danger/25 hover:text-danger", confirmClassName: "h-7 rounded-lg border border-danger/25 bg-danger/14 px-2 text-2xs font-bold text-danger transition-all hover:bg-danger/20", cancelClassName: "h-7 rounded-lg border border-border/35 px-2 text-2xs font-bold text-muted-strong transition-all hover:border-border-strong hover:text-txt", disabled: deleting || !doc.canDelete, busyLabel: "...", onConfirm: () => onDelete(doc.id) }) })] }));
31
31
  }
32
32
  /* ── Main KnowledgeView Component ───────────────────────────────────── */
33
33
  export function KnowledgeView({ fileInputId, inModal, embedded = false, onDocumentsChange, onSelectedDocumentIdChange, selectedDocumentId, showSelectorRail, } = {}) {
@@ -54,7 +54,8 @@ export function KnowledgeView({ fileInputId, inModal, embedded = false, onDocume
54
54
  }
55
55
  onSelectedDocumentIdChange?.(documentId);
56
56
  }, [onSelectedDocumentIdChange, selectedDocumentId]);
57
- const shouldShowSelectorRail = showSelectorRail ?? !embedded;
57
+ const shouldRenderSelectorRail = showSelectorRail !== false || embedded;
58
+ const useCompactSelectorRail = embedded;
58
59
  const loadData = useCallback(async () => {
59
60
  setLoading(true);
60
61
  setLoadError(null);
@@ -506,7 +507,20 @@ export function KnowledgeView({ fileInputId, inModal, embedded = false, onDocume
506
507
  const documentContent = (_jsx("div", { className: "order-2 flex min-w-0 flex-1 lg:order-1", children: _jsx(DocumentViewer, { documentId: selectedDocId, onUpdated: () => {
507
508
  void loadData();
508
509
  } }) }));
509
- const selectorRail = (_jsxs("div", { className: "order-1 flex w-full shrink-0 flex-col gap-3 lg:order-2 lg:w-[22rem] xl:w-[24rem]", children: [_jsx(PagePanel, { variant: "inset", className: "p-3 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: _jsx(UploadZone, { fileInputId: fileInputId, onFilesUpload: handleFilesUpload, onUrlUpload: handleUrlUpload, uploading: uploading, uploadStatus: uploadStatus }) }), _jsxs(PagePanel, { variant: "inset", className: "flex min-h-[18rem] flex-1 flex-col overflow-hidden p-2.5 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [searchInput, _jsxs("div", { className: "custom-scrollbar mt-2 flex min-h-0 flex-1 flex-col gap-1.5 overflow-y-auto px-0.5 py-0.5", children: [loading && !isShowingSearchResults && documents.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "px-0 py-10 text-center text-sm font-medium !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", title: t("knowledgeview.LoadingDocuments"), children: t("knowledgeview.LoadingDocuments") })), !loading && !isShowingSearchResults && documents.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "min-h-[12rem] px-0 py-8 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", description: t("knowledgeview.UploadFilesOrImpo"), title: t("knowledgeview.NoDocumentsYet") })), !loading &&
510
+ const selectorRail = (_jsxs("div", { className: `order-1 flex w-full shrink-0 flex-col gap-3 lg:order-2 ${useCompactSelectorRail
511
+ ? "lg:w-[18.5rem] xl:w-[20rem]"
512
+ : "lg:w-[22rem] xl:w-[24rem]"}`, children: [_jsx(PagePanel, { variant: "inset", className: `${useCompactSelectorRail ? "p-2" : "p-3"} !rounded-none !border-0 !bg-transparent !shadow-none !ring-0`, children: _jsx(UploadZone, { fileInputId: fileInputId, onFilesUpload: handleFilesUpload, onUrlUpload: handleUrlUpload, uploading: uploading, uploadStatus: uploadStatus }) }), _jsxs(PagePanel, { variant: "inset", className: `flex flex-1 flex-col overflow-hidden p-2.5 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0 ${useCompactSelectorRail ? "min-h-[14rem]" : "min-h-[18rem]"}`, children: [_jsxs("div", { className: "mb-2 flex items-center justify-between gap-3 px-1", children: [_jsx("div", { className: "min-w-0 text-xs font-semibold uppercase tracking-[0.12em] text-muted/70", children: isShowingSearchResults
513
+ ? t("knowledgeview.SearchResults", {
514
+ defaultValue: "Search results",
515
+ })
516
+ : t("knowledgeview.Documents", { defaultValue: "Documents" }) }), _jsx("div", { className: "shrink-0 text-2xs text-muted", children: documents.length === 1
517
+ ? t("knowledgeview.DocumentCountOne", {
518
+ defaultValue: "1 doc",
519
+ })
520
+ : t("knowledgeview.DocumentCountMany", {
521
+ defaultValue: "{{count}} docs",
522
+ count: documents.length,
523
+ }) })] }), searchInput, _jsxs("div", { className: "custom-scrollbar mt-2 flex min-h-0 flex-1 flex-col gap-1.5 overflow-y-auto px-0.5 py-0.5", children: [loading && !isShowingSearchResults && documents.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "px-0 py-10 text-center text-sm font-medium !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", title: t("knowledgeview.LoadingDocuments"), children: t("knowledgeview.LoadingDocuments") })), !loading && !isShowingSearchResults && documents.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "min-h-[12rem] px-0 py-8 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", description: t("knowledgeview.UploadFilesOrImpo"), title: t("knowledgeview.NoDocumentsYet") })), !loading &&
510
524
  !isShowingSearchResults &&
511
525
  documents.length > 0 &&
512
526
  filteredDocuments.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "min-h-[12rem] px-0 py-8 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", description: t("knowledgeview.SearchTips", {
@@ -518,5 +532,5 @@ export function KnowledgeView({ fileInputId, inModal, embedded = false, onDocume
518
532
  }), title: t("knowledgeview.NoResultsFound") })), isShowingSearchResults
519
533
  ? visibleSearchResults.map((result) => (_jsx(SearchResultListItem, { result: result, active: selectedDocId === (result.documentId || result.id), onSelect: setSelectedDocId }, result.id)))
520
534
  : filteredDocuments.map((doc) => (_jsx(DocumentListItem, { doc: doc, active: selectedDocId === doc.id, onSelect: setSelectedDocId, onDelete: handleDelete, deleting: deleting === doc.id }, doc.id)))] })] })] }));
521
- return (_jsxs("div", { className: `flex flex-1 min-h-0 flex-col gap-4 ${inModal ? "min-h-0" : ""}`, "data-testid": "knowledge-view", children: [!shouldShowSelectorRail && fileInputId ? (_jsx("input", { id: fileInputId, type: "file", className: "hidden", multiple: true, accept: KNOWLEDGE_UPLOAD_ACCEPT, onChange: handleExternalFileInputChange })) : null, isServiceLoading && (_jsxs(PagePanel, { variant: "inset", className: "flex items-center gap-2 px-0 py-3 text-sm text-muted-strong !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [_jsx("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-accent border-t-transparent" }), t("knowledgeview.KnowledgeServiceIs")] })), loadError && !isServiceLoading && (_jsx(PagePanel.Notice, { tone: "danger", actions: _jsx(Button, { variant: "outline", size: "sm", className: "border-danger/30 px-3 text-xs text-danger hover:bg-danger/16", onClick: () => loadData(), children: t("common.retry") }), children: loadError })), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-4 lg:flex-row", children: [documentContent, shouldShowSelectorRail ? selectorRail : null] })] }));
535
+ return (_jsxs("div", { className: `flex flex-1 min-h-0 flex-col gap-4 ${inModal ? "min-h-0" : ""}`, "data-testid": "knowledge-view", children: [!shouldRenderSelectorRail && fileInputId ? (_jsx("input", { id: fileInputId, type: "file", className: "hidden", multiple: true, accept: KNOWLEDGE_UPLOAD_ACCEPT, onChange: handleExternalFileInputChange })) : null, isServiceLoading && (_jsxs(PagePanel, { variant: "inset", className: "flex items-center gap-2 px-0 py-3 text-sm text-muted-strong !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [_jsx("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-accent border-t-transparent" }), t("knowledgeview.KnowledgeServiceIs")] })), loadError && !isServiceLoading && (_jsx(PagePanel.Notice, { tone: "danger", actions: _jsx(Button, { variant: "outline", size: "sm", className: "border-danger/30 px-3 text-xs text-danger hover:bg-danger/16", onClick: () => loadData(), children: t("common.retry") }), children: loadError })), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-4 lg:flex-row", children: [documentContent, shouldRenderSelectorRail ? selectorRail : null] })] }));
522
536
  }
@@ -1,7 +1,8 @@
1
1
  import type { RelationshipsGraphSnapshot } from "../../api/client-types-relationships";
2
- export declare function RelationshipsGraphPanel({ snapshot, selectedGroupId, onSelectGroupId, }: {
2
+ export declare function RelationshipsGraphPanel({ snapshot, selectedGroupId, compact, onSelectGroupId, }: {
3
3
  snapshot: RelationshipsGraphSnapshot | null;
4
4
  selectedGroupId: string | null;
5
+ compact?: boolean;
5
6
  onSelectGroupId: (groupId: string) => void;
6
7
  }): import("react/jsx-runtime").JSX.Element;
7
8
  //# sourceMappingURL=RelationshipsGraphPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipsGraphPanel.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/RelationshipsGraphPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,0BAA0B,EAE3B,MAAM,sCAAsC,CAAC;AAsgB9C,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,eAAe,EACf,eAAe,GAChB,EAAE;IACD,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC5C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C,2CAuQA"}
1
+ {"version":3,"file":"RelationshipsGraphPanel.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/RelationshipsGraphPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,0BAA0B,EAE3B,MAAM,sCAAsC,CAAC;AAsgB9C,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,eAAe,EACf,OAAe,EACf,eAAe,GAChB,EAAE;IACD,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC5C,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C,2CAyQA"}
@@ -319,7 +319,7 @@ function GraphTooltip({ state }) {
319
319
  const { edge } = state;
320
320
  return (_jsxs("div", { style: style, className: "rounded-xl border border-border/40 bg-card/95 px-3 py-2.5 shadow-lg backdrop-blur-md", children: [_jsxs("div", { className: "text-sm font-semibold text-txt", children: [edge.sourcePersonName, " \u2194 ", edge.targetPersonName] }), _jsxs("div", { className: "mt-1 space-y-0.5 text-xs-tight text-muted", children: [_jsxs("div", { children: ["Strength ", edge.strength.toFixed(2), " \u00B7 ", edge.sentiment, " \u00B7", " ", edge.interactionCount, " interactions"] }), edge.relationshipTypes.length > 0 ? (_jsx("div", { children: edge.relationshipTypes.join(", ") })) : null] })] }));
321
321
  }
322
- export function RelationshipsGraphPanel({ snapshot, selectedGroupId, onSelectGroupId, }) {
322
+ export function RelationshipsGraphPanel({ snapshot, selectedGroupId, compact = false, onSelectGroupId, }) {
323
323
  const [tooltip, setTooltip] = useState(null);
324
324
  const visibleGraph = useMemo(() => snapshot && snapshot.people.length > 0
325
325
  ? selectVisibleGraph(snapshot, selectedGroupId)
@@ -353,9 +353,9 @@ export function RelationshipsGraphPanel({ snapshot, selectedGroupId, onSelectGro
353
353
  });
354
354
  };
355
355
  const hideTooltip = () => setTooltip(null);
356
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-xs-tight font-semibold uppercase tracking-[0.16em] text-muted/70", children: "Identity Graph" }), _jsx("div", { className: "mt-2 text-xl font-semibold text-txt", children: "Canonical people and cross-person relationships" }), _jsxs("div", { className: "mt-2 text-xs text-muted", children: [visibleGraph.modeLabel, visibleGraph.truncated
356
+ return (_jsxs("div", { className: compact ? "space-y-3" : "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-xs-tight font-semibold uppercase tracking-[0.16em] text-muted/70", children: "Identity Graph" }), _jsx("div", { className: `${compact ? "mt-1 text-lg" : "mt-2 text-xl"} font-semibold text-txt`, children: "Canonical people and cross-person relationships" }), _jsxs("div", { className: "mt-2 text-xs text-muted", children: [visibleGraph.modeLabel, visibleGraph.truncated
357
357
  ? ` · showing ${visibleGraph.people.length} of ${snapshot.stats.totalPeople}`
358
- : null] })] }), _jsx(GraphLegend, {})] }), _jsxs("div", { className: "relative overflow-hidden rounded-3xl border border-border/26 bg-[radial-gradient(circle_at_top,rgba(240,185,11,0.12),transparent_42%),linear-gradient(180deg,color-mix(in_srgb,var(--card)_92%,transparent),color-mix(in_srgb,var(--bg)_97%,transparent))]", "data-graph-container": true, onMouseLeave: hideTooltip, children: [_jsx(GraphTooltip, { state: tooltip }), _jsxs("svg", { viewBox: `0 0 ${GRAPH_WIDTH} ${GRAPH_HEIGHT}`, className: "h-[24rem] w-full", role: "img", "aria-label": "Relationships graph", children: [_jsxs("defs", { children: [_jsxs("radialGradient", { id: "relationships-node-fill", cx: "50%", cy: "35%", r: "70%", children: [_jsx("stop", { offset: "0%", stopColor: "rgba(255,240,199,0.92)" }), _jsx("stop", { offset: "100%", stopColor: "rgba(240,185,11,0.86)" })] }), _jsxs("radialGradient", { id: "relationships-owner-fill", cx: "50%", cy: "35%", r: "70%", children: [_jsx("stop", { offset: "0%", stopColor: "rgba(199,210,255,0.94)" }), _jsx("stop", { offset: "100%", stopColor: "rgba(99,102,241,0.82)" })] })] }), visibleGraph.relationships.map((edge) => {
358
+ : null] })] }), _jsx(GraphLegend, {})] }), _jsxs("div", { className: "relative overflow-hidden rounded-3xl border border-border/26 bg-[radial-gradient(circle_at_top,rgba(240,185,11,0.12),transparent_42%),linear-gradient(180deg,color-mix(in_srgb,var(--card)_92%,transparent),color-mix(in_srgb,var(--bg)_97%,transparent))]", "data-graph-container": true, onMouseLeave: hideTooltip, children: [_jsx(GraphTooltip, { state: tooltip }), _jsxs("svg", { viewBox: `0 0 ${GRAPH_WIDTH} ${GRAPH_HEIGHT}`, className: `${compact ? "h-[20rem]" : "h-[30rem]"} w-full`, role: "img", "aria-label": "Relationships graph", children: [_jsxs("defs", { children: [_jsxs("radialGradient", { id: "relationships-node-fill", cx: "50%", cy: "35%", r: "70%", children: [_jsx("stop", { offset: "0%", stopColor: "rgba(255,240,199,0.92)" }), _jsx("stop", { offset: "100%", stopColor: "rgba(240,185,11,0.86)" })] }), _jsxs("radialGradient", { id: "relationships-owner-fill", cx: "50%", cy: "35%", r: "70%", children: [_jsx("stop", { offset: "0%", stopColor: "rgba(199,210,255,0.94)" }), _jsx("stop", { offset: "100%", stopColor: "rgba(99,102,241,0.82)" })] })] }), visibleGraph.relationships.map((edge) => {
359
359
  const source = positions.get(edge.sourcePersonId);
360
360
  const target = positions.get(edge.targetPersonId);
361
361
  if (!source || !target) {
@@ -1,12 +1,3 @@
1
- /**
2
- * WorkflowGraphViewer — React Flow graph for n8n workflow visualisation.
3
- *
4
- * Renders nodes and edges from an N8nWorkflow object. Supports a live
5
- * "generating" mode that pulses the border and shows a spinner overlay while
6
- * the agent is constructing the workflow via CREATE_N8N_WORKFLOW.
7
- *
8
- * Layer: feature (packages/app-core/src/components/pages/)
9
- */
10
1
  import type { N8nStatusResponse, N8nWorkflow } from "../../api/client-types-chat";
11
2
  interface WorkflowGraphViewerProps {
12
3
  workflow: N8nWorkflow | null;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowGraphViewer.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/WorkflowGraphViewer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkCH,OAAO,KAAK,EAEV,iBAAiB,EACjB,WAAW,EAEZ,MAAM,6BAA6B,CAAC;AAohBrC,UAAU,wBAAwB;IAChC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,OAAe,EACf,YAAoB,EACpB,qBAAgD,EAChD,kBAAoE,EACpE,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,wBAAwB,2CA+N1B"}
1
+ {"version":3,"file":"WorkflowGraphViewer.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/WorkflowGraphViewer.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAEV,iBAAiB,EACjB,WAAW,EAEZ,MAAM,6BAA6B,CAAC;AAghBrC,UAAU,wBAAwB;IAChC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,OAAe,EACf,YAAoB,EACpB,qBAAgD,EAChD,kBAAqE,EACrE,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,wBAAwB,2CAwQ1B"}
@@ -1,16 +1,7 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- /**
3
- * WorkflowGraphViewer — React Flow graph for n8n workflow visualisation.
4
- *
5
- * Renders nodes and edges from an N8nWorkflow object. Supports a live
6
- * "generating" mode that pulses the border and shows a spinner overlay while
7
- * the agent is constructing the workflow via CREATE_N8N_WORKFLOW.
8
- *
9
- * Layer: feature (packages/app-core/src/components/pages/)
10
- */
11
2
  import { Button, Dialog, DialogContent, DialogHeader, DialogTitle, Spinner, StatusBadge, } from "@elizaos/ui";
12
3
  import { Background, Controls, MiniMap, ReactFlow, } from "@xyflow/react";
13
- import { ChevronDown, ChevronUp, ExternalLink, Maximize2, X, } from "lucide-react";
4
+ import { ExternalLink, Maximize2, X } from "lucide-react";
14
5
  import { useCallback, useEffect, useId, useMemo, useRef, useState, } from "react";
15
6
  import { getBootConfig } from "../../config/boot-config";
16
7
  import { useApp } from "../../state";
@@ -151,6 +142,34 @@ function generatingEdges(edges) {
151
142
  },
152
143
  }));
153
144
  }
145
+ function graphChrome(uiTheme) {
146
+ if (uiTheme === "light") {
147
+ return {
148
+ canvasBg: "#f8fafc",
149
+ dots: "#cbd5e1",
150
+ minimapMask: "rgba(226, 232, 240, 0.72)",
151
+ minimapBg: "#ffffff",
152
+ minimapBorder: "#cbd5e1",
153
+ emptyTitleClass: "text-slate-700",
154
+ emptyHelpClass: "text-slate-500",
155
+ overlayBg: "rgba(248, 250, 252, 0.72)",
156
+ overlayChipBg: "rgba(255, 255, 255, 0.94)",
157
+ overlayChipText: "#1d4ed8",
158
+ };
159
+ }
160
+ return {
161
+ canvasBg: "#020817",
162
+ dots: "#334155",
163
+ minimapMask: "rgba(2, 8, 23, 0.7)",
164
+ minimapBg: "#0f172a",
165
+ minimapBorder: "#334155",
166
+ emptyTitleClass: "text-slate-300",
167
+ emptyHelpClass: "text-slate-500",
168
+ overlayBg: "rgba(2, 8, 23, 0.6)",
169
+ overlayChipBg: "rgba(2, 8, 23, 0.82)",
170
+ overlayChipText: "#60a5fa",
171
+ };
172
+ }
154
173
  // ── Node detail drawer ────────────────────────────────────────────────────────
155
174
  const PARAM_TRUNCATE_LENGTH = 200;
156
175
  function ParamValue({ value }) {
@@ -195,14 +214,8 @@ function buildEditorUrl(workflow, status, cloudAgentId, uiTheme) {
195
214
  }
196
215
  function NodeDetailDrawer({ node, workflow, status, onClose, labelId, }) {
197
216
  const { t, activeAgentProfile, uiTheme } = useApp();
198
- const [rawJsonOpen, setRawJsonOpen] = useState(false);
199
217
  const closeButtonRef = useRef(null);
200
218
  const isOpen = node !== null;
201
- // Reset raw JSON section when node changes
202
- // biome-ignore lint/correctness/useExhaustiveDependencies: reset on node identity change
203
- useEffect(() => {
204
- setRawJsonOpen(false);
205
- }, [node?.id, node?.name]);
206
219
  // Focus the close button when drawer opens
207
220
  useEffect(() => {
208
221
  if (isOpen) {
@@ -231,16 +244,21 @@ function NodeDetailDrawer({ node, workflow, status, onClose, labelId, }) {
231
244
  "border-l border-border/40 bg-bg shadow-xl backdrop-blur-[2px]",
232
245
  "transition-transform duration-200 ease-out",
233
246
  isOpen ? "translate-x-0" : "translate-x-full",
234
- ].join(" "), children: [_jsxs("div", { className: "flex shrink-0 items-start gap-2 border-b border-border/30 px-4 py-3", children: [_jsxs("div", { className: "flex-1 min-w-0 space-y-1", children: [_jsx("h2", { id: labelId, className: "text-sm font-semibold text-txt leading-tight truncate", children: node?.name ?? "" }), _jsx("div", { className: "flex items-center gap-1.5", children: _jsx(StatusBadge, { label: typeLabel, variant: badgeVariant }) })] }), _jsx("button", { ref: closeButtonRef, type: "button", "aria-label": t("workflowGraph.closeDrawer"), tabIndex: isOpen ? 0 : -1, className: "shrink-0 flex h-6 w-6 items-center justify-center rounded text-muted hover:text-txt transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: onClose, children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto space-y-4 px-4 py-3", children: node && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wider text-muted", children: "Name" }), _jsx("pre", { className: "font-mono text-xs text-txt/80 break-all whitespace-pre-wrap", children: node.name })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wider text-muted", children: t("workflowGraph.nodeDrawer.parametersLabel") }), hasParams ? (_jsx("div", { className: "space-y-2", children: Object.entries(node.parameters ?? {}).map(([key, val]) => (_jsxs("div", { className: "space-y-0.5", children: [_jsx("div", { className: "text-xs font-medium text-muted/80 font-mono", children: key }), _jsx("div", { className: "rounded bg-bg/40 border border-border/20 px-2 py-1", children: _jsx(ParamValue, { value: val }) })] }, key))) })) : (_jsx("p", { className: "text-xs text-muted/60 italic", children: t("workflowGraph.nodeDrawer.noParameters") }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("button", { type: "button", className: "flex w-full items-center justify-between text-xs font-semibold uppercase tracking-wider text-muted hover:text-txt transition-colors", onClick: () => setRawJsonOpen((v) => !v), "aria-expanded": rawJsonOpen, children: [_jsx("span", { children: t("workflowGraph.nodeDrawer.rawJsonLabel") }), rawJsonOpen ? (_jsx(ChevronUp, { className: "h-3.5 w-3.5" })) : (_jsx(ChevronDown, { className: "h-3.5 w-3.5" }))] }), rawJsonOpen && (_jsx("div", { className: "rounded border border-border/20 bg-bg/40 p-2 overflow-auto max-h-64", children: _jsx("pre", { className: "font-mono text-xs text-txt/70 whitespace-pre-wrap break-all", children: JSON.stringify(node, null, 2) }) }))] })] })) }), _jsx("div", { className: "shrink-0 border-t border-border/30 px-4 py-3", children: editorUrl ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "w-full h-8 text-xs gap-1.5", tabIndex: isOpen ? 0 : -1, onClick: () => window.open(editorUrl, "_blank", "noopener"), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), t("workflowGraph.nodeDrawer.openInEditor")] })) : (_jsx(Button, { type: "button", variant: "outline", size: "sm", className: "w-full h-8 text-xs", disabled: true, tabIndex: isOpen ? 0 : -1, title: t("workflowGraph.nodeDrawer.editorDisabled"), children: t("workflowGraph.nodeDrawer.openInEditor") })) })] }));
247
+ ].join(" "), children: [_jsxs("div", { className: "flex shrink-0 items-start gap-2 border-b border-border/30 px-4 py-3", children: [_jsxs("div", { className: "flex-1 min-w-0 space-y-1", children: [_jsx("h2", { id: labelId, className: "text-sm font-semibold text-txt leading-tight truncate", children: node?.name ?? "" }), _jsx("div", { className: "flex items-center gap-1.5", children: _jsx(StatusBadge, { label: typeLabel, variant: badgeVariant }) })] }), _jsx("button", { ref: closeButtonRef, type: "button", "aria-label": t("workflowGraph.closeDrawer"), tabIndex: isOpen ? 0 : -1, className: "shrink-0 flex h-6 w-6 items-center justify-center rounded text-muted hover:text-txt transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: onClose, children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto space-y-4 px-4 py-3", children: node && (_jsx(_Fragment, { children: _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs font-semibold uppercase tracking-wider text-muted", children: t("workflowGraph.nodeDrawer.parametersLabel") }), hasParams ? (_jsx("div", { className: "space-y-2", children: Object.entries(node.parameters ?? {}).map(([key, val]) => (_jsxs("div", { className: "space-y-0.5", children: [_jsx("div", { className: "text-xs font-medium text-muted/80 font-mono", children: key }), _jsx("div", { className: "rounded bg-bg/40 border border-border/20 px-2 py-1", children: _jsx(ParamValue, { value: val }) })] }, key))) })) : (_jsx("p", { className: "text-xs text-muted/60 italic", children: t("workflowGraph.nodeDrawer.noParameters") }))] }) })) }), _jsx("div", { className: "shrink-0 border-t border-border/30 px-4 py-3", children: editorUrl ? (_jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "w-full h-8 text-xs gap-1.5", tabIndex: isOpen ? 0 : -1, onClick: () => window.open(editorUrl, "_blank", "noopener"), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), t("workflowGraph.nodeDrawer.openInEditor")] })) : (_jsx(Button, { type: "button", variant: "outline", size: "sm", className: "w-full h-8 text-xs", disabled: true, tabIndex: isOpen ? 0 : -1, title: t("workflowGraph.nodeDrawer.editorDisabled"), children: t("workflowGraph.nodeDrawer.openInEditor") })) })] }));
235
248
  }
236
249
  // ── Graph panel (shared between inline and full-screen modal) ─────────────────
237
- function GraphPanel({ nodes, edges, isGenerating, ariaLabel, onNodeClick, }) {
238
- return (_jsxs(ReactFlow, { nodes: nodes, edges: isGenerating ? generatingEdges(edges) : edges, nodesDraggable: !isGenerating, nodesConnectable: false, edgesReconnectable: false, onNodeClick: onNodeClick, fitView: true, fitViewOptions: { padding: 0.2, maxZoom: 1.2 }, proOptions: { hideAttribution: true }, "aria-label": ariaLabel, children: [_jsx(Background, { color: "#334155", gap: 20, size: 1 }), _jsx(Controls, { showInteractive: false }), _jsx(MiniMap, { nodeColor: (n) => {
250
+ function GraphPanel({ nodes, edges, isGenerating, ariaLabel, onNodeClick, uiTheme, }) {
251
+ const chrome = graphChrome(uiTheme);
252
+ return (_jsxs(ReactFlow, { nodes: nodes, edges: isGenerating ? generatingEdges(edges) : edges, nodesDraggable: !isGenerating, nodesConnectable: false, edgesReconnectable: false, onNodeClick: onNodeClick, fitView: true, fitViewOptions: { padding: 0.2, maxZoom: 1.2 }, proOptions: { hideAttribution: true }, "aria-label": ariaLabel, children: [_jsx(Background, { color: chrome.dots, gap: 20, size: 1 }), _jsx(Controls, { showInteractive: false }), _jsx(MiniMap, { nodeColor: (n) => {
239
253
  const colors = n.data?.colors;
240
254
  return colors?.border ?? "#475569";
241
- }, maskColor: "rgba(2, 8, 23, 0.7)", style: { background: "#0f172a", border: "1px solid #334155" } })] }));
255
+ }, maskColor: chrome.minimapMask, style: {
256
+ background: chrome.minimapBg,
257
+ border: `1px solid ${chrome.minimapBorder}`,
258
+ } })] }));
242
259
  }
243
- export function WorkflowGraphViewer({ workflow, loading = false, isGenerating = false, emptyStateActionLabel = "Describe your workflow", emptyStateHelpText = "Use the sidebar agent to build this workflow.", onNodeClick, onEmptyStateAction, status, }) {
260
+ export function WorkflowGraphViewer({ workflow, loading = false, isGenerating = false, emptyStateActionLabel = "Describe your workflow", emptyStateHelpText = "Describe the trigger and steps in the sidebar.", onNodeClick, onEmptyStateAction, status, }) {
261
+ const { activeAgentProfile, uiTheme } = useApp();
244
262
  const [fullScreen, setFullScreen] = useState(false);
245
263
  const [selectedNode, setSelectedNode] = useState(null);
246
264
  const containerRef = useRef(null);
@@ -291,19 +309,27 @@ export function WorkflowGraphViewer({ workflow, loading = false, isGenerating =
291
309
  return () => window.removeEventListener("keydown", handler);
292
310
  }, [fullScreen, selectedNode]);
293
311
  const hasNodes = nodes.length > 0;
312
+ const editorDisabled = !status || status.mode === "disabled" || status.status === "error";
313
+ const editorUrl = !editorDisabled && workflow && status
314
+ ? buildEditorUrl(workflow, status, activeAgentProfile?.cloudAgentId, uiTheme)
315
+ : null;
294
316
  const borderClass = isGenerating
295
317
  ? "animate-pulse ring-2 ring-blue-500/50"
296
318
  : "ring-1 ring-border/30";
297
- return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: containerRef, role: "img", "aria-label": ariaLabel, className: `relative overflow-hidden rounded-lg bg-[#020817] ${borderClass}`, style: { height: 420 }, children: [loading && !hasNodes && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx(Spinner, { className: "h-6 w-6 text-muted" }) })), !loading && !hasNodes && !isGenerating && (_jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-3 px-6 text-center", children: [_jsx("p", { className: "text-sm font-medium text-muted", children: "No nodes yet" }), _jsx("p", { className: "text-xs text-muted/60", children: emptyStateHelpText }), onEmptyStateAction && (_jsx("button", { type: "button", className: "mt-1 rounded-md border border-border/40 bg-bg/40 px-3 py-1.5 text-xs text-txt hover:bg-bg/70 transition-colors", onClick: onEmptyStateAction, children: emptyStateActionLabel }))] })), isGenerating && (_jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center backdrop-blur-[1px]", children: _jsxs("div", { className: "flex items-center gap-2 rounded-full border border-blue-500/30 bg-[#020817]/80 px-4 py-2 text-sm text-blue-400", children: [_jsx(Spinner, { className: "h-4 w-4" }), "Building workflow..."] }) })), !loading && (_jsx("div", { role: "presentation", className: "h-full w-full", onClick: (e) => e.stopPropagation(), onKeyDown: (e) => e.stopPropagation(), children: _jsxs(ReactFlow, { nodes: nodes, edges: isGenerating ? generatingEdges(edges) : edges, nodesDraggable: !isGenerating, nodesConnectable: false, edgesReconnectable: false, onNodeClick: handleNodeClick, fitView: true, fitViewOptions: { padding: 0.2, maxZoom: 1.2 }, proOptions: { hideAttribution: true }, "aria-label": ariaLabel, children: [_jsx(Background, { color: "#334155", gap: 20, size: 1 }), _jsx(Controls, { showInteractive: false }), hasNodes && (_jsx(MiniMap, { nodeColor: (n) => {
319
+ const chrome = graphChrome(uiTheme);
320
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { ref: containerRef, role: "img", "aria-label": ariaLabel, className: `relative overflow-hidden rounded-lg ${borderClass}`, style: { height: 420, background: chrome.canvasBg }, children: [loading && !hasNodes && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx(Spinner, { className: "h-6 w-6 text-muted" }) })), !loading && !hasNodes && !isGenerating && (_jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center gap-3 px-6 text-center", children: [_jsx("p", { className: `text-sm font-medium ${chrome.emptyTitleClass}`, children: "Blank workflow" }), _jsx("p", { className: `max-w-sm text-xs ${chrome.emptyHelpClass}`, children: emptyStateHelpText }), onEmptyStateAction && (_jsx("button", { type: "button", className: "mt-1 rounded-md border border-border/40 bg-bg/40 px-3 py-1.5 text-xs text-txt hover:bg-bg/70 transition-colors", onClick: onEmptyStateAction, children: emptyStateActionLabel }))] })), isGenerating && (_jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center backdrop-blur-[1px]", style: { background: chrome.overlayBg }, children: _jsxs("div", { className: "flex items-center gap-2 rounded-full border border-blue-500/30 px-4 py-2 text-sm", style: {
321
+ background: chrome.overlayChipBg,
322
+ color: chrome.overlayChipText,
323
+ }, children: [_jsx(Spinner, { className: "h-4 w-4" }), "Building workflow..."] }) })), !loading && (_jsx("div", { role: "presentation", className: "h-full w-full", onClick: (e) => e.stopPropagation(), onKeyDown: (e) => e.stopPropagation(), children: _jsxs(ReactFlow, { nodes: nodes, edges: isGenerating ? generatingEdges(edges) : edges, nodesDraggable: !isGenerating, nodesConnectable: false, edgesReconnectable: false, onNodeClick: handleNodeClick, fitView: true, fitViewOptions: { padding: 0.2, maxZoom: 1.2 }, proOptions: { hideAttribution: true }, "aria-label": ariaLabel, children: [_jsx(Background, { color: chrome.dots, gap: 20, size: 1 }), _jsx(Controls, { showInteractive: false }), hasNodes && (_jsx(MiniMap, { nodeColor: (n) => {
298
324
  const colors = n.data
299
325
  ?.colors;
300
326
  return colors?.border ?? "#475569";
301
- }, maskColor: "rgba(2, 8, 23, 0.7)", style: {
302
- background: "#0f172a",
303
- border: "1px solid #334155",
327
+ }, maskColor: chrome.minimapMask, style: {
328
+ background: chrome.minimapBg,
329
+ border: `1px solid ${chrome.minimapBorder}`,
304
330
  } }))] }) })), hasNodes && !isGenerating && (_jsx("button", { type: "button", "aria-label": "Full screen", className: [
305
331
  "absolute top-3 z-20 flex h-7 w-7 items-center justify-center",
306
332
  "rounded border border-border/40 bg-bg/80 text-muted hover:text-txt transition-all duration-200",
307
333
  selectedNode ? "right-[calc(18rem+0.75rem)]" : "right-3",
308
- ].join(" "), onClick: () => setFullScreen(true), children: _jsx(Maximize2, { className: "h-3.5 w-3.5" }) })), !fullScreen && (_jsx(NodeDetailDrawer, { node: selectedNode, workflow: workflow, status: status, onClose: handleCloseDrawer, labelId: drawerLabelId }))] }), _jsx(Dialog, { open: fullScreen, onOpenChange: setFullScreen, children: _jsxs(DialogContent, { className: "h-[90dvh] w-[90vw] !max-w-none !max-h-none flex flex-col p-0 gap-0", showCloseButton: false, children: [_jsxs(DialogHeader, { className: "flex flex-row items-center justify-between border-b border-border/30 px-4 py-3 shrink-0", children: [_jsx(DialogTitle, { className: "text-sm font-medium", children: workflow?.name ?? "Workflow Graph" }), _jsx("button", { type: "button", "aria-label": "Close", className: "flex h-7 w-7 items-center justify-center rounded text-muted hover:text-txt transition-colors", onClick: () => setFullScreen(false), children: _jsx(X, { className: "h-4 w-4" }) })] }), _jsxs("div", { className: "relative flex-1 min-h-0 overflow-hidden bg-[#020817]", children: [_jsx(GraphPanel, { nodes: nodes, edges: edges, isGenerating: isGenerating, ariaLabel: ariaLabel, onNodeClick: handleNodeClick }), _jsx(NodeDetailDrawer, { node: selectedNode, workflow: workflow, status: status, onClose: handleCloseDrawer, labelId: drawerLabelId })] })] }) })] }));
334
+ ].join(" "), onClick: () => setFullScreen(true), children: _jsx(Maximize2, { className: "h-3.5 w-3.5" }) })), editorUrl && !isGenerating && (_jsx("button", { type: "button", "aria-label": "Open in n8n editor", className: "absolute right-12 top-3 z-20 rounded border border-border/40 bg-bg/80 px-2.5 py-1 text-xs text-muted transition-colors hover:text-txt", onClick: () => window.open(editorUrl, "_blank", "noopener"), children: "Open in n8n" })), !fullScreen && (_jsx(NodeDetailDrawer, { node: selectedNode, workflow: workflow, status: status, onClose: handleCloseDrawer, labelId: drawerLabelId }))] }), _jsx(Dialog, { open: fullScreen, onOpenChange: setFullScreen, children: _jsxs(DialogContent, { className: "h-[90dvh] w-[90vw] !max-w-none !max-h-none flex flex-col p-0 gap-0", showCloseButton: false, children: [_jsxs(DialogHeader, { className: "flex flex-row items-center justify-between border-b border-border/30 px-4 py-3 shrink-0", children: [_jsx(DialogTitle, { className: "text-sm font-medium", children: workflow?.name ?? "Workflow Graph" }), _jsx("button", { type: "button", "aria-label": "Close", className: "flex h-7 w-7 items-center justify-center rounded text-muted hover:text-txt transition-colors", onClick: () => setFullScreen(false), children: _jsx(X, { className: "h-4 w-4" }) })] }), _jsxs("div", { className: "relative flex-1 min-h-0 overflow-hidden", style: { background: chrome.canvasBg }, children: [_jsx(GraphPanel, { nodes: nodes, edges: edges, isGenerating: isGenerating, ariaLabel: ariaLabel, onNodeClick: handleNodeClick, uiTheme: uiTheme }), _jsx(NodeDetailDrawer, { node: selectedNode, workflow: workflow, status: status, onClose: handleCloseDrawer, labelId: drawerLabelId })] })] }) })] }));
309
335
  }
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-detail.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/knowledge-detail.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,6BAA6B,CAAC;AAIrC,wBAAgB,qBAAqB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAC5D,MAAM,CAQR;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,iBAAiB,EACtB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAC5D,MAAM,CAWR;AAID,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,SAAS,GACV,EAAE;IACD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,2CAkPA"}
1
+ {"version":3,"file":"knowledge-detail.d.ts","sourceRoot":"","sources":["../../../../../../src/components/pages/knowledge-detail.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,6BAA6B,CAAC;AAIrC,wBAAgB,qBAAqB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAC5D,MAAM,CAQR;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,iBAAiB,EACtB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAC5D,MAAM,CAWR;AAgBD,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,SAAS,GACV,EAAE;IACD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,2CA0SA"}
@@ -27,6 +27,19 @@ export function getKnowledgeDocumentSummary(doc, t) {
27
27
  });
28
28
  return `${getKnowledgeSourceLabel(doc.source, t)} • ${fragmentLabel} • ${formatByteSize(doc.fileSize)}`;
29
29
  }
30
+ function formatKnowledgeTimestamp(value) {
31
+ if (!value)
32
+ return null;
33
+ const timestamp = value < 1_000_000_000_000 ? value * 1000 : value;
34
+ const date = new Date(timestamp);
35
+ if (Number.isNaN(date.getTime()))
36
+ return null;
37
+ return date.toLocaleDateString(undefined, {
38
+ month: "short",
39
+ day: "numeric",
40
+ year: "numeric",
41
+ });
42
+ }
30
43
  /* ── Document Viewer ────────────────────────────────────────────────── */
31
44
  export function DocumentViewer({ documentId, onUpdated, }) {
32
45
  const { t, setActionNotice } = useApp();
@@ -82,6 +95,7 @@ export function DocumentViewer({ documentId, onUpdated, }) {
82
95
  };
83
96
  }, [documentId, reloadToken, t]);
84
97
  const previewText = doc?.content?.text?.trim();
98
+ const documentCreatedLabel = formatKnowledgeTimestamp(doc?.createdAt);
85
99
  const handleSave = async () => {
86
100
  if (!documentId || !doc)
87
101
  return;
@@ -115,9 +129,21 @@ export function DocumentViewer({ documentId, onUpdated, }) {
115
129
  defaultValue: "No document selected",
116
130
  }) })), !loading && !error && doc && (_jsxs("div", { className: "mx-auto flex w-full max-w-4xl flex-col gap-4", children: [_jsxs("div", { className: "px-1", children: [_jsx("h2", { className: "break-words text-lg font-semibold text-txt", children: doc.filename }), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-muted", children: [_jsx("span", { children: doc.provenance.label }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: formatByteSize(doc.fileSize) }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: doc.fragmentCount === 1
117
131
  ? "1 fragment"
118
- : `${doc.fragmentCount} fragments` }), doc.provenance.detail ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u2022" }), _jsx("span", { className: "truncate", children: doc.provenance.detail })] })) : null] }), _jsx("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: doc.canEditText ? (_jsxs(_Fragment, { children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", className: "rounded-lg", onClick: () => setEditing((current) => !current), disabled: saving, children: editing ? "Cancel" : "Edit text" }), editing ? (_jsx(Button, { type: "button", size: "sm", className: "rounded-lg", onClick: () => void handleSave(), disabled: saving || draftText.trim().length === 0, children: saving ? "Saving..." : "Save" })) : null] })) : doc.editabilityReason ? (_jsx("div", { className: "text-xs text-muted", children: doc.editabilityReason })) : null })] }), _jsxs(PagePanel, { variant: "inset", className: "p-4 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [_jsx("div", { className: "mb-3 text-xs font-semibold uppercase tracking-[0.12em] text-muted/70", children: t("knowledgeview.Preview", { defaultValue: "Preview" }) }), editing ? (_jsx(Textarea, { value: draftText, rows: 16, onChange: (event) => setDraftText(event.target.value), className: "min-h-[20rem] resize-y rounded-xl border-border/40 bg-bg-muted/15 font-mono text-sm leading-relaxed" })) : previewText ? (_jsx("pre", { className: "custom-scrollbar max-h-[16rem] overflow-auto whitespace-pre-wrap break-words text-sm leading-relaxed text-txt/88", children: previewText.slice(0, 2000) })) : (_jsx("div", { className: "py-6 text-center text-xs text-muted", children: t("knowledgeview.NoPreview", {
132
+ : `${doc.fragmentCount} fragments` }), doc.provenance.detail ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u2022" }), _jsx("span", { className: "truncate", children: doc.provenance.detail })] })) : null, _jsx("span", { children: "\u2022" }), _jsx("span", { children: getKnowledgeTypeLabel(doc.contentType) }), documentCreatedLabel ? (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u2022" }), _jsx("span", { children: documentCreatedLabel })] })) : null] }), _jsx("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: doc.canEditText ? (_jsxs(_Fragment, { children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", className: "rounded-lg", onClick: () => setEditing((current) => !current), disabled: saving, children: editing ? "Cancel" : "Edit text" }), editing ? (_jsx(Button, { type: "button", size: "sm", className: "rounded-lg", onClick: () => void handleSave(), disabled: saving || draftText.trim().length === 0, children: saving ? "Saving..." : "Save" })) : null] })) : doc.editabilityReason ? (_jsx("div", { className: "text-xs text-muted", children: doc.editabilityReason })) : null })] }), _jsxs(PagePanel, { variant: "inset", className: "p-4 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [_jsx("div", { className: "mb-3 text-xs font-semibold uppercase tracking-[0.12em] text-muted/70", children: t("knowledgeview.Preview", { defaultValue: "Preview" }) }), editing ? (_jsx(Textarea, { value: draftText, rows: 16, onChange: (event) => setDraftText(event.target.value), className: "min-h-[20rem] resize-y rounded-xl border-border/40 bg-bg-muted/15 font-mono text-sm leading-relaxed" })) : previewText ? (_jsx("pre", { className: "custom-scrollbar max-h-[16rem] overflow-auto whitespace-pre-wrap break-words text-sm leading-relaxed text-txt/88", children: previewText.slice(0, 2000) })) : (_jsx("div", { className: "py-6 text-center text-xs text-muted", children: t("knowledgeview.NoPreview", {
119
133
  defaultValue: "Full text preview is not available",
120
134
  }) }))] }), _jsxs(PagePanel, { variant: "inset", className: "p-4 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", children: [_jsx("div", { className: "mb-3 text-xs font-semibold uppercase tracking-[0.12em] text-muted/70", children: t("knowledgeview.FragmentsLabel", {
121
135
  defaultValue: "Fragments",
122
- }) }), _jsxs("div", { className: "space-y-3", children: [fragments.map((fragment) => (_jsx("div", { className: "py-3", children: _jsx("p", { className: "whitespace-pre-wrap text-sm leading-relaxed text-txt/90", children: fragment.text }) }, fragment.id))), fragments.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "min-h-[8rem] py-8 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", title: t("knowledgeview.NoFragmentsFound") }))] })] })] }))] }) }));
136
+ }) }), _jsxs("div", { className: "divide-y divide-border/20", children: [fragments.map((fragment, index) => {
137
+ const createdLabel = formatKnowledgeTimestamp(fragment.createdAt);
138
+ return (_jsxs("article", { className: "grid gap-3 py-4 sm:grid-cols-[4rem_minmax(0,1fr)]", children: [_jsxs("div", { className: "flex items-start gap-2 sm:block", children: [_jsx("div", { className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border/35 bg-bg-muted/20 text-xs font-bold text-muted-strong", children: index + 1 }), _jsx("div", { className: "mt-0.5 text-2xs font-semibold uppercase tracking-[0.12em] text-muted/60 sm:mt-2", children: t("knowledgeview.Chunk", {
139
+ defaultValue: "Chunk",
140
+ }) })] }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "mb-2 flex flex-wrap items-center gap-2 text-2xs text-muted", children: [fragment.position !== undefined ? (_jsx("span", { children: t("knowledgeview.FragmentPosition", {
141
+ defaultValue: "position {{position}}",
142
+ position: fragment.position,
143
+ }) })) : null, createdLabel ? (_jsxs(_Fragment, { children: [fragment.position !== undefined ? (_jsx("span", { children: "\u2022" })) : null, _jsx("span", { children: createdLabel })] })) : null, (fragment.position !== undefined ||
144
+ createdLabel) && _jsx("span", { children: "\u2022" }), _jsx("span", { children: t("knowledgeview.CharacterCount", {
145
+ defaultValue: "{{count}} chars",
146
+ count: fragment.text.length,
147
+ }) })] }), _jsx("p", { className: "whitespace-pre-wrap break-words text-sm leading-relaxed text-txt/90", children: fragment.text })] })] }, fragment.id));
148
+ }), fragments.length === 0 && (_jsx(PagePanel.Empty, { variant: "inset", className: "min-h-[8rem] py-8 !rounded-none !border-0 !bg-transparent !shadow-none !ring-0", title: t("knowledgeview.NoFragmentsFound") }))] })] })] }))] }) }));
123
149
  }
@@ -7,7 +7,7 @@ export declare const PAGE_SCOPES: readonly PageScope[];
7
7
  * single prompt-regime cohort instead of mixing trajectories generated under
8
8
  * different surface contracts.
9
9
  */
10
- export declare const PAGE_SCOPE_VERSION = 10;
10
+ export declare const PAGE_SCOPE_VERSION = 11;
11
11
  export interface PageScopeIntroCopy {
12
12
  /** Short user-facing intro card title shown when the conversation is empty. */
13
13
  title: string;
@@ -15,7 +15,7 @@ export const PAGE_SCOPES = [
15
15
  * single prompt-regime cohort instead of mixing trajectories generated under
16
16
  * different surface contracts.
17
17
  */
18
- export const PAGE_SCOPE_VERSION = 10;
18
+ export const PAGE_SCOPE_VERSION = 11;
19
19
  export const PAGE_SCOPE_COPY = {
20
20
  "page-browser": {
21
21
  title: "Browser chat",
@@ -28,8 +28,8 @@ export const PAGE_SCOPE_COPY = {
28
28
  systemAddendum: "You are answering inside the Character view. The Character hub is organized into Overview, Personality, Knowledge, Experience, and Relationships. Help the user navigate those sections, recommend the next character step from live state, and draft exact wording when they need copy. Use Overview for high-level status and identity framing, Personality for editable persona/voice fields, Knowledge for uploaded reference material, Experience for surfaced learnings, and Relationships for contact and graph context. Guide the user to the relevant section instead of inventing a generic setter action. Reference live character state when answering.",
29
29
  },
30
30
  "page-automations": {
31
- title: "Automations chat",
32
- body: "Use me to create tasks and n8n workflows, wire them to a schedule or event, inspect what is running, and troubleshoot failures. Workflows are multi-step pipelines; tasks are simple prompts. Recommended: tell me the trigger, timing, and desired result, and I'll choose the right shape.",
31
+ title: "Automations",
32
+ body: "Create or inspect a task or n8n workflow. Tell me the trigger, timing, and result.",
33
33
  systemAddendum: "You are answering inside the Automations view. The user can create tasks and n8n workflows, attach either one to a schedule or event, configure wake mode, max runs, and enabled state, browse templates, inspect existing automations, and troubleshoot failed runs. Treat tasks as simple prompt-driven automations and workflows as multi-step n8n pipelines. Recommend the smaller task shape unless the user clearly needs a multi-step pipeline. Use createTriggerTaskAction and manageTasksAction when the request is concrete. Reference live tasks and workflows in context by display name. Never fabricate automation names.",
34
34
  },
35
35
  "page-apps": {
@@ -44,7 +44,7 @@ export const PAGE_SCOPE_COPY = {
44
44
  },
45
45
  "page-lifeops": {
46
46
  title: "LifeOps chat",
47
- body: "Use me to plan and inspect today, goals, reminders, calendar, messages, mail, sleep, screen time, social, connectors, and LifeOps setup. Recommended: start with capability readiness and the current overview, then ask me to create or adjust the next reminder, goal, reply draft, or schedule block. Ask me to explain any LifeOps item or turn it into an action.",
47
+ body: "Ask about the visible LifeOps item or the next action you want handled.",
48
48
  systemAddendum: "You are answering inside the LifeOps view. The user can inspect the current overview, goals, reminders, calendar, messages, mail, sleep, screen time, social context, connector setup, capability readiness, and LifeOps settings. Recommend capability readiness and overview review before creating or changing durable personal workflows. When the user asks for concrete LifeOps work, route through the LifeOps app actions/providers already available in the runtime instead of generic advice. Reference live LifeOps state when present, and never invent reminders, goals, messages, calendar events, or connector state.",
49
49
  },
50
50
  "page-settings": {
@@ -1,8 +1,9 @@
1
1
  import type { RelationshipsPersonDetail } from "../../../api/client-types-relationships";
2
2
  import { type RelationshipsPersonSupplementalDetail } from "./relationships-utils";
3
3
  type RelationshipsDisplayPerson = RelationshipsPersonDetail & RelationshipsPersonSupplementalDetail;
4
- export declare function RelationshipsPersonSummaryPanel({ person, onViewMemories, }: {
4
+ export declare function RelationshipsPersonSummaryPanel({ person, compact, onViewMemories, }: {
5
5
  person: RelationshipsDisplayPerson;
6
+ compact?: boolean;
6
7
  onViewMemories?: (entityIds: string[]) => void;
7
8
  }): import("react/jsx-runtime").JSX.Element;
8
9
  export declare function RelationshipsFactsPanel({ person, }: {
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipsPersonPanels.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/pages/relationships/RelationshipsPersonPanels.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAIL,KAAK,qCAAqC,EAE3C,MAAM,uBAAuB,CAAC;AAE/B,KAAK,0BAA0B,GAAG,yBAAyB,GACzD,qCAAqC,CAAC;AA8FxC,wBAAgB,+BAA+B,CAAC,EAC9C,MAAM,EACN,cAAc,GACf,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAChD,2CA+JA;AAED,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAkFA;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAoDA;AAED,wBAAgB,+BAA+B,CAAC,EAC9C,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CA0DA;AAED,wBAAgB,kCAAkC,CAAC,EACjD,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAkDA;AAED,wBAAgB,iCAAiC,CAAC,EAChD,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAsDA"}
1
+ {"version":3,"file":"RelationshipsPersonPanels.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/pages/relationships/RelationshipsPersonPanels.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAIL,KAAK,qCAAqC,EAE3C,MAAM,uBAAuB,CAAC;AAE/B,KAAK,0BAA0B,GAAG,yBAAyB,GACzD,qCAAqC,CAAC;AAkIxC,wBAAgB,+BAA+B,CAAC,EAC9C,MAAM,EACN,OAAe,EACf,cAAc,GACf,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAChD,2CAsKA;AAqBD,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAyEA;AAED,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CA2DA;AAED,wBAAgB,+BAA+B,CAAC,EAC9C,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAsFA;AAED,wBAAgB,kCAAkC,CAAC,EACjD,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAuDA;AAED,wBAAgB,iCAAiC,CAAC,EAChD,MAAM,GACP,EAAE;IACD,MAAM,EAAE,0BAA0B,CAAC;CACpC,2CAmEA"}