codex-overleaf-link 2.5.0 → 2.6.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 +155 -392
- package/README.zh-CN.md +154 -393
- 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 +283 -55
- package/extension/src/backgroundBootstrapMigration.js +181 -0
- package/extension/src/backgroundSharedSessions.js +129 -16
- package/extension/src/backgroundUpdateCoordinator.js +242 -29
- package/extension/src/backgroundUpdateSafety.js +173 -0
- package/extension/src/content/activeTurnControl.js +171 -8
- package/extension/src/content/applyResultFormatters.js +46 -73
- package/extension/src/content/assetTransferBroker.js +72 -14
- package/extension/src/content/composerAttachments.js +104 -47
- package/extension/src/content/composerPanel.js +110 -12
- package/extension/src/content/contentRuntime.js +1555 -926
- package/extension/src/content/contextTray.js +8 -2
- package/extension/src/content/contextUsageView.js +267 -0
- package/extension/src/content/diagnosticsController.js +122 -96
- package/extension/src/content/diagnosticsExport.js +19 -5
- package/extension/src/content/diagnosticsPanel.js +48 -0
- package/extension/src/content/directoryCleanupRecovery.js +54 -0
- package/extension/src/content/generated/content.bundle.js +11077 -3412
- package/extension/src/content/generated/content.bundle.meta.json +14 -3
- package/extension/src/content/globalPreferencesController.js +1 -1
- package/extension/src/content/legacyGlobalRegistry.js +10 -0
- package/extension/src/content/localSkillsPanel.js +104 -14
- package/extension/src/content/markdownDomRenderer.js +5 -3
- package/extension/src/content/markdownText.js +47 -11
- package/extension/src/content/modelPicker.js +8 -4
- package/extension/src/content/nativeCompatibilityController.js +74 -30
- package/extension/src/content/otWarmMirror.js +5 -6
- package/extension/src/content/otWarmMirrorController.js +17 -20
- package/extension/src/content/pageBridgeClient.js +17 -4
- package/extension/src/content/panelMaintenance.js +46 -14
- package/extension/src/content/panelRenderer.js +57 -27
- package/extension/src/content/pendingInputView.js +1 -1
- package/extension/src/content/projectProviderSelection.js +13 -4
- package/extension/src/content/projectSessionCleanup.js +109 -62
- package/extension/src/content/projectSettingsCoordinator.js +67 -6
- package/extension/src/content/providerSettingsCoordinator.js +46 -8
- package/extension/src/content/providerSettingsDialog.js +73 -14
- package/extension/src/content/recentProjects.js +15 -8
- package/extension/src/content/runActivitySummary.js +160 -18
- package/extension/src/content/runCompletionMeta.js +532 -0
- package/extension/src/content/runController.js +39 -15
- package/extension/src/content/runFailureNotice.js +29 -13
- package/extension/src/content/runGuidanceController.js +72 -27
- package/extension/src/content/runGuidanceView.js +59 -10
- package/extension/src/content/runPresence.js +18 -8
- package/extension/src/content/runQueueScheduler.js +157 -47
- package/extension/src/content/runRecoveryActions.js +147 -0
- package/extension/src/content/runResultActions.js +28 -143
- package/extension/src/content/runReviewController.js +633 -0
- package/extension/src/content/runScrollLayout.js +21 -2
- package/extension/src/content/runTimelineView.js +367 -175
- package/extension/src/content/scopedPersistencePanelState.js +134 -20
- package/extension/src/content/selectionContextView.js +1 -1
- package/extension/src/content/sensitivePreflight.js +153 -0
- package/extension/src/content/sessionForkController.js +80 -17
- package/extension/src/content/sessionManager.js +50 -4
- package/extension/src/content/sessionMenuView.js +54 -18
- package/extension/src/content/sessionPersistence.js +25 -5
- package/extension/src/content/settingsPanel.js +22 -5
- package/extension/src/content/settingsWorkbench.js +132 -89
- package/extension/src/content/sharedSessionViewSync.js +49 -11
- package/extension/src/content/subagentActivityView.js +23 -7
- package/extension/src/content/updateIdle.js +4 -1
- package/extension/src/content/updateNotice.js +118 -12
- package/extension/src/content/updateSafetyReceiver.js +58 -0
- package/extension/src/content/writebackController.js +53 -4
- package/extension/src/content/writebackOrchestrator.js +116 -94
- package/extension/src/content/writingStyleSettings.js +35 -11
- package/extension/src/page/binaryAssetUploader.js +136 -14
- package/extension/src/page/compileBridge.js +193 -180
- package/extension/src/page/fileMover.js +256 -0
- package/extension/src/page/overleafCapabilities.js +4 -1
- 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/textCoordinates.js +17 -1
- package/extension/src/page/textFileCreator.js +114 -26
- 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 +103 -155
- package/extension/src/pageBridge.js +126 -69
- package/extension/src/popup.js +62 -10
- package/extension/src/shared/agentTranscript.js +373 -17
- package/extension/src/shared/auditRecords.js +4 -0
- package/extension/src/shared/compatibility.js +22 -6
- package/extension/src/shared/compileAdapter.js +129 -66
- package/extension/src/shared/composerAttachmentDraft.js +156 -0
- package/extension/src/shared/contextUsage.js +125 -0
- package/extension/src/shared/directoryCleanupProof.js +43 -0
- package/extension/src/shared/failureReasons.js +349 -4
- package/extension/src/shared/globalPreferences.js +30 -13
- package/extension/src/shared/governanceRules.js +4 -37
- package/extension/src/shared/i18n.js +590 -24
- package/extension/src/shared/lineReferences.js +38 -31
- 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/panelIcons.js +39 -0
- package/extension/src/shared/projectFiles.js +21 -44
- package/extension/src/shared/providerProfiles.js +5 -3
- package/extension/src/shared/reviewing.js +130 -1
- package/extension/src/shared/runActivityModel.js +70 -4
- package/extension/src/shared/runExecutionSnapshot.js +13 -0
- package/extension/src/shared/runInputQueue.js +48 -5
- package/extension/src/shared/selectionContext.js +12 -3
- package/extension/src/shared/sessionState.js +132 -28
- package/extension/src/shared/sessionTitle.js +14 -1
- package/extension/src/shared/settlementFacts.js +10 -2
- package/extension/src/shared/sharedSessionBridge.js +118 -27
- package/extension/src/shared/sharedSessionTransfer.js +140 -0
- package/extension/src/shared/staleGuard.js +166 -52
- package/extension/src/shared/storageDb.js +90 -26
- package/extension/src/shared/storageMigration.js +78 -112
- package/extension/src/shared/storageRunActions.js +267 -30
- package/extension/src/shared/subagentActivityModel.js +1 -1
- package/extension/src/shared/undoOperations.js +253 -32
- package/extension/src/shared/updateConsent.js +6 -4
- package/extension/src/shared/updateRuntimeIdentity.js +17 -3
- package/extension/src/shared/writebackIntent.js +16 -0
- package/extension/src/shared/writebackOperationEvidence.js +4 -15
- package/extension/src/shared/writebackSettlement.js +58 -40
- package/extension/styles/panel.css +1123 -493
- 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 +269 -0
- package/native-host/src/bootstrapUpdateWatchdog.js +44 -0
- package/native-host/src/chatBridgeRequest.js +60 -6
- package/native-host/src/chatBridgeResponse.js +20 -1
- package/native-host/src/chatCompletionsBridge.js +48 -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 +114 -127
- package/native-host/src/codexProviderTest.js +24 -26
- package/native-host/src/codexSessionRunner.js +234 -198
- 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/providerContextError.js +20 -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 +92 -57
- package/native-host/src/textPatch.js +473 -377
- package/native-host/src/tomlStatements.js +140 -0
- package/native-host/src/updateManager.js +409 -46
- package/native-host/src/writingStyleRuntime.js +57 -29
- package/native-host/src/writingStyleStore.js +73 -0
- package/package.json +5 -8
- package/scripts/install-managed.mjs +1 -0
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
3
|
module.exports = factory({
|
|
4
4
|
getFailureReasons: function getFailureReasonsCjs() { return require('./failureReasons.js'); },
|
|
5
|
-
getI18n: function getI18nCjs() { return require('./i18n.js'); }
|
|
5
|
+
getI18n: function getI18nCjs() { return require('./i18n.js'); },
|
|
6
|
+
RunActivityModel: require('./runActivityModel.js')
|
|
6
7
|
});
|
|
7
8
|
} else {
|
|
8
9
|
root.CodexOverleafModuleRegistry.define('AgentTranscript', [
|
|
9
10
|
'FailureReasons',
|
|
10
|
-
'I18n'
|
|
11
|
-
|
|
11
|
+
'I18n',
|
|
12
|
+
'RunActivityModel'
|
|
13
|
+
], function createAgentTranscript(FailureReasons, I18n, RunActivityModel) {
|
|
12
14
|
return factory({
|
|
13
15
|
getFailureReasons: function getFailureReasonsWindow() { return FailureReasons; },
|
|
14
|
-
getI18n: function getI18nWindow() { return I18n; }
|
|
16
|
+
getI18n: function getI18nWindow() { return I18n; },
|
|
17
|
+
RunActivityModel
|
|
15
18
|
});
|
|
16
19
|
});
|
|
17
20
|
}
|
|
@@ -25,6 +28,221 @@
|
|
|
25
28
|
? deps.getI18n
|
|
26
29
|
: function noI18n() { return null; };
|
|
27
30
|
|
|
31
|
+
// Only explicit product producers may attach these semantic identities.
|
|
32
|
+
const PRODUCT_CONCLUSIONS = {
|
|
33
|
+
"context_compacted": ["Conversation context compacted.", "会话上下文已压缩。"],
|
|
34
|
+
"compact_busy": ["Wait for the current task to finish before compacting context.", "请等待当前任务结束后再压缩上下文。"],
|
|
35
|
+
"compact_unsupported": ["This local Codex connection does not support manual compaction. Update Codex and reload the extension.", "当前本地 Codex 连接不支持手动压缩,请更新 Codex 并重新加载扩展。"],
|
|
36
|
+
"compact_failed": ["Context compaction did not complete. Check Technical Details before retrying.", "上下文压缩未完成,请查看技术详情后再重试。"],
|
|
37
|
+
"full_project_unread": [
|
|
38
|
+
"This run did not continue: the full Overleaf project was not read.",
|
|
39
|
+
"这轮没有继续:没有读到完整的 Overleaf 项目内容。"
|
|
40
|
+
],
|
|
41
|
+
"empty_result": [
|
|
42
|
+
"Codex completed, but it produced no assistant response and no local file changes.",
|
|
43
|
+
"Codex 已完成,但没有产生助手回复,也没有产生本地文件改动。"
|
|
44
|
+
],
|
|
45
|
+
"skill_installer_completed": [
|
|
46
|
+
"Skill installer completed.",
|
|
47
|
+
"Skill installer 已完成。"
|
|
48
|
+
],
|
|
49
|
+
"launch_not_started": [
|
|
50
|
+
"This task did not start: Codex did not run and no files were written.",
|
|
51
|
+
"这轮任务没有开始:Codex 没有运行,也没有写入文件。"
|
|
52
|
+
],
|
|
53
|
+
"cancelled": [
|
|
54
|
+
"This run was cancelled. It did not continue syncing or writing to Overleaf.",
|
|
55
|
+
"这轮已中断,没有继续同步或写入 Overleaf。"
|
|
56
|
+
],
|
|
57
|
+
"reload_interrupted": [
|
|
58
|
+
"The plugin reloaded while this run was still marked in progress. It has been marked interrupted to avoid showing a stale status — run the task again to continue.",
|
|
59
|
+
"插件重新加载时发现这轮任务还标记为处理中。为了避免继续显示过期状态,已把它标记为中断;可以重新运行任务。"
|
|
60
|
+
],
|
|
61
|
+
"ask_inspected": [
|
|
62
|
+
"This run only inspected and explained; no files were written.",
|
|
63
|
+
"这轮只做了检查和说明,没有写入文件。"
|
|
64
|
+
],
|
|
65
|
+
"delete_handled": [
|
|
66
|
+
"Changes were written, and delete items were handled after your confirmation.",
|
|
67
|
+
"已写入修改,并按你的确认处理删除项。"
|
|
68
|
+
],
|
|
69
|
+
"delete_rejected": [
|
|
70
|
+
"Non-delete changes were kept; delete items were not written.",
|
|
71
|
+
"已保留非删除修改;删除项没有写入。"
|
|
72
|
+
],
|
|
73
|
+
"run_complete": [
|
|
74
|
+
"This run is complete.",
|
|
75
|
+
"这轮任务已完成。"
|
|
76
|
+
],
|
|
77
|
+
"withheld_changes": [
|
|
78
|
+
"Some generated changes were blocked.",
|
|
79
|
+
"部分生成的改动已被阻止。"
|
|
80
|
+
],
|
|
81
|
+
"ask_ignored_changes": [
|
|
82
|
+
"Codex finished in Ask mode. Any local file changes were ignored and were not synced to Overleaf.",
|
|
83
|
+
"Codex 已在 Ask 模式完成;本地文件改动已忽略,未同步到 Overleaf。"
|
|
84
|
+
],
|
|
85
|
+
"no_sync_changes": [
|
|
86
|
+
"Codex finished locally. There are no changes to sync back to Overleaf.",
|
|
87
|
+
"Codex 已完成本地处理,没有需要同步回 Overleaf 的改动。"
|
|
88
|
+
],
|
|
89
|
+
"no_approved_changes": [
|
|
90
|
+
"No approved changes were written back to Overleaf.",
|
|
91
|
+
"没有已确认的改动写回 Overleaf。"
|
|
92
|
+
],
|
|
93
|
+
"reviewing_unavailable": [
|
|
94
|
+
"No files were written: Track is enabled, but Codex could not verify Overleaf Reviewing/Track Changes.",
|
|
95
|
+
"这轮没有写入:已开启“留痕”要求,但 Codex 没能确认 Overleaf 正在用 Reviewing/Track Changes。"
|
|
96
|
+
],
|
|
97
|
+
"sensitive_blocked": [
|
|
98
|
+
"This run was blocked before Codex received project context because sensitive content was detected.",
|
|
99
|
+
"检测到敏感内容,本轮已在向 Codex 发送项目上下文前阻止。"
|
|
100
|
+
],
|
|
101
|
+
"synced": [
|
|
102
|
+
"Local Codex changes were synced back to Overleaf.",
|
|
103
|
+
"本地 Codex 改动已同步回 Overleaf。"
|
|
104
|
+
],
|
|
105
|
+
"partial_sync": [
|
|
106
|
+
"Local Codex changes were sent to Overleaf, but some items were skipped.",
|
|
107
|
+
"本地 Codex 改动已尝试同步回 Overleaf,但有部分项目被跳过。"
|
|
108
|
+
],
|
|
109
|
+
"blocked_sync": [
|
|
110
|
+
"No changes were written to Overleaf; every change was blocked before writing.",
|
|
111
|
+
"没有向 Overleaf 写入任何改动;所有改动都在写入前被拦下。"
|
|
112
|
+
],
|
|
113
|
+
"unconfirmed_sync": [
|
|
114
|
+
"Codex tried to write local changes to Overleaf, but the write result did not confirm any applied or skipped entries.",
|
|
115
|
+
"Codex 已尝试把本地改动写入 Overleaf,但写入结果没有确认任何已写入或已跳过条目。"
|
|
116
|
+
],
|
|
117
|
+
"partial_sync_note": [
|
|
118
|
+
"Sync note: local Codex changes were sent to Overleaf, but some items were skipped.",
|
|
119
|
+
"同步提示:本地 Codex 改动已尝试写回 Overleaf,但有部分项目被跳过。"
|
|
120
|
+
],
|
|
121
|
+
"blocked_sync_note": [
|
|
122
|
+
"Sync note: no changes were written to Overleaf; every change was blocked before writing.",
|
|
123
|
+
"同步提示:没有向 Overleaf 写入任何改动;所有改动都在写入前被拦下。"
|
|
124
|
+
],
|
|
125
|
+
"unconfirmed_sync_note": [
|
|
126
|
+
"Writeback note: Codex could not confirm any Overleaf write result entries, so local mirror refresh and auto compile were skipped.",
|
|
127
|
+
"写入提示:Codex 没能确认任何 Overleaf 写入结果条目,因此已跳过本地 mirror 刷新和自动编译。"
|
|
128
|
+
],
|
|
129
|
+
"retry_sync": [
|
|
130
|
+
"Retried the remaining file transfers for this task.",
|
|
131
|
+
"已重试本轮未完成的文件同步。"
|
|
132
|
+
],
|
|
133
|
+
"default_no_write": [
|
|
134
|
+
"This task completed without writing Overleaf files.",
|
|
135
|
+
"这轮任务已完成,没有写入 Overleaf 文件。"
|
|
136
|
+
],
|
|
137
|
+
"default_complete": [
|
|
138
|
+
"This task completed.",
|
|
139
|
+
"这轮任务已完成。"
|
|
140
|
+
],
|
|
141
|
+
"warm_mirror_stale": [
|
|
142
|
+
"This run did not continue: Overleaf did not provide the full project, and the local workspace is not fresh enough.",
|
|
143
|
+
"这轮没有继续:Overleaf 没有提供完整项目内容,本地 workspace 也不够新。"
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const ERROR_CONCLUSIONS = {
|
|
148
|
+
"local_skill_unavailable": {
|
|
149
|
+
"code": "codex_local_skill_unavailable"
|
|
150
|
+
},
|
|
151
|
+
"local_skills_failed": {
|
|
152
|
+
"code": "codex_local_skills_failed"
|
|
153
|
+
},
|
|
154
|
+
"mode_removed": {
|
|
155
|
+
"message": "suggest_mode_removed"
|
|
156
|
+
},
|
|
157
|
+
"mode_write_required": {
|
|
158
|
+
"message": "Mode must be \"ask\" or \"auto\""
|
|
159
|
+
},
|
|
160
|
+
"invalid_json": {
|
|
161
|
+
"message": "Agent returned invalid JSON"
|
|
162
|
+
},
|
|
163
|
+
"invalid_output": {
|
|
164
|
+
"message": "Could not parse Codex output"
|
|
165
|
+
},
|
|
166
|
+
"timeout": {
|
|
167
|
+
"message": "timed out"
|
|
168
|
+
},
|
|
169
|
+
"output_limit": {
|
|
170
|
+
"message": "output limit exceeded"
|
|
171
|
+
},
|
|
172
|
+
"context_limit": {
|
|
173
|
+
"code": "codex_context_limit"
|
|
174
|
+
},
|
|
175
|
+
"codex_not_found": {
|
|
176
|
+
"message": "codex_not_found"
|
|
177
|
+
},
|
|
178
|
+
"project_locked": {
|
|
179
|
+
"message": "project_locked"
|
|
180
|
+
},
|
|
181
|
+
"reasoning_unsupported": {
|
|
182
|
+
"message": "unsupported_parameter reasoning.summary"
|
|
183
|
+
},
|
|
184
|
+
"storage_quota": {
|
|
185
|
+
"message": "quota"
|
|
186
|
+
},
|
|
187
|
+
"checkpoint": {
|
|
188
|
+
"message": "checkpoint"
|
|
189
|
+
},
|
|
190
|
+
"stale_source": {
|
|
191
|
+
"message": "changed while Codex was working"
|
|
192
|
+
},
|
|
193
|
+
"post_processing": {
|
|
194
|
+
"codexReturned": true
|
|
195
|
+
},
|
|
196
|
+
"ask_failed": {
|
|
197
|
+
"mode": "ask"
|
|
198
|
+
},
|
|
199
|
+
"auto_failed": {
|
|
200
|
+
"mode": "auto"
|
|
201
|
+
},
|
|
202
|
+
"provider_revision_conflict": {
|
|
203
|
+
"message": "provider_revision_conflict"
|
|
204
|
+
},
|
|
205
|
+
"provider_auth_rejected": {
|
|
206
|
+
"message": "provider_auth_rejected"
|
|
207
|
+
},
|
|
208
|
+
"provider_model_not_found": {
|
|
209
|
+
"message": "provider_model_not_found"
|
|
210
|
+
},
|
|
211
|
+
"provider_model_not_configured": {
|
|
212
|
+
"message": "provider_model_not_configured"
|
|
213
|
+
},
|
|
214
|
+
"provider_protocol_unverified": {
|
|
215
|
+
"message": "provider_protocol_unverified"
|
|
216
|
+
},
|
|
217
|
+
"provider_protocol_incompatible": {
|
|
218
|
+
"message": "provider_protocol_incompatible"
|
|
219
|
+
},
|
|
220
|
+
"provider_rate_limited": {
|
|
221
|
+
"message": "provider_rate_limited"
|
|
222
|
+
},
|
|
223
|
+
"provider_connection_timeout": {
|
|
224
|
+
"message": "provider_connection_timeout"
|
|
225
|
+
},
|
|
226
|
+
"provider_dns_failed": {
|
|
227
|
+
"message": "provider_dns_failed"
|
|
228
|
+
},
|
|
229
|
+
"provider_tls_failed": {
|
|
230
|
+
"message": "provider_tls_failed"
|
|
231
|
+
},
|
|
232
|
+
"provider_not_found": {
|
|
233
|
+
"message": "provider_not_found"
|
|
234
|
+
},
|
|
235
|
+
"provider_store_corrupt": {
|
|
236
|
+
"message": "provider_store_corrupt"
|
|
237
|
+
},
|
|
238
|
+
"provider_store_unavailable": {
|
|
239
|
+
"message": "provider_store_unavailable"
|
|
240
|
+
},
|
|
241
|
+
"provider_response_invalid": {
|
|
242
|
+
"message": "provider_response_invalid"
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
28
246
|
const TECHNICAL_EVENT_PATTERNS = [
|
|
29
247
|
/^agent\.command\./,
|
|
30
248
|
/^native\.task\./,
|
|
@@ -63,6 +281,14 @@
|
|
|
63
281
|
const locale = normalizeLocale(options);
|
|
64
282
|
const type = String(event.type || '');
|
|
65
283
|
|
|
284
|
+
if (type === 'codex.local_skills.missing' || type === 'codex.local_skill_invocation.ignored') {
|
|
285
|
+
return { kind: 'activity', visible: true,
|
|
286
|
+
title: type === 'codex.local_skills.missing'
|
|
287
|
+
? textFor(locale, '所选的本地技能未能加载。', 'A selected local skill could not be loaded.')
|
|
288
|
+
: textFor(locale, '所选的本地技能已关闭或不可用。', 'A selected local skill is disabled or unavailable.'),
|
|
289
|
+
status: event.status || 'failed', technicalDetail: normalizeRawEvent(event) };
|
|
290
|
+
}
|
|
291
|
+
|
|
66
292
|
if (isContextCompactionEvent(event)) {
|
|
67
293
|
return formatContextCompactionCheckpoint(event, locale);
|
|
68
294
|
}
|
|
@@ -428,16 +654,11 @@
|
|
|
428
654
|
}
|
|
429
655
|
|
|
430
656
|
function isContextCompactionEvent(event = {}) {
|
|
431
|
-
|
|
432
|
-
const method = String(event.detail?.method || event.title || '');
|
|
433
|
-
const label = `${type} ${method}`;
|
|
434
|
-
return /(compact|compaction|compacted)/i.test(label)
|
|
435
|
-
&& /(context|thread|turn|conversation|codex)/i.test(label);
|
|
657
|
+
return Boolean(deps.RunActivityModel.contextCompactionState(event));
|
|
436
658
|
}
|
|
437
659
|
|
|
438
660
|
function formatContextCompactionCheckpoint(event = {}, locale = 'en') {
|
|
439
|
-
const
|
|
440
|
-
const running = event.status === 'running' || /(started|starting|begin|prepar)/i.test(method);
|
|
661
|
+
const running = deps.RunActivityModel.contextCompactionState(event) === 'running';
|
|
441
662
|
return {
|
|
442
663
|
kind: 'checkpoint',
|
|
443
664
|
visible: true,
|
|
@@ -720,7 +941,7 @@
|
|
|
720
941
|
};
|
|
721
942
|
}
|
|
722
943
|
|
|
723
|
-
function
|
|
944
|
+
function translateRawErrorCopy(message, context = {}) {
|
|
724
945
|
const locale = normalizeLocale(context);
|
|
725
946
|
const text = String(message || '');
|
|
726
947
|
// Each branch returns the user-visible {conclusion, nextStep} pair and,
|
|
@@ -730,6 +951,28 @@
|
|
|
730
951
|
// failure data alongside the human-readable text. The string text is kept
|
|
731
952
|
// verbatim because it has mode-aware nuance (e.g. "No files were written"
|
|
732
953
|
// vs "This run did not start") the catalog's fallback strings don't capture.
|
|
954
|
+
if (context.code === 'codex_local_skill_unavailable' || /(?:The )?selected local Codex skill is unavailable/i.test(text)) {
|
|
955
|
+
return {
|
|
956
|
+
conclusion: textFor(locale, '所选 Codex 本地技能不可用或已关闭,本轮没有启动。', 'The selected local Codex skill is unavailable or disabled. This run did not start.'),
|
|
957
|
+
nextStep: textFor(locale, '请打开技能页,选择可用且已启用的技能后重新提交。', 'Open Skills, select an available enabled skill, and submit again.'),
|
|
958
|
+
failureCode: 'codex_local_skill_unavailable'
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
if (/^codex_local_skills_/.test(String(context.code || ''))
|
|
962
|
+
|| /local Codex skill discovery|Codex could not (?:list local skills|start local skill discovery)|Codex returned an invalid local skill catalog/i.test(text)) {
|
|
963
|
+
return {
|
|
964
|
+
conclusion: textFor(locale, 'Codex 本地技能未能加载,本轮没有启动。', 'Local Codex skills could not be loaded. This run did not start.'),
|
|
965
|
+
nextStep: textFor(locale, '请打开技能页重新加载本地目录,然后重新提交。', 'Open Skills to reload the local catalog, then submit again.'),
|
|
966
|
+
failureCode: 'codex_local_skills_failed'
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
if (getFailureReasonsModule()?.isContextLimitError(text, context.code)) {
|
|
970
|
+
return {
|
|
971
|
+
conclusion: textFor(locale, '本轮已停止:上下文超出模型的容量限制。', 'This run stopped because the model context limit was exceeded.'),
|
|
972
|
+
nextStep: textFor(locale, '请重试任务;如果再次超限,可使用 /compact,或新建会话并减少上下文。', 'Retry the task. If the context limit is reached again, use /compact or start a new conversation with less context.'),
|
|
973
|
+
failureCode: 'codex_context_limit'
|
|
974
|
+
};
|
|
975
|
+
}
|
|
733
976
|
const providerError = translateProviderError(text, locale);
|
|
734
977
|
if (providerError) {
|
|
735
978
|
return providerError;
|
|
@@ -848,12 +1091,107 @@
|
|
|
848
1091
|
};
|
|
849
1092
|
}
|
|
850
1093
|
|
|
1094
|
+
function productConclusionText(key, locale = 'en') {
|
|
1095
|
+
if (Object.hasOwn(PRODUCT_CONCLUSIONS, key)) return PRODUCT_CONCLUSIONS[key][locale === 'zh' ? 1 : 0];
|
|
1096
|
+
const error = key.startsWith('error:') && Object.hasOwn(ERROR_CONCLUSIONS, key.slice(6)) && ERROR_CONCLUSIONS[key.slice(6)];
|
|
1097
|
+
return error ? translateRawErrorCopy(error.message || '', { ...error, locale }).conclusion : null;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
function translateRawError(message, context = {}) {
|
|
1101
|
+
const translated = translateRawErrorCopy(message, context), locale = normalizeLocale(context);
|
|
1102
|
+
const key = Object.keys(ERROR_CONCLUSIONS).find(id => productConclusionText(`error:${id}`, locale) === translated.conclusion);
|
|
1103
|
+
return { ...translated, ...(key ? { conclusionKey: `error:${key}` } : {}) };
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// Old Native failures retained the real transport error even when their
|
|
1107
|
+
// product summary used the generic empty-result category. Re-project only
|
|
1108
|
+
// those identified product events; model prose and stored records stay intact.
|
|
1109
|
+
function projectContextLimitEvent(event, locale = 'en') {
|
|
1110
|
+
const failure = event?.failure;
|
|
1111
|
+
if (event?.status !== 'failed' || event.streamRole || event.guidanceId || event.subagent) return event;
|
|
1112
|
+
if (failure?.code === 'codex_context_limit' && failure.stage === 'codex'
|
|
1113
|
+
&& (!event.kind || event.kind === 'activity')
|
|
1114
|
+
&& ['en', 'zh'].some(language => productConclusionText('error:context_limit', language) === event.title)) {
|
|
1115
|
+
return { ...event, title: productConclusionText('error:context_limit', locale) };
|
|
1116
|
+
}
|
|
1117
|
+
if (failure?.code !== 'codex_no_usable_result' || failure.stage !== 'codex'
|
|
1118
|
+
|| !getFailureReasonsModule()?.isContextLimitError(failure.technicalMessage)) return event;
|
|
1119
|
+
const generic = ['ask_failed', 'auto_failed'].flatMap(key => ['en', 'zh'].map(language =>
|
|
1120
|
+
productConclusionText(`error:${key}`, language)));
|
|
1121
|
+
const translated = translateRawError(failure.technicalMessage, { locale });
|
|
1122
|
+
const projectedFailure = { ...failure, code: translated.failureCode,
|
|
1123
|
+
userMessage: translated.conclusion, nextAction: translated.nextStep };
|
|
1124
|
+
if ((!event.kind || event.kind === 'activity') && generic.includes(event.title)) {
|
|
1125
|
+
return { ...event, title: translated.conclusion, failure: projectedFailure };
|
|
1126
|
+
}
|
|
1127
|
+
const structured = event.detailStructured, source = structured?.conclusionSource;
|
|
1128
|
+
if (event.kind !== 'report' || source?.origin !== 'product'
|
|
1129
|
+
|| !['error:ask_failed', 'error:auto_failed'].includes(source.key)
|
|
1130
|
+
|| !generic.includes(structured.conclusion)) return event;
|
|
1131
|
+
const oldNext = ['en', 'zh'].map(language => translateRawError('', { locale: language }).nextStep);
|
|
1132
|
+
return { ...event, failure: projectedFailure, detailStructured: { ...structured,
|
|
1133
|
+
conclusion: translated.conclusion, conclusionSource: { origin: 'product', key: translated.conclusionKey },
|
|
1134
|
+
meta: (structured.meta || []).map(row => row.key === 'nextStep' && oldNext.includes(row.value)
|
|
1135
|
+
? { ...row, value: translated.nextStep } : row) } };
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
function normalizeConclusionSource(source) {
|
|
1139
|
+
if (source?.origin !== 'product' || typeof source.key !== 'string') return null;
|
|
1140
|
+
if (productConclusionText(source.key) !== null) return { origin: 'product', key: source.key };
|
|
1141
|
+
if (source.key !== 'writeback' || !['synced', 'partial_sync', 'blocked_sync', 'unconfirmed_sync'].includes(source.outcome)) return null;
|
|
1142
|
+
return { origin: 'product', key: 'writeback', outcome: source.outcome,
|
|
1143
|
+
prefixLength: Number.isSafeInteger(source.prefixLength) && source.prefixLength >= 0 ? source.prefixLength : -1,
|
|
1144
|
+
prefixKey: source.prefixKey === 'retry_sync' ? 'retry_sync' : '',
|
|
1145
|
+
hasCompile: source.hasCompile === true,
|
|
1146
|
+
compileStatus: typeof source.compileStatus === 'string' ? source.compileStatus : '',
|
|
1147
|
+
compileReason: typeof source.compileReason === 'string' ? source.compileReason : '',
|
|
1148
|
+
errorCount: Number.isSafeInteger(source.errorCount) && source.errorCount >= 0 ? source.errorCount : 0,
|
|
1149
|
+
errors: Array.isArray(source.errors) ? source.errors.slice(0, 3).filter(value => typeof value === 'string') : [],
|
|
1150
|
+
warningCount: Number.isSafeInteger(source.warningCount) && source.warningCount >= 0 ? source.warningCount : 0 };
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
function projectProductConclusion(source, locale = 'en', localizeCompileReason = value => value, raw = '') {
|
|
1154
|
+
const identity = normalizeConclusionSource(source);
|
|
1155
|
+
if (!identity) return null;
|
|
1156
|
+
if (identity.key !== 'writeback') return productConclusionText(identity.key, locale);
|
|
1157
|
+
if (identity.prefixLength < 0 || identity.prefixLength > raw.length) return null;
|
|
1158
|
+
const originalPrefix = raw.slice(0, identity.prefixLength);
|
|
1159
|
+
if (identity.prefixKey && !['en', 'zh'].some(language => productConclusionText(identity.prefixKey, language) === originalPrefix)) return null;
|
|
1160
|
+
const compose = (language, projectReason) => {
|
|
1161
|
+
const tx = (en, zh) => language === 'zh' ? zh : en;
|
|
1162
|
+
const prefix = projectReason && identity.prefixKey ? productConclusionText(identity.prefixKey, language) : originalPrefix;
|
|
1163
|
+
const note = productConclusionText(identity.outcome + (prefix && identity.outcome !== 'synced' ? '_note' : ''), language);
|
|
1164
|
+
const conclusion = prefix ? [prefix, identity.outcome === 'synced' ? '' : note].filter(Boolean).join('\n\n') : note;
|
|
1165
|
+
const { compileStatus: status, errors, errorCount, warningCount: warnings } = identity;
|
|
1166
|
+
if (!identity.hasCompile) return conclusion;
|
|
1167
|
+
const reason = projectReason ? localizeCompileReason(identity.compileReason) : identity.compileReason;
|
|
1168
|
+
const summary = errorCount
|
|
1169
|
+
? tx(`Post-write compile check: ${errorCount} remaining error(s): ${errors.slice(0, 3).join('; ')}`,
|
|
1170
|
+
`写后编译检查:仍有 ${errorCount} 个错误:${errors.slice(0, 3).join(';')}`)
|
|
1171
|
+
: status === 'success' ? (warnings
|
|
1172
|
+
? tx(`Post-write compile check succeeded with ${warnings} warning(s).`, `写后编译检查已通过,但仍有 ${warnings} 个警告。`)
|
|
1173
|
+
: tx('Post-write compile check succeeded with no reported errors.', '写后编译检查已通过,未发现错误。'))
|
|
1174
|
+
: status === 'triggered' ? (warnings
|
|
1175
|
+
? tx(`Post-write compile was triggered; latest log shows ${warnings} warning(s).`, `已触发写后编译;最新日志显示 ${warnings} 个警告。`)
|
|
1176
|
+
: tx('Post-write compile was triggered; Overleaf may still be updating the result.', '已触发写后编译;Overleaf 可能仍在更新结果。'))
|
|
1177
|
+
: status === 'unconfirmed' ? getI18nModule().t(language, 'runCompileUnconfirmed')
|
|
1178
|
+
: status === 'failed' ? tx(`Post-write compile check failed: ${reason || 'unknown reason'}`,
|
|
1179
|
+
`写后编译检查失败:${reason || '未知原因'}`)
|
|
1180
|
+
: tx(`Post-write compile finished with status: ${status || 'unknown'}.`, `写后编译完成,状态:${status || '未知'}。`);
|
|
1181
|
+
return [conclusion, summary].filter(Boolean).join('\n');
|
|
1182
|
+
};
|
|
1183
|
+
// A compacted or changed raw answer must never be reconstructed from metadata.
|
|
1184
|
+
if (!['en', 'zh'].some(language => compose(language, false) === raw)) return null;
|
|
1185
|
+
return compose(locale, true);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
851
1188
|
function buildHumanCompletionReport(input = {}) {
|
|
852
1189
|
const locale = normalizeLocale(input);
|
|
853
1190
|
const applyResults = normalizeApplyResults(input.applyResults);
|
|
854
1191
|
const appliedCount = countApplyResultEntries(applyResults, 'applied');
|
|
855
1192
|
const skippedCount = countApplyResultEntries(applyResults, 'skipped');
|
|
856
|
-
const translatedError = input.errorMessage ? translateRawError(input.errorMessage, { mode: input.mode, locale
|
|
1193
|
+
const translatedError = input.errorMessage ? translateRawError(input.errorMessage, { mode: input.mode, locale, code: input.failure?.code,
|
|
1194
|
+
codexReturned: input.conclusionKey === 'error:post_processing' }) : null;
|
|
857
1195
|
const userReport = normalizeUserReport(input.userReport);
|
|
858
1196
|
const report = userReport || buildFallbackReport(input, {
|
|
859
1197
|
appliedCount,
|
|
@@ -905,6 +1243,16 @@
|
|
|
905
1243
|
return report.text;
|
|
906
1244
|
}
|
|
907
1245
|
|
|
1246
|
+
function completionConclusionText(report) {
|
|
1247
|
+
const source = report.conclusionSource;
|
|
1248
|
+
// The new blocked composite preserves its exact model prefix. Keep the
|
|
1249
|
+
// historical formatter for every other report shape.
|
|
1250
|
+
if (source?.key === 'writeback' && source.outcome === 'blocked_sync'
|
|
1251
|
+
&& typeof report.conclusion === 'string' && ['en', 'zh'].some(locale =>
|
|
1252
|
+
projectProductConclusion(source, locale, undefined, report.conclusion) === report.conclusion)) return report.conclusion;
|
|
1253
|
+
return cleanVisibleMarkdownText(report.conclusion || '');
|
|
1254
|
+
}
|
|
1255
|
+
|
|
908
1256
|
/**
|
|
909
1257
|
* Splits the human report into a conclusion (the human-language outcome),
|
|
910
1258
|
* a body of list-style content sections (checked / findings / planned /
|
|
@@ -915,7 +1263,7 @@
|
|
|
915
1263
|
* shape for transcripts, storage fallback, and existing assertions.
|
|
916
1264
|
*/
|
|
917
1265
|
function buildStructuredHumanReport(report = {}, locale = 'en') {
|
|
918
|
-
const conclusion =
|
|
1266
|
+
const conclusion = completionConclusionText(report);
|
|
919
1267
|
|
|
920
1268
|
const bodySections = [];
|
|
921
1269
|
addListSection(bodySections, textFor(locale, '检查范围', 'Checked'), report.checked, locale);
|
|
@@ -959,12 +1307,13 @@
|
|
|
959
1307
|
}
|
|
960
1308
|
|
|
961
1309
|
if (report.saveState) meta.push({ key: 'saveState', label: textFor(locale, '保存', 'Save'), value: report.saveState });
|
|
962
|
-
return { conclusion, body: bodySections.join('\n\n'), meta
|
|
1310
|
+
return { conclusion, body: bodySections.join('\n\n'), meta,
|
|
1311
|
+
...(normalizeConclusionSource(report.conclusionSource) ? { conclusionSource: normalizeConclusionSource(report.conclusionSource) } : {}) };
|
|
963
1312
|
}
|
|
964
1313
|
|
|
965
1314
|
function formatHumanReport(report = {}, locale = 'en') {
|
|
966
1315
|
const sections = [];
|
|
967
|
-
const conclusion =
|
|
1316
|
+
const conclusion = completionConclusionText(report);
|
|
968
1317
|
if (conclusion) {
|
|
969
1318
|
sections.push(textFor(locale, `结论:${conclusion}`, `Conclusion: ${conclusion}`));
|
|
970
1319
|
}
|
|
@@ -1005,8 +1354,13 @@
|
|
|
1005
1354
|
? textFor(locale, '这轮任务已完成,没有写入 Overleaf 文件。', 'This task completed without writing Overleaf files.')
|
|
1006
1355
|
: textFor(locale, '这轮任务已完成。', 'This task completed.'));
|
|
1007
1356
|
|
|
1357
|
+
const conclusionSource = counts.translatedError?.conclusionKey
|
|
1358
|
+
? { origin: 'product', key: counts.translatedError.conclusionKey }
|
|
1359
|
+
: input.conclusionKey ? { origin: 'product', key: input.conclusionKey }
|
|
1360
|
+
: input.conclusionSource || (!input.conclusion && !input.notes
|
|
1361
|
+
? { origin: 'product', key: noWrites ? 'default_no_write' : 'default_complete' } : null);
|
|
1008
1362
|
return {
|
|
1009
|
-
conclusion,
|
|
1363
|
+
conclusion, conclusionSource: normalizeConclusionSource(conclusionSource),
|
|
1010
1364
|
checked: normalizeStringList(input.checked || input.userReport?.checked),
|
|
1011
1365
|
findings: normalizeStringList(input.findings),
|
|
1012
1366
|
plannedChanges: counts.appliedCount ? [] : operations.map(operation => formatOperationLine(operation, locale)),
|
|
@@ -1733,6 +2087,8 @@
|
|
|
1733
2087
|
|
|
1734
2088
|
return {
|
|
1735
2089
|
buildHumanCompletionReport,
|
|
2090
|
+
projectProductConclusion,
|
|
2091
|
+
projectContextLimitEvent,
|
|
1736
2092
|
buildStructuredHumanReport,
|
|
1737
2093
|
formatFallbackFinalReport,
|
|
1738
2094
|
formatFailureBlock,
|
|
@@ -25,12 +25,15 @@
|
|
|
25
25
|
const now = new Date().toISOString();
|
|
26
26
|
return {
|
|
27
27
|
id: input.id || generateId('aud'),
|
|
28
|
+
accountScopeId: redactSecretLikeText(stringField(input.accountScopeId)),
|
|
28
29
|
projectId: redactSecretLikeText(stringField(input.projectId)),
|
|
29
30
|
sessionId: redactSecretLikeText(stringField(input.sessionId)),
|
|
30
31
|
turnId: redactSecretLikeText(stringField(input.turnId)),
|
|
31
32
|
createdAt: redactSecretLikeText(stringField(input.createdAt)) || now,
|
|
32
33
|
completedAt: '',
|
|
33
34
|
mode: redactSecretLikeText(stringField(input.mode)),
|
|
35
|
+
requireReviewing: typeof input.requireReviewing === 'boolean' ? input.requireReviewing : undefined,
|
|
36
|
+
trackingDecision: ['continue', 'disable'].includes(input.trackingDecision) ? input.trackingDecision : '',
|
|
34
37
|
providerId: redactSecretLikeText(stringField(input.providerId)) || 'builtin',
|
|
35
38
|
providerName: redactSecretLikeText(stringField(input.providerName)),
|
|
36
39
|
providerRevision: finiteNumber(input.providerRevision) || 0,
|
|
@@ -84,6 +87,7 @@
|
|
|
84
87
|
function normalizeAuditLogRecord(input = {}) {
|
|
85
88
|
return {
|
|
86
89
|
id: redactSecretLikeText(stringField(input.id)) || generateId('aud'),
|
|
90
|
+
accountScopeId: redactSecretLikeText(stringField(input.accountScopeId)),
|
|
87
91
|
projectId: redactSecretLikeText(stringField(input.projectId)),
|
|
88
92
|
sessionId: redactSecretLikeText(stringField(input.sessionId)),
|
|
89
93
|
turnId: redactSecretLikeText(stringField(input.turnId)),
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const MIN_NATIVE_VERSION = '1.0.0';
|
|
13
13
|
const MIN_COMPATIBLE_NATIVE_VERSION = '1.0.0';
|
|
14
14
|
const MIN_COMPATIBLE_EXTENSION_VERSION = '1.0.0';
|
|
15
|
-
const BUILD_TARGET_VERSION = '2.
|
|
15
|
+
const BUILD_TARGET_VERSION = '2.6.0';
|
|
16
16
|
const DEFAULT_CHROME_EXTENSION_ID = 'illdpneeeopfffmiepaejglgmhpmdhdc';
|
|
17
17
|
const REQUIRED_CAPABILITIES = Object.freeze([
|
|
18
18
|
'bridgePing',
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
'codexModels',
|
|
26
26
|
'historyClearPlugin',
|
|
27
27
|
'localSkills',
|
|
28
|
+
'localCodexSkills',
|
|
28
29
|
'mirrorSensitiveScan',
|
|
29
30
|
'providerProfiles',
|
|
30
31
|
'assetTransfer',
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
function evaluateNativeCompatibility(response, metadata = {}) {
|
|
68
|
+
if (response?.extensionInstallIdentity) metadata = { ...metadata,
|
|
69
|
+
installIdentity: { ...(metadata.installIdentity || {}), ...response.extensionInstallIdentity } };
|
|
67
70
|
const native = unwrapNativeResponse(response);
|
|
68
71
|
if (!native) {
|
|
69
72
|
return compatibilityResult('native_missing', response, metadata, 'incompatible');
|
|
@@ -86,13 +89,25 @@
|
|
|
86
89
|
return analyzeNativeCompatibility(native, metadata).classification;
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
function buildInstallCommand(version = BUILD_TARGET_VERSION, platform, extensionId) {
|
|
92
|
+
function buildInstallCommand(version = BUILD_TARGET_VERSION, platform, extensionId, options = {}) {
|
|
90
93
|
const normalized = normalizeReleaseVersion(version) || BUILD_TARGET_VERSION;
|
|
91
94
|
const allowedExtensionId = normalizeInstallExtensionId(extensionId);
|
|
92
95
|
const extensionIdArg = allowedExtensionId && allowedExtensionId !== DEFAULT_CHROME_EXTENSION_ID
|
|
93
|
-
? ` --extension-id ${allowedExtensionId}`
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
? ` --extension-id ${allowedExtensionId}` : '';
|
|
97
|
+
if (options.managed === true) {
|
|
98
|
+
if (!allowedExtensionId || options.extensionId !== allowedExtensionId) return '';
|
|
99
|
+
const managedRoot = options.managedRoot;
|
|
100
|
+
const browser = options.browser === 'auto' ? 'chrome' : options.browser;
|
|
101
|
+
if (!['chrome', 'chromium'].includes(browser) || typeof managedRoot !== 'string'
|
|
102
|
+
|| !managedRoot || managedRoot.length > 4096 || managedRoot.trim() !== managedRoot
|
|
103
|
+
|| /[\u0000-\u001f\u007f]/.test(managedRoot)
|
|
104
|
+
|| !(/^(?:\/|[a-zA-Z]:[\\/]|\\\\)/.test(managedRoot))) return '';
|
|
105
|
+
// Windows setup commands are shown for PowerShell; POSIX uses sh quoting.
|
|
106
|
+
const quotedRoot = platform === 'win32' || options.platform === 'win32'
|
|
107
|
+
? "'" + managedRoot.replace(/'/g, "''") + "'"
|
|
108
|
+
: "'" + managedRoot.replace(/'/g, "'\\''") + "'";
|
|
109
|
+
return `npm exec --yes codex-overleaf-link@${normalized} -- install-managed --browser ${browser} --managed-root ${quotedRoot}${extensionIdArg}`;
|
|
110
|
+
}
|
|
96
111
|
return `npm exec --yes codex-overleaf-link@${normalized} -- install-native${extensionIdArg}`;
|
|
97
112
|
}
|
|
98
113
|
|
|
@@ -126,7 +141,7 @@
|
|
|
126
141
|
const extensionVersion = resolveMetadataVersion(metadata);
|
|
127
142
|
const nativeVersion = native && typeof native === 'object' ? native.version : undefined;
|
|
128
143
|
const platform = native && typeof native === 'object' ? native.platform : undefined;
|
|
129
|
-
const updateCommand = buildInstallCommand(BUILD_TARGET_VERSION, platform, metadata.extensionId);
|
|
144
|
+
const updateCommand = buildInstallCommand(BUILD_TARGET_VERSION, platform, metadata.extensionId, metadata.installIdentity);
|
|
130
145
|
const updateAvailable = isOlderReleaseVersion(nativeVersion, BUILD_TARGET_VERSION);
|
|
131
146
|
return {
|
|
132
147
|
status,
|
|
@@ -139,6 +154,7 @@
|
|
|
139
154
|
requiredVersion: MIN_COMPATIBLE_NATIVE_VERSION,
|
|
140
155
|
recommendedVersion: BUILD_TARGET_VERSION,
|
|
141
156
|
updateAvailable,
|
|
157
|
+
...(metadata.installIdentity ? { installIdentity: metadata.installIdentity } : {}),
|
|
142
158
|
installCommand: updateCommand,
|
|
143
159
|
updateCommand,
|
|
144
160
|
releaseUrl: buildReleaseUrl(BUILD_TARGET_VERSION),
|