@spotpatch/runtime 1.8.0 → 1.10.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/dist/chunk-7ES63LA7.js +28 -0
- package/dist/chunk-7ES63LA7.js.map +1 -0
- package/dist/chunk-NII5OBAN.js +14 -0
- package/dist/chunk-NII5OBAN.js.map +1 -0
- package/dist/chunk-QY5T4DPA.js +552 -0
- package/dist/chunk-QY5T4DPA.js.map +1 -0
- package/dist/chunk-XBD55BCF.js +14 -0
- package/dist/chunk-XBD55BCF.js.map +1 -0
- package/dist/data-flow-panel.cjs +333 -0
- package/dist/data-flow-panel.cjs.map +1 -0
- package/dist/data-flow-panel.d.cts +38 -0
- package/dist/data-flow-panel.d.ts +38 -0
- package/dist/data-flow-panel.js +283 -0
- package/dist/data-flow-panel.js.map +1 -0
- package/dist/data-flow-runtime-B3itbieT.d.cts +67 -0
- package/dist/data-flow-runtime-B3itbieT.d.ts +67 -0
- package/dist/data-flow.cjs +575 -0
- package/dist/data-flow.cjs.map +1 -0
- package/dist/data-flow.d.cts +8 -0
- package/dist/data-flow.d.ts +8 -0
- package/dist/data-flow.js +15 -0
- package/dist/data-flow.js.map +1 -0
- package/dist/external-handoff-panel.cjs +1002 -0
- package/dist/external-handoff-panel.cjs.map +1 -0
- package/dist/external-handoff-panel.d.cts +36 -0
- package/dist/external-handoff-panel.d.ts +36 -0
- package/dist/external-handoff-panel.js +959 -0
- package/dist/external-handoff-panel.js.map +1 -0
- package/dist/index.cjs +871 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +335 -31
- package/dist/index.js.map +1 -1
- package/package.json +46 -3
package/dist/index.cjs
CHANGED
|
@@ -18,12 +18,17 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
23
|
UI_MARKER_ATTRIBUTE: () => UI_MARKER_ATTRIBUTE,
|
|
24
|
-
bootstrapSpotPatch: () => bootstrapSpotPatch
|
|
24
|
+
bootstrapSpotPatch: () => bootstrapSpotPatch,
|
|
25
|
+
createDataFlowRuntime: () => createDataFlowRuntime,
|
|
26
|
+
getDataFlowRuntime: () => getDataFlowRuntime,
|
|
27
|
+
installDataFlowPrelude: () => installDataFlowPrelude,
|
|
28
|
+
mergeComponentDataFlowReport: () => mergeComponentDataFlowReport,
|
|
29
|
+
mergePageDataFlowReport: () => mergePageDataFlowReport
|
|
25
30
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
31
|
+
module.exports = __toCommonJS(src_exports);
|
|
27
32
|
|
|
28
33
|
// src/controller/runtime-controller.ts
|
|
29
34
|
var import_react_adapter = require("@spotpatch/react-adapter");
|
|
@@ -348,15 +353,36 @@ function parseJson(text2) {
|
|
|
348
353
|
throw new RuntimeApiError();
|
|
349
354
|
}
|
|
350
355
|
}
|
|
351
|
-
async function readJsonEnvelope(response) {
|
|
356
|
+
async function readJsonEnvelope(response, maximumBytes = MAX_JSON_RESPONSE_BYTES) {
|
|
352
357
|
const payload = parseJson(
|
|
353
|
-
await readBoundedText(response,
|
|
358
|
+
await readBoundedText(response, maximumBytes)
|
|
354
359
|
);
|
|
355
360
|
if (!response.ok) {
|
|
356
361
|
throw new RuntimeApiError(readFailureCode(payload));
|
|
357
362
|
}
|
|
358
363
|
return readSuccessData(payload);
|
|
359
364
|
}
|
|
365
|
+
function isStringArray(value) {
|
|
366
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
367
|
+
}
|
|
368
|
+
function isReportCompleteness(value) {
|
|
369
|
+
return isRecord2(value) && typeof value.complete === "boolean" && typeof value.visitedModules === "number" && typeof value.visitedCallsites === "number" && typeof value.frontierCount === "number";
|
|
370
|
+
}
|
|
371
|
+
function isDataFlowCapability(value) {
|
|
372
|
+
return isRecord2(value) && typeof value.enabled === "boolean" && (value.staticAnalysis === "available" || value.staticAnalysis === "partial" || value.staticAnalysis === "unavailable") && value.runtimeObservation === "dispatch-only" && value.responseShape === "consumed-fields-only" && value.aiAssistance === "disabled" && Array.isArray(value.reasons);
|
|
373
|
+
}
|
|
374
|
+
function isDataFlowDependency(value) {
|
|
375
|
+
return isRecord2(value) && typeof value.id === "string" && typeof value.kind === "string" && typeof value.direction === "string" && typeof value.execution === "string" && typeof value.proof === "string" && typeof value.association === "string" && Array.isArray(value.parameters) && isRecord2(value.response) && isStringArray(value.response.consumedFields) && isStringArray(value.evidenceIds) && isStringArray(value.observationIds);
|
|
376
|
+
}
|
|
377
|
+
function isDataFlowReportBase(value) {
|
|
378
|
+
return isRecord2(value) && value.schemaVersion === import_shared3.DATA_FLOW_SCHEMA_VERSION && typeof value.reportId === "string" && isRecord2(value.baseline) && typeof value.baseline.registryEpoch === "string" && typeof value.baseline.analyzerVersion === "string" && isStringArray(value.baseline.analyzedSourceVersions) && isDataFlowCapability(value.capability) && Array.isArray(value.dependencies) && value.dependencies.every(isDataFlowDependency) && Array.isArray(value.evidence) && Array.isArray(value.diagnostics) && isReportCompleteness(value.completeness);
|
|
379
|
+
}
|
|
380
|
+
function isComponentDataFlowReport(value) {
|
|
381
|
+
return isDataFlowReportBase(value) && isRecord2(value) && isRecord2(value.component) && isRecord2(value.component.source) && typeof value.component.source.fileId === "string" && typeof value.component.source.sourceVersion === "string";
|
|
382
|
+
}
|
|
383
|
+
function isPageDataFlowReport(value) {
|
|
384
|
+
return isDataFlowReportBase(value);
|
|
385
|
+
}
|
|
360
386
|
function parseCapability(value, expected) {
|
|
361
387
|
if (!isAgentCapabilitySnapshot(value) || value.providerProfileId !== expected.providerProfileId || value.modelProfileId !== expected.modelProfileId) {
|
|
362
388
|
throw new RuntimeApiError();
|
|
@@ -408,7 +434,7 @@ function createRuntimeApi(options) {
|
|
|
408
434
|
}
|
|
409
435
|
pendingRequests.clear();
|
|
410
436
|
}
|
|
411
|
-
async function requestJson(endpoint, method, body) {
|
|
437
|
+
async function requestJson(endpoint, method, body, maximumResponseBytes = MAX_JSON_RESPONSE_BYTES) {
|
|
412
438
|
const abortController = new AbortController();
|
|
413
439
|
pendingRequests.add(abortController);
|
|
414
440
|
try {
|
|
@@ -421,7 +447,7 @@ function createRuntimeApi(options) {
|
|
|
421
447
|
...body === void 0 ? {} : { body: JSON.stringify(body) },
|
|
422
448
|
signal: abortController.signal
|
|
423
449
|
});
|
|
424
|
-
return await readJsonEnvelope(response);
|
|
450
|
+
return await readJsonEnvelope(response, maximumResponseBytes);
|
|
425
451
|
} finally {
|
|
426
452
|
pendingRequests.delete(abortController);
|
|
427
453
|
}
|
|
@@ -515,6 +541,30 @@ function createRuntimeApi(options) {
|
|
|
515
541
|
}
|
|
516
542
|
return Object.freeze({ ...data });
|
|
517
543
|
},
|
|
544
|
+
async componentDataFlowReport(request) {
|
|
545
|
+
const data = await requestJson(
|
|
546
|
+
import_shared3.SPOTPATCH_ENDPOINTS.dataFlowComponentReport,
|
|
547
|
+
"POST",
|
|
548
|
+
request,
|
|
549
|
+
options.dataFlowReportMaxBytes
|
|
550
|
+
);
|
|
551
|
+
if (!isComponentDataFlowReport(data)) {
|
|
552
|
+
throw new RuntimeApiError();
|
|
553
|
+
}
|
|
554
|
+
return deepFreeze(data);
|
|
555
|
+
},
|
|
556
|
+
async pageDataFlowReport(request) {
|
|
557
|
+
const data = await requestJson(
|
|
558
|
+
import_shared3.SPOTPATCH_ENDPOINTS.dataFlowPageReport,
|
|
559
|
+
"POST",
|
|
560
|
+
request,
|
|
561
|
+
options.dataFlowReportMaxBytes
|
|
562
|
+
);
|
|
563
|
+
if (!isPageDataFlowReport(data)) {
|
|
564
|
+
throw new RuntimeApiError();
|
|
565
|
+
}
|
|
566
|
+
return deepFreeze(data);
|
|
567
|
+
},
|
|
518
568
|
async openEditor(request) {
|
|
519
569
|
const data = await requestJson(import_shared3.SPOTPATCH_ENDPOINTS.openEditor, "POST", request);
|
|
520
570
|
if (!isRecord2(data) || data.editor !== "auto" && data.editor !== "vscode" && data.editor !== "cursor") {
|
|
@@ -2455,6 +2505,12 @@ function createBrandMark(document, content) {
|
|
|
2455
2505
|
return svg;
|
|
2456
2506
|
}
|
|
2457
2507
|
|
|
2508
|
+
// src/ui/data-flow-panel-contract.ts
|
|
2509
|
+
var DATA_FLOW_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.data-flow.extension.v1");
|
|
2510
|
+
function getDataFlowExtension(target2 = globalThis) {
|
|
2511
|
+
return target2[DATA_FLOW_EXTENSION_KEY];
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2458
2514
|
// src/ui/dialog-placement.ts
|
|
2459
2515
|
var VIEWPORT_MARGIN = 16;
|
|
2460
2516
|
var TARGET_GAP = 14;
|
|
@@ -2522,6 +2578,12 @@ function calculateDialogPlacement({
|
|
|
2522
2578
|
});
|
|
2523
2579
|
}
|
|
2524
2580
|
|
|
2581
|
+
// src/ui/external-handoff-contract.ts
|
|
2582
|
+
var EXTERNAL_HANDOFF_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.external-handoff.v1");
|
|
2583
|
+
function getExternalHandoffExtension() {
|
|
2584
|
+
return globalThis[EXTERNAL_HANDOFF_EXTENSION_KEY];
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2525
2587
|
// src/ui/localization.ts
|
|
2526
2588
|
var import_shared6 = require("@spotpatch/shared");
|
|
2527
2589
|
var STATUS_EN = Object.freeze({
|
|
@@ -2554,6 +2616,8 @@ var STATUS_ZH = Object.freeze({
|
|
|
2554
2616
|
reverted: "\u5DF2\u64A4\u9500",
|
|
2555
2617
|
failed: "\u5931\u8D25"
|
|
2556
2618
|
});
|
|
2619
|
+
var EXTERNAL_HANDOFF_ERROR_EN = "The external Agent handoff request failed.";
|
|
2620
|
+
var EXTERNAL_HANDOFF_ERROR_ZH = "\u5916\u90E8 Agent \u4EA4\u63A5\u8BF7\u6C42\u5931\u8D25\u3002";
|
|
2557
2621
|
var ERROR_MESSAGES_EN = Object.freeze({
|
|
2558
2622
|
[import_shared6.ERROR_CODES.INVALID_REQUEST]: "The Agent request was rejected as invalid.",
|
|
2559
2623
|
[import_shared6.ERROR_CODES.INVALID_TOKEN]: "The local SpotPatch session expired.",
|
|
@@ -2562,6 +2626,9 @@ var ERROR_MESSAGES_EN = Object.freeze({
|
|
|
2562
2626
|
[import_shared6.ERROR_CODES.SOURCE_OUTSIDE_ROOT]: "The selected source is outside the project.",
|
|
2563
2627
|
[import_shared6.ERROR_CODES.SOURCE_TOO_LARGE]: "The selected source exceeds the safety limit.",
|
|
2564
2628
|
[import_shared6.ERROR_CODES.EDITOR_OPEN_FAILED]: "The editor request failed.",
|
|
2629
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_DISABLED]: "Component data-flow analysis is disabled.",
|
|
2630
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_SOURCE_STALE]: "The selected source changed. Select the component again.",
|
|
2631
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_ANALYSIS_CANCELLED]: "Component data-flow analysis was cancelled.",
|
|
2565
2632
|
[import_shared6.ERROR_CODES.AI_DISABLED]: "AI execution is disabled in Vite configuration.",
|
|
2566
2633
|
[import_shared6.ERROR_CODES.PROVIDER_NOT_CONFIGURED]: "The provider Key environment variable is missing on the Vite process.",
|
|
2567
2634
|
[import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "The provider rejected authentication. Check the server-side Key.",
|
|
@@ -2572,6 +2639,24 @@ var ERROR_MESSAGES_EN = Object.freeze({
|
|
|
2572
2639
|
[import_shared6.ERROR_CODES.AGENT_BUSY]: "Another write Agent job is still active.",
|
|
2573
2640
|
[import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "The Agent stopped at a configured time, turn, output, or size limit.",
|
|
2574
2641
|
[import_shared6.ERROR_CODES.AGENT_CANCELLED]: "The Agent job was cancelled.",
|
|
2642
|
+
[import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_DISABLED]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2643
|
+
[import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_UNAVAILABLE]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2644
|
+
[import_shared6.ERROR_CODES.HANDOFF_VALIDATION_FAILED]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2645
|
+
[import_shared6.ERROR_CODES.HANDOFF_SOURCE_STALE]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2646
|
+
[import_shared6.ERROR_CODES.HANDOFF_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2647
|
+
[import_shared6.ERROR_CODES.HANDOFF_EXPIRED]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2648
|
+
[import_shared6.ERROR_CODES.HANDOFF_CURSOR_INVALID]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2649
|
+
[import_shared6.ERROR_CODES.HANDOFF_RESPONSE_TOO_LARGE]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2650
|
+
[import_shared6.ERROR_CODES.BRIDGE_UNAUTHORIZED]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2651
|
+
[import_shared6.ERROR_CODES.BRIDGE_PROTOCOL_MISMATCH]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2652
|
+
[import_shared6.ERROR_CODES.BRIDGE_BUSY]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2653
|
+
[import_shared6.ERROR_CODES.EXTERNAL_AGENT_BUSY]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2654
|
+
[import_shared6.ERROR_CODES.ACTIVE_ADAPTER_CONFLICT]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2655
|
+
[import_shared6.ERROR_CODES.ACTIVE_ADAPTER_LEASE_INVALID]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2656
|
+
[import_shared6.ERROR_CODES.ACTIVE_DISPATCH_INVALID]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2657
|
+
[import_shared6.ERROR_CODES.SESSION_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2658
|
+
[import_shared6.ERROR_CODES.SESSION_AMBIGUOUS]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2659
|
+
[import_shared6.ERROR_CODES.SESSION_CLOSED]: EXTERNAL_HANDOFF_ERROR_EN,
|
|
2575
2660
|
[import_shared6.ERROR_CODES.WORKTREE_DIRTY]: "Confirm inclusion of local changes before running AI.",
|
|
2576
2661
|
[import_shared6.ERROR_CODES.WORKTREE_NOT_REPOSITORY]: "Vite root must be an initialized Git repository root.",
|
|
2577
2662
|
[import_shared6.ERROR_CODES.WORKTREE_OPERATION_IN_PROGRESS]: "Finish the active merge, rebase, cherry-pick, or revert.",
|
|
@@ -2597,6 +2682,9 @@ var ERROR_MESSAGES_ZH = Object.freeze({
|
|
|
2597
2682
|
[import_shared6.ERROR_CODES.SOURCE_OUTSIDE_ROOT]: "\u9009\u4E2D\u6E90\u7801\u4F4D\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\u4E4B\u5916\u3002",
|
|
2598
2683
|
[import_shared6.ERROR_CODES.SOURCE_TOO_LARGE]: "\u9009\u4E2D\u6E90\u7801\u8D85\u8FC7\u5B89\u5168\u5927\u5C0F\u9650\u5236\u3002",
|
|
2599
2684
|
[import_shared6.ERROR_CODES.EDITOR_OPEN_FAILED]: "\u7F16\u8F91\u5668\u6253\u5F00\u8BF7\u6C42\u5931\u8D25\u3002",
|
|
2685
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_DISABLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u672A\u542F\u7528\u3002",
|
|
2686
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_SOURCE_STALE]: "\u9009\u4E2D\u6E90\u7801\u5DF2\u7ECF\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u7EC4\u4EF6\u3002",
|
|
2687
|
+
[import_shared6.ERROR_CODES.DATA_FLOW_ANALYSIS_CANCELLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u5DF2\u53D6\u6D88\u3002",
|
|
2600
2688
|
[import_shared6.ERROR_CODES.AI_DISABLED]: "Vite \u914D\u7F6E\u672A\u542F\u7528 AI \u6267\u884C\u3002",
|
|
2601
2689
|
[import_shared6.ERROR_CODES.PROVIDER_NOT_CONFIGURED]: "\u542F\u52A8 Vite \u7684\u8FDB\u7A0B\u4E2D\u7F3A\u5C11\u6A21\u578B\u670D\u52A1 Key \u73AF\u5883\u53D8\u91CF\u3002",
|
|
2602
2690
|
[import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "\u6A21\u578B\u670D\u52A1\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u7AEF Key\u3002",
|
|
@@ -2607,6 +2695,24 @@ var ERROR_MESSAGES_ZH = Object.freeze({
|
|
|
2607
2695
|
[import_shared6.ERROR_CODES.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
|
|
2608
2696
|
[import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
|
|
2609
2697
|
[import_shared6.ERROR_CODES.AGENT_CANCELLED]: "Agent \u4EFB\u52A1\u5DF2\u53D6\u6D88\u3002",
|
|
2698
|
+
[import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_DISABLED]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2699
|
+
[import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_UNAVAILABLE]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2700
|
+
[import_shared6.ERROR_CODES.HANDOFF_VALIDATION_FAILED]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2701
|
+
[import_shared6.ERROR_CODES.HANDOFF_SOURCE_STALE]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2702
|
+
[import_shared6.ERROR_CODES.HANDOFF_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2703
|
+
[import_shared6.ERROR_CODES.HANDOFF_EXPIRED]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2704
|
+
[import_shared6.ERROR_CODES.HANDOFF_CURSOR_INVALID]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2705
|
+
[import_shared6.ERROR_CODES.HANDOFF_RESPONSE_TOO_LARGE]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2706
|
+
[import_shared6.ERROR_CODES.BRIDGE_UNAUTHORIZED]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2707
|
+
[import_shared6.ERROR_CODES.BRIDGE_PROTOCOL_MISMATCH]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2708
|
+
[import_shared6.ERROR_CODES.BRIDGE_BUSY]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2709
|
+
[import_shared6.ERROR_CODES.EXTERNAL_AGENT_BUSY]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2710
|
+
[import_shared6.ERROR_CODES.ACTIVE_ADAPTER_CONFLICT]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2711
|
+
[import_shared6.ERROR_CODES.ACTIVE_ADAPTER_LEASE_INVALID]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2712
|
+
[import_shared6.ERROR_CODES.ACTIVE_DISPATCH_INVALID]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2713
|
+
[import_shared6.ERROR_CODES.SESSION_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2714
|
+
[import_shared6.ERROR_CODES.SESSION_AMBIGUOUS]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2715
|
+
[import_shared6.ERROR_CODES.SESSION_CLOSED]: EXTERNAL_HANDOFF_ERROR_ZH,
|
|
2610
2716
|
[import_shared6.ERROR_CODES.WORKTREE_DIRTY]: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u660E\u786E\u540C\u610F\u5C06\u5F53\u524D\u672C\u5730\u4FEE\u6539\u7EB3\u5165\u9694\u79BB\u57FA\u7EBF\u3002",
|
|
2611
2717
|
[import_shared6.ERROR_CODES.WORKTREE_NOT_REPOSITORY]: "Vite \u6839\u76EE\u5F55\u4E0D\u662F\u5DF2\u521D\u59CB\u5316 Git \u4ED3\u5E93\u7684\u9876\u5C42\u76EE\u5F55\u3002",
|
|
2612
2718
|
[import_shared6.ERROR_CODES.WORKTREE_OPERATION_IN_PROGRESS]: "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D merge\u3001rebase\u3001cherry-pick \u6216 revert\uFF0C\u518D\u8FD0\u884C AI\u3002",
|
|
@@ -3031,6 +3137,15 @@ var DIALOG_FALLBACK_HEIGHT = Object.freeze({
|
|
|
3031
3137
|
previewing: 560,
|
|
3032
3138
|
selected: DIALOG_MAX_HEIGHT
|
|
3033
3139
|
});
|
|
3140
|
+
function resolveStyleNonce(document) {
|
|
3141
|
+
const nonces = new Set(
|
|
3142
|
+
[...document.querySelectorAll("script[nonce]")].map((script) => script.nonce?.trim() ?? "").filter(Boolean)
|
|
3143
|
+
);
|
|
3144
|
+
if (nonces.size !== 1) {
|
|
3145
|
+
return void 0;
|
|
3146
|
+
}
|
|
3147
|
+
return nonces.values().next().value;
|
|
3148
|
+
}
|
|
3034
3149
|
function createStyles(document) {
|
|
3035
3150
|
const style = document.createElement("style");
|
|
3036
3151
|
style.textContent = `
|
|
@@ -3741,7 +3856,18 @@ function summaryLine(summary, prefix) {
|
|
|
3741
3856
|
const line = summary.split("\n").find((candidate) => candidate.startsWith(`${prefix}: `));
|
|
3742
3857
|
return line?.slice(prefix.length + 2).trim();
|
|
3743
3858
|
}
|
|
3744
|
-
function
|
|
3859
|
+
function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot) {
|
|
3860
|
+
changesRoot.append(diagnosticsRoot);
|
|
3861
|
+
return Object.freeze({
|
|
3862
|
+
root: changesRoot,
|
|
3863
|
+
refreshButton: createButton(document, ""),
|
|
3864
|
+
styles: document.createElement("style"),
|
|
3865
|
+
dispose: () => void 0,
|
|
3866
|
+
render: () => void 0,
|
|
3867
|
+
resetView: () => void 0
|
|
3868
|
+
});
|
|
3869
|
+
}
|
|
3870
|
+
function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "") {
|
|
3745
3871
|
const localizer = createUiLocalizer(document, localePreference);
|
|
3746
3872
|
let messages = localizer.messages();
|
|
3747
3873
|
const host = document.createElement("spotpatch-root");
|
|
@@ -3857,7 +3983,29 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3857
3983
|
summary.className = "spotpatch-summary";
|
|
3858
3984
|
diagnostics.append(diagnosticsLabel, summary);
|
|
3859
3985
|
const agentPanel = createAgentPanel(document, ai, localizer);
|
|
3860
|
-
|
|
3986
|
+
const changesPanel = createMarkedElement(document, "div");
|
|
3987
|
+
const externalHandoffPanel = externalAgentEnabled ? getExternalHandoffExtension()?.createPanel(
|
|
3988
|
+
document,
|
|
3989
|
+
framework,
|
|
3990
|
+
localizer.locale,
|
|
3991
|
+
sessionId,
|
|
3992
|
+
localizer.subscribe,
|
|
3993
|
+
placeDialog
|
|
3994
|
+
) : void 0;
|
|
3995
|
+
changesPanel.append(
|
|
3996
|
+
targetsPanel,
|
|
3997
|
+
agentPanel.root,
|
|
3998
|
+
...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.root]
|
|
3999
|
+
);
|
|
4000
|
+
const dataFlowPanel = getDataFlowExtension()?.createPanel(
|
|
4001
|
+
document,
|
|
4002
|
+
dataFlowEnabled,
|
|
4003
|
+
localizer.locale,
|
|
4004
|
+
changesPanel,
|
|
4005
|
+
diagnostics,
|
|
4006
|
+
placeDialog
|
|
4007
|
+
) ?? createUnavailableDataFlowPanel(document, changesPanel, diagnostics);
|
|
4008
|
+
selectionPanel.append(dataFlowPanel.root);
|
|
3861
4009
|
const previewPanel = createMarkedElement(document, "div");
|
|
3862
4010
|
previewPanel.className = "spotpatch-preview-panel";
|
|
3863
4011
|
previewPanel.hidden = true;
|
|
@@ -3900,6 +4048,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3900
4048
|
agentPanel.testButton,
|
|
3901
4049
|
addTargetButton,
|
|
3902
4050
|
agentPanel.runButton,
|
|
4051
|
+
...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.sendButton],
|
|
3903
4052
|
previewButton,
|
|
3904
4053
|
agentPanel.cancelButton,
|
|
3905
4054
|
agentPanel.applyButton,
|
|
@@ -3915,8 +4064,19 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3915
4064
|
liveRegion.className = "spotpatch-live";
|
|
3916
4065
|
liveRegion.setAttribute("aria-live", "polite");
|
|
3917
4066
|
liveRegion.setAttribute("aria-atomic", "true");
|
|
3918
|
-
|
|
4067
|
+
const styles2 = [
|
|
3919
4068
|
createStyles(document),
|
|
4069
|
+
dataFlowPanel.styles,
|
|
4070
|
+
...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.styles]
|
|
4071
|
+
];
|
|
4072
|
+
const styleNonce = resolveStyleNonce(document);
|
|
4073
|
+
if (styleNonce !== void 0) {
|
|
4074
|
+
for (const style of styles2) {
|
|
4075
|
+
style.nonce = styleNonce;
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
shadowRoot.append(
|
|
4079
|
+
...styles2,
|
|
3920
4080
|
selectionHighlights,
|
|
3921
4081
|
highlight,
|
|
3922
4082
|
dialog,
|
|
@@ -3934,6 +4094,13 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3934
4094
|
let currentTargets = [];
|
|
3935
4095
|
let currentMaximum = 0;
|
|
3936
4096
|
let currentEditorFeedbackState = "idle";
|
|
4097
|
+
let currentDataFlowState = Object.freeze({
|
|
4098
|
+
component: Object.freeze({
|
|
4099
|
+
status: dataFlowEnabled ? "idle" : "disabled"
|
|
4100
|
+
}),
|
|
4101
|
+
page: Object.freeze({ status: dataFlowEnabled ? "idle" : "disabled" }),
|
|
4102
|
+
observationCount: 0
|
|
4103
|
+
});
|
|
3937
4104
|
function renderEditorStatus(state) {
|
|
3938
4105
|
currentEditorFeedbackState = state;
|
|
3939
4106
|
editorFeedback.dataset.state = state;
|
|
@@ -4191,6 +4358,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4191
4358
|
openEditorButton.disabled = !canOpenEditor;
|
|
4192
4359
|
previewButton.disabled = !canPreview;
|
|
4193
4360
|
agentPanel.setContextReady(canPreview);
|
|
4361
|
+
externalHandoffPanel?.setContextReady(canPreview);
|
|
4194
4362
|
updateContextOverview(summaryText);
|
|
4195
4363
|
placeDialog();
|
|
4196
4364
|
}
|
|
@@ -4207,6 +4375,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4207
4375
|
previewButton.hidden = !selected;
|
|
4208
4376
|
secondaryActions.hidden = !selected;
|
|
4209
4377
|
agentPanel.setSelectionVisible(selected);
|
|
4378
|
+
externalHandoffPanel?.setSelectionVisible(selected);
|
|
4210
4379
|
copyButton.hidden = !previewing;
|
|
4211
4380
|
backButton.hidden = !previewing;
|
|
4212
4381
|
title.textContent = previewing ? messages.dialog.previewTitle : messages.dialog.editTitle;
|
|
@@ -4235,6 +4404,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4235
4404
|
previewButton.textContent = messages.actions.preview;
|
|
4236
4405
|
copyButton.textContent = messages.actions.copy;
|
|
4237
4406
|
backButton.textContent = messages.actions.back;
|
|
4407
|
+
dataFlowPanel.render(currentDataFlowState);
|
|
4238
4408
|
triggerButton.title = messages.trigger.title(shortcut);
|
|
4239
4409
|
triggerButton.textContent = currentStatus === "inspecting" ? messages.trigger.stop : messages.trigger.select;
|
|
4240
4410
|
renderPanelStatus(currentStatus);
|
|
@@ -4273,6 +4443,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4273
4443
|
repositoryLink,
|
|
4274
4444
|
previewButton,
|
|
4275
4445
|
copyButton,
|
|
4446
|
+
dataFlowRefreshButton: dataFlowPanel.refreshButton,
|
|
4276
4447
|
backButton,
|
|
4277
4448
|
closeButton,
|
|
4278
4449
|
agentProviderSelect: agentPanel.providerSelect,
|
|
@@ -4286,6 +4457,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4286
4457
|
agentApplyButton: agentPanel.applyButton,
|
|
4287
4458
|
agentRevertButton: agentPanel.revertButton,
|
|
4288
4459
|
agentResetButton: agentPanel.resetButton,
|
|
4460
|
+
...externalHandoffPanel === void 0 ? {} : { externalHandoffPanel },
|
|
4289
4461
|
renderStatus(status) {
|
|
4290
4462
|
const inspecting = status === "inspecting";
|
|
4291
4463
|
triggerButton.setAttribute("aria-pressed", String(inspecting));
|
|
@@ -4293,6 +4465,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4293
4465
|
renderPanelStatus(status);
|
|
4294
4466
|
},
|
|
4295
4467
|
renderEditorStatus,
|
|
4468
|
+
renderDataFlow(state) {
|
|
4469
|
+
currentDataFlowState = state;
|
|
4470
|
+
dataFlowPanel.render(state);
|
|
4471
|
+
placeDialog();
|
|
4472
|
+
},
|
|
4296
4473
|
showHighlight(rect, label) {
|
|
4297
4474
|
currentRect = rect;
|
|
4298
4475
|
highlight.hidden = false;
|
|
@@ -4329,6 +4506,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4329
4506
|
currentCanPreview = enabled;
|
|
4330
4507
|
previewButton.disabled = !enabled;
|
|
4331
4508
|
agentPanel.setContextReady(enabled);
|
|
4509
|
+
externalHandoffPanel?.setContextReady(enabled);
|
|
4332
4510
|
},
|
|
4333
4511
|
hideSelection() {
|
|
4334
4512
|
dialog.hidden = true;
|
|
@@ -4353,8 +4531,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4353
4531
|
currentCanPreview = false;
|
|
4354
4532
|
agentPanel.setContextReady(false);
|
|
4355
4533
|
agentPanel.setSelectionVisible(false);
|
|
4534
|
+
externalHandoffPanel?.setContextReady(false);
|
|
4535
|
+
externalHandoffPanel?.setSelectionVisible(false);
|
|
4356
4536
|
agentPanel.setEditingEnabled(true);
|
|
4357
4537
|
agentPanel.resetJob();
|
|
4538
|
+
dataFlowPanel.resetView();
|
|
4358
4539
|
},
|
|
4359
4540
|
hideSelectionTemporarily() {
|
|
4360
4541
|
dialog.hidden = true;
|
|
@@ -4384,6 +4565,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4384
4565
|
});
|
|
4385
4566
|
openEditorButton.disabled = !currentCanOpenEditor;
|
|
4386
4567
|
previewButton.disabled = !enabled || !currentCanPreview;
|
|
4568
|
+
externalHandoffPanel?.setContextReady(enabled && currentCanPreview);
|
|
4387
4569
|
agentPanel.setEditingEnabled(enabled);
|
|
4388
4570
|
placeDialog();
|
|
4389
4571
|
},
|
|
@@ -4423,6 +4605,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
4423
4605
|
diagnostics.removeEventListener("toggle", placeDialog);
|
|
4424
4606
|
localeButton.removeEventListener("click", localizer.toggle);
|
|
4425
4607
|
unsubscribeLocale();
|
|
4608
|
+
dataFlowPanel.dispose();
|
|
4609
|
+
externalHandoffPanel?.dispose();
|
|
4426
4610
|
agentPanel.dispose();
|
|
4427
4611
|
host.remove();
|
|
4428
4612
|
}
|
|
@@ -4913,9 +5097,19 @@ function resolveBrowserDependencies(dependencies) {
|
|
|
4913
5097
|
}
|
|
4914
5098
|
function createController(config, dependencies = {}) {
|
|
4915
5099
|
const browser = resolveBrowserDependencies(dependencies);
|
|
4916
|
-
const view = dependencies.view ?? createRuntimeView(
|
|
5100
|
+
const view = dependencies.view ?? createRuntimeView(
|
|
5101
|
+
browser.document,
|
|
5102
|
+
config.shortcut,
|
|
5103
|
+
config.ai,
|
|
5104
|
+
config.locale,
|
|
5105
|
+
config.dataFlow.enabled,
|
|
5106
|
+
config.externalAgent.enabled,
|
|
5107
|
+
config.framework,
|
|
5108
|
+
config.sessionId
|
|
5109
|
+
);
|
|
4917
5110
|
const api = dependencies.api ?? createRuntimeApi({
|
|
4918
5111
|
apiBase: config.apiBase,
|
|
5112
|
+
dataFlowReportMaxBytes: config.dataFlow.limits.reportMaxBytes,
|
|
4919
5113
|
fetch: browser.window.fetch.bind(browser.window),
|
|
4920
5114
|
sessionToken: config.sessionToken
|
|
4921
5115
|
});
|
|
@@ -4927,6 +5121,9 @@ function createController(config, dependencies = {}) {
|
|
|
4927
5121
|
const restoredSelection = selectionSession.load();
|
|
4928
5122
|
const sourceResolver = createSourceResolver({
|
|
4929
5123
|
adapter: dependencies.reactAdapter ?? (0, import_react_adapter.createReact18Adapter)({
|
|
5124
|
+
...config.dataFlow.enabled ? {
|
|
5125
|
+
getComponentRegistration: (component) => getDataFlowExtension()?.getComponentRegistration(component)
|
|
5126
|
+
} : {},
|
|
4930
5127
|
maxComponentDepth: config.budget.maxComponentDepth
|
|
4931
5128
|
}),
|
|
4932
5129
|
onAdapterError() {
|
|
@@ -4950,6 +5147,8 @@ function createController(config, dependencies = {}) {
|
|
|
4950
5147
|
apiStatus: marker === void 0 ? "not-required" : target2.code === void 0 ? "failed" : "connected",
|
|
4951
5148
|
code: target2.code,
|
|
4952
5149
|
collectionStatus: "ready",
|
|
5150
|
+
dataFlowReport: void 0,
|
|
5151
|
+
dataFlowStatus: "idle",
|
|
4953
5152
|
element: void 0,
|
|
4954
5153
|
elementContext: target2.element,
|
|
4955
5154
|
instruction: target2.instruction,
|
|
@@ -4964,6 +5163,9 @@ function createController(config, dependencies = {}) {
|
|
|
4964
5163
|
let workflowSelectionActive = false;
|
|
4965
5164
|
let sessionRevision = 0;
|
|
4966
5165
|
let editorRequestRevision = 0;
|
|
5166
|
+
let dataFlowRequestRevision = 0;
|
|
5167
|
+
let pageDataFlowReport;
|
|
5168
|
+
let pageDataFlowStatus = "idle";
|
|
4967
5169
|
let addingTarget = false;
|
|
4968
5170
|
let previewPrompt = "";
|
|
4969
5171
|
let previousFocus;
|
|
@@ -4978,6 +5180,90 @@ function createController(config, dependencies = {}) {
|
|
|
4978
5180
|
function activeTarget() {
|
|
4979
5181
|
return targets.find((target2) => target2.id === activeTargetId) ?? targets.at(-1);
|
|
4980
5182
|
}
|
|
5183
|
+
function dataFlowRequest(target2) {
|
|
5184
|
+
const react2 = target2.resolution.react;
|
|
5185
|
+
if (react2.componentSourceId !== void 0 && react2.sourceVersion !== void 0) {
|
|
5186
|
+
return Object.freeze({
|
|
5187
|
+
schemaVersion: import_shared9.DATA_FLOW_SCHEMA_VERSION,
|
|
5188
|
+
componentSourceId: react2.componentSourceId,
|
|
5189
|
+
sourceVersion: react2.sourceVersion
|
|
5190
|
+
});
|
|
5191
|
+
}
|
|
5192
|
+
const marker = target2.marker;
|
|
5193
|
+
return marker === void 0 ? void 0 : Object.freeze({
|
|
5194
|
+
schemaVersion: import_shared9.DATA_FLOW_SCHEMA_VERSION,
|
|
5195
|
+
fileId: marker.fileId,
|
|
5196
|
+
line: marker.line,
|
|
5197
|
+
column: marker.column
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
function renderDataFlowView() {
|
|
5201
|
+
const dataFlowClient = getDataFlowExtension();
|
|
5202
|
+
const observations = dataFlowClient?.observations(browser.window.location.pathname) ?? [];
|
|
5203
|
+
const current = activeTarget();
|
|
5204
|
+
view.renderDataFlow({
|
|
5205
|
+
component: Object.freeze({
|
|
5206
|
+
status: config.dataFlow.enabled ? current?.dataFlowStatus ?? "idle" : "disabled",
|
|
5207
|
+
...current?.dataFlowReport === void 0 ? {} : {
|
|
5208
|
+
report: dataFlowClient?.mergeComponentReport(
|
|
5209
|
+
current.dataFlowReport,
|
|
5210
|
+
observations
|
|
5211
|
+
) ?? current.dataFlowReport
|
|
5212
|
+
}
|
|
5213
|
+
}),
|
|
5214
|
+
page: Object.freeze({
|
|
5215
|
+
status: config.dataFlow.enabled ? pageDataFlowStatus : "disabled",
|
|
5216
|
+
...pageDataFlowReport === void 0 ? {} : {
|
|
5217
|
+
report: dataFlowClient?.mergePageReport(pageDataFlowReport, observations) ?? pageDataFlowReport
|
|
5218
|
+
}
|
|
5219
|
+
}),
|
|
5220
|
+
observationCount: observations.length
|
|
5221
|
+
});
|
|
5222
|
+
}
|
|
5223
|
+
async function loadDataFlowReports() {
|
|
5224
|
+
if (!config.dataFlow.enabled) {
|
|
5225
|
+
renderDataFlowView();
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
5228
|
+
const current = activeTarget();
|
|
5229
|
+
const currentRequest = current === void 0 ? void 0 : dataFlowRequest(current);
|
|
5230
|
+
const pageTargets = targets.flatMap((target2) => {
|
|
5231
|
+
const request = dataFlowRequest(target2);
|
|
5232
|
+
return request === void 0 ? [] : [request];
|
|
5233
|
+
});
|
|
5234
|
+
const revision = ++dataFlowRequestRevision;
|
|
5235
|
+
const selectionRevision = sessionRevision;
|
|
5236
|
+
if (current !== void 0) current.dataFlowStatus = "loading";
|
|
5237
|
+
pageDataFlowStatus = pageTargets.length === 0 ? "idle" : "loading";
|
|
5238
|
+
renderDataFlowView();
|
|
5239
|
+
const [componentResult, pageResult] = await Promise.allSettled([
|
|
5240
|
+
currentRequest === void 0 ? Promise.resolve(void 0) : api.componentDataFlowReport(currentRequest),
|
|
5241
|
+
pageTargets.length === 0 ? Promise.resolve(void 0) : api.pageDataFlowReport({
|
|
5242
|
+
schemaVersion: import_shared9.DATA_FLOW_SCHEMA_VERSION,
|
|
5243
|
+
targets: pageTargets
|
|
5244
|
+
})
|
|
5245
|
+
]);
|
|
5246
|
+
if (!mounted || revision !== dataFlowRequestRevision || selectionRevision !== sessionRevision) {
|
|
5247
|
+
return;
|
|
5248
|
+
}
|
|
5249
|
+
if (current !== void 0 && targets.includes(current)) {
|
|
5250
|
+
if (componentResult.status === "fulfilled") {
|
|
5251
|
+
current.dataFlowReport = componentResult.value;
|
|
5252
|
+
current.dataFlowStatus = componentResult.value === void 0 ? "idle" : "ready";
|
|
5253
|
+
} else {
|
|
5254
|
+
current.dataFlowReport = void 0;
|
|
5255
|
+
current.dataFlowStatus = "error";
|
|
5256
|
+
}
|
|
5257
|
+
}
|
|
5258
|
+
if (pageResult.status === "fulfilled") {
|
|
5259
|
+
pageDataFlowReport = pageResult.value;
|
|
5260
|
+
pageDataFlowStatus = pageResult.value === void 0 ? "idle" : "ready";
|
|
5261
|
+
} else {
|
|
5262
|
+
pageDataFlowReport = void 0;
|
|
5263
|
+
pageDataFlowStatus = "error";
|
|
5264
|
+
}
|
|
5265
|
+
renderDataFlowView();
|
|
5266
|
+
}
|
|
4981
5267
|
function snapshotTarget(target2) {
|
|
4982
5268
|
if (target2.elementContext === void 0 || target2.styles === void 0) {
|
|
4983
5269
|
return void 0;
|
|
@@ -5142,10 +5428,14 @@ ${summary}`;
|
|
|
5142
5428
|
sessionRevision += 1;
|
|
5143
5429
|
api.cancelPending();
|
|
5144
5430
|
agentWorkflow.disposeSelection();
|
|
5431
|
+
externalHandoffWorkflow?.cancelPending();
|
|
5145
5432
|
clearCollectionTimers();
|
|
5146
5433
|
resizeObserver?.disconnect();
|
|
5147
5434
|
targets = [];
|
|
5148
5435
|
activeTargetId = void 0;
|
|
5436
|
+
dataFlowRequestRevision += 1;
|
|
5437
|
+
pageDataFlowReport = void 0;
|
|
5438
|
+
pageDataFlowStatus = "idle";
|
|
5149
5439
|
selectionOpen = false;
|
|
5150
5440
|
workflowSelectionActive = false;
|
|
5151
5441
|
addingTarget = false;
|
|
@@ -5200,6 +5490,7 @@ ${summary}`;
|
|
|
5200
5490
|
workflowSelectionActive = true;
|
|
5201
5491
|
}
|
|
5202
5492
|
refreshSelectionView(true);
|
|
5493
|
+
void loadDataFlowReports();
|
|
5203
5494
|
view.focusTargetInstruction(activeTargetId);
|
|
5204
5495
|
persistSelection();
|
|
5205
5496
|
return;
|
|
@@ -5256,6 +5547,13 @@ ${summary}`;
|
|
|
5256
5547
|
},
|
|
5257
5548
|
view
|
|
5258
5549
|
});
|
|
5550
|
+
const externalHandoffWorkflow = config.externalAgent.enabled && view.externalHandoffPanel !== void 0 ? getExternalHandoffExtension()?.createWorkflow(
|
|
5551
|
+
browser.window.fetch.bind(browser.window),
|
|
5552
|
+
view.externalHandoffPanel,
|
|
5553
|
+
selectedAnnotation,
|
|
5554
|
+
config.sessionToken,
|
|
5555
|
+
browser.window
|
|
5556
|
+
) : void 0;
|
|
5259
5557
|
async function loadSourceContext(target2, revision) {
|
|
5260
5558
|
const marker = target2.marker;
|
|
5261
5559
|
if (marker === void 0) {
|
|
@@ -5350,6 +5648,7 @@ ${summary}`;
|
|
|
5350
5648
|
transition({ type: "SELECT" });
|
|
5351
5649
|
view.hideHighlight();
|
|
5352
5650
|
refreshSelectionView(true);
|
|
5651
|
+
void loadDataFlowReports();
|
|
5353
5652
|
view.focusTargetInstruction(duplicate.id);
|
|
5354
5653
|
view.announce(view.messages().announcements.duplicate);
|
|
5355
5654
|
return;
|
|
@@ -5381,7 +5680,9 @@ ${summary}`;
|
|
|
5381
5680
|
styles: void 0,
|
|
5382
5681
|
instruction: "",
|
|
5383
5682
|
apiStatus: marker === void 0 ? "not-required" : "loading",
|
|
5384
|
-
collectionStatus: "loading"
|
|
5683
|
+
collectionStatus: "loading",
|
|
5684
|
+
dataFlowReport: void 0,
|
|
5685
|
+
dataFlowStatus: "idle"
|
|
5385
5686
|
};
|
|
5386
5687
|
targets.push(target2);
|
|
5387
5688
|
activeTargetId = target2.id;
|
|
@@ -5391,6 +5692,7 @@ ${summary}`;
|
|
|
5391
5692
|
view.hideHighlight();
|
|
5392
5693
|
resizeObserver?.observe(element2);
|
|
5393
5694
|
refreshSelectionView(true);
|
|
5695
|
+
void loadDataFlowReports();
|
|
5394
5696
|
selectionOpen = true;
|
|
5395
5697
|
view.focusTargetInstruction(target2.id);
|
|
5396
5698
|
scheduleBrowserContextCollection(target2, revision);
|
|
@@ -5495,11 +5797,15 @@ ${summary}`;
|
|
|
5495
5797
|
}
|
|
5496
5798
|
view.hideSelectionTemporarily();
|
|
5497
5799
|
view.hideSelectionHighlights();
|
|
5800
|
+
pageDataFlowReport = void 0;
|
|
5801
|
+
pageDataFlowStatus = "idle";
|
|
5802
|
+
renderDataFlowView();
|
|
5498
5803
|
selectionSession.clear();
|
|
5499
5804
|
view.announce(view.messages().announcements.allTargetsRemoved);
|
|
5500
5805
|
return;
|
|
5501
5806
|
}
|
|
5502
5807
|
refreshSelectionView();
|
|
5808
|
+
void loadDataFlowReports();
|
|
5503
5809
|
persistSelection();
|
|
5504
5810
|
view.announce(view.messages().announcements.targetRemoved);
|
|
5505
5811
|
}
|
|
@@ -5662,16 +5968,21 @@ ${summary}`;
|
|
|
5662
5968
|
}
|
|
5663
5969
|
activeTargetId = targetId;
|
|
5664
5970
|
refreshSelectionView();
|
|
5971
|
+
void loadDataFlowReports();
|
|
5665
5972
|
view.focusTargetInstruction(targetId);
|
|
5666
5973
|
}
|
|
5667
5974
|
function handleReselect() {
|
|
5668
5975
|
beginReselect();
|
|
5669
5976
|
}
|
|
5977
|
+
function handleDataFlowRefresh() {
|
|
5978
|
+
void loadDataFlowReports();
|
|
5979
|
+
}
|
|
5670
5980
|
function mount() {
|
|
5671
5981
|
if (mounted) {
|
|
5672
5982
|
return;
|
|
5673
5983
|
}
|
|
5674
5984
|
mounted = true;
|
|
5985
|
+
externalHandoffWorkflow?.mount();
|
|
5675
5986
|
view.renderStatus(state.status);
|
|
5676
5987
|
browser.document.addEventListener("pointermove", handlePointerMove, true);
|
|
5677
5988
|
browser.document.addEventListener("click", handleClick, true);
|
|
@@ -5685,6 +5996,7 @@ ${summary}`;
|
|
|
5685
5996
|
view.targetList.addEventListener("input", handleTargetListInput);
|
|
5686
5997
|
view.targetList.addEventListener("keydown", handleTargetListKeydown);
|
|
5687
5998
|
view.openEditorButton.addEventListener("click", handleOpenEditorButtonClick);
|
|
5999
|
+
view.dataFlowRefreshButton.addEventListener("click", handleDataFlowRefresh);
|
|
5688
6000
|
view.previewButton.addEventListener("click", handlePreview);
|
|
5689
6001
|
view.copyButton.addEventListener("click", handleCopy);
|
|
5690
6002
|
view.backButton.addEventListener("click", handleBack);
|
|
@@ -5737,6 +6049,7 @@ ${summary}`;
|
|
|
5737
6049
|
api.cancelPending();
|
|
5738
6050
|
api.dispose();
|
|
5739
6051
|
agentWorkflow.disposeSelection();
|
|
6052
|
+
externalHandoffWorkflow?.dispose();
|
|
5740
6053
|
sourceResolver.dispose();
|
|
5741
6054
|
return;
|
|
5742
6055
|
}
|
|
@@ -5755,6 +6068,7 @@ ${summary}`;
|
|
|
5755
6068
|
view.targetList.removeEventListener("input", handleTargetListInput);
|
|
5756
6069
|
view.targetList.removeEventListener("keydown", handleTargetListKeydown);
|
|
5757
6070
|
view.openEditorButton.removeEventListener("click", handleOpenEditorButtonClick);
|
|
6071
|
+
view.dataFlowRefreshButton.removeEventListener("click", handleDataFlowRefresh);
|
|
5758
6072
|
view.previewButton.removeEventListener("click", handlePreview);
|
|
5759
6073
|
view.copyButton.removeEventListener("click", handleCopy);
|
|
5760
6074
|
view.backButton.removeEventListener("click", handleBack);
|
|
@@ -5799,6 +6113,7 @@ ${summary}`;
|
|
|
5799
6113
|
api.cancelPending();
|
|
5800
6114
|
api.dispose();
|
|
5801
6115
|
agentWorkflow.disposeSelection();
|
|
6116
|
+
externalHandoffWorkflow?.dispose();
|
|
5802
6117
|
sourceResolver.dispose();
|
|
5803
6118
|
view.dispose();
|
|
5804
6119
|
state = INITIAL_RUNTIME_STATE;
|
|
@@ -5815,9 +6130,551 @@ function bootstrapSpotPatch(config) {
|
|
|
5815
6130
|
target2[RUNTIME_INSTANCE_KEY] = controller;
|
|
5816
6131
|
controller.mount();
|
|
5817
6132
|
}
|
|
6133
|
+
|
|
6134
|
+
// src/data-flow/data-flow-runtime.ts
|
|
6135
|
+
var import_data_flow_runtime = require("@spotpatch/shared/data-flow-runtime");
|
|
6136
|
+
var RUNTIME_KEY = /* @__PURE__ */ Symbol.for(
|
|
6137
|
+
"spotpatch.data-flow.runtime.v1"
|
|
6138
|
+
);
|
|
6139
|
+
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
6140
|
+
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
6141
|
+
function positiveNow(target2) {
|
|
6142
|
+
return target2.performance?.now() ?? Date.now();
|
|
6143
|
+
}
|
|
6144
|
+
function createOpaqueSequence(prefix) {
|
|
6145
|
+
let sequence = 0;
|
|
6146
|
+
const randomPrefix = (() => {
|
|
6147
|
+
try {
|
|
6148
|
+
const bytes = new Uint8Array(8);
|
|
6149
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
6150
|
+
return Array.from(bytes, (value) => value.toString(36).padStart(2, "0")).join("");
|
|
6151
|
+
} catch {
|
|
6152
|
+
return "local";
|
|
6153
|
+
}
|
|
6154
|
+
})();
|
|
6155
|
+
return () => {
|
|
6156
|
+
sequence += 1;
|
|
6157
|
+
return `${prefix}_${randomPrefix}_${sequence.toString(36)}`;
|
|
6158
|
+
};
|
|
6159
|
+
}
|
|
6160
|
+
function freezeUrl(value, baseUrl) {
|
|
6161
|
+
try {
|
|
6162
|
+
const url = new URL(value, baseUrl);
|
|
6163
|
+
return Object.freeze({
|
|
6164
|
+
origin: url.origin,
|
|
6165
|
+
pathname: url.pathname,
|
|
6166
|
+
queryKeys: Object.freeze(
|
|
6167
|
+
[...new Set(url.searchParams.keys())].sort().slice(0, import_data_flow_runtime.DATA_FLOW_URL_QUERY_KEY_LIMIT)
|
|
6168
|
+
)
|
|
6169
|
+
});
|
|
6170
|
+
} catch {
|
|
6171
|
+
return Object.freeze({
|
|
6172
|
+
pathname: value.split(/[?#]/u, 1)[0] ?? "{invalid}",
|
|
6173
|
+
queryKeys: Object.freeze([])
|
|
6174
|
+
});
|
|
6175
|
+
}
|
|
6176
|
+
}
|
|
6177
|
+
function readFetchUrl(input) {
|
|
6178
|
+
if (typeof input === "string") return input;
|
|
6179
|
+
if (input instanceof URL) return input.toString();
|
|
6180
|
+
return input.url;
|
|
6181
|
+
}
|
|
6182
|
+
function readFetchMethod(input, init) {
|
|
6183
|
+
if (init?.method !== void 0) return init.method.toUpperCase();
|
|
6184
|
+
return typeof Request !== "undefined" && input instanceof Request ? input.method.toUpperCase() : "GET";
|
|
6185
|
+
}
|
|
6186
|
+
function isSpotPatchInternalUrl(value, baseUrl) {
|
|
6187
|
+
try {
|
|
6188
|
+
const pathname = new URL(value, baseUrl).pathname;
|
|
6189
|
+
return pathname === import_data_flow_runtime.SPOTPATCH_API_BASE || pathname.startsWith(`${import_data_flow_runtime.SPOTPATCH_API_BASE}/`);
|
|
6190
|
+
} catch {
|
|
6191
|
+
return false;
|
|
6192
|
+
}
|
|
6193
|
+
}
|
|
6194
|
+
function approximateBytes(value) {
|
|
6195
|
+
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
6196
|
+
}
|
|
6197
|
+
function createRingStore(limits, target2) {
|
|
6198
|
+
const entries = [];
|
|
6199
|
+
let totalBytes = 0;
|
|
6200
|
+
function removeExpired(now) {
|
|
6201
|
+
while (entries[0] !== void 0 && now - entries[0].recordedAt > limits.observationTtlMs) {
|
|
6202
|
+
const removed = entries.shift();
|
|
6203
|
+
if (removed !== void 0) totalBytes -= removed.bytes;
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
return Object.freeze({
|
|
6207
|
+
add(observation) {
|
|
6208
|
+
const now = positiveNow(target2);
|
|
6209
|
+
removeExpired(now);
|
|
6210
|
+
const bytes = approximateBytes(observation);
|
|
6211
|
+
if (bytes > limits.observationMaxBytes) return;
|
|
6212
|
+
entries.push(Object.freeze({ bytes, observation, recordedAt: now }));
|
|
6213
|
+
totalBytes += bytes;
|
|
6214
|
+
while (entries.length > limits.observationMaxEntries || totalBytes > limits.observationMaxBytes) {
|
|
6215
|
+
const removed = entries.shift();
|
|
6216
|
+
if (removed !== void 0) totalBytes -= removed.bytes;
|
|
6217
|
+
}
|
|
6218
|
+
},
|
|
6219
|
+
clear() {
|
|
6220
|
+
entries.length = 0;
|
|
6221
|
+
totalBytes = 0;
|
|
6222
|
+
},
|
|
6223
|
+
values() {
|
|
6224
|
+
removeExpired(positiveNow(target2));
|
|
6225
|
+
return Object.freeze(entries.map(({ observation }) => observation));
|
|
6226
|
+
}
|
|
6227
|
+
});
|
|
6228
|
+
}
|
|
6229
|
+
function ownPropertyDescriptor(target2, key) {
|
|
6230
|
+
try {
|
|
6231
|
+
return Object.getOwnPropertyDescriptor(target2, key);
|
|
6232
|
+
} catch {
|
|
6233
|
+
return void 0;
|
|
6234
|
+
}
|
|
6235
|
+
}
|
|
6236
|
+
function nestedReactWrapperComponent(candidate) {
|
|
6237
|
+
const marker = ownPropertyDescriptor(candidate, "$$typeof")?.value;
|
|
6238
|
+
const key = marker === REACT_MEMO_TYPE ? "type" : marker === REACT_FORWARD_REF_TYPE ? "render" : void 0;
|
|
6239
|
+
if (key === void 0) return void 0;
|
|
6240
|
+
const nested = ownPropertyDescriptor(candidate, key)?.value;
|
|
6241
|
+
return typeof nested === "object" && nested !== null || typeof nested === "function" ? nested : void 0;
|
|
6242
|
+
}
|
|
6243
|
+
function installWritableDataProperty(target2, key, replacement, original = ownPropertyDescriptor(target2, key)) {
|
|
6244
|
+
if (original === void 0 || !("value" in original) || !original.writable) {
|
|
6245
|
+
return void 0;
|
|
6246
|
+
}
|
|
6247
|
+
try {
|
|
6248
|
+
Object.defineProperty(target2, key, { ...original, value: replacement });
|
|
6249
|
+
} catch {
|
|
6250
|
+
return void 0;
|
|
6251
|
+
}
|
|
6252
|
+
return () => {
|
|
6253
|
+
try {
|
|
6254
|
+
if (ownPropertyDescriptor(target2, key)?.value === replacement) {
|
|
6255
|
+
Object.defineProperty(target2, key, original);
|
|
6256
|
+
}
|
|
6257
|
+
} catch {
|
|
6258
|
+
}
|
|
6259
|
+
};
|
|
6260
|
+
}
|
|
6261
|
+
function recordWithoutAffectingHost(record2) {
|
|
6262
|
+
try {
|
|
6263
|
+
record2();
|
|
6264
|
+
} catch {
|
|
6265
|
+
}
|
|
6266
|
+
}
|
|
6267
|
+
function createDataFlowRuntime(config, target2 = globalThis) {
|
|
6268
|
+
const componentRegistry = /* @__PURE__ */ new WeakMap();
|
|
6269
|
+
const xhrMetadata = /* @__PURE__ */ new WeakMap();
|
|
6270
|
+
const store = createRingStore(config.limits, target2);
|
|
6271
|
+
const nextInvocationId = createOpaqueSequence("invocation");
|
|
6272
|
+
const nextObservationId = createOpaqueSequence("observation");
|
|
6273
|
+
const pageEpoch = createOpaqueSequence("page")();
|
|
6274
|
+
const nextRouteEpoch = createOpaqueSequence("route");
|
|
6275
|
+
let routeEpoch = nextRouteEpoch();
|
|
6276
|
+
let routeKey;
|
|
6277
|
+
let currentInvocation;
|
|
6278
|
+
let currentRequestFrame;
|
|
6279
|
+
let disposed = false;
|
|
6280
|
+
const originalFetch = (() => {
|
|
6281
|
+
try {
|
|
6282
|
+
return target2.fetch;
|
|
6283
|
+
} catch {
|
|
6284
|
+
return void 0;
|
|
6285
|
+
}
|
|
6286
|
+
})();
|
|
6287
|
+
function spotPatchFetch(input, init) {
|
|
6288
|
+
if (originalFetch === void 0) {
|
|
6289
|
+
throw new TypeError("Fetch is unavailable.");
|
|
6290
|
+
}
|
|
6291
|
+
const result = Reflect.apply(originalFetch, this, [input, init]);
|
|
6292
|
+
recordWithoutAffectingHost(() => {
|
|
6293
|
+
const frame = currentRequestFrame;
|
|
6294
|
+
const token = frame?.invocationToken;
|
|
6295
|
+
const rawUrl = readFetchUrl(input);
|
|
6296
|
+
if (isSpotPatchInternalUrl(
|
|
6297
|
+
rawUrl,
|
|
6298
|
+
target2.location?.href ?? "http://spotpatch.invalid/"
|
|
6299
|
+
)) {
|
|
6300
|
+
return;
|
|
6301
|
+
}
|
|
6302
|
+
store.add(
|
|
6303
|
+
Object.freeze({
|
|
6304
|
+
schemaVersion: import_data_flow_runtime.DATA_FLOW_SCHEMA_VERSION,
|
|
6305
|
+
id: nextObservationId(),
|
|
6306
|
+
pageEpoch,
|
|
6307
|
+
routeEpoch,
|
|
6308
|
+
...frame === void 0 ? {} : {
|
|
6309
|
+
requestCallsiteId: frame.requestCallsiteId,
|
|
6310
|
+
sourceVersion: frame.sourceVersion
|
|
6311
|
+
},
|
|
6312
|
+
...token === void 0 ? {} : {
|
|
6313
|
+
invocationId: token.invocationId,
|
|
6314
|
+
componentSourceId: token.componentSourceId,
|
|
6315
|
+
triggerCallsiteId: token.triggerCallsiteId
|
|
6316
|
+
},
|
|
6317
|
+
transport: "fetch",
|
|
6318
|
+
method: readFetchMethod(input, init),
|
|
6319
|
+
url: freezeUrl(rawUrl, target2.location?.href ?? "http://spotpatch.invalid/"),
|
|
6320
|
+
outcome: "dispatched",
|
|
6321
|
+
freshness: "current",
|
|
6322
|
+
diagnosticIds: Object.freeze([])
|
|
6323
|
+
})
|
|
6324
|
+
);
|
|
6325
|
+
});
|
|
6326
|
+
return result;
|
|
6327
|
+
}
|
|
6328
|
+
const restoreFetch = originalFetch === void 0 ? void 0 : installWritableDataProperty(target2, "fetch", spotPatchFetch);
|
|
6329
|
+
const xhrPrototype = (() => {
|
|
6330
|
+
try {
|
|
6331
|
+
return target2.XMLHttpRequest?.prototype;
|
|
6332
|
+
} catch {
|
|
6333
|
+
return void 0;
|
|
6334
|
+
}
|
|
6335
|
+
})();
|
|
6336
|
+
const originalOpenDescriptor = xhrPrototype === void 0 ? void 0 : ownPropertyDescriptor(xhrPrototype, "open");
|
|
6337
|
+
const originalSendDescriptor = xhrPrototype === void 0 ? void 0 : ownPropertyDescriptor(xhrPrototype, "send");
|
|
6338
|
+
function spotPatchOpen(method, url, ...rest) {
|
|
6339
|
+
const original = originalOpenDescriptor?.value;
|
|
6340
|
+
if (typeof original === "function") {
|
|
6341
|
+
Reflect.apply(original, this, [method, url, ...rest]);
|
|
6342
|
+
}
|
|
6343
|
+
recordWithoutAffectingHost(() => {
|
|
6344
|
+
xhrMetadata.set(this, Object.freeze({ method, url: String(url) }));
|
|
6345
|
+
});
|
|
6346
|
+
}
|
|
6347
|
+
function spotPatchSend(body) {
|
|
6348
|
+
const original = originalSendDescriptor?.value;
|
|
6349
|
+
if (typeof original === "function") Reflect.apply(original, this, [body]);
|
|
6350
|
+
recordWithoutAffectingHost(() => {
|
|
6351
|
+
const metadata = xhrMetadata.get(this);
|
|
6352
|
+
if (metadata === void 0 || isSpotPatchInternalUrl(
|
|
6353
|
+
metadata.url,
|
|
6354
|
+
target2.location?.href ?? "http://spotpatch.invalid/"
|
|
6355
|
+
)) {
|
|
6356
|
+
return;
|
|
6357
|
+
}
|
|
6358
|
+
const frame = currentRequestFrame;
|
|
6359
|
+
const token = frame?.invocationToken;
|
|
6360
|
+
store.add(
|
|
6361
|
+
Object.freeze({
|
|
6362
|
+
schemaVersion: import_data_flow_runtime.DATA_FLOW_SCHEMA_VERSION,
|
|
6363
|
+
id: nextObservationId(),
|
|
6364
|
+
pageEpoch,
|
|
6365
|
+
routeEpoch,
|
|
6366
|
+
...frame === void 0 ? {} : {
|
|
6367
|
+
requestCallsiteId: frame.requestCallsiteId,
|
|
6368
|
+
sourceVersion: frame.sourceVersion
|
|
6369
|
+
},
|
|
6370
|
+
...token === void 0 ? {} : {
|
|
6371
|
+
invocationId: token.invocationId,
|
|
6372
|
+
componentSourceId: token.componentSourceId,
|
|
6373
|
+
triggerCallsiteId: token.triggerCallsiteId
|
|
6374
|
+
},
|
|
6375
|
+
transport: "xhr",
|
|
6376
|
+
method: metadata.method.toUpperCase(),
|
|
6377
|
+
url: freezeUrl(
|
|
6378
|
+
metadata.url,
|
|
6379
|
+
target2.location?.href ?? "http://spotpatch.invalid/"
|
|
6380
|
+
),
|
|
6381
|
+
outcome: "dispatched",
|
|
6382
|
+
freshness: "current",
|
|
6383
|
+
diagnosticIds: Object.freeze([])
|
|
6384
|
+
})
|
|
6385
|
+
);
|
|
6386
|
+
});
|
|
6387
|
+
}
|
|
6388
|
+
const restoreXhrOpen = xhrPrototype === void 0 || typeof originalOpenDescriptor?.value !== "function" ? void 0 : installWritableDataProperty(
|
|
6389
|
+
xhrPrototype,
|
|
6390
|
+
"open",
|
|
6391
|
+
spotPatchOpen,
|
|
6392
|
+
originalOpenDescriptor
|
|
6393
|
+
);
|
|
6394
|
+
const restoreXhrSend = xhrPrototype === void 0 || typeof originalSendDescriptor?.value !== "function" ? void 0 : installWritableDataProperty(
|
|
6395
|
+
xhrPrototype,
|
|
6396
|
+
"send",
|
|
6397
|
+
spotPatchSend,
|
|
6398
|
+
originalSendDescriptor
|
|
6399
|
+
);
|
|
6400
|
+
const runtime = Object.freeze({
|
|
6401
|
+
beginInvocation(metadata) {
|
|
6402
|
+
return Object.freeze({
|
|
6403
|
+
invocationId: nextInvocationId(),
|
|
6404
|
+
componentSourceId: metadata.componentSourceId,
|
|
6405
|
+
triggerCallsiteId: metadata.triggerCallsiteId,
|
|
6406
|
+
sourceVersion: metadata.sourceVersion
|
|
6407
|
+
});
|
|
6408
|
+
},
|
|
6409
|
+
bindInvocation(token, callback) {
|
|
6410
|
+
return function boundInvocation(...args) {
|
|
6411
|
+
return runtime.withInvocation(token, () => Reflect.apply(callback, this, args));
|
|
6412
|
+
};
|
|
6413
|
+
},
|
|
6414
|
+
bindTrigger(metadata, callback) {
|
|
6415
|
+
if (typeof callback !== "function") return callback;
|
|
6416
|
+
const callable = callback;
|
|
6417
|
+
return function boundTrigger(...args) {
|
|
6418
|
+
const token = runtime.beginInvocation(metadata);
|
|
6419
|
+
return runtime.withInvocation(token, () => Reflect.apply(callable, this, args));
|
|
6420
|
+
};
|
|
6421
|
+
},
|
|
6422
|
+
captureInvocation: () => currentInvocation,
|
|
6423
|
+
clear: store.clear,
|
|
6424
|
+
createTrpcLink() {
|
|
6425
|
+
return () => (options) => {
|
|
6426
|
+
recordWithoutAffectingHost(() => {
|
|
6427
|
+
const operation = options.op.path;
|
|
6428
|
+
const operationType = options.op.type;
|
|
6429
|
+
if (typeof operation !== "string" || operation.length === 0 || operation.length > 512 || operationType !== "query" && operationType !== "mutation" && operationType !== "subscription") {
|
|
6430
|
+
return;
|
|
6431
|
+
}
|
|
6432
|
+
const frame = currentRequestFrame;
|
|
6433
|
+
const token = frame?.invocationToken;
|
|
6434
|
+
store.add(
|
|
6435
|
+
Object.freeze({
|
|
6436
|
+
schemaVersion: import_data_flow_runtime.DATA_FLOW_SCHEMA_VERSION,
|
|
6437
|
+
id: nextObservationId(),
|
|
6438
|
+
pageEpoch,
|
|
6439
|
+
routeEpoch,
|
|
6440
|
+
...frame === void 0 ? {} : {
|
|
6441
|
+
requestCallsiteId: frame.requestCallsiteId,
|
|
6442
|
+
sourceVersion: frame.sourceVersion
|
|
6443
|
+
},
|
|
6444
|
+
...token === void 0 ? {} : {
|
|
6445
|
+
invocationId: token.invocationId,
|
|
6446
|
+
componentSourceId: token.componentSourceId,
|
|
6447
|
+
triggerCallsiteId: token.triggerCallsiteId
|
|
6448
|
+
},
|
|
6449
|
+
transport: "trpc",
|
|
6450
|
+
method: operationType.toUpperCase(),
|
|
6451
|
+
operation,
|
|
6452
|
+
url: Object.freeze({
|
|
6453
|
+
pathname: operation,
|
|
6454
|
+
queryKeys: Object.freeze([])
|
|
6455
|
+
}),
|
|
6456
|
+
outcome: "dispatched",
|
|
6457
|
+
freshness: "current",
|
|
6458
|
+
diagnosticIds: Object.freeze([])
|
|
6459
|
+
})
|
|
6460
|
+
);
|
|
6461
|
+
});
|
|
6462
|
+
return options.next(options.op);
|
|
6463
|
+
};
|
|
6464
|
+
},
|
|
6465
|
+
dispose() {
|
|
6466
|
+
if (disposed) return;
|
|
6467
|
+
disposed = true;
|
|
6468
|
+
store.clear();
|
|
6469
|
+
restoreFetch?.();
|
|
6470
|
+
restoreXhrOpen?.();
|
|
6471
|
+
restoreXhrSend?.();
|
|
6472
|
+
},
|
|
6473
|
+
getComponentRegistration: (component) => componentRegistry.get(component),
|
|
6474
|
+
getCurrentRequestFrame: () => currentRequestFrame,
|
|
6475
|
+
observations: () => Object.freeze(
|
|
6476
|
+
store.values().map(
|
|
6477
|
+
(observation) => observation.routeEpoch === routeEpoch ? observation : Object.freeze({ ...observation, freshness: "stale-route" })
|
|
6478
|
+
)
|
|
6479
|
+
),
|
|
6480
|
+
registerComponent(component, componentSourceId, registeredSourceVersion) {
|
|
6481
|
+
const registration = Object.freeze({
|
|
6482
|
+
componentSourceId,
|
|
6483
|
+
sourceVersion: registeredSourceVersion
|
|
6484
|
+
});
|
|
6485
|
+
const pending = [component];
|
|
6486
|
+
const registered = /* @__PURE__ */ new Set();
|
|
6487
|
+
while (pending.length > 0) {
|
|
6488
|
+
const candidate = pending.pop();
|
|
6489
|
+
if (candidate === void 0 || registered.has(candidate)) continue;
|
|
6490
|
+
registered.add(candidate);
|
|
6491
|
+
componentRegistry.set(candidate, registration);
|
|
6492
|
+
const nested = nestedReactWrapperComponent(candidate);
|
|
6493
|
+
if (nested !== void 0) pending.push(nested);
|
|
6494
|
+
}
|
|
6495
|
+
},
|
|
6496
|
+
updateRoute(nextRouteKey) {
|
|
6497
|
+
if (routeKey === void 0) {
|
|
6498
|
+
routeKey = nextRouteKey;
|
|
6499
|
+
} else if (routeKey !== nextRouteKey) {
|
|
6500
|
+
routeKey = nextRouteKey;
|
|
6501
|
+
routeEpoch = nextRouteEpoch();
|
|
6502
|
+
}
|
|
6503
|
+
},
|
|
6504
|
+
withInvocation(token, callback) {
|
|
6505
|
+
const parent = currentInvocation;
|
|
6506
|
+
currentInvocation = token;
|
|
6507
|
+
try {
|
|
6508
|
+
return callback();
|
|
6509
|
+
} finally {
|
|
6510
|
+
currentInvocation = parent;
|
|
6511
|
+
}
|
|
6512
|
+
},
|
|
6513
|
+
withRequestFrame(token, metadata, callback) {
|
|
6514
|
+
const parent = currentRequestFrame;
|
|
6515
|
+
currentRequestFrame = Object.freeze({
|
|
6516
|
+
requestCallsiteId: metadata.requestCallsiteId,
|
|
6517
|
+
sourceVersion: metadata.sourceVersion,
|
|
6518
|
+
...token === void 0 ? {} : { invocationToken: token }
|
|
6519
|
+
});
|
|
6520
|
+
try {
|
|
6521
|
+
return callback();
|
|
6522
|
+
} finally {
|
|
6523
|
+
currentRequestFrame = parent;
|
|
6524
|
+
}
|
|
6525
|
+
}
|
|
6526
|
+
});
|
|
6527
|
+
return runtime;
|
|
6528
|
+
}
|
|
6529
|
+
function installDataFlowPrelude(config, target2 = globalThis) {
|
|
6530
|
+
if (!config.enabled) return void 0;
|
|
6531
|
+
const runtime = target2[RUNTIME_KEY] ?? createDataFlowRuntime(config, target2);
|
|
6532
|
+
target2[RUNTIME_KEY] = runtime;
|
|
6533
|
+
return runtime;
|
|
6534
|
+
}
|
|
6535
|
+
function getDataFlowRuntime(target2 = globalThis) {
|
|
6536
|
+
return target2[RUNTIME_KEY];
|
|
6537
|
+
}
|
|
6538
|
+
|
|
6539
|
+
// src/data-flow/report-merger.ts
|
|
6540
|
+
var import_shared10 = require("@spotpatch/shared");
|
|
6541
|
+
function observationMatchesDependency(observation, dependency) {
|
|
6542
|
+
const origin = dependency.origin;
|
|
6543
|
+
const transportMatches = dependency.kind === "rpc" ? observation.transport === "trpc" && dependency.operation !== void 0 && observation.operation === dependency.operation : dependency.kind === "http" ? observation.transport === "fetch" || observation.transport === "xhr" : false;
|
|
6544
|
+
if (!transportMatches || observation.freshness !== "current" || origin === void 0 || observation.requestCallsiteId !== origin.requestCallsiteId || observation.sourceVersion !== origin.sourceVersion || dependency.method !== void 0 && observation.method.toUpperCase() !== dependency.method.toUpperCase() || dependency.url !== void 0 && observation.url.pathname !== dependency.url.pathname || dependency.url?.origin !== void 0 && observation.url.origin !== dependency.url.origin || origin.componentSourceId !== void 0 && observation.componentSourceId !== void 0 && observation.componentSourceId !== origin.componentSourceId || origin.triggerCallsiteId !== void 0 && observation.triggerCallsiteId !== void 0 && observation.triggerCallsiteId !== origin.triggerCallsiteId) {
|
|
6545
|
+
return false;
|
|
6546
|
+
}
|
|
6547
|
+
return dependency.association !== "transitive" || observation.componentSourceId === origin.componentSourceId && observation.triggerCallsiteId === origin.triggerCallsiteId;
|
|
6548
|
+
}
|
|
6549
|
+
function runtimeEvidence(observation) {
|
|
6550
|
+
return Object.freeze({
|
|
6551
|
+
id: observation.id,
|
|
6552
|
+
kind: "runtime-observation",
|
|
6553
|
+
summaryKey: "dataFlow.evidence.runtimeDispatch"
|
|
6554
|
+
});
|
|
6555
|
+
}
|
|
6556
|
+
function mergeDependencies(dependencies, observations) {
|
|
6557
|
+
const matchedObservationIds = /* @__PURE__ */ new Set();
|
|
6558
|
+
const merged = dependencies.map((dependency) => {
|
|
6559
|
+
const matches = observations.filter(
|
|
6560
|
+
(observation) => observationMatchesDependency(observation, dependency)
|
|
6561
|
+
);
|
|
6562
|
+
for (const observation of matches) matchedObservationIds.add(observation.id);
|
|
6563
|
+
if (matches.length === 0) return dependency;
|
|
6564
|
+
const observedOrigins = [
|
|
6565
|
+
...new Set(
|
|
6566
|
+
matches.flatMap(({ url }) => url.origin === void 0 ? [] : [url.origin])
|
|
6567
|
+
)
|
|
6568
|
+
];
|
|
6569
|
+
const observedOrigin = observedOrigins.length === 1 ? observedOrigins[0] : void 0;
|
|
6570
|
+
return Object.freeze({
|
|
6571
|
+
...dependency,
|
|
6572
|
+
...dependency.url === void 0 || dependency.url.origin !== void 0 || observedOrigin === void 0 ? {} : {
|
|
6573
|
+
url: Object.freeze({
|
|
6574
|
+
...dependency.url,
|
|
6575
|
+
origin: observedOrigin
|
|
6576
|
+
})
|
|
6577
|
+
},
|
|
6578
|
+
execution: "observed",
|
|
6579
|
+
observationIds: Object.freeze([
|
|
6580
|
+
.../* @__PURE__ */ new Set([...dependency.observationIds, ...matches.map(({ id }) => id)])
|
|
6581
|
+
]),
|
|
6582
|
+
evidenceIds: Object.freeze([
|
|
6583
|
+
.../* @__PURE__ */ new Set([...dependency.evidenceIds, ...matches.map(({ id }) => id)])
|
|
6584
|
+
])
|
|
6585
|
+
});
|
|
6586
|
+
});
|
|
6587
|
+
return Object.freeze({
|
|
6588
|
+
dependencies: Object.freeze(merged),
|
|
6589
|
+
matchedObservationIds
|
|
6590
|
+
});
|
|
6591
|
+
}
|
|
6592
|
+
function appendRuntimeEvidence(evidence, observations, matchedIds) {
|
|
6593
|
+
const existing = new Set(evidence.map(({ id }) => id));
|
|
6594
|
+
return Object.freeze([
|
|
6595
|
+
...evidence,
|
|
6596
|
+
...observations.flatMap(
|
|
6597
|
+
(observation) => matchedIds.has(observation.id) && !existing.has(observation.id) ? [runtimeEvidence(observation)] : []
|
|
6598
|
+
)
|
|
6599
|
+
]);
|
|
6600
|
+
}
|
|
6601
|
+
function mergeComponentDataFlowReport(report, observations) {
|
|
6602
|
+
const componentObservations = observations.filter(
|
|
6603
|
+
(observation) => observation.componentSourceId === void 0 || observation.componentSourceId === report.component.componentSourceId
|
|
6604
|
+
);
|
|
6605
|
+
const merged = mergeDependencies(report.dependencies, componentObservations);
|
|
6606
|
+
return (0, import_shared10.limitDataFlowReportCollections)(
|
|
6607
|
+
Object.freeze({
|
|
6608
|
+
...report,
|
|
6609
|
+
dependencies: merged.dependencies,
|
|
6610
|
+
evidence: appendRuntimeEvidence(
|
|
6611
|
+
report.evidence,
|
|
6612
|
+
componentObservations,
|
|
6613
|
+
merged.matchedObservationIds
|
|
6614
|
+
)
|
|
6615
|
+
}),
|
|
6616
|
+
{ mode: "observation" }
|
|
6617
|
+
);
|
|
6618
|
+
}
|
|
6619
|
+
function unassignedDependency(observation) {
|
|
6620
|
+
const isRpc = observation.transport === "trpc";
|
|
6621
|
+
return Object.freeze({
|
|
6622
|
+
id: observation.id,
|
|
6623
|
+
kind: isRpc ? "rpc" : "http",
|
|
6624
|
+
direction: observation.method === "GET" || observation.method === "HEAD" || observation.method === "QUERY" || observation.method === "SUBSCRIPTION" ? "read" : "write",
|
|
6625
|
+
execution: "observed",
|
|
6626
|
+
proof: "unavailable",
|
|
6627
|
+
association: "unassigned",
|
|
6628
|
+
method: observation.method,
|
|
6629
|
+
...isRpc ? observation.operation === void 0 ? {} : { operation: observation.operation } : { url: observation.url },
|
|
6630
|
+
parameters: Object.freeze(
|
|
6631
|
+
(isRpc ? [] : observation.url.queryKeys).map(
|
|
6632
|
+
(path) => Object.freeze({
|
|
6633
|
+
path,
|
|
6634
|
+
position: "query",
|
|
6635
|
+
sensitive: (0, import_shared10.isSensitiveName)(path),
|
|
6636
|
+
valueState: "not-collected",
|
|
6637
|
+
evidenceIds: Object.freeze([observation.id])
|
|
6638
|
+
})
|
|
6639
|
+
)
|
|
6640
|
+
),
|
|
6641
|
+
response: Object.freeze({
|
|
6642
|
+
consumedFields: Object.freeze([])
|
|
6643
|
+
}),
|
|
6644
|
+
suppliedBindings: Object.freeze([]),
|
|
6645
|
+
locationIds: Object.freeze([]),
|
|
6646
|
+
evidenceIds: Object.freeze([observation.id]),
|
|
6647
|
+
observationIds: Object.freeze([observation.id])
|
|
6648
|
+
});
|
|
6649
|
+
}
|
|
6650
|
+
function mergePageDataFlowReport(report, observations) {
|
|
6651
|
+
const currentObservations = observations.filter(
|
|
6652
|
+
({ freshness }) => freshness === "current"
|
|
6653
|
+
);
|
|
6654
|
+
const merged = mergeDependencies(report.dependencies, currentObservations);
|
|
6655
|
+
const unassigned = currentObservations.filter(({ id }) => !merged.matchedObservationIds.has(id)).map(unassignedDependency);
|
|
6656
|
+
const allObservationIds = new Set(currentObservations.map(({ id }) => id));
|
|
6657
|
+
return (0, import_shared10.limitDataFlowReportCollections)(
|
|
6658
|
+
Object.freeze({
|
|
6659
|
+
...report,
|
|
6660
|
+
dependencies: Object.freeze([...merged.dependencies, ...unassigned]),
|
|
6661
|
+
evidence: appendRuntimeEvidence(
|
|
6662
|
+
report.evidence,
|
|
6663
|
+
currentObservations,
|
|
6664
|
+
allObservationIds
|
|
6665
|
+
)
|
|
6666
|
+
}),
|
|
6667
|
+
{ mode: "observation" }
|
|
6668
|
+
);
|
|
6669
|
+
}
|
|
5818
6670
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5819
6671
|
0 && (module.exports = {
|
|
5820
6672
|
UI_MARKER_ATTRIBUTE,
|
|
5821
|
-
bootstrapSpotPatch
|
|
6673
|
+
bootstrapSpotPatch,
|
|
6674
|
+
createDataFlowRuntime,
|
|
6675
|
+
getDataFlowRuntime,
|
|
6676
|
+
installDataFlowPrelude,
|
|
6677
|
+
mergeComponentDataFlowReport,
|
|
6678
|
+
mergePageDataFlowReport
|
|
5822
6679
|
});
|
|
5823
6680
|
//# sourceMappingURL=index.cjs.map
|