@parhelia/core 0.3.12827 → 0.3.12832
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/dist/editor/agent-changes/agentChangeTargets.d.ts +58 -0
- package/dist/editor/agent-changes/agentChangeTargets.js +174 -0
- package/dist/editor/agent-changes/agentChangeTargets.js.map +1 -0
- package/dist/editor/agent-changes/agentChangeTextHighlight.d.ts +57 -0
- package/dist/editor/agent-changes/agentChangeTextHighlight.js +109 -0
- package/dist/editor/agent-changes/agentChangeTextHighlight.js.map +1 -0
- package/dist/editor/ai/activityRowNavigation.d.ts +28 -0
- package/dist/editor/ai/activityRowNavigation.js +53 -0
- package/dist/editor/ai/activityRowNavigation.js.map +1 -0
- package/dist/editor/ai/terminal/activeReasoningModel.d.ts +9 -0
- package/dist/editor/ai/terminal/activeReasoningModel.js +20 -0
- package/dist/editor/ai/terminal/activeReasoningModel.js.map +1 -0
- package/dist/editor/ai/terminal/agentDurations.d.ts +27 -0
- package/dist/editor/ai/terminal/agentDurations.js +89 -0
- package/dist/editor/ai/terminal/agentDurations.js.map +1 -0
- package/dist/editor/ai/terminal/agentTurnTiming.d.ts +35 -0
- package/dist/editor/ai/terminal/agentTurnTiming.js +128 -0
- package/dist/editor/ai/terminal/agentTurnTiming.js.map +1 -0
- package/dist/editor/ai/terminal/components/AgentMemorySettingsSection.d.ts +9 -0
- package/dist/editor/ai/terminal/components/AgentMemorySettingsSection.js +75 -0
- package/dist/editor/ai/terminal/components/AgentMemorySettingsSection.js.map +1 -0
- package/dist/editor/ai/terminal/components/AgentProfileRecovery.d.ts +10 -0
- package/dist/editor/ai/terminal/components/AgentProfileRecovery.js +12 -0
- package/dist/editor/ai/terminal/components/AgentProfileRecovery.js.map +1 -0
- package/dist/editor/ai/terminal/components/CreateItemToolCallContent.d.ts +3 -0
- package/dist/editor/ai/terminal/components/CreateItemToolCallContent.js +47 -0
- package/dist/editor/ai/terminal/components/CreateItemToolCallContent.js.map +1 -0
- package/dist/editor/ai/terminal/components/ResponseTurnDuration.d.ts +15 -0
- package/dist/editor/ai/terminal/components/ResponseTurnDuration.js +63 -0
- package/dist/editor/ai/terminal/components/ResponseTurnDuration.js.map +1 -0
- package/dist/editor/ai/terminal/components/toolCallResultJson.d.ts +1 -0
- package/dist/editor/ai/terminal/components/toolCallResultJson.js +46 -0
- package/dist/editor/ai/terminal/components/toolCallResultJson.js.map +1 -0
- package/dist/editor/ai/terminal/reasoningEffortLevels.d.ts +8 -0
- package/dist/editor/ai/terminal/reasoningEffortLevels.js +54 -0
- package/dist/editor/ai/terminal/reasoningEffortLevels.js.map +1 -0
- package/dist/editor/ai/terminal/requestUsage.d.ts +3 -0
- package/dist/editor/ai/terminal/requestUsage.js +22 -0
- package/dist/editor/ai/terminal/requestUsage.js.map +1 -0
- package/dist/editor/ai/terminal/useAgentProviderWait.d.ts +18 -0
- package/dist/editor/ai/terminal/useAgentProviderWait.js +23 -0
- package/dist/editor/ai/terminal/useAgentProviderWait.js.map +1 -0
- package/dist/editor/ai/terminal/useAgentReasoningEffortState.d.ts +5 -0
- package/dist/editor/ai/terminal/useAgentReasoningEffortState.js +10 -0
- package/dist/editor/ai/terminal/useAgentReasoningEffortState.js.map +1 -0
- package/dist/editor/bridge/bridgeKeys.d.ts +5 -0
- package/dist/editor/bridge/bridgeKeys.js +8 -0
- package/dist/editor/bridge/bridgeKeys.js.map +1 -0
- package/dist/editor/client/SessionsDialog.d.ts +2 -0
- package/dist/editor/client/SessionsDialog.js +27 -0
- package/dist/editor/client/SessionsDialog.js.map +1 -0
- package/dist/editor/client/agentLoadItemPolicy.d.ts +22 -0
- package/dist/editor/client/agentLoadItemPolicy.js +60 -0
- package/dist/editor/client/agentLoadItemPolicy.js.map +1 -0
- package/dist/editor/client/localUserEditActivity.d.ts +3 -0
- package/dist/editor/client/localUserEditActivity.js +12 -0
- package/dist/editor/client/localUserEditActivity.js.map +1 -0
- package/dist/editor/commands/mediaCommands.d.ts +5 -0
- package/dist/editor/commands/mediaCommands.js +59 -0
- package/dist/editor/commands/mediaCommands.js.map +1 -0
- package/dist/editor/componentVisualMode.d.ts +14 -0
- package/dist/editor/componentVisualMode.js +43 -0
- package/dist/editor/componentVisualMode.js.map +1 -0
- package/dist/editor/field-types/FieldHistoryBoundary.d.ts +7 -0
- package/dist/editor/field-types/FieldHistoryBoundary.js +19 -0
- package/dist/editor/field-types/FieldHistoryBoundary.js.map +1 -0
- package/dist/editor/field-types/richtext/utils/changeHighlight.d.ts +18 -0
- package/dist/editor/field-types/richtext/utils/changeHighlight.js +57 -0
- package/dist/editor/field-types/richtext/utils/changeHighlight.js.map +1 -0
- package/dist/editor/itemContextMenuGroups.d.ts +16 -0
- package/dist/editor/itemContextMenuGroups.js +48 -0
- package/dist/editor/itemContextMenuGroups.js.map +1 -0
- package/dist/editor/media-selector/UploadMediaFileDialog.d.ts +5 -0
- package/dist/editor/media-selector/UploadMediaFileDialog.js +14 -0
- package/dist/editor/media-selector/UploadMediaFileDialog.js.map +1 -0
- package/dist/editor/menubar/OpenPublishedPageButton.d.ts +1 -0
- package/dist/editor/menubar/OpenPublishedPageButton.js +22 -0
- package/dist/editor/menubar/OpenPublishedPageButton.js.map +1 -0
- package/dist/editor/page-editor-chrome/AgentChangeHighlightings.d.ts +20 -0
- package/dist/editor/page-editor-chrome/AgentChangeHighlightings.js +31 -0
- package/dist/editor/page-editor-chrome/AgentChangeHighlightings.js.map +1 -0
- package/dist/editor/page-editor-chrome/DiffHighlightOverlay.d.ts +33 -0
- package/dist/editor/page-editor-chrome/DiffHighlightOverlay.js +290 -0
- package/dist/editor/page-editor-chrome/DiffHighlightOverlay.js.map +1 -0
- package/dist/editor/page-editor-chrome/diffRulerSegments.d.ts +18 -0
- package/dist/editor/page-editor-chrome/diffRulerSegments.js +37 -0
- package/dist/editor/page-editor-chrome/diffRulerSegments.js.map +1 -0
- package/dist/editor/page-viewer/PreviewModeNotice.d.ts +7 -0
- package/dist/editor/page-viewer/PreviewModeNotice.js +19 -0
- package/dist/editor/page-viewer/PreviewModeNotice.js.map +1 -0
- package/dist/editor/page-viewer/previewEditAttempt.d.ts +31 -0
- package/dist/editor/page-viewer/previewEditAttempt.js +68 -0
- package/dist/editor/page-viewer/previewEditAttempt.js.map +1 -0
- package/dist/editor/services/migrationService.d.ts +31 -0
- package/dist/editor/services/migrationService.js +22 -0
- package/dist/editor/services/migrationService.js.map +1 -0
- package/dist/editor/services/publicSiteService.d.ts +40 -0
- package/dist/editor/services/publicSiteService.js +5 -0
- package/dist/editor/services/publicSiteService.js.map +1 -0
- package/dist/editor/settings/MigrationJournalCard.d.ts +12 -0
- package/dist/editor/settings/MigrationJournalCard.js +114 -0
- package/dist/editor/settings/MigrationJournalCard.js.map +1 -0
- package/dist/editor/settings/panels/PublicSiteEntryDialog.d.ts +8 -0
- package/dist/editor/settings/panels/PublicSiteEntryDialog.js +113 -0
- package/dist/editor/settings/panels/PublicSiteEntryDialog.js.map +1 -0
- package/dist/editor/settings/panels/PublicSitesPanel.d.ts +1 -0
- package/dist/editor/settings/panels/PublicSitesPanel.js +153 -0
- package/dist/editor/settings/panels/PublicSitesPanel.js.map +1 -0
- package/dist/editor/settings/panels/publicSiteHelpers.d.ts +6 -0
- package/dist/editor/settings/panels/publicSiteHelpers.js +30 -0
- package/dist/editor/settings/panels/publicSiteHelpers.js.map +1 -0
- package/dist/editor/sidebar/OperationDetailsContent.d.ts +14 -0
- package/dist/editor/sidebar/OperationDetailsContent.js +521 -0
- package/dist/editor/sidebar/OperationDetailsContent.js.map +1 -0
- package/dist/editor/sidebar/liveComponentThumbnails.d.ts +53 -0
- package/dist/editor/sidebar/liveComponentThumbnails.js +204 -0
- package/dist/editor/sidebar/liveComponentThumbnails.js.map +1 -0
- package/dist/editor/ui/PublishReadinessSummary.d.ts +12 -0
- package/dist/editor/ui/PublishReadinessSummary.js +34 -0
- package/dist/editor/ui/PublishReadinessSummary.js.map +1 -0
- package/dist/editor/ui/publishReadiness.d.ts +98 -0
- package/dist/editor/ui/publishReadiness.js +307 -0
- package/dist/editor/ui/publishReadiness.js.map +1 -0
- package/dist/editor/ui/usePublishingItem.d.ts +8 -0
- package/dist/editor/ui/usePublishingItem.js +47 -0
- package/dist/editor/ui/usePublishingItem.js.map +1 -0
- package/dist/editor/utils/linkDisplay.d.ts +12 -0
- package/dist/editor/utils/linkDisplay.js +23 -0
- package/dist/editor/utils/linkDisplay.js.map +1 -0
- package/dist/editor/validation/ValidationIssuesPopover.d.ts +39 -0
- package/dist/editor/validation/ValidationIssuesPopover.js +51 -0
- package/dist/editor/validation/ValidationIssuesPopover.js.map +1 -0
- package/dist/editor/validation/navigateToValidationIssue.d.ts +13 -0
- package/dist/editor/validation/navigateToValidationIssue.js +43 -0
- package/dist/editor/validation/navigateToValidationIssue.js.map +1 -0
- package/dist/editor/validation/validationFixAgent.d.ts +26 -0
- package/dist/editor/validation/validationFixAgent.js +124 -0
- package/dist/editor/validation/validationFixAgent.js.map +1 -0
- package/dist/editor/validation/validationSeverity.d.ts +15 -0
- package/dist/editor/validation/validationSeverity.js +47 -0
- package/dist/editor/validation/validationSeverity.js.map +1 -0
- package/dist/lib/viewportClip.d.ts +18 -0
- package/dist/lib/viewportClip.js +22 -0
- package/dist/lib/viewportClip.js.map +1 -0
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/components/ProjectProgressIndicator.d.ts +8 -0
- package/dist/task-board/components/ProjectProgressIndicator.js +17 -0
- package/dist/task-board/components/ProjectProgressIndicator.js.map +1 -0
- package/dist/task-board/components/commentAuthor.d.ts +14 -0
- package/dist/task-board/components/commentAuthor.js +25 -0
- package/dist/task-board/components/commentAuthor.js.map +1 -0
- package/dist/task-board/utils/projectDashboardModel.d.ts +68 -0
- package/dist/task-board/utils/projectDashboardModel.js +355 -0
- package/dist/task-board/utils/projectDashboardModel.js.map +1 -0
- package/dist/task-board/views/ProjectDashboardView.d.ts +28 -0
- package/dist/task-board/views/ProjectDashboardView.js +316 -0
- package/dist/task-board/views/ProjectDashboardView.js.map +1 -0
- package/dist/tour/TourInputBoundary.d.ts +6 -0
- package/dist/tour/TourInputBoundary.js +82 -0
- package/dist/tour/TourInputBoundary.js.map +1 -0
- package/dist/tour/sandbox-tour-copy.d.ts +48 -0
- package/dist/tour/sandbox-tour-copy.js +48 -0
- package/dist/tour/sandbox-tour-copy.js.map +1 -0
- package/dist/tour/sandbox-tour.d.ts +3 -0
- package/dist/tour/sandbox-tour.js +212 -0
- package/dist/tour/sandbox-tour.js.map +1 -0
- package/dist/tour/tour-utils.d.ts +32 -0
- package/dist/tour/tour-utils.js +148 -0
- package/dist/tour/tour-utils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SerializablePageStructure } from "../bridge/protocol";
|
|
2
|
+
import type { FieldDescriptor, ItemDescriptor } from "../pageModel";
|
|
3
|
+
import type { EditFieldOperation, EditOperation } from "../../types";
|
|
4
|
+
import { type ComponentDiffTarget, type DiffTarget } from "../version-diff/versionDiffTargets";
|
|
5
|
+
/**
|
|
6
|
+
* The agent whose edit operations are currently highlighted across the page
|
|
7
|
+
* iframe, the minimap and the edit form. Owned by the terminal's "Changes"
|
|
8
|
+
* tray checkbox; `null` when highlighting is off.
|
|
9
|
+
*/
|
|
10
|
+
export type AgentChangeHighlighting = {
|
|
11
|
+
agentId: string;
|
|
12
|
+
operations: EditOperation[];
|
|
13
|
+
};
|
|
14
|
+
export type AgentFieldChange = {
|
|
15
|
+
itemId: string;
|
|
16
|
+
language?: string;
|
|
17
|
+
/** Undefined or 0 means "any version" (the op did not pin one). */
|
|
18
|
+
version?: number;
|
|
19
|
+
fieldId: string;
|
|
20
|
+
fieldName?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The value before the agent's FIRST edit of this field, so repeated edits
|
|
23
|
+
* diff cumulatively. Undefined when no op captured an old value.
|
|
24
|
+
*/
|
|
25
|
+
baselineValue?: string;
|
|
26
|
+
/** The value written by the agent's LAST edit of this field. */
|
|
27
|
+
latestValue?: string;
|
|
28
|
+
operations: EditFieldOperation[];
|
|
29
|
+
};
|
|
30
|
+
export type AgentChangeTargetsResult = {
|
|
31
|
+
fieldTargets: DiffTarget[];
|
|
32
|
+
componentTargets: ComponentDiffTarget[];
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Collapses the agent's edit-field operations into one entry per field.
|
|
36
|
+
* Undone operations are ignored; a field whose every edit was undone drops out.
|
|
37
|
+
*/
|
|
38
|
+
export declare function collectAgentFieldChanges(operations: EditOperation[]): AgentFieldChange[];
|
|
39
|
+
export declare function agentFieldChangeMatches(change: AgentFieldChange, descriptor: FieldDescriptor): boolean;
|
|
40
|
+
export declare function findAgentFieldChange(highlighting: AgentChangeHighlighting | null | undefined, descriptor: FieldDescriptor | undefined): AgentFieldChange | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Components the agent added, duplicated, moved or linked. Removed components
|
|
43
|
+
* are no longer on the page and cannot be marked in the iframe.
|
|
44
|
+
*/
|
|
45
|
+
export declare function collectAgentComponentChanges(operations: EditOperation[]): ComponentDiffTarget[];
|
|
46
|
+
/**
|
|
47
|
+
* Turns the agent's operations into the same target shapes the version-diff
|
|
48
|
+
* overlay renders: added-text ranges per rendered field (diffing the value
|
|
49
|
+
* before the agent's first edit against the text now on the page) plus one
|
|
50
|
+
* component box per component the agent introduced. Fields without a
|
|
51
|
+
* captured baseline, or whose change is deletion-only, get the whole-field
|
|
52
|
+
* marker.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveAgentChangeTargets({ operations, bridgeStructure, pageItem, }: {
|
|
55
|
+
operations: EditOperation[];
|
|
56
|
+
bridgeStructure?: SerializablePageStructure;
|
|
57
|
+
pageItem: ItemDescriptor;
|
|
58
|
+
}): AgentChangeTargetsResult;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { collectRenderedFieldsFromBridge, computeWordDiffRanges, normalizeId, stripHtml, } from "../version-diff/versionDiffTargets";
|
|
2
|
+
function asString(value) {
|
|
3
|
+
if (value == null)
|
|
4
|
+
return undefined;
|
|
5
|
+
return typeof value === "string" ? value : String(value);
|
|
6
|
+
}
|
|
7
|
+
function sortChronologically(operations) {
|
|
8
|
+
return [...operations].sort((a, b) => {
|
|
9
|
+
const left = new Date(a.date).getTime() || 0;
|
|
10
|
+
const right = new Date(b.date).getTime() || 0;
|
|
11
|
+
return left - right;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function fieldChangeKey(itemId, language, fieldId) {
|
|
15
|
+
return `${normalizeId(itemId)}|${(language || "").toLowerCase()}|${normalizeId(fieldId)}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Collapses the agent's edit-field operations into one entry per field.
|
|
19
|
+
* Undone operations are ignored; a field whose every edit was undone drops out.
|
|
20
|
+
*/
|
|
21
|
+
export function collectAgentFieldChanges(operations) {
|
|
22
|
+
const changes = new Map();
|
|
23
|
+
for (const op of sortChronologically(operations)) {
|
|
24
|
+
if (op.type !== "edit-field" || op.undone)
|
|
25
|
+
continue;
|
|
26
|
+
const edit = op;
|
|
27
|
+
const itemId = edit.itemId || edit.mainItem?.id;
|
|
28
|
+
if (!itemId || !edit.fieldId)
|
|
29
|
+
continue;
|
|
30
|
+
const language = edit.mainItem?.language;
|
|
31
|
+
const isMainItem = !!edit.mainItem?.id &&
|
|
32
|
+
normalizeId(edit.mainItem.id) === normalizeId(itemId);
|
|
33
|
+
const version = isMainItem ? edit.mainItem?.version : undefined;
|
|
34
|
+
const key = fieldChangeKey(itemId, language, edit.fieldId);
|
|
35
|
+
const existing = changes.get(key);
|
|
36
|
+
if (existing) {
|
|
37
|
+
existing.latestValue = asString(edit.value) ?? existing.latestValue;
|
|
38
|
+
existing.fieldName = existing.fieldName || edit.fieldName;
|
|
39
|
+
existing.operations.push(edit);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
changes.set(key, {
|
|
43
|
+
itemId,
|
|
44
|
+
language,
|
|
45
|
+
version,
|
|
46
|
+
fieldId: edit.fieldId,
|
|
47
|
+
fieldName: edit.fieldName,
|
|
48
|
+
baselineValue: asString(edit.oldValue),
|
|
49
|
+
latestValue: asString(edit.value),
|
|
50
|
+
operations: [edit],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return Array.from(changes.values());
|
|
54
|
+
}
|
|
55
|
+
export function agentFieldChangeMatches(change, descriptor) {
|
|
56
|
+
if (normalizeId(change.fieldId) !== normalizeId(descriptor.fieldId))
|
|
57
|
+
return false;
|
|
58
|
+
if (normalizeId(change.itemId) !== normalizeId(descriptor.item.id))
|
|
59
|
+
return false;
|
|
60
|
+
if (change.language &&
|
|
61
|
+
descriptor.item.language &&
|
|
62
|
+
change.language.toLowerCase() !== descriptor.item.language.toLowerCase()) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (change.version &&
|
|
66
|
+
descriptor.item.version &&
|
|
67
|
+
change.version !== descriptor.item.version) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
export function findAgentFieldChange(highlighting, descriptor) {
|
|
73
|
+
if (!highlighting || !descriptor?.item?.id)
|
|
74
|
+
return undefined;
|
|
75
|
+
return collectAgentFieldChanges(highlighting.operations).find((change) => agentFieldChangeMatches(change, descriptor));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Components the agent added, duplicated, moved or linked. Removed components
|
|
79
|
+
* are no longer on the page and cannot be marked in the iframe.
|
|
80
|
+
*/
|
|
81
|
+
export function collectAgentComponentChanges(operations) {
|
|
82
|
+
const targets = new Map();
|
|
83
|
+
const add = (id, dataItemId) => {
|
|
84
|
+
const key = normalizeId(id || dataItemId);
|
|
85
|
+
if (!key || targets.has(key))
|
|
86
|
+
return;
|
|
87
|
+
targets.set(key, {
|
|
88
|
+
id: id || dataItemId,
|
|
89
|
+
visualId: id || dataItemId,
|
|
90
|
+
kind: "added",
|
|
91
|
+
dataItemId,
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
for (const op of operations) {
|
|
95
|
+
if (op.undone)
|
|
96
|
+
continue;
|
|
97
|
+
switch (op.type) {
|
|
98
|
+
case "add-component":
|
|
99
|
+
add(op.componentId);
|
|
100
|
+
break;
|
|
101
|
+
case "duplicate-components":
|
|
102
|
+
op.componentIds?.forEach((id) => add(id));
|
|
103
|
+
break;
|
|
104
|
+
case "move-component":
|
|
105
|
+
op.componentIds?.forEach((id) => add(id));
|
|
106
|
+
break;
|
|
107
|
+
case "link-component": {
|
|
108
|
+
const linked = op.linkedComponentItem;
|
|
109
|
+
add(undefined, linked?.id);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
default:
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return Array.from(targets.values());
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Turns the agent's operations into the same target shapes the version-diff
|
|
120
|
+
* overlay renders: added-text ranges per rendered field (diffing the value
|
|
121
|
+
* before the agent's first edit against the text now on the page) plus one
|
|
122
|
+
* component box per component the agent introduced. Fields without a
|
|
123
|
+
* captured baseline, or whose change is deletion-only, get the whole-field
|
|
124
|
+
* marker.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveAgentChangeTargets({ operations, bridgeStructure, pageItem, }) {
|
|
127
|
+
const fieldChanges = collectAgentFieldChanges(operations);
|
|
128
|
+
const componentTargets = collectAgentComponentChanges(operations);
|
|
129
|
+
if (!bridgeStructure || fieldChanges.length === 0) {
|
|
130
|
+
return { fieldTargets: [], componentTargets };
|
|
131
|
+
}
|
|
132
|
+
const renderedFields = collectRenderedFieldsFromBridge(bridgeStructure, pageItem);
|
|
133
|
+
const fieldTargets = renderedFields.flatMap((renderedField) => {
|
|
134
|
+
const change = fieldChanges.find((candidate) => agentFieldChangeMatches(candidate, renderedField.descriptor));
|
|
135
|
+
if (!change)
|
|
136
|
+
return [];
|
|
137
|
+
// The bridge structure's textContent is a load-time summary that does not
|
|
138
|
+
// follow field patches, so it can be empty or stale right after the agent
|
|
139
|
+
// wrote the field. The agent's last written value is what the host now
|
|
140
|
+
// renders (the bridge measures ranges against the live DOM text), so
|
|
141
|
+
// prefer it and fall back to the bridge text only when no value is known.
|
|
142
|
+
const currentText = change.latestValue !== undefined
|
|
143
|
+
? stripHtml(change.latestValue)
|
|
144
|
+
: renderedField.currentText;
|
|
145
|
+
if (change.baselineValue === undefined) {
|
|
146
|
+
return [
|
|
147
|
+
{
|
|
148
|
+
...renderedField,
|
|
149
|
+
currentText,
|
|
150
|
+
baselineText: "",
|
|
151
|
+
ranges: [],
|
|
152
|
+
rangeKind: "added",
|
|
153
|
+
hasDeletionOnlyChange: true,
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
|
+
const baselineText = stripHtml(change.baselineValue);
|
|
158
|
+
if (baselineText === currentText)
|
|
159
|
+
return [];
|
|
160
|
+
const ranges = computeWordDiffRanges(baselineText, currentText).added;
|
|
161
|
+
return [
|
|
162
|
+
{
|
|
163
|
+
...renderedField,
|
|
164
|
+
currentText,
|
|
165
|
+
baselineText,
|
|
166
|
+
ranges,
|
|
167
|
+
rangeKind: "added",
|
|
168
|
+
hasDeletionOnlyChange: ranges.length === 0,
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
});
|
|
172
|
+
return { fieldTargets, componentTargets };
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=agentChangeTargets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentChangeTargets.js","sourceRoot":"","sources":["../../../src/editor/agent-changes/agentChangeTargets.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,+BAA+B,EAC/B,qBAAqB,EACrB,WAAW,EACX,SAAS,GAGV,MAAM,oCAAoC,CAAC;AAkC5C,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,mBAAmB,CAAC,UAA2B;IACtD,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,IAAI,GAAG,KAAK,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CACrB,MAAc,EACd,QAA4B,EAC5B,OAAe;IAEf,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;AAC5F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAA2B;IAE3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAEpD,KAAK,MAAM,EAAE,IAAI,mBAAmB,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC,MAAM;YAAE,SAAS;QACpD,MAAM,IAAI,GAAG,EAAwB,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACzC,MAAM,UAAU,GACd,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE;YACnB,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAChE,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAE3D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC;YACpE,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;YAC1D,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACf,MAAM;YACN,QAAQ;YACR,OAAO;YACP,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;YACtC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,UAAU,EAAE,CAAC,IAAI,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAAwB,EACxB,UAA2B;IAE3B,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC;QACjE,OAAO,KAAK,CAAC;IACf,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,IACE,MAAM,CAAC,QAAQ;QACf,UAAU,CAAC,IAAI,CAAC,QAAQ;QACxB,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EACxE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,MAAM,CAAC,OAAO;QACd,UAAU,CAAC,IAAI,CAAC,OAAO;QACvB,MAAM,CAAC,OAAO,KAAK,UAAU,CAAC,IAAI,CAAC,OAAO,EAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,YAAwD,EACxD,UAAuC;IAEvC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE;QAAE,OAAO,SAAS,CAAC;IAC7D,OAAO,wBAAwB,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACvE,uBAAuB,CAAC,MAAM,EAAE,UAAU,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,UAA2B;IAE3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+B,CAAC;IACvD,MAAM,GAAG,GAAG,CAAC,EAAsB,EAAE,UAAmB,EAAE,EAAE;QAC1D,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QACrC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;YACf,EAAE,EAAE,EAAE,IAAI,UAAW;YACrB,QAAQ,EAAE,EAAE,IAAI,UAAW;YAC3B,IAAI,EAAE,OAAO;YACb,UAAU;SACX,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,EAAE,CAAC,MAAM;YAAE,SAAS;QACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YAChB,KAAK,eAAe;gBAClB,GAAG,CAAE,EAA4B,CAAC,WAAW,CAAC,CAAC;gBAC/C,MAAM;YACR,KAAK,sBAAsB;gBACxB,EAAmC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAChE,GAAG,CAAC,EAAE,CAAC,CACR,CAAC;gBACF,MAAM;YACR,KAAK,gBAAgB;gBAClB,EAA6B,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtE,MAAM;YACR,KAAK,gBAAgB,EAAE,CAAC;gBACtB,MAAM,MAAM,GAAI,EAA6B,CAAC,mBAAmB,CAAC;gBAClE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC3B,MAAM;YACR,CAAC;YACD;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CAAC,EACxC,UAAU,EACV,eAAe,EACf,QAAQ,GAKT;IACC,MAAM,YAAY,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,CAAC,eAAe,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,cAAc,GAAG,+BAA+B,CACpD,eAAe,EACf,QAAQ,CACT,CAAC;IACF,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,aAAa,EAAgB,EAAE;QAC1E,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAC7C,uBAAuB,CAAC,SAAS,EAAE,aAAa,CAAC,UAAU,CAAC,CAC7D,CAAC;QACF,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,0EAA0E;QAC1E,0EAA0E;QAC1E,uEAAuE;QACvE,qEAAqE;QACrE,0EAA0E;QAC1E,MAAM,WAAW,GACf,MAAM,CAAC,WAAW,KAAK,SAAS;YAC9B,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC;YAC/B,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC;QAChC,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO;gBACL;oBACE,GAAG,aAAa;oBAChB,WAAW;oBACX,YAAY,EAAE,EAAE;oBAChB,MAAM,EAAE,EAAE;oBACV,SAAS,EAAE,OAAO;oBAClB,qBAAqB,EAAE,IAAI;iBAC5B;aACF,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACrD,IAAI,YAAY,KAAK,WAAW;YAAE,OAAO,EAAE,CAAC;QAE5C,MAAM,MAAM,GAAG,qBAAqB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC;QACtE,OAAO;YACL;gBACE,GAAG,aAAa;gBAChB,WAAW;gBACX,YAAY;gBACZ,MAAM;gBACN,SAAS,EAAE,OAAO;gBAClB,qBAAqB,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;aAC3C;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import type { FieldDescriptor } from "../pageModel";
|
|
3
|
+
import { type DiffRange } from "../version-diff/versionDiffTargets";
|
|
4
|
+
import { type AgentFieldChange } from "./agentChangeTargets";
|
|
5
|
+
/**
|
|
6
|
+
* Form-side twin of the canvas agent-change highlight: instead of tinting the
|
|
7
|
+
* field row, the text the agent added is marked inside the editor itself,
|
|
8
|
+
* the same way the page overlay marks the added words. A change whose baseline
|
|
9
|
+
* is unknown, or that only removed text, has nothing to mark and gets a dashed
|
|
10
|
+
* whole-field outline instead (again mirroring the canvas).
|
|
11
|
+
*/
|
|
12
|
+
export type AgentTextHighlight = {
|
|
13
|
+
/** [start, end) offsets into the editor's current plain text. */
|
|
14
|
+
ranges: DiffRange[];
|
|
15
|
+
/** True when there is no added text to mark (baseline unknown / deletion-only). */
|
|
16
|
+
wholeField: boolean;
|
|
17
|
+
};
|
|
18
|
+
/** Tailwind classes shared by every added-text mark in the form. */
|
|
19
|
+
export declare const agentAddedTextClass = "bg-feedback-green/35 rounded-sm";
|
|
20
|
+
/** Dashed outline for a changed field that has no added text to mark. */
|
|
21
|
+
export declare const agentWholeFieldClass = "outline outline-1 outline-dashed outline-feedback-green outline-offset-0";
|
|
22
|
+
/**
|
|
23
|
+
* The agent change for `descriptor` while the terminal's "Highlight changes"
|
|
24
|
+
* checkbox is on for the agent that made it; undefined otherwise.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useAgentFieldChange(descriptor: FieldDescriptor | undefined): AgentFieldChange | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Diffs the editor's live text against the text before the agent's first
|
|
29
|
+
* edit. Diffing the live text (not the agent's written value) keeps the marks
|
|
30
|
+
* in step while the user keeps typing, and clears them once the text is back
|
|
31
|
+
* to the baseline.
|
|
32
|
+
*/
|
|
33
|
+
export declare function computeAgentTextHighlight(change: AgentFieldChange | undefined, currentText: string, baselineFormat?: "plain" | "html"): AgentTextHighlight | null;
|
|
34
|
+
export declare function computeTextHighlight(baselineText: string, currentText: string): AgentTextHighlight | null;
|
|
35
|
+
type TextSegment = {
|
|
36
|
+
text: string;
|
|
37
|
+
added: boolean;
|
|
38
|
+
};
|
|
39
|
+
/** Splits `text` into unchanged / added runs following `ranges` (sorted, disjoint). */
|
|
40
|
+
export declare function splitTextByRanges(text: string, ranges: DiffRange[]): TextSegment[];
|
|
41
|
+
/**
|
|
42
|
+
* Highlight layer for `<input>` / `<textarea>` editors, whose values are not
|
|
43
|
+
* DOM text and cannot be marked directly. It sits behind the (then
|
|
44
|
+
* transparent) control, mirrors its text metrics, and paints the added runs;
|
|
45
|
+
* scrolling and the textarea's scrollbar width are kept in sync so the marks
|
|
46
|
+
* stay under the glyphs they belong to.
|
|
47
|
+
*
|
|
48
|
+
* `className` must repeat the control's padding and font classes.
|
|
49
|
+
*/
|
|
50
|
+
export declare function AgentChangeTextBackdrop({ text, highlight, inputRef, className, multiline, }: {
|
|
51
|
+
text: string;
|
|
52
|
+
highlight: AgentTextHighlight;
|
|
53
|
+
inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
54
|
+
className?: string;
|
|
55
|
+
multiline?: boolean;
|
|
56
|
+
}): import("react").JSX.Element;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
import { useEditContext } from "../client/editContext";
|
|
5
|
+
import { computeWordDiffRanges, stripHtml, } from "../version-diff/versionDiffTargets";
|
|
6
|
+
import { agentFieldChangeMatches, collectAgentFieldChanges, } from "./agentChangeTargets";
|
|
7
|
+
/** Tailwind classes shared by every added-text mark in the form. */
|
|
8
|
+
export const agentAddedTextClass = "bg-feedback-green/35 rounded-sm";
|
|
9
|
+
/** Dashed outline for a changed field that has no added text to mark. */
|
|
10
|
+
export const agentWholeFieldClass = "outline outline-1 outline-dashed outline-feedback-green outline-offset-0";
|
|
11
|
+
/**
|
|
12
|
+
* The agent change for `descriptor` while the terminal's "Highlight changes"
|
|
13
|
+
* checkbox is on for the agent that made it; undefined otherwise.
|
|
14
|
+
*/
|
|
15
|
+
export function useAgentFieldChange(descriptor) {
|
|
16
|
+
const operations = useEditContext()?.agentChangeHighlighting?.operations;
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
if (!operations || !descriptor?.item?.id)
|
|
19
|
+
return undefined;
|
|
20
|
+
return collectAgentFieldChanges(operations).find((change) => agentFieldChangeMatches(change, descriptor));
|
|
21
|
+
}, [operations, descriptor]);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Diffs the editor's live text against the text before the agent's first
|
|
25
|
+
* edit. Diffing the live text (not the agent's written value) keeps the marks
|
|
26
|
+
* in step while the user keeps typing, and clears them once the text is back
|
|
27
|
+
* to the baseline.
|
|
28
|
+
*/
|
|
29
|
+
export function computeAgentTextHighlight(change, currentText, baselineFormat = "plain") {
|
|
30
|
+
if (!change)
|
|
31
|
+
return null;
|
|
32
|
+
if (change.baselineValue === undefined) {
|
|
33
|
+
return { ranges: [], wholeField: true };
|
|
34
|
+
}
|
|
35
|
+
const baselineText = baselineFormat === "html"
|
|
36
|
+
? stripHtml(change.baselineValue)
|
|
37
|
+
: change.baselineValue;
|
|
38
|
+
return computeTextHighlight(baselineText, currentText);
|
|
39
|
+
}
|
|
40
|
+
export function computeTextHighlight(baselineText, currentText) {
|
|
41
|
+
if (baselineText === currentText)
|
|
42
|
+
return null;
|
|
43
|
+
const ranges = computeWordDiffRanges(baselineText, currentText).added;
|
|
44
|
+
return { ranges, wholeField: ranges.length === 0 };
|
|
45
|
+
}
|
|
46
|
+
/** Splits `text` into unchanged / added runs following `ranges` (sorted, disjoint). */
|
|
47
|
+
export function splitTextByRanges(text, ranges) {
|
|
48
|
+
const segments = [];
|
|
49
|
+
let position = 0;
|
|
50
|
+
for (const range of [...ranges].sort((a, b) => a.start - b.start)) {
|
|
51
|
+
const start = Math.max(position, Math.min(range.start, text.length));
|
|
52
|
+
const end = Math.max(start, Math.min(range.end, text.length));
|
|
53
|
+
if (start > position) {
|
|
54
|
+
segments.push({ text: text.slice(position, start), added: false });
|
|
55
|
+
}
|
|
56
|
+
if (end > start) {
|
|
57
|
+
segments.push({ text: text.slice(start, end), added: true });
|
|
58
|
+
}
|
|
59
|
+
position = end;
|
|
60
|
+
}
|
|
61
|
+
if (position < text.length) {
|
|
62
|
+
segments.push({ text: text.slice(position), added: false });
|
|
63
|
+
}
|
|
64
|
+
return segments;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Highlight layer for `<input>` / `<textarea>` editors, whose values are not
|
|
68
|
+
* DOM text and cannot be marked directly. It sits behind the (then
|
|
69
|
+
* transparent) control, mirrors its text metrics, and paints the added runs;
|
|
70
|
+
* scrolling and the textarea's scrollbar width are kept in sync so the marks
|
|
71
|
+
* stay under the glyphs they belong to.
|
|
72
|
+
*
|
|
73
|
+
* `className` must repeat the control's padding and font classes.
|
|
74
|
+
*/
|
|
75
|
+
export function AgentChangeTextBackdrop({ text, highlight, inputRef, className, multiline = false, }) {
|
|
76
|
+
const mirrorRef = useRef(null);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
const input = inputRef.current;
|
|
79
|
+
const mirror = mirrorRef.current;
|
|
80
|
+
if (!input || !mirror)
|
|
81
|
+
return;
|
|
82
|
+
const sync = () => {
|
|
83
|
+
// A textarea scrollbar narrows its content box; shrink the mirror by the
|
|
84
|
+
// same amount so both wrap at the same column.
|
|
85
|
+
const scrollbarWidth = Math.max(0, input.offsetWidth - input.clientWidth - horizontalBorder(input));
|
|
86
|
+
mirror.style.right = `${scrollbarWidth}px`;
|
|
87
|
+
mirror.scrollTop = input.scrollTop;
|
|
88
|
+
mirror.scrollLeft = input.scrollLeft;
|
|
89
|
+
};
|
|
90
|
+
sync();
|
|
91
|
+
input.addEventListener("scroll", sync);
|
|
92
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(sync);
|
|
93
|
+
observer?.observe(input);
|
|
94
|
+
return () => {
|
|
95
|
+
input.removeEventListener("scroll", sync);
|
|
96
|
+
observer?.disconnect();
|
|
97
|
+
};
|
|
98
|
+
}, [inputRef, text]);
|
|
99
|
+
const segments = useMemo(() => splitTextByRanges(text, highlight.ranges), [text, highlight.ranges]);
|
|
100
|
+
return (_jsx("div", { ref: mirrorRef, "aria-hidden": true, "data-testid": "agent-change-text-backdrop", "data-whole-field": highlight.wholeField ? "true" : undefined, className: cn("bg-neutral-grey-5 pointer-events-none absolute inset-0 overflow-hidden rounded-[4px] border border-transparent text-transparent select-none", multiline
|
|
101
|
+
? "break-words whitespace-pre-wrap"
|
|
102
|
+
: "flex items-center whitespace-pre", highlight.wholeField && agentWholeFieldClass, className), children: _jsxs("span", { className: cn(!multiline && "min-w-0 shrink-0"), children: [segments.map((segment, index) => segment.added ? (_jsx("span", { className: agentAddedTextClass, "data-testid": "agent-change-text-mark", children: segment.text }, index)) : (_jsx("span", { children: segment.text }, index))), multiline && text.endsWith("\n") ? "" : null] }) }));
|
|
103
|
+
}
|
|
104
|
+
function horizontalBorder(element) {
|
|
105
|
+
const style = getComputedStyle(element);
|
|
106
|
+
return ((parseFloat(style.borderLeftWidth) || 0) +
|
|
107
|
+
(parseFloat(style.borderRightWidth) || 0));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=agentChangeTextHighlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentChangeTextHighlight.js","sourceRoot":"","sources":["../../../src/editor/agent-changes/agentChangeTextHighlight.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { EditOperation } from "../../types";
|
|
2
|
+
import type { FieldDescriptor, ItemDescriptor, Page } from "../pageModel";
|
|
3
|
+
export type ActivityRowNavigation =
|
|
4
|
+
/** The change is rendered on the open page: scroll to it, stay put. */
|
|
5
|
+
{
|
|
6
|
+
kind: "scroll";
|
|
7
|
+
componentId: string;
|
|
8
|
+
field?: FieldDescriptor;
|
|
9
|
+
}
|
|
10
|
+
/** Not on this page (or no page open): open the item in the editor. */
|
|
11
|
+
| {
|
|
12
|
+
kind: "load";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* What a click on a "Changes" row should do. Leaving the page to load an item
|
|
16
|
+
* the user is already looking at loses their place, so a change that maps to a
|
|
17
|
+
* component on the open page scrolls to it — to the edited field where the
|
|
18
|
+
* geometry is known, with the component as the fallback target.
|
|
19
|
+
*
|
|
20
|
+
* Rows are grouped by main item, so an edit to a component's embedded item is
|
|
21
|
+
* filed under the page. The row item alone would therefore resolve to the page
|
|
22
|
+
* root (a scroll to the top, which looks like nothing happened) — the real
|
|
23
|
+
* component comes from the operations themselves.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveActivityRowNavigation(summary: {
|
|
26
|
+
item?: ItemDescriptor;
|
|
27
|
+
operations?: EditOperation[];
|
|
28
|
+
}, page: Page | undefined): ActivityRowNavigation;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getComponentById } from "../componentTreeHelper";
|
|
2
|
+
import { collectAgentFieldChanges } from "../agent-changes/agentChangeTargets";
|
|
3
|
+
/**
|
|
4
|
+
* What a click on a "Changes" row should do. Leaving the page to load an item
|
|
5
|
+
* the user is already looking at loses their place, so a change that maps to a
|
|
6
|
+
* component on the open page scrolls to it — to the edited field where the
|
|
7
|
+
* geometry is known, with the component as the fallback target.
|
|
8
|
+
*
|
|
9
|
+
* Rows are grouped by main item, so an edit to a component's embedded item is
|
|
10
|
+
* filed under the page. The row item alone would therefore resolve to the page
|
|
11
|
+
* root (a scroll to the top, which looks like nothing happened) — the real
|
|
12
|
+
* component comes from the operations themselves.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveActivityRowNavigation(summary, page) {
|
|
15
|
+
if (!page)
|
|
16
|
+
return { kind: "load" };
|
|
17
|
+
const rootComponentId = page.rootComponent?.id;
|
|
18
|
+
let fallback;
|
|
19
|
+
for (const change of collectAgentFieldChanges(summary.operations ?? [])) {
|
|
20
|
+
const component = getComponentById(change.itemId, page);
|
|
21
|
+
if (!component)
|
|
22
|
+
continue;
|
|
23
|
+
const candidate = {
|
|
24
|
+
kind: "scroll",
|
|
25
|
+
componentId: component.id,
|
|
26
|
+
field: {
|
|
27
|
+
item: {
|
|
28
|
+
id: change.itemId,
|
|
29
|
+
language: change.language ?? summary.item?.language ?? "",
|
|
30
|
+
version: change.version ?? summary.item?.version ?? 0,
|
|
31
|
+
},
|
|
32
|
+
fieldId: change.fieldId,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
// A change on the page item itself resolves to the root component, i.e. a
|
|
36
|
+
// scroll to the top. Keep looking for a change inside a real component.
|
|
37
|
+
if (component.id === rootComponentId) {
|
|
38
|
+
fallback ??= candidate;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
return candidate;
|
|
42
|
+
}
|
|
43
|
+
if (fallback)
|
|
44
|
+
return fallback;
|
|
45
|
+
const rowComponent = summary.item?.id
|
|
46
|
+
? getComponentById(summary.item.id, page)
|
|
47
|
+
: undefined;
|
|
48
|
+
if (rowComponent) {
|
|
49
|
+
return { kind: "scroll", componentId: rowComponent.id };
|
|
50
|
+
}
|
|
51
|
+
return { kind: "load" };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=activityRowNavigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activityRowNavigation.js","sourceRoot":"","sources":["../../../src/editor/ai/activityRowNavigation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAQ/E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAGC,EACD,IAAsB;IAEtB,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAEnC,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;IAC/C,IAAI,QAA2C,CAAC;IAEhD,KAAK,MAAM,MAAM,IAAI,wBAAwB,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,MAAM,SAAS,GAA0B;YACvC,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,SAAS,CAAC,EAAE;YACzB,KAAK,EAAE;gBACL,IAAI,EAAE;oBACJ,EAAE,EAAE,MAAM,CAAC,MAAM;oBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE;oBACzD,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC;iBACtD;gBACD,OAAO,EAAE,MAAM,CAAC,OAAO;aACxB;SACF,CAAC;QAEF,0EAA0E;QAC1E,wEAAwE;QACxE,IAAI,SAAS,CAAC,EAAE,KAAK,eAAe,EAAE,CAAC;YACrC,QAAQ,KAAK,SAAS,CAAC;YACvB,SAAS;QACX,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE;QACnC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;QACzC,CAAC,CAAC,SAAS,CAAC;IACd,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AiModel } from "../../services/aiService";
|
|
2
|
+
import type { AgentDetails } from "../../services/agentService";
|
|
3
|
+
/**
|
|
4
|
+
* The model the current run is actually using, read from the agent snapshot
|
|
5
|
+
* the terminal already receives (GetAgent attaches `activeReasoningModel`
|
|
6
|
+
* while an execution is live). Undefined for drafts, idle agents and runs
|
|
7
|
+
* whose model matches the row.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getActiveReasoningModel(agent: AgentDetails | undefined): AiModel | undefined;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Statuses under which the backend attaches the run's captured model to the
|
|
2
|
+
// agent snapshot. Anything else means no run holds a model right now.
|
|
3
|
+
const LIVE_RUN_STATUSES = new Set([
|
|
4
|
+
"running",
|
|
5
|
+
"queued",
|
|
6
|
+
"waitingforapproval",
|
|
7
|
+
]);
|
|
8
|
+
/**
|
|
9
|
+
* The model the current run is actually using, read from the agent snapshot
|
|
10
|
+
* the terminal already receives (GetAgent attaches `activeReasoningModel`
|
|
11
|
+
* while an execution is live). Undefined for drafts, idle agents and runs
|
|
12
|
+
* whose model matches the row.
|
|
13
|
+
*/
|
|
14
|
+
export function getActiveReasoningModel(agent) {
|
|
15
|
+
if (!agent?.userId)
|
|
16
|
+
return undefined;
|
|
17
|
+
const live = LIVE_RUN_STATUSES.has(String(agent.status ?? "").toLowerCase());
|
|
18
|
+
return live ? agent.activeReasoningModel : undefined;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=activeReasoningModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activeReasoningModel.js","sourceRoot":"","sources":["../../../../src/editor/ai/terminal/activeReasoningModel.ts"],"names":[],"mappings":"AAGA,4EAA4E;AAC5E,sEAAsE;AACtE,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS;IACxC,SAAS;IACT,QAAQ;IACR,oBAAoB;CACrB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAA+B;IAE/B,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duration and timestamp helpers shared by the agent terminal's tool-call
|
|
3
|
+
* rows, activity headers and the per-turn response timer.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Formats a measured duration: `850ms`, `1.2s`, `42s`, `3m 5s`, `1h 2m`.
|
|
7
|
+
* Returns null for missing or unusable values.
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatDurationMs(durationMs: number | null | undefined): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Coarser variant for a ticking clock: whole seconds, so the label advances
|
|
12
|
+
* steadily instead of jittering through sub-second values.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatElapsedMs(elapsedMs: number | null | undefined): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Sum of the measured execution times in a batch of tool calls. Calls without
|
|
17
|
+
* a measurement are skipped; null when nothing was measured.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sumToolCallDurationsMs(toolCalls: ReadonlyArray<{
|
|
20
|
+
responseTimeMs?: number | null;
|
|
21
|
+
}>): number | null;
|
|
22
|
+
/**
|
|
23
|
+
* Parses an agent timestamp to epoch milliseconds. Persisted dates are UTC, so
|
|
24
|
+
* a value without a zone designator is read as UTC rather than local time to
|
|
25
|
+
* keep server and client timestamps comparable.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseTimestampMs(value: string | number | Date | null | undefined): number | null;
|