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
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
function create(deps = {}) {
|
|
5
5
|
if (!deps.RunActivityModel) return null;
|
|
6
|
-
const { RunActivityModel: Model, tx, findRunRecord, getPanel, cssEscape, isGuidance,
|
|
7
|
-
formatElapsed, renderMarkdownBlockText, renderRunEvent, presence, classifyStatus, getProjectId, summarizeCommand,
|
|
6
|
+
const { RunActivityModel: Model, RunGuidanceView, getPendingGuidance = () => [], PanelIcons, tx, findRunRecord, getPanel, cssEscape, isGuidance,
|
|
7
|
+
formatElapsed, renderMarkdownBlockText, renderRunEvent, presence, getNotStartedRun, getFinishedRun, classifyStatus, getProjectId, summarizeCommand, projectReviewResultEvent, formatReviewResultFailure,
|
|
8
8
|
sanitizeAssistantVisibleText: sanitize = value => String(value || '') } = deps;
|
|
9
9
|
const cards = new WeakMap();
|
|
10
10
|
const choices = new Map();
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
return node;
|
|
25
25
|
};
|
|
26
26
|
const subagentView = deps.SubagentActivityView?.create({
|
|
27
|
-
tx, getPanel, plain, make, icon, formatElapsed,
|
|
27
|
+
tx, getPanel, plain, plainThought, make, icon, formatElapsed, glyph: name => deps.PanelIcons?.svg?.(name) || '',
|
|
28
28
|
renderBlocks: (parent, blocks, rows, card, run) => reconcile(parent, blocks, rows,
|
|
29
29
|
block => buildBlock(block, card), (row, block) => updateBlock(row, block, card, run))
|
|
30
30
|
});
|
|
@@ -115,6 +115,31 @@
|
|
|
115
115
|
disclosure(el, key);
|
|
116
116
|
return { el, label, target, status, diff, body, key, bodyStamp: '' };
|
|
117
117
|
}
|
|
118
|
+
function reviewResultLines(item) {
|
|
119
|
+
const source = item.event || {};
|
|
120
|
+
if (item.kind !== 'notice' || source.streamRole || source.guidanceId || source.subagent || source.technicalDetail
|
|
121
|
+
|| (source.kind && source.kind !== 'activity') || item.meta?.noticeSource || source.activity?.noticeSource || source.activity?.id) return [];
|
|
122
|
+
const event = projectReviewResultEvent?.(source) || source;
|
|
123
|
+
const english = /^(?:Undo result: (?:undone \d+ item\(s\), skipped \d+ item\(s\)|undone \d+ file\(s\), skipped \d+|rejected \d+ tracked change\(s\), skipped \d+)|Accept result: accepted \d+ tracked change\(s\), skipped \d+)$/;
|
|
124
|
+
const chinese = /^(?:撤销结果:(?:已撤销 \d+ 项,跳过 \d+ 项|已撤销 \d+ 个文件,跳过 \d+ 项|已拒绝 \d+ 条留痕,跳过 \d+ 条)|接受结果:已接受 \d+ 条留痕,跳过 \d+ 条)$/;
|
|
125
|
+
if (!english.test(event.title || '') && !chinese.test(event.title || '')) return [];
|
|
126
|
+
const skipped = event.detail?.Skipped || event.detail?.['跳过'];
|
|
127
|
+
if (!Array.isArray(skipped) && source.failure) {
|
|
128
|
+
const message = plain(formatReviewResultFailure?.(source.failure)?.message).slice(0, 1000);
|
|
129
|
+
return message ? [message] : [];
|
|
130
|
+
}
|
|
131
|
+
if (!Array.isArray(skipped)) return [];
|
|
132
|
+
return skipped.flatMap(entry => {
|
|
133
|
+
const fileValue = entry?.File ?? entry?.['文件'], reasonValue = entry?.Reason ?? entry?.['原因'];
|
|
134
|
+
if (typeof fileValue !== 'string' || typeof reasonValue !== 'string') return [];
|
|
135
|
+
if (source.failure?.file === fileValue && [source.failure.userMessage, fileValue + ': ' + source.failure.userMessage].includes(reasonValue)) {
|
|
136
|
+
const message = plain(formatReviewResultFailure?.(source.failure)?.message).slice(0, 1000);
|
|
137
|
+
if (message) return [message];
|
|
138
|
+
}
|
|
139
|
+
const file = plain(fileValue).slice(0, 300), reason = plain(reasonValue).slice(0, 1000);
|
|
140
|
+
return file && reason ? [reason.startsWith(file + ': ') ? reason : file + ': ' + reason] : [];
|
|
141
|
+
});
|
|
142
|
+
}
|
|
118
143
|
function renderTool(row, item, card, run) {
|
|
119
144
|
const meta = item.meta || {};
|
|
120
145
|
const state = effectiveState(item, run);
|
|
@@ -140,7 +165,8 @@
|
|
|
140
165
|
row.status.hidden = true;
|
|
141
166
|
} else row.status.hidden = false;
|
|
142
167
|
const publicText = plain(item.event?.title);
|
|
143
|
-
const
|
|
168
|
+
const reviewLines = reviewResultLines(item);
|
|
169
|
+
const stamp = [publicText, meta.output, meta.command, meta.exitCode, file?.preview, state, meta.clipped, JSON.stringify(reviewLines)].join('\0');
|
|
144
170
|
if (stamp !== row.bodyStamp) {
|
|
145
171
|
row.bodyStamp = stamp;
|
|
146
172
|
row.body.replaceChildren();
|
|
@@ -155,9 +181,11 @@
|
|
|
155
181
|
} else {
|
|
156
182
|
if (meta.command) { const command = make('pre', 'run-workflow-command'); command.textContent = plain(meta.command); row.body.append(command); }
|
|
157
183
|
if (meta.output) { const output = make('pre', 'run-workflow-output'); output.textContent = plain(meta.output); row.body.append(output); }
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
184
|
+
for (const value of reviewLines.length ? reviewLines : [publicText]) {
|
|
185
|
+
const note = make('div', 'run-workflow-tool-note');
|
|
186
|
+
note.textContent = value;
|
|
187
|
+
row.body.append(note);
|
|
188
|
+
}
|
|
161
189
|
}
|
|
162
190
|
if (meta.exitCode !== undefined) { const exit = make('div', 'run-workflow-tool-note'); exit.textContent = tx('Exit code: ', '退出码:') + meta.exitCode; row.body.append(exit); }
|
|
163
191
|
if (meta.clipped || file?.clipped) { const more = make('div', 'run-workflow-tool-note'); more.textContent = tx('Preview only. More detail may be available in diagnostics.', '当前为摘要预览,更多信息可通过诊断查看。'); row.body.append(more); }
|
|
@@ -201,6 +229,16 @@
|
|
|
201
229
|
el.addEventListener('toggle', row.showFull);
|
|
202
230
|
return row;
|
|
203
231
|
}
|
|
232
|
+
// One-line thought previews are plain text: drop the Markdown emphasis that
|
|
233
|
+
// reasoning summaries use for their headings ("**Reading the file**").
|
|
234
|
+
function plainThought(value) {
|
|
235
|
+
return String(value || '').replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g, '$2').replace(/\s+/g, ' ').trim();
|
|
236
|
+
}
|
|
237
|
+
// A finished thought that opens with a bold heading is summarised by that heading.
|
|
238
|
+
function thoughtLead(value) {
|
|
239
|
+
const heading = /^\s*(\*\*|__)(?=\S)(.+?\S)\1\s*(?:\n|$)/.exec(String(value || ''));
|
|
240
|
+
return heading ? heading[2].trim() : firstSentence(plainThought(value));
|
|
241
|
+
}
|
|
204
242
|
function updateThought(row, block, run) {
|
|
205
243
|
const value = String(sanitize(block.event.title) || '').trim();
|
|
206
244
|
const live = run.status === 'running' && block.event.status === 'running';
|
|
@@ -215,8 +253,7 @@
|
|
|
215
253
|
const started = Date.parse(block.startedAt || ''), ended = Date.parse(block.event.timestamp || '');
|
|
216
254
|
const seconds = Number.isFinite(started) && Number.isFinite(ended) && ended > started ? formatElapsed(ended - started) : '';
|
|
217
255
|
text(row.label, seconds ? tx('Thought ' + seconds, '思考 ' + seconds) : tx('Thought', '思考'));
|
|
218
|
-
|
|
219
|
-
text(row.lead, (flat.match(/^.{12,160}?[.!?。!?](?=\s|$)/) || [flat.slice(0, 160)])[0]);
|
|
256
|
+
text(row.lead, thoughtLead(value));
|
|
220
257
|
row.value = value;
|
|
221
258
|
row.showFull();
|
|
222
259
|
}
|
|
@@ -350,10 +387,10 @@
|
|
|
350
387
|
const live = run.status === 'running' && block.event.status === 'running';
|
|
351
388
|
const started = Date.parse(block.startedAt || ''), ended = Date.parse(block.event.timestamp || '');
|
|
352
389
|
const seconds = Number.isFinite(started) && Number.isFinite(ended) && ended > started ? ' ' + formatElapsed(ended - started) : '';
|
|
353
|
-
const flat = value
|
|
390
|
+
const flat = plainThought(value);
|
|
354
391
|
entries.push({ key: block.key, kind: 'thought', state: live ? 'running' : 'completed',
|
|
355
392
|
label: live ? tx('Thinking', '思考中') : tx('Thought', '思考') + seconds,
|
|
356
|
-
lead: live ? (flat.length > 90 ? '…' + flat.slice(-90) : flat) :
|
|
393
|
+
lead: live ? (flat.length > 90 ? '…' + flat.slice(-90) : flat) : thoughtLead(value) });
|
|
357
394
|
} else if (block.kind !== 'message' && block.kind !== 'guidance') {
|
|
358
395
|
for (const item of block.kind === 'exploreGroup' ? block.items : [block]) {
|
|
359
396
|
if (item.kind === 'notice') continue;
|
|
@@ -464,6 +501,74 @@
|
|
|
464
501
|
if (!choices.has(row.key)) row.el.open = items.some(item => card.projection.notices.some(notice => notice.key === item.key));
|
|
465
502
|
}
|
|
466
503
|
|
|
504
|
+
// Compaction marks sit outside the activity rows: a manual /compact run is
|
|
505
|
+
// shown as a divider, and a completed automatic compaction leaves one above
|
|
506
|
+
// that turn's answer.
|
|
507
|
+
function mountCompaction(root, run) {
|
|
508
|
+
const node = make('div', 'run-compaction');
|
|
509
|
+
node.hidden = true;
|
|
510
|
+
const line = make('div', 'run-compaction-line');
|
|
511
|
+
const label = make('span', 'run-compaction-label');
|
|
512
|
+
const glyph = make('span', 'run-compaction-glyph');
|
|
513
|
+
glyph.setAttribute('aria-hidden', 'true');
|
|
514
|
+
const title = make('span', 'run-compaction-title');
|
|
515
|
+
const time = make('span', 'run-compaction-time');
|
|
516
|
+
label.append(glyph, title, time);
|
|
517
|
+
line.append(label);
|
|
518
|
+
const sub = make('div', 'run-compaction-sub');
|
|
519
|
+
node.append(line, sub);
|
|
520
|
+
if (run.operation === 'compact') {
|
|
521
|
+
root.dataset.operation = 'compact';
|
|
522
|
+
node.dataset.kind = 'manual';
|
|
523
|
+
root.querySelector('[data-run-task]')?.after(node);
|
|
524
|
+
} else {
|
|
525
|
+
node.dataset.kind = 'auto';
|
|
526
|
+
root.querySelector('[data-run-report]')?.before(node);
|
|
527
|
+
}
|
|
528
|
+
return { node, glyph, title, time, sub, icon: '' };
|
|
529
|
+
}
|
|
530
|
+
function renderCompaction(card, run, result) {
|
|
531
|
+
const view = card.compaction;
|
|
532
|
+
if (!view) return;
|
|
533
|
+
const clock = value => {
|
|
534
|
+
const date = new Date(value || '');
|
|
535
|
+
return Number.isFinite(date.getTime())
|
|
536
|
+
? new Intl.DateTimeFormat(tx('en-US', 'zh-CN'), { hour: '2-digit', minute: '2-digit' }).format(date) : '';
|
|
537
|
+
};
|
|
538
|
+
const setIcon = name => {
|
|
539
|
+
if (view.icon === name) return;
|
|
540
|
+
view.icon = name;
|
|
541
|
+
view.glyph.innerHTML = name ? PanelIcons?.svg(name) || '' : '';
|
|
542
|
+
};
|
|
543
|
+
if (view.node.dataset.kind === 'manual') {
|
|
544
|
+
const state = run.status === 'running' ? 'running' : run.status === 'completed' ? 'completed'
|
|
545
|
+
: ['cancelled', 'rejected'].includes(run.status) ? 'cancelled' : run.status === 'interrupted' ? 'interrupted' : 'failed';
|
|
546
|
+
view.node.dataset.state = state;
|
|
547
|
+
view.node.hidden = false;
|
|
548
|
+
setIcon(state === 'running' ? '' : state === 'completed' ? 'compact' : 'alert');
|
|
549
|
+
text(view.title, ({
|
|
550
|
+
running: tx('Compacting context', '正在压缩上下文'),
|
|
551
|
+
completed: tx('Context compacted', '上下文已压缩'),
|
|
552
|
+
cancelled: tx('Compaction stopped', '已停止压缩'),
|
|
553
|
+
interrupted: tx('Compaction interrupted', '压缩已中断'),
|
|
554
|
+
failed: tx('Compaction did not finish', '压缩未完成')
|
|
555
|
+
})[state]);
|
|
556
|
+
text(view.time, state === 'running' ? '' : clock(run.finishedAt));
|
|
557
|
+
text(view.sub, state === 'running' ? tx('You can keep typing; messages send after compaction.', '可以继续输入,消息会在压缩完成后发送。')
|
|
558
|
+
: state === 'completed' ? tx('Earlier turns were summarized.', '此前的对话已整理为摘要。') : '');
|
|
559
|
+
view.sub.hidden = !view.sub.textContent;
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
view.node.hidden = !result.compactedAt;
|
|
563
|
+
if (!result.compactedAt) return;
|
|
564
|
+
view.node.dataset.state = 'completed';
|
|
565
|
+
setIcon('compact');
|
|
566
|
+
text(view.title, tx('Context compacted automatically', '上下文已自动压缩'));
|
|
567
|
+
text(view.time, clock(result.compactedAt));
|
|
568
|
+
text(view.sub, tx('Codex summarized earlier turns partway through this turn, then continued.',
|
|
569
|
+
'Codex 在这一轮中途整理了此前的对话,然后继续处理。'));
|
|
570
|
+
view.sub.hidden = false;
|
|
571
|
+
}
|
|
467
572
|
function mount(root, run) {
|
|
468
573
|
if (!Model || cards.has(root)) return;
|
|
469
574
|
const process = root.querySelector('[data-run-process]');
|
|
@@ -502,8 +607,9 @@
|
|
|
502
607
|
busy.setAttribute('role', 'status');
|
|
503
608
|
events.after(busy);
|
|
504
609
|
const card = { id: String(run.id), root, process, summary, events, metrics, attention,
|
|
610
|
+
guidance: root.querySelector('[data-run-guidance]'),
|
|
505
611
|
busy, rows: new Map(), run, setup: setupEl, setupSummary, setupFold, setupSteps,
|
|
506
|
-
peek, peekTrack, peekMore, peekRows: new Map() };
|
|
612
|
+
peek, peekTrack, peekMore, peekRows: new Map(), compaction: mountCompaction(root, run) };
|
|
507
613
|
const expand = () => { remember(card.id + ':run', true); process.open = true; update({ root, recordId: run.id }); };
|
|
508
614
|
peek.addEventListener('click', expand);
|
|
509
615
|
peekMore.addEventListener('click', expand);
|
|
@@ -514,9 +620,10 @@
|
|
|
514
620
|
events.dataset.expanded = String(process.open);
|
|
515
621
|
card.attention.hidden = process.open || !card.noticeCount;
|
|
516
622
|
if (card.projection) {
|
|
517
|
-
|
|
623
|
+
const active = card.run.status === 'running' && !card.notStarted;
|
|
624
|
+
renderSetup(card, card.projection.setup, active);
|
|
518
625
|
if (!process.open) card.setup.hidden = true;
|
|
519
|
-
renderPeek(card, card.projection, card.run,
|
|
626
|
+
renderPeek(card, card.projection, card.run, active);
|
|
520
627
|
}
|
|
521
628
|
});
|
|
522
629
|
render(card, run);
|
|
@@ -524,13 +631,34 @@
|
|
|
524
631
|
function render(card, run, incoming) {
|
|
525
632
|
card.run = run;
|
|
526
633
|
const result = Model.project(run, incoming, { isGuidance });
|
|
634
|
+
const notStarted = getNotStartedRun?.(run);
|
|
635
|
+
const outcome = getFinishedRun?.(run);
|
|
636
|
+
card.root.dataset.outcomeTone = outcome?.tone || '';
|
|
637
|
+
card.root.dataset.outcome = outcome?.kind || '';
|
|
638
|
+
card.notStarted = Boolean(notStarted);
|
|
639
|
+
if (notStarted) {
|
|
640
|
+
// The single launch card replaces preflight workflow/Notice projections.
|
|
641
|
+
// Stored events remain available to history, audit and recovery.
|
|
642
|
+
result.blocks = [];
|
|
643
|
+
result.notices = [];
|
|
644
|
+
result.setup = null;
|
|
645
|
+
}
|
|
646
|
+
// The outcome card owns the visible cause. Keep workflow evidence in the
|
|
647
|
+
// existing process disclosure, without another attention banner.
|
|
648
|
+
if (outcome) result.notices = [];
|
|
649
|
+
const guidanceEvents = (run.events || []).concat(incoming && !(run.events || []).includes(incoming) ? [incoming] : []);
|
|
650
|
+
RunGuidanceView?.reconcileGuidance(card.guidance,
|
|
651
|
+
guidanceEvents.concat(getPendingGuidance(run)),
|
|
652
|
+
tx, { active: run.status === 'running' });
|
|
653
|
+
result.blocks = result.blocks.filter(block => block.kind !== 'guidance');
|
|
527
654
|
card.projection = result;
|
|
528
655
|
subagentView?.update(card);
|
|
529
|
-
const active = run.status === 'running';
|
|
656
|
+
const active = run.status === 'running' && !notStarted;
|
|
530
657
|
const abnormal = ['failed', 'interrupted', 'needs_review_after_navigation', 'abandoned_after_navigation'].includes(run.status);
|
|
531
|
-
if (
|
|
658
|
+
if (notStarted) card.process.open = false;
|
|
659
|
+
else if (choices.has(card.id + ':run')) card.process.open = choices.get(card.id + ':run');
|
|
532
660
|
// A live run starts collapsed onto its peek window; problems open it.
|
|
533
|
-
else card.process.open = abnormal;
|
|
661
|
+
else card.process.open = abnormal && !outcome;
|
|
534
662
|
card.events.dataset.expanded = String(card.process.open);
|
|
535
663
|
card.summary.setAttribute('aria-expanded', String(card.process.open));
|
|
536
664
|
reconcile(card.events, result.blocks, card.rows, block => buildBlock(block, card),
|
|
@@ -541,6 +669,7 @@
|
|
|
541
669
|
else if (!choices.has(card.id + ':setup')) card.setup.open = false;
|
|
542
670
|
if (!card.process.open) card.setup.hidden = true;
|
|
543
671
|
renderPeek(card, result, run, active);
|
|
672
|
+
renderCompaction(card, run, result);
|
|
544
673
|
card.noticeCount = result.notices.length;
|
|
545
674
|
const latestNotice = result.notices.at(-1);
|
|
546
675
|
card.attention.hidden = card.process.open || !latestNotice;
|
|
@@ -555,12 +684,13 @@
|
|
|
555
684
|
|| block.meta?.state === 'running');
|
|
556
685
|
// The presence header already narrates the live state.
|
|
557
686
|
card.busy.hidden = !active || hasActive || Boolean(presence);
|
|
558
|
-
text(card.busy, result.stage === 'local_completed'
|
|
687
|
+
text(card.busy, result.compacting ? tx('Compacting context…', '正在压缩上下文…') : result.stage === 'local_completed'
|
|
559
688
|
? (run.mode === 'ask' ? tx('Preparing the answer…', '正在整理回答…') : tx('Preparing writeback and verification…', '正在准备写回与验证…'))
|
|
560
689
|
: result.stage === 'preparing' ? tx('Preparing project context…', '正在准备项目上下文…') : tx('Working…', '正在处理…'));
|
|
561
690
|
}
|
|
562
691
|
// Live header: long phases are named; otherwise a rarely-changing word. Tool steps stay in the round list.
|
|
563
692
|
function runningLabel(result, run) {
|
|
693
|
+
if (result.compacting) return { kind: 'stage', text: tx('Compacting context', '正在压缩上下文') };
|
|
564
694
|
if (result.stage === 'sync') return { kind: 'stage', text: tx('Syncing changes to Overleaf', '正在同步改动到 Overleaf') };
|
|
565
695
|
// Before the model's first response the header names the real start-up step, not a playful word.
|
|
566
696
|
if (result.setup && !result.setup.done) return { kind: 'stage', text: setupLiveLabel(result.setup) };
|
|
@@ -574,6 +704,11 @@
|
|
|
574
704
|
function paintPresence(card, run, result, active) {
|
|
575
705
|
const status = card.root.querySelector('[data-run-status]');
|
|
576
706
|
if (!presence || !status) return;
|
|
707
|
+
const notStarted = getNotStartedRun?.(run);
|
|
708
|
+
if (notStarted) {
|
|
709
|
+
presence.paintSettled(status, { kind: notStarted.cancelled ? 'not-started-cancelled' : 'not-started', text: notStarted.status });
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
577
712
|
// History cards arrive with plain status text; keep it for failure and fallback labels.
|
|
578
713
|
if (!status.dataset.presence && !status.dataset.presenceText) status.dataset.presenceText = status.textContent;
|
|
579
714
|
const started = Date.parse(run.startedAt || '');
|
|
@@ -587,6 +722,12 @@
|
|
|
587
722
|
elapsedMs: Number.isFinite(started) && Number.isFinite(finished) ? Math.max(0, finished - started) : null,
|
|
588
723
|
files: result.fileCount, filesClipped: result.clipped === true, added: 0, removed: 0, steps: 0, compiled: false,
|
|
589
724
|
projectId: getProjectId?.() || '', animate: card.animateNext === true };
|
|
725
|
+
const outcome = getFinishedRun?.(run);
|
|
726
|
+
if (outcome?.status) {
|
|
727
|
+
facts.kind = outcome.kind;
|
|
728
|
+
facts.text = outcome.status;
|
|
729
|
+
}
|
|
730
|
+
if (outcome?.kind === 'compile-errors') facts.compileChip = outcome.compileChip;
|
|
590
731
|
card.animateNext = false;
|
|
591
732
|
for (const block of result.blocks) {
|
|
592
733
|
if (['message', 'guidance', 'thought'].includes(block.kind)) continue;
|
|
@@ -597,6 +738,7 @@
|
|
|
597
738
|
}
|
|
598
739
|
if (block.kind === 'compile' && block.meta?.state === 'completed') facts.compiled = true;
|
|
599
740
|
}
|
|
741
|
+
if (facts.compileChip) facts.compiled = false;
|
|
600
742
|
presence.paintSettled(status, facts);
|
|
601
743
|
}
|
|
602
744
|
function update(view, incoming) {
|