codex-overleaf-link 1.1.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +457 -0
  3. package/bin/codex-overleaf-link.mjs +223 -0
  4. package/extension/src/shared/agentTranscript.js +1175 -0
  5. package/extension/src/shared/auditRecords.js +568 -0
  6. package/extension/src/shared/compatibility.js +372 -0
  7. package/extension/src/shared/compileAdapter.js +176 -0
  8. package/extension/src/shared/governanceRules.js +252 -0
  9. package/extension/src/shared/i18n.js +565 -0
  10. package/extension/src/shared/models.js +106 -0
  11. package/extension/src/shared/otText.js +505 -0
  12. package/extension/src/shared/projectFiles.js +180 -0
  13. package/extension/src/shared/reviewing.js +99 -0
  14. package/extension/src/shared/sensitiveScan.js +116 -0
  15. package/extension/src/shared/sessionState.js +1084 -0
  16. package/extension/src/shared/staleGuard.js +150 -0
  17. package/extension/src/shared/storageDb.js +986 -0
  18. package/extension/src/shared/storageKeys.js +29 -0
  19. package/extension/src/shared/storageMigration.js +168 -0
  20. package/extension/src/shared/summary.js +248 -0
  21. package/extension/src/shared/undoOperations.js +369 -0
  22. package/native-host/src/codexArgs.js +43 -0
  23. package/native-host/src/codexHome.js +538 -0
  24. package/native-host/src/codexModels.js +247 -0
  25. package/native-host/src/codexPrompt.js +192 -0
  26. package/native-host/src/codexPromptAssembly.js +411 -0
  27. package/native-host/src/codexSessionRunner.js +1247 -0
  28. package/native-host/src/commandApproval.js +914 -0
  29. package/native-host/src/debugLog.js +78 -0
  30. package/native-host/src/diffEngine.js +247 -0
  31. package/native-host/src/index.js +132 -0
  32. package/native-host/src/launcher.js +81 -0
  33. package/native-host/src/localSkills.js +476 -0
  34. package/native-host/src/manifest.js +226 -0
  35. package/native-host/src/mirrorSensitiveScan.js +119 -0
  36. package/native-host/src/mirrorWorkspace.js +1019 -0
  37. package/native-host/src/nativeDoctor.js +826 -0
  38. package/native-host/src/nativeEnvironment.js +315 -0
  39. package/native-host/src/nativeHostPlatform.js +112 -0
  40. package/native-host/src/nativeMessaging.js +60 -0
  41. package/native-host/src/nativeQuotas.js +294 -0
  42. package/native-host/src/nativeResponseBudget.js +194 -0
  43. package/native-host/src/runtimeInstaller.js +357 -0
  44. package/native-host/src/taskRunner.js +3 -0
  45. package/native-host/src/taskRunnerRuntime.js +1083 -0
  46. package/native-host/src/textPatch.js +287 -0
  47. package/package.json +40 -0
  48. package/scripts/codex-json-agent.mjs +269 -0
  49. package/scripts/install-native-host.mjs +255 -0
  50. package/scripts/npm-package-files-v1.1.1.txt +52 -0
  51. package/scripts/uninstall-native-host.mjs +298 -0
  52. package/scripts/verify-npm-package.mjs +296 -0
@@ -0,0 +1,29 @@
1
+ (function initStorageKeys(root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory();
4
+ } else {
5
+ root.CodexOverleafStorageKeys = factory();
6
+ }
7
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function storageKeysFactory() {
8
+ 'use strict';
9
+
10
+ function getOverleafProjectId(urlLike) {
11
+ try {
12
+ const url = new URL(String(urlLike || ''));
13
+ const match = url.pathname.match(/^\/project\/([^/?#]+)/);
14
+ return match ? decodeURIComponent(match[1]) : '';
15
+ } catch {
16
+ return '';
17
+ }
18
+ }
19
+
20
+ function getProjectStorageKey(baseKey, urlLike) {
21
+ const projectId = getOverleafProjectId(urlLike);
22
+ return projectId ? `${baseKey}:project:${projectId}` : baseKey;
23
+ }
24
+
25
+ return {
26
+ getOverleafProjectId,
27
+ getProjectStorageKey
28
+ };
29
+ });
@@ -0,0 +1,168 @@
1
+ (function initStorageMigration(root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory();
4
+ } else {
5
+ root.CodexOverleafStorageMigration = factory();
6
+ }
7
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function storageMigrationFactory() {
8
+ 'use strict';
9
+
10
+ var PREFS_KEY = 'codexOverleafPrefs';
11
+ var CUSTOM_INSTRUCTIONS_MAX_CHARS = 12000;
12
+ var PROJECT_PREF_KEY_MAX_CHARS = 160;
13
+
14
+ function runMigrationIfNeeded(projectId, legacyStorageKey) {
15
+ var StorageDb = (typeof window !== 'undefined' && window.CodexOverleafStorageDb)
16
+ ? window.CodexOverleafStorageDb
17
+ : require('./storageDb');
18
+ return chrome.storage.local.get([PREFS_KEY, legacyStorageKey]).then(function (stored) {
19
+ var prefs = normalizePrefs(stored[PREFS_KEY] || {});
20
+ var schemaVersion = prefs.storageSchemaVersion || 0;
21
+
22
+ if (schemaVersion >= StorageDb.TARGET_SCHEMA_VERSION) {
23
+ var activeSessionByProject = prefs.activeSessionByProject || {};
24
+ var activeSessionId = activeSessionByProject[projectId] || '';
25
+ return StorageDb.getAllByIndex('sessions', 'projectId', projectId).then(function (sessions) {
26
+ return { prefs: prefs, sessions: sessions, activeSessionId: activeSessionId, migrated: false };
27
+ });
28
+ }
29
+
30
+ // Migration v0 → v1
31
+ var legacyBlob = stored[legacyStorageKey] || {};
32
+ var legacySessions = Array.isArray(legacyBlob.sessions) ? legacyBlob.sessions : [];
33
+ var migratedSessions = [];
34
+
35
+ for (var i = 0; i < legacySessions.length; i++) {
36
+ var legacy = legacySessions[i];
37
+ if (!legacy || !legacy.id) { continue; }
38
+ var record = StorageDb.buildSessionRecord(
39
+ buildLegacySessionRecordInput(projectId, legacyBlob, legacy)
40
+ );
41
+ migratedSessions.push(record);
42
+ }
43
+
44
+ var putPromise = migratedSessions.length
45
+ ? StorageDb.putRecords('sessions', migratedSessions)
46
+ : Promise.resolve([]);
47
+
48
+ return putPromise.then(function () {
49
+ var newPrefs = StorageDb.extractLightweightPrefs(legacyBlob, projectId);
50
+ newPrefs.activeSessionByProject = StorageDb.buildActiveSessionByProject(
51
+ {},
52
+ projectId,
53
+ legacyBlob.activeSessionId || (migratedSessions.length ? migratedSessions[migratedSessions.length - 1].id : '')
54
+ );
55
+ newPrefs = normalizePrefs(newPrefs);
56
+
57
+ return chrome.storage.local.set({ [PREFS_KEY]: newPrefs }).then(function () {
58
+ return chrome.storage.local.remove(legacyStorageKey).catch(function () {});
59
+ }).then(function () {
60
+ return {
61
+ prefs: newPrefs,
62
+ sessions: migratedSessions,
63
+ activeSessionId: newPrefs.activeSessionByProject[projectId] || '',
64
+ migrated: true
65
+ };
66
+ });
67
+ });
68
+ });
69
+ }
70
+
71
+ function buildLegacySessionRecordInput(projectId, legacyBlob, legacy) {
72
+ return {
73
+ id: legacy.id,
74
+ projectId: projectId,
75
+ title: legacy.title || '',
76
+ titleSource: legacy.titleSource === 'manual' ? 'manual' : 'auto',
77
+ codexThreadId: '',
78
+ status: 'active',
79
+ focusFiles: Array.isArray(legacy.focusFiles) ? legacy.focusFiles : [],
80
+ history: Array.isArray(legacy.history) ? legacy.history : [],
81
+ runs: Array.isArray(legacy.runs) ? legacy.runs : [],
82
+ task: typeof legacy.task === 'string' ? legacy.task : '',
83
+ mode: typeof legacy.mode === 'string' ? legacy.mode : legacyBlob.mode || '',
84
+ model: typeof legacy.model === 'string' ? legacy.model : legacyBlob.model || '',
85
+ reasoningEffort: typeof legacy.reasoningEffort === 'string' ? legacy.reasoningEffort : legacyBlob.reasoningEffort || '',
86
+ speedTier: typeof legacy.speedTier === 'string' ? legacy.speedTier : legacyBlob.speedTier || '',
87
+ requireReviewing: legacy.requireReviewing !== false && legacyBlob.requireReviewing !== false,
88
+ createdAt: legacy.createdAt,
89
+ updatedAt: legacy.updatedAt
90
+ };
91
+ }
92
+
93
+ function savePrefs(prefs) {
94
+ return chrome.storage.local.set({ [PREFS_KEY]: normalizePrefs(prefs) });
95
+ }
96
+
97
+ function loadPrefs() {
98
+ return chrome.storage.local.get([PREFS_KEY]).then(function (stored) {
99
+ return normalizePrefs(stored[PREFS_KEY] || {});
100
+ });
101
+ }
102
+
103
+ function normalizePrefs(prefs) {
104
+ var source = prefs && typeof prefs === 'object' ? prefs : {};
105
+ return Object.assign({}, source, {
106
+ experimentalOtByProject: normalizeBooleanMap(source.experimentalOtByProject),
107
+ customInstructionsByProject: normalizeStringMap(source.customInstructionsByProject)
108
+ });
109
+ }
110
+
111
+ function normalizeBooleanMap(value) {
112
+ var result = {};
113
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
114
+ return result;
115
+ }
116
+ var keys = Object.keys(value);
117
+ for (var i = 0; i < keys.length; i++) {
118
+ var key = keys[i];
119
+ if (!key) {
120
+ continue;
121
+ }
122
+ result[key] = value[key] === true;
123
+ }
124
+ return result;
125
+ }
126
+
127
+ function normalizeStringMap(value) {
128
+ var result = {};
129
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
130
+ return result;
131
+ }
132
+ var keys = Object.keys(value);
133
+ for (var i = 0; i < keys.length; i++) {
134
+ var rawKey = keys[i];
135
+ var key = normalizeProjectPrefKey(rawKey);
136
+ if (!key) {
137
+ continue;
138
+ }
139
+ result[key] = typeof value[rawKey] === 'string'
140
+ ? normalizeTextField(value[rawKey], CUSTOM_INSTRUCTIONS_MAX_CHARS)
141
+ : '';
142
+ }
143
+ return result;
144
+ }
145
+
146
+ function normalizeProjectPrefKey(value) {
147
+ var key = typeof value === 'string' ? value.trim() : '';
148
+ if (!key) {
149
+ return '';
150
+ }
151
+ return normalizeTextField(key, PROJECT_PREF_KEY_MAX_CHARS);
152
+ }
153
+
154
+ function normalizeTextField(value, maxChars) {
155
+ var text = typeof value === 'string' ? value : '';
156
+ if (!Number.isFinite(maxChars) || maxChars <= 0 || text.length <= maxChars) {
157
+ return text;
158
+ }
159
+ return text.slice(0, Math.max(0, maxChars - 1)) + '…';
160
+ }
161
+
162
+ return {
163
+ PREFS_KEY: PREFS_KEY,
164
+ runMigrationIfNeeded: runMigrationIfNeeded,
165
+ savePrefs: savePrefs,
166
+ loadPrefs: loadPrefs
167
+ };
168
+ });
@@ -0,0 +1,248 @@
1
+ (function initSummary(root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory();
4
+ } else {
5
+ root.CodexOverleafSummary = factory();
6
+ }
7
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function summaryFactory() {
8
+ 'use strict';
9
+
10
+ const HIGH_RISK_TYPES = ['delete', 'overwrite-binary', 'tracked-change-decision'];
11
+
12
+ const TYPE_TO_COUNT_KEY = {
13
+ edit: 'edit',
14
+ create: 'create',
15
+ rename: 'rename',
16
+ move: 'move',
17
+ delete: 'delete',
18
+ 'overwrite-binary': 'binaryOverwrite',
19
+ 'tracked-change-decision': 'trackedChangeDecision'
20
+ };
21
+
22
+ function emptyCounts() {
23
+ return {
24
+ edit: 0,
25
+ create: 0,
26
+ rename: 0,
27
+ move: 0,
28
+ delete: 0,
29
+ binaryOverwrite: 0,
30
+ trackedChangeDecision: 0
31
+ };
32
+ }
33
+
34
+ function buildOperationSummary(operations) {
35
+ const counts = emptyCounts();
36
+ const affectedFiles = new Set();
37
+ const deletePlan = [];
38
+
39
+ for (const operation of operations || []) {
40
+ const countKey = TYPE_TO_COUNT_KEY[operation.type];
41
+ if (countKey) {
42
+ counts[countKey] += 1;
43
+ }
44
+
45
+ addPath(affectedFiles, operation.path);
46
+ addPath(affectedFiles, operation.to);
47
+
48
+ if (operation.type === 'delete') {
49
+ deletePlan.push({
50
+ path: operation.path,
51
+ reason: operation.reason || 'No reason provided'
52
+ });
53
+ }
54
+ }
55
+
56
+ return {
57
+ counts,
58
+ affectedFiles: Array.from(affectedFiles).sort(),
59
+ deletePlan
60
+ };
61
+ }
62
+
63
+ function splitDeletePlan(operations) {
64
+ const immediate = [];
65
+ const needsConfirmation = [];
66
+
67
+ for (const operation of operations || []) {
68
+ if (HIGH_RISK_TYPES.includes(operation.type)) {
69
+ needsConfirmation.push(operation);
70
+ } else {
71
+ immediate.push(operation);
72
+ }
73
+ }
74
+
75
+ return {
76
+ immediate,
77
+ needsConfirmation
78
+ };
79
+ }
80
+
81
+ function buildChangeSummaryLine({
82
+ notes = '',
83
+ operations = [],
84
+ summary,
85
+ applyResults = [],
86
+ status,
87
+ deletePlanRejected = false
88
+ } = {}) {
89
+ if (status === 'rejected') {
90
+ return 'Summary: proposed changes were rejected; no project files changed.';
91
+ }
92
+
93
+ const results = normalizeApplyResults(applyResults);
94
+ const appliedOperations = collectAppliedOperations(results);
95
+ const skippedCount = countSkippedOperations(results);
96
+ const effectiveSummary = results.length > 0
97
+ ? buildOperationSummary(appliedOperations)
98
+ : normalizeSummary(summary) || buildOperationSummary(operations);
99
+
100
+ const changePhrase = describeCounts(effectiveSummary.counts);
101
+ const note = firstUsefulSentence(notes);
102
+ const segments = [`Summary: ${changePhrase}`];
103
+ const affectedFiles = formatAffectedFiles(effectiveSummary.affectedFiles);
104
+
105
+ if (affectedFiles && changePhrase !== 'no project files changed') {
106
+ segments[0] += ` (${affectedFiles})`;
107
+ }
108
+
109
+ if (changePhrase === 'no project files changed' && note) {
110
+ segments.push(note);
111
+ }
112
+
113
+ if (deletePlanRejected) {
114
+ segments.push('delete plan was not applied');
115
+ }
116
+
117
+ if (skippedCount > 0) {
118
+ segments.push(`${skippedCount} ${pluralize('operation', skippedCount)} skipped`);
119
+ }
120
+
121
+ return ensureTerminalPeriod(segments.join('; '));
122
+ }
123
+
124
+ function addPath(paths, filePath) {
125
+ if (typeof filePath === 'string' && filePath.length > 0) {
126
+ paths.add(filePath);
127
+ }
128
+ }
129
+
130
+ function normalizeApplyResults(applyResults) {
131
+ if (!applyResults) {
132
+ return [];
133
+ }
134
+ return Array.isArray(applyResults) ? applyResults.filter(Boolean) : [applyResults];
135
+ }
136
+
137
+ function collectAppliedOperations(applyResults) {
138
+ const operations = [];
139
+ for (const result of applyResults) {
140
+ for (const item of getApplyResultEntries(result, 'applied')) {
141
+ if (item?.operation) {
142
+ operations.push(item.operation);
143
+ }
144
+ }
145
+ }
146
+ return operations;
147
+ }
148
+
149
+ function countSkippedOperations(applyResults) {
150
+ return applyResults.reduce((count, result) => count + getApplyResultEntries(result, 'skipped').length, 0);
151
+ }
152
+
153
+ function hasSkippedApplyOperations(applyResults) {
154
+ return countSkippedOperations(normalizeApplyResults(applyResults)) > 0;
155
+ }
156
+
157
+ function getApplyResultEntries(result, key) {
158
+ const entries = result?.[key];
159
+ return Array.isArray(entries) ? entries : [];
160
+ }
161
+
162
+ function normalizeSummary(summary) {
163
+ if (!summary?.counts) {
164
+ return null;
165
+ }
166
+ return {
167
+ counts: {
168
+ ...emptyCounts(),
169
+ ...summary.counts
170
+ },
171
+ affectedFiles: Array.isArray(summary.affectedFiles) ? summary.affectedFiles : [],
172
+ deletePlan: Array.isArray(summary.deletePlan) ? summary.deletePlan : []
173
+ };
174
+ }
175
+
176
+ function describeCounts(counts = emptyCounts()) {
177
+ const parts = [];
178
+ addCountPart(parts, counts.edit, 'edited', 'file');
179
+ addCountPart(parts, counts.create, 'created', 'file');
180
+ addCountPart(parts, counts.rename, 'renamed', 'file');
181
+ addCountPart(parts, counts.move, 'moved', 'file');
182
+ addCountPart(parts, counts.delete, 'deleted', 'file');
183
+ addCountPart(parts, counts.binaryOverwrite, 'overwrote', 'binary file');
184
+ addCountPart(parts, counts.trackedChangeDecision, 'handled', 'tracked-change decision');
185
+
186
+ return joinParts(parts) || 'no project files changed';
187
+ }
188
+
189
+ function addCountPart(parts, count, verb, noun) {
190
+ if (count > 0) {
191
+ parts.push(`${verb} ${count} ${pluralize(noun, count)}`);
192
+ }
193
+ }
194
+
195
+ function joinParts(parts) {
196
+ if (parts.length <= 1) {
197
+ return parts[0] || '';
198
+ }
199
+ return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
200
+ }
201
+
202
+ function pluralize(noun, count) {
203
+ if (count === 1) {
204
+ return noun;
205
+ }
206
+ if (noun.endsWith('y')) {
207
+ return `${noun.slice(0, -1)}ies`;
208
+ }
209
+ return `${noun}s`;
210
+ }
211
+
212
+ function formatAffectedFiles(files = []) {
213
+ const unique = Array.from(new Set(files.filter(file => typeof file === 'string' && file.length > 0))).sort();
214
+ if (unique.length === 0) {
215
+ return '';
216
+ }
217
+ if (unique.length <= 4) {
218
+ return unique.join(', ');
219
+ }
220
+ return `${unique.slice(0, 4).join(', ')}, +${unique.length - 4} more`;
221
+ }
222
+
223
+ function firstUsefulSentence(text) {
224
+ const compact = String(text || '').replace(/\s+/g, ' ').trim();
225
+ if (!compact) {
226
+ return '';
227
+ }
228
+
229
+ const match = compact.match(/^(.{1,220}?[.!?。!?])(?:\s|$)/);
230
+ if (match) {
231
+ return match[1];
232
+ }
233
+
234
+ return compact.length > 220 ? `${compact.slice(0, 217)}...` : compact;
235
+ }
236
+
237
+ function ensureTerminalPeriod(text) {
238
+ return /[.!?。!?]$/.test(text) ? text : `${text}.`;
239
+ }
240
+
241
+ return {
242
+ HIGH_RISK_TYPES,
243
+ buildChangeSummaryLine,
244
+ buildOperationSummary,
245
+ hasSkippedApplyOperations,
246
+ splitDeletePlan
247
+ };
248
+ });