@xopcai/xopc 0.0.330 → 0.0.332

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 (166) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BDG0hI-J.js → agent-avatar-dicebear-C2wg3xC_.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Se1Z72VG.js +1 -0
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-BX_Bhre1.js → agent-plugin-dialog-BeNnu1Ts.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-udIitwV8.js +70 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DgttzUCG.js → app-management-settings-panel-etFSkfzl.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CHpyWV8Z.js → appearance-settings-DKmU2VAP.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-DVNySL58.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-B7Q7Oeo7.js → archive-plugin-D0z_Fr2G.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BYwqQ8qN.js → attachment-load-DNCDbeOX.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-CsvAtTNd.js → automations-page-B7_C-p66.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-BMgJvdcv.js +7 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DdgWCI-M.js → binary-plugins-BYn2hScX.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DyOagNnn.js → block-editor-ChWW8Z9L.js} +3 -3
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-CwF8OQFN.js → browser-automation-inputs-C5s1yHOu.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-D_EQjiiu.js → browser-automations-page-BV00BXRb.js} +2 -2
  18. package/dist/gateway/static/root/assets/browser-settings-page-xwTmuZjS.js +3 -0
  19. package/dist/gateway/static/root/assets/capabilities-CHA-sTAZ.js +1 -0
  20. package/dist/gateway/static/root/assets/capabilities-page-v0WkhV5o.js +2 -0
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-DefBGjhV.js +8 -0
  22. package/dist/gateway/static/root/assets/{capability-header-actions-C5F2GNE9.js → capability-header-actions-vmx35sbu.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-Eo4ONF5X.js +1 -0
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-C6tl9Rfw.js → chat-terminal-dock-C41mXCAi.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-C0MsVw4l.js → computer-settings-page-BJkqok2G.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connector-service-page-DsF60pPs.js → connector-service-page-BKCZMmwm.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-DZYgogQw.js +2 -0
  28. package/dist/gateway/static/root/assets/{date-picker-CELKKqYN.js → date-picker-CrOV4Ynd.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-BcEwCnI5.js → dependency-picker-CqADAHZp.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-Ww7Gm8-x.js → desktop-pet-Bab-iWED.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-D-dbAxGu.js → desktop-pet-settings-BqgzLOdi.js} +1 -1
  32. package/dist/gateway/static/root/assets/{device-pairing-wizard-DsYY6szg.js → device-pairing-wizard-DFg7FDPf.js} +1 -1
  33. package/dist/gateway/static/root/assets/{directory-picker-path-field-CVmuCRyO.js → directory-picker-path-field-hqJ9sFCR.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-debug-page-UUHNJj-d.js → extension-debug-page-DX3PFhRE.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-BvL452mX.js → extension-page-DkREdHLs.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-CrNnUSOs.js → extension-settings-page-wF-HNTM-.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-DMm1vU51.js → gateway-config-swr-cR-tz7-Q.js} +1 -1
  38. package/dist/gateway/static/root/assets/gateway-settings-Du-Dos9O.js +1 -0
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-Ck6tj6yE.js → gateway-startup-retry-6jLRcQsu.js} +1 -1
  40. package/dist/gateway/static/root/assets/home-page-D7YoMHq4.js +1 -0
  41. package/dist/gateway/static/root/assets/{image-generation-api-BOh6j0BF.js → image-generation-api-CSSkwsyC.js} +1 -1
  42. package/dist/gateway/static/root/assets/{imports-page-BuqdzA7h.js → imports-page-B80Cv043.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BEw0xrde.css +1 -0
  44. package/dist/gateway/static/root/assets/index-DalslRUx.js +121 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D9L7IdUg.js → keyboard-shortcuts-settings-BgoFaTwv.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-BKL5UZAj.js +1 -0
  47. package/dist/gateway/static/root/assets/local-apps-page-HO6OQlQT.js +1 -0
  48. package/dist/gateway/static/root/assets/{locale-store-DAOwT3Zp.js → locale-store-wNXWkWu5.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-CjzR9Rpj.js +2 -0
  50. package/dist/gateway/static/root/assets/management-settings-Dk_gTJb9.js +1 -0
  51. package/dist/gateway/static/root/assets/{markdown-view-nL4xzvI8.js → markdown-view-DlT9KqwF.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-dHbcqMan.js → media-plugins-Dlj6TD3M.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-fmf0dnr4.js +3 -0
  54. package/dist/gateway/static/root/assets/note-detail-panel-BebJPjjk.js +5 -0
  55. package/dist/gateway/static/root/assets/notes-page-CmS_hvz8.js +8 -0
  56. package/dist/gateway/static/root/assets/{page-context-capture-button-BKsMcPOy.js → page-context-capture-button-BArPtqp5.js} +1 -1
  57. package/dist/gateway/static/root/assets/page-tabs-vqI30Yrg.js +1 -0
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-Du18QgWc.js → preview-open-alternatives-B-mwPBJW.js} +1 -1
  59. package/dist/gateway/static/root/assets/product-open-page-D--sj_uN.js +1 -0
  60. package/dist/gateway/static/root/assets/project-detail-page-BFUdtWXF.js +1 -0
  61. package/dist/gateway/static/root/assets/{projects-page-BdYbDNUn.js → projects-page-DBsBwAQ6.js} +1 -1
  62. package/dist/gateway/static/root/assets/{registry-api-DCFXWBOt.js → registry-api-BIpltJ47.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-BurdDY0m.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CuTFmXyj.js → runtime-tools-settings-panel-CAnb0PNY.js} +1 -1
  65. package/dist/gateway/static/root/assets/scenes-page-Cj8xtr5t.js +2 -0
  66. package/dist/gateway/static/root/assets/{schema-form-qWQii8IU.js → schema-form-BKj6wIMb.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-BCsjgkCs.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-BLL7csOJ.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-form-section-B0ZBr0L9.js → settings-form-section-78ycUHfv.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-DpII4NO3.js → settings-page-BOdxIVzo.js} +1 -1
  71. package/dist/gateway/static/root/assets/setup-status-panel-CbKHBjrU.js +1 -0
  72. package/dist/gateway/static/root/assets/{share-preview-page-B2CGYZHc.js → share-preview-page-DyLfktib.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-BzvSNouj.js +1 -0
  74. package/dist/gateway/static/root/assets/{skill-api-_ddww47C.js → skill-api-CiBGQ0Jg.js} +1 -1
  75. package/dist/gateway/static/root/assets/skill-reload-api-BHnru0F5.js +1 -0
  76. package/dist/gateway/static/root/assets/skills-page-C35VKjhb.js +2 -0
  77. package/dist/gateway/static/root/assets/{system-settings-panel-25ABVt7H.js → system-settings-panel-CyJUeREH.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-Bd1_Fguk.js +1 -0
  79. package/dist/gateway/static/root/assets/{tunnel-api-CwQGBI_4.js → tunnel-api-Day9zhKi.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-CL3wytbs.js → use-autosave-Bj9hC6ML.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-model-page-DuYzuR1T.js +2 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-zjAzQrx4.js → voice-api-key-field-fWRD6B8r.js} +1 -1
  83. package/dist/gateway/static/root/assets/{voice-config-api-DvzQ-128.js → voice-config-api-ujEySjyc.js} +1 -1
  84. package/dist/gateway/static/root/assets/{work-discovery-overlay-MaPPjWwl.js → work-discovery-overlay-CnxdvIk8.js} +1 -1
  85. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C3dQN1fE.js → workflow-run-setup-panel-DlWNN1VA.js} +2 -2
  86. package/dist/gateway/static/root/assets/workflows-page-B45YDiEw.js +6 -0
  87. package/dist/gateway/static/root/index.html +9 -9
  88. package/dist/package.js +1 -1
  89. package/dist/packages/gateway-contract/src/automations.js +15 -0
  90. package/dist/src/agent/orchestration/agent-orchestrator.js +0 -21
  91. package/dist/src/automations/capabilities/write.d.ts +17 -0
  92. package/dist/src/automations/capabilities/write.js +26 -2
  93. package/dist/src/automations/domain/defaults.js +1 -1
  94. package/dist/src/automations/domain/index.js +2 -2
  95. package/dist/src/automations/domain/types.d.ts +22 -0
  96. package/dist/src/automations/domain/validation.d.ts +68 -0
  97. package/dist/src/automations/domain/validation.js +17 -1
  98. package/dist/src/automations/draft/automation-draft-validator.d.ts +9 -0
  99. package/dist/src/automations/draft/automation-draft-validator.js +1 -0
  100. package/dist/src/automations/index.js +2 -2
  101. package/dist/src/automations/service/action-executor.js +16 -0
  102. package/dist/src/automations/storage/automation-repository.js +4 -3
  103. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  104. package/dist/src/config/schema.d.ts +4 -0
  105. package/dist/src/config/schema.js +4 -0
  106. package/dist/src/gateway/home-intelligence-automation-reconciler.d.ts +3 -0
  107. package/dist/src/gateway/home-intelligence-automation-reconciler.js +49 -0
  108. package/dist/src/gateway/hono/routes/config-patch/misc.js +16 -2
  109. package/dist/src/gateway/hono/routes/home.js +0 -1
  110. package/dist/src/gateway/hono/routes/update.js +6 -1
  111. package/dist/src/gateway/memory-maintenance-automation-reconciler.js +17 -14
  112. package/dist/src/gateway/service.d.ts +1 -0
  113. package/dist/src/gateway/service.js +35 -13
  114. package/dist/src/home-intelligence/host.d.ts +1 -1
  115. package/dist/src/home-intelligence/host.js +2 -10
  116. package/dist/src/home-intelligence/notification.js +1 -1
  117. package/dist/src/home-intelligence/repository.d.ts +1 -1
  118. package/dist/src/infra/update-check.d.ts +8 -4
  119. package/dist/src/infra/update-check.js +43 -41
  120. package/dist/src/infra/update-startup.d.ts +7 -1
  121. package/dist/src/infra/update-startup.js +15 -6
  122. package/dist/src/memory-maintenance/index.js +2 -2
  123. package/dist/src/memory-maintenance/schedule.d.ts +0 -3
  124. package/dist/src/memory-maintenance/schedule.js +1 -8
  125. package/dist/src/storage/sqlite/migrations/208_automation_management.sql +2 -0
  126. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  127. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  128. package/dist/src/storage/sqlite/schema.js +1 -1
  129. package/dist/src/tasks/home-query-service.js +1 -0
  130. package/dist/src/user-context/config.d.ts +9 -0
  131. package/dist/src/user-context/config.js +13 -4
  132. package/package.json +2 -2
  133. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-ArM6Sm9S.js +0 -1
  134. package/dist/gateway/static/root/assets/agents-BiQqpMw0.js +0 -70
  135. package/dist/gateway/static/root/assets/apps-page-BhfYQcm8.js +0 -1
  136. package/dist/gateway/static/root/assets/automations-workspace-DMH_1Ped.js +0 -7
  137. package/dist/gateway/static/root/assets/browser-settings-page-BE6691Jz.js +0 -3
  138. package/dist/gateway/static/root/assets/capabilities-page-MweWNrC1.js +0 -2
  139. package/dist/gateway/static/root/assets/capabilities-sAZT4brT.js +0 -1
  140. package/dist/gateway/static/root/assets/capabilities-settings-panel-CdSWkh89.js +0 -8
  141. package/dist/gateway/static/root/assets/channels-NGfwR3He.js +0 -1
  142. package/dist/gateway/static/root/assets/connectors-page-BE8NdQcR.js +0 -2
  143. package/dist/gateway/static/root/assets/gateway-settings-DrHhtZqv.js +0 -1
  144. package/dist/gateway/static/root/assets/home-page-YgI6jfGA.js +0 -1
  145. package/dist/gateway/static/root/assets/index-DJmO2VAY.css +0 -1
  146. package/dist/gateway/static/root/assets/index-vCIBfJp7.js +0 -121
  147. package/dist/gateway/static/root/assets/local-app-workbench-page-DO8uUtos.js +0 -1
  148. package/dist/gateway/static/root/assets/local-apps-page-BEvyufm7.js +0 -1
  149. package/dist/gateway/static/root/assets/logs-page-Jev1m9sS.js +0 -2
  150. package/dist/gateway/static/root/assets/management-settings-41i7B1RO.js +0 -1
  151. package/dist/gateway/static/root/assets/messages-BZbt9x1y.js +0 -3
  152. package/dist/gateway/static/root/assets/note-detail-panel-DonP0E6Q.js +0 -5
  153. package/dist/gateway/static/root/assets/notes-page-CYHMeVKo.js +0 -8
  154. package/dist/gateway/static/root/assets/product-open-page-IY1QL6s0.js +0 -1
  155. package/dist/gateway/static/root/assets/project-detail-page-Bpw9mxfV.js +0 -1
  156. package/dist/gateway/static/root/assets/remote-access-hub-CLhbz3TF.js +0 -1
  157. package/dist/gateway/static/root/assets/scenes-page-XwK2IEmr.js +0 -2
  158. package/dist/gateway/static/root/assets/sessions-page-4-QoiDES.js +0 -1
  159. package/dist/gateway/static/root/assets/settings-advanced-gate-BggQVM1y.js +0 -1
  160. package/dist/gateway/static/root/assets/setup-status-panel-HPpC7EE0.js +0 -1
  161. package/dist/gateway/static/root/assets/shares-settings-DhVCRYGP.js +0 -1
  162. package/dist/gateway/static/root/assets/skill-reload-api-XPZkWJJe.js +0 -1
  163. package/dist/gateway/static/root/assets/skills-page-uF7DkJMC.js +0 -2
  164. package/dist/gateway/static/root/assets/task-detail-page-gepxhO4j.js +0 -1
  165. package/dist/gateway/static/root/assets/user-model-page-DldQW9Wh.js +0 -2
  166. package/dist/gateway/static/root/assets/workflows-page-B9lnTU3U.js +0 -6
@@ -10,8 +10,28 @@ import { AutomationAlreadyExistsError, AutomationAlreadyRunningError } from "../
10
10
  import { z } from "zod";
11
11
  //#region src/automations/capabilities/write.ts
12
12
  init_src();
13
- const AutomationCreateCapabilityInputSchema = CreateAutomationSchema.omit({ state: true });
14
- const AutomationUpdatePatchSchema = UpdateAutomationSchema.safeExtend({ state: z.never().optional() });
13
+ const AutomationCreateCapabilityInputSchema = CreateAutomationSchema.omit({
14
+ state: true,
15
+ management: true
16
+ }).refine((input) => input.action.kind !== "system", { message: "System actions can only be created by the runtime" });
17
+ const AutomationUpdatePatchSchema = UpdateAutomationSchema.safeExtend({
18
+ state: z.never().optional(),
19
+ management: z.never().optional()
20
+ });
21
+ function assertManagedOperation(automation, operation, patch) {
22
+ const management = automation.management;
23
+ if (!management) return;
24
+ if (operation === "run") {
25
+ if (!management.runnable) throw new CapabilityError("FORBIDDEN", "This managed automation cannot be run manually");
26
+ return;
27
+ }
28
+ if (operation === "delete") {
29
+ if (!management.deletable) throw new CapabilityError("FORBIDDEN", "This managed automation cannot be deleted");
30
+ return;
31
+ }
32
+ const forbidden = Object.entries(patch ?? {}).filter(([key, value]) => JSON.stringify(automation[key]) !== JSON.stringify(value)).map(([key]) => key).filter((field) => !management.editable.includes(field));
33
+ if (forbidden.length > 0) throw new CapabilityError("FORBIDDEN", `Managed fields cannot be changed: ${forbidden.join(", ")}`);
34
+ }
15
35
  function registerAutomationWriteCapabilities(dispatcher, service, projects) {
16
36
  const policy = {
17
37
  majorVersion: 1,
@@ -75,6 +95,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
75
95
  const automationId = command === "run" ? id : getAutomationRun(id)?.automationId;
76
96
  const automation = automationId ? getAutomation(automationId) : null;
77
97
  if (!automation) throw new CapabilityError("NOT_FOUND", "Automation or source run not found");
98
+ assertManagedOperation(automation, "run");
78
99
  try {
79
100
  const run = command === "run" ? service.queueRunAtomically(id) : service.queueRerunAtomically(id);
80
101
  return {
@@ -98,6 +119,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
98
119
  execute({ id, expectedRevision }) {
99
120
  const current = getAutomation(id);
100
121
  if (current && current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
122
+ if (current) assertManagedOperation(current, "delete");
101
123
  const result = service.removeAtomically(id);
102
124
  return {
103
125
  ok: true,
@@ -138,6 +160,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
138
160
  const current = getAutomation(id);
139
161
  if (!current) throw new CapabilityError("NOT_FOUND", "Automation not found");
140
162
  if (current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
163
+ assertManagedOperation(current, "update", patch);
141
164
  requireProject(patch.projectId);
142
165
  return {
143
166
  ok: true,
@@ -158,6 +181,7 @@ function registerAutomationWriteCapabilities(dispatcher, service, projects) {
158
181
  const current = getAutomation(id);
159
182
  if (!current) throw new CapabilityError("NOT_FOUND", "Automation not found");
160
183
  if (current.updatedAtMs !== expectedRevision) throw new CapabilityError("REVISION_CONFLICT", "Automation changed");
184
+ assertManagedOperation(current, "update", { enabled });
161
185
  const automation = service.updateAtomically(id, { enabled });
162
186
  if (!automation) throw new CapabilityError("NOT_FOUND", "Automation not found");
163
187
  return {
@@ -2,7 +2,7 @@
2
2
  const DEFAULT_AUTOMATION_TIMEOUT_SECONDS = 1800;
3
3
  const DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS = 600;
4
4
  function defaultAutomationTimeoutSeconds(action) {
5
- return action.kind === "browser_automation" ? 600 : DEFAULT_AUTOMATION_TIMEOUT_SECONDS;
5
+ return action.kind === "system" ? 60 : action.kind === "browser_automation" ? 600 : DEFAULT_AUTOMATION_TIMEOUT_SECONDS;
6
6
  }
7
7
  function resolveAutomationTimeoutSeconds(action, reliability) {
8
8
  return reliability?.executionTimeoutSeconds ?? ("timeoutSeconds" in action ? action.timeoutSeconds : void 0) ?? reliability?.timeoutSeconds ?? defaultAutomationTimeoutSeconds(action);
@@ -1,4 +1,4 @@
1
- import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
1
+ import { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./validation.js";
2
2
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./schedule.js";
3
3
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./defaults.js";
4
- export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
4
+ export { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds, timerDelayUntil };
@@ -54,7 +54,17 @@ export type AutomationAction = {
54
54
  kind: 'task_command';
55
55
  taskId: string;
56
56
  command: TaskCommand;
57
+ } | {
58
+ kind: 'system';
59
+ capability: 'home.advisor.refresh' | 'memory.temporal_sweep' | 'memory.daily_reconciliation' | 'memory.weekly_knowledge';
57
60
  };
61
+ export type AutomationEditableField = 'enabled' | 'trigger';
62
+ export interface AutomationManagement {
63
+ owner: string;
64
+ editable: AutomationEditableField[];
65
+ runnable: boolean;
66
+ deletable: boolean;
67
+ }
58
68
  export type AutomationConversationMode = 'new_session' | 'continuous';
59
69
  export type AutomationNotificationPolicy = 'attention' | 'all' | 'none';
60
70
  export interface AutomationReliability {
@@ -97,6 +107,7 @@ export interface Automation {
97
107
  notificationPolicy: AutomationNotificationPolicy;
98
108
  completionWebhookUrl?: string;
99
109
  reliability?: AutomationReliability;
110
+ management?: AutomationManagement;
100
111
  state: AutomationState;
101
112
  createdAtMs: number;
102
113
  updatedAtMs: number;
@@ -210,6 +221,17 @@ export interface AutomationDeps {
210
221
  reason?: string;
211
222
  runId?: string;
212
223
  };
224
+ executeSystemAction?: (input: {
225
+ capability: Extract<AutomationAction, {
226
+ kind: 'system';
227
+ }>['capability'];
228
+ automationId: string;
229
+ runId: string;
230
+ }) => Promise<{
231
+ summary?: string;
232
+ }> | {
233
+ summary?: string;
234
+ };
213
235
  }
214
236
  export interface AutomationActionTask {
215
237
  status: 'succeeded' | 'failed' | 'timeout' | 'cancelled';
@@ -151,7 +151,24 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
151
151
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
152
152
  }, z.core.$strip>;
153
153
  }, z.core.$strip>], "type">;
154
+ }, z.core.$strict>, z.ZodObject<{
155
+ kind: z.ZodLiteral<"system">;
156
+ capability: z.ZodEnum<{
157
+ "home.advisor.refresh": "home.advisor.refresh";
158
+ "memory.temporal_sweep": "memory.temporal_sweep";
159
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
160
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
161
+ }>;
154
162
  }, z.core.$strict>], "kind">;
163
+ export declare const AutomationManagementSchema: z.ZodObject<{
164
+ owner: z.ZodString;
165
+ editable: z.ZodArray<z.ZodEnum<{
166
+ enabled: "enabled";
167
+ trigger: "trigger";
168
+ }>>;
169
+ runnable: z.ZodBoolean;
170
+ deletable: z.ZodBoolean;
171
+ }, z.core.$strict>;
155
172
  export declare const AutomationReliabilitySchema: z.ZodObject<{
156
173
  executionTimeoutSeconds: z.ZodOptional<z.ZodNumber>;
157
174
  timeoutSeconds: z.ZodOptional<z.ZodNumber>;
@@ -328,6 +345,14 @@ export declare const AutomationSchema: z.ZodObject<{
328
345
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
329
346
  }, z.core.$strip>;
330
347
  }, z.core.$strip>], "type">;
348
+ }, z.core.$strict>, z.ZodObject<{
349
+ kind: z.ZodLiteral<"system">;
350
+ capability: z.ZodEnum<{
351
+ "home.advisor.refresh": "home.advisor.refresh";
352
+ "memory.temporal_sweep": "memory.temporal_sweep";
353
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
354
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
355
+ }>;
331
356
  }, z.core.$strict>], "kind">;
332
357
  safety: z.ZodOptional<z.ZodObject<{
333
358
  mode: z.ZodEnum<{
@@ -353,6 +378,15 @@ export declare const AutomationSchema: z.ZodObject<{
353
378
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
354
379
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
355
380
  }, z.core.$strict>>;
381
+ management: z.ZodOptional<z.ZodObject<{
382
+ owner: z.ZodString;
383
+ editable: z.ZodArray<z.ZodEnum<{
384
+ enabled: "enabled";
385
+ trigger: "trigger";
386
+ }>>;
387
+ runnable: z.ZodBoolean;
388
+ deletable: z.ZodBoolean;
389
+ }, z.core.$strict>>;
356
390
  state: z.ZodDefault<z.ZodObject<{
357
391
  nextRunAtMs: z.ZodOptional<z.ZodNumber>;
358
392
  runningRunId: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string, string>>;
@@ -490,6 +524,14 @@ export declare const CreateAutomationSchema: z.ZodObject<{
490
524
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
491
525
  }, z.core.$strip>;
492
526
  }, z.core.$strip>], "type">;
527
+ }, z.core.$strict>, z.ZodObject<{
528
+ kind: z.ZodLiteral<"system">;
529
+ capability: z.ZodEnum<{
530
+ "home.advisor.refresh": "home.advisor.refresh";
531
+ "memory.temporal_sweep": "memory.temporal_sweep";
532
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
533
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
534
+ }>;
493
535
  }, z.core.$strict>], "kind">;
494
536
  trigger: z.ZodDiscriminatedUnion<[z.ZodObject<{
495
537
  kind: z.ZodLiteral<"manual">;
@@ -541,6 +583,15 @@ export declare const CreateAutomationSchema: z.ZodObject<{
541
583
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
542
584
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
543
585
  }, z.core.$strict>>;
586
+ management: z.ZodOptional<z.ZodObject<{
587
+ owner: z.ZodString;
588
+ editable: z.ZodArray<z.ZodEnum<{
589
+ enabled: "enabled";
590
+ trigger: "trigger";
591
+ }>>;
592
+ runnable: z.ZodBoolean;
593
+ deletable: z.ZodBoolean;
594
+ }, z.core.$strict>>;
544
595
  id: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string, string>>;
545
596
  enabled: z.ZodOptional<z.ZodBoolean>;
546
597
  state: z.ZodOptional<z.ZodObject<{
@@ -679,6 +730,14 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
679
730
  outputDestinations: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
680
731
  }, z.core.$strip>;
681
732
  }, z.core.$strip>], "type">;
733
+ }, z.core.$strict>, z.ZodObject<{
734
+ kind: z.ZodLiteral<"system">;
735
+ capability: z.ZodEnum<{
736
+ "home.advisor.refresh": "home.advisor.refresh";
737
+ "memory.temporal_sweep": "memory.temporal_sweep";
738
+ "memory.daily_reconciliation": "memory.daily_reconciliation";
739
+ "memory.weekly_knowledge": "memory.weekly_knowledge";
740
+ }>;
682
741
  }, z.core.$strict>], "kind">>;
683
742
  trigger: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
684
743
  kind: z.ZodLiteral<"manual">;
@@ -721,6 +780,15 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
721
780
  maxConcurrentRuns: z.ZodOptional<z.ZodNumber>;
722
781
  disableAfterConsecutiveFailures: z.ZodOptional<z.ZodNumber>;
723
782
  }, z.core.$strict>>>;
783
+ management: z.ZodOptional<z.ZodOptional<z.ZodObject<{
784
+ owner: z.ZodString;
785
+ editable: z.ZodArray<z.ZodEnum<{
786
+ enabled: "enabled";
787
+ trigger: "trigger";
788
+ }>>;
789
+ runnable: z.ZodBoolean;
790
+ deletable: z.ZodBoolean;
791
+ }, z.core.$strict>>>;
724
792
  conversationMode: z.ZodOptional<z.ZodEnum<{
725
793
  new_session: "new_session";
726
794
  continuous: "continuous";
@@ -89,8 +89,23 @@ const AutomationActionSchema = z.discriminatedUnion("kind", [
89
89
  kind: z.literal("task_command"),
90
90
  taskId: nonEmptyString.max(200),
91
91
  command: TaskCommandSchema
92
+ }).strict(),
93
+ z.object({
94
+ kind: z.literal("system"),
95
+ capability: z.enum([
96
+ "home.advisor.refresh",
97
+ "memory.temporal_sweep",
98
+ "memory.daily_reconciliation",
99
+ "memory.weekly_knowledge"
100
+ ])
92
101
  }).strict()
93
102
  ]);
103
+ const AutomationManagementSchema = z.object({
104
+ owner: nonEmptyString.max(100),
105
+ editable: z.array(z.enum(["enabled", "trigger"])).max(2),
106
+ runnable: z.boolean(),
107
+ deletable: z.boolean()
108
+ }).strict();
94
109
  const AutomationReliabilitySchema = z.object({
95
110
  executionTimeoutSeconds: z.number().int().min(1).max(86400).optional(),
96
111
  timeoutSeconds: z.number().int().min(1).max(86400).optional(),
@@ -136,6 +151,7 @@ const AutomationSchema = z.object({
136
151
  ]).default("attention"),
137
152
  completionWebhookUrl: optionalTrimmedString(2e3),
138
153
  reliability: AutomationReliabilitySchema.optional(),
154
+ management: AutomationManagementSchema.optional(),
139
155
  state: AutomationStateSchema.default({}),
140
156
  createdAtMs: z.number().int().nonnegative(),
141
157
  updatedAtMs: z.number().int().nonnegative()
@@ -165,4 +181,4 @@ const UpdateAutomationSchema = AutomationSchema.omit({
165
181
  state: AutomationStateSchema
166
182
  }).partial().refine((data) => Object.keys(data).length > 0, { message: "At least one field must be provided" });
167
183
  //#endregion
168
- export { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
184
+ export { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema };
@@ -102,6 +102,9 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
102
102
  outputDestinations: Record<string, unknown>[];
103
103
  };
104
104
  };
105
+ } | {
106
+ kind: "system";
107
+ capability: "home.advisor.refresh" | "memory.temporal_sweep" | "memory.daily_reconciliation" | "memory.weekly_knowledge";
105
108
  };
106
109
  trigger?: {
107
110
  kind: "manual";
@@ -140,6 +143,12 @@ export declare function buildAutomationDraftResponse(draft: GeneratedAutomationD
140
143
  maxConcurrentRuns?: number;
141
144
  disableAfterConsecutiveFailures?: number;
142
145
  };
146
+ management?: {
147
+ owner: string;
148
+ editable: ("enabled" | "trigger")[];
149
+ runnable: boolean;
150
+ deletable: boolean;
151
+ };
143
152
  id?: string;
144
153
  enabled?: boolean;
145
154
  state?: {
@@ -92,6 +92,7 @@ function summarizeAction(action) {
92
92
  if (action.kind === "workflow") return `Starts workflow ${action.workflowId}.`;
93
93
  if (action.kind === "browser_automation") return `Runs browser automation ${action.automationId}.`;
94
94
  if (action.kind === "task_command") return `Applies ${action.command?.type ?? "a command"} to task ${action.taskId}.`;
95
+ if (action.kind === "system") return `Runs system capability ${action.capability}.`;
95
96
  return action.agentId ? `Runs agent ${action.agentId}.` : "Runs the default agent.";
96
97
  }
97
98
  function repairPatchNeedsApproval(patch) {
@@ -1,9 +1,9 @@
1
1
  import { onAutomationProductEvent, publishAutomationProductEvent } from "./product-events.js";
2
- import { AutomationActionSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
2
+ import { AutomationActionSchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
3
3
  import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./domain/schedule.js";
4
4
  import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./domain/defaults.js";
5
5
  import { AutomationActionExecutor } from "./service/action-executor.js";
6
6
  import { AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationService } from "./service/automation-service.js";
7
7
  import "./domain/index.js";
8
8
  import "./service/index.js";
9
- export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };
9
+ export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, onAutomationProductEvent, publishAutomationProductEvent, resolveAutomationTimeoutSeconds, timerDelayUntil };
@@ -128,6 +128,22 @@ var AutomationActionExecutor = class {
128
128
  error: result.reason ?? "Task command failed"
129
129
  };
130
130
  }
131
+ if (automation.action.kind === "system") {
132
+ await hooks.onRunPatch?.({ currentPhase: "action" });
133
+ const execute = this.deps.executeSystemAction;
134
+ if (!execute) return {
135
+ status: "failed",
136
+ error: "System action executor is unavailable"
137
+ };
138
+ return {
139
+ status: "succeeded",
140
+ summary: (await execute({
141
+ capability: automation.action.capability,
142
+ automationId: automation.id,
143
+ runId: run.id
144
+ })).summary ?? "System action completed"
145
+ };
146
+ }
131
147
  return this.executeAgent(automation, automation.action, run, signal, hooks, deadlineAtMs, context);
132
148
  }
133
149
  async executeBrowserAutomation(automation, action, signal, hooks, context) {
@@ -23,6 +23,7 @@ function rowToAutomation(row) {
23
23
  notificationPolicy: row.notification_policy,
24
24
  completionWebhookUrl: row.completion_webhook_url ?? void 0,
25
25
  reliability: parseJson(row.reliability_json),
26
+ management: parseJson(row.management_json),
26
27
  state: parseJson(row.state_json) ?? {},
27
28
  createdAtMs: row.created_at_ms,
28
29
  updatedAtMs: row.updated_at_ms
@@ -32,13 +33,13 @@ function upsertAutomation(db, automation) {
32
33
  db.prepare(`INSERT OR REPLACE INTO automations (
33
34
  automation_id, name, description, project_id, enabled, trigger_json, action_json,
34
35
  safety_json, conversation_mode, notification_policy, completion_webhook_url,
35
- reliability_json, state_json, created_at_ms, updated_at_ms
36
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(automation.id, automation.name, automation.description ?? null, automation.projectId ?? null, automation.enabled ? 1 : 0, JSON.stringify(automation.trigger), JSON.stringify(automation.action), bindJson(automation.safety ?? { mode: "auto_apply" }), automation.conversationMode, automation.notificationPolicy, automation.completionWebhookUrl ?? null, bindJson(automation.reliability), JSON.stringify(automation.state ?? {}), automation.createdAtMs, automation.updatedAtMs);
36
+ reliability_json, management_json, state_json, created_at_ms, updated_at_ms
37
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(automation.id, automation.name, automation.description ?? null, automation.projectId ?? null, automation.enabled ? 1 : 0, JSON.stringify(automation.trigger), JSON.stringify(automation.action), bindJson(automation.safety ?? { mode: "auto_apply" }), automation.conversationMode, automation.notificationPolicy, automation.completionWebhookUrl ?? null, bindJson(automation.reliability), bindJson(automation.management), JSON.stringify(automation.state ?? {}), automation.createdAtMs, automation.updatedAtMs);
37
38
  }
38
39
  const AUTOMATION_SELECT = `
39
40
  SELECT automation_id, name, description, project_id, enabled, trigger_json, action_json,
40
41
  safety_json, conversation_mode, notification_policy, completion_webhook_url,
41
- reliability_json, state_json, created_at_ms, updated_at_ms
42
+ reliability_json, management_json, state_json, created_at_ms, updated_at_ms
42
43
  FROM automations
43
44
  `;
44
45
  function listAutomations(options) {
@@ -53,7 +53,7 @@ async function checkDatabaseSchema(ctx) {
53
53
  id: "database-schema",
54
54
  label: "Database schema",
55
55
  status: "pass",
56
- message: `SQLite schema v${status.dbVersion} (current release v207).`,
56
+ message: `SQLite schema v${status.dbVersion} (current release v208).`,
57
57
  hints: []
58
58
  };
59
59
  }
@@ -1360,6 +1360,10 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1360
1360
  postCompactionSections: z.ZodDefault<z.ZodArray<z.ZodString>>;
1361
1361
  }, z.core.$strict>>;
1362
1362
  }, z.core.$strict>>;
1363
+ homeIntelligence: z.ZodDefault<z.ZodObject<{
1364
+ enabled: z.ZodDefault<z.ZodBoolean>;
1365
+ refreshOnContextChange: z.ZodDefault<z.ZodBoolean>;
1366
+ }, z.core.$strict>>;
1363
1367
  }, z.core.$strict>>;
1364
1368
  session: z.ZodDefault<z.ZodObject<{
1365
1369
  scope: z.ZodDefault<z.ZodEnum<{
@@ -1052,6 +1052,10 @@ workDiscoveryOnboarding: z.boolean().default(true) }).strict().default({ workDis
1052
1052
  maxKnowledge: 12,
1053
1053
  maxChars: 6e3,
1054
1054
  compaction: DEFAULT_CONTEXT_COMPACTION_POLICY
1055
+ },
1056
+ homeIntelligence: {
1057
+ enabled: true,
1058
+ refreshOnContextChange: true
1055
1059
  }
1056
1060
  },
1057
1061
  session: {
@@ -0,0 +1,3 @@
1
+ import type { AutomationService } from '../automations/index.js';
2
+ export declare const HOME_ADVISOR_REFRESH_AUTOMATION_ID = "system-home-advisor-refresh";
3
+ export declare function reconcileHomeIntelligenceAutomation(automationService: AutomationService): Promise<'created' | 'updated' | 'unchanged'>;
@@ -0,0 +1,49 @@
1
+ //#region src/gateway/home-intelligence-automation-reconciler.ts
2
+ const HOME_ADVISOR_REFRESH_AUTOMATION_ID = "system-home-advisor-refresh";
3
+ async function reconcileHomeIntelligenceAutomation(automationService) {
4
+ const current = await automationService.get(HOME_ADVISOR_REFRESH_AUTOMATION_ID);
5
+ const managed = {
6
+ name: "Refresh Home AI suggestions",
7
+ description: "Re-evaluate Home suggestions from current workspace context.",
8
+ action: {
9
+ kind: "system",
10
+ capability: "home.advisor.refresh"
11
+ },
12
+ safety: { mode: "auto_apply" },
13
+ conversationMode: "new_session",
14
+ notificationPolicy: "none",
15
+ reliability: { disableAfterConsecutiveFailures: 3 },
16
+ management: {
17
+ owner: "home-intelligence",
18
+ editable: ["enabled", "trigger"],
19
+ runnable: true,
20
+ deletable: false
21
+ }
22
+ };
23
+ if (!current) {
24
+ await automationService.create({
25
+ id: HOME_ADVISOR_REFRESH_AUTOMATION_ID,
26
+ enabled: false,
27
+ trigger: {
28
+ kind: "schedule",
29
+ schedule: {
30
+ kind: "interval",
31
+ everyMs: 30 * 6e4,
32
+ anchorMs: Date.now()
33
+ }
34
+ },
35
+ ...managed
36
+ });
37
+ return "created";
38
+ }
39
+ const patch = {
40
+ ...managed,
41
+ enabled: current.enabled,
42
+ trigger: current.trigger
43
+ };
44
+ if (!Object.entries(patch).some(([key, value]) => JSON.stringify(current[key]) !== JSON.stringify(value))) return "unchanged";
45
+ await automationService.update(HOME_ADVISOR_REFRESH_AUTOMATION_ID, patch);
46
+ return "updated";
47
+ }
48
+ //#endregion
49
+ export { HOME_ADVISOR_REFRESH_AUTOMATION_ID, reconcileHomeIntelligenceAutomation };
@@ -1,6 +1,6 @@
1
1
  import { ComputerConfigSchema, init_config } from "../../../../computer/config.js";
2
2
  import { BindingsSchema, init_binding_schema } from "../../../../routing/binding-schema.js";
3
- import { ContextPlanningConfigSchema, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config as init_config$1 } from "../../../../user-context/config.js";
3
+ import { ContextPlanningConfigSchema, HomeIntelligenceConfigSchema, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config as init_config$1 } from "../../../../user-context/config.js";
4
4
  import { BrowserConfigSchema, McpConfigSchema, VoiceConfigSchema, init_schema } from "../../../../config/schema.js";
5
5
  import { CredentialResolver, init_credentials } from "../../../../auth/credentials.js";
6
6
  import { canonicalizeConfiguredMcpServer } from "../../../../config/mcp-config-normalize.js";
@@ -37,7 +37,8 @@ async function applyMiscPatch(config, body) {
37
37
  "preferences",
38
38
  "userModel",
39
39
  "knowledgeMemory",
40
- "contextPlanning"
40
+ "contextPlanning",
41
+ "homeIntelligence"
41
42
  ].includes(key));
42
43
  if (unknownKeys.length) return patchError(`Unknown userContext settings: ${unknownKeys.join(", ")}`);
43
44
  if (userContextPatch.enabled !== void 0) {
@@ -111,6 +112,19 @@ async function applyMiscPatch(config, body) {
111
112
  contextPlanning: parsed.data
112
113
  };
113
114
  }
115
+ if (userContextPatch.homeIntelligence !== void 0) {
116
+ const patch = userContextPatch.homeIntelligence;
117
+ if (typeof patch !== "object" || patch === null || Array.isArray(patch)) return patchError("userContext.homeIntelligence must be an object");
118
+ const parsed = HomeIntelligenceConfigSchema.safeParse({
119
+ ...config.userContext.homeIntelligence,
120
+ ...patch
121
+ });
122
+ if (!parsed.success) return patchError(parsed.error.issues.map((issue) => issue.message).join("; "));
123
+ config.userContext = {
124
+ ...config.userContext,
125
+ homeIntelligence: parsed.data
126
+ };
127
+ }
114
128
  const parsedUserContext = UserContextConfigSchema.safeParse(config.userContext);
115
129
  if (!parsedUserContext.success) return patchError(parsedUserContext.error.issues.map((issue) => issue.message).join("; "));
116
130
  config.userContext = parsedUserContext.data;
@@ -16,7 +16,6 @@ function registerHomeRoutes(authenticated, deps) {
16
16
  const home = new HomeQueryService(service, () => service.homeIntelligence.getAdvisor());
17
17
  authenticated.get("/api/home", async (c) => {
18
18
  const locale = c.req.query("locale");
19
- service.homeIntelligence.requestRefresh("home_opened", void 0, locale);
20
19
  return c.json(await home.getSnapshot(locale));
21
20
  });
22
21
  authenticated.get("/api/home/advisor/metrics", (c) => {
@@ -32,13 +32,18 @@ function registerUpdateRoutes(authenticated, deps) {
32
32
  });
33
33
  });
34
34
  authenticated.post("/api/update/check", strictRateLimitMiddleware, async (c) => {
35
- await runGatewayUpdateCheck({
35
+ const checkResult = await runGatewayUpdateCheck({
36
36
  config: loadConfig(service.getHealth().configPath),
37
37
  force: true,
38
38
  onUpdateAvailableChange: (update) => {
39
39
  service.emit("update.available", update);
40
40
  }
41
41
  });
42
+ if (checkResult.ok === false) return c.json({
43
+ ok: false,
44
+ error: "update-check-failed",
45
+ message: `Could not check npm for updates: ${checkResult.error}`
46
+ }, 502);
42
47
  const result = getUpdateAvailable();
43
48
  return c.json({
44
49
  ok: true,
@@ -1,9 +1,6 @@
1
- import { normalizeAgentId } from "../agent-catalog/id.js";
2
- import { init_agent_scope, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
3
- import { maintenanceInstruction, resolveMemoryMaintenanceSchedules } from "../memory-maintenance/schedule.js";
1
+ import { resolveMemoryMaintenanceSchedules } from "../memory-maintenance/schedule.js";
4
2
  import "../memory-maintenance/index.js";
5
3
  //#region src/gateway/memory-maintenance-automation-reconciler.ts
6
- init_agent_scope();
7
4
  const AUTOMATION_IDS = [
8
5
  "system-memory-temporal-sweep",
9
6
  "system-memory-daily-reconciliation",
@@ -17,8 +14,6 @@ async function reconcileMemoryMaintenanceAutomations(input) {
17
14
  };
18
15
  const schedules = resolveMemoryMaintenanceSchedules(input.config);
19
16
  const enabledIds = new Set(schedules.map((item) => item.automationId));
20
- const agentId = normalizeAgentId(resolveDefaultAgentId());
21
- const workingDirectory = resolveAgentWorkspaceDir(agentId);
22
17
  for (const id of AUTOMATION_IDS) {
23
18
  if (enabledIds.has(id)) continue;
24
19
  if ((await input.automationService.get(id))?.enabled) {
@@ -36,11 +31,8 @@ async function reconcileMemoryMaintenanceAutomations(input) {
36
31
  }
37
32
  };
38
33
  const action = {
39
- kind: "agent",
40
- agentId,
41
- instruction: maintenanceInstruction(schedule.jobType),
42
- workingDirectory,
43
- timeoutSeconds: 300
34
+ kind: "system",
35
+ capability: `memory.${schedule.jobType}`
44
36
  };
45
37
  const next = {
46
38
  name: schedule.name,
@@ -51,7 +43,13 @@ async function reconcileMemoryMaintenanceAutomations(input) {
51
43
  safety: { mode: "auto_apply" },
52
44
  conversationMode: "continuous",
53
45
  notificationPolicy: "none",
54
- reliability: { disableAfterConsecutiveFailures: 3 }
46
+ reliability: { disableAfterConsecutiveFailures: 3 },
47
+ management: {
48
+ owner: "memory-maintenance",
49
+ editable: ["enabled", "trigger"],
50
+ runnable: true,
51
+ deletable: false
52
+ }
55
53
  };
56
54
  const current = await input.automationService.get(schedule.automationId);
57
55
  if (!current) {
@@ -62,8 +60,13 @@ async function reconcileMemoryMaintenanceAutomations(input) {
62
60
  result.created += 1;
63
61
  continue;
64
62
  }
65
- if (current.name !== next.name || current.description !== next.description || !current.enabled || JSON.stringify(current.trigger) !== JSON.stringify(trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.notificationPolicy !== "none") {
66
- await input.automationService.update(schedule.automationId, next);
63
+ const reconciled = current.management ? {
64
+ ...next,
65
+ enabled: current.enabled,
66
+ trigger: current.trigger
67
+ } : next;
68
+ if (current.name !== reconciled.name || current.description !== next.description || current.enabled !== reconciled.enabled || JSON.stringify(current.trigger) !== JSON.stringify(reconciled.trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.notificationPolicy !== "none" || JSON.stringify(current.management) !== JSON.stringify(next.management)) {
69
+ await input.automationService.update(schedule.automationId, reconciled);
67
70
  result.updated += 1;
68
71
  }
69
72
  }
@@ -318,6 +318,7 @@ export declare class GatewayService {
318
318
  getEffectiveListenPort(): number;
319
319
  get automationServiceInstance(): AutomationService;
320
320
  private reconcileMemoryMaintenanceAutomations;
321
+ private executeSystemAutomationAction;
321
322
  get notesServiceInstance(): NotesService;
322
323
  get sessionIndexInstance(): SessionIndex;
323
324
  /** Shared workflow run orchestrator + session bridge (one instance per gateway). */