@xopcai/xopc 0.0.168 → 0.0.169
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.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DjEDu38T.js → activity-store-DumQD8EX.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DVuLzaJi.js → agent-avatar-dicebear-CNI1HQdV.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-tF_QTWxn.js → agents-DfpeWAnu.js} +2 -2
- package/dist/gateway/static/root/assets/{api-DwVCuPOb.js → api-D7eNcGmE.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-spzVBvAu.js → app-management-settings-panel-BPbnbnFn.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CetimI47.js → appearance-settings-WWFCDver.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-HDyN6Fjx.js → apps-page-B27faKqW.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-TOmQ2XKc.js → archive-plugin-Cu2dsFtI.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-NFNEWVLJ.js → attachment-load-C9mycbtr.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-B0FnLpSl.js → automation-suggestion-card-DtHqVViI.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DVevVD6A.js → automations-page-BoH5grBX.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-Csc4xkR9.js → binary-plugins-DqrPRyjm.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C6Xgrbse.js → block-editor-B9dc3pqc.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-CyDDEKxB.js → browser-settings-page-CK2fnxHY.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-DaxyAai1.js → browser-workflow-inputs-70k5yvTc.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CaX6iIJA.js → browser-workflows-page-DBNuaWwR.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-EXZv96j1.js → capabilities-settings-panel-gg9GXU00.js} +6 -6
- package/dist/gateway/static/root/assets/{capability-presets-api-DdCHSzcA.js → capability-presets-api-CvV4M4Oe.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-A1qGVyll.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BOkLI89e.js → channel-recipient-api-BnLOBd7v.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-aCN05KdJ.js → channels-settings-H4vCzqiD.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-DtswVkDX.js +1 -0
- package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-uQ0fehio.js → chunk-KS7C4IRE-BMhrPKJC.js} +2 -2
- package/dist/gateway/static/root/assets/{connector-logo-Mp40HWsb.js → connector-logo-CYQPu4Nn.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-i0cu5rg5.js → connectors-page-DphVkloc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BtzUJ0d7.js → desktop-pet-Deb8fsr-.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Dg0Duj8B.js → desktop-pet-settings-DHTY5Ku1.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-9f0k1wZq.js → directory-picker-path-field-cGL2aEB6.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-rdW7dsGP.js → dreaming-settings-C2XF2wL4.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-C9zUnn-z.js → extension-debug-page-F8AzDx0d.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Cy5rfU0h.js → extension-page-ZrX_Ge87.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BjIquAw6.js → extension-settings-page-VypAD6ok.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-AQQmI6SW.js → gateway-config-api-C-UsxEKi.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CYNmbqHj.js → gateway-settings-ChG26Coy.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-qnEmj-vL.js → gateway-startup-retry-D73V3EVy.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-CkXaDfN3.js → goal-create-dialog-B6aBG2KK.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-detail-page-FqDa5bfO.js → goal-detail-page-B_G9oVL1.js} +3 -3
- package/dist/gateway/static/root/assets/{goals-config-api-CaVGtM6n.js → goals-config-api-fv7JLhjy.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-B-uBRGN6.js → goals-page-BQmg_7aD.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-settings-C9J3MX0F.js → goals-settings-DlfyneMz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-C0qFLyew.js → heartbeat-settings-BPyFbSbh.js} +1 -1
- package/dist/gateway/static/root/assets/image-generation-api-CSKX7PsM.js +1 -0
- package/dist/gateway/static/root/assets/index-DJtuKve9.js +199 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BAZlRZMd.js → keyboard-shortcuts-settings-BUxrnWH_.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-DkJUQRyC.js → local-app-workbench-page-Dzlj4fH8.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-PcQABi7F.js → local-apps-page-BsZMeDnS.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-tnRLWdx2.js → locale-store-DXq-Y8Bi.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-B-nXM29t.js → logs-page-Bg1B-cKU.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-B6W1H0Fj.js → markdown-split-Cmaw70yM.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-B-r9Tj74.js → media-plugins-Blqj_oJD.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-B1EG4gdu.js → messages-Cj_n7gUv.js} +2 -2
- package/dist/gateway/static/root/assets/notes-page-B6Fdlf_s.js +1 -0
- package/dist/gateway/static/root/assets/{notes-workbench-Be97S0Im.js → notes-workbench-4HYPR6Hb.js} +2 -2
- package/dist/gateway/static/root/assets/{page-tabs-BmUWVWO9.js → page-tabs-D6zFoyJY.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-a76A8p5R.js → preview-open-alternatives-BLoo7Ad8.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-BWhYrt-U.js → product-open-page-0-tt2dp7.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-md0ANZ-f.js → project-detail-page-CGa68F1d.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-D1MNrLcy.js → projects-page-BXmIeErj.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-GTuiqlJO.js → remote-access-hub-bxrIHaRt.js} +1 -1
- package/dist/gateway/static/root/assets/{save-bar-controls-_ZMLDSUw.js → save-bar-controls-9ujl7LRy.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-D4ErObRc.js → schedule-field-e80Mj-0z.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-PqNSGlcH.js → schema-form-DYZQD-PL.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-Ct0MVjNv.js → sessions-page-D_7ms_LG.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-VLuu9WHc.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BCKaoLhJ.js → settings-form-section-Clt3p-mk.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-Dn95fked.js → settings-loading-skeleton-CTuS66nC.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C8MPUl2Q.js → settings-page-CMP_owwc.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-Bigc8-GR.js → settings-page-layout-BWUV_wx6.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DFTcAHsd.js → setup-status-panel-CAClgrxi.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-xAjqaV4y.js → share-preview-page-tISZJtRK.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-D2uvC_aM.js → shares-settings-t-hP0QDv.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CYRaxTqs.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-6dr3RRVW.js → skills-page-C6CXLWnN.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BJJQulg9.js → system-settings-panel-6u0k0wJi.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-H9T49Iar.js → theme-store-DSpAOJ9G.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-DsuPUbRE.js → time-picker-BF3f8el1.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-Djk3F3EL.js → typed-models-lib-CyRCjjGS.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-UACJTyH0.js → use-channel-catalog-B_Igd7ec.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-BC585kHK.js → user-context-page-B3zeQLeM.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CvocOFat.js → voice-api-key-field-BanJk_cf.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-DiMn6nrT.js → work-discovery-page-BCANmOUS.js} +1 -1
- package/dist/gateway/static/root/assets/{work-item-detail-page-CFBlQbPy.js → work-item-detail-page-t5xiIEFv.js} +1 -1
- package/dist/gateway/static/root/assets/{work-page-CLJLKqsf.js → work-page-CEI3zs-y.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DbQwWPjv.js → workflow-run-setup-panel-DCXTQx7p.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-BJOhlABF.js → workflows-page-B8FRLCHp.js} +3 -3
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/memory/dreaming/config.js +1 -1
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/runtime-profile.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/routes/composer-history.d.ts +3 -0
- package/dist/src/gateway/hono/routes/composer-history.js +28 -0
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/session/client-history.d.ts +2 -0
- package/dist/src/session/client-history.js +2 -0
- package/dist/src/storage/sqlite/composer-input-history-repository.d.ts +12 -0
- package/dist/src/storage/sqlite/composer-input-history-repository.js +42 -0
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/migrations/059_composer_input_history.sql +8 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +3 -1
- package/dist/src/tui/backends/embedded-backend.js +7 -0
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +13 -0
- package/dist/src/tui/components/custom-editor.d.ts +1 -0
- package/dist/src/tui/components/custom-editor.js +6 -0
- package/dist/src/tui/tui-backend.d.ts +9 -0
- package/dist/src/tui/tui-submit.d.ts +1 -0
- package/dist/src/tui/tui-submit.js +1 -1
- package/dist/src/tui/tui.js +58 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-o08SXqM4.js +0 -2
- package/dist/gateway/static/root/assets/channels-status-swr-ZrqadU60.js +0 -1
- package/dist/gateway/static/root/assets/index-DchbD-qM.js +0 -199
- package/dist/gateway/static/root/assets/notes-page-BNECY6Oy.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-QOUph2Oq.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DYtfQXB-.js +0 -1
|
@@ -11,29 +11,29 @@
|
|
|
11
11
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
|
|
12
12
|
<link rel="manifest" href="/site.webmanifest?v=20260713-1" />
|
|
13
13
|
<title>XOPC — Turn goals into loops. Keep what matters moving.</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-DJtuKve9.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
|
|
16
16
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="/assets/dist-CxGUk8J-.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/Combination-14nmIgxH.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/dist-C230izr8.js">
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/assets/chunk-KS7C4IRE-
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/chunk-KS7C4IRE-BMhrPKJC.js">
|
|
22
22
|
<link rel="modulepreload" crossorigin href="/assets/vendor-swr-BIWyz7Rc.js">
|
|
23
23
|
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-DPHK1VkS.js">
|
|
24
24
|
<link rel="modulepreload" crossorigin href="/assets/check-DUBLcKHA.js">
|
|
25
25
|
<link rel="modulepreload" crossorigin href="/assets/circle-alert-BEjgurr2.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/messages-
|
|
28
|
-
<link rel="modulepreload" crossorigin href="/assets/locale-store-
|
|
27
|
+
<link rel="modulepreload" crossorigin href="/assets/messages-Cj_n7gUv.js">
|
|
28
|
+
<link rel="modulepreload" crossorigin href="/assets/locale-store-DXq-Y8Bi.js">
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/cn-JdwAhgNB.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/product-delivery-BTRT9kCS.js">
|
|
32
32
|
<link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
|
|
33
33
|
<link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
|
|
34
|
-
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-
|
|
35
|
-
<link rel="modulepreload" crossorigin href="/assets/activity-store-
|
|
36
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-store-
|
|
34
|
+
<link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-D73V3EVy.js">
|
|
35
|
+
<link rel="modulepreload" crossorigin href="/assets/activity-store-DumQD8EX.js">
|
|
36
|
+
<link rel="modulepreload" crossorigin href="/assets/theme-store-DSpAOJ9G.js">
|
|
37
37
|
<link rel="stylesheet" crossorigin href="/assets/index-DfE2j0g8.css">
|
|
38
38
|
</head>
|
|
39
39
|
<body>
|
package/dist/package.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DEFAULT_DEEP_CRON, DEFAULT_LIGHT_CRON, DEFAULT_REM_CRON } from "./constants.js";
|
|
2
1
|
import { buildMemoryRuntime } from "../../../agent-runtime/memory-runtime.js";
|
|
2
|
+
import { DEFAULT_DEEP_CRON, DEFAULT_LIGHT_CRON, DEFAULT_REM_CRON } from "./constants.js";
|
|
3
3
|
//#region src/agent/memory/dreaming/config.ts
|
|
4
4
|
function clampScore(value, fallback) {
|
|
5
5
|
if (!Number.isFinite(value)) return fallback;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { buildMemoryRuntime } from "./memory-runtime.js";
|
|
2
1
|
import { checkBoundary } from "./boundary-guard.js";
|
|
3
2
|
import { resolveModelRole } from "./model-router.js";
|
|
4
3
|
import { buildRuntimeToolRegistry } from "./tool-registry.js";
|
|
4
|
+
import { buildMemoryRuntime } from "./memory-runtime.js";
|
|
5
5
|
import { resolveWorkflow, validateWorkflowForRuntime } from "./workflow-runtime.js";
|
|
6
6
|
import { buildAgentRuntimeProfile } from "./runtime-profile.js";
|
|
7
7
|
import { appendAgentRunEvent, createAgentRunTrace, finishAgentRunTrace, hashEffectiveManifest } from "./run-trace.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { buildAgentManifestPromptSection } from "../agent-manifest/prompt.js";
|
|
2
2
|
import "../agent-manifest/index.js";
|
|
3
|
-
import { buildMemoryRuntime } from "./memory-runtime.js";
|
|
4
3
|
import { checkBoundary } from "./boundary-guard.js";
|
|
5
4
|
import { resolveModelRole } from "./model-router.js";
|
|
6
5
|
import { buildRuntimeToolRegistry } from "./tool-registry.js";
|
|
6
|
+
import { buildMemoryRuntime } from "./memory-runtime.js";
|
|
7
7
|
import { resolveWorkflow, validateWorkflowForRuntime } from "./workflow-runtime.js";
|
|
8
8
|
//#region src/agent-runtime/runtime-profile.ts
|
|
9
9
|
function buildAgentRuntimeProfile(params) {
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v59).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
2
1
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
3
2
|
import "../agent-manifest/index.js";
|
|
3
|
+
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
4
4
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
5
5
|
import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
6
6
|
//#region src/config/agent-profile.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
2
1
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
2
|
+
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
3
3
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
4
4
|
import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
|
|
5
5
|
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
4
5
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
5
6
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { appendComposerInputHistory, clearComposerInputHistory, listComposerInputHistory } from "../../../storage/sqlite/composer-input-history-repository.js";
|
|
2
|
+
import "../../../storage/sqlite/index.js";
|
|
3
|
+
//#region src/gateway/hono/routes/composer-history.ts
|
|
4
|
+
const MAX_TEXT_LENGTH = 1e5;
|
|
5
|
+
function registerComposerHistoryRoutes(authenticated, deps) {
|
|
6
|
+
authenticated.get("/api/composer-history", (c) => {
|
|
7
|
+
return c.json({ items: listComposerInputHistory() });
|
|
8
|
+
});
|
|
9
|
+
authenticated.post("/api/composer-history", deps.strictRateLimitMiddleware, async (c) => {
|
|
10
|
+
const body = await c.req.json().catch(() => null);
|
|
11
|
+
const text = body && typeof body === "object" && typeof body.text === "string" ? body.text.trim() : "";
|
|
12
|
+
if (!text) return c.json({ error: "text is required" }, 400);
|
|
13
|
+
if (text.length > MAX_TEXT_LENGTH) return c.json({ error: "text is too long" }, 413);
|
|
14
|
+
const result = appendComposerInputHistory(text);
|
|
15
|
+
if (result.inserted) deps.service.emit("composer-history.appended", result.item);
|
|
16
|
+
return c.json(result);
|
|
17
|
+
});
|
|
18
|
+
authenticated.delete("/api/composer-history", deps.strictRateLimitMiddleware, (c) => {
|
|
19
|
+
const cleared = clearComposerInputHistory();
|
|
20
|
+
if (cleared > 0) deps.service.emit("composer-history.cleared", { cleared });
|
|
21
|
+
return c.json({
|
|
22
|
+
ok: true,
|
|
23
|
+
cleared
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { registerComposerHistoryRoutes };
|
|
@@ -8,6 +8,7 @@ import { registerSearchRoutes } from "./search.js";
|
|
|
8
8
|
import { registerMobileRoutes } from "./mobile.js";
|
|
9
9
|
import { registerTaskOutcomeRoutes } from "./task-outcomes.js";
|
|
10
10
|
import { registerInteractionStateRoutes } from "./interaction-state.js";
|
|
11
|
+
import { registerComposerHistoryRoutes } from "./composer-history.js";
|
|
11
12
|
import { registerLocalAppsRoutes } from "./local-apps.js";
|
|
12
13
|
import { registerWorkDiscoveryRoutes } from "./work-discovery.js";
|
|
13
14
|
import { mountAppLazyRoutePrefixes, registerAuthenticatedLazyRouteFallback } from "./lazy-fallback.js";
|
|
@@ -25,6 +26,7 @@ function registerCoreAuthenticatedRoutes(authenticated, deps) {
|
|
|
25
26
|
registerMobileRoutes(authenticated, deps);
|
|
26
27
|
registerTaskOutcomeRoutes(authenticated, deps);
|
|
27
28
|
registerInteractionStateRoutes(authenticated, deps);
|
|
29
|
+
registerComposerHistoryRoutes(authenticated, deps);
|
|
28
30
|
}
|
|
29
31
|
function registerAuthenticatedRoutes(app, authenticated, deps) {
|
|
30
32
|
registerCoreAuthenticatedRoutes(authenticated, deps);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
2
3
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
3
4
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -7,6 +7,8 @@ export interface ClientHistoryMessage {
|
|
|
7
7
|
content: string;
|
|
8
8
|
displayIndex?: number;
|
|
9
9
|
rawContent?: string | unknown[];
|
|
10
|
+
/** Persisted inbound attachment metadata used by chat clients to reload media. */
|
|
11
|
+
media?: Message['media'];
|
|
10
12
|
timestamp?: number;
|
|
11
13
|
kind?: 'message' | 'compaction' | 'context' | 'bash' | 'custom' | 'branch';
|
|
12
14
|
tokensBefore?: number;
|
|
@@ -111,6 +111,7 @@ function messagesToClientHistory(messages, opts) {
|
|
|
111
111
|
out.push({
|
|
112
112
|
role: m.role,
|
|
113
113
|
content: text,
|
|
114
|
+
...m.media?.length ? { media: m.media } : {},
|
|
114
115
|
timestamp: parseTimestamp(m.timestamp)
|
|
115
116
|
});
|
|
116
117
|
continue;
|
|
@@ -410,6 +411,7 @@ function transcriptRowsToClientHistory(rows, opts) {
|
|
|
410
411
|
role: messageRow.role,
|
|
411
412
|
kind: "message",
|
|
412
413
|
content: flattenMessageContent(messageRow.content ?? ""),
|
|
414
|
+
...messageRow.media?.length ? { media: messageRow.media } : {},
|
|
413
415
|
...displayIndex !== void 0 ? { displayIndex } : {},
|
|
414
416
|
timestamp: parseTimestampValue(messageRow.timestamp)
|
|
415
417
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const COMPOSER_INPUT_HISTORY_LIMIT = 100;
|
|
2
|
+
export interface ComposerInputHistoryItem {
|
|
3
|
+
id: number;
|
|
4
|
+
text: string;
|
|
5
|
+
createdAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function listComposerInputHistory(limit?: number): ComposerInputHistoryItem[];
|
|
8
|
+
export declare function appendComposerInputHistory(text: string, now?: number): {
|
|
9
|
+
item: ComposerInputHistoryItem;
|
|
10
|
+
inserted: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function clearComposerInputHistory(): number;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
//#region src/storage/sqlite/composer-input-history-repository.ts
|
|
3
|
+
const COMPOSER_INPUT_HISTORY_LIMIT = 100;
|
|
4
|
+
function fromRow(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.id,
|
|
7
|
+
text: row.text,
|
|
8
|
+
createdAt: row.created_at
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function listComposerInputHistory(limit = 100) {
|
|
12
|
+
const boundedLimit = Number.isFinite(limit) ? Math.min(100, Math.max(1, Math.trunc(limit))) : 100;
|
|
13
|
+
return getSqliteDatabase().prepare("SELECT id, text, created_at FROM composer_input_history ORDER BY id DESC LIMIT ?").all(boundedLimit).map(fromRow);
|
|
14
|
+
}
|
|
15
|
+
function appendComposerInputHistory(text, now = Date.now()) {
|
|
16
|
+
const normalized = text.trim();
|
|
17
|
+
if (!normalized) throw new Error("Composer history text is required");
|
|
18
|
+
return runSqliteWriteTransaction((db) => {
|
|
19
|
+
const latest = db.prepare("SELECT id, text, created_at FROM composer_input_history ORDER BY id DESC LIMIT 1").get();
|
|
20
|
+
if (latest?.text === normalized) return {
|
|
21
|
+
item: fromRow(latest),
|
|
22
|
+
inserted: false
|
|
23
|
+
};
|
|
24
|
+
const result = db.prepare("INSERT INTO composer_input_history (text, created_at) VALUES (?, ?)").run(normalized, now);
|
|
25
|
+
const id = Number(result.lastInsertRowid);
|
|
26
|
+
db.prepare(`DELETE FROM composer_input_history
|
|
27
|
+
WHERE id NOT IN (SELECT id FROM composer_input_history ORDER BY id DESC LIMIT ?)`).run(100);
|
|
28
|
+
return {
|
|
29
|
+
item: {
|
|
30
|
+
id,
|
|
31
|
+
text: normalized,
|
|
32
|
+
createdAt: now
|
|
33
|
+
},
|
|
34
|
+
inserted: true
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function clearComposerInputHistory() {
|
|
39
|
+
return Number(runSqliteWriteTransaction((db) => db.prepare("DELETE FROM composer_input_history").run().changes));
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { COMPOSER_INPUT_HISTORY_LIMIT, appendComposerInputHistory, clearComposerInputHistory, listComposerInputHistory };
|
|
@@ -5,6 +5,7 @@ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, } from './m
|
|
|
5
5
|
export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrations/discover.js';
|
|
6
6
|
export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
|
|
7
7
|
export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
|
|
8
|
+
export { appendComposerInputHistory, clearComposerInputHistory, listComposerInputHistory, COMPOSER_INPUT_HISTORY_LIMIT, type ComposerInputHistoryItem, } from './composer-input-history-repository.js';
|
|
8
9
|
export { getInteractionState, setInteractionState, updateInteractionStateFromMessage, type InteractionState, } from './interaction-state-repository.js';
|
|
9
10
|
export { buildRelationshipPrompt, getRelationshipSettings, isProactiveSupportAllowed, updateRelationshipSettings, type RelationshipSettings, type SupportMode, } from './relationship-settings-repository.js';
|
|
10
11
|
export { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listTaskOutcomes, setTaskOutcomeFeedback, startTaskOutcome, summarizeTaskOutcomes, updateTaskOutcome, type TaskContract, type TaskEvidence, type TaskFeedbackOutcome, type TaskOutcome, type TaskOutcomeMetrics, type TaskOutcomeStatus, } from './task-outcome-repository.js';
|
|
@@ -6,6 +6,7 @@ import { XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, applyPendingMi
|
|
|
6
6
|
import { ensureXopcDatabaseSchema } from "./schema.js";
|
|
7
7
|
import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
|
|
8
8
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
9
|
+
import { COMPOSER_INPUT_HISTORY_LIMIT, appendComposerInputHistory, clearComposerInputHistory, listComposerInputHistory } from "./composer-input-history-repository.js";
|
|
9
10
|
import { getInteractionState, setInteractionState, updateInteractionStateFromMessage } from "./interaction-state-repository.js";
|
|
10
11
|
import { buildRelationshipPrompt, getRelationshipSettings, isProactiveSupportAllowed, updateRelationshipSettings } from "./relationship-settings-repository.js";
|
|
11
12
|
import { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listTaskOutcomes, setTaskOutcomeFeedback, startTaskOutcome, summarizeTaskOutcomes, updateTaskOutcome } from "./task-outcome-repository.js";
|
|
@@ -24,4 +25,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
|
|
|
24
25
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
25
26
|
import { consumeMemoryReferenceConsent, decideMemoryReferenceConsent, ensureMemoryReferenceConsentRequest, hasMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent } from "./memory-reference-consent-repository.js";
|
|
26
27
|
import { getUserProfilePromptState, setUserProfilePromptState } from "./user-profile-setup-repository.js";
|
|
27
|
-
export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, completeTaskOutcome, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, findTaskOutcomeForAssistant, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getTaskOutcome, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isProactiveSupportAllowed, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTaskOutcomes, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setTaskOutcomeFeedback, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, startTaskOutcome, summarizeMemoryRecallFeedback, summarizeTaskOutcomes, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateTaskOutcome, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
|
|
28
|
+
export { COMPOSER_INPUT_HISTORY_LIMIT, DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendComposerInputHistory, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, clearComposerInputHistory, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, completeTaskOutcome, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, findTaskOutcomeForAssistant, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getTaskOutcome, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isProactiveSupportAllowed, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listComposerInputHistory, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTaskOutcomes, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setTaskOutcomeFeedback, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, startTaskOutcome, summarizeMemoryRecallFeedback, summarizeTaskOutcomes, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateTaskOutcome, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 59;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
|
|
|
12
12
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
13
13
|
const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
14
14
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
15
|
-
const XOPC_DB_SCHEMA_VERSION =
|
|
15
|
+
const XOPC_DB_SCHEMA_VERSION = 59;
|
|
16
16
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
function resolveMigrationsDir(override) {
|
|
18
18
|
if (override) return override;
|
|
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
|
|
|
46
46
|
* Each step runs in its own transaction and updates schema_meta on success.
|
|
47
47
|
*/
|
|
48
48
|
function applyPendingMigrations(db, options = {}) {
|
|
49
|
-
const targetVersion = options.targetVersion ??
|
|
49
|
+
const targetVersion = options.targetVersion ?? 59;
|
|
50
50
|
let currentVersion = readSchemaVersion(db);
|
|
51
51
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
52
52
|
if (currentVersion >= targetVersion) return currentVersion;
|
|
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
62
62
|
}
|
|
63
63
|
/** Inspect schema version without mutating the database. */
|
|
64
64
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
65
|
-
const appVersion = options.targetVersion ??
|
|
65
|
+
const appVersion = options.targetVersion ?? 59;
|
|
66
66
|
const dbVersion = readSchemaVersion(db);
|
|
67
67
|
if (dbVersion > appVersion) return {
|
|
68
68
|
dbVersion,
|
|
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
|
|
|
19
19
|
export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
20
20
|
|
|
21
21
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
22
|
-
export const XOPC_DB_SCHEMA_VERSION =
|
|
22
|
+
export const XOPC_DB_SCHEMA_VERSION = 59;
|
|
23
23
|
|
|
24
24
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
|
|
|
31
31
|
bootstrapFreshDatabase(db);
|
|
32
32
|
currentVersion = 11;
|
|
33
33
|
}
|
|
34
|
-
applyPendingMigrations(db, { targetVersion:
|
|
34
|
+
applyPendingMigrations(db, { targetVersion: 59 });
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
37
|
export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
|
|
@@ -2,7 +2,7 @@ import type { ExtensionRegistryImpl } from '../../extensions/loader.js';
|
|
|
2
2
|
import { type SessionTimelineItem } from '../../session/transcript-outline.js';
|
|
3
3
|
import { type Config } from '../../config/schema.js';
|
|
4
4
|
import type { ExportFormat } from '../../session/types.js';
|
|
5
|
-
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
5
|
+
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiComposerHistoryItem, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
6
6
|
import type { SessionInfo } from '../tui-types.js';
|
|
7
7
|
interface EmbeddedBackendOptions {
|
|
8
8
|
config?: Config;
|
|
@@ -33,6 +33,8 @@ export declare class EmbeddedBackend implements TuiBackend {
|
|
|
33
33
|
onDisconnected?: (reason: string) => void;
|
|
34
34
|
constructor(opts?: EmbeddedBackendOptions);
|
|
35
35
|
get connectionLabel(): string;
|
|
36
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
37
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
36
38
|
start(): void;
|
|
37
39
|
private ensureAgent;
|
|
38
40
|
private createAgent;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
4
|
+
import { appendComposerInputHistory, listComposerInputHistory } from "../../storage/sqlite/composer-input-history-repository.js";
|
|
4
5
|
import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../routing/agent-session-key.js";
|
|
5
6
|
import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
|
|
6
7
|
import "../../storage/sqlite/index.js";
|
|
@@ -77,6 +78,12 @@ var EmbeddedBackend = class {
|
|
|
77
78
|
get connectionLabel() {
|
|
78
79
|
return "local embedded";
|
|
79
80
|
}
|
|
81
|
+
async getComposerInputHistory() {
|
|
82
|
+
return listComposerInputHistory();
|
|
83
|
+
}
|
|
84
|
+
async recordComposerInputHistory(text) {
|
|
85
|
+
return appendComposerInputHistory(text).item;
|
|
86
|
+
}
|
|
80
87
|
start() {
|
|
81
88
|
if (this.running) return;
|
|
82
89
|
this.running = true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExportFormat } from '../../session/types.js';
|
|
2
2
|
import type { SessionTimelineItem } from '../../session/transcript-outline.js';
|
|
3
|
-
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiStartupResources, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
3
|
+
import type { ChatSendOptions, HistoryMessage, TuiBackend, TuiCompactionResult, TuiComposerHistoryItem, TuiEvent, TuiModelChoice, TuiShareRequest, TuiShareResult, TuiSessionStats, TuiSessionItem, TuiStartupResources, TuiTranscriptTreeEntry, TuiAgentInfo, TuiWorkspaceFileSearchEntry, TuiWorkflowRunStartRequest, TuiWorkflowRunStartResult, TuiStartupProjectResult } from '../tui-backend.js';
|
|
4
4
|
import type { SessionInfo } from '../tui-types.js';
|
|
5
5
|
import type { ReviewContext } from '../../review/review-git.js';
|
|
6
6
|
import { type GatewayCredential } from '../../gateway/credential.js';
|
|
@@ -33,6 +33,8 @@ export declare class GatewaySseBackend implements TuiBackend {
|
|
|
33
33
|
start(): void;
|
|
34
34
|
stop(): void;
|
|
35
35
|
getActiveSignal(): AbortSignal | undefined;
|
|
36
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
37
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
36
38
|
sendChat(opts: ChatSendOptions): Promise<{
|
|
37
39
|
runId: string;
|
|
38
40
|
}>;
|
|
@@ -80,6 +80,19 @@ var GatewaySseBackend = class {
|
|
|
80
80
|
const signal = this.chatAbort?.signal;
|
|
81
81
|
return signal && !signal.aborted ? signal : void 0;
|
|
82
82
|
}
|
|
83
|
+
async getComposerInputHistory() {
|
|
84
|
+
const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential);
|
|
85
|
+
if (!res.ok) throw new Error(`Failed to load composer history (${res.status})`);
|
|
86
|
+
return (await res.json()).items ?? [];
|
|
87
|
+
}
|
|
88
|
+
async recordComposerInputHistory(text) {
|
|
89
|
+
const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
body: JSON.stringify({ text })
|
|
92
|
+
});
|
|
93
|
+
if (!res.ok) throw new Error(`Failed to save composer history (${res.status})`);
|
|
94
|
+
return (await res.json()).item;
|
|
95
|
+
}
|
|
83
96
|
async sendChat(opts) {
|
|
84
97
|
this.chatAbort?.abort();
|
|
85
98
|
this.chatAbort = new AbortController();
|
|
@@ -13,5 +13,6 @@ export declare class CustomEditor extends Editor {
|
|
|
13
13
|
onExtensionShortcut?: (data: string) => boolean;
|
|
14
14
|
constructor(tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager, options?: EditorOptions);
|
|
15
15
|
onAction(action: XopcTuiAppKeybinding, handler: () => void): void;
|
|
16
|
+
replaceHistory(itemsNewestFirst: string[]): void;
|
|
16
17
|
handleInput(data: string): void;
|
|
17
18
|
}
|
|
@@ -18,6 +18,12 @@ var CustomEditor = class extends Editor {
|
|
|
18
18
|
onAction(action, handler) {
|
|
19
19
|
this.actionHandlers.set(action, handler);
|
|
20
20
|
}
|
|
21
|
+
replaceHistory(itemsNewestFirst) {
|
|
22
|
+
const internals = this;
|
|
23
|
+
internals.history = itemsNewestFirst.slice(0, 100);
|
|
24
|
+
internals.historyIndex = -1;
|
|
25
|
+
internals.historyDraft = "";
|
|
26
|
+
}
|
|
21
27
|
handleInput(data) {
|
|
22
28
|
if (this.onExtensionShortcut?.(data)) return;
|
|
23
29
|
if (this.keybindings.matches(data, "app.clipboard.pasteImage")) {
|
|
@@ -25,6 +25,11 @@ export interface TuiEvent {
|
|
|
25
25
|
data: unknown;
|
|
26
26
|
source?: TuiEventSource;
|
|
27
27
|
}
|
|
28
|
+
export interface TuiComposerHistoryItem {
|
|
29
|
+
id: number;
|
|
30
|
+
text: string;
|
|
31
|
+
createdAt: number;
|
|
32
|
+
}
|
|
28
33
|
/** Minimal session list item. */
|
|
29
34
|
export interface TuiSessionItem {
|
|
30
35
|
key: string;
|
|
@@ -180,6 +185,10 @@ export interface TuiBackend {
|
|
|
180
185
|
stop(): void;
|
|
181
186
|
/** Current active chat abort signal, if a run is in progress. */
|
|
182
187
|
getActiveSignal?(): AbortSignal | undefined;
|
|
188
|
+
/** Global composer history, shared across sessions and clients. */
|
|
189
|
+
getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
|
|
190
|
+
/** Persist one submitted chat input. */
|
|
191
|
+
recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
|
|
183
192
|
/** Send a chat message, returns the run id. */
|
|
184
193
|
sendChat(opts: ChatSendOptions): Promise<{
|
|
185
194
|
runId: string;
|
|
@@ -7,6 +7,7 @@ export declare function createEditorSubmitHandler(params: {
|
|
|
7
7
|
setText: (value: string) => void;
|
|
8
8
|
addToHistory: (value: string) => void;
|
|
9
9
|
};
|
|
10
|
+
recordChatHistory?: (value: string) => void;
|
|
10
11
|
handleCommand: (value: string) => void | Promise<void>;
|
|
11
12
|
sendMessage: (value: string) => void | Promise<void>;
|
|
12
13
|
handleBangLine: (value: string) => void | Promise<void>;
|
|
@@ -36,7 +36,7 @@ function createEditorSubmitHandler(params) {
|
|
|
36
36
|
params.handleBangLine(raw);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
params.editor.addToHistory(
|
|
39
|
+
if (rawTrimmed) (params.recordChatHistory ?? params.editor.addToHistory)(rawTrimmed);
|
|
40
40
|
if (value.startsWith("/")) {
|
|
41
41
|
params.handleCommand(value);
|
|
42
42
|
return;
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -360,6 +360,7 @@ async function runTui(opts) {
|
|
|
360
360
|
paddingX: tuiSettings.editorPaddingX,
|
|
361
361
|
autocompleteMaxVisible: tuiSettings.autocompleteMaxVisible
|
|
362
362
|
});
|
|
363
|
+
let composerHistoryTexts = [];
|
|
363
364
|
let editor = defaultEditor;
|
|
364
365
|
let editorComponentFactory;
|
|
365
366
|
const editorContainer = new Container();
|
|
@@ -421,6 +422,7 @@ async function runTui(opts) {
|
|
|
421
422
|
nextEditor.setAutocompleteProvider?.(extensionRuntime.autocompleteProvider);
|
|
422
423
|
copyDefaultEditorAppHandlers(nextEditor);
|
|
423
424
|
editor = nextEditor;
|
|
425
|
+
for (const text of composerHistoryTexts.slice().reverse()) editor.addToHistory?.(text);
|
|
424
426
|
} else {
|
|
425
427
|
defaultEditor.setText(currentText);
|
|
426
428
|
editor = defaultEditor;
|
|
@@ -1762,12 +1764,48 @@ async function runTui(opts) {
|
|
|
1762
1764
|
updateFooter();
|
|
1763
1765
|
tui.requestRender();
|
|
1764
1766
|
};
|
|
1767
|
+
let composerHistory = [];
|
|
1768
|
+
let composerHistoryWriteQueue = Promise.resolve();
|
|
1769
|
+
const applyComposerHistory = (next) => {
|
|
1770
|
+
composerHistory = next.slice(0, 100);
|
|
1771
|
+
composerHistoryTexts = composerHistory.map((item) => item.text);
|
|
1772
|
+
if (editor === defaultEditor) {
|
|
1773
|
+
defaultEditor.replaceHistory(composerHistory.map((item) => item.text));
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
for (const item of composerHistory.slice().reverse()) editor.addToHistory?.(item.text);
|
|
1777
|
+
};
|
|
1778
|
+
const refreshComposerHistory = async () => {
|
|
1779
|
+
try {
|
|
1780
|
+
await composerHistoryWriteQueue;
|
|
1781
|
+
applyComposerHistory(await client.getComposerInputHistory());
|
|
1782
|
+
} catch {}
|
|
1783
|
+
};
|
|
1784
|
+
const recordChatHistory = (value) => {
|
|
1785
|
+
const text = value.trim();
|
|
1786
|
+
if (!text) return;
|
|
1787
|
+
editor.addToHistory?.(text);
|
|
1788
|
+
if (composerHistory[0]?.text !== text) {
|
|
1789
|
+
composerHistory = [{
|
|
1790
|
+
id: 0,
|
|
1791
|
+
text,
|
|
1792
|
+
createdAt: Date.now()
|
|
1793
|
+
}, ...composerHistory].slice(0, 100);
|
|
1794
|
+
composerHistoryTexts = composerHistory.map((item) => item.text);
|
|
1795
|
+
}
|
|
1796
|
+
composerHistoryWriteQueue = composerHistoryWriteQueue.then(async () => {
|
|
1797
|
+
const item = await client.recordComposerInputHistory(text);
|
|
1798
|
+
const optimisticIndex = composerHistory.findIndex((entry) => entry.id === 0 && entry.text === item.text);
|
|
1799
|
+
if (optimisticIndex >= 0) composerHistory[optimisticIndex] = item;
|
|
1800
|
+
}).catch(() => {});
|
|
1801
|
+
};
|
|
1765
1802
|
const submitBurst = createSubmitBurstCoalescer({
|
|
1766
1803
|
submit: createEditorSubmitHandler({
|
|
1767
1804
|
editor: {
|
|
1768
1805
|
setText: (value) => editor.setText(value),
|
|
1769
1806
|
addToHistory: (value) => editor.addToHistory?.(value)
|
|
1770
1807
|
},
|
|
1808
|
+
recordChatHistory: (value) => recordChatHistory(value),
|
|
1771
1809
|
handleCommand,
|
|
1772
1810
|
sendMessage,
|
|
1773
1811
|
handleBangLine: runLocalShellLine,
|
|
@@ -1798,7 +1836,7 @@ async function runTui(opts) {
|
|
|
1798
1836
|
tui.requestRender();
|
|
1799
1837
|
return;
|
|
1800
1838
|
}
|
|
1801
|
-
|
|
1839
|
+
recordChatHistory(text);
|
|
1802
1840
|
state.messageFollowUpQueue.push(text);
|
|
1803
1841
|
editor.setText("");
|
|
1804
1842
|
chatLog.addSystem(theme.dim(`Queued follow-up (${state.messageFollowUpQueue.length} in queue). ${tuiSettings.followUpMode === "all" ? "All queued messages send together when this reply finishes." : "Next sends when this reply finishes."}`));
|
|
@@ -2052,6 +2090,23 @@ async function runTui(opts) {
|
|
|
2052
2090
|
};
|
|
2053
2091
|
client.onEvent = (evt) => {
|
|
2054
2092
|
const data = evt.data ?? {};
|
|
2093
|
+
if (evt.event === "composer-history.appended") {
|
|
2094
|
+
const item = data;
|
|
2095
|
+
if (typeof item.text === "string" && typeof item.id === "number") {
|
|
2096
|
+
const optimisticIndex = composerHistory.findIndex((entry) => entry.id === 0 && entry.text === item.text);
|
|
2097
|
+
if (optimisticIndex >= 0) composerHistory[optimisticIndex] = item;
|
|
2098
|
+
else if (composerHistory[0]?.text !== item.text) {
|
|
2099
|
+
composerHistory = [item, ...composerHistory].slice(0, 100);
|
|
2100
|
+
composerHistoryTexts = composerHistory.map((entry) => entry.text);
|
|
2101
|
+
editor.addToHistory?.(item.text);
|
|
2102
|
+
} else composerHistory[0] = item;
|
|
2103
|
+
}
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
if (evt.event === "composer-history.cleared") {
|
|
2107
|
+
applyComposerHistory([]);
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
2055
2110
|
if (evt.event === "workflow.run.updated" && handleWorkflowRunUpdated(data)) return;
|
|
2056
2111
|
dispatchAgentEvent(evt.event, data, state, chatLog, tui, setActivityStatus, touchStreamingActivity, onAgentRunEnded, (message) => sessionSnapshot.appendMessage("assistant", assistantMessagePlainText(message)), evt.source);
|
|
2057
2112
|
};
|
|
@@ -2061,6 +2116,7 @@ async function runTui(opts) {
|
|
|
2061
2116
|
setConnectionStatus(isLocalMode ? "local ready" : "gateway connected");
|
|
2062
2117
|
touchStreamingActivity();
|
|
2063
2118
|
(async () => {
|
|
2119
|
+
await refreshComposerHistory();
|
|
2064
2120
|
if (opts.openSessionPickerOnStart && !startupSessionPickerOpened) {
|
|
2065
2121
|
startupSessionPickerOpened = true;
|
|
2066
2122
|
await openSessionPickerOverlay(pickerSvc, {
|
|
@@ -2125,6 +2181,7 @@ async function runTui(opts) {
|
|
|
2125
2181
|
setConnectionStatus(`event gap: expected ${info.expected}, got ${info.received}`);
|
|
2126
2182
|
if (state.activeRunId) recoverActiveRunFromHistory("broadcast event gap");
|
|
2127
2183
|
else loadSessionHistory({ merge: true });
|
|
2184
|
+
refreshComposerHistory();
|
|
2128
2185
|
tui.requestRender();
|
|
2129
2186
|
};
|
|
2130
2187
|
const sigintHandler = () => handleCtrlC();
|