codex-overleaf-link 1.8.5 → 1.9.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 +45 -21
- package/bin/codex-overleaf-link.mjs +58 -0
- package/extension/assets/icons/codex-overleaf-dialog-icon.png +0 -0
- package/extension/assets/icons/codex-overleaf-icon.png +0 -0
- package/extension/assets/icons/icon128.png +0 -0
- package/extension/assets/icons/icon16.png +0 -0
- package/extension/assets/icons/icon32.png +0 -0
- package/extension/assets/icons/icon48.png +0 -0
- package/extension/bootstrap/background.js +404 -0
- package/extension/bootstrap/manifest.template.json +51 -0
- package/extension/bootstrap/popup.css +26 -0
- package/extension/bootstrap/popup.html +38 -0
- package/extension/bootstrap/popup.js +44 -0
- package/extension/bootstrap/runtimeContext.js +2 -0
- package/extension/runtime-manifest.json +60 -0
- package/extension/src/background.js +532 -0
- package/extension/src/content/applyResultFormatters.js +387 -0
- package/extension/src/content/composerAttachments.js +522 -0
- package/extension/src/content/composerPanel.js +254 -0
- package/extension/src/content/contentRuntime.js +8895 -0
- package/extension/src/content/contextTray.js +686 -0
- package/extension/src/content/diagnosticsController.js +659 -0
- package/extension/src/content/diagnosticsPanel.js +342 -0
- package/extension/src/content/diffReviewPanel.js +797 -0
- package/extension/src/content/localSkillsPanel.js +280 -0
- package/extension/src/content/markdownText.js +606 -0
- package/extension/src/content/mirrorHealth.js +92 -0
- package/extension/src/content/modelPicker.js +489 -0
- package/extension/src/content/nativeChannel.js +62 -0
- package/extension/src/content/otWarmMirror.js +964 -0
- package/extension/src/content/otWarmMirrorController.js +174 -0
- package/extension/src/content/panelMaintenance.js +367 -0
- package/extension/src/content/panelRenderer.js +253 -0
- package/extension/src/content/recentProjects.js +1063 -0
- package/extension/src/content/reviewHunks.js +247 -0
- package/extension/src/content/runController.js +242 -0
- package/extension/src/content/runTimelineView.js +1126 -0
- package/extension/src/content/sessionManager.js +487 -0
- package/extension/src/content/sessionPanel.js +263 -0
- package/extension/src/content/settingsPanel.js +527 -0
- package/extension/src/content/themeController.js +91 -0
- package/extension/src/content/updateIdle.js +67 -0
- package/extension/src/content/writebackController.js +300 -0
- package/extension/src/content/writebackOrchestrator.js +850 -0
- package/extension/src/contentScript.js +8 -0
- package/extension/src/page/compileBridge.js +460 -0
- package/extension/src/page/overleafCapabilities.js +100 -0
- package/extension/src/page/overleafEditor.js +282 -0
- package/extension/src/page/overleafProjectSnapshot.js +234 -0
- package/extension/src/page/overleafRealtimeObserver.js +491 -0
- package/extension/src/page/pageBridgeCapability.js +71 -0
- package/extension/src/page/snapshotRouter.js +948 -0
- package/extension/src/page/trackedChangesLifecycle.js +1506 -0
- package/extension/src/page/treeOperations.js +1584 -0
- package/extension/src/page/writeGuard.js +142 -0
- package/extension/src/page/writebackRouter.js +1934 -0
- package/extension/src/pageBridge.js +2224 -0
- package/extension/src/popup.js +247 -0
- package/extension/src/shared/compatibility.js +1 -1
- package/extension/styles/panel.css +4048 -0
- package/native-host/src/index.js +9 -2
- package/native-host/src/launcher.js +2 -0
- package/native-host/src/managedInstall.js +393 -0
- package/native-host/src/managedLauncherRuntime.js +71 -0
- package/native-host/src/nativeEnvironment.js +4 -0
- package/native-host/src/nativeHostPlatform.js +16 -0
- package/native-host/src/runtimeInstaller.js +6 -1
- package/native-host/src/taskRunnerRuntime.js +8 -0
- package/native-host/src/updateArchive.js +253 -0
- package/native-host/src/updateManager.js +548 -0
- package/native-host/src/updateTrust.js +156 -0
- package/package.json +11 -2
- package/scripts/install-managed.mjs +64 -0
- package/scripts/uninstall-managed.mjs +48 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
(function initCodexOverleafLocalSkillsPanel(root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) {
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
} else {
|
|
5
|
+
root.CodexOverleafLocalSkillsPanel = factory();
|
|
6
|
+
}
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function localSkillsPanelFactory() {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Destructuring defaults handle the "dep omitted" case. Production callers
|
|
11
|
+
// pass real functions; tests that exercise partial wiring rely on the
|
|
12
|
+
// undefined-only defaults to land on the noop. Passing `null` or a non-
|
|
13
|
+
// function value is no longer silently coerced — that was an antipattern
|
|
14
|
+
// (the typeof guards used to hide a missing wire-up by swapping in a noop).
|
|
15
|
+
function createLocalSkillsPanelController({
|
|
16
|
+
root = (typeof window !== 'undefined' ? window : globalThis),
|
|
17
|
+
document: documentDep = null,
|
|
18
|
+
getPanel = () => null,
|
|
19
|
+
getState = () => null,
|
|
20
|
+
setState = () => {},
|
|
21
|
+
saveState = null,
|
|
22
|
+
sendBackgroundNative = () => Promise.resolve({ ok: false }),
|
|
23
|
+
getSkillLoadingSettings = () => ({ loadCodexOverleafSkills: true }),
|
|
24
|
+
isCodexOverleafSkillEnabled = () => true,
|
|
25
|
+
setCodexOverleafSkillEnabled = () => {},
|
|
26
|
+
setProjectSettingsStatus = () => {},
|
|
27
|
+
tr = (key) => key,
|
|
28
|
+
tx = (english) => english,
|
|
29
|
+
getComposerSkillInvocation = () => null,
|
|
30
|
+
normalizeComposerSkillInvocation = (value) => value,
|
|
31
|
+
clearComposerSkillInvocation = () => {},
|
|
32
|
+
setSlashCodexOverleafSkills = () => {},
|
|
33
|
+
clearSlashCodexOverleafSkills = () => {}
|
|
34
|
+
} = {}) {
|
|
35
|
+
const document = documentDep
|
|
36
|
+
|| root.document
|
|
37
|
+
|| (typeof globalThis !== 'undefined' ? globalThis.document : null);
|
|
38
|
+
|
|
39
|
+
async function refreshLocalSkills() {
|
|
40
|
+
showSkillListLoading();
|
|
41
|
+
try {
|
|
42
|
+
const codexOverleafResponse = await sendBackgroundNative({
|
|
43
|
+
method: 'skills.list',
|
|
44
|
+
params: { scope: 'codex-overleaf' }
|
|
45
|
+
});
|
|
46
|
+
if (!codexOverleafResponse?.ok) {
|
|
47
|
+
throw new Error(codexOverleafResponse?.error?.message || 'native host did not return Codex Overleaf skills');
|
|
48
|
+
}
|
|
49
|
+
const codexOverleafSkills = Array.isArray(codexOverleafResponse.result?.skills)
|
|
50
|
+
? codexOverleafResponse.result.skills
|
|
51
|
+
: [];
|
|
52
|
+
const state = getState() || {};
|
|
53
|
+
setState({
|
|
54
|
+
...state,
|
|
55
|
+
codexOverleafSkills
|
|
56
|
+
});
|
|
57
|
+
setSlashCodexOverleafSkills(codexOverleafSkills);
|
|
58
|
+
renderLocalSkillList();
|
|
59
|
+
} catch (err) {
|
|
60
|
+
renderLocalSkillList();
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function showSkillListLoading() {
|
|
66
|
+
const list = getPanel()?.querySelector('[data-local-skill-list]');
|
|
67
|
+
if (!list) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
list.textContent = '';
|
|
71
|
+
const placeholder = document.createElement('div');
|
|
72
|
+
placeholder.className = 'codex-project-settings-empty';
|
|
73
|
+
placeholder.textContent = tr('codexOverleafSkillsLoading');
|
|
74
|
+
list.append(placeholder);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Tracks which row is currently in "confirming remove" state.
|
|
78
|
+
// Only one row may be in this state at a time.
|
|
79
|
+
let confirmingRowId = null;
|
|
80
|
+
|
|
81
|
+
function getCodexOverleafSkillsForSettings() {
|
|
82
|
+
const state = getState() || {};
|
|
83
|
+
return Array.isArray(state.codexOverleafSkills) ? state.codexOverleafSkills : [];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function renderLocalSkillList() {
|
|
87
|
+
const list = getPanel()?.querySelector('[data-local-skill-list]');
|
|
88
|
+
if (!list) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
confirmingRowId = null;
|
|
92
|
+
const codexOverleafSkills = getCodexOverleafSkillsForSettings();
|
|
93
|
+
const codexOverleafEnabled = getSkillLoadingSettings().loadCodexOverleafSkills !== false;
|
|
94
|
+
list.textContent = '';
|
|
95
|
+
if (!codexOverleafEnabled) {
|
|
96
|
+
appendLocalSkillEmpty(list, tr('codexOverleafSkillsDisabled'));
|
|
97
|
+
}
|
|
98
|
+
if (!codexOverleafSkills.length) {
|
|
99
|
+
appendLocalSkillEmpty(list, tr('codexOverleafSkillsEmpty'));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
for (const skill of codexOverleafSkills) {
|
|
103
|
+
renderCodexOverleafSkillRow(list, skill, codexOverleafEnabled);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function renderCodexOverleafSkillRow(list, skill, masterEnabled) {
|
|
108
|
+
const id = String(skill?.id || '').trim();
|
|
109
|
+
if (!id) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const row = document.createElement('div');
|
|
113
|
+
row.className = 'codex-local-skill-row';
|
|
114
|
+
row.dataset.scope = 'codex-overleaf';
|
|
115
|
+
if (!masterEnabled) {
|
|
116
|
+
row.dataset.disabled = 'true';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Skill display name on the left — a single human-readable label
|
|
120
|
+
// (title when available, else the id). Avoids redundant "Title (id)"
|
|
121
|
+
// form per user feedback: one canonical name. The id remains as the
|
|
122
|
+
// accessible `title` tooltip so the underlying identifier is still
|
|
123
|
+
// discoverable on hover for advanced users.
|
|
124
|
+
const text = document.createElement('span');
|
|
125
|
+
const trimmedTitle = typeof skill.title === 'string' ? skill.title.trim() : '';
|
|
126
|
+
text.textContent = trimmedTitle || id;
|
|
127
|
+
text.title = id;
|
|
128
|
+
row.append(text);
|
|
129
|
+
|
|
130
|
+
// Per-skill enable switch — appended last so it sits on the right of the
|
|
131
|
+
// row, after the Remove control. It remains a real checkbox input.
|
|
132
|
+
const toggle = document.createElement('input');
|
|
133
|
+
toggle.type = 'checkbox';
|
|
134
|
+
toggle.className = 'codex-switch';
|
|
135
|
+
toggle.checked = isCodexOverleafSkillEnabled(id);
|
|
136
|
+
toggle.setAttribute('aria-label', tr('codexOverleafSkillEnableToggle'));
|
|
137
|
+
if (!masterEnabled) {
|
|
138
|
+
toggle.disabled = true;
|
|
139
|
+
}
|
|
140
|
+
toggle.addEventListener('change', event => {
|
|
141
|
+
setCodexOverleafSkillEnabled(id, event.target.checked);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
if (skill.removable !== false) {
|
|
145
|
+
// The Remove / Confirm / Cancel controls share an actions container so
|
|
146
|
+
// the per-skill switch always stays rightmost in the row, regardless of
|
|
147
|
+
// the inline confirmation state.
|
|
148
|
+
const actions = document.createElement('div');
|
|
149
|
+
actions.className = 'codex-local-skill-actions';
|
|
150
|
+
|
|
151
|
+
// Remove button — clicking it enters the inline confirmation state.
|
|
152
|
+
const removeBtn = document.createElement('button');
|
|
153
|
+
removeBtn.type = 'button';
|
|
154
|
+
removeBtn.className = 'codex-set-btn codex-set-btn--subtle';
|
|
155
|
+
removeBtn.textContent = tr('localSkillRemove');
|
|
156
|
+
|
|
157
|
+
// Confirm and Cancel buttons — only in the DOM while confirming.
|
|
158
|
+
const confirmBtn = document.createElement('button');
|
|
159
|
+
confirmBtn.type = 'button';
|
|
160
|
+
confirmBtn.className = 'codex-set-btn codex-set-btn--danger';
|
|
161
|
+
confirmBtn.textContent = tr('localSkillRemoveConfirm');
|
|
162
|
+
|
|
163
|
+
const cancelBtn = document.createElement('button');
|
|
164
|
+
cancelBtn.type = 'button';
|
|
165
|
+
cancelBtn.className = 'codex-set-btn';
|
|
166
|
+
cancelBtn.textContent = tr('localSkillRemoveCancel');
|
|
167
|
+
|
|
168
|
+
function enterConfirming() {
|
|
169
|
+
// Reset any previously confirming row back to its Remove button state.
|
|
170
|
+
if (confirmingRowId !== null && confirmingRowId !== id) {
|
|
171
|
+
resetConfirmingRow();
|
|
172
|
+
}
|
|
173
|
+
confirmingRowId = id;
|
|
174
|
+
removeBtn.remove();
|
|
175
|
+
row.dataset.confirming = 'true';
|
|
176
|
+
actions.append(confirmBtn, cancelBtn);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function exitConfirming() {
|
|
180
|
+
confirmingRowId = null;
|
|
181
|
+
confirmBtn.remove();
|
|
182
|
+
cancelBtn.remove();
|
|
183
|
+
delete row.dataset.confirming;
|
|
184
|
+
actions.append(removeBtn);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
removeBtn.addEventListener('click', event => {
|
|
188
|
+
event.preventDefault();
|
|
189
|
+
enterConfirming();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
cancelBtn.addEventListener('click', event => {
|
|
193
|
+
event.preventDefault();
|
|
194
|
+
exitConfirming();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
confirmBtn.addEventListener('click', event => {
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
// In-progress: disable Confirm, Cancel, and the enable toggle; update text.
|
|
200
|
+
confirmBtn.disabled = true;
|
|
201
|
+
cancelBtn.disabled = true;
|
|
202
|
+
toggle.disabled = true;
|
|
203
|
+
confirmBtn.textContent = tr('localSkillRemoving');
|
|
204
|
+
removeCodexOverleafSkill(id).catch(error => {
|
|
205
|
+
setProjectSettingsStatus(tx(`Failed to remove Codex Overleaf skill: ${error.message}`, `删除 Codex Overleaf 技能失败:${error.message}`), 'failed');
|
|
206
|
+
// Restore row on failure so the user can retry.
|
|
207
|
+
confirmBtn.disabled = false;
|
|
208
|
+
cancelBtn.disabled = false;
|
|
209
|
+
toggle.disabled = !masterEnabled;
|
|
210
|
+
confirmBtn.textContent = tr('localSkillRemoveConfirm');
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
actions.append(removeBtn);
|
|
215
|
+
row.append(actions);
|
|
216
|
+
|
|
217
|
+
// Store references so resetConfirmingRow can find and reset this row.
|
|
218
|
+
row._exitConfirming = exitConfirming;
|
|
219
|
+
row._skillId = id;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Per-skill enable switch is always the last child (rightmost).
|
|
223
|
+
row.append(toggle);
|
|
224
|
+
|
|
225
|
+
list.append(row);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function resetConfirmingRow() {
|
|
229
|
+
// Walk the skill list to find the row whose id matches confirmingRowId.
|
|
230
|
+
const list = getPanel()?.querySelector('[data-local-skill-list]');
|
|
231
|
+
if (!list) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
for (const child of Array.from(list.children || [])) {
|
|
235
|
+
if (child._skillId === confirmingRowId && child._exitConfirming) {
|
|
236
|
+
child._exitConfirming();
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function appendLocalSkillEmpty(list, text) {
|
|
243
|
+
const empty = document.createElement('div');
|
|
244
|
+
empty.className = 'codex-project-settings-empty';
|
|
245
|
+
empty.textContent = text;
|
|
246
|
+
list.append(empty);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function removeCodexOverleafSkill(id) {
|
|
250
|
+
const response = await sendBackgroundNative({
|
|
251
|
+
method: 'skills.remove',
|
|
252
|
+
params: {
|
|
253
|
+
scope: 'codex-overleaf',
|
|
254
|
+
id
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
if (!response?.ok) {
|
|
258
|
+
throw new Error(response?.error?.message || 'native host did not remove Codex Overleaf skill');
|
|
259
|
+
}
|
|
260
|
+
const activeSkill = normalizeComposerSkillInvocation(getComposerSkillInvocation());
|
|
261
|
+
if (activeSkill?.scope === 'codex-overleaf' && activeSkill.skillId === id) {
|
|
262
|
+
clearComposerSkillInvocation();
|
|
263
|
+
}
|
|
264
|
+
setProjectSettingsStatus(tr('codexOverleafSkillRemoveDone'), 'completed');
|
|
265
|
+
clearSlashCodexOverleafSkills();
|
|
266
|
+
await refreshLocalSkills();
|
|
267
|
+
await saveState?.();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
refreshLocalSkills,
|
|
272
|
+
renderLocalSkillList,
|
|
273
|
+
removeCodexOverleafSkill
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return {
|
|
278
|
+
createLocalSkillsPanelController
|
|
279
|
+
};
|
|
280
|
+
});
|