rivet-design 0.10.0 → 0.10.2
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/config/flags.d.ts +3 -0
- package/dist/config/flags.d.ts.map +1 -1
- package/dist/config/flags.js +3 -0
- package/dist/config/flags.js.map +1 -1
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +249 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/agent-variants/SessionStore.d.ts +43 -0
- package/dist/mcp/agent-variants/SessionStore.d.ts.map +1 -1
- package/dist/mcp/agent-variants/SessionStore.js +174 -9
- package/dist/mcp/agent-variants/SessionStore.js.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts +21 -0
- package/dist/mcp/agent-variants/WorktreeOrchestrator.d.ts.map +1 -1
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js +225 -11
- package/dist/mcp/agent-variants/WorktreeOrchestrator.js.map +1 -1
- package/dist/mcp/agent-variants/contracts.d.ts +13 -4
- package/dist/mcp/agent-variants/contracts.d.ts.map +1 -1
- package/dist/mcp/agent-variants/contracts.js +4 -1
- package/dist/mcp/agent-variants/contracts.js.map +1 -1
- package/dist/mcp/agent-variants/errors.d.ts +1 -1
- package/dist/mcp/agent-variants/errors.d.ts.map +1 -1
- package/dist/mcp/agent-variants/errors.js +1 -0
- package/dist/mcp/agent-variants/errors.js.map +1 -1
- package/dist/mcp/agent-variants/tools.d.ts.map +1 -1
- package/dist/mcp/agent-variants/tools.js +17 -0
- package/dist/mcp/agent-variants/tools.js.map +1 -1
- package/dist/mcp/changeBatchClassification.d.ts +2 -0
- package/dist/mcp/changeBatchClassification.d.ts.map +1 -1
- package/dist/mcp/changeBatchClassification.js +7 -0
- package/dist/mcp/changeBatchClassification.js.map +1 -1
- package/dist/mcp/server.d.ts +25 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +156 -102
- package/dist/mcp/server.js.map +1 -1
- package/dist/proxy-middleware/preview-bridge.d.ts +24 -0
- package/dist/proxy-middleware/preview-bridge.d.ts.map +1 -0
- package/dist/proxy-middleware/preview-bridge.js +358 -0
- package/dist/proxy-middleware/preview-bridge.js.map +1 -0
- package/dist/proxy-middleware/proxy-config.d.ts +5 -1
- package/dist/proxy-middleware/proxy-config.d.ts.map +1 -1
- package/dist/proxy-middleware/proxy-config.js +62 -18
- package/dist/proxy-middleware/proxy-config.js.map +1 -1
- package/dist/routes/controls.d.ts +7 -0
- package/dist/routes/controls.d.ts.map +1 -0
- package/dist/routes/controls.js +50 -0
- package/dist/routes/controls.js.map +1 -0
- package/dist/routes/mcp.d.ts +3 -1
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +172 -28
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/static.d.ts +6 -1
- package/dist/routes/static.d.ts.map +1 -1
- package/dist/routes/static.js +15 -3
- package/dist/routes/static.js.map +1 -1
- package/dist/server.d.ts +48 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +230 -33
- package/dist/server.js.map +1 -1
- package/dist/services/AgentSessionService.d.ts +87 -0
- package/dist/services/AgentSessionService.d.ts.map +1 -0
- package/dist/services/AgentSessionService.js +275 -0
- package/dist/services/AgentSessionService.js.map +1 -0
- package/dist/services/ConfigManager.d.ts +7 -0
- package/dist/services/ConfigManager.d.ts.map +1 -1
- package/dist/services/ConfigManager.js +13 -0
- package/dist/services/ConfigManager.js.map +1 -1
- package/dist/services/FeatureFlagService.d.ts.map +1 -1
- package/dist/services/FeatureFlagService.js +13 -0
- package/dist/services/FeatureFlagService.js.map +1 -1
- package/dist/services/HostedDemoAuthSessionService.d.ts +6 -0
- package/dist/services/HostedDemoAuthSessionService.d.ts.map +1 -1
- package/dist/services/HostedDemoAuthSessionService.js +13 -0
- package/dist/services/HostedDemoAuthSessionService.js.map +1 -1
- package/dist/services/InlineVariantGenerationService.d.ts +50 -0
- package/dist/services/InlineVariantGenerationService.d.ts.map +1 -0
- package/dist/services/InlineVariantGenerationService.js +394 -0
- package/dist/services/InlineVariantGenerationService.js.map +1 -0
- package/dist/services/InterfaceGenerationService.d.ts +12 -0
- package/dist/services/InterfaceGenerationService.d.ts.map +1 -0
- package/dist/services/InterfaceGenerationService.js +256 -0
- package/dist/services/InterfaceGenerationService.js.map +1 -0
- package/dist/services/SessionBridgeService.d.ts +11 -3
- package/dist/services/SessionBridgeService.d.ts.map +1 -1
- package/dist/services/SessionBridgeService.js +35 -3
- package/dist/services/SessionBridgeService.js.map +1 -1
- package/dist/services/TerminalAgentRunner.d.ts +65 -0
- package/dist/services/TerminalAgentRunner.d.ts.map +1 -0
- package/dist/services/TerminalAgentRunner.js +511 -0
- package/dist/services/TerminalAgentRunner.js.map +1 -0
- package/dist/services/WorktreeManager.d.ts +5 -4
- package/dist/services/WorktreeManager.d.ts.map +1 -1
- package/dist/services/WorktreeManager.js +22 -12
- package/dist/services/WorktreeManager.js.map +1 -1
- package/dist/services/accessTokenRefresh.d.ts +8 -0
- package/dist/services/accessTokenRefresh.d.ts.map +1 -1
- package/dist/services/accessTokenRefresh.js +30 -1
- package/dist/services/accessTokenRefresh.js.map +1 -1
- package/dist/services/createAgentVariantsOrchestrator.d.ts +16 -0
- package/dist/services/createAgentVariantsOrchestrator.d.ts.map +1 -0
- package/dist/services/createAgentVariantsOrchestrator.js +42 -0
- package/dist/services/createAgentVariantsOrchestrator.js.map +1 -0
- package/dist/types/change-request-types.d.ts +29 -0
- package/dist/types/change-request-types.d.ts.map +1 -1
- package/dist/types/editor-interface-types.d.ts +67 -0
- package/dist/types/editor-interface-types.d.ts.map +1 -0
- package/dist/types/editor-interface-types.js +12 -0
- package/dist/types/editor-interface-types.js.map +1 -0
- package/dist/utils/elementFileHintSignals.d.ts +8 -0
- package/dist/utils/elementFileHintSignals.d.ts.map +1 -0
- package/dist/utils/elementFileHintSignals.js +40 -0
- package/dist/utils/elementFileHintSignals.js.map +1 -0
- package/dist/utils/formatElementTargetingContext.d.ts +34 -0
- package/dist/utils/formatElementTargetingContext.d.ts.map +1 -0
- package/dist/utils/formatElementTargetingContext.js +88 -0
- package/dist/utils/formatElementTargetingContext.js.map +1 -0
- package/dist/utils/queueAccess.d.ts +11 -0
- package/dist/utils/queueAccess.d.ts.map +1 -0
- package/dist/utils/queueAccess.js +15 -0
- package/dist/utils/queueAccess.js.map +1 -0
- package/package.json +1 -1
- package/src/ui/dist/assets/main-C8QYh4jE.css +1 -0
- package/src/ui/dist/assets/main-CMk2ORlB.js +645 -0
- package/src/ui/dist/index.html +2 -2
- package/src/ui/dist/assets/main-BZEruoyc.css +0 -1
- package/src/ui/dist/assets/main-CIJUZXe8.js +0 -382
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isHtmlDocumentRequest = exports.injectPreviewBridge = exports.shouldInjectPreviewBridge = exports.allowPreviewBridgeNonceInCsp = exports.createPreviewBridgeScript = exports.PREVIEW_BRIDGE_CHANNEL = exports.PREVIEW_BRIDGE_SCRIPT_ID = void 0;
|
|
4
|
+
exports.PREVIEW_BRIDGE_SCRIPT_ID = 'rivet-preview-bridge';
|
|
5
|
+
exports.PREVIEW_BRIDGE_CHANNEL = 'rivet-preview-bridge';
|
|
6
|
+
const MAX_SIBLING_CONTEXT_COUNT = 6;
|
|
7
|
+
const TEXT_SNIPPET_MAX_LENGTH = 80;
|
|
8
|
+
const buildBridgeScript = ({ expectedParentOrigin, } = {}) => `
|
|
9
|
+
(() => {
|
|
10
|
+
const CHANNEL = '${exports.PREVIEW_BRIDGE_CHANNEL}';
|
|
11
|
+
const EXPECTED_PARENT_ORIGIN = ${JSON.stringify(expectedParentOrigin ?? null)} || window.location.origin;
|
|
12
|
+
const RIVET_ID_ATTR = 'data-rivet-id';
|
|
13
|
+
const MAX_SIBLING_CONTEXT_COUNT = ${MAX_SIBLING_CONTEXT_COUNT};
|
|
14
|
+
const TEXT_SNIPPET_MAX_LENGTH = ${TEXT_SNIPPET_MAX_LENGTH};
|
|
15
|
+
if (window.__RIVET_PREVIEW_BRIDGE_ACTIVE__) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
window.__RIVET_PREVIEW_BRIDGE_ACTIVE__ = true;
|
|
19
|
+
|
|
20
|
+
const getClassName = (element) => {
|
|
21
|
+
try {
|
|
22
|
+
const value = element.className;
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
if (value && typeof value === 'object' && 'baseVal' in value) {
|
|
27
|
+
return value.baseVal || '';
|
|
28
|
+
}
|
|
29
|
+
} catch {}
|
|
30
|
+
return '';
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getTextSnippet = (element) => {
|
|
34
|
+
const text = (element.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
35
|
+
return text.slice(0, TEXT_SNIPPET_MAX_LENGTH);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const getXPath = (element) => {
|
|
39
|
+
if (element.id) {
|
|
40
|
+
return '//*[@id="' + element.id + '"]';
|
|
41
|
+
}
|
|
42
|
+
if (element === document.body) {
|
|
43
|
+
return '/html/body';
|
|
44
|
+
}
|
|
45
|
+
let index = 0;
|
|
46
|
+
const siblings = element.parentNode ? element.parentNode.childNodes : [];
|
|
47
|
+
for (let i = 0; i < siblings.length; i += 1) {
|
|
48
|
+
const sibling = siblings[i];
|
|
49
|
+
if (sibling === element) {
|
|
50
|
+
const parent = element.parentNode;
|
|
51
|
+
return parent
|
|
52
|
+
? getXPath(parent) + '/' + element.tagName.toLowerCase() + '[' + (index + 1) + ']'
|
|
53
|
+
: '';
|
|
54
|
+
}
|
|
55
|
+
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
|
|
56
|
+
index += 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const getElementByXPath = (xpath) => {
|
|
63
|
+
try {
|
|
64
|
+
const result = document.evaluate(
|
|
65
|
+
xpath,
|
|
66
|
+
document,
|
|
67
|
+
null,
|
|
68
|
+
XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
69
|
+
null,
|
|
70
|
+
);
|
|
71
|
+
return result.singleNodeValue || null;
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const ensureRivetId = (element) => {
|
|
78
|
+
const existing = element.getAttribute(RIVET_ID_ATTR);
|
|
79
|
+
if (existing && existing.trim()) {
|
|
80
|
+
return existing.trim();
|
|
81
|
+
}
|
|
82
|
+
const id =
|
|
83
|
+
globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function'
|
|
84
|
+
? globalThis.crypto.randomUUID()
|
|
85
|
+
: 'rivet-' + Math.random().toString(36).slice(2, 11);
|
|
86
|
+
element.setAttribute(RIVET_ID_ATTR, id);
|
|
87
|
+
return id;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const transformStyles = (styles) => {
|
|
91
|
+
const result = {};
|
|
92
|
+
for (let i = 0; i < styles.length; i += 1) {
|
|
93
|
+
const prop = styles[i];
|
|
94
|
+
result[prop] = styles.getPropertyValue(prop);
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const getSiblingElements = (element) => {
|
|
100
|
+
const parent = element.parentElement;
|
|
101
|
+
if (!parent) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
const siblings = Array.from(parent.children);
|
|
105
|
+
const currentIndex = siblings.indexOf(element);
|
|
106
|
+
if (currentIndex === -1) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
const result = siblings
|
|
110
|
+
.map((sibling, index) => ({ sibling, index }))
|
|
111
|
+
.filter(({ sibling }) => sibling !== element)
|
|
112
|
+
.sort((a, b) => Math.abs(a.index - currentIndex) - Math.abs(b.index - currentIndex))
|
|
113
|
+
.slice(0, MAX_SIBLING_CONTEXT_COUNT)
|
|
114
|
+
.map(({ sibling, index }) => ({
|
|
115
|
+
tagName: sibling.tagName.toLowerCase(),
|
|
116
|
+
className: getClassName(sibling),
|
|
117
|
+
id: sibling.id || '',
|
|
118
|
+
textSnippet: getTextSnippet(sibling),
|
|
119
|
+
relativePosition: index < currentIndex ? 'previous' : 'next',
|
|
120
|
+
}));
|
|
121
|
+
return result.length > 0 ? result : undefined;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const getParentSummary = (element) => {
|
|
125
|
+
const parent = element.parentElement;
|
|
126
|
+
if (!parent) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
tagName: parent.tagName.toLowerCase(),
|
|
131
|
+
className: getClassName(parent),
|
|
132
|
+
id: parent.id || '',
|
|
133
|
+
textSnippet: getTextSnippet(parent),
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const extractElement = (element) => {
|
|
138
|
+
if (!element) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const rect = element.getBoundingClientRect();
|
|
142
|
+
const computedStyles = window.getComputedStyle(element);
|
|
143
|
+
const attributes = {};
|
|
144
|
+
for (const attr of Array.from(element.attributes || [])) {
|
|
145
|
+
attributes[attr.name] = attr.value;
|
|
146
|
+
}
|
|
147
|
+
const rivetId = ensureRivetId(element);
|
|
148
|
+
return {
|
|
149
|
+
tagName: element.tagName.toLowerCase(),
|
|
150
|
+
className: getClassName(element),
|
|
151
|
+
id: element.id || '',
|
|
152
|
+
textContent: (element.textContent || '').trim().slice(0, 100),
|
|
153
|
+
innerHTML: (element.innerHTML || '').slice(0, 200),
|
|
154
|
+
attributes,
|
|
155
|
+
computedStyles: transformStyles(computedStyles),
|
|
156
|
+
boundingRect: {
|
|
157
|
+
x: rect.x,
|
|
158
|
+
y: rect.y,
|
|
159
|
+
width: rect.width,
|
|
160
|
+
height: rect.height,
|
|
161
|
+
top: rect.top,
|
|
162
|
+
left: rect.left,
|
|
163
|
+
right: rect.right,
|
|
164
|
+
bottom: rect.bottom,
|
|
165
|
+
},
|
|
166
|
+
xpath: getXPath(element),
|
|
167
|
+
rivetId,
|
|
168
|
+
siblingElements: getSiblingElements(element),
|
|
169
|
+
parentElementSummary: getParentSummary(element),
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const elementFromIdentifier = (identifier) => {
|
|
174
|
+
if (!identifier || typeof identifier !== 'object') {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
const rivetId = typeof identifier.rivetId === 'string' ? identifier.rivetId.trim() : '';
|
|
178
|
+
if (rivetId) {
|
|
179
|
+
try {
|
|
180
|
+
const element = document.querySelector('[' + RIVET_ID_ATTR + '="' + CSS.escape(rivetId) + '"]');
|
|
181
|
+
if (element) {
|
|
182
|
+
return element;
|
|
183
|
+
}
|
|
184
|
+
} catch {}
|
|
185
|
+
}
|
|
186
|
+
const xpath = typeof identifier.xpath === 'string' ? identifier.xpath : '';
|
|
187
|
+
return xpath ? getElementByXPath(xpath) : null;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const elementsInBox = (box) => {
|
|
191
|
+
const candidates = new Set();
|
|
192
|
+
const step = 32;
|
|
193
|
+
const xCount = Math.max(2, Math.min(24, Math.ceil((box.right - box.left) / step) + 1));
|
|
194
|
+
const yCount = Math.max(2, Math.min(24, Math.ceil((box.bottom - box.top) / step) + 1));
|
|
195
|
+
for (let xi = 0; xi < xCount; xi += 1) {
|
|
196
|
+
const x = box.left + ((box.right - box.left) * xi) / (xCount - 1);
|
|
197
|
+
for (let yi = 0; yi < yCount; yi += 1) {
|
|
198
|
+
const y = box.top + ((box.bottom - box.top) * yi) / (yCount - 1);
|
|
199
|
+
const elements =
|
|
200
|
+
typeof document.elementsFromPoint === 'function'
|
|
201
|
+
? document.elementsFromPoint(x, y)
|
|
202
|
+
: [document.elementFromPoint(x, y)].filter(Boolean);
|
|
203
|
+
for (const element of elements) {
|
|
204
|
+
let current = element;
|
|
205
|
+
while (current) {
|
|
206
|
+
candidates.add(current);
|
|
207
|
+
current = current.parentElement;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return Array.from(candidates)
|
|
213
|
+
.filter((element) => {
|
|
214
|
+
const rect = element.getBoundingClientRect();
|
|
215
|
+
return (
|
|
216
|
+
rect.left < box.right &&
|
|
217
|
+
rect.right > box.left &&
|
|
218
|
+
rect.top < box.bottom &&
|
|
219
|
+
rect.bottom > box.top &&
|
|
220
|
+
rect.width > 0 &&
|
|
221
|
+
rect.height > 0
|
|
222
|
+
);
|
|
223
|
+
})
|
|
224
|
+
.map(extractElement)
|
|
225
|
+
.filter(Boolean);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const send = (source, id, responseNonce, payload) => {
|
|
229
|
+
source.postMessage(
|
|
230
|
+
{
|
|
231
|
+
channel: CHANNEL,
|
|
232
|
+
direction: 'response',
|
|
233
|
+
id,
|
|
234
|
+
responseNonce,
|
|
235
|
+
...payload,
|
|
236
|
+
},
|
|
237
|
+
EXPECTED_PARENT_ORIGIN,
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
window.addEventListener('message', (event) => {
|
|
242
|
+
const message = event.data;
|
|
243
|
+
if (!message || message.channel !== CHANNEL || message.direction !== 'request') {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (event.origin !== EXPECTED_PARENT_ORIGIN) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
event.stopImmediatePropagation();
|
|
250
|
+
const source = event.source;
|
|
251
|
+
if (!source || typeof source.postMessage !== 'function') {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
let result = null;
|
|
256
|
+
if (message.action === 'elementAtPoint') {
|
|
257
|
+
result = extractElement(document.elementFromPoint(message.payload.x, message.payload.y));
|
|
258
|
+
} else if (message.action === 'elementsInBox') {
|
|
259
|
+
result = elementsInBox(message.payload);
|
|
260
|
+
} else if (message.action === 'resolveElement') {
|
|
261
|
+
result = extractElement(elementFromIdentifier(message.payload));
|
|
262
|
+
} else if (message.action === 'setCursor') {
|
|
263
|
+
const cursor = typeof message.payload.cursor === 'string' ? message.payload.cursor : '';
|
|
264
|
+
document.documentElement.style.cursor = cursor;
|
|
265
|
+
document.body.style.cursor = cursor;
|
|
266
|
+
result = true;
|
|
267
|
+
} else if (message.action === 'scrollBy') {
|
|
268
|
+
window.scrollBy(message.payload.deltaX || 0, message.payload.deltaY || 0);
|
|
269
|
+
result = true;
|
|
270
|
+
} else {
|
|
271
|
+
throw new Error('Unknown action');
|
|
272
|
+
}
|
|
273
|
+
send(source, message.id, message.responseNonce, { ok: true, result });
|
|
274
|
+
} catch (error) {
|
|
275
|
+
send(source, message.id, message.responseNonce, {
|
|
276
|
+
ok: false,
|
|
277
|
+
error: error instanceof Error ? error.message : String(error),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
})();
|
|
282
|
+
`.trim();
|
|
283
|
+
const createPreviewBridgeScript = (options = {}) => {
|
|
284
|
+
const nonceAttribute = options.scriptNonce
|
|
285
|
+
? ` nonce="${options.scriptNonce}"`
|
|
286
|
+
: '';
|
|
287
|
+
return `<script id="${exports.PREVIEW_BRIDGE_SCRIPT_ID}"${nonceAttribute}>${buildBridgeScript(options)}</script>`;
|
|
288
|
+
};
|
|
289
|
+
exports.createPreviewBridgeScript = createPreviewBridgeScript;
|
|
290
|
+
const SCRIPT_DIRECTIVES = new Set(['script-src', 'script-src-elem']);
|
|
291
|
+
const splitCspDirective = (directive) => directive
|
|
292
|
+
.trim()
|
|
293
|
+
.split(/\s+/)
|
|
294
|
+
.filter((part) => part.length > 0);
|
|
295
|
+
const allowPreviewBridgeNonceInCsp = (csp, { scriptNonce }) => {
|
|
296
|
+
const nonceSource = `'nonce-${scriptNonce}'`;
|
|
297
|
+
const directives = csp
|
|
298
|
+
.split(';')
|
|
299
|
+
.map((directive) => directive.trim())
|
|
300
|
+
.filter((directive) => directive.length > 0);
|
|
301
|
+
let hasScriptDirective = false;
|
|
302
|
+
const nextDirectives = directives.map((directive) => {
|
|
303
|
+
const parts = splitCspDirective(directive);
|
|
304
|
+
const name = parts[0]?.toLowerCase();
|
|
305
|
+
if (!SCRIPT_DIRECTIVES.has(name)) {
|
|
306
|
+
return directive;
|
|
307
|
+
}
|
|
308
|
+
hasScriptDirective = true;
|
|
309
|
+
return parts.includes(nonceSource)
|
|
310
|
+
? directive
|
|
311
|
+
: [...parts, nonceSource].join(' ');
|
|
312
|
+
});
|
|
313
|
+
if (!hasScriptDirective) {
|
|
314
|
+
const defaultDirective = directives.find((directive) => splitCspDirective(directive)[0]?.toLowerCase() === 'default-src');
|
|
315
|
+
const defaultSources = defaultDirective
|
|
316
|
+
? splitCspDirective(defaultDirective).slice(1)
|
|
317
|
+
: [];
|
|
318
|
+
nextDirectives.push(['script-src', ...defaultSources, nonceSource].join(' '));
|
|
319
|
+
}
|
|
320
|
+
return nextDirectives.join('; ');
|
|
321
|
+
};
|
|
322
|
+
exports.allowPreviewBridgeNonceInCsp = allowPreviewBridgeNonceInCsp;
|
|
323
|
+
const firstHeaderValue = (value) => Array.isArray(value) ? (value[0] ?? '') : (value ?? '');
|
|
324
|
+
/** Decides whether a proxied response should receive the isolated-preview bridge. */
|
|
325
|
+
const shouldInjectPreviewBridge = ({ method, accept, contentType, }) => {
|
|
326
|
+
if (method != null && method !== 'GET') {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
const normalizedAccept = firstHeaderValue(accept).toLowerCase();
|
|
330
|
+
const normalizedContentType = firstHeaderValue(contentType).toLowerCase();
|
|
331
|
+
return (normalizedAccept.includes('text/html') &&
|
|
332
|
+
normalizedContentType.includes('text/html'));
|
|
333
|
+
};
|
|
334
|
+
exports.shouldInjectPreviewBridge = shouldInjectPreviewBridge;
|
|
335
|
+
/** Adds the isolated-preview bridge to a proxied HTML document. */
|
|
336
|
+
const injectPreviewBridge = (html, options = {}) => {
|
|
337
|
+
if (html.includes(`id="${exports.PREVIEW_BRIDGE_SCRIPT_ID}"`)) {
|
|
338
|
+
return html;
|
|
339
|
+
}
|
|
340
|
+
const script = (0, exports.createPreviewBridgeScript)(options);
|
|
341
|
+
const headMatch = html.match(/<head[^>]*>/i);
|
|
342
|
+
if (headMatch?.index !== undefined) {
|
|
343
|
+
const insertAt = headMatch.index + headMatch[0].length;
|
|
344
|
+
return `${html.slice(0, insertAt)}${script}${html.slice(insertAt)}`;
|
|
345
|
+
}
|
|
346
|
+
if (html.includes('</head>')) {
|
|
347
|
+
return html.replace('</head>', `${script}</head>`);
|
|
348
|
+
}
|
|
349
|
+
if (html.includes('</body>')) {
|
|
350
|
+
return html.replace('</body>', `${script}</body>`);
|
|
351
|
+
}
|
|
352
|
+
return `${script}${html}`;
|
|
353
|
+
};
|
|
354
|
+
exports.injectPreviewBridge = injectPreviewBridge;
|
|
355
|
+
const isHtmlDocumentRequest = (req) => req.method === 'GET' &&
|
|
356
|
+
firstHeaderValue(req.headers.accept).toLowerCase().includes('text/html');
|
|
357
|
+
exports.isHtmlDocumentRequest = isHtmlDocumentRequest;
|
|
358
|
+
//# sourceMappingURL=preview-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-bridge.js","sourceRoot":"","sources":["../../src/proxy-middleware/preview-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const markPreviewBridgeDocumentUncacheable: (proxyRes: IncomingMessage) => void;
|
|
3
|
+
export declare const createUserDevServerProxy: (userPort: number, userHost?: string, options?: {
|
|
4
|
+
isPreviewBridgeEnabled?: boolean;
|
|
5
|
+
expectedPreviewParentOrigin?: string;
|
|
6
|
+
}) => {
|
|
3
7
|
middleware: import("http-proxy-middleware").RequestHandler<IncomingMessage, ServerResponse<IncomingMessage>, (err?: any) => void>;
|
|
4
8
|
setVariantTarget: (port: number | null) => void;
|
|
5
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-config.d.ts","sourceRoot":"","sources":["../../src/proxy-middleware/proxy-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy-config.d.ts","sourceRoot":"","sources":["../../src/proxy-middleware/proxy-config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAiB,MAAM,MAAM,CAAC;AAwB3E,eAAO,MAAM,oCAAoC,GAC/C,UAAU,eAAe,KACxB,IAEF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,UAAU,MAAM,EAChB,WAAU,MAAoB,EAC9B,UAAS;IACP,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACjC;;6BAgC0B,MAAM,GAAG,IAAI;CAkM9C,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createUserDevServerProxy = void 0;
|
|
3
|
+
exports.createUserDevServerProxy = exports.markPreviewBridgeDocumentUncacheable = void 0;
|
|
4
4
|
const http_proxy_middleware_1 = require("http-proxy-middleware");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
5
6
|
const logger_1 = require("../utils/logger");
|
|
7
|
+
const preview_bridge_1 = require("./preview-bridge");
|
|
6
8
|
const log = (0, logger_1.createLogger)('ProxyConfig');
|
|
7
9
|
/**
|
|
8
10
|
* Satisfies http-proxy-middleware's required `target` option; real routing is
|
|
@@ -11,9 +13,14 @@ const log = (0, logger_1.createLogger)('ProxyConfig');
|
|
|
11
13
|
*/
|
|
12
14
|
const PROXY_LIBRARY_PLACEHOLDER_TARGET = 'http://127.0.0.1:9';
|
|
13
15
|
const hasValidUserDevPort = (userPort) => Number.isInteger(userPort) && userPort > 0;
|
|
14
|
-
const
|
|
16
|
+
const markPreviewBridgeDocumentUncacheable = (proxyRes) => {
|
|
17
|
+
proxyRes.headers['cache-control'] = 'no-cache, no-store';
|
|
18
|
+
};
|
|
19
|
+
exports.markPreviewBridgeDocumentUncacheable = markPreviewBridgeDocumentUncacheable;
|
|
20
|
+
const createUserDevServerProxy = (userPort, userHost = 'localhost', options = {}) => {
|
|
15
21
|
let variantTarget = null;
|
|
16
22
|
const hasDefaultUpstream = hasValidUserDevPort(userPort);
|
|
23
|
+
const isPreviewBridgeEnabled = options.isPreviewBridgeEnabled ?? false;
|
|
17
24
|
const defaultTarget = hasDefaultUpstream
|
|
18
25
|
? `http://${userHost}:${userPort}`
|
|
19
26
|
: null;
|
|
@@ -45,25 +52,58 @@ const createUserDevServerProxy = (userPort, userHost = 'localhost') => {
|
|
|
45
52
|
const nextLabel = next ?? defaultTarget ?? '(none)';
|
|
46
53
|
log.info(`setVariantTarget: ${prior} → ${nextLabel}`);
|
|
47
54
|
};
|
|
48
|
-
const
|
|
55
|
+
const prepareProxyResponseHeaders = (proxyRes) => {
|
|
56
|
+
// Allow iframe embedding by removing restrictive security headers
|
|
57
|
+
delete proxyRes.headers['x-frame-options'];
|
|
58
|
+
delete proxyRes.headers['content-security-policy-report-only'];
|
|
59
|
+
// Update Content-Security-Policy to allow iframe embedding
|
|
60
|
+
if (proxyRes.headers['content-security-policy']) {
|
|
61
|
+
const csp = proxyRes.headers['content-security-policy'];
|
|
62
|
+
if (typeof csp === 'string') {
|
|
63
|
+
// Remove frame-ancestors to allow embedding anywhere during development
|
|
64
|
+
proxyRes.headers['content-security-policy'] = csp.replace(/frame-ancestors[^;]*;?/, '');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const allowBridgeScriptInCsp = (proxyRes, scriptNonce) => {
|
|
69
|
+
const csp = proxyRes.headers['content-security-policy'];
|
|
70
|
+
if (typeof csp === 'string') {
|
|
71
|
+
proxyRes.headers['content-security-policy'] = (0, preview_bridge_1.allowPreviewBridgeNonceInCsp)(csp, { scriptNonce });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(csp)) {
|
|
75
|
+
proxyRes.headers['content-security-policy'] = csp.map((value) => (0, preview_bridge_1.allowPreviewBridgeNonceInCsp)(value, { scriptNonce }));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const createProxyOptions = (isHtmlTransformProxy) => ({
|
|
49
79
|
target: defaultTarget ?? PROXY_LIBRARY_PLACEHOLDER_TARGET,
|
|
50
80
|
router: () => getRouterTargetForLibrary(),
|
|
51
81
|
changeOrigin: true,
|
|
82
|
+
selfHandleResponse: isHtmlTransformProxy,
|
|
52
83
|
// No path rewriting needed when proxying all routes by default
|
|
53
84
|
on: {
|
|
54
|
-
proxyRes:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
85
|
+
proxyRes: isHtmlTransformProxy
|
|
86
|
+
? (0, http_proxy_middleware_1.responseInterceptor)(async (responseBuffer, proxyRes, req, _res) => {
|
|
87
|
+
prepareProxyResponseHeaders(proxyRes);
|
|
88
|
+
const contentType = proxyRes.headers['content-type'];
|
|
89
|
+
if (!(0, preview_bridge_1.shouldInjectPreviewBridge)({
|
|
90
|
+
method: req.method,
|
|
91
|
+
accept: req.headers.accept,
|
|
92
|
+
contentType,
|
|
93
|
+
})) {
|
|
94
|
+
return responseBuffer;
|
|
64
95
|
}
|
|
65
|
-
|
|
66
|
-
|
|
96
|
+
const scriptNonce = (0, crypto_1.randomBytes)(16).toString('base64');
|
|
97
|
+
allowBridgeScriptInCsp(proxyRes, scriptNonce);
|
|
98
|
+
(0, exports.markPreviewBridgeDocumentUncacheable)(proxyRes);
|
|
99
|
+
return (0, preview_bridge_1.injectPreviewBridge)(responseBuffer.toString('utf8'), {
|
|
100
|
+
expectedParentOrigin: options.expectedPreviewParentOrigin,
|
|
101
|
+
scriptNonce,
|
|
102
|
+
});
|
|
103
|
+
})
|
|
104
|
+
: (proxyRes, _req, _res) => {
|
|
105
|
+
prepareProxyResponseHeaders(proxyRes);
|
|
106
|
+
},
|
|
67
107
|
proxyReq: (proxyReq, req, _res) => {
|
|
68
108
|
// Preserve the original host for Next.js Server Actions
|
|
69
109
|
// Next.js checks that x-forwarded-host matches the origin header
|
|
@@ -94,8 +134,9 @@ const createUserDevServerProxy = (userPort, userHost = 'localhost') => {
|
|
|
94
134
|
// Timeout configurations
|
|
95
135
|
proxyTimeout: 30_000, // In MS
|
|
96
136
|
timeout: 30_000, // In MS
|
|
97
|
-
};
|
|
98
|
-
const proxyMiddlewareInstance = (0, http_proxy_middleware_1.createProxyMiddleware)(
|
|
137
|
+
});
|
|
138
|
+
const proxyMiddlewareInstance = (0, http_proxy_middleware_1.createProxyMiddleware)(createProxyOptions(false));
|
|
139
|
+
const htmlTransformProxyMiddlewareInstance = (0, http_proxy_middleware_1.createProxyMiddleware)(createProxyOptions(true));
|
|
99
140
|
const gatedHttp = (req, res, next) => {
|
|
100
141
|
const upstream = getActiveUpstream();
|
|
101
142
|
if (upstream === null) {
|
|
@@ -109,7 +150,10 @@ const createUserDevServerProxy = (userPort, userHost = 'localhost') => {
|
|
|
109
150
|
}
|
|
110
151
|
return;
|
|
111
152
|
}
|
|
112
|
-
|
|
153
|
+
const middleware = isPreviewBridgeEnabled && (0, preview_bridge_1.isHtmlDocumentRequest)(req)
|
|
154
|
+
? htmlTransformProxyMiddlewareInstance
|
|
155
|
+
: proxyMiddlewareInstance;
|
|
156
|
+
void middleware(req, res, next);
|
|
113
157
|
};
|
|
114
158
|
const gated = gatedHttp;
|
|
115
159
|
gated.upgrade = (req, socket, head) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-config.js","sourceRoot":"","sources":["../../src/proxy-middleware/proxy-config.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"proxy-config.js","sourceRoot":"","sources":["../../src/proxy-middleware/proxy-config.ts"],"names":[],"mappings":";;;AAAA,iEAI+B;AAG/B,mCAAqC;AACrC,4CAA+C;AAE/C,qDAK0B;AAE1B,MAAM,GAAG,GAAG,IAAA,qBAAY,EAAC,aAAa,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,gCAAgC,GAAG,oBAAoB,CAAC;AAE9D,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAW,EAAE,CACxD,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEtC,MAAM,oCAAoC,GAAG,CAClD,QAAyB,EACnB,EAAE;IACR,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,oBAAoB,CAAC;AAC3D,CAAC,CAAC;AAJW,QAAA,oCAAoC,wCAI/C;AAEK,MAAM,wBAAwB,GAAG,CACtC,QAAgB,EAChB,WAAmB,WAAW,EAC9B,UAGI,EAAE,EACN,EAAE;IACF,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,IAAI,KAAK,CAAC;IACvE,MAAM,aAAa,GAAG,kBAAkB;QACtC,CAAC,CAAC,UAAU,QAAQ,IAAI,QAAQ,EAAE;QAClC,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,iBAAiB,GAAG,GAAkB,EAAE,CAC5C,aAAa,IAAI,aAAa,IAAI,IAAI,CAAC;IAEzC,MAAM,yBAAyB,GAAG,GAAW,EAAE,CAC7C,iBAAiB,EAAE,IAAI,gCAAgC,CAAC;IAE1D,MAAM,mBAAmB,GAAG,GAAoB,EAAE;QAChD,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;gBACnD,OAAO,UAAU,CAAC;YACpB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,OAAO,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACpD,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,IAAmB,EAAE,EAAE;QAC/C,MAAM,KAAK,GAAG,aAAa,IAAI,aAAa,IAAI,QAAQ,CAAC;QACzD,MAAM,IAAI,GACR,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC;YACjD,CAAC,CAAC,oBAAoB,IAAI,EAAE;YAC5B,CAAC,CAAC,IAAI,CAAC;QACX,aAAa,GAAG,IAAI,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,IAAI,aAAa,IAAI,QAAQ,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,qBAAqB,KAAK,MAAM,SAAS,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,2BAA2B,GAAG,CAAC,QAAyB,EAAE,EAAE;QAChE,kEAAkE;QAClE,OAAO,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC3C,OAAO,QAAQ,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAE/D,2DAA2D;QAC3D,IAAI,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;YACxD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC5B,wEAAwE;gBACxE,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,GAAG,GAAG,CAAC,OAAO,CACvD,wBAAwB,EACxB,EAAE,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,sBAAsB,GAAG,CAC7B,QAAyB,EACzB,WAAmB,EACnB,EAAE;QACF,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACxD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,GAAG,IAAA,6CAA4B,EACxE,GAAG,EACH,EAAE,WAAW,EAAE,CAChB,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,OAAO,CAAC,yBAAyB,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC9D,IAAA,6CAA4B,EAAC,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC,CACrD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAG,CAAC,oBAA6B,EAAW,EAAE,CAAC,CAAC;QACtE,MAAM,EAAE,aAAa,IAAI,gCAAgC;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,yBAAyB,EAAE;QACzC,YAAY,EAAE,IAAI;QAClB,kBAAkB,EAAE,oBAAoB;QACxC,+DAA+D;QAC/D,EAAE,EAAE;YACF,QAAQ,EAAE,oBAAoB;gBAC5B,CAAC,CAAC,IAAA,2CAAmB,EAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;oBAChE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;oBACtC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;oBACrD,IACE,CAAC,IAAA,0CAAyB,EAAC;wBACzB,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM;wBAC1B,WAAW;qBACZ,CAAC,EACF,CAAC;wBACD,OAAO,cAAc,CAAC;oBACxB,CAAC;oBACD,MAAM,WAAW,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBACvD,sBAAsB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAC9C,IAAA,4CAAoC,EAAC,QAAQ,CAAC,CAAC;oBAC/C,OAAO,IAAA,oCAAmB,EAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;wBAC1D,oBAAoB,EAAE,OAAO,CAAC,2BAA2B;wBACzD,WAAW;qBACZ,CAAC,CAAC;gBACL,CAAC,CAAC;gBACJ,CAAC,CAAC,CACE,QAAyB,EACzB,IAAqB,EACrB,IAAoB,EACpB,EAAE;oBACF,2BAA2B,CAAC,QAAQ,CAAC,CAAC;gBACxC,CAAC;YACL,QAAQ,EAAE,CACR,QAAuB,EACvB,GAAoB,EACpB,IAAoB,EACpB,EAAE;gBACF,wDAAwD;gBACxD,iEAAiE;gBACjE,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;oBACrB,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC3D,CAAC;gBAED,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC;gBAC7B,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAClC,GAAG,CAAC,KAAK,CACP,YAAY,GAAG,CAAC,MAAM,IAAI,YAAY,OAAO,WAAW,OAAO,yBAAyB,EAAE,EAAE,CAC7F,CAAC;YACJ,CAAC;YACD,KAAK,EAAE,CACL,GAAU,EACV,GAAoB,EACpB,GAA6C,EAC7C,EAAE;gBACF,GAAG,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACnE,wDAAwD;gBACxD,IAAI,GAAG,IAAI,WAAW,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;oBAClD,6EAA6E;oBAC7E,sFAAsF;oBACtF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;oBAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;wBACb,KAAK,EAAE,aAAa;wBACpB,OAAO,EAAE,mDAAmD,mBAAmB,EAAE,EAAE;wBACnF,OAAO,EAAE,GAAG,CAAC,OAAO;qBACrB,CAAC,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;SACF;QACD,2DAA2D;QAC3D,EAAE,EAAE,IAAI;QACR,yBAAyB;QACzB,YAAY,EAAE,MAAM,EAAE,QAAQ;QAC9B,OAAO,EAAE,MAAM,EAAE,QAAQ;KAC1B,CAAC,CAAC;IAEH,MAAM,uBAAuB,GAAG,IAAA,6CAAqB,EACnD,kBAAkB,CAAC,KAAK,CAAC,CAC1B,CAAC;IACF,MAAM,oCAAoC,GAAG,IAAA,6CAAqB,EAChE,kBAAkB,CAAC,IAAI,CAAC,CACzB,CAAC;IAGF,MAAM,SAAS,GAAG,CAChB,GAAoB,EACpB,GAAmB,EACnB,IAAkB,EACZ,EAAE;QACR,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,IAAI,WAAW,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBAC3C,GAAG,CAAC,KAAK,CACP,6DAA6D,QAAQ,IAAI,CAC1E,CAAC;gBACF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;oBACb,KAAK,EAAE,qBAAqB;oBAC5B,OAAO,EACL,+FAA+F;iBAClG,CAAC,CACH,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GACd,sBAAsB,IAAI,IAAA,sCAAqB,EAAC,GAAG,CAAC;YAClD,CAAC,CAAC,oCAAoC;YACtC,CAAC,CAAC,uBAAuB,CAAC;QAC9B,KAAK,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,SAAwC,CAAC;IACvD,KAAK,CAAC,OAAO,GAAG,CACd,GAAoB,EACpB,MAAc,EACd,IAAY,EACN,EAAE;QACR,IAAI,iBAAiB,EAAE,KAAK,IAAI,EAAE,CAAC;YACjC,GAAG,CAAC,KAAK,CACP,uDAAuD,QAAQ,IAAI,CACpE,CAAC;YACF,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,uBAAuB,CAAC,OAAO,EAAE,CAAC;YACpC,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QACD,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,IAAI,kBAAkB,EAAE,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,sCAAsC,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,CACN,wDAAwD,QAAQ,sCAAsC,CACvG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;AACjD,CAAC,CAAC;AAxOW,QAAA,wBAAwB,4BAwOnC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routes for Generative Editor Interfaces. Generation only — promotion (Phase 3)
|
|
3
|
+
* reuses the existing apply pipeline, so there is no `/promote` route here.
|
|
4
|
+
* See docs/generative-editor-interfaces.md.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createControlsRouter: () => import("express-serve-static-core").Router;
|
|
7
|
+
//# sourceMappingURL=controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/routes/controls.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,kDA0ChC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createControlsRouter = void 0;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
const InterfaceGenerationService_1 = require("../services/InterfaceGenerationService");
|
|
7
|
+
const log = (0, logger_1.createLogger)('ControlsRoutes');
|
|
8
|
+
/**
|
|
9
|
+
* Routes for Generative Editor Interfaces. Generation only — promotion (Phase 3)
|
|
10
|
+
* reuses the existing apply pipeline, so there is no `/promote` route here.
|
|
11
|
+
* See docs/generative-editor-interfaces.md.
|
|
12
|
+
*/
|
|
13
|
+
const createControlsRouter = () => {
|
|
14
|
+
const router = (0, express_1.Router)();
|
|
15
|
+
router.post('/controls/generate', async (req, res) => {
|
|
16
|
+
try {
|
|
17
|
+
const body = req.body ?? {};
|
|
18
|
+
const description = String(body.description ?? '').trim();
|
|
19
|
+
if (!description) {
|
|
20
|
+
return res.status(400).json({ error: 'description is required' });
|
|
21
|
+
}
|
|
22
|
+
const params = {
|
|
23
|
+
description,
|
|
24
|
+
existingSectionTitles: Array.isArray(body.existingSectionTitles)
|
|
25
|
+
? body.existingSectionTitles.map(String)
|
|
26
|
+
: undefined,
|
|
27
|
+
elementSummary: typeof body.elementSummary === 'string'
|
|
28
|
+
? body.elementSummary
|
|
29
|
+
: undefined,
|
|
30
|
+
tokenSummary: typeof body.tokenSummary === 'string' ? body.tokenSummary : undefined,
|
|
31
|
+
model: typeof body.model === 'string' && body.model.trim().length > 0
|
|
32
|
+
? body.model.trim()
|
|
33
|
+
: undefined,
|
|
34
|
+
};
|
|
35
|
+
const sections = await (0, InterfaceGenerationService_1.generateEditorInterface)(params);
|
|
36
|
+
return res.json({ sections });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
log.error('Interface generation failed', error);
|
|
40
|
+
return res.status(500).json({
|
|
41
|
+
error: error instanceof Error
|
|
42
|
+
? error.message
|
|
43
|
+
: 'Interface generation failed',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return router;
|
|
48
|
+
};
|
|
49
|
+
exports.createControlsRouter = createControlsRouter;
|
|
50
|
+
//# sourceMappingURL=controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../../src/routes/controls.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AACjC,4CAA+C;AAC/C,uFAGgD;AAEhD,MAAM,GAAG,GAAG,IAAA,qBAAY,EAAC,gBAAgB,CAAC,CAAC;AAE3C;;;;GAIG;AACI,MAAM,oBAAoB,GAAG,GAAG,EAAE;IACvC,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;IAExB,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;YAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1D,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACpE,CAAC;YAED,MAAM,MAAM,GAA4B;gBACtC,WAAW;gBACX,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC;oBAC9D,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC;oBACxC,CAAC,CAAC,SAAS;gBACb,cAAc,EACZ,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ;oBACrC,CAAC,CAAC,IAAI,CAAC,cAAc;oBACrB,CAAC,CAAC,SAAS;gBACf,YAAY,EACV,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;gBACvE,KAAK,EACH,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;oBAC5D,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;oBACnB,CAAC,CAAC,SAAS;aAChB,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,IAAA,oDAAuB,EAAC,MAAM,CAAC,CAAC;YACvD,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EACH,KAAK,YAAY,KAAK;oBACpB,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,6BAA6B;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AA1CW,QAAA,oBAAoB,wBA0C/B"}
|
package/dist/routes/mcp.d.ts
CHANGED
|
@@ -11,5 +11,7 @@ import type { AgentVariantsOrchestrator } from '../mcp/agent-variants';
|
|
|
11
11
|
* provided, the intake rejects new variant-request batches while a variants
|
|
12
12
|
* session is already active for the current project.
|
|
13
13
|
*/
|
|
14
|
-
export declare const createMCPRouter: (bridge: SessionBridgeService, telemetry?: TelemetryService, agentVariantsOrchestrator?: AgentVariantsOrchestrator
|
|
14
|
+
export declare const createMCPRouter: (bridge: SessionBridgeService, telemetry?: TelemetryService, agentVariantsOrchestrator?: AgentVariantsOrchestrator, options?: {
|
|
15
|
+
queueAccessToken?: string;
|
|
16
|
+
}) => Router;
|
|
15
17
|
//# sourceMappingURL=mcp.d.ts.map
|
package/dist/routes/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/routes/mcp.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAOrE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/routes/mcp.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAOrE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAqSvE;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,oBAAoB,EAC5B,YAAY,gBAAgB,EAC5B,4BAA4B,yBAAyB,EACrD,UAAS;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,KAC1C,MA6ZF,CAAC"}
|