@xopcai/xopc 0.0.246 → 0.0.248
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/src/update-offset-store.js +17 -54
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/auth/accounts.js +3 -5
- package/dist/extensions/weixin/src/monitor/monitor.js +3 -5
- package/dist/extensions/weixin/src/storage/sync-buf.d.ts +3 -6
- package/dist/extensions/weixin/src/storage/sync-buf.js +9 -22
- package/dist/gateway/static/root/assets/{activity-store-BlxqErph.js → activity-store-etpmyV7S.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CJJzpYYS.js → agent-avatar-dicebear-BmKxSM1k.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CUXApfcE.js +1 -0
- package/dist/gateway/static/root/assets/{agents-je3sRGmk.js → agents-DNq_GKuc.js} +1 -1
- package/dist/gateway/static/root/assets/{api-BbXzyQMj.js → api-B0-hLuZ1.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cnn3i00c.js → app-management-settings-panel-qfwAgyhQ.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BToQaw_v.js → appearance-settings-DqQVUpCC.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-dwIqYmXk.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-DD2SweEH.js → archive-plugin-BnMSgZvR.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BFtcib5t.js → attachment-load-CejsQMev.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-XS8wIl5o.js → automations-page-RC8EyoAf.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-SkdcSZ0i.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-Xs7pLHxR.js → binary-plugins-DGjppLSG.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BPdSzceB.js → block-editor-CWdP4bUc.js} +44 -44
- package/dist/gateway/static/root/assets/browser-settings-page-CKCa6TvG.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BAAc151l.js → browser-workflow-inputs-BQ1Ilw_o.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DUPPvE30.js → browser-workflows-page-CJh4NyxT.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-cl9kYilL.js → capabilities-settings-panel-DSp--zIZ.js} +5 -5
- package/dist/gateway/static/root/assets/channels-settings-CMd2dDrI.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-CCBCtLDg.js → channels-status-swr-Ohhee4vm.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DKW1M6aJ.js → chat-terminal-dock-BOtoKTK3.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-udWs5Kdm.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-Bijb0ZQu.js → cron-expression-DTj1V3Sw.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BZuHw-SY.js → date-picker-Yr6OCvGL.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-BsBD2JFY.js → dependency-picker-DpN3XZg9.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Ceuw3QKb.js → desktop-pet-DbGzggPF.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DctOXexM.js → desktop-pet-settings-DinCToZh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BNlMPATK.js → extension-debug-page-DgTtk4KC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CK4Uvzge.js → extension-page-DtQeiP6f.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CpnXXemw.js → extension-settings-page-DcguCgsH.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-C_mlpe-r.js → gateway-config-api-Br7lSf6H.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-826dipyU.js → gateway-config-swr-DXuXtU1w.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DSSW17ed.js → gateway-settings-CdPoDMuj.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DyvcAIMm.js → gateway-startup-retry-CzBzglzQ.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-hbmIZTpg.js → heartbeat-settings-DHk1hawP.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-YGipe_W6.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-D7cyfks6.js → image-generation-api-TIgsn04n.js} +1 -1
- package/dist/gateway/static/root/assets/{index-eZjksPvq.js → index-D5TQQpeb.js} +44 -44
- package/dist/gateway/static/root/assets/index-DReBaaTX.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQrDwwgi.js → keyboard-shortcuts-settings-wsWuoa8p.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CpyvYyrb.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-D-YWD6LS.js → local-apps-page-CXrbrGo8.js} +1 -1
- package/dist/gateway/static/root/assets/local-context-graph-BjUf7fQ9.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-CBoCuIMx.js → locale-store-BJFLQY8O.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DvLc9l59.js → logs-page-CXKy6E_l.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-DsULLUUv.js → management-settings-BdJZFR7U.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-CjqlP6IB.js → markdown-split-NK3ACVG2.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-BXsHghJd.js → markdown-view-DTF9v1gg.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DQL029DU.js → media-plugins-F0jcUxyl.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CHNYp8EQ.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-gauprAae.js → mobile-pairing-wizard-3NKCniSp.js} +1 -1
- package/dist/gateway/static/root/assets/models-hub-cache-nCfkBN8M.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-AsEfLZt9.js → notes-page-DuqLahi6.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-C7j9EdQk.js +5 -0
- package/dist/gateway/static/root/assets/{oauth-api-BjSUDIgq.js → oauth-api-8lP_qJpq.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CAJeUXeU.js → product-open-page-CxGGlWA8.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CfebYVX0.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-48GvzSVa.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BhGKnvLP.js → registry-api-CIsNlSBi.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-64xj_s2m.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DH6EilMV.js → runtime-tools-settings-panel-YkjhiQfA.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-DYHmEZeZ.js → schema-form-oFGf3G3s.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CcwcdRN8.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BaN84CyW.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-BHwPd_M3.js → settings-page-C7VWs0IT.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DVVOCNbr.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BjwrS03F.js → share-preview-page-t5oz18rh.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DUYbYLi7.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BGyD0gB9.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-OHyK25op.js → skills-page-CjF8DTsN.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DQx9ulmg.js → skills-page.utils-DEDTYs2W.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-wO7DWv4C.js → system-settings-panel-BSYuRgFI.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-YZYSTJH7.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-hybK3oC9.js → theme-store-O597U8q_.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-CVC8BHZu.js → tunnel-api-FKUi9wDL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DMvRu2XZ.js → use-autosave-B5eUJ6Zq.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-BCyiduKd.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DuBK2NDG.js → voice-api-key-field-CMKSwz4C.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-CBbiF1T3.js → voice-config-api-q7B6fOFB.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-B7VXWpDr.js → work-discovery-overlay-jhT2EzeH.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BokVAsWN.js → workflow-run-setup-panel-DZmvLZjb.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DQC0TpMa.js +5 -0
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/src/agent/commands/command-registry.d.ts +1 -0
- package/dist/src/agent/commands/command-registry.js +12 -22
- package/dist/src/agent/ipc/inbox.d.ts +8 -31
- package/dist/src/agent/ipc/inbox.js +64 -133
- package/dist/src/agent/service/process-direct-one-shot.js +15 -10
- package/dist/src/agent/workflow/catalog.d.ts +1 -8
- package/dist/src/agent/workflow/catalog.js +44 -102
- package/dist/src/agent/workflow/index.d.ts +1 -1
- package/dist/src/agent/workflow/index.js +2 -2
- package/dist/src/automations/domain/types.d.ts +1 -0
- package/dist/src/automations/service/action-executor.js +2 -2
- package/dist/src/automations/service/automation-service.js +2 -2
- package/dist/src/channels/manager.d.ts +1 -1
- package/dist/src/channels/manager.js +2 -2
- package/dist/src/channels/outbound/persist-store.d.ts +2 -8
- package/dist/src/channels/outbound/persist-store.js +11 -38
- package/dist/src/channels/outbound-sender.d.ts +1 -1
- package/dist/src/channels/outbound-sender.js +2 -2
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/schema.js +2 -2
- package/dist/src/connectors/auth-provider-registry.js +1 -1
- package/dist/src/connectors/composio-triggers.d.ts +2 -2
- package/dist/src/connectors/composio-triggers.js +8 -15
- package/dist/src/connectors/connected-source-ingestion.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/gateway/automation-agent-session.js +3 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +8 -25
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +3 -3
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/projects.js +1 -1
- package/dist/src/gateway/hono/routes/you.js +20 -4
- package/dist/src/gateway/service.js +4 -5
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/notes/index.d.ts +1 -1
- package/dist/src/notes/index.js +2 -2
- package/dist/src/notes/paths.d.ts +0 -3
- package/dist/src/notes/paths.js +1 -10
- package/dist/src/notes/service.d.ts +0 -1
- package/dist/src/notes/service.js +0 -3
- package/dist/src/notes/store.d.ts +0 -2
- package/dist/src/notes/store.js +33 -80
- package/dist/src/share/hosted-session-share.d.ts +1 -4
- package/dist/src/share/hosted-session-share.js +14 -47
- package/dist/src/share/share-auto.d.ts +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.d.ts +2 -7
- package/dist/src/share/share-store.js +153 -195
- package/dist/src/share/share-types.d.ts +0 -4
- package/dist/src/share/site-share-store.d.ts +3 -8
- package/dist/src/share/site-share-store.js +94 -153
- package/dist/src/share/site-share-types.d.ts +0 -4
- package/dist/src/storage/sqlite/connection.d.ts +1 -2
- package/dist/src/storage/sqlite/connection.js +50 -47
- package/dist/src/storage/sqlite/durable-queue.d.ts +16 -0
- package/dist/src/storage/sqlite/durable-queue.js +52 -0
- package/dist/src/storage/sqlite/durable-state.d.ts +16 -0
- package/dist/src/storage/sqlite/durable-state.js +43 -0
- package/dist/src/storage/sqlite/migrations/146_understanding_focus_exclusions.sql +9 -0
- package/dist/src/storage/sqlite/migrations/147_durable_application_state.sql +39 -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/storage/sqlite/understanding-focus-exclusions.d.ts +2 -0
- package/dist/src/storage/sqlite/understanding-focus-exclusions.js +24 -0
- package/dist/src/tui/tui-scoped-models.js +9 -6
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/voice/dashscope/streaming-tts-stream.js +49 -0
- package/dist/src/voice/realtime/agentEngine.js +63 -18
- package/dist/src/voice/realtime/conversationTurn.d.ts +20 -0
- package/dist/src/voice/realtime/conversationTurn.js +83 -0
- package/dist/src/voice/realtime/omniEngine.js +72 -18
- package/dist/src/workflows/authoring/workflow-draft-store.d.ts +1 -5
- package/dist/src/workflows/authoring/workflow-draft-store.js +23 -43
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/store/event-store.d.ts +1 -2
- package/dist/src/workflows/store/event-store.js +19 -64
- package/dist/src/workflows/store/paths.d.ts +0 -2
- package/dist/src/workflows/store/paths.js +1 -7
- package/dist/src/workflows/store/run-store.d.ts +0 -1
- package/dist/src/workflows/store/run-store.js +1 -24
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-0dRjnL2s.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-EpUZsl4h.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BGQdHrip.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DJGcm7rH.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-BcIr-_GM.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DNHqaZfX.js +0 -2
- package/dist/gateway/static/root/assets/home-page-CaVvW77l.js +0 -1
- package/dist/gateway/static/root/assets/index-Dbh5SXyV.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-D3K1XmOM.js +0 -2
- package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-CI30cDh3.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-jO_4I5zN.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BrTGFME0.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CH70D5SH.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-hbfUNtNs.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Vg3_jua6.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DkcpWSss.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BL4DEt6p.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CafhNktn.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-anyomXsu.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-BBk9YdBn.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-RUTv0yvR.js +0 -5
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
+
import { requireXopcDatabase } from "../storage/sqlite/connection.js";
|
|
5
|
+
import { runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
4
6
|
import { init_paths } from "../config/paths.js";
|
|
7
|
+
import { DurableState } from "../storage/sqlite/durable-state.js";
|
|
5
8
|
import { SHARE_CONFIG_DEFAULTS } from "./share-types.js";
|
|
6
9
|
import { isPathUnderWorkspace } from "../gateway/workspace-editor-path.js";
|
|
7
10
|
import { logShareAudit } from "./share-audit.js";
|
|
8
11
|
import { join, relative, resolve } from "node:path";
|
|
9
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
12
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
11
13
|
import { lstat, readdir, realpath, rm, stat } from "node:fs/promises";
|
|
12
14
|
//#region src/share/share-store.ts
|
|
13
15
|
init_paths();
|
|
14
16
|
init_logger();
|
|
15
17
|
const log = createLogger("ShareStore");
|
|
16
|
-
const SHARES_FILE = "shares.json";
|
|
17
18
|
const CLEANUP_INTERVAL_MS = 10 * 6e4;
|
|
18
19
|
const EXPIRED_RETENTION_MS = 1440 * 6e4;
|
|
19
|
-
const MAX_STORED_RECORDS = 500;
|
|
20
|
-
const TRUNCATE_TO = 200;
|
|
21
|
-
const COUNTER_DEBOUNCE_MS = 2e3;
|
|
22
|
-
function resolveSharesPath() {
|
|
23
|
-
return join(resolveStateDir(), SHARES_FILE);
|
|
24
|
-
}
|
|
25
20
|
var ShareStore = class {
|
|
26
|
-
shares =
|
|
27
|
-
tokenIndex = /* @__PURE__ */ new Map();
|
|
28
|
-
dirty = false;
|
|
29
|
-
debounceTimer = null;
|
|
21
|
+
shares = new DurableState("shares");
|
|
30
22
|
cleanupTimer = null;
|
|
31
23
|
config;
|
|
32
24
|
listingCache = /* @__PURE__ */ new Map();
|
|
@@ -37,9 +29,15 @@ var ShareStore = class {
|
|
|
37
29
|
...SHARE_CONFIG_DEFAULTS,
|
|
38
30
|
...config
|
|
39
31
|
};
|
|
40
|
-
this.load();
|
|
41
32
|
this.startCleanupTimer();
|
|
42
33
|
}
|
|
34
|
+
saveNew(record) {
|
|
35
|
+
requireXopcDatabase();
|
|
36
|
+
runSqliteWriteTransaction(() => {
|
|
37
|
+
if (this.getActiveShares().length >= this.config.maxActiveShares) throw new Error("Maximum active shares reached");
|
|
38
|
+
this.shares.set(record.id, record);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
43
41
|
updateConfig(config) {
|
|
44
42
|
this.config = {
|
|
45
43
|
...this.config,
|
|
@@ -193,8 +191,7 @@ var ShareStore = class {
|
|
|
193
191
|
...common,
|
|
194
192
|
kind: "file"
|
|
195
193
|
};
|
|
196
|
-
this.
|
|
197
|
-
this.tokenIndex.set(token, id);
|
|
194
|
+
this.saveNew(record);
|
|
198
195
|
return record;
|
|
199
196
|
}
|
|
200
197
|
createNoteShare(input) {
|
|
@@ -226,8 +223,7 @@ var ShareStore = class {
|
|
|
226
223
|
createdByTokenHash: input.gatewayTokenHash,
|
|
227
224
|
description: input.description
|
|
228
225
|
};
|
|
229
|
-
this.
|
|
230
|
-
this.tokenIndex.set(record.token, record.id);
|
|
226
|
+
this.saveNew(record);
|
|
231
227
|
this.persistAndAudit(record, "share.create", `Note share created: ${record.fileName}`, {
|
|
232
228
|
noteId: record.sourceNoteId,
|
|
233
229
|
sourceVersion: record.sourceVersion,
|
|
@@ -237,20 +233,23 @@ var ShareStore = class {
|
|
|
237
233
|
return record;
|
|
238
234
|
}
|
|
239
235
|
updateNoteSnapshot(id, patch) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
236
|
+
requireXopcDatabase();
|
|
237
|
+
return runSqliteWriteTransaction(() => {
|
|
238
|
+
const record = this.shares.get(id);
|
|
239
|
+
if (!record || record.kind !== "note") return null;
|
|
240
|
+
record.sourceVersion = patch.sourceVersion;
|
|
241
|
+
record.fileSize = patch.artifactSize;
|
|
242
|
+
record.attachmentCount = patch.attachmentCount;
|
|
243
|
+
record.fileName = patch.fileName;
|
|
244
|
+
record.snapshotRevision += 1;
|
|
245
|
+
this.shares.set(record.id, record);
|
|
246
|
+
logShareAudit("share.update", {
|
|
247
|
+
shareId: id,
|
|
248
|
+
noteId: record.sourceNoteId,
|
|
249
|
+
snapshotRevision: record.snapshotRevision
|
|
250
|
+
}, `Note share snapshot updated: ${record.fileName}`);
|
|
251
|
+
return record;
|
|
252
|
+
});
|
|
254
253
|
}
|
|
255
254
|
getNoteShares(noteId) {
|
|
256
255
|
return this.getAllShares().filter((record) => record.kind === "note" && record.sourceNoteId === noteId);
|
|
@@ -286,8 +285,7 @@ var ShareStore = class {
|
|
|
286
285
|
createdByTokenHash: input.gatewayTokenHash,
|
|
287
286
|
description: input.description
|
|
288
287
|
};
|
|
289
|
-
this.
|
|
290
|
-
this.tokenIndex.set(record.token, record.id);
|
|
288
|
+
this.saveNew(record);
|
|
291
289
|
this.persistAndAudit(record, "share.create", `Session share created: ${record.fileName}`, {
|
|
292
290
|
sourceSessionId: record.sourceSessionId,
|
|
293
291
|
cutoffSeq: record.cutoffSeq,
|
|
@@ -300,26 +298,29 @@ var ShareStore = class {
|
|
|
300
298
|
return this.getAllShares().filter((record) => record.kind === "session" && record.sourceSessionId === sessionId);
|
|
301
299
|
}
|
|
302
300
|
updateSessionSnapshot(id, patch) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
301
|
+
requireXopcDatabase();
|
|
302
|
+
return runSqliteWriteTransaction(() => {
|
|
303
|
+
const record = this.shares.get(id);
|
|
304
|
+
if (!record || record.kind !== "session") return null;
|
|
305
|
+
record.cutoffSeq = patch.cutoffSeq;
|
|
306
|
+
record.fileSize = patch.artifactSize;
|
|
307
|
+
record.messageCount = patch.messageCount;
|
|
308
|
+
record.attachmentCount = patch.attachmentCount;
|
|
309
|
+
record.includeToolActivities = patch.includeToolActivities;
|
|
310
|
+
record.fileName = patch.fileName;
|
|
311
|
+
record.snapshotRevision += 1;
|
|
312
|
+
this.shares.set(record.id, record);
|
|
313
|
+
logShareAudit("share.update", {
|
|
314
|
+
shareId: id,
|
|
315
|
+
sourceSessionId: record.sourceSessionId,
|
|
316
|
+
cutoffSeq: record.cutoffSeq,
|
|
317
|
+
snapshotRevision: record.snapshotRevision
|
|
318
|
+
}, `Session share snapshot updated: ${record.fileName}`);
|
|
319
|
+
return record;
|
|
320
|
+
});
|
|
320
321
|
}
|
|
321
322
|
persistAndAudit(record, event, message, extra) {
|
|
322
|
-
this.
|
|
323
|
+
this.shares.set(record.id, record);
|
|
323
324
|
logShareAudit(event, {
|
|
324
325
|
shareId: record.id,
|
|
325
326
|
tokenPrefix: record.token.slice(0, 8),
|
|
@@ -330,9 +331,7 @@ var ShareStore = class {
|
|
|
330
331
|
return this.shares.get(id) ?? null;
|
|
331
332
|
}
|
|
332
333
|
getByToken(token) {
|
|
333
|
-
|
|
334
|
-
if (!id) return null;
|
|
335
|
-
return this.shares.get(id) ?? null;
|
|
334
|
+
return this.shares.values().find((record) => record.token === token) ?? null;
|
|
336
335
|
}
|
|
337
336
|
/** Validate a share is still accessible for download. Returns null reason if valid. */
|
|
338
337
|
validateAccess(record) {
|
|
@@ -350,28 +349,40 @@ var ShareStore = class {
|
|
|
350
349
|
};
|
|
351
350
|
return { valid: true };
|
|
352
351
|
}
|
|
353
|
-
/** Increment download counter (used by directory & file downloads).
|
|
352
|
+
/** Increment download counter (used by directory & file downloads). Persisted before returning. */
|
|
354
353
|
incrementDownloadCount(id) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
this.shares.update(id, (record) => {
|
|
355
|
+
if (record) record.downloadCount++;
|
|
356
|
+
return {
|
|
357
|
+
value: record,
|
|
358
|
+
result: void 0
|
|
359
|
+
};
|
|
360
|
+
});
|
|
359
361
|
}
|
|
360
362
|
/** Atomically validate and consume one access in the single-threaded store. */
|
|
361
363
|
consumeAccess(id) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
364
|
+
return this.shares.update(id, (record) => {
|
|
365
|
+
if (!record) return {
|
|
366
|
+
value: void 0,
|
|
367
|
+
result: {
|
|
368
|
+
valid: false,
|
|
369
|
+
reason: "not_found"
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
const validation = this.validateAccess(record);
|
|
373
|
+
if (!validation.valid) return {
|
|
374
|
+
value: record,
|
|
375
|
+
result: {
|
|
376
|
+
valid: false,
|
|
377
|
+
reason: validation.reason ?? "access_denied"
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
record.downloadCount++;
|
|
381
|
+
return {
|
|
382
|
+
value: record,
|
|
383
|
+
result: { valid: true }
|
|
384
|
+
};
|
|
385
|
+
});
|
|
375
386
|
}
|
|
376
387
|
/** Check if the file still exists and inode matches. */
|
|
377
388
|
async validateFileIntegrity(record) {
|
|
@@ -504,74 +515,89 @@ var ShareStore = class {
|
|
|
504
515
|
}
|
|
505
516
|
/** Update thumbnail status. Persists immediately so generator restart is safe. */
|
|
506
517
|
setThumbnailStatus(id, status) {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
518
|
+
requireXopcDatabase();
|
|
519
|
+
return runSqliteWriteTransaction(() => {
|
|
520
|
+
const record = this.shares.get(id);
|
|
521
|
+
if (!record) return;
|
|
522
|
+
record.thumbnailStatus = status;
|
|
523
|
+
if (status === "ready") record.thumbnailGeneratedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
524
|
+
if (status === "failed") record.thumbnailFailedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
525
|
+
this.shares.set(record.id, record);
|
|
526
|
+
});
|
|
513
527
|
}
|
|
514
528
|
/** Drop the listing cache for a share (used on revoke/update). */
|
|
515
529
|
invalidateListingCache(shareId) {
|
|
516
530
|
for (const key of this.listingCache.keys()) if (key.startsWith(`${shareId}::`)) this.listingCache.delete(key);
|
|
517
531
|
}
|
|
518
532
|
revoke(id) {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
533
|
+
requireXopcDatabase();
|
|
534
|
+
return runSqliteWriteTransaction(() => {
|
|
535
|
+
const record = this.shares.get(id);
|
|
536
|
+
if (!record) return false;
|
|
537
|
+
record.revoked = true;
|
|
538
|
+
this.cleanupStateArtifact(record);
|
|
539
|
+
this.invalidateListingCache(id);
|
|
540
|
+
this.shares.set(record.id, record);
|
|
541
|
+
logShareAudit("share.revoke", {
|
|
542
|
+
shareId: id,
|
|
543
|
+
tokenPrefix: record.token.slice(0, 8),
|
|
544
|
+
fileName: record.fileName
|
|
545
|
+
}, `Share revoked: ${record.fileName}`);
|
|
546
|
+
return true;
|
|
547
|
+
});
|
|
531
548
|
}
|
|
532
549
|
revokeMany(ids) {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
550
|
+
requireXopcDatabase();
|
|
551
|
+
return runSqliteWriteTransaction(() => {
|
|
552
|
+
let count = 0;
|
|
553
|
+
for (const id of ids) {
|
|
554
|
+
const record = this.shares.get(id);
|
|
555
|
+
if (record && !record.revoked) {
|
|
556
|
+
record.revoked = true;
|
|
557
|
+
this.shares.set(record.id, record);
|
|
558
|
+
this.cleanupStateArtifact(record);
|
|
559
|
+
this.invalidateListingCache(id);
|
|
560
|
+
count++;
|
|
561
|
+
logShareAudit("share.revoke", {
|
|
562
|
+
shareId: id,
|
|
563
|
+
tokenPrefix: record.token.slice(0, 8),
|
|
564
|
+
fileName: record.fileName
|
|
565
|
+
}, `Share revoked (batch): ${record.fileName}`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return count;
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
revokeExpired() {
|
|
572
|
+
requireXopcDatabase();
|
|
573
|
+
return runSqliteWriteTransaction(() => {
|
|
574
|
+
const now = Date.now();
|
|
575
|
+
let count = 0;
|
|
576
|
+
for (const record of this.shares.values()) if (!record.revoked && now >= new Date(record.expiresAt).getTime()) {
|
|
537
577
|
record.revoked = true;
|
|
578
|
+
this.shares.set(record.id, record);
|
|
538
579
|
this.cleanupStateArtifact(record);
|
|
539
|
-
this.invalidateListingCache(id);
|
|
580
|
+
this.invalidateListingCache(record.id);
|
|
540
581
|
count++;
|
|
541
|
-
logShareAudit("share.revoke", {
|
|
542
|
-
shareId: id,
|
|
543
|
-
tokenPrefix: record.token.slice(0, 8),
|
|
544
|
-
fileName: record.fileName
|
|
545
|
-
}, `Share revoked (batch): ${record.fileName}`);
|
|
546
582
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
return count;
|
|
550
|
-
}
|
|
551
|
-
revokeExpired() {
|
|
552
|
-
const now = Date.now();
|
|
553
|
-
let count = 0;
|
|
554
|
-
for (const record of this.shares.values()) if (!record.revoked && now >= new Date(record.expiresAt).getTime()) {
|
|
555
|
-
record.revoked = true;
|
|
556
|
-
this.cleanupStateArtifact(record);
|
|
557
|
-
this.invalidateListingCache(record.id);
|
|
558
|
-
count++;
|
|
559
|
-
}
|
|
560
|
-
if (count > 0) this.persistSync();
|
|
561
|
-
return count;
|
|
583
|
+
return count;
|
|
584
|
+
});
|
|
562
585
|
}
|
|
563
586
|
update(id, patch) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
587
|
+
requireXopcDatabase();
|
|
588
|
+
return runSqliteWriteTransaction(() => {
|
|
589
|
+
const record = this.shares.get(id);
|
|
590
|
+
if (!record) return null;
|
|
591
|
+
if (patch.extendTtlMs !== void 0) record.expiresAt = new Date(Date.now() + patch.extendTtlMs).toISOString();
|
|
592
|
+
if (patch.maxViews !== void 0) record.maxViews = patch.maxViews;
|
|
593
|
+
this.shares.set(record.id, record);
|
|
594
|
+
logShareAudit("share.update", {
|
|
595
|
+
shareId: id,
|
|
596
|
+
tokenPrefix: record.token.slice(0, 8),
|
|
597
|
+
patch
|
|
598
|
+
}, `Share updated: ${record.fileName}`);
|
|
599
|
+
return record;
|
|
600
|
+
});
|
|
575
601
|
}
|
|
576
602
|
getActiveShares() {
|
|
577
603
|
const now = Date.now();
|
|
@@ -580,62 +606,6 @@ var ShareStore = class {
|
|
|
580
606
|
getAllShares() {
|
|
581
607
|
return [...this.shares.values()].sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
582
608
|
}
|
|
583
|
-
load() {
|
|
584
|
-
const path = resolveSharesPath();
|
|
585
|
-
if (!existsSync(path)) return;
|
|
586
|
-
try {
|
|
587
|
-
const raw = readFileSync(path, "utf8");
|
|
588
|
-
const data = JSON.parse(raw);
|
|
589
|
-
if (data.version !== 1 && data.version !== 2 || !Array.isArray(data.shares)) return;
|
|
590
|
-
const now = Date.now();
|
|
591
|
-
let cleaned = 0;
|
|
592
|
-
for (const record of data.shares) {
|
|
593
|
-
if (now - new Date(record.expiresAt).getTime() > EXPIRED_RETENTION_MS) {
|
|
594
|
-
cleaned++;
|
|
595
|
-
continue;
|
|
596
|
-
}
|
|
597
|
-
this.shares.set(record.id, record);
|
|
598
|
-
this.tokenIndex.set(record.token, record.id);
|
|
599
|
-
}
|
|
600
|
-
if (cleaned > 0) {
|
|
601
|
-
log.info({ cleaned }, `Cleaned ${cleaned} expired share records on load`);
|
|
602
|
-
this.persistSync();
|
|
603
|
-
}
|
|
604
|
-
} catch (err) {
|
|
605
|
-
log.warn({ err }, "Failed to load shares.json");
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
persistSync() {
|
|
609
|
-
const path = resolveSharesPath();
|
|
610
|
-
mkdirSync(resolveStateDir(), { recursive: true });
|
|
611
|
-
let records = [...this.shares.values()];
|
|
612
|
-
if (records.length > MAX_STORED_RECORDS) {
|
|
613
|
-
records.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
614
|
-
records = records.filter((r) => !r.revoked && Date.now() < new Date(r.expiresAt).getTime()).slice(0, TRUNCATE_TO);
|
|
615
|
-
this.shares.clear();
|
|
616
|
-
this.tokenIndex.clear();
|
|
617
|
-
for (const r of records) {
|
|
618
|
-
this.shares.set(r.id, r);
|
|
619
|
-
this.tokenIndex.set(r.token, r.id);
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
writeFileSync(path, `${JSON.stringify({
|
|
623
|
-
version: 2,
|
|
624
|
-
shares: records
|
|
625
|
-
}, null, 2)}\n`, "utf8");
|
|
626
|
-
}
|
|
627
|
-
scheduleDebouncedPersist() {
|
|
628
|
-
this.dirty = true;
|
|
629
|
-
if (this.debounceTimer) return;
|
|
630
|
-
this.debounceTimer = setTimeout(() => {
|
|
631
|
-
this.debounceTimer = null;
|
|
632
|
-
if (this.dirty) {
|
|
633
|
-
this.dirty = false;
|
|
634
|
-
this.persistSync();
|
|
635
|
-
}
|
|
636
|
-
}, COUNTER_DEBOUNCE_MS);
|
|
637
|
-
this.debounceTimer.unref?.();
|
|
638
|
-
}
|
|
639
609
|
startCleanupTimer() {
|
|
640
610
|
this.cleanupTimer = setInterval(() => {
|
|
641
611
|
this.cleanupExpired();
|
|
@@ -650,7 +620,6 @@ var ShareStore = class {
|
|
|
650
620
|
if (expiredMs >= 0) this.cleanupStateArtifact(record);
|
|
651
621
|
if (expiredMs > EXPIRED_RETENTION_MS) {
|
|
652
622
|
this.shares.delete(id);
|
|
653
|
-
this.tokenIndex.delete(record.token);
|
|
654
623
|
this.invalidateListingCache(id);
|
|
655
624
|
if (this.onCleanup) try {
|
|
656
625
|
this.onCleanup(record);
|
|
@@ -663,24 +632,13 @@ var ShareStore = class {
|
|
|
663
632
|
removed++;
|
|
664
633
|
}
|
|
665
634
|
}
|
|
666
|
-
if (removed > 0) {
|
|
667
|
-
this.persistSync();
|
|
668
|
-
log.debug({ removed }, `Cleaned ${removed} expired shares`);
|
|
669
|
-
}
|
|
635
|
+
if (removed > 0) log.debug({ removed }, `Cleaned ${removed} expired shares`);
|
|
670
636
|
}
|
|
671
637
|
shutdown() {
|
|
672
638
|
if (this.cleanupTimer) {
|
|
673
639
|
clearInterval(this.cleanupTimer);
|
|
674
640
|
this.cleanupTimer = null;
|
|
675
641
|
}
|
|
676
|
-
if (this.debounceTimer) {
|
|
677
|
-
clearTimeout(this.debounceTimer);
|
|
678
|
-
this.debounceTimer = null;
|
|
679
|
-
}
|
|
680
|
-
if (this.dirty) {
|
|
681
|
-
this.dirty = false;
|
|
682
|
-
this.persistSync();
|
|
683
|
-
}
|
|
684
642
|
this.listingCache.clear();
|
|
685
643
|
}
|
|
686
644
|
async resolveAndValidatePath(relPath, workspaceRoot) {
|
|
@@ -126,10 +126,6 @@ export interface CreateShareParams {
|
|
|
126
126
|
/** Directory: walk depth cap (default 20). */
|
|
127
127
|
maxDepth?: number;
|
|
128
128
|
}
|
|
129
|
-
export interface ShareStoreData {
|
|
130
|
-
version: 1 | 2;
|
|
131
|
-
shares: ShareRecord[];
|
|
132
|
-
}
|
|
133
129
|
export type ShareReachability = 'public' | 'lan' | 'local-only';
|
|
134
130
|
export interface ResolvedShareUrl {
|
|
135
131
|
shareUrl: string;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { type CreateSiteShareParams, type SiteShareConfig, type SiteShareRecord } from './site-share-types.js';
|
|
2
2
|
export declare class SiteShareStore {
|
|
3
3
|
private shares;
|
|
4
|
-
private byToken;
|
|
5
|
-
private bySubdomain;
|
|
6
4
|
private config;
|
|
7
|
-
private dirty;
|
|
8
|
-
private debounceTimer;
|
|
9
5
|
private cleanupTimer;
|
|
10
6
|
/** Optional cleanup hook invoked when a record is dropped (e.g. delete staging dir). */
|
|
11
7
|
private onCleanup;
|
|
12
8
|
constructor(config?: Partial<SiteShareConfig>);
|
|
9
|
+
private saveNew;
|
|
13
10
|
updateConfig(config: Partial<SiteShareConfig>): void;
|
|
14
11
|
setCleanupHook(hook: (record: SiteShareRecord) => void): void;
|
|
15
12
|
getConfig(): SiteShareConfig;
|
|
@@ -33,7 +30,7 @@ export declare class SiteShareStore {
|
|
|
33
30
|
valid: boolean;
|
|
34
31
|
reason?: string;
|
|
35
32
|
};
|
|
36
|
-
/** Increment counters when a request lands.
|
|
33
|
+
/** Increment counters when a request lands. Persisted before returning. */
|
|
37
34
|
recordRequest(id: string, clientIp: string): void;
|
|
38
35
|
setThumbnailStatus(id: string, status: 'pending' | 'ready' | 'failed'): void;
|
|
39
36
|
revoke(id: string): boolean;
|
|
@@ -43,9 +40,7 @@ export declare class SiteShareStore {
|
|
|
43
40
|
extendTtlMs?: number;
|
|
44
41
|
maxRequests?: number | null;
|
|
45
42
|
}): SiteShareRecord | null;
|
|
46
|
-
private
|
|
47
|
-
private persistSync;
|
|
48
|
-
private scheduleDebouncedPersist;
|
|
43
|
+
private hasSubdomain;
|
|
49
44
|
private startCleanupTimer;
|
|
50
45
|
shutdown(): void;
|
|
51
46
|
}
|