codex-overleaf-link 2.1.4 → 2.2.0
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 +27 -23
- package/extension/bootstrap/background.js +14 -1
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/runtime-manifest.json +11 -0
- package/extension/src/background.js +507 -8
- package/extension/src/backgroundUpdateCoordinator.js +284 -19
- package/extension/src/content/activeTurnControl.js +179 -0
- package/extension/src/content/composerPanel.js +19 -6
- package/extension/src/content/contentRuntime.js +335 -317
- package/extension/src/content/diagnosticsPanel.js +132 -1
- package/extension/src/content/markdownDomRenderer.js +451 -0
- package/extension/src/content/markdownText.js +86 -7
- package/extension/src/content/mathText.js +49 -4
- package/extension/src/content/modelPicker.js +14 -5
- package/extension/src/content/nativeChannel.js +7 -1
- package/extension/src/content/otWarmMirror.js +1 -1
- package/extension/src/content/panelRenderer.js +112 -12
- package/extension/src/content/pendingInputView.js +106 -0
- package/extension/src/content/projectProviderSelection.js +68 -0
- package/extension/src/content/projectSessionCleanup.js +104 -0
- package/extension/src/content/providerSettingsCoordinator.js +170 -22
- package/extension/src/content/providerSettingsDialog.js +2 -2
- package/extension/src/content/recentProjects.js +24 -13
- package/extension/src/content/runController.js +2 -2
- package/extension/src/content/runGuidanceController.js +70 -0
- package/extension/src/content/runGuidanceView.js +48 -0
- package/extension/src/content/runQueueScheduler.js +260 -0
- package/extension/src/content/runTimelineView.js +33 -80
- package/extension/src/content/sessionManager.js +2 -2
- package/extension/src/content/sessionPersistence.js +62 -0
- package/extension/src/content/settingsPanel.js +1 -1
- package/extension/src/content/updateNotice.js +80 -1
- package/extension/src/page/writebackRouter.js +3 -9
- package/extension/src/shared/compatibility.js +2 -1
- package/extension/src/shared/i18n.js +54 -0
- package/extension/src/shared/providerProfiles.js +3 -2
- package/extension/src/shared/runInputQueue.js +253 -0
- package/extension/src/shared/sessionState.js +45 -22
- package/extension/src/shared/storageDb.js +39 -44
- package/extension/src/shared/storageMigration.js +123 -3
- package/extension/src/shared/storageRunActions.js +34 -1
- package/extension/src/shared/updateConsent.js +15 -4
- package/extension/styles/panel.css +370 -23
- package/extension/vendor/katex/katex.min.css +1 -1
- package/extension/vendor/markdown-it/LICENSE +22 -0
- package/extension/vendor/markdown-it/SOURCE.json +7 -0
- package/extension/vendor/markdown-it/VERSION +1 -0
- package/extension/vendor/markdown-it/markdown-it.min.js +3 -0
- package/native-host/src/anthropicBridgeRequest.js +3 -3
- package/native-host/src/anthropicBridgeResponse.js +58 -17
- package/native-host/src/anthropicMessagesBridge.js +156 -23
- package/native-host/src/chatBridgeRequest.js +1 -1
- package/native-host/src/chatBridgeResponse.js +12 -8
- package/native-host/src/chatCompletionsBridge.js +22 -40
- package/native-host/src/codexPromptAssembly.js +3 -1
- package/native-host/src/codexProviderLaunch.js +6 -3
- package/native-host/src/codexSessionRunner.js +66 -66
- package/native-host/src/codexSessionTiming.js +45 -0
- package/native-host/src/diffEngine.js +10 -5
- package/native-host/src/index.js +58 -3
- package/native-host/src/managedInstall.js +45 -7
- package/native-host/src/providerProfile.js +2 -2
- package/native-host/src/providerStreamLifecycle.js +100 -0
- package/native-host/src/responsesPassthroughBridge.js +636 -0
- package/native-host/src/taskRunnerRuntime.js +81 -2
- package/native-host/src/updateArchive.js +4 -3
- package/native-host/src/updateManager.js +306 -19
- package/native-host/src/updateTrust.js +1 -1
- package/package.json +3 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
(function initStorageDb(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory(require('./storageRunActions'));
|
|
3
|
+
module.exports = factory(require('./storageRunActions'), require('./runInputQueue'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafStorageDb = factory(root.CodexOverleafStorageRunActions);
|
|
5
|
+
root.CodexOverleafStorageDb = factory(root.CodexOverleafStorageRunActions, root.CodexOverleafRunInputQueue);
|
|
6
6
|
}
|
|
7
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions) {
|
|
7
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue) {
|
|
8
8
|
'use strict';
|
|
9
|
-
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot) {
|
|
9
|
+
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage) {
|
|
10
10
|
throw new Error('Codex Overleaf storage run-action helpers are unavailable.');
|
|
11
11
|
}
|
|
12
12
|
// IndexedDB versions are monotonic; v2.0 RC profiles have already opened v3.
|
|
@@ -272,6 +272,11 @@
|
|
|
272
272
|
codexThreadId: typeof input.codexThreadId === 'string' ? input.codexThreadId : '',
|
|
273
273
|
status: typeof input.status === 'string' && input.status ? input.status : 'active',
|
|
274
274
|
focusFiles: normalizePathList(input.focusFiles),
|
|
275
|
+
pendingInputs: RunInputQueue.compactForStorage(input.pendingInputs, {
|
|
276
|
+
normalizeField: normalizeTextField,
|
|
277
|
+
normalizeDisplay: normalizeDisplayTextForStorage,
|
|
278
|
+
normalizePaths: normalizePathList
|
|
279
|
+
}),
|
|
275
280
|
history: compactHistoryForStorage(input.history),
|
|
276
281
|
runs: compactRunsForStorage(input.runs, options),
|
|
277
282
|
task: normalizeDisplayTextForStorage(input.task, SESSION_STORAGE_LIMITS.taskChars),
|
|
@@ -663,8 +668,23 @@
|
|
|
663
668
|
undoBaseFiles: actionPayload.undoBaseFiles,
|
|
664
669
|
undoTrackedChanges: actionPayload.undoTrackedChanges,
|
|
665
670
|
undoExpectedFiles: actionPayload.undoExpectedFiles,
|
|
666
|
-
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars)
|
|
671
|
+
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars),
|
|
672
|
+
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
673
|
+
codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
674
|
+
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
675
|
+
queueItemId: normalizeTextField(run.queueItemId, 160)
|
|
667
676
|
};
|
|
677
|
+
if (run.interruptedDraft && typeof run.interruptedDraft === 'object') {
|
|
678
|
+
compact.interruptedDraft = {
|
|
679
|
+
requestId: normalizeTextField(run.interruptedDraft.requestId, 160),
|
|
680
|
+
threadId: normalizeTextField(run.interruptedDraft.threadId, 160),
|
|
681
|
+
turnId: normalizeTextField(run.interruptedDraft.turnId, 160),
|
|
682
|
+
lastEventSeq: Number.isFinite(Number(run.interruptedDraft.lastEventSeq))
|
|
683
|
+
? Number(run.interruptedDraft.lastEventSeq)
|
|
684
|
+
: 0,
|
|
685
|
+
reason: normalizeTextField(run.interruptedDraft.reason, 80)
|
|
686
|
+
};
|
|
687
|
+
}
|
|
668
688
|
if (VALID_TRACKED_CHANGE_STATUSES[run.trackedChangeStatus] === true) {
|
|
669
689
|
compact.trackedChangeStatus = run.trackedChangeStatus;
|
|
670
690
|
}
|
|
@@ -712,27 +732,11 @@
|
|
|
712
732
|
// its shape while redacting + truncating every string field. Bounded depth +
|
|
713
733
|
// breadth so a pathological value can't blow up the stored record.
|
|
714
734
|
function compactStructuredEventValueForStorage(value, depth) {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return value;
|
|
721
|
-
}
|
|
722
|
-
if (d > 6 || typeof value !== 'object') {
|
|
723
|
-
return null;
|
|
724
|
-
}
|
|
725
|
-
if (Array.isArray(value)) {
|
|
726
|
-
return value.slice(0, 32).map(function (item) {
|
|
727
|
-
return compactStructuredEventValueForStorage(item, d + 1);
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
var out = {};
|
|
731
|
-
var keys = Object.keys(value).slice(0, 32);
|
|
732
|
-
for (var i = 0; i < keys.length; i++) {
|
|
733
|
-
out[keys[i]] = compactStructuredEventValueForStorage(value[keys[i]], d + 1);
|
|
734
|
-
}
|
|
735
|
-
return out;
|
|
735
|
+
return StorageRunActions.compactStructuredEventValue(value, {
|
|
736
|
+
normalizeString: function (text) {
|
|
737
|
+
return normalizeDisplayTextForStorage(text, SESSION_STORAGE_LIMITS.reportDetailChars);
|
|
738
|
+
}
|
|
739
|
+
}, depth);
|
|
736
740
|
}
|
|
737
741
|
|
|
738
742
|
function getEventDetailLimit(event) {
|
|
@@ -1142,7 +1146,11 @@
|
|
|
1142
1146
|
return Promise.resolve([]);
|
|
1143
1147
|
}
|
|
1144
1148
|
return getAllSessions().then(function (all) {
|
|
1145
|
-
return filterRecentProjectsAcrossAccount(all, {
|
|
1149
|
+
return filterRecentProjectsAcrossAccount(all, {
|
|
1150
|
+
accountScopeId: accountScopeId,
|
|
1151
|
+
limit: limit,
|
|
1152
|
+
deletedSessionIdsByProject: options && options.deletedSessionIdsByProject
|
|
1153
|
+
});
|
|
1146
1154
|
});
|
|
1147
1155
|
}
|
|
1148
1156
|
|
|
@@ -1153,6 +1161,7 @@
|
|
|
1153
1161
|
function filterRecentProjectsAcrossAccount(sessions, options) {
|
|
1154
1162
|
var accountScopeId = options && options.accountScopeId;
|
|
1155
1163
|
var limit = options && Number.isFinite(options.limit) ? options.limit : 10;
|
|
1164
|
+
var deletedSessionIdsByProject = options && options.deletedSessionIdsByProject;
|
|
1156
1165
|
if (!accountScopeId) {
|
|
1157
1166
|
return [];
|
|
1158
1167
|
}
|
|
@@ -1163,6 +1172,8 @@
|
|
|
1163
1172
|
var s = all[i];
|
|
1164
1173
|
if (!s) continue;
|
|
1165
1174
|
if (s.accountScopeId !== accountScopeId) continue;
|
|
1175
|
+
if (deletedSessionIdsByProject && Array.isArray(deletedSessionIdsByProject[s.projectId])
|
|
1176
|
+
&& deletedSessionIdsByProject[s.projectId].indexOf(s.id) !== -1) continue;
|
|
1166
1177
|
if (typeof s.lastActivityAt !== 'string' || !s.lastActivityAt) continue;
|
|
1167
1178
|
if (!isValidOverleafProjectId(s.projectId)) continue;
|
|
1168
1179
|
var prev = byProject[s.projectId];
|
|
@@ -1303,23 +1314,7 @@
|
|
|
1303
1314
|
}
|
|
1304
1315
|
}
|
|
1305
1316
|
|
|
1306
|
-
|
|
1307
|
-
var hash = 2166136261;
|
|
1308
|
-
var text = String(value || '');
|
|
1309
|
-
for (var i = 0; i < text.length; i++) {
|
|
1310
|
-
hash ^= text.charCodeAt(i);
|
|
1311
|
-
hash = Math.imul(hash, 16777619);
|
|
1312
|
-
}
|
|
1313
|
-
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
function cloneJsonValue(value) {
|
|
1317
|
-
try {
|
|
1318
|
-
return JSON.parse(JSON.stringify(value));
|
|
1319
|
-
} catch (_error) {
|
|
1320
|
-
return Array.isArray(value) ? value.slice() : value;
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1317
|
+
var hashString = StorageRunActions.hashString;
|
|
1323
1318
|
|
|
1324
1319
|
return {
|
|
1325
1320
|
TARGET_SCHEMA_VERSION: TARGET_SCHEMA_VERSION,
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
var PREFS_KEY = 'codexOverleafPrefs';
|
|
11
|
+
var SESSION_TOMBSTONES_KEY = 'codexOverleafSessionTombstones';
|
|
12
|
+
var SESSION_TOMBSTONE_ENTRY_PREFIX = 'codexOverleafSessionTombstone:v2:';
|
|
13
|
+
var MAX_DELETED_SESSION_IDS_PER_PROJECT = 100;
|
|
11
14
|
var CUSTOM_INSTRUCTIONS_MAX_CHARS = 12000;
|
|
12
15
|
var PROJECT_PREF_KEY_MAX_CHARS = 160;
|
|
13
16
|
|
|
@@ -15,15 +18,20 @@
|
|
|
15
18
|
var StorageDb = (typeof window !== 'undefined' && window.CodexOverleafStorageDb)
|
|
16
19
|
? window.CodexOverleafStorageDb
|
|
17
20
|
: require('./storageDb');
|
|
18
|
-
return chrome.storage.local.get(
|
|
21
|
+
return chrome.storage.local.get(null).then(function (stored) {
|
|
19
22
|
var prefs = normalizePrefs(stored[PREFS_KEY] || {});
|
|
23
|
+
var tombstones = collectSessionTombstones(stored);
|
|
24
|
+
var deletedSessionIds = getDeletedSessionIds(tombstones, projectId);
|
|
20
25
|
var schemaVersion = prefs.storageSchemaVersion || 0;
|
|
21
26
|
|
|
22
27
|
if (schemaVersion >= StorageDb.TARGET_SCHEMA_VERSION) {
|
|
23
28
|
var activeSessionByProject = prefs.activeSessionByProject || {};
|
|
24
29
|
var activeSessionId = activeSessionByProject[projectId] || '';
|
|
25
30
|
return StorageDb.getAllByIndex('sessions', 'projectId', projectId).then(function (sessions) {
|
|
26
|
-
|
|
31
|
+
var visibleSessions = sessions.filter(function (session) {
|
|
32
|
+
return deletedSessionIds.indexOf(session && session.id) === -1;
|
|
33
|
+
});
|
|
34
|
+
return { prefs: prefs, sessions: visibleSessions, activeSessionId: activeSessionId, migrated: false };
|
|
27
35
|
});
|
|
28
36
|
}
|
|
29
37
|
|
|
@@ -35,6 +43,7 @@
|
|
|
35
43
|
for (var i = 0; i < legacySessions.length; i++) {
|
|
36
44
|
var legacy = legacySessions[i];
|
|
37
45
|
if (!legacy || !legacy.id) { continue; }
|
|
46
|
+
if (deletedSessionIds.indexOf(legacy.id) !== -1) { continue; }
|
|
38
47
|
var record = StorageDb.buildSessionRecord(
|
|
39
48
|
buildLegacySessionRecordInput(projectId, legacyBlob, legacy)
|
|
40
49
|
);
|
|
@@ -101,6 +110,112 @@
|
|
|
101
110
|
});
|
|
102
111
|
}
|
|
103
112
|
|
|
113
|
+
function normalizeDeletedSessionIdsByProject(value) {
|
|
114
|
+
var result = {};
|
|
115
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
Object.keys(value).forEach(function (rawProjectId) {
|
|
119
|
+
var projectId = normalizeProjectPrefKey(rawProjectId);
|
|
120
|
+
if (!projectId || !Array.isArray(value[rawProjectId])) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
var seen = {};
|
|
124
|
+
var ids = value[rawProjectId].map(function (id) {
|
|
125
|
+
return normalizeTextField(id, PROJECT_PREF_KEY_MAX_CHARS);
|
|
126
|
+
}).filter(function (id) {
|
|
127
|
+
if (!id || seen[id]) { return false; }
|
|
128
|
+
seen[id] = true;
|
|
129
|
+
return true;
|
|
130
|
+
}).slice(-MAX_DELETED_SESSION_IDS_PER_PROJECT);
|
|
131
|
+
if (ids.length) {
|
|
132
|
+
result[projectId] = ids;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function getDeletedSessionIds(tombstones, projectId) {
|
|
139
|
+
var normalized = normalizeDeletedSessionIdsByProject(tombstones);
|
|
140
|
+
var key = normalizeProjectPrefKey(projectId);
|
|
141
|
+
return key && Array.isArray(normalized[key]) ? normalized[key].slice() : [];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function loadSessionTombstones() {
|
|
145
|
+
return chrome.storage.local.get(null).then(function (stored) {
|
|
146
|
+
return collectSessionTombstones(stored);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function addSessionTombstones(projectId, sessionIds) {
|
|
151
|
+
var key = normalizeProjectPrefKey(projectId);
|
|
152
|
+
if (!key) {
|
|
153
|
+
return loadSessionTombstones();
|
|
154
|
+
}
|
|
155
|
+
var incoming = (Array.isArray(sessionIds) ? sessionIds : [])
|
|
156
|
+
.map(function (id) { return normalizeTextField(id, PROJECT_PREF_KEY_MAX_CHARS); })
|
|
157
|
+
.filter(Boolean);
|
|
158
|
+
if (!incoming.length) {
|
|
159
|
+
return loadSessionTombstones();
|
|
160
|
+
}
|
|
161
|
+
var deletedAt = new Date().toISOString();
|
|
162
|
+
var payload = {};
|
|
163
|
+
incoming.forEach(function (sessionId) {
|
|
164
|
+
payload[buildSessionTombstoneEntryKey(key, sessionId)] = {
|
|
165
|
+
projectId: key,
|
|
166
|
+
sessionId: sessionId,
|
|
167
|
+
deletedAt: deletedAt
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
return chrome.storage.local.set(payload)
|
|
171
|
+
.then(function () { return pruneSessionTombstoneEntries(key); })
|
|
172
|
+
.then(loadSessionTombstones);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function collectSessionTombstones(stored) {
|
|
176
|
+
var tombstones = normalizeDeletedSessionIdsByProject(
|
|
177
|
+
stored && stored[SESSION_TOMBSTONES_KEY] || {}
|
|
178
|
+
);
|
|
179
|
+
Object.keys(stored || {}).forEach(function (storageKey) {
|
|
180
|
+
if (storageKey.indexOf(SESSION_TOMBSTONE_ENTRY_PREFIX) !== 0) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
var entry = stored[storageKey];
|
|
184
|
+
var projectId = normalizeProjectPrefKey(entry && entry.projectId);
|
|
185
|
+
var sessionId = normalizeTextField(entry && entry.sessionId, PROJECT_PREF_KEY_MAX_CHARS);
|
|
186
|
+
if (!projectId || !sessionId) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
tombstones[projectId] = (tombstones[projectId] || [])
|
|
190
|
+
.filter(function (id) { return id !== sessionId; })
|
|
191
|
+
.concat(sessionId)
|
|
192
|
+
.slice(-MAX_DELETED_SESSION_IDS_PER_PROJECT);
|
|
193
|
+
});
|
|
194
|
+
return normalizeDeletedSessionIdsByProject(tombstones);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function buildSessionTombstoneEntryKey(projectId, sessionId) {
|
|
198
|
+
return SESSION_TOMBSTONE_ENTRY_PREFIX +
|
|
199
|
+
encodeURIComponent(projectId) + ':' +
|
|
200
|
+
encodeURIComponent(sessionId);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function pruneSessionTombstoneEntries(projectId) {
|
|
204
|
+
return chrome.storage.local.get(null).then(function (stored) {
|
|
205
|
+
var entries = Object.keys(stored || {}).filter(function (storageKey) {
|
|
206
|
+
var entry = stored[storageKey];
|
|
207
|
+
return storageKey.indexOf(SESSION_TOMBSTONE_ENTRY_PREFIX) === 0 &&
|
|
208
|
+
normalizeProjectPrefKey(entry && entry.projectId) === projectId;
|
|
209
|
+
}).sort(function (leftKey, rightKey) {
|
|
210
|
+
var left = String(stored[leftKey] && stored[leftKey].deletedAt || '');
|
|
211
|
+
var right = String(stored[rightKey] && stored[rightKey].deletedAt || '');
|
|
212
|
+
return left === right ? leftKey.localeCompare(rightKey) : left.localeCompare(right);
|
|
213
|
+
});
|
|
214
|
+
var obsolete = entries.slice(0, Math.max(0, entries.length - MAX_DELETED_SESSION_IDS_PER_PROJECT));
|
|
215
|
+
return obsolete.length ? chrome.storage.local.remove(obsolete) : undefined;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
104
219
|
function normalizePrefs(prefs) {
|
|
105
220
|
var source = prefs && typeof prefs === 'object' ? prefs : {};
|
|
106
221
|
return Object.assign({}, source, {
|
|
@@ -162,8 +277,13 @@
|
|
|
162
277
|
|
|
163
278
|
return {
|
|
164
279
|
PREFS_KEY: PREFS_KEY,
|
|
280
|
+
SESSION_TOMBSTONES_KEY: SESSION_TOMBSTONES_KEY,
|
|
165
281
|
runMigrationIfNeeded: runMigrationIfNeeded,
|
|
166
282
|
savePrefs: savePrefs,
|
|
167
|
-
loadPrefs: loadPrefs
|
|
283
|
+
loadPrefs: loadPrefs,
|
|
284
|
+
loadSessionTombstones: loadSessionTombstones,
|
|
285
|
+
addSessionTombstones: addSessionTombstones,
|
|
286
|
+
getDeletedSessionIds: getDeletedSessionIds,
|
|
287
|
+
normalizeDeletedSessionIdsByProject: normalizeDeletedSessionIdsByProject
|
|
168
288
|
};
|
|
169
289
|
});
|
|
@@ -101,9 +101,42 @@
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
function compactStructuredEventValue(value, options, depth) {
|
|
105
|
+
var config = options || {};
|
|
106
|
+
var d = depth || 0;
|
|
107
|
+
if (typeof value === 'string') {
|
|
108
|
+
return typeof config.normalizeString === 'function' ? config.normalizeString(value) : value;
|
|
109
|
+
}
|
|
110
|
+
if (value === null || typeof value === 'number' || typeof value === 'boolean') return value;
|
|
111
|
+
if (d > 6 || typeof value !== 'object') return null;
|
|
112
|
+
if (Array.isArray(value)) {
|
|
113
|
+
return value.slice(0, 32).map(function (item) {
|
|
114
|
+
return compactStructuredEventValue(item, config, d + 1);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
var out = {};
|
|
118
|
+
var keys = Object.keys(value).slice(0, 32);
|
|
119
|
+
for (var i = 0; i < keys.length; i++) {
|
|
120
|
+
out[keys[i]] = compactStructuredEventValue(value[keys[i]], config, d + 1);
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function hashString(value) {
|
|
126
|
+
var hash = 2166136261;
|
|
127
|
+
var text = String(value || '');
|
|
128
|
+
for (var i = 0; i < text.length; i++) {
|
|
129
|
+
hash ^= text.charCodeAt(i);
|
|
130
|
+
hash = Math.imul(hash, 16777619);
|
|
131
|
+
}
|
|
132
|
+
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
133
|
+
}
|
|
134
|
+
|
|
104
135
|
return {
|
|
136
|
+
compactStructuredEventValue: compactStructuredEventValue,
|
|
105
137
|
compactRunsForStorage: compactRunsForStorage,
|
|
106
138
|
compactRunActionPayload: compactRunActionPayload,
|
|
107
|
-
compactProviderSnapshot: compactProviderSnapshot
|
|
139
|
+
compactProviderSnapshot: compactProviderSnapshot,
|
|
140
|
+
hashString: hashString
|
|
108
141
|
};
|
|
109
142
|
});
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
'waiting_for_idle',
|
|
19
19
|
'applying',
|
|
20
20
|
'awaiting_health',
|
|
21
|
+
'rolling_back',
|
|
21
22
|
'committed',
|
|
22
23
|
'rolled_back',
|
|
23
24
|
'failed'
|
|
@@ -27,7 +28,8 @@
|
|
|
27
28
|
'staged',
|
|
28
29
|
'waiting_for_idle',
|
|
29
30
|
'applying',
|
|
30
|
-
'awaiting_health'
|
|
31
|
+
'awaiting_health',
|
|
32
|
+
'rolling_back'
|
|
31
33
|
]);
|
|
32
34
|
const TERMINAL_STATES = new Set(['committed', 'rolled_back', 'failed']);
|
|
33
35
|
const QUIET_FAILURE_CODES = new Set([
|
|
@@ -44,6 +46,7 @@
|
|
|
44
46
|
waiting_for_idle: { value: 65, determinate: true, phase: 'waiting' },
|
|
45
47
|
applying: { value: 82, determinate: false, phase: 'applying' },
|
|
46
48
|
awaiting_health: { value: 94, determinate: false, phase: 'health' },
|
|
49
|
+
rolling_back: { value: 94, determinate: false, phase: 'rollback' },
|
|
47
50
|
committed: { value: 100, determinate: true, phase: 'committed' },
|
|
48
51
|
rolled_back: { value: 94, determinate: true, phase: 'rolled_back' },
|
|
49
52
|
failed: { value: 0, determinate: true, phase: 'failed' }
|
|
@@ -63,8 +66,12 @@
|
|
|
63
66
|
blocker: blockers[0] || '',
|
|
64
67
|
blockers,
|
|
65
68
|
transactionId: safeId(value.transactionId),
|
|
69
|
+
initiatedBy: ['automatic', 'manual'].includes(value.initiatedBy) ? value.initiatedBy : '',
|
|
66
70
|
lastCheckedAt: finiteNumber(value.lastCheckedAt),
|
|
67
71
|
stagedAt: finiteNumber(value.stagedAt),
|
|
72
|
+
phaseStartedAt: finiteNumber(value.phaseStartedAt),
|
|
73
|
+
deadlineAt: finiteNumber(value.deadlineAt),
|
|
74
|
+
heartbeatAt: finiteNumber(value.heartbeatAt),
|
|
68
75
|
postponeUntil: finiteNumber(value.postponeUntil),
|
|
69
76
|
code: safeToken(value.code),
|
|
70
77
|
message: String(value.message || '').replace(/\s+/g, ' ').trim().slice(0, 300)
|
|
@@ -96,7 +103,11 @@
|
|
|
96
103
|
const execution = EXECUTION_STATES.has(state.state);
|
|
97
104
|
const available = state.state === 'update_available' && newer;
|
|
98
105
|
const progress = getProgressModel(state);
|
|
99
|
-
const quietFailure = state.state === 'failed' &&
|
|
106
|
+
const quietFailure = state.state === 'failed' &&
|
|
107
|
+
state.initiatedBy !== 'manual' &&
|
|
108
|
+
QUIET_FAILURE_CODES.has(state.code);
|
|
109
|
+
const visibleFailure = state.state === 'failed' &&
|
|
110
|
+
(state.initiatedBy === 'manual' || (!quietFailure && newer));
|
|
100
111
|
|
|
101
112
|
return {
|
|
102
113
|
state,
|
|
@@ -112,7 +123,7 @@
|
|
|
112
123
|
snoozed,
|
|
113
124
|
execution,
|
|
114
125
|
showPanel: (available && !snoozed) || execution || state.state === 'rolled_back' ||
|
|
115
|
-
|
|
126
|
+
visibleFailure,
|
|
116
127
|
badge: getBadge(state, { available, snoozed }),
|
|
117
128
|
actions: {
|
|
118
129
|
check: ['idle', 'committed', 'rolled_back', 'failed'].includes(state.state),
|
|
@@ -135,7 +146,7 @@
|
|
|
135
146
|
}
|
|
136
147
|
|
|
137
148
|
function getBadge(state, flags) {
|
|
138
|
-
if (state.state === 'applying' || state.state === 'awaiting_health') {
|
|
149
|
+
if (state.state === 'applying' || state.state === 'awaiting_health' || state.state === 'rolling_back') {
|
|
139
150
|
return { text: '...', color: '#3578bd' };
|
|
140
151
|
}
|
|
141
152
|
if (state.state === 'failed' || state.state === 'rolled_back') {
|