@xopcai/xopc 0.0.205 → 0.0.207

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 (208) hide show
  1. package/README.md +7 -7
  2. package/README.zh-CN.md +7 -7
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-DJBadfSX.js → activity-store-BmpM0zwM.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Br6C32BX.js → agent-avatar-dicebear-DhK5wi6_.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-Bc3Lc-n2.js +68 -0
  8. package/dist/gateway/static/root/assets/{api-B5O7fKXa.js → api-CzaAcDOn.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-Le1vJ1OO.js → app-management-settings-panel-Dqj5G_cd.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-CZlAU60t.js → appearance-settings-Bm1uLGMi.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-BKtwU47-.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-CRzXRXPE.js → archive-plugin-CgnzBplN.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-CYAAQ6Qi.js → attachment-load-Cuybcmhn.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-page-ilGeRLDN.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-CVR5cUmS.js → binary-plugins-D6BBx6Ps.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-CFe74rWi.js → block-editor-Dk1c3Spa.js} +46 -46
  17. package/dist/gateway/static/root/assets/browser-settings-page-BCu8AZbs.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bd68yluo.js → browser-workflow-inputs-DvfIzCgV.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-B0uiDLga.js → browser-workflows-page-DZScuPlF.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-BbWQBtTe.js +7 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-BerPMp6f.js → capability-presets-api-hoA8R_J1.js} +1 -1
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BTVU46Yn.js +3 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-D2d21_XA.js → channel-recipient-api-BS8I65NT.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-BEQsC9a9.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-DRwbgtOT.js +1 -0
  26. package/dist/gateway/static/root/assets/chat-terminal-dock-BIPhWBDI.js +36 -0
  27. package/dist/gateway/static/root/assets/chat-terminal-dock-uQUnjRtf.css +1 -0
  28. package/dist/gateway/static/root/assets/{connectors-api-Bq_vUzxP.js → connectors-api-B_78jmvM.js} +1 -1
  29. package/dist/gateway/static/root/assets/connectors-page-w_3kpqbc.js +2 -0
  30. package/dist/gateway/static/root/assets/{cron-expression-DZBxmKGR.js → cron-expression-BBheaBIr.js} +1 -1
  31. package/dist/gateway/static/root/assets/{date-picker-BNHd7HT7.js → date-picker-CDwj7UrT.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-D1kJBknt.js → dependency-picker-Dnrc2qZe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-Di75oHkC.js → desktop-pet-Bj_vUjXp.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-D6tD1uym.js → desktop-pet-settings-uiCwJJk4.js} +1 -1
  35. package/dist/gateway/static/root/assets/directory-picker-path-field-D0zUQ-TO.js +1 -0
  36. package/dist/gateway/static/root/assets/{extension-debug-page-D91_S7NQ.js → extension-debug-page-_GZ4y2da.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-DHzmmr_N.js → extension-page-scR96Edg.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-settings-page-BpJNtePi.js → extension-settings-page-CILsAwxx.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-api-BAzLYTKZ.js → gateway-config-api-984O_4wM.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-VVcfd3sG.js → gateway-config-swr-D4hvsdJA.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-settings-C5-aKkTp.js → gateway-settings-aF4eQHo3.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-qAX_T2t2.js → gateway-startup-retry-Deo5-O87.js} +1 -1
  43. package/dist/gateway/static/root/assets/heartbeat-settings-D5DrFWH6.js +1 -0
  44. package/dist/gateway/static/root/assets/home-page-DiMWxngC.js +3 -0
  45. package/dist/gateway/static/root/assets/index-DzKLVgY-.js +85 -0
  46. package/dist/gateway/static/root/assets/index-wR5jX-lw.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fpNjXnJK.js → keyboard-shortcuts-settings-DGmOlNcB.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-De8vuwu1.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-DBpQIfNd.js → local-apps-page-CzS2sCxg.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-CbPVxonP.js → locale-store-C7xtkP3D.js} +1 -1
  51. package/dist/gateway/static/root/assets/logs-page-BI9stsVO.js +2 -0
  52. package/dist/gateway/static/root/assets/{management-settings-CiK7Xkvi.js → management-settings-Cpxs43JB.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-DVgpcOze.js → markdown-split-CQvFHxUa.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-view-Dl-0_9JR.js → markdown-view-BRwrSbwM.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-DMj1lW-n.js → media-plugins-Bs9MsiaM.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-Dxk5Rzj_.js +3 -0
  57. package/dist/gateway/static/root/assets/{notes-page-DvX1sTlf.js → notes-page-Dux_g6aZ.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CGafcgJ8.js +4 -0
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-DvsLigha.js → preview-open-alternatives-fvhtN4Y2.js} +1 -1
  60. package/dist/gateway/static/root/assets/{product-open-page-DbCraAI3.js → product-open-page-f_jbg-9N.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-C6mNsjYr.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-D1G6VIxR.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-CIez6X0x.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DzuUglQo.js → runtime-tools-settings-panel-zapSiJrv.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-plDnazVj.js → schema-form-CFyz8y5v.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-6irxQjHb.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-CRb0QTG2.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-BwAxX_7e.js → settings-form-section-DCiK4TIq.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-B3OiTnF9.js → settings-loading-skeleton-DFUJEv4G.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-DvIWXBvp.js → settings-page-Cnp9Bdd0.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-DThKKjLV.js → setup-status-panel-BFMGTGBO.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-CFnoGHJb.js → share-preview-page-DA8nA4cz.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CaKfvJzQ.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-BOBUcYr5.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-B38fY22S.js → skills-page-BJJACxzz.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-vLIlk1c3.js → skills-page.utils--1-vOg3V.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DRV2wljT.js → system-settings-panel-DY0lIaXY.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-Ciuwe7AG.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Bc_eRUev.js → theme-store-DoyRfkoi.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-DTu23D9J.js → use-autosave-DzIR5Lxf.js} +1 -1
  81. package/dist/gateway/static/root/assets/{user-context-page-DCwqzN03.js → user-context-page-yf18T_BZ.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-CVDMesWc.js → voice-api-key-field-B7MZS8tS.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-cyt93k0V.js → work-discovery-overlay-zyX6yxxF.js} +1 -1
  84. package/dist/gateway/static/root/assets/work-discovery-page-2e5J0sIp.js +1 -0
  85. package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cj1vPWRM.js +3 -0
  86. package/dist/gateway/static/root/assets/workflows-page-D37zWlWY.js +5 -0
  87. package/dist/gateway/static/root/assets/{working-directory-picker-modal-CYWdZUJ5.js → working-directory-picker-modal-Bm7cox3y.js} +1 -1
  88. package/dist/gateway/static/root/index.html +10 -10
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +11 -0
  91. package/dist/src/agent/agent-manager.js +36 -6
  92. package/dist/src/agent/embedded/transcript-runtime.d.ts +2 -1
  93. package/dist/src/agent/embedded/transcript-runtime.js +38 -4
  94. package/dist/src/agent/inbound/inbound-loop.d.ts +1 -1
  95. package/dist/src/agent/memory/compaction-ledger.d.ts +11 -0
  96. package/dist/src/agent/memory/compaction-ledger.js +108 -0
  97. package/dist/src/agent/memory/compaction-serializer.d.ts +2 -0
  98. package/dist/src/agent/memory/compaction-serializer.js +52 -0
  99. package/dist/src/agent/memory/compaction-source-planner.d.ts +20 -0
  100. package/dist/src/agent/memory/compaction-source-planner.js +67 -0
  101. package/dist/src/agent/memory/compaction.d.ts +11 -5
  102. package/dist/src/agent/memory/compaction.js +245 -153
  103. package/dist/src/agent/prompt/sections/behavior.js +1 -1
  104. package/dist/src/agent/prompt/sections/memory-skills.js +4 -2
  105. package/dist/src/agent/prompt/sections/tooling.js +2 -0
  106. package/dist/src/agent/service.d.ts +4 -1
  107. package/dist/src/agent/service.js +12 -0
  108. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  109. package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
  110. package/dist/src/agent/tools/factory.js +5 -0
  111. package/dist/src/agent/tools/index.d.ts +1 -0
  112. package/dist/src/agent/tools/index.js +2 -1
  113. package/dist/src/agent/tools/session-recall-tool.d.ts +7 -0
  114. package/dist/src/agent/tools/session-recall-tool.js +82 -0
  115. package/dist/src/agent/tools/xopc-use-tool.js +6 -2
  116. package/dist/src/automations/api/routes.js +8 -0
  117. package/dist/src/automations/domain/index.js +2 -2
  118. package/dist/src/automations/domain/types.d.ts +17 -12
  119. package/dist/src/automations/domain/validation.d.ts +30 -32
  120. package/dist/src/automations/domain/validation.js +8 -10
  121. package/dist/src/automations/draft/automation-draft-prompt.js +9 -5
  122. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -8
  123. package/dist/src/automations/draft/automation-draft-validator.js +3 -3
  124. package/dist/src/automations/index.js +2 -2
  125. package/dist/src/automations/service/action-executor.js +13 -4
  126. package/dist/src/automations/service/automation-service.d.ts +5 -1
  127. package/dist/src/automations/service/automation-service.js +19 -12
  128. package/dist/src/automations/storage/automation-repository.js +8 -4
  129. package/dist/src/automations/storage/automation-run-repository.d.ts +5 -0
  130. package/dist/src/automations/storage/automation-run-repository.js +24 -8
  131. package/dist/src/automations/storage/index.js +2 -2
  132. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  133. package/dist/src/config/agent-profile.js +1 -1
  134. package/dist/src/config/schema.d.ts +1 -0
  135. package/dist/src/gateway/agents-admin.js +1 -1
  136. package/dist/src/gateway/automation-agent-session.d.ts +4 -0
  137. package/dist/src/gateway/automation-agent-session.js +40 -0
  138. package/dist/src/gateway/dreaming-automation-reconciler.js +3 -2
  139. package/dist/src/gateway/heartbeat/service.js +1 -1
  140. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  141. package/dist/src/gateway/hono/routes/commands-skills.js +36 -2
  142. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  143. package/dist/src/gateway/service/marketplace-service.d.ts +4 -1
  144. package/dist/src/gateway/service/marketplace-service.js +9 -0
  145. package/dist/src/gateway/service/run-gateway-agent.js +3 -3
  146. package/dist/src/gateway/service.js +19 -2
  147. package/dist/src/heartbeat/index.js +1 -1
  148. package/dist/src/mobile/notification-service.js +7 -4
  149. package/dist/src/session/compaction-types.d.ts +30 -0
  150. package/dist/src/session/compaction-types.js +35 -0
  151. package/dist/src/session/manager.d.ts +3 -0
  152. package/dist/src/session/session-context-for-llm.d.ts +4 -2
  153. package/dist/src/session/session-context-for-llm.js +2 -1
  154. package/dist/src/session/store.d.ts +10 -1
  155. package/dist/src/session/store.js +55 -23
  156. package/dist/src/session/types.d.ts +3 -2
  157. package/dist/src/storage/sqlite/index.d.ts +1 -1
  158. package/dist/src/storage/sqlite/index.js +2 -2
  159. package/dist/src/storage/sqlite/migrations/121_automation_inbox.sql +24 -0
  160. package/dist/src/storage/sqlite/migrations/122_automation_session_projects.sql +18 -0
  161. package/dist/src/storage/sqlite/migrations/123_remove_v2_compaction_boundaries.sql +25 -0
  162. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  163. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  164. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  165. package/dist/src/storage/sqlite/schema.js +1 -1
  166. package/dist/src/storage/sqlite/transcript-repository.d.ts +24 -1
  167. package/dist/src/storage/sqlite/transcript-repository.js +78 -29
  168. package/dist/src/user-context/config.d.ts +4 -0
  169. package/dist/src/user-context/config.js +2 -0
  170. package/package.json +4 -3
  171. package/skills/THIRD_PARTY_NOTICES.md +1 -1
  172. package/skills/engineering/define-task/SKILL.md +48 -0
  173. package/skills/engineering/define-task/references/task-contract-rubric.md +15 -0
  174. package/dist/gateway/static/root/assets/agents-DnFIy8Ye.js +0 -68
  175. package/dist/gateway/static/root/assets/apps-page-CONlVc-f.js +0 -1
  176. package/dist/gateway/static/root/assets/automations-page-DuG69tIj.js +0 -6
  177. package/dist/gateway/static/root/assets/browser-settings-page-Cvt-8fqE.js +0 -8
  178. package/dist/gateway/static/root/assets/capabilities-settings-panel-yk3QkGBP.js +0 -7
  179. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJjVOCJY.js +0 -3
  180. package/dist/gateway/static/root/assets/channels-settings-CaNnYUQo.js +0 -1
  181. package/dist/gateway/static/root/assets/channels-status-swr-CZ5P9jbB.js +0 -1
  182. package/dist/gateway/static/root/assets/connectors-page-DTpCnOsQ.js +0 -2
  183. package/dist/gateway/static/root/assets/directory-picker-path-field-Ly0TUflq.js +0 -1
  184. package/dist/gateway/static/root/assets/heartbeat-settings-CMZr1_Op.js +0 -1
  185. package/dist/gateway/static/root/assets/home-page-CBG9Bk-1.js +0 -3
  186. package/dist/gateway/static/root/assets/index-BBw9QL0p.js +0 -85
  187. package/dist/gateway/static/root/assets/index-Dm-cvIpl.css +0 -2
  188. package/dist/gateway/static/root/assets/local-app-workbench-page-Bi_0Sknt.js +0 -2
  189. package/dist/gateway/static/root/assets/logs-page-BmXcJCKz.js +0 -2
  190. package/dist/gateway/static/root/assets/messages-9zCa8KkW.js +0 -3
  191. package/dist/gateway/static/root/assets/notes-workbench-CMyosgjY.js +0 -4
  192. package/dist/gateway/static/root/assets/project-detail-page-DkS-kbpj.js +0 -1
  193. package/dist/gateway/static/root/assets/projects-page-B3NxP6S4.js +0 -1
  194. package/dist/gateway/static/root/assets/remote-access-hub-DwhrMhjl.js +0 -1
  195. package/dist/gateway/static/root/assets/sessions-page-BOfXXmBL.js +0 -1
  196. package/dist/gateway/static/root/assets/settings-advanced-gate-sPrZfZVR.js +0 -1
  197. package/dist/gateway/static/root/assets/shares-settings-Dvl13Udt.js +0 -1
  198. package/dist/gateway/static/root/assets/skill-reload-api-D9elkZOz.js +0 -1
  199. package/dist/gateway/static/root/assets/task-detail-page-Xd8PlB24.js +0 -1
  200. package/dist/gateway/static/root/assets/work-discovery-page--DTi90d5.js +0 -1
  201. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DrdcfX_N.js +0 -3
  202. package/dist/gateway/static/root/assets/workflows-page-DXyButkm.js +0 -5
  203. package/dist/src/agent/memory/compaction-planner.d.ts +0 -16
  204. package/dist/src/agent/memory/compaction-planner.js +0 -168
  205. package/dist/src/agent/memory/summary-generator.d.ts +0 -46
  206. package/dist/src/agent/memory/summary-generator.js +0 -229
  207. package/skills/engineering/define-goal/SKILL.md +0 -41
  208. package/skills/engineering/define-goal/references/objective-rubric.md +0 -12
@@ -56,6 +56,7 @@ export interface AgentSkillAvailabilityEntry extends SkillCatalogEntry {
56
56
  }
57
57
  export interface AgentSkillAvailabilityPayload {
58
58
  agentId: string;
59
+ workspacePath: string;
59
60
  version: string;
60
61
  loadedAt: number;
61
62
  diagnostics: SkillDiagnostic[];
@@ -65,6 +66,12 @@ export interface AgentSkillAvailabilityPayload {
65
66
  effectiveAllowlist?: string[];
66
67
  skills: AgentSkillAvailabilityEntry[];
67
68
  }
69
+ export interface WorkspaceTrustState {
70
+ workspacePath: string;
71
+ required: boolean;
72
+ decision: boolean | null;
73
+ trusted: boolean;
74
+ }
68
75
  export interface AgentManagerConfig {
69
76
  workspace: string;
70
77
  model?: string;
@@ -223,7 +230,11 @@ export declare class AgentManager implements AgentInstanceGateway {
223
230
  private skillCatalogEntryFromSkill;
224
231
  getSkillCatalog(): SkillCatalogEntry[];
225
232
  getSkillCatalogSnapshot(): SkillCatalogSnapshot;
233
+ private buildAgentSkillAvailability;
226
234
  getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload;
235
+ getSessionSkillAvailability(sessionKey: string): AgentSkillAvailabilityPayload;
236
+ getSessionWorkspaceTrust(sessionKey: string): WorkspaceTrustState;
237
+ setSessionWorkspaceTrust(sessionKey: string, trusted: boolean): WorkspaceTrustState;
227
238
  /**
228
239
  * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.
229
240
  */
@@ -503,14 +503,13 @@ var AgentManager = class {
503
503
  status: rt.skillManager.getStatus()
504
504
  };
505
505
  }
506
- getAgentSkillAvailability(agentId) {
506
+ buildAgentSkillAvailability(profile, workspaceDir) {
507
507
  const cfg = this.config.config;
508
- const entry = Array.isArray(cfg.agents?.list) ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === agentId.toLowerCase()) : void 0;
509
- const profile = resolveEffectiveAgentProfile(cfg, agentId);
510
- const rt = this.workspaceRuntimes.getOrCreate(profile.resolvedWorkspacePath, profile.agentId);
508
+ const entry = Array.isArray(cfg.agents?.list) ? cfg.agents.list.find((a) => a && a.enabled !== false && a.id.toLowerCase() === profile.agentId.toLowerCase()) : void 0;
509
+ const rt = this.workspaceRuntimes.getOrCreate(workspaceDir, profile.agentId);
511
510
  const skillsConfig = createSkillConfigManager(resolveStateDir()).load();
512
511
  const lock = loadSkillsLock();
513
- const workspaceLock = loadSkillsLock(resolveWorkspaceSkillsLockPath(profile.resolvedWorkspacePath));
512
+ const workspaceLock = loadSkillsLock(resolveWorkspaceSkillsLockPath(workspaceDir));
514
513
  const allow = profile.skillsAllowlist === void 0 ? void 0 : new Set(profile.skillsAllowlist.map((s) => s.toLowerCase()));
515
514
  const skills = rt.skillManager.getSkills().map((s) => {
516
515
  let unavailableReason = null;
@@ -519,13 +518,14 @@ var AgentManager = class {
519
518
  else if (!isSkillEnabled(s, skillsConfig)) unavailableReason = "requirements-unmet";
520
519
  else if (allow !== void 0 && !allow.has(s.name.toLowerCase())) unavailableReason = "agent-denied";
521
520
  return {
522
- ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock, workspaceLock, profile.resolvedWorkspacePath),
521
+ ...this.skillCatalogEntryFromSkill(s, skillsConfig, lock, workspaceLock, workspaceDir),
523
522
  availableForCurrentAgent: unavailableReason === null,
524
523
  unavailableReason
525
524
  };
526
525
  });
527
526
  return {
528
527
  agentId: profile.agentId,
528
+ workspacePath: workspaceDir,
529
529
  version: rt.skillManager.getVersion(),
530
530
  loadedAt: rt.skillManager.getLoadedAt(),
531
531
  diagnostics: rt.skillManager.getDiagnostics(),
@@ -535,6 +535,36 @@ var AgentManager = class {
535
535
  skills
536
536
  };
537
537
  }
538
+ getAgentSkillAvailability(agentId) {
539
+ const profile = resolveEffectiveAgentProfile(this.config.config, agentId);
540
+ return this.buildAgentSkillAvailability(profile, profile.resolvedWorkspacePath);
541
+ }
542
+ getSessionSkillAvailability(sessionKey) {
543
+ const profile = resolveEffectiveAgentProfileForSession(this.config.config, sessionKey);
544
+ return this.buildAgentSkillAvailability(profile, this.getResolvedWorkspaceForSession(sessionKey));
545
+ }
546
+ getSessionWorkspaceTrust(sessionKey) {
547
+ const workspacePath = this.getResolvedWorkspaceForSession(sessionKey);
548
+ const required = hasTrustRequiringProjectResources(workspacePath);
549
+ return {
550
+ workspacePath,
551
+ required,
552
+ decision: required ? this.projectTrustStore.get(workspacePath) : null,
553
+ trusted: required && this.isProjectWorkspaceTrusted(workspacePath)
554
+ };
555
+ }
556
+ setSessionWorkspaceTrust(sessionKey, trusted) {
557
+ const workspacePath = this.getResolvedWorkspaceForSession(sessionKey);
558
+ if (!hasTrustRequiringProjectResources(workspacePath)) return {
559
+ workspacePath,
560
+ required: false,
561
+ decision: null,
562
+ trusted: false
563
+ };
564
+ this.projectTrustStore.set(workspacePath, trusted);
565
+ this.refreshSkillsAfterTrustChange();
566
+ return this.getSessionWorkspaceTrust(sessionKey);
567
+ }
538
568
  /**
539
569
  * After ~/.xopc/skills.json changes (enable/disable), refresh `<available_skills>` on active agents.
540
570
  */
@@ -21,6 +21,7 @@ export declare class InMemoryTranscriptRuntime implements EmbeddedTranscriptRunt
21
21
  readonly sessionId: string;
22
22
  private readonly sessionManager;
23
23
  private readonly compactor;
24
+ private readonly compactionRows;
24
25
  private baselineEntryCount;
25
26
  constructor(params: {
26
27
  runtimeId: string;
@@ -31,5 +32,5 @@ export declare class InMemoryTranscriptRuntime implements EmbeddedTranscriptRunt
31
32
  loadMessages(): Promise<AgentMessage[]>;
32
33
  captureBaseline(): void;
33
34
  loadConversationMessages(): AgentMessage[];
34
- compact(messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
35
+ compact(_messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
35
36
  }
@@ -24,6 +24,7 @@ var InMemoryTranscriptRuntime = class {
24
24
  sessionId;
25
25
  sessionManager;
26
26
  compactor = new SessionCompactor();
27
+ compactionRows = /* @__PURE__ */ new Map();
27
28
  baselineEntryCount = 0;
28
29
  constructor(params) {
29
30
  this.runtimeId = params.runtimeId;
@@ -46,10 +47,27 @@ var InMemoryTranscriptRuntime = class {
46
47
  loadConversationMessages() {
47
48
  return this.sessionManager.getBranch().slice(this.baselineEntryCount).flatMap((entry) => entry.type === "message" ? [entry.message] : []);
48
49
  }
49
- async compact(messages, model, instructions, force, options) {
50
- const result = await this.compactor.compact(messages, model, instructions, force, options);
51
- if (!result.compacted) return result;
52
- const firstKept = this.sessionManager.getBranch().filter((entry) => entry.type === "message")[result.firstKeptIndex];
50
+ async compact(_messages, model, instructions, force, options) {
51
+ const branch = this.sessionManager.getBranch();
52
+ const sources = branch.flatMap((entry, index) => {
53
+ const compaction = this.compactionRows.get(entry.id);
54
+ if (compaction) return [{
55
+ entryId: entry.id,
56
+ seq: index + 1,
57
+ createdAt: Date.now(),
58
+ row: compaction
59
+ }];
60
+ if (entry.type !== "message") return [];
61
+ return [{
62
+ entryId: entry.id,
63
+ seq: index + 1,
64
+ createdAt: Date.now(),
65
+ row: entry.message
66
+ }];
67
+ });
68
+ const result = await this.compactor.compact(sources, model, instructions, force, options);
69
+ if (!result.compacted || !result.handover || !result.audit) return result;
70
+ const firstKept = branch.filter((entry) => entry.type === "message")[result.firstKeptIndex];
53
71
  if (!firstKept) return {
54
72
  ...result,
55
73
  compacted: false
@@ -59,6 +77,22 @@ var InMemoryTranscriptRuntime = class {
59
77
  summaryModelRef: result.summaryModelRef,
60
78
  qualityAudit: result.qualityAudit
61
79
  });
80
+ const boundary = this.sessionManager.getBranch().at(-1);
81
+ if (boundary) this.compactionRows.set(boundary.id, {
82
+ type: "compaction",
83
+ at: (/* @__PURE__ */ new Date()).toISOString(),
84
+ baseSeq: branch.length,
85
+ plannerVersion: 3,
86
+ summaryModelRef: result.summaryModelRef ?? "unknown",
87
+ qualityAudit: result.qualityAudit ?? "disabled",
88
+ handover: result.handover,
89
+ audit: result.audit,
90
+ summary: result.summary,
91
+ messages: result.messages,
92
+ firstKeptIndex: result.firstKeptIndex,
93
+ tokensBefore: result.tokensBefore,
94
+ tokensAfter: result.tokensAfter
95
+ });
62
96
  return result;
63
97
  }
64
98
  };
@@ -46,7 +46,7 @@ export interface InboundLoopConfig {
46
46
  setupSessionEventHandling: (sessionKey: string) => void;
47
47
  /** Per-session config hydration (workspace + model override) before a turn runs. */
48
48
  sessionHydrator: SessionHydrator;
49
- /** Returns the visible last assistant text used for outbound + persistent-goal hook. */
49
+ /** Returns the visible last assistant text used for outbound delivery. */
50
50
  getLastAssistantPlainText: (sessionKey: string) => string;
51
51
  /** Pre-turn auto-compaction (only used by system messages). */
52
52
  /** Fire-and-forget auto-title (no-ops for cron/heartbeat keys). */
@@ -0,0 +1,11 @@
1
+ import { type CompactionHandover } from '../../session/compaction-types.js';
2
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
3
+ export type { CompactionAudit, CompactionHandover, CompactionHandoverItem, HandoverItemKind, } from '../../session/compaction-types.js';
4
+ export declare function parseCompactionHandover(params: {
5
+ text: string;
6
+ sourceThroughSeq: number;
7
+ previousBoundaryId?: string;
8
+ allowedSources: readonly TranscriptSourceEntry[];
9
+ }): CompactionHandover;
10
+ export declare function renderCompactionHandover(handover: CompactionHandover): string;
11
+ export declare function handoverForPrompt(handover: CompactionHandover | undefined): object;
@@ -0,0 +1,108 @@
1
+ import { HANDOVER_ITEM_KINDS } from "../../session/compaction-types.js";
2
+ import { createHash } from "node:crypto";
3
+ import { z } from "zod";
4
+ //#region src/agent/memory/compaction-ledger.ts
5
+ const RawHandoverItemSchema = z.object({
6
+ kind: z.enum(HANDOVER_ITEM_KINDS),
7
+ text: z.string().min(1),
8
+ status: z.enum([
9
+ "active",
10
+ "completed",
11
+ "superseded"
12
+ ]),
13
+ sourceSeqs: z.array(z.number().int().positive()).min(1),
14
+ identifiers: z.array(z.string()).default([])
15
+ }).strict();
16
+ const RawHandoverSchema = z.object({ items: z.array(RawHandoverItemSchema).max(120) }).strict();
17
+ function extractJsonObject(text) {
18
+ const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
19
+ if (fenced) return fenced;
20
+ const start = text.indexOf("{");
21
+ const end = text.lastIndexOf("}");
22
+ if (start < 0 || end <= start) throw new Error("Compaction model did not return a JSON object");
23
+ return text.slice(start, end + 1);
24
+ }
25
+ function itemId(kind, text, seqs) {
26
+ return createHash("sha256").update(`${kind}\0${text.trim()}\0${[...seqs].sort((a, b) => a - b).join(",")}`).digest("hex").slice(0, 20);
27
+ }
28
+ function parseCompactionHandover(params) {
29
+ const parsed = RawHandoverSchema.parse(JSON.parse(extractJsonObject(params.text)));
30
+ const sourceBySeq = new Map(params.allowedSources.map((source) => [source.seq, source]));
31
+ const items = parsed.items.map((item) => {
32
+ const seqs = [...new Set(item.sourceSeqs)].sort((a, b) => a - b);
33
+ const sources = seqs.map((seq) => {
34
+ const source = sourceBySeq.get(seq);
35
+ if (!source || seq > params.sourceThroughSeq) throw new Error(`Compaction handover references unavailable source seq ${seq}`);
36
+ return {
37
+ entryId: source.entryId,
38
+ seq
39
+ };
40
+ });
41
+ const text = item.text.trim();
42
+ return {
43
+ id: itemId(item.kind, text, seqs),
44
+ kind: item.kind,
45
+ text,
46
+ status: item.status,
47
+ sources,
48
+ identifiers: [...new Set(item.identifiers.map((value) => value.trim()).filter(Boolean))]
49
+ };
50
+ });
51
+ return {
52
+ version: 1,
53
+ sourceThroughSeq: params.sourceThroughSeq,
54
+ ...params.previousBoundaryId ? { previousBoundaryId: params.previousBoundaryId } : {},
55
+ items: [...new Map(items.map((item) => [item.id, item])).values()]
56
+ };
57
+ }
58
+ const SUMMARY_GROUPS = [
59
+ {
60
+ heading: "Decisions",
61
+ kinds: ["objective", "decision"]
62
+ },
63
+ {
64
+ heading: "Pending user asks",
65
+ kinds: ["pending_user_ask"]
66
+ },
67
+ {
68
+ heading: "Open TODOs",
69
+ kinds: ["todo", "next_action"]
70
+ },
71
+ {
72
+ heading: "Constraints and rules",
73
+ kinds: ["constraint"]
74
+ },
75
+ {
76
+ heading: "Tool operations and results",
77
+ kinds: [
78
+ "file_change",
79
+ "tool_outcome",
80
+ "failure"
81
+ ]
82
+ },
83
+ {
84
+ heading: "Recent state",
85
+ kinds: ["current_state"]
86
+ }
87
+ ];
88
+ function renderCompactionHandover(handover) {
89
+ const active = handover.items.filter((item) => item.status === "active");
90
+ const sections = SUMMARY_GROUPS.map(({ heading, kinds }) => {
91
+ const items = active.filter((item) => kinds.includes(item.kind));
92
+ return `## ${heading}\n${items.length > 0 ? items.map((item) => `- ${item.text}`).join("\n") : "None"}`;
93
+ });
94
+ const identifiers = [...new Set(active.flatMap((item) => item.identifiers))];
95
+ sections.splice(4, 0, `## Exact identifiers\n${identifiers.length > 0 ? identifiers.map((value) => `- \`${value}\``).join("\n") : "None"}`);
96
+ return sections.join("\n\n");
97
+ }
98
+ function handoverForPrompt(handover) {
99
+ return { items: handover?.items.map((item) => ({
100
+ kind: item.kind,
101
+ text: item.text,
102
+ status: item.status,
103
+ sourceSeqs: item.sources.map((source) => source.seq),
104
+ identifiers: item.identifiers
105
+ })) ?? [] };
106
+ }
107
+ //#endregion
108
+ export { handoverForPrompt, parseCompactionHandover, renderCompactionHandover };
@@ -0,0 +1,2 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ export declare function serializeMessageForCompaction(message: AgentMessage): string;
@@ -0,0 +1,52 @@
1
+ import { readAgentMessageContent } from "./agent-message-access.js";
2
+ //#region src/agent/memory/compaction-serializer.ts
3
+ function safeJson(value) {
4
+ try {
5
+ return JSON.stringify(value);
6
+ } catch {
7
+ return String(value);
8
+ }
9
+ }
10
+ function valueRecord(value) {
11
+ return value && typeof value === "object" ? value : void 0;
12
+ }
13
+ function serializeContentBlock(block) {
14
+ const record = valueRecord(block);
15
+ if (!record) return safeJson(block);
16
+ const type = String(record.type ?? "unknown");
17
+ if (type === "text") return String(record.text ?? "");
18
+ if (type === "toolCall") return [
19
+ "[Tool call]",
20
+ `name: ${String(record.name ?? "unknown")}`,
21
+ `id: ${String(record.id ?? record.toolCallId ?? "unknown")}`,
22
+ `arguments: ${safeJson(record.arguments ?? record.args ?? {})}`
23
+ ].join("\n");
24
+ if (type === "image" || type === "audio" || type === "video" || type === "file") {
25
+ const metadata = { ...record };
26
+ delete metadata.data;
27
+ delete metadata.bytes;
28
+ delete metadata.base64;
29
+ return `[${type} content]\nmetadata: ${safeJson(metadata)}`;
30
+ }
31
+ if (type === "thinking" || type === "reasoning" || type === "reasoning_details") return "[Assistant private reasoning omitted from compaction input]";
32
+ return `[${type} block]\n${safeJson(record)}`;
33
+ }
34
+ function serializeMessageForCompaction(message) {
35
+ const record = message;
36
+ const raw = readAgentMessageContent(message);
37
+ const content = typeof raw === "string" ? raw : Array.isArray(raw) ? raw.map(serializeContentBlock).filter(Boolean).join("\n\n") : safeJson(raw);
38
+ const metadata = [];
39
+ if (message.role === "toolResult") {
40
+ metadata.push(`tool: ${String(record.toolName ?? "unknown")}`);
41
+ metadata.push(`toolCallId: ${String(record.toolCallId ?? "unknown")}`);
42
+ metadata.push(`status: ${record.isError === true ? "error" : "success"}`);
43
+ if (record.details != null) metadata.push(`details: ${safeJson(record.details)}`);
44
+ }
45
+ return [
46
+ `### ${message.role}`,
47
+ ...metadata,
48
+ content
49
+ ].filter(Boolean).join("\n");
50
+ }
51
+ //#endregion
52
+ export { serializeMessageForCompaction };
@@ -0,0 +1,20 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
3
+ export interface CompactionSourcePlan {
4
+ sourceEntries: TranscriptSourceEntry[];
5
+ keptEntries: TranscriptSourceEntry[];
6
+ keptMessages: AgentMessage[];
7
+ allMessages: AgentMessage[];
8
+ sourceThroughSeq: number;
9
+ }
10
+ export declare function planCompactionSource(params: {
11
+ entries: readonly TranscriptSourceEntry[];
12
+ minMessagesBeforeCompact: number;
13
+ recentTurnsPreserve: number;
14
+ keepRecentTokens: number;
15
+ force: boolean;
16
+ }): CompactionSourcePlan | null;
17
+ export declare function estimateCompactionSourceTokens(plan: CompactionSourcePlan): {
18
+ before: number;
19
+ kept: number;
20
+ };
@@ -0,0 +1,67 @@
1
+ import { buildSessionContextForLlm, isRuntimeOnlyTranscriptMessage, isTranscriptCompactionEntry, isTranscriptContextEntry, isTranscriptCustomMessageEntry, isTranscriptCustomStateEntry, isTranscriptLabelEntry, isTranscriptMetadataEntry, isTranscriptSummaryMessageEntry } from "../../session/session-context-for-llm.js";
2
+ import { estimateMessagesTokens, estimateTextTokens } from "./context-budget.js";
3
+ //#region src/agent/memory/compaction-source-planner.ts
4
+ function isModelSource(entry) {
5
+ const row = entry.row;
6
+ return !isTranscriptCompactionEntry(row) && !isTranscriptContextEntry(row) && !isTranscriptCustomStateEntry(row) && !isTranscriptSummaryMessageEntry(row) && !isTranscriptLabelEntry(row) && !isTranscriptMetadataEntry(row) && !isRuntimeOnlyTranscriptMessage(row);
7
+ }
8
+ function isTurnStart(entry) {
9
+ return entry.row.role === "user" || isTranscriptCustomMessageEntry(entry.row);
10
+ }
11
+ function estimateEntryTokens(entry) {
12
+ try {
13
+ return estimateTextTokens(JSON.stringify(entry.row)) + 12;
14
+ } catch {
15
+ return 12;
16
+ }
17
+ }
18
+ function findNthTurnFromEnd(entries, count) {
19
+ let found = 0;
20
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
21
+ if (!isTurnStart(entries[index])) continue;
22
+ found += 1;
23
+ if (found === count) return index;
24
+ }
25
+ return 0;
26
+ }
27
+ function findTurnAtOrBefore(entries, start) {
28
+ for (let index = Math.min(start, entries.length - 1); index >= 0; index -= 1) if (isTurnStart(entries[index])) return index;
29
+ return 0;
30
+ }
31
+ function findRecentTokenBoundary(entries, keepRecentTokens) {
32
+ let tokens = 0;
33
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
34
+ tokens += estimateEntryTokens(entries[index]);
35
+ if (tokens >= keepRecentTokens) return findTurnAtOrBefore(entries, index);
36
+ }
37
+ return 0;
38
+ }
39
+ function planCompactionSource(params) {
40
+ const rawEntries = params.entries.filter(isModelSource);
41
+ const allMessages = buildSessionContextForLlm(rawEntries.map((entry) => entry.row));
42
+ if (!params.force && allMessages.length < params.minMessagesBeforeCompact || params.force && allMessages.length < 2) return null;
43
+ const turnBoundary = findNthTurnFromEnd(rawEntries, params.recentTurnsPreserve);
44
+ const tokenBoundary = findRecentTokenBoundary(rawEntries, params.keepRecentTokens);
45
+ let splitAt = Math.min(turnBoundary, tokenBoundary);
46
+ if (splitAt <= 0 && params.force) splitAt = findNthTurnFromEnd(rawEntries, 1);
47
+ if (splitAt <= 0) return null;
48
+ const sourceEntries = rawEntries.slice(0, splitAt);
49
+ const keptEntries = rawEntries.slice(splitAt);
50
+ const keptMessages = buildSessionContextForLlm(keptEntries.map((entry) => entry.row));
51
+ if (sourceEntries.length === 0 || keptMessages.length === 0) return null;
52
+ return {
53
+ sourceEntries,
54
+ keptEntries,
55
+ keptMessages,
56
+ allMessages,
57
+ sourceThroughSeq: sourceEntries.at(-1).seq
58
+ };
59
+ }
60
+ function estimateCompactionSourceTokens(plan) {
61
+ return {
62
+ before: estimateMessagesTokens(plan.allMessages),
63
+ kept: estimateMessagesTokens(plan.keptMessages)
64
+ };
65
+ }
66
+ //#endregion
67
+ export { estimateCompactionSourceTokens, planCompactionSource };
@@ -1,14 +1,19 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
2
  import { type Api, type Model } from '@earendil-works/pi-ai/compat';
3
+ import type { CompactionAudit, CompactionHandover } from '../../session/compaction-types.js';
4
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
3
5
  export interface CompactionResult {
4
6
  summary: string;
7
+ messages: AgentMessage[];
5
8
  firstKeptIndex: number;
6
9
  tokensBefore: number;
7
10
  tokensAfter: number;
8
11
  compacted: boolean;
9
- plannerVersion?: number;
12
+ plannerVersion?: 3;
10
13
  summaryModelRef?: string;
11
14
  qualityAudit?: 'passed' | 'disabled';
15
+ handover?: CompactionHandover;
16
+ audit?: CompactionAudit;
12
17
  compactedUsage?: {
13
18
  input: number;
14
19
  output: number;
@@ -27,6 +32,7 @@ export interface CompactionConfig {
27
32
  summaryTimeoutMs: number;
28
33
  summaryRetries: number;
29
34
  qualityGuard: boolean;
35
+ gapAudit: boolean;
30
36
  accumulateUsage: boolean;
31
37
  }
32
38
  export interface CompactionExecutionOptions {
@@ -45,10 +51,10 @@ export declare class SessionCompactor {
45
51
  private readonly config;
46
52
  constructor(config?: Partial<CompactionConfig>);
47
53
  getConfig(): Readonly<CompactionConfig>;
48
- compact(messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
49
- private generateSummary;
50
- private callSummaryModels;
51
- applyCompaction(messages: AgentMessage[], result: CompactionResult): AgentMessage[];
54
+ compact(entries: readonly TranscriptSourceEntry[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
52
55
  estimateTotalTokens(messages: AgentMessage[]): number;
56
+ private generateHandover;
57
+ private auditHandover;
58
+ private callHandoverModels;
53
59
  }
54
60
  export {};