codex-overleaf-link 2.5.0 → 2.5.1
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/README.md +38 -26
- package/README.zh-CN.md +39 -27
- package/extension/bootstrap/background.js +52 -9
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/bootstrap/popup.html +1 -0
- package/extension/bootstrap/popupFallback.js +55 -0
- package/extension/bootstrap/updateStatus.js +1 -0
- package/extension/src/background.js +206 -53
- package/extension/src/backgroundBootstrapMigration.js +181 -0
- package/extension/src/backgroundSharedSessions.js +74 -14
- package/extension/src/backgroundUpdateCoordinator.js +118 -21
- package/extension/src/backgroundUpdateSafety.js +173 -0
- package/extension/src/content/activeTurnControl.js +8 -2
- package/extension/src/content/applyResultFormatters.js +46 -73
- package/extension/src/content/assetTransferBroker.js +72 -14
- package/extension/src/content/composerAttachments.js +93 -45
- package/extension/src/content/composerPanel.js +18 -0
- package/extension/src/content/contentRuntime.js +661 -676
- package/extension/src/content/diagnosticsController.js +122 -96
- package/extension/src/content/diagnosticsExport.js +19 -5
- package/extension/src/content/diagnosticsPanel.js +30 -0
- package/extension/src/content/directoryCleanupRecovery.js +54 -0
- package/extension/src/content/generated/content.bundle.js +6879 -2786
- package/extension/src/content/generated/content.bundle.meta.json +11 -3
- package/extension/src/content/globalPreferencesController.js +1 -1
- package/extension/src/content/legacyGlobalRegistry.js +6 -0
- package/extension/src/content/localSkillsPanel.js +102 -12
- package/extension/src/content/markdownText.js +5 -6
- package/extension/src/content/modelPicker.js +7 -4
- package/extension/src/content/nativeCompatibilityController.js +45 -20
- package/extension/src/content/otWarmMirror.js +4 -5
- package/extension/src/content/otWarmMirrorController.js +17 -20
- package/extension/src/content/pageBridgeClient.js +15 -2
- package/extension/src/content/panelMaintenance.js +40 -12
- package/extension/src/content/panelRenderer.js +6 -0
- package/extension/src/content/projectProviderSelection.js +13 -4
- package/extension/src/content/projectSessionCleanup.js +109 -62
- package/extension/src/content/projectSettingsCoordinator.js +39 -2
- package/extension/src/content/providerSettingsCoordinator.js +46 -8
- package/extension/src/content/providerSettingsDialog.js +71 -13
- package/extension/src/content/recentProjects.js +11 -5
- package/extension/src/content/runActivitySummary.js +40 -6
- package/extension/src/content/runCompletionMeta.js +344 -0
- package/extension/src/content/runController.js +37 -14
- package/extension/src/content/runFailureNotice.js +21 -12
- package/extension/src/content/runGuidanceController.js +72 -27
- package/extension/src/content/runGuidanceView.js +59 -10
- package/extension/src/content/runQueueScheduler.js +148 -42
- package/extension/src/content/runRecoveryActions.js +146 -0
- package/extension/src/content/runResultActions.js +8 -125
- package/extension/src/content/runReviewController.js +574 -0
- package/extension/src/content/runScrollLayout.js +21 -2
- package/extension/src/content/runTimelineView.js +146 -153
- package/extension/src/content/scopedPersistencePanelState.js +51 -6
- package/extension/src/content/selectionContextView.js +1 -1
- package/extension/src/content/sensitivePreflight.js +140 -0
- package/extension/src/content/sessionForkController.js +80 -17
- package/extension/src/content/sessionManager.js +1 -1
- package/extension/src/content/settingsPanel.js +7 -3
- package/extension/src/content/settingsWorkbench.js +5 -0
- package/extension/src/content/sharedSessionViewSync.js +45 -8
- package/extension/src/content/updateIdle.js +4 -1
- package/extension/src/content/updateNotice.js +60 -8
- package/extension/src/content/updateSafetyReceiver.js +58 -0
- package/extension/src/content/writebackController.js +53 -4
- package/extension/src/content/writebackOrchestrator.js +82 -73
- package/extension/src/content/writingStyleSettings.js +35 -11
- package/extension/src/page/binaryAssetUploader.js +136 -14
- package/extension/src/page/fileMover.js +256 -0
- package/extension/src/page/ownedDirectoryCleanup.js +94 -0
- package/extension/src/page/referenceProjects.js +1 -0
- package/extension/src/page/reviewContext.js +113 -0
- package/extension/src/page/saveState.js +6 -4
- package/extension/src/page/snapshotRouter.js +84 -39
- package/extension/src/page/textFileCreator.js +105 -25
- package/extension/src/page/trackedChangeCapture.js +12 -2
- package/extension/src/page/trackedChangeOwnership.js +19 -1
- package/extension/src/page/trackedChangeReplay.js +41 -21
- package/extension/src/page/trackedChangesLifecycle.js +217 -199
- package/extension/src/page/treeOperations.js +7 -10
- package/extension/src/page/updateSafetyProbe.js +41 -0
- package/extension/src/page/writebackReceiptJournal.js +2 -0
- package/extension/src/page/writebackRouter.js +80 -79
- package/extension/src/pageBridge.js +19 -3
- package/extension/src/popup.js +62 -10
- package/extension/src/shared/agentTranscript.js +23 -0
- package/extension/src/shared/auditRecords.js +2 -0
- package/extension/src/shared/compatibility.js +22 -6
- package/extension/src/shared/compileAdapter.js +79 -57
- package/extension/src/shared/composerAttachmentDraft.js +151 -0
- package/extension/src/shared/directoryCleanupProof.js +43 -0
- package/extension/src/shared/failureReasons.js +309 -3
- package/extension/src/shared/globalPreferences.js +30 -13
- package/extension/src/shared/governanceRules.js +4 -37
- package/extension/src/shared/i18n.js +298 -2
- package/extension/src/shared/managedUpdateProjection.js +2 -2
- package/extension/src/shared/nativeRequestIdentity.js +1 -0
- package/extension/src/shared/pageRpcContract.js +5 -4
- package/extension/src/shared/projectFiles.js +21 -44
- package/extension/src/shared/providerProfiles.js +5 -3
- package/extension/src/shared/runInputQueue.js +48 -5
- package/extension/src/shared/selectionContext.js +12 -3
- package/extension/src/shared/sessionState.js +72 -27
- package/extension/src/shared/settlementFacts.js +10 -2
- package/extension/src/shared/sharedSessionBridge.js +37 -14
- package/extension/src/shared/sharedSessionTransfer.js +140 -0
- package/extension/src/shared/staleGuard.js +118 -13
- package/extension/src/shared/storageDb.js +58 -26
- package/extension/src/shared/storageMigration.js +71 -111
- package/extension/src/shared/storageRunActions.js +209 -26
- package/extension/src/shared/subagentActivityModel.js +1 -1
- package/extension/src/shared/undoOperations.js +136 -13
- package/extension/src/shared/updateConsent.js +6 -4
- package/extension/src/shared/updateRuntimeIdentity.js +1 -1
- package/extension/src/shared/writebackIntent.js +16 -0
- package/extension/src/shared/writebackOperationEvidence.js +4 -15
- package/extension/src/shared/writebackSettlement.js +38 -38
- package/extension/styles/panel.css +19 -5
- package/native-host/src/anthropicBridgeRequest.js +4 -2
- package/native-host/src/anthropicBridgeResponse.js +6 -2
- package/native-host/src/anthropicMessagesBridge.js +24 -16
- package/native-host/src/bootstrapMigration.js +296 -0
- package/native-host/src/bootstrapMigrationContract.js +101 -0
- package/native-host/src/bootstrapUpdate.js +233 -0
- package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
- package/native-host/src/chatBridgeResponse.js +10 -0
- package/native-host/src/chatCompletionsBridge.js +21 -15
- package/native-host/src/codexConfigPaths.js +106 -0
- package/native-host/src/codexHome.js +66 -73
- package/native-host/src/codexHomeScope.js +124 -0
- package/native-host/src/codexInheritedAuth.js +90 -0
- package/native-host/src/codexLocalSkills.js +301 -0
- package/native-host/src/codexPromptAssembly.js +31 -12
- package/native-host/src/codexProviderTest.js +24 -26
- package/native-host/src/codexSessionRunner.js +110 -183
- package/native-host/src/codexSessionTiming.js +18 -8
- package/native-host/src/codexSkillIsolation.js +170 -0
- package/native-host/src/codexThreadFork.js +19 -3
- package/native-host/src/index.js +19 -7
- package/native-host/src/managedInstall.js +110 -35
- package/native-host/src/managedInstallRecovery.js +140 -0
- package/native-host/src/managedRuntimeEvidence.js +57 -0
- package/native-host/src/mirrorWorkspace.js +92 -22
- package/native-host/src/nativeDoctor.js +15 -0
- package/native-host/src/nativeHelperLifecycle.js +21 -0
- package/native-host/src/nativeHostRegistration.js +33 -0
- package/native-host/src/nativeRunLifecycle.js +71 -0
- package/native-host/src/processStopBarrier.js +42 -7
- package/native-host/src/projectPathPlatform.js +30 -0
- package/native-host/src/providerHttp.js +80 -0
- package/native-host/src/providerProfile.js +4 -2
- package/native-host/src/providerReasoning.js +2 -7
- package/native-host/src/providerRuntime.js +1 -0
- package/native-host/src/providerStore.js +72 -14
- package/native-host/src/responsesPassthroughBridge.js +266 -52
- package/native-host/src/runtimeInstaller.js +21 -1
- package/native-host/src/selectionScope.js +36 -8
- package/native-host/src/subagentAdmission.js +26 -0
- package/native-host/src/subagentBroker.js +79 -66
- package/native-host/src/subagentTelemetry.js +19 -10
- package/native-host/src/subagentWorkspacePath.js +5 -2
- package/native-host/src/taskRunnerRuntime.js +77 -54
- package/native-host/src/tomlStatements.js +140 -0
- package/native-host/src/updateManager.js +297 -39
- package/native-host/src/writingStyleRuntime.js +57 -29
- package/native-host/src/writingStyleStore.js +73 -0
- package/package.json +1 -1
- package/scripts/install-managed.mjs +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
3
|
+
else root.CodexOverleafModuleRegistry.define('SharedSessionTransfer', [], factory);
|
|
4
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function () {
|
|
5
|
+
'use strict';
|
|
6
|
+
const MAX_WIRE_BYTES = 24 * 1024 * 1024;
|
|
7
|
+
// The old UTF-16 estimate admitted up to 3 UTF-8 bytes per code unit.
|
|
8
|
+
// Retain that finite Unicode window without enlarging ordinary ASCII writes.
|
|
9
|
+
const MAX_RECORD_BYTES = MAX_WIRE_BYTES * 3 / 2;
|
|
10
|
+
const MAX_RESPONSE_BYTES = MAX_RECORD_BYTES;
|
|
11
|
+
const MAX_DECODED_BYTES = 2 * MAX_RECORD_BYTES + 64 * 1024;
|
|
12
|
+
const error = (code, message) => Object.assign(new Error(message), { code });
|
|
13
|
+
const tooLarge = () => error('shared_session_too_large', 'The session batch exceeds the bounded shared storage transfer limit.');
|
|
14
|
+
const invalid = () => error('shared_session_transfer_invalid', 'The shared history transfer is invalid or incomplete.');
|
|
15
|
+
const byteLength = text => new TextEncoder().encode(text).byteLength;
|
|
16
|
+
|
|
17
|
+
function serialize(value, limit) {
|
|
18
|
+
// Count a lower bound during serialization, before a large aggregate string
|
|
19
|
+
// can be produced. The final UTF-8 check also includes commas and escaping.
|
|
20
|
+
let lowerBound = 0;
|
|
21
|
+
const text = JSON.stringify(value, function (key, item) {
|
|
22
|
+
if (key && !Array.isArray(this)) lowerBound += byteLength(JSON.stringify(key)) + 1;
|
|
23
|
+
if (typeof item === 'string') {
|
|
24
|
+
if (item.length > limit) throw tooLarge();
|
|
25
|
+
lowerBound += byteLength(JSON.stringify(item));
|
|
26
|
+
} else if (item === null) lowerBound += 4;
|
|
27
|
+
else if (typeof item === 'number') lowerBound += Number.isFinite(item) ? String(item).length : 4;
|
|
28
|
+
else if (typeof item === 'boolean') lowerBound += String(item).length;
|
|
29
|
+
else if (item && typeof item === 'object') lowerBound += 2;
|
|
30
|
+
if (lowerBound > limit) throw tooLarge();
|
|
31
|
+
return item;
|
|
32
|
+
});
|
|
33
|
+
if (typeof text !== 'string') throw invalid();
|
|
34
|
+
const bytes = byteLength(text);
|
|
35
|
+
if (bytes > limit) throw tooLarge();
|
|
36
|
+
return { text, bytes };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function validateRecord(record) {
|
|
40
|
+
const value = serialize(record, MAX_RECORD_BYTES);
|
|
41
|
+
if (value.bytes > MAX_WIRE_BYTES && value.text.length * 2 > MAX_WIRE_BYTES) throw tooLarge();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function validateResponse(records) { serialize(records, MAX_RESPONSE_BYTES); }
|
|
45
|
+
|
|
46
|
+
function validateEntries(entries) {
|
|
47
|
+
if (!Array.isArray(entries)) throw invalid();
|
|
48
|
+
for (const entry of entries) {
|
|
49
|
+
if (!entry || !entry.record || typeof entry.record !== 'object' || Array.isArray(entry.record)) throw invalid();
|
|
50
|
+
validateRecord(entry.record);
|
|
51
|
+
if (entry.base != null) {
|
|
52
|
+
if (typeof entry.base !== 'object' || Array.isArray(entry.base)) throw invalid();
|
|
53
|
+
// A previously stored merged baseline may be larger than new records;
|
|
54
|
+
// allow a bounded old base so a smaller candidate can repair it.
|
|
55
|
+
serialize(entry.base, MAX_DECODED_BYTES);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function readLimited(stream, limit) {
|
|
61
|
+
const reader = stream.getReader(), chunks = [];
|
|
62
|
+
let length = 0;
|
|
63
|
+
try {
|
|
64
|
+
while (true) {
|
|
65
|
+
const result = await reader.read();
|
|
66
|
+
if (result.done) break;
|
|
67
|
+
length += result.value.byteLength;
|
|
68
|
+
if (length > limit) { await reader.cancel().catch(() => {}); throw tooLarge(); }
|
|
69
|
+
chunks.push(result.value);
|
|
70
|
+
}
|
|
71
|
+
} finally { reader.releaseLock(); }
|
|
72
|
+
const output = new Uint8Array(length); let offset = 0;
|
|
73
|
+
for (const chunk of chunks) { output.set(chunk, offset); offset += chunk.byteLength; }
|
|
74
|
+
return output;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function toBase64(bytes) {
|
|
78
|
+
let text = '';
|
|
79
|
+
for (let i = 0; i < bytes.length; i += 0x8000) text += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
80
|
+
return btoa(text);
|
|
81
|
+
}
|
|
82
|
+
function fromBase64(value) {
|
|
83
|
+
if (typeof value !== 'string' || !value.length || value.length % 4
|
|
84
|
+
|| !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) throw invalid();
|
|
85
|
+
const text = atob(value);
|
|
86
|
+
const bytes = new Uint8Array(text.length);
|
|
87
|
+
for (let i = 0; i < text.length; i++) bytes[i] = text.charCodeAt(i);
|
|
88
|
+
return bytes;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function encode(entries, environment = globalThis) {
|
|
92
|
+
validateEntries(entries);
|
|
93
|
+
const raw = serialize(entries, MAX_DECODED_BYTES);
|
|
94
|
+
if (raw.bytes <= MAX_WIRE_BYTES || (raw.bytes <= MAX_RECORD_BYTES && raw.text.length * 2 <= MAX_WIRE_BYTES)) {
|
|
95
|
+
return { method: 'put', payload: { entries } };
|
|
96
|
+
}
|
|
97
|
+
if (typeof environment.CompressionStream !== 'function') {
|
|
98
|
+
throw error('shared_session_compression_unavailable',
|
|
99
|
+
'Lossless transfer compression is unavailable. History remains in memory; retry with a supported browser.');
|
|
100
|
+
}
|
|
101
|
+
const input = new Blob([raw.text]).stream();
|
|
102
|
+
const packed = await readLimited(input.pipeThrough(new environment.CompressionStream('gzip')),
|
|
103
|
+
Math.floor((MAX_WIRE_BYTES - 1024) * 3 / 4));
|
|
104
|
+
const payload = { encoding: 'gzip-base64', version: 1, decodedBytes: raw.bytes, data: toBase64(packed) };
|
|
105
|
+
serialize(payload, MAX_WIRE_BYTES);
|
|
106
|
+
// A distinct method makes an older worker reject rather than acknowledge
|
|
107
|
+
// an absent `entries` array as a successful empty write.
|
|
108
|
+
return { method: 'put-compressed', payload };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function decode(message, environment = globalThis) {
|
|
112
|
+
if (message.method !== 'put-compressed') {
|
|
113
|
+
const entries = message.method === 'import' ? [{ record: message.record }] : message.entries || [];
|
|
114
|
+
const raw = serialize(entries, MAX_RECORD_BYTES);
|
|
115
|
+
if (raw.bytes > MAX_WIRE_BYTES && raw.text.length * 2 > MAX_WIRE_BYTES) throw tooLarge();
|
|
116
|
+
validateEntries(entries); return entries;
|
|
117
|
+
}
|
|
118
|
+
const payload = { encoding: message.encoding, version: message.version, decodedBytes: message.decodedBytes, data: message.data };
|
|
119
|
+
serialize(payload, MAX_WIRE_BYTES);
|
|
120
|
+
if (message.entries != null || payload.encoding !== 'gzip-base64' || payload.version !== 1
|
|
121
|
+
|| !Number.isSafeInteger(payload.decodedBytes) || payload.decodedBytes < 1 || payload.decodedBytes > MAX_DECODED_BYTES) throw invalid();
|
|
122
|
+
if (typeof environment.DecompressionStream !== 'function') throw error('shared_session_compression_unavailable',
|
|
123
|
+
'Lossless transfer decompression is unavailable. Reload the extension and retry.');
|
|
124
|
+
let bytes;
|
|
125
|
+
try {
|
|
126
|
+
bytes = await readLimited(new Blob([fromBase64(payload.data)]).stream()
|
|
127
|
+
.pipeThrough(new environment.DecompressionStream('gzip')), MAX_DECODED_BYTES);
|
|
128
|
+
} catch (failure) {
|
|
129
|
+
if (['shared_session_too_large', 'shared_session_transfer_invalid'].includes(failure?.code)) throw failure;
|
|
130
|
+
throw invalid();
|
|
131
|
+
}
|
|
132
|
+
if (bytes.byteLength !== payload.decodedBytes) throw invalid();
|
|
133
|
+
let entries;
|
|
134
|
+
try { entries = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes)); }
|
|
135
|
+
catch (_error) { throw invalid(); }
|
|
136
|
+
validateEntries(entries);
|
|
137
|
+
return entries;
|
|
138
|
+
}
|
|
139
|
+
return { MAX_WIRE_BYTES, MAX_RECORD_BYTES, MAX_RESPONSE_BYTES, MAX_DECODED_BYTES, byteLength, validateRecord, validateResponse, encode, decode };
|
|
140
|
+
});
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
if (typeof file?.path === 'string') {
|
|
18
18
|
const path = normalizePath(file.path);
|
|
19
19
|
if (path) {
|
|
20
|
-
|
|
20
|
+
// Patch offsets refer to this exact UTF-16 string. Normalize only
|
|
21
|
+
// for comparisons, never discard the source coordinate system.
|
|
22
|
+
lookup.set(path, String(file.content ?? ''));
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
}
|
|
@@ -40,13 +42,7 @@
|
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
const baseContent = baseFileLookup.get(filePath);
|
|
44
|
-
if (!baseContent || baseContent.trim().length === 0) {
|
|
45
|
-
if (typeof console !== 'undefined') {
|
|
46
|
-
console.warn('[codex-overleaf] staleGuard: base empty for', filePath, '→ skipping check');
|
|
47
|
-
}
|
|
48
|
-
return { ok: true };
|
|
49
|
-
}
|
|
45
|
+
const baseContent = normalizeText(baseFileLookup.get(filePath));
|
|
50
46
|
const current = normalizeText(currentContent);
|
|
51
47
|
if (current !== baseContent) {
|
|
52
48
|
if (typeof console !== 'undefined') {
|
|
@@ -55,7 +51,7 @@
|
|
|
55
51
|
'base[0..80]:', JSON.stringify(baseContent.slice(0, 80)),
|
|
56
52
|
'current[0..80]:', JSON.stringify(current.slice(0, 80)));
|
|
57
53
|
}
|
|
58
|
-
const patchRangeFreshness = checkPatchRangeFreshness(operation,
|
|
54
|
+
const patchRangeFreshness = checkPatchRangeFreshness(operation, currentContent, baseFileLookup);
|
|
59
55
|
if (patchRangeFreshness) {
|
|
60
56
|
return patchRangeFreshness;
|
|
61
57
|
}
|
|
@@ -71,13 +67,17 @@
|
|
|
71
67
|
return { ok: true };
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
function checkPatchRangeFreshness(operation, currentContent) {
|
|
75
|
-
const
|
|
70
|
+
function checkPatchRangeFreshness(operation, currentContent, baseFileLookup) {
|
|
71
|
+
const prepared = prepareOperationPatches(operation, currentContent, baseFileLookup);
|
|
72
|
+
if (!prepared.ok) {
|
|
73
|
+
return { ...prepared, code: 'stale_patch_range', reasonKey: 'stalePatchConflict' };
|
|
74
|
+
}
|
|
75
|
+
const patches = prepared.patches;
|
|
76
76
|
if (!patches.length) {
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const current =
|
|
80
|
+
const current = String(currentContent ?? '');
|
|
81
81
|
for (const rawPatch of patches) {
|
|
82
82
|
const from = Number(rawPatch?.from);
|
|
83
83
|
const to = Number(rawPatch?.to);
|
|
@@ -107,12 +107,116 @@
|
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
// Bridge the raw Native baseline to the editor's line-ending representation.
|
|
111
|
+
// Logical LF offsets are only an intermediate coordinate system: both the
|
|
112
|
+
// range check and the eventual editor dispatch use the same raw patches.
|
|
113
|
+
function prepareOperationPatches(operation, currentContent, baseFileLookup) {
|
|
114
|
+
const patches = Array.isArray(operation?.patches) ? operation.patches : [];
|
|
115
|
+
const current = String(currentContent ?? '');
|
|
116
|
+
const path = normalizePath(operation?.path);
|
|
117
|
+
const base = baseFileLookup?.get(path);
|
|
118
|
+
if (!patches.length || typeof base !== 'string' || base === current) {
|
|
119
|
+
return { ok: true, patches };
|
|
120
|
+
}
|
|
121
|
+
const baseMap = lineEndingMap(base);
|
|
122
|
+
const currentMap = lineEndingMap(current);
|
|
123
|
+
// With no CRLF on either side, retain the existing raw range semantics.
|
|
124
|
+
if (!baseMap.removed.length && !currentMap.removed.length) return { ok: true, patches };
|
|
125
|
+
|
|
126
|
+
const groups = [];
|
|
127
|
+
let previousTo = 0;
|
|
128
|
+
for (const patch of patches) {
|
|
129
|
+
const from = Number(patch?.from), to = Number(patch?.to);
|
|
130
|
+
if (!Number.isInteger(from) || !Number.isInteger(to) || from < previousTo || to < from || to > base.length) {
|
|
131
|
+
return patchMappingFailure('invalid_patch');
|
|
132
|
+
}
|
|
133
|
+
if (base.slice(from, to) !== String(patch.expected ?? '')) return patchMappingFailure('stale_patch');
|
|
134
|
+
previousTo = to;
|
|
135
|
+
// Expand only a split CRLF or a new pair formed across an edit edge.
|
|
136
|
+
// Other neighbouring newlines belong to the editor and stay untouched.
|
|
137
|
+
let start = from, end = to;
|
|
138
|
+
const insert = String(patch.insert ?? '');
|
|
139
|
+
if (base[from - 1] === '\r' && (base[from] === '\n' || insert.startsWith('\n') || (!insert && base[to] === '\n'))) start -= 1;
|
|
140
|
+
if (base[to] === '\n' && (base[to - 1] === '\r' || insert.endsWith('\r') || (!insert && base[from - 1] === '\r'))) end += 1;
|
|
141
|
+
const previous = groups[groups.length - 1];
|
|
142
|
+
if (previous && start <= previous.end) {
|
|
143
|
+
previous.end = Math.max(previous.end, end);
|
|
144
|
+
previous.patches.push({ ...patch, from, to });
|
|
145
|
+
} else groups.push({ start, end, patches: [{ ...patch, from, to }] });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const mapped = [], sourceChanges = [];
|
|
149
|
+
for (const group of groups) {
|
|
150
|
+
const logicalFrom = baseMap.toLogical(group.start), logicalTo = baseMap.toLogical(group.end);
|
|
151
|
+
if (logicalTo > currentMap.length) return patchMappingFailure('invalid_patch');
|
|
152
|
+
const from = currentMap.toRaw(logicalFrom), to = currentMap.toRaw(logicalTo);
|
|
153
|
+
const expected = current.slice(from, to);
|
|
154
|
+
if (normalizeText(expected) !== normalizeText(base.slice(group.start, group.end))) {
|
|
155
|
+
return patchMappingFailure('stale_patch');
|
|
156
|
+
}
|
|
157
|
+
let insert = base.slice(group.start, group.end);
|
|
158
|
+
for (const patch of group.patches.slice().sort((left, right) => right.from - left.from)) {
|
|
159
|
+
if (insert.slice(patch.from - group.start, patch.to - group.start) !== String(patch.expected ?? '')) {
|
|
160
|
+
return patchMappingFailure('stale_patch');
|
|
161
|
+
}
|
|
162
|
+
insert = insert.slice(0, patch.from - group.start) + String(patch.insert ?? '') + insert.slice(patch.to - group.start);
|
|
163
|
+
}
|
|
164
|
+
sourceChanges.push({ from: group.start, to: group.end, insert });
|
|
165
|
+
const sourceEnding = nearestLineEnding(base, group.start);
|
|
166
|
+
const editorEnding = nearestLineEnding(current, from);
|
|
167
|
+
if (sourceEnding && editorEnding && sourceEnding !== editorEnding) {
|
|
168
|
+
insert = normalizeText(insert).replace(/\n/g, editorEnding);
|
|
169
|
+
}
|
|
170
|
+
// Leave equal surrounding text out of the dispatch/Track range.
|
|
171
|
+
let prefix = 0, oldEnd = expected.length, newEnd = insert.length;
|
|
172
|
+
while (prefix < oldEnd && prefix < newEnd && expected[prefix] === insert[prefix]) prefix += 1;
|
|
173
|
+
while (oldEnd > prefix && newEnd > prefix && expected[oldEnd - 1] === insert[newEnd - 1]) { oldEnd -= 1; newEnd -= 1; }
|
|
174
|
+
mapped.push({ from: from + prefix, to: from + oldEnd, expected: expected.slice(prefix, oldEnd), insert: insert.slice(prefix, newEnd) });
|
|
175
|
+
}
|
|
176
|
+
// A later operation in the same batch still addresses the original
|
|
177
|
+
// representation, so advance its baseline separately from editor text.
|
|
178
|
+
let sourceContent = base;
|
|
179
|
+
for (const patch of sourceChanges.reverse()) {
|
|
180
|
+
sourceContent = sourceContent.slice(0, patch.from) + patch.insert + sourceContent.slice(patch.to);
|
|
181
|
+
}
|
|
182
|
+
return { ok: true, patches: mapped, sourceContent };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function patchMappingFailure(code) {
|
|
186
|
+
return { ok: false, code, reason: 'Codex 要修改的位置已经无法和当前 Overleaf 内容对齐,所以没有写入。请重新运行任务。' };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function lineEndingMap(text) {
|
|
190
|
+
const removed = [];
|
|
191
|
+
for (let index = 0; index < text.length - 1; index += 1) {
|
|
192
|
+
if (text[index] === '\r' && text[index + 1] === '\n') removed.push(index);
|
|
193
|
+
}
|
|
194
|
+
function countBefore(offset, logical) {
|
|
195
|
+
let low = 0, high = removed.length;
|
|
196
|
+
while (low < high) {
|
|
197
|
+
const middle = (low + high) >>> 1;
|
|
198
|
+
if (removed[middle] - (logical ? middle : 0) < offset) low = middle + 1;
|
|
199
|
+
else high = middle;
|
|
200
|
+
}
|
|
201
|
+
return low;
|
|
202
|
+
}
|
|
203
|
+
return { removed, length: text.length - removed.length,
|
|
204
|
+
toLogical: offset => offset - countBefore(offset, false),
|
|
205
|
+
toRaw: offset => offset + countBefore(offset, true) };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function nearestLineEnding(text, offset) {
|
|
209
|
+
let newline = text.indexOf('\n', offset);
|
|
210
|
+
if (newline < 0) newline = text.lastIndexOf('\n', offset - 1);
|
|
211
|
+
return newline < 0 ? '' : text[newline - 1] === '\r' ? '\r\n' : '\n';
|
|
212
|
+
}
|
|
213
|
+
|
|
110
214
|
function updateExpectedFileContent(baseFileLookup, filePath, content) {
|
|
111
215
|
const path = normalizePath(filePath);
|
|
112
216
|
if (!baseFileLookup || !path) {
|
|
113
217
|
return;
|
|
114
218
|
}
|
|
115
|
-
baseFileLookup.set(path,
|
|
219
|
+
baseFileLookup.set(path, String(content ?? ''));
|
|
116
220
|
}
|
|
117
221
|
|
|
118
222
|
function removeExpectedFile(baseFileLookup, filePath) {
|
|
@@ -152,6 +256,7 @@
|
|
|
152
256
|
return {
|
|
153
257
|
buildBaseFileLookup,
|
|
154
258
|
checkOperationFreshness,
|
|
259
|
+
prepareOperationPatches,
|
|
155
260
|
updateExpectedFileContent,
|
|
156
261
|
removeExpectedFile,
|
|
157
262
|
moveExpectedFile,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(function initStorageDb(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
3
|
module.exports = factory(require('./storageRunActions'), require('./runInputQueue'),
|
|
4
|
-
require('./settlementFacts'), require('./storageSessionClaims'), require('./sessionState'), require('./runActivityModel'), require('./sharedSessionBridge'), require('./subagentActivityModel'), require('./storageValuePruning'));
|
|
4
|
+
require('./settlementFacts'), require('./storageSessionClaims'), require('./sessionState'), require('./runActivityModel'), require('./sharedSessionBridge'), require('./subagentActivityModel'), require('./storageValuePruning'), require('./composerAttachmentDraft'), require('./sharedSessionTransfer'));
|
|
5
5
|
} else {
|
|
6
6
|
root.CodexOverleafModuleRegistry.define('StorageDb', [
|
|
7
7
|
'StorageRunActions',
|
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
'RunActivityModel',
|
|
13
13
|
'SharedSessionBridge',
|
|
14
14
|
'SubagentActivityModel',
|
|
15
|
-
'StorageValuePruning'
|
|
15
|
+
'StorageValuePruning',
|
|
16
|
+
'ComposerAttachmentDraft',
|
|
17
|
+
'SharedSessionTransfer'
|
|
16
18
|
], factory);
|
|
17
19
|
}
|
|
18
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims, SessionState, RunActivityModel, SharedSessionBridge, SubagentActivityModel, StorageValuePruning) {
|
|
20
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue, SettlementFacts, StorageSessionClaims, SessionState, RunActivityModel, SharedSessionBridge, SubagentActivityModel, StorageValuePruning, ComposerAttachmentDraft, SharedSessionTransfer) {
|
|
19
21
|
'use strict';
|
|
20
22
|
const { removeEmptySummaryFields, removeEmptyFields } = StorageValuePruning;
|
|
21
23
|
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactRunExecutionSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage || !SettlementFacts?.compactSettlementFacts || !StorageSessionClaims?.createSessionClaimer) {
|
|
@@ -140,6 +142,7 @@
|
|
|
140
142
|
});
|
|
141
143
|
}
|
|
142
144
|
var claimSessionsForAccount = StorageSessionClaims.createSessionClaimer(openDb, function () { return IDBKeyRange; });
|
|
145
|
+
var composerDraftStore = ComposerAttachmentDraft.createStore(openDb);
|
|
143
146
|
|
|
144
147
|
function putRecord(storeName, record) {
|
|
145
148
|
return openDb().then(function (db) {
|
|
@@ -237,17 +240,7 @@
|
|
|
237
240
|
}
|
|
238
241
|
|
|
239
242
|
function clearAllStores() {
|
|
240
|
-
return
|
|
241
|
-
var storeNames = Object.keys(STORES);
|
|
242
|
-
return new Promise(function (resolve, reject) {
|
|
243
|
-
var tx = db.transaction(storeNames, 'readwrite');
|
|
244
|
-
for (var i = 0; i < storeNames.length; i++) {
|
|
245
|
-
tx.objectStore(storeNames[i]).clear();
|
|
246
|
-
}
|
|
247
|
-
tx.oncomplete = function () { resolve(); };
|
|
248
|
-
tx.onerror = function (event) { reject(event.target.error); };
|
|
249
|
-
});
|
|
250
|
-
});
|
|
243
|
+
return composerDraftStore.clear(Object.keys(STORES));
|
|
251
244
|
}
|
|
252
245
|
|
|
253
246
|
// --- Record builders ---
|
|
@@ -277,12 +270,14 @@
|
|
|
277
270
|
var lastActivityAt = typeof input.lastActivityAt === 'string' && input.lastActivityAt
|
|
278
271
|
? input.lastActivityAt
|
|
279
272
|
: updatedAt;
|
|
280
|
-
|
|
273
|
+
var record = {
|
|
281
274
|
id: input.id || generateId('ses'),
|
|
282
275
|
projectId: input.projectId || '',
|
|
283
276
|
title: normalizeSessionTitleForStorage(input.title, titleSource),
|
|
284
277
|
titleSource: titleSource,
|
|
285
278
|
codexThreadId: typeof input.codexThreadId === 'string' ? input.codexThreadId : '',
|
|
279
|
+
forkedFromSessionId: normalizeTextField(input.forkedFromSessionId, 160),
|
|
280
|
+
forkedFromRunId: normalizeTextField(input.forkedFromRunId, 160),
|
|
286
281
|
status: typeof input.status === 'string' && input.status ? input.status : 'active',
|
|
287
282
|
focusFiles: normalizePathList(input.focusFiles),
|
|
288
283
|
selectionContext: SessionState.normalizeSelectionContext(input.selectionContext),
|
|
@@ -293,7 +288,8 @@
|
|
|
293
288
|
normalizePaths: normalizePathList
|
|
294
289
|
}),
|
|
295
290
|
history: compactHistoryForStorage(input.history),
|
|
296
|
-
runs: compactRunsForStorage(input.runs,
|
|
291
|
+
runs: compactRunsForStorage(input.runs, { preserveRunActionPayload: false,
|
|
292
|
+
deferDirectoryCleanup: options.preserveRunActionPayload === true || options.deferDirectoryCleanup === true }),
|
|
297
293
|
task: normalizeDisplayTextForStorage(input.task, SESSION_STORAGE_LIMITS.taskChars),
|
|
298
294
|
mode: normalizeCurrentMode(input.mode), providerId: typeof input.providerId === 'string' && input.providerId ? input.providerId : 'builtin',
|
|
299
295
|
model: typeof input.model === 'string' ? input.model : '',
|
|
@@ -307,6 +303,23 @@
|
|
|
307
303
|
accountScopeUnavailable: accountScopeUnavailable,
|
|
308
304
|
safeTaskSummary: safeTaskSummary
|
|
309
305
|
};
|
|
306
|
+
if (options.preserveRunActionPayload === true) {
|
|
307
|
+
// Count the real display record before allocating recovery space. Adding
|
|
308
|
+
// older checkpoints must not make an otherwise valid history unwritable.
|
|
309
|
+
var metadataText = JSON.stringify(record), metadataBytes = SharedSessionTransfer.byteLength(metadataText);
|
|
310
|
+
record.runs = compactRunsForStorage(input.runs, { ...options,
|
|
311
|
+
canRetainActionPayload: function (bytes, chars) {
|
|
312
|
+
var totalBytes = metadataBytes + bytes + 4096, totalChars = metadataText.length + chars + 4096;
|
|
313
|
+
return totalBytes <= SharedSessionTransfer.MAX_WIRE_BYTES
|
|
314
|
+
|| (totalBytes <= SharedSessionTransfer.MAX_RECORD_BYTES && totalChars * 2 <= SharedSessionTransfer.MAX_WIRE_BYTES);
|
|
315
|
+
} });
|
|
316
|
+
}
|
|
317
|
+
for (var run of record.runs) SessionState.pruneRunRecoveryScope(run, record);
|
|
318
|
+
return record;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function compactSessionBatchActions(records, options) {
|
|
322
|
+
return StorageRunActions.compactSessionBatchActions(records, options, buildSessionRecord, SharedSessionTransfer);
|
|
310
323
|
}
|
|
311
324
|
|
|
312
325
|
function resolveAccountScopeId(input) {
|
|
@@ -417,6 +430,7 @@
|
|
|
417
430
|
var now = new Date().toISOString();
|
|
418
431
|
return {
|
|
419
432
|
id: input.id || generateId('aud'),
|
|
433
|
+
accountScopeId: typeof input.accountScopeId === 'string' ? input.accountScopeId : '',
|
|
420
434
|
projectId: typeof input.projectId === 'string' ? input.projectId : '',
|
|
421
435
|
sessionId: typeof input.sessionId === 'string' ? input.sessionId : '',
|
|
422
436
|
turnId: typeof input.turnId === 'string' ? input.turnId : '',
|
|
@@ -466,7 +480,8 @@
|
|
|
466
480
|
customInstructionsByProject: normalizeStringMap(state.customInstructionsByProject),
|
|
467
481
|
governanceRulesByProject: normalizeGovernanceRulesMap(state.governanceRulesByProject),
|
|
468
482
|
selectedLocalSkillIdsByProject: normalizeStringListMap(state.selectedLocalSkillIdsByProject),
|
|
469
|
-
codexOverleafSkillEnabled: normalizeCodexOverleafSkillEnabledMap(state.codexOverleafSkillEnabled)
|
|
483
|
+
codexOverleafSkillEnabled: normalizeCodexOverleafSkillEnabledMap(state.codexOverleafSkillEnabled),
|
|
484
|
+
codexLocalSkillEnabled: SessionState.normalizeCodexLocalSkillEnabled(state.codexLocalSkillEnabled)
|
|
470
485
|
};
|
|
471
486
|
return prefs;
|
|
472
487
|
}
|
|
@@ -519,7 +534,7 @@
|
|
|
519
534
|
continue;
|
|
520
535
|
}
|
|
521
536
|
result[key] = typeof value[rawKey] === 'string'
|
|
522
|
-
?
|
|
537
|
+
? normalizeDisplayTextForStorage(value[rawKey], CUSTOM_INSTRUCTIONS_MAX_CHARS)
|
|
523
538
|
: '';
|
|
524
539
|
}
|
|
525
540
|
return result;
|
|
@@ -640,9 +655,9 @@
|
|
|
640
655
|
function normalizeSessionTitleForStorage(value, titleSource) {
|
|
641
656
|
var title = typeof value === 'string' ? value.trim() : '';
|
|
642
657
|
if (titleSource === 'manual') {
|
|
643
|
-
return
|
|
658
|
+
return normalizeDisplayTextForStorage(title === LEGACY_DEFAULT_SESSION_TITLE ? '' : title, SESSION_STORAGE_LIMITS.sessionTitleChars);
|
|
644
659
|
}
|
|
645
|
-
return
|
|
660
|
+
return normalizeDisplayTextForStorage(title === LEGACY_DEFAULT_SESSION_TITLE ? '' : title, SESSION_STORAGE_LIMITS.sessionTitleChars);
|
|
646
661
|
}
|
|
647
662
|
|
|
648
663
|
function compactHistoryForStorage(history) {
|
|
@@ -660,12 +675,14 @@
|
|
|
660
675
|
function compactRunsForStorage(runs, options) {
|
|
661
676
|
return StorageRunActions.compactRunsForStorage(runs, options, SESSION_STORAGE_LIMITS.maxRunsPerSession, compactRunForStorage);
|
|
662
677
|
}
|
|
663
|
-
function compactRunForStorage(run, keepActionPayload) {
|
|
678
|
+
function compactRunForStorage(run, keepActionPayload, preparedActionPayload) {
|
|
664
679
|
run = SessionState.recoverRecordedRunFailure(run);
|
|
665
|
-
var actionPayload = StorageRunActions.compactRunActionPayload(run, keepActionPayload);
|
|
680
|
+
var actionPayload = preparedActionPayload || StorageRunActions.compactRunActionPayload(run, keepActionPayload);
|
|
666
681
|
var compact = {
|
|
667
682
|
...SessionState.pickWritebackRecovery(run),
|
|
668
683
|
id: run.id,
|
|
684
|
+
forkSnapshot: run.forkSnapshot === true,
|
|
685
|
+
forkSourceRunId: normalizeTextField(run.forkSourceRunId, 160),
|
|
669
686
|
task: normalizeDisplayTextForStorage(run.task || 'untitled task', SESSION_STORAGE_LIMITS.taskChars),
|
|
670
687
|
mode: typeof run.mode === 'string' ? redactSecretLikeText(run.mode) : '', ...StorageRunActions.compactProviderSnapshot(run),
|
|
671
688
|
...StorageRunActions.compactRunExecutionSnapshot(run, function (text) { return normalizeTextField(text, 4096); }),
|
|
@@ -686,7 +703,10 @@
|
|
|
686
703
|
undoTrackedChanges: actionPayload.undoTrackedChanges,
|
|
687
704
|
undoExpectedFiles: actionPayload.undoExpectedFiles,
|
|
688
705
|
...(actionPayload.trackedChangeCaptures ? { trackedChangeCaptures: actionPayload.trackedChangeCaptures } : {}),
|
|
706
|
+
...(actionPayload.pendingDirectoryCleanup ? { pendingDirectoryCleanup: actionPayload.pendingDirectoryCleanup } : {}),
|
|
707
|
+
...(actionPayload.recoveryRetention ? { recoveryRetention: SessionState.normalizeRecoveryRetention(actionPayload.recoveryRetention) } : {}),
|
|
689
708
|
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars),
|
|
709
|
+
...(run.undoOwnerProtocol === 1 ? { undoOwnerProtocol: 1 } : {}),
|
|
690
710
|
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
691
711
|
codexThreadId: normalizeTextField(run.codexThreadId, 160), codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
692
712
|
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
@@ -725,6 +745,7 @@
|
|
|
725
745
|
status: normalizeEventStatus(event.status),
|
|
726
746
|
timestamp: typeof event.timestamp === 'string' ? redactSecretLikeText(event.timestamp) : '',
|
|
727
747
|
kind: typeof event.kind === 'string' ? redactSecretLikeText(event.kind) : 'activity',
|
|
748
|
+
guidanceId: normalizeTextField(event.guidanceId, 160),
|
|
728
749
|
streamKey: typeof event.streamKey === 'string' ? redactSecretLikeText(event.streamKey) : '',
|
|
729
750
|
streamRole: typeof event.streamRole === 'string' ? redactSecretLikeText(event.streamRole) : ''
|
|
730
751
|
};
|
|
@@ -760,7 +781,7 @@
|
|
|
760
781
|
|
|
761
782
|
// Deep-copies a known-safe structured event value (the completion-report
|
|
762
783
|
// {conclusion, body, meta[]} payload, or a FailureReason object) preserving
|
|
763
|
-
// its shape while
|
|
784
|
+
// its shape while applying display-path rules and string limits. Bounded depth +
|
|
764
785
|
// breadth so a pathological value can't blow up the stored record.
|
|
765
786
|
function compactStructuredEventValueForStorage(value, depth) {
|
|
766
787
|
return StorageRunActions.compactStructuredEventValue(value, {
|
|
@@ -803,7 +824,11 @@
|
|
|
803
824
|
}
|
|
804
825
|
|
|
805
826
|
function normalizeDisplayTextForStorage(value, maxChars) {
|
|
806
|
-
|
|
827
|
+
var text = sanitizeAssistantVisibleText(value);
|
|
828
|
+
if (!Number.isFinite(maxChars) || maxChars <= 0 || text.length <= maxChars) {
|
|
829
|
+
return text;
|
|
830
|
+
}
|
|
831
|
+
return text.slice(0, Math.max(0, maxChars - 1)) + '…';
|
|
807
832
|
}
|
|
808
833
|
|
|
809
834
|
function summarizeStructuredValueForStorage(value, maxChars) {
|
|
@@ -1013,7 +1038,7 @@
|
|
|
1013
1038
|
}
|
|
1014
1039
|
|
|
1015
1040
|
function normalizeTextField(value, maxChars) {
|
|
1016
|
-
var text = sanitizeAssistantVisibleText(value);
|
|
1041
|
+
var text = sanitizeAssistantVisibleText(redactSecretLikeText(value));
|
|
1017
1042
|
if (!Number.isFinite(maxChars) || maxChars <= 0 || text.length <= maxChars) {
|
|
1018
1043
|
return text;
|
|
1019
1044
|
}
|
|
@@ -1024,7 +1049,8 @@
|
|
|
1024
1049
|
if (typeof value !== 'string' || !value) {
|
|
1025
1050
|
return '';
|
|
1026
1051
|
}
|
|
1027
|
-
|
|
1052
|
+
// Preserve conversation examples and quotations through save/reload.
|
|
1053
|
+
var text = value;
|
|
1028
1054
|
if (!mightContainLocalReferenceText(text)) {
|
|
1029
1055
|
return text;
|
|
1030
1056
|
}
|
|
@@ -1309,7 +1335,13 @@
|
|
|
1309
1335
|
deleteByIndex: deleteByIndex,
|
|
1310
1336
|
clearStore: clearStore,
|
|
1311
1337
|
clearAllStores: clearAllStores,
|
|
1338
|
+
clearAuxiliaryStores: function () { return composerDraftStore.clear(Object.keys(STORES).filter(name => name !== 'sessions')); },
|
|
1339
|
+
readComposerAttachmentDraft: composerDraftStore.read,
|
|
1340
|
+
writeComposerAttachmentDraft: composerDraftStore.write,
|
|
1312
1341
|
buildSessionRecord: buildSessionRecord,
|
|
1342
|
+
compactSessionBatchActions: compactSessionBatchActions,
|
|
1343
|
+
projectRetentionWarnings: StorageRunActions.projectRetentionWarnings,
|
|
1344
|
+
projectRetentionUpdates: StorageRunActions.projectRetentionUpdates,
|
|
1313
1345
|
mergeSessionReviewState: StorageRunActions.mergeSessionReviewState,
|
|
1314
1346
|
buildTurnRecord: buildTurnRecord,
|
|
1315
1347
|
buildEventRecord: buildEventRecord,
|