@xopcai/xopc 0.0.337 → 0.0.338

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 (143) 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-CSHghJkF.js → agent-avatar-dicebear-D7lwnzGf.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DcDz1HJb.js → agent-defaults-settings-panel-Bsf_C5G-.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-C7A9k86o.js → agent-plugin-dialog-D1bd54F4.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-wih5cVy1.js → agents-D9LauN1U.js} +3 -3
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-LQ_zVJ9C.js → app-management-settings-panel-Blp7cgN9.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-C2gaax8U.js → appearance-settings-CKEHZAl0.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-CobrkzwB.js → apps-page-CHCvTpXO.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-CK_qS4Ex.js → archive-plugin-BTQaxZoS.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-page-DtuUM9W8.js → automations-page-DT_SzVIu.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-workspace-BNcU6ReT.js → automations-workspace-xyYt1P_F.js} +1 -1
  13. package/dist/gateway/static/root/assets/{binary-plugins-BN0iLzVY.js → binary-plugins-CeeqvrXF.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-CpLJmCV2.js → block-editor-B5Si55pP.js} +1 -1
  15. package/dist/gateway/static/root/assets/{browser-automations-page-DqKKZQNI.js → browser-automations-page-DApYWSvZ.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-settings-page-B0Vxlns8.js → browser-settings-page-B4FRZt79.js} +1 -1
  17. package/dist/gateway/static/root/assets/{capabilities-page-Bn72DIFn.js → capabilities-page-Dm3rO9D9.js} +2 -2
  18. package/dist/gateway/static/root/assets/{capabilities-settings-panel-n4g4t5LK.js → capabilities-settings-panel-BxWC1fto.js} +1 -1
  19. package/dist/gateway/static/root/assets/{capability-header-actions-CIxZrN4w.js → capability-header-actions-ulVgiGk5.js} +1 -1
  20. package/dist/gateway/static/root/assets/{channels-D8P0Sbu1.js → channels-CxjiPi_K.js} +1 -1
  21. package/dist/gateway/static/root/assets/{chat-terminal-dock-BJzZ5vkP.js → chat-terminal-dock-k7s5v_aC.js} +1 -1
  22. package/dist/gateway/static/root/assets/{computer-settings-page-WT8yMsKu.js → computer-settings-page-B6aKe8Pz.js} +1 -1
  23. package/dist/gateway/static/root/assets/{connector-service-page-71NVbenX.js → connector-service-page-DS_dCuYu.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-DdBdSoYi.js → connectors-page-CbLxkIGU.js} +1 -1
  25. package/dist/gateway/static/root/assets/{date-picker-WyLSk4_J.js → date-picker-DOl4D6Og.js} +1 -1
  26. package/dist/gateway/static/root/assets/{dependency-picker-BTdAiaBP.js → dependency-picker-DTZpqUW9.js} +1 -1
  27. package/dist/gateway/static/root/assets/{desktop-pet-f0MgT5Um.js → desktop-pet-A9AmyZFd.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-DKVITn3D.js → desktop-pet-settings-D4NMQfeC.js} +1 -1
  29. package/dist/gateway/static/root/assets/{device-pairing-wizard-1Buarqmz.js → device-pairing-wizard-B19IahuA.js} +1 -1
  30. package/dist/gateway/static/root/assets/{directory-picker-path-field-BoGtoYn0.js → directory-picker-path-field-D_92XGjD.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-debug-page-DPwnz1-y.js → extension-debug-page-CJEVTdVQ.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-CzioOhli.js → extension-page-Bo_QfERv.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-Cqq5bdYp.js → extension-settings-page-DyQKVwEg.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-CoXYbhk4.js → gateway-settings-Cm57iUdQ.js} +1 -1
  35. package/dist/gateway/static/root/assets/{home-page-z3Jiv5fF.js → home-page-NBbSjN9G.js} +1 -1
  36. package/dist/gateway/static/root/assets/{imports-page-DHiUg7PR.js → imports-page-B9T8hM43.js} +1 -1
  37. package/dist/gateway/static/root/assets/{index-D3OtdgCs.js → index-B-NICmRj.js} +7 -7
  38. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CbcZK4S6.js → keyboard-shortcuts-settings-DU3r7EWf.js} +1 -1
  39. package/dist/gateway/static/root/assets/{local-app-workbench-page-3HC00KSx.js → local-app-workbench-page-ChpwIJTp.js} +1 -1
  40. package/dist/gateway/static/root/assets/{local-apps-page-etrJtvmm.js → local-apps-page-Cz8SE9jo.js} +1 -1
  41. package/dist/gateway/static/root/assets/{logs-page-BsSdbCw2.js → logs-page-1oTbkOs_.js} +1 -1
  42. package/dist/gateway/static/root/assets/{management-settings-DODrHfBO.js → management-settings-BXeXgpGe.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-C0JdlHpy.js → media-plugins-DU8A_g9F.js} +1 -1
  44. package/dist/gateway/static/root/assets/{note-detail-panel-fPUNv1PI.js → note-detail-panel-D4KpPyvg.js} +3 -3
  45. package/dist/gateway/static/root/assets/{notes-page-I9h6l38z.js → notes-page-DvUYRsn1.js} +1 -1
  46. package/dist/gateway/static/root/assets/{page-context-capture-button-BlcjlzGF.js → page-context-capture-button-BmpkysKb.js} +1 -1
  47. package/dist/gateway/static/root/assets/{page-tabs-_eLR6cpb.js → page-tabs-BYVaSh2t.js} +1 -1
  48. package/dist/gateway/static/root/assets/{preview-open-alternatives-BfJBJ4NU.js → preview-open-alternatives-C3EhH0bN.js} +1 -1
  49. package/dist/gateway/static/root/assets/{product-open-page-RdYBwQ_V.js → product-open-page-CR5vTalE.js} +1 -1
  50. package/dist/gateway/static/root/assets/{project-detail-page-DyAKlm_h.js → project-detail-page-5e5nW6aK.js} +1 -1
  51. package/dist/gateway/static/root/assets/{projects-page-Bk51sbKy.js → projects-page-BEcT_inq.js} +1 -1
  52. package/dist/gateway/static/root/assets/{remote-access-hub-BbMbnizV.js → remote-access-hub-B1qvhjS4.js} +1 -1
  53. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-yqbX-cYN.js → runtime-tools-settings-panel-B_0CfBAT.js} +1 -1
  54. package/dist/gateway/static/root/assets/{scenes-page-L69Imde_.js → scenes-page-DUL9nosj.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schema-form-BWlMiaNv.js → schema-form-va7QWGEA.js} +1 -1
  56. package/dist/gateway/static/root/assets/{sessions-page-S-UqCz6P.js → sessions-page-vVCF7_fY.js} +1 -1
  57. package/dist/gateway/static/root/assets/settings-advanced-gate-BArcldzX.js +1 -0
  58. package/dist/gateway/static/root/assets/{settings-form-section-DqUsAh0K.js → settings-form-section-CFLiI9wl.js} +1 -1
  59. package/dist/gateway/static/root/assets/{settings-page-4eoaA_Hs.js → settings-page-uNvPtLCL.js} +1 -1
  60. package/dist/gateway/static/root/assets/{setup-status-panel-6BuwbANT.js → setup-status-panel-_w4HzIN6.js} +1 -1
  61. package/dist/gateway/static/root/assets/{share-preview-page-B-w3pIG5.js → share-preview-page-ByyeLleG.js} +1 -1
  62. package/dist/gateway/static/root/assets/{shares-settings-Bn03bnYk.js → shares-settings-BiLA03S-.js} +1 -1
  63. package/dist/gateway/static/root/assets/{skill-api-BN7zgPjv.js → skill-api-DXOq4iWa.js} +1 -1
  64. package/dist/gateway/static/root/assets/{skill-reload-api-BsBfMvch.js → skill-reload-api-D2uzVAZq.js} +1 -1
  65. package/dist/gateway/static/root/assets/{skills-page-CcYeAh5v.js → skills-page-BSnyNWx-.js} +1 -1
  66. package/dist/gateway/static/root/assets/{system-settings-panel-BV2zesop.js → system-settings-panel-BPoF82eS.js} +1 -1
  67. package/dist/gateway/static/root/assets/{task-detail-page-BqN3GUm7.js → task-detail-page-DvVPVptc.js} +1 -1
  68. package/dist/gateway/static/root/assets/{tunnel-api-Dk3SmnSL.js → tunnel-api-CA92GwfO.js} +1 -1
  69. package/dist/gateway/static/root/assets/{usage-page-DStU1Zyn.js → usage-page-B7F4u0TA.js} +1 -1
  70. package/dist/gateway/static/root/assets/{use-autosave-D3oLuZ7h.js → use-autosave-Ca0tBkcs.js} +1 -1
  71. package/dist/gateway/static/root/assets/{user-model-page-BXMZoqpb.js → user-model-page-aeTxECGB.js} +1 -1
  72. package/dist/gateway/static/root/assets/{voice-api-key-field-CzvudzG6.js → voice-api-key-field-BL6CNWHA.js} +1 -1
  73. package/dist/gateway/static/root/assets/{work-discovery-overlay-D6oUEOYn.js → work-discovery-overlay-CSc9Xv9J.js} +1 -1
  74. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CXxr4wmO.js → workflow-run-setup-panel-hho2_zza.js} +1 -1
  75. package/dist/gateway/static/root/assets/{workflows-page-D9uPt_T2.js → workflows-page-N--cEC4e.js} +1 -1
  76. package/dist/gateway/static/root/index.html +1 -1
  77. package/dist/package.js +1 -1
  78. package/dist/packages/gateway-contract/src/index.js +2 -0
  79. package/dist/packages/gateway-contract/src/mobile-user-understanding.js +140 -0
  80. package/dist/src/agent/agent-manager.js +4 -4
  81. package/dist/src/agent/background-review/run-background-review.js +1 -1
  82. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
  83. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  84. package/dist/src/agent/image/tool-model-config.js +1 -1
  85. package/dist/src/agent/service.js +2 -2
  86. package/dist/src/agent/source-context/index.d.ts +1 -0
  87. package/dist/src/agent/source-context/index.js +2 -1
  88. package/dist/src/agent/source-context/types.d.ts +2 -2
  89. package/dist/src/agent/source-context/types.js +1 -1
  90. package/dist/src/agent/source-context/user-assertion-context.d.ts +2 -0
  91. package/dist/src/agent/source-context/user-assertion-context.js +30 -0
  92. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  93. package/dist/src/agent-catalog/capabilities.js +2 -2
  94. package/dist/src/auth/credentials.js +1 -1
  95. package/dist/src/auth/oauth-provider-lock.js +1 -1
  96. package/dist/src/auth/sync-provider-auth.js +1 -1
  97. package/dist/src/automations/capabilities/drafts.js +1 -1
  98. package/dist/src/bootstrap/application-state.js +1 -1
  99. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  100. package/dist/src/capabilities/runtime/product.js +1 -1
  101. package/dist/src/chat-commands/agent-edit.js +1 -1
  102. package/dist/src/chat-commands/builtins/config.js +1 -1
  103. package/dist/src/cli/commands/agent.js +1 -1
  104. package/dist/src/cli/commands/agents.js +1 -1
  105. package/dist/src/cli/commands/models.js +1 -1
  106. package/dist/src/cli/commands/onboard/model.js +2 -2
  107. package/dist/src/cli/index.js +1 -1
  108. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  109. package/dist/src/config/index.js +4 -4
  110. package/dist/src/config/loader.js +2 -2
  111. package/dist/src/config/models-json.js +1 -1
  112. package/dist/src/config/schema.js +1 -1
  113. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  114. package/dist/src/gateway/agents-admin.js +2 -2
  115. package/dist/src/gateway/file-path-classifier.js +1 -1
  116. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  117. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  118. package/dist/src/gateway/hono/routes/models.js +1 -1
  119. package/dist/src/gateway/hono/routes/notes.js +2 -2
  120. package/dist/src/gateway/hono/routes/projects.js +2 -2
  121. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +2 -2
  122. package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
  123. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  124. package/dist/src/gateway/hono/routes/user-model.js +202 -0
  125. package/dist/src/gateway/image-generation-setup.js +2 -2
  126. package/dist/src/gateway/lock.js +1 -1
  127. package/dist/src/gateway/run-loop.js +1 -1
  128. package/dist/src/gateway/security/gateway-scopes.js +3 -0
  129. package/dist/src/gateway/service/session-input-coordinator.js +1 -1
  130. package/dist/src/gateway/service.js +8 -3
  131. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  132. package/dist/src/local-apps/service.js +1 -1
  133. package/dist/src/providers/model-catalog-persistence.js +1 -1
  134. package/dist/src/tasks/capabilities/read.js +2 -2
  135. package/dist/src/tui/backends/embedded-backend.js +3 -3
  136. package/dist/src/tui/tui-commands.js +1 -1
  137. package/dist/src/tui/tui-startup-resources.js +1 -1
  138. package/dist/src/tui/tui.js +1 -1
  139. package/dist/src/user-model/goals.d.ts +1 -1
  140. package/dist/src/user-model/goals.js +2 -1
  141. package/dist/src/voice/realtime/persona-context.js +1 -1
  142. package/package.json +3 -3
  143. package/dist/gateway/static/root/assets/settings-advanced-gate-Q52AAHh_.js +0 -1
@@ -116,6 +116,19 @@ const RULE_STATUSES = new Set([
116
116
  "disabled",
117
117
  "archived"
118
118
  ]);
119
+ const MOBILE_PROFILE_PREDICATES = new Set([
120
+ "identity.call_name",
121
+ "identity.role",
122
+ "identity.pronouns",
123
+ "preference.timezone",
124
+ "preference.locale"
125
+ ]);
126
+ const MOBILE_ASSERTION_FILTERS = new Set([
127
+ "all",
128
+ "explicit",
129
+ "learned",
130
+ "review"
131
+ ]);
119
132
  function assertionView(assertion, sources = listUserAssertionSources([assertion.id]).get(assertion.id) ?? []) {
120
133
  const slot = getAssertionSlot(assertion.slotId);
121
134
  if (!slot) throw new Error(`Assertion slot not found: ${assertion.slotId}`);
@@ -131,6 +144,70 @@ function assertionView(assertion, sources = listUserAssertionSources([assertion.
131
144
  })
132
145
  };
133
146
  }
147
+ function mobileAssertionView(assertion, sources = listUserAssertionSources([assertion.id]).get(assertion.id) ?? []) {
148
+ const view = assertionView(assertion, sources);
149
+ return {
150
+ id: view.id,
151
+ predicate: view.predicate,
152
+ statement: view.statement,
153
+ kind: view.kind,
154
+ status: view.status,
155
+ authority: view.authority,
156
+ usable: view.usable,
157
+ confidence: view.confidence,
158
+ volatility: view.volatility,
159
+ layer: view.layer,
160
+ independentSourceCount: view.independentSourceCount,
161
+ observedAt: view.observedAt,
162
+ recordedAt: view.recordedAt,
163
+ ...view.validTo === void 0 ? {} : { validTo: view.validTo },
164
+ scope: view.scope,
165
+ sources: view.sources
166
+ };
167
+ }
168
+ function isMobileAssertion(item, filter) {
169
+ if (item.scope.type !== "global" || MOBILE_PROFILE_PREDICATES.has(item.predicate)) return false;
170
+ if (filter === "review") return item.status === "needs_review" || item.status === "conflicted";
171
+ if (!item.usable) return false;
172
+ if (filter === "explicit") return item.authority === "user_explicit";
173
+ if (filter === "learned") return item.authority !== "user_explicit";
174
+ return true;
175
+ }
176
+ function normalizeMobileSearch(value, maxLength) {
177
+ const normalized = (value ?? "").normalize("NFKC").trim().toLocaleLowerCase();
178
+ return maxLength === void 0 ? normalized : normalized.slice(0, maxLength);
179
+ }
180
+ function matchesMobileSearch(item, query) {
181
+ if (!query) return true;
182
+ const statusAliases = item.status === "needs_review" || item.status === "conflicted" ? "needs review review 待确认 需要确认" : item.status;
183
+ const authorityAliases = item.authority === "user_explicit" ? "explicit user said 你明确说过 用户明确" : "learned inferred 逐渐学到 系统推断";
184
+ return normalizeMobileSearch([
185
+ item.statement,
186
+ item.predicate,
187
+ item.kind,
188
+ statusAliases,
189
+ authorityAliases,
190
+ item.scope.type,
191
+ item.scope.id ?? "",
192
+ ...item.sources.flatMap((source) => [
193
+ source.label ?? "",
194
+ source.kind,
195
+ source.category ?? ""
196
+ ])
197
+ ].join(" ")).includes(query);
198
+ }
199
+ function encodeMobileCursor(item) {
200
+ return Buffer.from(JSON.stringify([item.recordedAt, item.id])).toString("base64url");
201
+ }
202
+ function decodeMobileCursor(value) {
203
+ if (!value) return void 0;
204
+ try {
205
+ const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
206
+ return Array.isArray(parsed) && typeof parsed[0] === "number" && typeof parsed[1] === "string" ? [parsed[0], parsed[1]] : void 0;
207
+ } catch {
208
+ return;
209
+ }
210
+ }
134
211
  function registerUserModelRoutes(authenticated, deps) {
135
212
  const write = deps.strictRateLimitMiddleware;
136
213
  authenticated.get("/api/user-model", (c) => {
@@ -184,6 +261,78 @@ function registerUserModelRoutes(authenticated, deps) {
184
261
  }
185
262
  });
186
263
  });
264
+ authenticated.get("/api/user-model/mobile-summary", (c) => {
265
+ const rawAssertions = listUserAssertions({
266
+ statuses: [
267
+ "active",
268
+ "candidate",
269
+ "needs_review",
270
+ "conflicted",
271
+ "stale"
272
+ ],
273
+ limit: 2e3
274
+ });
275
+ const sourceMap = listUserAssertionSources(rawAssertions.map((item) => item.id));
276
+ const items = rawAssertions.map((item) => mobileAssertionView(item, sourceMap.get(item.id) ?? []));
277
+ const visible = items.filter((item) => isMobileAssertion(item, "all"));
278
+ const review = items.filter((item) => isMobileAssertion(item, "review"));
279
+ const profile = getUserProfileSnapshot();
280
+ const goals = listUserGoals();
281
+ const now = Date.now();
282
+ const primary = listPriorityWindows().filter((item) => item.status === "active" && item.rank === "primary" && item.validTo >= now).sort((left, right) => (right.declaredImportance ?? right.urgency) - (left.declaredImportance ?? left.urgency))[0];
283
+ const primaryGoal = primary?.targetType === "goal" ? goals.find((goal) => goal.id === primary.targetId) : void 0;
284
+ const primaryTitle = primaryGoal?.title ?? (primary && !/^[0-9a-f]{8}-[0-9a-f-]{20,}$/i.test(primary.targetId) ? primary.targetId : void 0);
285
+ const mobileGoals = goals.filter((goal) => goal.status === "active" || goal.status === "paused" || goal.status === "proposed").sort((left, right) => {
286
+ if (left.id === primaryGoal?.id) return -1;
287
+ if (right.id === primaryGoal?.id) return 1;
288
+ if (left.status === "active" && right.status !== "active") return -1;
289
+ if (right.status === "active" && left.status !== "active") return 1;
290
+ return (left.targetAt ?? Number.MAX_SAFE_INTEGER) - (right.targetAt ?? Number.MAX_SAFE_INTEGER) || right.updatedAt - left.updatedAt;
291
+ }).slice(0, 5).map((goal) => ({
292
+ id: goal.id,
293
+ title: goal.title,
294
+ desiredOutcome: goal.desiredOutcome,
295
+ status: goal.status,
296
+ ...goal.targetAt === void 0 ? {} : { targetAt: goal.targetAt },
297
+ updatedAt: goal.updatedAt,
298
+ isPrimary: goal.id === primaryGoal?.id
299
+ }));
300
+ const result = {
301
+ profile: {
302
+ callName: profile.callName ?? "",
303
+ role: profile.role ?? "",
304
+ pronouns: profile.pronouns ?? "",
305
+ timezone: profile.timezone ?? "",
306
+ locale: profile.locale ?? ""
307
+ },
308
+ suggestedCallName: profile.callName || machineCallName(),
309
+ counts: {
310
+ total: visible.length,
311
+ explicit: visible.filter((item) => item.authority === "user_explicit").length,
312
+ learned: visible.filter((item) => item.authority !== "user_explicit").length,
313
+ review: review.length,
314
+ workMemory: listKnowledgeItems({
315
+ statuses: ["active"],
316
+ recordClass: "memory",
317
+ limit: 2e3
318
+ }).length
319
+ },
320
+ ...primary && primaryTitle ? { primaryFocus: {
321
+ id: primary.id,
322
+ title: primaryTitle,
323
+ ...primaryGoal?.desiredOutcome ? { desiredOutcome: primaryGoal.desiredOutcome } : {},
324
+ validTo: primary.validTo
325
+ } } : {},
326
+ goals: mobileGoals,
327
+ recent: [...visible].sort((left, right) => right.recordedAt - left.recordedAt).slice(0, 3),
328
+ rules: listCollaborationRules().filter((rule) => rule.status === "active").slice(0, 3).map((rule) => ({
329
+ id: rule.id,
330
+ statement: rule.statement,
331
+ category: rule.category
332
+ }))
333
+ };
334
+ return c.json(result);
335
+ });
187
336
  authenticated.patch("/api/user-model/profile", write, async (c) => {
188
337
  const input = await body(c);
189
338
  if (!input) return c.json({ error: "A profile patch is required" }, 400);
@@ -224,6 +373,34 @@ function registerUserModelRoutes(authenticated, deps) {
224
373
  }
225
374
  });
226
375
  authenticated.get("/api/user-model/assertions", (c) => {
376
+ if (c.req.query("view") === "mobile") {
377
+ const filter = c.req.query("filter") ?? "all";
378
+ if (!MOBILE_ASSERTION_FILTERS.has(filter)) return c.json({ error: "Invalid mobile assertion filter" }, 400);
379
+ const requestedLimit = Number(c.req.query("limit") ?? 20);
380
+ const limit = Number.isFinite(requestedLimit) ? Math.max(1, Math.min(50, Math.trunc(requestedLimit))) : 20;
381
+ const query = normalizeMobileSearch(c.req.query("q"), 100);
382
+ const cursorValue = c.req.query("cursor");
383
+ const cursor = decodeMobileCursor(cursorValue);
384
+ if (cursorValue && !cursor) return c.json({ error: "Invalid cursor" }, 400);
385
+ const assertions = listUserAssertions({
386
+ statuses: [
387
+ "active",
388
+ "candidate",
389
+ "needs_review",
390
+ "conflicted",
391
+ "stale"
392
+ ],
393
+ limit: 2e3
394
+ });
395
+ const sourceMap = listUserAssertionSources(assertions.map((item) => item.id));
396
+ const filtered = assertions.map((item) => mobileAssertionView(item, sourceMap.get(item.id) ?? [])).filter((item) => isMobileAssertion(item, filter)).filter((item) => matchesMobileSearch(item, query)).sort((left, right) => right.recordedAt - left.recordedAt || right.id.localeCompare(left.id)).filter((item) => !cursor || item.recordedAt < cursor[0] || item.recordedAt === cursor[0] && item.id.localeCompare(cursor[1]) < 0);
397
+ const items = filtered.slice(0, limit);
398
+ const result = {
399
+ items,
400
+ ...filtered.length > limit && items.length ? { nextCursor: encodeMobileCursor(items[items.length - 1]) } : {}
401
+ };
402
+ return c.json(result);
403
+ }
227
404
  const requested = c.req.query("status")?.split(",").filter(Boolean);
228
405
  if (requested?.some((status) => !ASSERTION_STATUSES.has(status))) return c.json({ error: "Invalid assertion status" }, 400);
229
406
  const assertions = listUserAssertions({
@@ -363,6 +540,31 @@ function registerUserModelRoutes(authenticated, deps) {
363
540
  const goal = setUserGoalStatus(c.req.param("id"), status);
364
541
  return goal ? c.json({ goal }) : c.json({ error: "Goal not found" }, 404);
365
542
  });
543
+ authenticated.patch("/api/user-model/goals/:id", write, async (c) => {
544
+ const input = await body(c);
545
+ const current = listUserGoals().find((goal) => goal.id === c.req.param("id"));
546
+ if (!current) return c.json({ error: "Goal not found" }, 404);
547
+ if (!input) return c.json({ error: "A goal patch is required" }, 400);
548
+ const title = Object.hasOwn(input, "title") ? input.title : current.title;
549
+ const desiredOutcome = Object.hasOwn(input, "desiredOutcome") ? input.desiredOutcome : current.desiredOutcome;
550
+ const rawTargetAt = Object.hasOwn(input, "targetAt") ? input.targetAt : current.targetAt;
551
+ const status = Object.hasOwn(input, "status") ? input.status : current.status;
552
+ if (typeof title !== "string" || typeof desiredOutcome !== "string" || rawTargetAt !== void 0 && rawTargetAt !== null && typeof rawTargetAt !== "number" || typeof status !== "string" || !GOAL_STATUSES.has(status)) return c.json({ error: "Goal patch fields have invalid types" }, 400);
553
+ const targetAt = typeof rawTargetAt === "number" ? rawTargetAt : rawTargetAt === null ? null : void 0;
554
+ try {
555
+ const goal = runSqliteWriteTransaction(() => {
556
+ const updated = updateUserGoal(current.id, {
557
+ title,
558
+ desiredOutcome,
559
+ ...targetAt === void 0 ? {} : { targetAt }
560
+ });
561
+ return status === current.status ? updated : setUserGoalStatus(current.id, status);
562
+ });
563
+ return c.json({ goal });
564
+ } catch (error) {
565
+ return c.json({ error: errorMessage(error) }, 400);
566
+ }
567
+ });
366
568
  authenticated.get("/api/user-model/rules", (c) => c.json({ rules: listCollaborationRules() }));
367
569
  authenticated.post("/api/user-model/rules", write, async (c) => {
368
570
  const input = await body(c);
@@ -1,11 +1,11 @@
1
1
  import { normalizeAgentId } from "../agent-catalog/id.js";
2
2
  import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
3
- import { ConfigSchema, init_schema } from "../config/schema.js";
4
3
  import { init_agent_scope } from "../agent/agent-scope.js";
4
+ import { AgentCatalogService } from "../agent-catalog/service.js";
5
+ import { ConfigSchema, init_schema } from "../config/schema.js";
5
6
  import { resolveEffectiveAgentConfigForAgent } from "../config/agent-profile.js";
6
7
  import { fetchWithTimeoutGuarded } from "../media-shared/http/provider-http.js";
7
8
  import "../media-shared/http/index.js";
8
- import { AgentCatalogService } from "../agent-catalog/service.js";
9
9
  import { getImageGenerationProvider, listImageGenerationProvidersSummary } from "../agent/image/generation/provider-registry.js";
10
10
  //#region src/gateway/image-generation-setup.ts
11
11
  init_repository();
@@ -1,8 +1,8 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
3
  import { createHash } from "node:crypto";
4
- import net from "node:net";
5
4
  import fs$1 from "node:fs/promises";
5
+ import net from "node:net";
6
6
  import { homedir } from "os";
7
7
  //#region src/gateway/lock.ts
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  import { acquireGatewayLock } from "./lock.js";
2
2
  import { loadConfig } from "../config/loader.js";
3
- import { runBootstrapMigrationsSync } from "../migrations/runner.js";
4
3
  import "../config/index.js";
4
+ import { runBootstrapMigrationsSync } from "../migrations/runner.js";
5
5
  import { isRestartEnabled } from "../config/commands.flags.js";
6
6
  import { restartGatewayProcessWithFreshPid } from "./respawn.js";
7
7
  import { consumeGatewayRestartIntentSync, consumeGatewaySigusr1RestartAuthorization, isGatewaySigusr1RestartExternallyAllowed, resetGatewayRestartStateForInProcessRestart, scheduleGatewaySigusr1Restart, setGatewaySigusr1RestartPolicy } from "../infra/restart.js";
@@ -35,6 +35,9 @@ function requiredGatewayScope(method, path) {
35
35
  if (path === "/api/voice/selection" || path === "/api/voice/catalog/refresh") return "voice.configure";
36
36
  if (path.startsWith("/api/voice") || path.startsWith("/api/media") || path.startsWith("/api/clarifications")) return "sessions.write";
37
37
  if (path.startsWith("/api/commands") || path.startsWith("/api/skills")) return methodScope(method, "agents.read", "gateway.admin");
38
+ if (path === "/api/user-model/refresh" || path.startsWith("/api/user-model/refresh/")) return "gateway.admin";
39
+ if (path === "/api/user-model" || path.startsWith("/api/user-model/")) return methodScope(method, "workspace.read", "workspace.write");
40
+ if (path === "/api/knowledge-memory" || path.startsWith("/api/knowledge-memory/")) return methodScope(method, "workspace.read", "workspace.write");
38
41
  if (path === "/api/discussions" || path.startsWith("/api/discussions/") || path === "/api/discussion-capture/settings" || path.startsWith("/api/workspace") || path.startsWith("/api/files") || path.startsWith("/api/projects") || path.startsWith("/api/notes") || path.startsWith("/api/shares")) return methodScope(method, "workspace.read", "workspace.write");
39
42
  return "gateway.admin";
40
43
  }
@@ -26,7 +26,7 @@ function sameAppContext(input, existing) {
26
26
  return isDeepStrictEqual(identity(input.sourceContexts), identity(existing.contextSnapshots));
27
27
  }
28
28
  function contextRefsMatchFrozenSnapshot(requested, frozen) {
29
- const editable = frozen?.filter((ref) => ref.kind === "note" || ref.kind === "task" || ref.kind === "file" || ref.kind === "session" || ref.kind === "browser_tab" || ref.kind === "mcp_resource") ?? [];
29
+ const editable = frozen?.filter((ref) => ref.kind === "note" || ref.kind === "task" || ref.kind === "file" || ref.kind === "session" || ref.kind === "browser_tab" || ref.kind === "mcp_resource" || ref.kind === "user_assertion") ?? [];
30
30
  if (requested.length !== editable.length) return false;
31
31
  return requested.every((ref, index) => {
32
32
  const snapshot = editable[index];
@@ -16,14 +16,14 @@ import { init_session_repository, listSessionMetadata, patchSessionMetadata } fr
16
16
  import { getSessionConfig, init_config_repository } from "../storage/sqlite/config-repository.js";
17
17
  import { init_sqlite } from "../storage/sqlite/index.js";
18
18
  import { normalizeAgentId } from "../agent-catalog/id.js";
19
+ import { init_agent_scope, listAgentEntries, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
20
+ import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
19
21
  import { init_config, resolveKnowledgeReadPolicy } from "../user-context/config.js";
20
22
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
21
- import { init_agent_scope, listAgentEntries, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
22
23
  import { init_agent_session_key, resolveAgentMainConversationId } from "../routing/agent-session-key.js";
23
24
  import { init_session_key, resolveConversationId, sanitizeSegment } from "../routing/session-key.js";
24
25
  import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
25
26
  import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
26
- import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
27
27
  import { prewarmModelRegistry } from "../providers/model-registry.js";
28
28
  import { init_providers, providers_exports } from "../providers/index.js";
29
29
  import { AI_USAGE_RETENTION_MS, markStaleAiUsageEventsUnknown, pruneAiUsageEvents } from "../storage/sqlite/ai-usage-repository.js";
@@ -65,7 +65,6 @@ import { MessageBus, MessageBusShutdownError } from "../infra/bus/queue.js";
65
65
  import "../infra/bus/index.js";
66
66
  import { collectMediaUrisFromMessages, deleteMediaUris } from "../media/session-references.js";
67
67
  import { AgentService } from "../agent/service.js";
68
- import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
69
68
  import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
70
69
  import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
71
70
  import { ChannelManager } from "../channels/manager.js";
@@ -73,6 +72,7 @@ import { ChatPreviewService } from "../chat-previews/service.js";
73
72
  import "../chat-previews/index.js";
74
73
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
75
74
  import "../config/index.js";
75
+ import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
76
76
  import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
77
77
  import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
78
78
  import "../knowledge/index.js";
@@ -98,6 +98,7 @@ import { buildFileAgentContext } from "../agent/source-context/file-context.js";
98
98
  import { buildSessionAgentContext } from "../agent/source-context/session-context.js";
99
99
  import { buildMcpResourceAgentContext } from "../agent/source-context/mcp-resource-context.js";
100
100
  import { buildBrowserTabAgentContext } from "../agent/source-context/browser-tab.js";
101
+ import { buildUserAssertionAgentContext } from "../agent/source-context/user-assertion-context.js";
101
102
  import { WorkDiscoveryService } from "../work-discovery/service.js";
102
103
  import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
103
104
  import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
@@ -504,6 +505,10 @@ var GatewayService = class {
504
505
  getConfig: () => this.config,
505
506
  resolveTurnContext: async (ref, conversationId) => {
506
507
  if (ref.kind === "task") return buildTaskAgentContext(new TaskRepository().get(ref.sourceId), ref.expectedVersion);
508
+ if (ref.kind === "user_assertion") {
509
+ const metadata = await this.sessionIndex.getSessionMetadata(conversationId);
510
+ return buildUserAssertionAgentContext(ref.sourceId, ref.expectedVersion, metadata?.agentId);
511
+ }
507
512
  if (ref.kind === "file") {
508
513
  const files = getGatewayFileSpaceService(this);
509
514
  const space = await files.forContext("session", conversationId).catch(() => null);
@@ -1,7 +1,7 @@
1
1
  import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
2
+ import { AgentCatalogService } from "../agent-catalog/service.js";
2
3
  import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
3
4
  import { compareCatalogModels } from "../providers/model-catalog-ranking.js";
4
- import { AgentCatalogService } from "../agent-catalog/service.js";
5
5
  import { prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
6
6
  //#region src/gateway/xopc-cloud-capability-setup.ts
7
7
  init_repository();
@@ -5,10 +5,10 @@ import { currentOperationId, init_operation_context } from "../infra/operation-c
5
5
  import { afterSqliteCommit, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
6
6
  import { ExtensionCapabilityBindingsSchema, extensionCapabilityPermissions } from "../../packages/gateway-contract/src/extension-capabilities.js";
7
7
  import { init_src } from "../../packages/gateway-contract/src/index.js";
8
+ import { CapabilityError } from "../capabilities/runtime/errors.js";
8
9
  import { init_paths, resolveExtensionsDir } from "../config/paths.js";
9
10
  import { LocalAppStore } from "./store.js";
10
11
  import { slugifyProjectName } from "../projects/project-store.js";
11
- import { CapabilityError } from "../capabilities/runtime/errors.js";
12
12
  import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
13
13
  import { validateLocalAppCapabilityContracts } from "./capabilities/contracts.js";
14
14
  import { buildLocalAppFixGuidance } from "./fix-guidance.js";
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { init_paths_state, resolveXopcCloudCatalogCachePath } from "../config/paths-state.js";
3
- import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
4
3
  import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
4
+ import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
5
5
  import { voiceManifestSchema } from "../../packages/realtime-protocol/src/voice-catalog.js";
6
6
  import { init_voice } from "../../packages/realtime-protocol/src/voice.js";
7
7
  import { readFileSync, rmSync } from "node:fs";
@@ -2,10 +2,10 @@ import { ProductReadContracts } from "../../../packages/gateway-contract/src/cap
2
2
  import { init_src } from "../../../packages/gateway-contract/src/index.js";
3
3
  import { TaskRepository, init_task_repository } from "../task-repository.js";
4
4
  import { TaskRunRepository, init_task_run_repository } from "../task-run-repository.js";
5
- import { TaskConversationRepository } from "../task-conversation-repository.js";
6
- import { TaskReadModelProjector } from "../task-read-model-projector.js";
7
5
  import { CapabilityError } from "../../capabilities/runtime/errors.js";
8
6
  import { defineReadCapability } from "../../capabilities/runtime/dispatcher.js";
7
+ import { TaskConversationRepository } from "../task-conversation-repository.js";
8
+ import { TaskReadModelProjector } from "../task-read-model-projector.js";
9
9
  import { TaskContextRepository } from "../task-context-repository.js";
10
10
  import { TaskDependencyService } from "../task-dependency-service.js";
11
11
  import { TaskValueMetricsService } from "../task-value-metrics-service.js";
@@ -9,11 +9,12 @@ import { appendComposerInputHistory, listComposerInputHistory } from "../../stor
9
9
  import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
10
10
  import { init_sqlite } from "../../storage/sqlite/index.js";
11
11
  import { normalizeAgentId } from "../../agent-catalog/id.js";
12
- import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
13
12
  import { init_agent_scope, listAgentEntries } from "../../agent/agent-scope.js";
13
+ import { init_paths } from "../../config/paths.js";
14
+ import { AgentCatalogService } from "../../agent-catalog/service.js";
15
+ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
14
16
  import { init_agent_session_key, resolveAgentIdFromConversationId } from "../../routing/agent-session-key.js";
15
17
  import { resolveEffectiveAgentProfile } from "../../config/agent-profile.js";
16
- import { init_paths } from "../../config/paths.js";
17
18
  import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
18
19
  import { ProjectService } from "../../projects/project-service.js";
19
20
  import { inferSuggestedProjectDefaultAgentId } from "../../projects/project-agent-suggestion.js";
@@ -22,7 +23,6 @@ import { buildSessionTimeline } from "../../session/transcript-outline.js";
22
23
  import { transcriptRowsToClientHistory } from "../../session/client-history.js";
23
24
  import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
24
25
  import { evictEmbeddedSessionRunner } from "../../agent/embedded/session-runner.js";
25
- import { AgentCatalogService } from "../../agent-catalog/service.js";
26
26
  import { SessionIndex } from "../../session/manager.js";
27
27
  import "../../session/index.js";
28
28
  import { parseModelRef } from "../../agent/models/selection.js";
@@ -2,8 +2,8 @@ import { closeXopcDatabase, isXopcDatabaseOpen, openXopcDatabase } from "../stor
2
2
  import { TaskRepository } from "../tasks/task-repository.js";
3
3
  import { getSessionMetadata } from "../storage/sqlite/session-read-repository.js";
4
4
  import { init_sqlite } from "../storage/sqlite/index.js";
5
- import { init_agent_session_key, isValidAgentId, normalizeAgentId } from "../routing/agent-session-key.js";
6
5
  import { resolveConfigPath } from "../config/paths.js";
6
+ import { init_agent_session_key, isValidAgentId, normalizeAgentId } from "../routing/agent-session-key.js";
7
7
  import { init_providers, providerSupportsOAuth } from "../providers/index.js";
8
8
  import { ProjectService } from "../projects/project-service.js";
9
9
  import { isValidProjectAgentId, normalizeProjectAgentId } from "../projects/project-agent.js";
@@ -1,6 +1,6 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
- import { resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
3
2
  import { init_paths, resolveAgentProfileDir, resolveBundledSkillsDir } from "../config/paths.js";
3
+ import { resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
4
4
  import { resolveBootstrapFilesSync } from "../agent/bootstrap/bootstrap-files.js";
5
5
  import { listConnectorInstances } from "../connectors/instances.js";
6
6
  import { createSkillConfigManager, isSkillEnabled } from "../agent/skills/config.js";
@@ -1,8 +1,8 @@
1
1
  import { version } from "../../package.js";
2
2
  import { resolveStateDir, resolveXopcDatabasePath } from "../config/paths-state.js";
3
+ import { init_paths } from "../config/paths.js";
3
4
  import { init_agent_session_key, normalizeAgentId } from "../routing/agent-session-key.js";
4
5
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
5
- import { init_paths } from "../config/paths.js";
6
6
  import { getAllModels, getAllProviders, getApiKey, init_providers, isProviderConfiguredSync } from "../providers/index.js";
7
7
  import { isTerminalWorkflowRunStatus } from "../workflows/domain/run.js";
8
8
  import "../workflows/domain/index.js";
@@ -50,7 +50,7 @@ export declare function setUserGoalStatus(id: string, status: UserGoalStatus, no
50
50
  export declare function updateUserGoal(id: string, input: {
51
51
  title: string;
52
52
  desiredOutcome: string;
53
- targetAt?: number;
53
+ targetAt?: number | null;
54
54
  }, now?: number): UserGoal | undefined;
55
55
  export declare function listPriorityWindows(principalId?: string): UserPriorityWindow[];
56
56
  export declare function createPriorityWindow(input: {
@@ -65,8 +65,9 @@ function updateUserGoal(id, input, now = Date.now()) {
65
65
  db.prepare(`INSERT INTO user_goal_revisions (
66
66
  revision_id, goal_id, title, desired_outcome, created_by, change_reason, created_at
67
67
  ) VALUES (?, ?, ?, ?, 'user', 'Goal edited by user.', ?)`).run(revisionId, id, title, desiredOutcome, now);
68
+ const targetAt = input.targetAt === void 0 ? current.targetAt ?? null : input.targetAt;
68
69
  db.prepare(`UPDATE user_goals SET current_revision_id = ?, target_at = ?, updated_at = ?
69
- WHERE goal_id = ?`).run(revisionId, input.targetAt ?? current.targetAt ?? null, now, id);
70
+ WHERE goal_id = ?`).run(revisionId, targetAt, now, id);
70
71
  });
71
72
  return listUserGoals().find((goal) => goal.id === id);
72
73
  }
@@ -1,6 +1,6 @@
1
1
  import { init_agent_scope, resolveAgentProfileDir } from "../../agent/agent-scope.js";
2
- import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
2
  import { DEFAULT_IDENTITY_FILENAME, DEFAULT_SOUL_FILENAME } from "../../agent/context/workspace.js";
3
+ import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
4
4
  import { loadProfileBootstrapFiles } from "../../agent/bootstrap/load-bootstrap-files.js";
5
5
  import { join } from "node:path";
6
6
  import { statSync } from "node:fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.337",
3
+ "version": "0.0.338",
4
4
  "description": "Local-first personal AI for the one-person company, with durable context, tasks, workflows, automations, and local or cloud models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -159,11 +159,11 @@
159
159
  "vitest": "4.1.5",
160
160
  "vue": "^3.5.35",
161
161
  "@xopcai/browser-control-contract": "0.1.0",
162
+ "@xopcai/computer-control-contract": "0.1.0",
163
+ "@xopcai/endpoint-tools-client": "0.0.0",
162
164
  "@xopcai/endpoint-tools-protocol": "0.0.0",
163
165
  "@xopcai/gateway-contract": "0.0.0",
164
166
  "@xopcai/realtime-client": "0.0.0",
165
- "@xopcai/endpoint-tools-client": "0.0.0",
166
- "@xopcai/computer-control-contract": "0.1.0",
167
167
  "@xopcai/realtime-protocol": "0.0.0"
168
168
  },
169
169
  "scripts": {
@@ -1 +0,0 @@
1
- import{Cn as e}from"./index-D3OtdgCs.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};