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,369 @@
1
+ (function initUndoOperations(root, factory) {
2
+ if (typeof module === 'object' && module.exports) {
3
+ module.exports = factory();
4
+ } else {
5
+ root.CodexOverleafUndoOperations = factory();
6
+ }
7
+ })(typeof globalThis !== 'undefined' ? globalThis : window, function undoOperationsFactory() {
8
+ 'use strict';
9
+
10
+ function buildUndoOperations(project, appliedOperations) {
11
+ const workingFilesByPath = new Map();
12
+ for (const file of project?.files || []) {
13
+ if (typeof file?.path === 'string' && typeof file.content === 'string') {
14
+ workingFilesByPath.set(file.path, file.content);
15
+ }
16
+ }
17
+
18
+ const undo = [];
19
+ const fullRestoreEditPaths = new Set();
20
+
21
+ for (const operation of appliedOperations || []) {
22
+ if (!operation || typeof operation.type !== 'string') {
23
+ continue;
24
+ }
25
+
26
+ if (operation.type === 'edit') {
27
+ if (!operation.path || !workingFilesByPath.has(operation.path)) {
28
+ continue;
29
+ }
30
+ const currentBeforeEdit = workingFilesByPath.get(operation.path);
31
+ if (!fullRestoreEditPaths.has(operation.path)) {
32
+ const inversePatches = buildInverseTextPatches(currentBeforeEdit, operation.patches);
33
+ if (inversePatches.length) {
34
+ undo.push(normalizeUndoOperation({
35
+ type: 'edit',
36
+ path: operation.path,
37
+ patches: inversePatches,
38
+ reason: 'Undo edit'
39
+ }));
40
+ } else {
41
+ fullRestoreEditPaths.add(operation.path);
42
+ undo.push(normalizeUndoOperation({
43
+ type: 'edit',
44
+ path: operation.path,
45
+ replaceAll: currentBeforeEdit,
46
+ reason: 'Undo edit'
47
+ }));
48
+ }
49
+ }
50
+ } else if (operation.type === 'create') {
51
+ if (!operation.path) {
52
+ continue;
53
+ }
54
+ undo.push(normalizeUndoOperation({
55
+ type: 'delete',
56
+ path: operation.path,
57
+ reason: 'Undo create'
58
+ }));
59
+ } else if (operation.type === 'rename') {
60
+ if (!operation.path || !operation.to) {
61
+ continue;
62
+ }
63
+ undo.push(normalizeUndoOperation({
64
+ type: 'rename',
65
+ path: operation.to,
66
+ to: operation.path,
67
+ reason: 'Undo rename'
68
+ }));
69
+ } else if (operation.type === 'move') {
70
+ if (!operation.path || !operation.to) {
71
+ continue;
72
+ }
73
+ undo.push(normalizeUndoOperation({
74
+ type: 'move',
75
+ path: operation.to,
76
+ to: operation.path,
77
+ reason: 'Undo move'
78
+ }));
79
+ } else if (operation.type === 'delete') {
80
+ if (!operation.path || !workingFilesByPath.has(operation.path)) {
81
+ continue;
82
+ }
83
+ undo.push(normalizeUndoOperation({
84
+ type: 'create',
85
+ path: operation.path,
86
+ content: workingFilesByPath.get(operation.path),
87
+ reason: 'Undo delete'
88
+ }));
89
+ }
90
+
91
+ applyOperationToFiles(workingFilesByPath, operation);
92
+ }
93
+
94
+ return undo.reverse();
95
+ }
96
+
97
+ function buildInverseTextPatches(textBeforeEdit, patches) {
98
+ if (!Array.isArray(patches) || !patches.length) {
99
+ return [];
100
+ }
101
+ const normalized = normalizeTextPatches(patches, String(textBeforeEdit || '').length);
102
+ if (!normalized.ok) {
103
+ return [];
104
+ }
105
+ const applied = applyTextPatches(textBeforeEdit, normalized.patches);
106
+ if (!applied.ok) {
107
+ return [];
108
+ }
109
+
110
+ let offset = 0;
111
+ return normalized.patches.map(patch => {
112
+ const from = patch.from + offset;
113
+ const to = from + patch.insert.length;
114
+ offset += patch.insert.length - (patch.to - patch.from);
115
+ return {
116
+ from,
117
+ to,
118
+ expected: patch.insert,
119
+ insert: patch.expected
120
+ };
121
+ });
122
+ }
123
+
124
+ function buildUndoCheckpoint(project, appliedOperations) {
125
+ const undoOperations = buildUndoOperations(project, appliedOperations);
126
+ const expectedFiles = buildExpectedFilesAfterOperations(project, appliedOperations);
127
+ return {
128
+ undoOperations,
129
+ undoBaseFiles: filesMapToList(selectUndoBaseFiles(expectedFiles, undoOperations))
130
+ };
131
+ }
132
+
133
+ function buildSnapshotRestoreUndo(run = {}) {
134
+ const undoOperations = Array.isArray(run.undoOperations) ? run.undoOperations : [];
135
+ const originalByPath = buildOriginalFilesForSnapshotUndo(run, undoOperations);
136
+ if (!originalByPath.size) {
137
+ return {
138
+ operations: undoOperations,
139
+ snapshotRestore: false
140
+ };
141
+ }
142
+
143
+ const restoredEditPaths = new Set();
144
+ const operations = [];
145
+ let snapshotRestore = false;
146
+ for (const operation of undoOperations) {
147
+ if (operation?.type === 'edit' && operation.path && originalByPath.has(operation.path)) {
148
+ if (restoredEditPaths.has(operation.path)) {
149
+ continue;
150
+ }
151
+ restoredEditPaths.add(operation.path);
152
+ snapshotRestore = true;
153
+ operations.push(normalizeUndoOperation({
154
+ type: 'edit',
155
+ path: operation.path,
156
+ replaceAll: originalByPath.get(operation.path),
157
+ reason: 'Undo edit'
158
+ }));
159
+ continue;
160
+ }
161
+ operations.push(operation);
162
+ }
163
+
164
+ return {
165
+ operations,
166
+ snapshotRestore
167
+ };
168
+ }
169
+
170
+ function buildOriginalFilesForSnapshotUndo(run, undoOperations) {
171
+ const expectedFiles = filesListToMap(run.undoExpectedFiles);
172
+ if (expectedFiles.size) {
173
+ return expectedFiles;
174
+ }
175
+
176
+ const editPaths = new Set((undoOperations || [])
177
+ .filter(operation => operation?.type === 'edit' && operation.path)
178
+ .map(operation => operation.path));
179
+ if (!editPaths.size) {
180
+ return new Map();
181
+ }
182
+
183
+ const workingFiles = filesListToMap(run.undoBaseFiles);
184
+ if (!workingFiles.size) {
185
+ return new Map();
186
+ }
187
+ for (const operation of undoOperations || []) {
188
+ applyOperationToFiles(workingFiles, operation);
189
+ }
190
+
191
+ const originalByPath = new Map();
192
+ for (const path of editPaths) {
193
+ const content = workingFiles.get(path);
194
+ if (typeof content === 'string') {
195
+ originalByPath.set(path, content);
196
+ }
197
+ }
198
+ return originalByPath;
199
+ }
200
+
201
+ function buildExpectedFilesAfterOperations(project, appliedOperations) {
202
+ const filesByPath = new Map();
203
+ for (const file of project?.files || []) {
204
+ if (typeof file?.path === 'string' && typeof file.content === 'string') {
205
+ filesByPath.set(file.path, file.content);
206
+ }
207
+ }
208
+
209
+ for (const operation of appliedOperations || []) {
210
+ applyOperationToFiles(filesByPath, operation);
211
+ }
212
+
213
+ return filesByPath;
214
+ }
215
+
216
+ function applyOperationToFiles(filesByPath, operation) {
217
+ if (!operation || typeof operation.type !== 'string' || !operation.path) {
218
+ return;
219
+ }
220
+
221
+ if (operation.type === 'edit') {
222
+ const current = filesByPath.get(operation.path);
223
+ if (typeof current !== 'string') {
224
+ return;
225
+ }
226
+ if (typeof operation.replaceAll === 'string') {
227
+ filesByPath.set(operation.path, operation.replaceAll);
228
+ } else if (Array.isArray(operation.patches) && operation.patches.length) {
229
+ const patched = applyTextPatches(current, operation.patches);
230
+ if (patched.ok) {
231
+ filesByPath.set(operation.path, patched.text);
232
+ }
233
+ } else if (typeof operation.find === 'string' && typeof operation.replace === 'string') {
234
+ filesByPath.set(operation.path, current.split(operation.find).join(operation.replace));
235
+ }
236
+ } else if (operation.type === 'create') {
237
+ filesByPath.set(operation.path, operation.content || '');
238
+ } else if (operation.type === 'rename' || operation.type === 'move') {
239
+ if (!operation.to || !filesByPath.has(operation.path)) {
240
+ return;
241
+ }
242
+ const content = filesByPath.get(operation.path);
243
+ filesByPath.delete(operation.path);
244
+ filesByPath.set(operation.to, content);
245
+ } else if (operation.type === 'delete') {
246
+ filesByPath.delete(operation.path);
247
+ }
248
+ }
249
+
250
+ function filesMapToList(filesByPath) {
251
+ return Array.from(filesByPath.entries()).map(([path, content]) => ({
252
+ path,
253
+ content
254
+ }));
255
+ }
256
+
257
+ function filesListToMap(files) {
258
+ const filesByPath = new Map();
259
+ for (const file of files || []) {
260
+ if (typeof file?.path === 'string' && typeof file.content === 'string') {
261
+ filesByPath.set(file.path, file.content);
262
+ }
263
+ }
264
+ return filesByPath;
265
+ }
266
+
267
+ function selectUndoBaseFiles(expectedFilesByPath, undoOperations) {
268
+ const neededPaths = new Set();
269
+ for (const operation of undoOperations || []) {
270
+ if (!operation?.path) {
271
+ continue;
272
+ }
273
+ if (operation.type === 'edit' || operation.type === 'delete' || operation.type === 'rename' || operation.type === 'move') {
274
+ neededPaths.add(operation.path);
275
+ }
276
+ }
277
+
278
+ const selected = new Map();
279
+ for (const [path, content] of expectedFilesByPath.entries()) {
280
+ if (neededPaths.has(path)) {
281
+ selected.set(path, content);
282
+ }
283
+ }
284
+ return selected;
285
+ }
286
+
287
+ function normalizeUndoOperation(operation) {
288
+ const normalized = {
289
+ type: operation.type,
290
+ path: operation.path,
291
+ to: operation.to ?? null,
292
+ find: null,
293
+ replace: null,
294
+ replaceAll: operation.replaceAll ?? null,
295
+ content: operation.content ?? null,
296
+ reason: operation.reason || null
297
+ };
298
+ if (Array.isArray(operation.patches) && operation.patches.length) {
299
+ normalized.patches = operation.patches.map(patch => ({
300
+ from: patch.from,
301
+ to: patch.to,
302
+ expected: String(patch.expected ?? ''),
303
+ insert: String(patch.insert ?? '')
304
+ }));
305
+ }
306
+ return normalized;
307
+ }
308
+
309
+ function applyTextPatches(text, patches) {
310
+ const normalized = normalizeTextPatches(patches, text.length);
311
+ if (!normalized.ok) {
312
+ return normalized;
313
+ }
314
+
315
+ let next = text;
316
+ for (const patch of normalized.patches.slice().sort((left, right) => right.from - left.from)) {
317
+ if (next.slice(patch.from, patch.to) !== patch.expected) {
318
+ return {
319
+ ok: false,
320
+ reason: 'Patch expected text did not match'
321
+ };
322
+ }
323
+ next = next.slice(0, patch.from) + patch.insert + next.slice(patch.to);
324
+ }
325
+ return {
326
+ ok: true,
327
+ text: next
328
+ };
329
+ }
330
+
331
+ function normalizeTextPatches(patches, length) {
332
+ const normalized = [];
333
+ let previousTo = 0;
334
+ for (const rawPatch of patches || []) {
335
+ const from = Number(rawPatch?.from);
336
+ const to = Number(rawPatch?.to);
337
+ if (!Number.isInteger(from) || !Number.isInteger(to) || from < 0 || to < from || to > length) {
338
+ return {
339
+ ok: false,
340
+ reason: 'Invalid patch range'
341
+ };
342
+ }
343
+ if (from < previousTo) {
344
+ return {
345
+ ok: false,
346
+ reason: 'Overlapping patch ranges'
347
+ };
348
+ }
349
+ previousTo = to;
350
+ normalized.push({
351
+ from,
352
+ to,
353
+ expected: String(rawPatch.expected ?? ''),
354
+ insert: String(rawPatch.insert ?? '')
355
+ });
356
+ }
357
+ return {
358
+ ok: true,
359
+ patches: normalized
360
+ };
361
+ }
362
+
363
+ return {
364
+ buildUndoCheckpoint,
365
+ buildExpectedFilesAfterOperations,
366
+ buildUndoOperations,
367
+ buildSnapshotRestoreUndo
368
+ };
369
+ });
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ function buildCodexExecArgs({ cwd, schemaPath, outputPath, model, reasoningEffort, speedTier }) {
4
+ const args = [
5
+ ...buildCodexSpeedArgs(speedTier),
6
+ '--ask-for-approval',
7
+ 'never',
8
+ 'exec',
9
+ '--skip-git-repo-check',
10
+ '--sandbox',
11
+ 'read-only',
12
+ '--cd',
13
+ cwd,
14
+ '--output-schema',
15
+ schemaPath,
16
+ '--output-last-message',
17
+ outputPath,
18
+ '--json'
19
+ ];
20
+
21
+ if (model) {
22
+ args.push('-m', model);
23
+ }
24
+
25
+ if (reasoningEffort) {
26
+ args.push('-c', `model_reasoning_effort="${reasoningEffort}"`);
27
+ }
28
+
29
+ args.push('-');
30
+ return args;
31
+ }
32
+
33
+ function buildCodexSpeedArgs(speedTier) {
34
+ if (speedTier === 'fast') {
35
+ return ['--enable', 'fast_mode', '-c', 'service_tier="fast"'];
36
+ }
37
+ return ['--disable', 'fast_mode'];
38
+ }
39
+
40
+ module.exports = {
41
+ buildCodexExecArgs,
42
+ buildCodexSpeedArgs
43
+ };