@get-bb/plugin-sdk 0.4.9 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -2
- package/bundled-types/bb-plugin-sdk-app.d.ts +253 -28
- package/bundled-types/bb-plugin-sdk-internal-file-navigation-validation.d.ts +42 -0
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +209 -16
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +3314 -0
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +1362 -327
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +38 -2
- package/bundled-types/bb-plugin-sdk.d.ts +2259 -526
- package/dist/app.js +10 -0
- package/dist/internal/file-navigation-validation.js +135 -0
- package/dist/internal/host-policy.js +467 -4
- package/dist/internal/plugin-app-collector.js +22 -1
- package/dist/provider-bridge-testing.js +5777 -0
- package/dist/provider-bridge.js +2906 -2136
- package/dist/testing/app.js +334 -2
- package/dist/testing/index.js +481 -21
- package/package.json +13 -1
package/dist/testing/app.js
CHANGED
|
@@ -251,6 +251,137 @@ function collectComposerCustomization(registration, seenIds, onRejected) {
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// src/internal/file-navigation-validation.ts
|
|
255
|
+
var FILE_PATH_MAX_LENGTH = 32768;
|
|
256
|
+
var WINDOWS_DRIVE_ABSOLUTE_PATH = /^[A-Za-z]:[\\/]/u;
|
|
257
|
+
var WINDOWS_UNC_ABSOLUTE_PATH = /^\\\\/u;
|
|
258
|
+
function isJsonObject(value) {
|
|
259
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
const prototype = Object.getPrototypeOf(value);
|
|
263
|
+
return prototype === Object.prototype || prototype === null;
|
|
264
|
+
}
|
|
265
|
+
function hasExactKeys(value, keys) {
|
|
266
|
+
const actualKeys = Object.keys(value);
|
|
267
|
+
return actualKeys.length === keys.length && keys.every((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
268
|
+
}
|
|
269
|
+
function isNonEmptyIdentity(value) {
|
|
270
|
+
return typeof value === "string" && value.length > 0 && value.length <= FILE_PATH_MAX_LENGTH && value.trim() === value;
|
|
271
|
+
}
|
|
272
|
+
function hasControlCharacter(value) {
|
|
273
|
+
for (const character of value) {
|
|
274
|
+
const codePoint = character.codePointAt(0);
|
|
275
|
+
if (codePoint !== void 0 && codePoint < 32) return true;
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
function hasUnpairedSurrogate(value) {
|
|
280
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
281
|
+
const codeUnit = value.charCodeAt(index);
|
|
282
|
+
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
283
|
+
if (index + 1 >= value.length) return true;
|
|
284
|
+
const nextCodeUnit = value.charCodeAt(index + 1);
|
|
285
|
+
if (nextCodeUnit < 56320 || nextCodeUnit > 57343) return true;
|
|
286
|
+
index += 1;
|
|
287
|
+
} else if (codeUnit >= 56320 && codeUnit <= 57343) {
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
function isValidPathSegment(segment) {
|
|
294
|
+
return segment.length > 0 && segment !== "." && segment !== "..";
|
|
295
|
+
}
|
|
296
|
+
function isPositiveSafeInteger(value) {
|
|
297
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
298
|
+
}
|
|
299
|
+
function isValidRelativeFilePath(value) {
|
|
300
|
+
if (typeof value !== "string" || value.length === 0 || value.length > FILE_PATH_MAX_LENGTH || value.trim() !== value || value.includes("\\") || hasControlCharacter(value) || hasUnpairedSurrogate(value)) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
return value.split("/").every(isValidPathSegment);
|
|
304
|
+
}
|
|
305
|
+
function isValidAbsoluteHostFilePath(value) {
|
|
306
|
+
if (typeof value !== "string" || value.length === 0 || value.length > FILE_PATH_MAX_LENGTH || value.trim() !== value || hasControlCharacter(value) || hasUnpairedSurrogate(value)) {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
if (value.startsWith("/") && !value.startsWith("//")) {
|
|
310
|
+
const segments = value.slice(1).split("/");
|
|
311
|
+
return segments.length > 0 && segments.every(isValidPathSegment);
|
|
312
|
+
}
|
|
313
|
+
if (WINDOWS_DRIVE_ABSOLUTE_PATH.test(value)) {
|
|
314
|
+
const segments = value.slice(3).split(/[\\/]/u);
|
|
315
|
+
return segments.length > 0 && segments.every(isValidPathSegment);
|
|
316
|
+
}
|
|
317
|
+
if (WINDOWS_UNC_ABSOLUTE_PATH.test(value)) {
|
|
318
|
+
const segments = value.slice(2).split(/[\\/]/u);
|
|
319
|
+
return segments.length >= 3 && segments.every(isValidPathSegment);
|
|
320
|
+
}
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
function normalizeExperimentalLiveFileTarget(value) {
|
|
324
|
+
if (!isJsonObject(value) || typeof value.kind !== "string") return null;
|
|
325
|
+
switch (value.kind) {
|
|
326
|
+
case "workspace":
|
|
327
|
+
if (!hasExactKeys(value, ["kind", "environmentId", "path"]) || !isNonEmptyIdentity(value.environmentId) || !isValidRelativeFilePath(value.path)) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
kind: value.kind,
|
|
332
|
+
environmentId: value.environmentId,
|
|
333
|
+
path: value.path
|
|
334
|
+
};
|
|
335
|
+
case "host":
|
|
336
|
+
if (!hasExactKeys(value, ["kind", "hostId", "path"]) || !isNonEmptyIdentity(value.hostId) || !isValidAbsoluteHostFilePath(value.path)) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
return { kind: value.kind, hostId: value.hostId, path: value.path };
|
|
340
|
+
case "thread-storage":
|
|
341
|
+
if (!hasExactKeys(value, ["kind", "threadId", "path"]) || !isNonEmptyIdentity(value.threadId) || !isValidRelativeFilePath(value.path)) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return { kind: value.kind, threadId: value.threadId, path: value.path };
|
|
345
|
+
default:
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function normalizeExperimentalFileLocation(value) {
|
|
350
|
+
if (value === null) return null;
|
|
351
|
+
if (!isJsonObject(value) || typeof value.kind !== "string") return void 0;
|
|
352
|
+
switch (value.kind) {
|
|
353
|
+
case "line":
|
|
354
|
+
if (!hasExactKeys(value, ["kind", "line", "column"]) || !isPositiveSafeInteger(value.line) || value.column !== null && !isPositiveSafeInteger(value.column)) {
|
|
355
|
+
return void 0;
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
kind: value.kind,
|
|
359
|
+
line: value.line,
|
|
360
|
+
column: value.column
|
|
361
|
+
};
|
|
362
|
+
case "range":
|
|
363
|
+
if (!hasExactKeys(value, ["kind", "startLine", "endLine"]) || !isPositiveSafeInteger(value.startLine) || !isPositiveSafeInteger(value.endLine) || value.endLine < value.startLine) {
|
|
364
|
+
return void 0;
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
kind: value.kind,
|
|
368
|
+
startLine: value.startLine,
|
|
369
|
+
endLine: value.endLine
|
|
370
|
+
};
|
|
371
|
+
default:
|
|
372
|
+
return void 0;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function normalizeExperimentalFileOpenOptions(value) {
|
|
376
|
+
if (!isJsonObject(value) || !hasExactKeys(value, ["target", "location"])) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
const target = normalizeExperimentalLiveFileTarget(value.target);
|
|
380
|
+
const location = normalizeExperimentalFileLocation(value.location);
|
|
381
|
+
if (target === null || location === void 0) return null;
|
|
382
|
+
return { target, location };
|
|
383
|
+
}
|
|
384
|
+
|
|
254
385
|
// src/internal/plugin-app-collector.ts
|
|
255
386
|
function collectPluginAppRegistrations(definition, onComposerCustomizationRejected = (reason) => console.warn(reason)) {
|
|
256
387
|
const collected = {
|
|
@@ -324,6 +455,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
324
455
|
const kind = "slots.navPanel";
|
|
325
456
|
const id = requireSlotId(kind, registration?.id);
|
|
326
457
|
requireUniqueId(kind, seenIds.navPanel, id);
|
|
458
|
+
const panelId = id;
|
|
327
459
|
const path = requireNonEmptyString(kind, "path", registration.path);
|
|
328
460
|
if (!PLUGIN_SLOT_ID_PATTERN.test(path)) {
|
|
329
461
|
throw new Error(
|
|
@@ -359,8 +491,25 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
359
491
|
`${fixedTabKind}: "layout" must be "padded" or "flush" when set`
|
|
360
492
|
);
|
|
361
493
|
}
|
|
494
|
+
const fixedTabPanelId = requireNonEmptyString(
|
|
495
|
+
fixedTabKind,
|
|
496
|
+
"panelId",
|
|
497
|
+
fixedTab?.panelId
|
|
498
|
+
);
|
|
499
|
+
if (fixedTabPanelId !== panelId) {
|
|
500
|
+
throw new Error(
|
|
501
|
+
`${fixedTabKind}: "panelId" must match its containing navPanel id ${JSON.stringify(panelId)}`
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
const experimentalTarget = fixedTab?.experimental_target;
|
|
505
|
+
if (experimentalTarget !== void 0 && (typeof experimentalTarget !== "object" || experimentalTarget === null || typeof Reflect.get(experimentalTarget, "validate") !== "function")) {
|
|
506
|
+
throw new Error(
|
|
507
|
+
`${fixedTabKind}: "experimental_target.validate" must be a function when set`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
362
510
|
return {
|
|
363
511
|
id: id2,
|
|
512
|
+
panelId: fixedTabPanelId,
|
|
364
513
|
title: requireNonEmptyString(
|
|
365
514
|
fixedTabKind,
|
|
366
515
|
"title",
|
|
@@ -372,7 +521,10 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
372
521
|
fixedTab?.icon
|
|
373
522
|
),
|
|
374
523
|
component: requireComponent(fixedTabKind, fixedTab?.component),
|
|
375
|
-
...layout === void 0 ? {} : { layout }
|
|
524
|
+
...layout === void 0 ? {} : { layout },
|
|
525
|
+
...experimentalTarget === void 0 ? {} : {
|
|
526
|
+
experimental_target: experimentalTarget
|
|
527
|
+
}
|
|
376
528
|
};
|
|
377
529
|
});
|
|
378
530
|
})();
|
|
@@ -679,6 +831,65 @@ function TestThreadChat({
|
|
|
679
831
|
function TestMarkdown({ content, className }) {
|
|
680
832
|
return /* @__PURE__ */ jsx("div", { "data-testid": "bb-markdown", className, children: content });
|
|
681
833
|
}
|
|
834
|
+
function TestUrlLink({
|
|
835
|
+
href,
|
|
836
|
+
onClick,
|
|
837
|
+
rel,
|
|
838
|
+
target,
|
|
839
|
+
...anchorProps
|
|
840
|
+
}) {
|
|
841
|
+
const navigate = useSlotEnv("experimental_UrlLink").navigate;
|
|
842
|
+
const normalizedTarget = target?.toLowerCase();
|
|
843
|
+
const opensNewBrowsingContext = normalizedTarget !== void 0 && normalizedTarget !== "" && normalizedTarget !== "_self" && normalizedTarget !== "_parent" && normalizedTarget !== "_top" && normalizedTarget !== "_unfencedtop";
|
|
844
|
+
const relTokens = rel?.split(/\s+/u).filter(Boolean) ?? [];
|
|
845
|
+
const normalizedRelTokens = relTokens.map((token) => token.toLowerCase());
|
|
846
|
+
const resolvedRel = opensNewBrowsingContext && !normalizedRelTokens.includes("opener") ? [
|
|
847
|
+
...relTokens,
|
|
848
|
+
...normalizedRelTokens.includes("noopener") ? [] : ["noopener"],
|
|
849
|
+
...normalizedRelTokens.includes("noreferrer") ? [] : ["noreferrer"]
|
|
850
|
+
].join(" ") : rel;
|
|
851
|
+
return /* @__PURE__ */ jsx(
|
|
852
|
+
"a",
|
|
853
|
+
{
|
|
854
|
+
...anchorProps,
|
|
855
|
+
href,
|
|
856
|
+
target,
|
|
857
|
+
rel: resolvedRel,
|
|
858
|
+
onClick: (event) => {
|
|
859
|
+
onClick?.(event);
|
|
860
|
+
if (event.defaultPrevented || event.button !== 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.currentTarget.hasAttribute("download") || event.currentTarget.hasAttribute("target")) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
if (navigate.experimental_openUrl(href)) event.preventDefault();
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
function TestFileLink({
|
|
869
|
+
target,
|
|
870
|
+
location = null,
|
|
871
|
+
onClick,
|
|
872
|
+
...anchorProps
|
|
873
|
+
}) {
|
|
874
|
+
const navigate = useSlotEnv("experimental_FileLink").navigate;
|
|
875
|
+
const options = normalizeExperimentalFileOpenOptions({ target, location });
|
|
876
|
+
const href = options === null ? void 0 : `./${encodeURIComponent(options.target.path)}`;
|
|
877
|
+
return /* @__PURE__ */ jsx(
|
|
878
|
+
"a",
|
|
879
|
+
{
|
|
880
|
+
...anchorProps,
|
|
881
|
+
href,
|
|
882
|
+
onClick: (event) => {
|
|
883
|
+
onClick?.(event);
|
|
884
|
+
if (options === null || event.defaultPrevented || event.button !== 0 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.currentTarget.hasAttribute("download")) {
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
event.preventDefault();
|
|
888
|
+
navigate.experimental_openFilePreview(options);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
);
|
|
892
|
+
}
|
|
682
893
|
function TestNewThreadComposer({
|
|
683
894
|
defaultProjectId,
|
|
684
895
|
defaultProviderId,
|
|
@@ -829,6 +1040,30 @@ var testPluginSdkApp = {
|
|
|
829
1040
|
useBbNavigate() {
|
|
830
1041
|
return useSlotEnv("useBbNavigate").navigate;
|
|
831
1042
|
},
|
|
1043
|
+
experimental_useAppPanel() {
|
|
1044
|
+
return useSlotEnv("experimental_useAppPanel").appPanel;
|
|
1045
|
+
},
|
|
1046
|
+
experimental_useFixedTabTarget(tab) {
|
|
1047
|
+
const store = useSlotEnv("experimental_useFixedTabTarget").fixedTabTarget;
|
|
1048
|
+
const state = useSyncExternalStore(
|
|
1049
|
+
store.subscribe,
|
|
1050
|
+
store.getSnapshot,
|
|
1051
|
+
store.getSnapshot
|
|
1052
|
+
);
|
|
1053
|
+
if (state === null || state.panelId !== tab.panelId || state.tabId !== tab.id || tab.experimental_target === void 0) {
|
|
1054
|
+
return null;
|
|
1055
|
+
}
|
|
1056
|
+
try {
|
|
1057
|
+
if (!tab.experimental_target.validate(state.target)) return null;
|
|
1058
|
+
} catch {
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
return {
|
|
1062
|
+
clear: () => store.clear(state.sequence),
|
|
1063
|
+
sequence: state.sequence,
|
|
1064
|
+
target: state.target
|
|
1065
|
+
};
|
|
1066
|
+
},
|
|
832
1067
|
useComposer() {
|
|
833
1068
|
const composer = useSlotEnv("useComposer").composer;
|
|
834
1069
|
const version = useSyncExternalStore(
|
|
@@ -847,12 +1082,17 @@ var testPluginSdkApp = {
|
|
|
847
1082
|
},
|
|
848
1083
|
ThreadChat: TestThreadChat,
|
|
849
1084
|
Markdown: TestMarkdown,
|
|
1085
|
+
experimental_FileLink: TestFileLink,
|
|
1086
|
+
experimental_UrlLink: TestUrlLink,
|
|
850
1087
|
experimental_NewThreadComposer: TestNewThreadComposer,
|
|
851
1088
|
experimental_SourceCode: TestSourceCode,
|
|
852
1089
|
experimental_Diff: TestDiff,
|
|
853
1090
|
experimental_useSidebarThreads() {
|
|
854
1091
|
return useSlotEnv("experimental_useSidebarThreads").sidebarThreads;
|
|
855
1092
|
},
|
|
1093
|
+
experimental_useProviders() {
|
|
1094
|
+
return useSlotEnv("experimental_useProviders").providers;
|
|
1095
|
+
},
|
|
856
1096
|
experimental_useSidebarThreadActions() {
|
|
857
1097
|
return useSlotEnv("experimental_useSidebarThreadActions").sidebarActions;
|
|
858
1098
|
},
|
|
@@ -1086,6 +1326,70 @@ function renderSlot(registration, props, options = {}) {
|
|
|
1086
1326
|
}
|
|
1087
1327
|
};
|
|
1088
1328
|
const navigateCalls = [];
|
|
1329
|
+
const experimental_fixedTabOpenCalls = [];
|
|
1330
|
+
let fixedTabTargetSnapshot = options.experimental_fixedTabTarget === void 0 ? null : {
|
|
1331
|
+
panelId: options.experimental_fixedTabTarget.panelId,
|
|
1332
|
+
sequence: 1,
|
|
1333
|
+
tabId: options.experimental_fixedTabTarget.tabId,
|
|
1334
|
+
target: strictJsonRoundTrip(
|
|
1335
|
+
options.experimental_fixedTabTarget.target,
|
|
1336
|
+
"fixed tab target"
|
|
1337
|
+
)
|
|
1338
|
+
};
|
|
1339
|
+
const fixedTabTargetListeners = /* @__PURE__ */ new Set();
|
|
1340
|
+
const fixedTabTarget = {
|
|
1341
|
+
getSnapshot: () => fixedTabTargetSnapshot,
|
|
1342
|
+
subscribe(listener) {
|
|
1343
|
+
fixedTabTargetListeners.add(listener);
|
|
1344
|
+
return () => fixedTabTargetListeners.delete(listener);
|
|
1345
|
+
},
|
|
1346
|
+
clear(sequence) {
|
|
1347
|
+
if (fixedTabTargetSnapshot?.sequence !== sequence) return;
|
|
1348
|
+
fixedTabTargetSnapshot = null;
|
|
1349
|
+
for (const listener of fixedTabTargetListeners) listener();
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
const appPanel = {
|
|
1353
|
+
openFixedTab(panelOptions) {
|
|
1354
|
+
let target;
|
|
1355
|
+
if (panelOptions.target !== void 0) {
|
|
1356
|
+
try {
|
|
1357
|
+
target = strictJsonRoundTrip(
|
|
1358
|
+
panelOptions.target,
|
|
1359
|
+
"fixed tab open target"
|
|
1360
|
+
);
|
|
1361
|
+
} catch {
|
|
1362
|
+
return false;
|
|
1363
|
+
}
|
|
1364
|
+
if (panelOptions.tab.experimental_target === void 0) return false;
|
|
1365
|
+
try {
|
|
1366
|
+
if (!panelOptions.tab.experimental_target.validate(target)) {
|
|
1367
|
+
return false;
|
|
1368
|
+
}
|
|
1369
|
+
} catch {
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
const call = {
|
|
1374
|
+
surface: panelOptions.surface,
|
|
1375
|
+
panelId: panelOptions.tab.panelId,
|
|
1376
|
+
tabId: panelOptions.tab.id,
|
|
1377
|
+
...target === void 0 ? {} : { target }
|
|
1378
|
+
};
|
|
1379
|
+
experimental_fixedTabOpenCalls.push(call);
|
|
1380
|
+
const accepted = options.experimental_openFixedTab?.(call) ?? false;
|
|
1381
|
+
if (accepted && target !== void 0) {
|
|
1382
|
+
fixedTabTargetSnapshot = {
|
|
1383
|
+
panelId: panelOptions.tab.panelId,
|
|
1384
|
+
sequence: (fixedTabTargetSnapshot?.sequence ?? 0) + 1,
|
|
1385
|
+
tabId: panelOptions.tab.id,
|
|
1386
|
+
target
|
|
1387
|
+
};
|
|
1388
|
+
for (const listener of fixedTabTargetListeners) listener();
|
|
1389
|
+
}
|
|
1390
|
+
return accepted;
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1089
1393
|
const sidebarActionCalls = [];
|
|
1090
1394
|
const sidebarPullRequests = new Map(
|
|
1091
1395
|
Object.entries(options.sidebarPullRequests ?? {})
|
|
@@ -1095,6 +1399,10 @@ function renderSlot(registration, props, options = {}) {
|
|
|
1095
1399
|
threads: options.sidebarThreads?.threads ?? [],
|
|
1096
1400
|
projects: options.sidebarThreads?.projects ?? []
|
|
1097
1401
|
};
|
|
1402
|
+
const providers = {
|
|
1403
|
+
status: options.providers?.status ?? "ready",
|
|
1404
|
+
providers: options.providers?.providers ?? []
|
|
1405
|
+
};
|
|
1098
1406
|
const sidebarActions = {
|
|
1099
1407
|
open(threadId2, openOptions) {
|
|
1100
1408
|
sidebarActionCalls.push({
|
|
@@ -1151,6 +1459,24 @@ function renderSlot(registration, props, options = {}) {
|
|
|
1151
1459
|
options: panelOptions
|
|
1152
1460
|
});
|
|
1153
1461
|
return options.openThreadPanel?.(panelOptions) ?? false;
|
|
1462
|
+
},
|
|
1463
|
+
experimental_openUrl(url) {
|
|
1464
|
+
navigateCalls.push({ method: "experimental_openUrl", url });
|
|
1465
|
+
return options.openUrl?.(url) ?? false;
|
|
1466
|
+
},
|
|
1467
|
+
experimental_openFilePreview(fileOptions) {
|
|
1468
|
+
navigateCalls.push({
|
|
1469
|
+
method: "experimental_openFilePreview",
|
|
1470
|
+
options: fileOptions
|
|
1471
|
+
});
|
|
1472
|
+
return options.openFilePreview?.(fileOptions) ?? false;
|
|
1473
|
+
},
|
|
1474
|
+
experimental_openFileExternally(fileOptions) {
|
|
1475
|
+
navigateCalls.push({
|
|
1476
|
+
method: "experimental_openFileExternally",
|
|
1477
|
+
options: fileOptions
|
|
1478
|
+
});
|
|
1479
|
+
return options.openFileExternally?.(fileOptions) ?? false;
|
|
1154
1480
|
}
|
|
1155
1481
|
};
|
|
1156
1482
|
const projectId = options.context?.projectId ?? null;
|
|
@@ -1252,12 +1578,16 @@ ${block}
|
|
|
1252
1578
|
bbContext: { projectId, threadId },
|
|
1253
1579
|
navigate,
|
|
1254
1580
|
navigateCalls,
|
|
1581
|
+
appPanel,
|
|
1582
|
+
experimental_fixedTabOpenCalls,
|
|
1583
|
+
fixedTabTarget,
|
|
1255
1584
|
composer,
|
|
1256
1585
|
composerLog,
|
|
1257
1586
|
sidebarThreads,
|
|
1258
1587
|
sidebarActions,
|
|
1259
1588
|
sidebarActionCalls,
|
|
1260
|
-
sidebarPullRequests
|
|
1589
|
+
sidebarPullRequests,
|
|
1590
|
+
providers
|
|
1261
1591
|
};
|
|
1262
1592
|
const releaseComposerOwnership = () => {
|
|
1263
1593
|
if (!composerOwnership.active) return;
|
|
@@ -1307,6 +1637,7 @@ ${block}
|
|
|
1307
1637
|
setComposerText,
|
|
1308
1638
|
setComposerScope,
|
|
1309
1639
|
navigateCalls,
|
|
1640
|
+
experimental_fixedTabOpenCalls,
|
|
1310
1641
|
sidebarActionCalls,
|
|
1311
1642
|
composer: composerLog,
|
|
1312
1643
|
behavior: {
|
|
@@ -1318,6 +1649,7 @@ ${block}
|
|
|
1318
1649
|
inspection: {
|
|
1319
1650
|
rpcCalls,
|
|
1320
1651
|
navigateCalls,
|
|
1652
|
+
experimental_fixedTabOpenCalls,
|
|
1321
1653
|
sidebarActionCalls,
|
|
1322
1654
|
composer: composerLog
|
|
1323
1655
|
},
|