@a-t-h-i/bot-lobby 0.6.55 → 0.6.56

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.
@@ -1,4 +1,5 @@
1
1
  import type { Domain, Role } from "./agent.ts";
2
+ import { defaultHarnesses, harnessChoiceFields, harnessRunOf, normalizeHarnesses, type HarnessChoice, type HarnessesConfig, type HarnessRun } from "./harness.ts";
2
3
 
3
4
  export type ModelRef = "inherit" | string;
4
5
 
@@ -22,7 +23,7 @@ export function isThinkingLevel(value: string): value is ThinkingLevelName {
22
23
  return (THINKING_LEVELS as readonly string[]).includes(value);
23
24
  }
24
25
 
25
- export interface AgentModelConfig {
26
+ export interface AgentModelConfig extends HarnessChoice {
26
27
  model: ModelRef;
27
28
  thinking: string;
28
29
  /** Free-form instructions layered on top of this agent's built-in prompt. */
@@ -36,7 +37,7 @@ export interface AgentModelConfig {
36
37
  }
37
38
 
38
39
  /** Scouts pick a model only; their thinking is fixed at `SCOUT_THINKING`. */
39
- export interface ScoutConfig {
40
+ export interface ScoutConfig extends HarnessChoice {
40
41
  mcpTools?: string[];
41
42
  /** See AgentModelConfig.skills. */
42
43
  skills?: string[];
@@ -271,6 +272,8 @@ export interface BotLobbyConfig {
271
272
  knowledge: KnowledgeConfig;
272
273
  lobby: LobbyConfig;
273
274
  classifier: ClassifierConfig;
275
+ /** Third-party harnesses a subagent can run on instead of pi, each with its own settings. */
276
+ harnesses: HarnessesConfig;
274
277
  }
275
278
 
276
279
  export const DEFAULT_CONFIG: BotLobbyConfig = {
@@ -349,6 +352,7 @@ export const DEFAULT_CONFIG: BotLobbyConfig = {
349
352
  effort: { cheapModel: INHERIT_MODEL },
350
353
  exclude: [],
351
354
  },
355
+ harnesses: defaultHarnesses(),
352
356
  };
353
357
 
354
358
  /** Choices the settings menu cycles through for the planning round limit; 0 = unlimited. */
@@ -376,12 +380,18 @@ export function normalizeMcpTools(value: unknown): string[] {
376
380
  return Array.isArray(value) ? [...new Set(value.filter((tool): tool is string => typeof tool === "string" && /^mcp__[A-Za-z0-9_]+__[A-Za-z0-9_]+$/.test(tool)))] : [];
377
381
  }
378
382
 
379
- /** Merge one agent's override over its default; legacy `inherit` or unknown thinking falls back to the default level. */
380
- function normalizeAgent(base: AgentModelConfig, override: Partial<AgentModelConfig> | undefined): AgentModelConfig {
383
+ /**
384
+ * Merge one agent's override over its default; legacy `inherit` or unknown
385
+ * thinking falls back to the default level. Only subagents may name a
386
+ * harness (`pi` or an unknown one drops the field): the oracle and the
387
+ * planner live in the pi session.
388
+ */
389
+ function normalizeAgent(base: AgentModelConfig, override: Partial<AgentModelConfig> | undefined, harness = true): AgentModelConfig {
381
390
  const merged = { ...base, ...(override ?? {}) };
382
391
  const thinking = isThinkingLevel(merged.thinking) ? merged.thinking : base.thinking;
383
392
  const mcpTools = normalizeMcpTools(merged.mcpTools);
384
- return { model: merged.model, thinking, ...(mcpTools.length ? { mcpTools } : {}), ...skillsField(merged.skills), ...(typeof merged.instructions === "string" ? { instructions: merged.instructions } : {}), ...(merged.autoCompact === false ? { autoCompact: false } : {}) };
393
+ const choice = harness ? harnessChoiceFields(merged) : {};
394
+ return { model: merged.model, thinking, ...(mcpTools.length ? { mcpTools } : {}), ...skillsField(merged.skills), ...(typeof merged.instructions === "string" ? { instructions: merged.instructions } : {}), ...(merged.autoCompact === false ? { autoCompact: false } : {}), ...choice };
385
395
  }
386
396
 
387
397
  /** Scouts keep a model and a tool-call cap; any thinking value in the file is dropped. */
@@ -394,6 +404,7 @@ function normalizeScout(override: Partial<ScoutConfig> | undefined): ScoutConfig
394
404
  ...(mcpTools.length ? { mcpTools } : {}),
395
405
  ...skillsField(override?.skills),
396
406
  ...(override?.autoCompact === false ? { autoCompact: false } : {}),
407
+ ...harnessChoiceFields(override ?? {}),
397
408
  };
398
409
  }
399
410
 
@@ -517,7 +528,7 @@ export function resolveConfig(partial: unknown): BotLobbyConfig {
517
528
  const knowledge = { ...DEFAULT_CONFIG.knowledge, ...(src.knowledge as Partial<KnowledgeConfig> | undefined) };
518
529
  const srcAgents = (src.agents ?? {}) as Partial<BotLobbyConfig["agents"]>;
519
530
  return {
520
- master: normalizeAgent(DEFAULT_CONFIG.master, src.master as Partial<AgentModelConfig> | undefined),
531
+ master: normalizeAgent(DEFAULT_CONFIG.master, src.master as Partial<AgentModelConfig> | undefined, false),
521
532
  agents: {
522
533
  designer: normalizeAgent(DEFAULT_CONFIG.agents.designer, srcAgents.designer),
523
534
  backend: normalizeAgent(DEFAULT_CONFIG.agents.backend, srcAgents.backend),
@@ -526,12 +537,13 @@ export function resolveConfig(partial: unknown): BotLobbyConfig {
526
537
  scout: normalizeScout(src.scout as Partial<ScoutConfig> | undefined),
527
538
  researcher: normalizeAgent(DEFAULT_CONFIG.researcher, src.researcher as Partial<AgentModelConfig> | undefined),
528
539
  quickFix: normalizeAgent(DEFAULT_CONFIG.quickFix, src.quickFix as Partial<AgentModelConfig> | undefined),
529
- planner: normalizeAgent(DEFAULT_CONFIG.planner, src.planner as Partial<AgentModelConfig> | undefined),
540
+ planner: normalizeAgent(DEFAULT_CONFIG.planner, src.planner as Partial<AgentModelConfig> | undefined, false),
530
541
  workflow,
531
542
  lint: normalizeLint(src.lint),
532
543
  knowledge,
533
544
  lobby: normalizeLobby(src.lobby),
534
545
  classifier: normalizeClassifier(src.classifier),
546
+ harnesses: normalizeHarnesses(src.harnesses),
535
547
  };
536
548
  }
537
549
 
@@ -553,6 +565,14 @@ export interface AgentProfile {
553
565
  skills?: string[];
554
566
  /** False when its settings turn auto-compaction off. */
555
567
  autoCompact?: boolean;
568
+ /** The third-party harness it runs on; absent runs it on pi. */
569
+ harness?: HarnessRun;
570
+ }
571
+
572
+ /** `{ harness }` when an entry runs on a third-party harness, else nothing. */
573
+ function harnessField(config: BotLobbyConfig, entry: HarnessChoice): { harness?: HarnessRun } {
574
+ const harness = harnessRunOf(entry, config.harnesses);
575
+ return harness ? { harness } : {};
556
576
  }
557
577
 
558
578
  /** `{ autoCompact: false }` when an entry turns auto-compaction off, else nothing. */
@@ -586,10 +606,10 @@ export function agentProfile(config: BotLobbyConfig, domain: Domain, role: Role)
586
606
  const kind = profileKind(domain, role);
587
607
  const instructions = config.agents[domain].instructions;
588
608
  if (kind === "scout") {
589
- return { kind, model: modelOf(config.scout.model), thinking: SCOUT_THINKING, instructions, ...grantFields(config.scout), ...compactField(config.scout) };
609
+ return { kind, model: modelOf(config.scout.model), thinking: SCOUT_THINKING, instructions, ...grantFields(config.scout), ...compactField(config.scout), ...harnessField(config, config.scout) };
590
610
  }
591
611
  const entry = kind === "researcher" ? config.researcher : config.agents[kind];
592
- return { kind, model: modelOf(entry.model), thinking: entry.thinking, instructions, ...grantFields(entry), ...compactField(entry) };
612
+ return { kind, model: modelOf(entry.model), thinking: entry.thinking, instructions, ...grantFields(entry), ...compactField(entry), ...harnessField(config, entry) };
593
613
  }
594
614
 
595
615
  /** The settings entry of a lobby agent (quick fix or planner). */
@@ -598,18 +618,18 @@ export function lobbyAgentConfig(config: BotLobbyConfig, kind: LobbyAgentKind):
598
618
  }
599
619
 
600
620
  /** Profile for a lobby agent run, from settings alone; `model` is undefined while unset. */
601
- export function lobbyAgentProfile(config: BotLobbyConfig, kind: LobbyAgentKind): { model?: string; thinking: string; instructions?: string; mcpTools?: string[]; skills?: string[]; autoCompact?: boolean } {
621
+ export function lobbyAgentProfile(config: BotLobbyConfig, kind: LobbyAgentKind): { model?: string; thinking: string; instructions?: string; mcpTools?: string[]; skills?: string[]; autoCompact?: boolean; harness?: HarnessRun } {
602
622
  const entry = lobbyAgentConfig(config, kind);
603
- return { model: modelOf(entry.model), thinking: entry.thinking, instructions: entry.instructions, ...grantFields(entry), ...compactField(entry) };
623
+ return { model: modelOf(entry.model), thinking: entry.thinking, instructions: entry.instructions, ...grantFields(entry), ...compactField(entry), ...harnessField(config, entry) };
604
624
  }
605
625
 
606
626
  /**
607
627
  * A planning panel seat's profile: the domain's (or the researcher's) model,
608
628
  * thinking, custom instructions and grants.
609
629
  */
610
- export function panelMemberProfile(config: BotLobbyConfig, member: PanelMember): { model?: string; thinking: string; instructions?: string; mcpTools?: string[]; skills?: string[]; autoCompact?: boolean } {
630
+ export function panelMemberProfile(config: BotLobbyConfig, member: PanelMember): { model?: string; thinking: string; instructions?: string; mcpTools?: string[]; skills?: string[]; autoCompact?: boolean; harness?: HarnessRun } {
611
631
  const entry = member === "researcher" ? config.researcher : config.agents[member];
612
- return { model: modelOf(entry.model), thinking: entry.thinking, instructions: entry.instructions, ...grantFields(entry), ...compactField(entry) };
632
+ return { model: modelOf(entry.model), thinking: entry.thinking, instructions: entry.instructions, ...grantFields(entry), ...compactField(entry), ...harnessField(config, entry) };
613
633
  }
614
634
 
615
635
  /** The model and thinking a worker's `ask_expert` consults: the configured expert, or the oracle's model. */
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Third-party coding harnesses (Codex CLI, Claude Code, ACP agents such as
3
+ * Antigravity, Gemini CLI and OpenCode) that a subagent can run on instead of
4
+ * pi. The oracle always stays on pi: Bot Lobby is a pi extension, so the
5
+ * workflow, knowledge and compaction live there. A harness only replaces the
6
+ * process one subagent step runs in, with our role prompt injected into it.
7
+ *
8
+ * The per-harness fields follow T3 Code's provider settings
9
+ * (`packages/contracts/src/settings.ts`: binary path, home path, launch
10
+ * arguments, custom models, auto-compact window).
11
+ */
12
+
13
+ /** Harnesses a subagent can run on; `pi` (absent in the config) is the built-in default. */
14
+ export const HARNESS_IDS = ["codex", "claude", "antigravity", "gemini", "opencode", "acp"] as const;
15
+ export type HarnessId = (typeof HARNESS_IDS)[number];
16
+
17
+ export function isHarnessId(value: unknown): value is HarnessId {
18
+ return typeof value === "string" && (HARNESS_IDS as readonly string[]).includes(value);
19
+ }
20
+
21
+ /** How Bot Lobby talks to a harness. */
22
+ export type HarnessProtocol = "codex-exec" | "claude-stream" | "acp";
23
+
24
+ export interface HarnessSettings {
25
+ /** The executable; empty uses the harness's usual command on PATH. */
26
+ binaryPath: string;
27
+ /** Extra arguments, shell-quoted, passed on every run (for a custom ACP agent: the arguments that start it). */
28
+ launchArgs: string;
29
+ /** Codex's CODEX_HOME or Claude Code's CLAUDE_CONFIG_DIR; empty keeps the harness's own. */
30
+ homePath: string;
31
+ /** Who serves the models: Codex's `model_provider` (or `ollama`/`lmstudio` for local models), Claude Code's `anthropic`/`bedrock`/`vertex`; empty keeps the harness's own. */
32
+ modelProvider: string;
33
+ /** Compact the agent's context after this many tokens; 0 keeps the harness's own threshold. */
34
+ compactAt: number;
35
+ /** Put Bot Lobby's role prompt (the agent's instructions, knowledge and report format) into the harness; off sends the task alone. */
36
+ injectPrompts: boolean;
37
+ /** Model ids typed in by hand, listed after the harness's own. */
38
+ customModels: string[];
39
+ /** Antigravity's `localharness_external` next to its ACP server (ANTIGRAVITY_HARNESS_PATH); empty when the server finds it itself. */
40
+ harnessPath: string;
41
+ }
42
+
43
+ export const DEFAULT_HARNESS_SETTINGS: HarnessSettings = {
44
+ binaryPath: "",
45
+ launchArgs: "",
46
+ homePath: "",
47
+ modelProvider: "",
48
+ compactAt: 0,
49
+ injectPrompts: true,
50
+ customModels: [],
51
+ harnessPath: "",
52
+ };
53
+
54
+ export type HarnessesConfig = Record<HarnessId, HarnessSettings>;
55
+
56
+ export function defaultHarnesses(): HarnessesConfig {
57
+ return Object.fromEntries(HARNESS_IDS.map((id) => [id, { ...DEFAULT_HARNESS_SETTINGS, customModels: [] as string[] }])) as unknown as HarnessesConfig;
58
+ }
59
+
60
+ /** Smallest and largest compaction threshold a harness accepts, in tokens. */
61
+ export const HARNESS_COMPACT_MIN = 10_000;
62
+ export const HARNESS_COMPACT_MAX = 2_000_000;
63
+
64
+ function text(value: unknown, fallback: string): string {
65
+ return typeof value === "string" ? value.trim() : fallback;
66
+ }
67
+
68
+ function compactAt(value: unknown): number {
69
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0;
70
+ return Math.min(HARNESS_COMPACT_MAX, Math.max(HARNESS_COMPACT_MIN, Math.round(value)));
71
+ }
72
+
73
+ function modelIds(value: unknown): string[] {
74
+ if (!Array.isArray(value)) return [];
75
+ return [...new Set(value.filter((entry): entry is string => typeof entry === "string").map((entry) => entry.trim()).filter((entry) => entry.length > 0 && entry.length <= 200 && !/\s/.test(entry)))];
76
+ }
77
+
78
+ function normalizeHarness(value: unknown): HarnessSettings {
79
+ const source = (value && typeof value === "object" ? value : {}) as Record<string, unknown>;
80
+ const base = DEFAULT_HARNESS_SETTINGS;
81
+ return {
82
+ binaryPath: text(source.binaryPath, base.binaryPath),
83
+ launchArgs: text(source.launchArgs, base.launchArgs),
84
+ homePath: text(source.homePath, base.homePath),
85
+ modelProvider: text(source.modelProvider, base.modelProvider),
86
+ compactAt: compactAt(source.compactAt),
87
+ injectPrompts: source.injectPrompts !== false,
88
+ customModels: modelIds(source.customModels),
89
+ harnessPath: text(source.harnessPath, base.harnessPath),
90
+ };
91
+ }
92
+
93
+ export function normalizeHarnesses(value: unknown): HarnessesConfig {
94
+ const source = (value && typeof value === "object" ? value : {}) as Record<string, unknown>;
95
+ return Object.fromEntries(HARNESS_IDS.map((id) => [id, normalizeHarness(source[id])])) as HarnessesConfig;
96
+ }
97
+
98
+ /** An agent entry's harness fields: absent for pi, else the harness and its model (empty: the harness's default). */
99
+ export interface HarnessChoice {
100
+ harness?: HarnessId;
101
+ harnessModel?: string;
102
+ }
103
+
104
+ export function harnessChoiceFields(entry: { harness?: unknown; harnessModel?: unknown }): HarnessChoice {
105
+ if (!isHarnessId(entry.harness)) return {};
106
+ const model = text(entry.harnessModel, "");
107
+ return { harness: entry.harness, ...(model ? { harnessModel: model } : {}) };
108
+ }
109
+
110
+ /** Everything one run on a harness needs from the settings. */
111
+ export interface HarnessRun {
112
+ id: HarnessId;
113
+ /** Empty: the harness's own default model. */
114
+ model: string;
115
+ settings: HarnessSettings;
116
+ }
117
+
118
+ /** The harness an agent entry runs on, with that harness's settings; undefined for pi. */
119
+ export function harnessRunOf(entry: HarnessChoice, harnesses: HarnessesConfig): HarnessRun | undefined {
120
+ if (!entry.harness) return undefined;
121
+ return { id: entry.harness, model: entry.harnessModel ?? "", settings: harnesses[entry.harness] };
122
+ }
@@ -21,7 +21,7 @@ import { plansDiscard, plansGet, plansStart } from "./plans.ts";
21
21
  import { gitCancelReview, gitJev, gitPull, gitPulls, gitReview } from "./git.ts";
22
22
  import { issuesCreate, issuesGet, issuesList } from "./issues.ts";
23
23
  import { sessionsAnswer, sessionsArchive, sessionsChat, sessionsList, sessionsMessage, sessionsRename, sessionsStart, sessionsStop, sessionsSwitch } from "./sessions.ts";
24
- import { settingsGet, settingsGrants, settingsLinters, settingsSet } from "./settings.ts";
24
+ import { settingsGet, settingsGrants, settingsHarnesses, settingsLinters, settingsSet } from "./settings.ts";
25
25
  import { terminalClose, terminalInput, terminalList, terminalOpen, terminalResize } from "./terminal.ts";
26
26
  import { MAX_INPUT_CHARS } from "../terminal.ts";
27
27
  import { themesChoose, themesGet, themesRemove, themesRename, themesSave } from "./themes.ts";
@@ -386,6 +386,7 @@ function buildRoutes(): Record<string, Route> {
386
386
  };
387
387
  routes["settings.linters"] = { schema: Empty, run: (_body, ctx) => settingsLinters(ctx) };
388
388
  routes["settings.grants"] = { schema: Empty, run: (_body, ctx) => settingsGrants(ctx) };
389
+ routes["settings.harnesses"] = { schema: Empty, run: (_body, ctx) => settingsHarnesses(ctx) };
389
390
  const ThemeId = Type.String({ minLength: 1, maxLength: 40 });
390
391
  const ThemeName = Type.String({ minLength: 1, maxLength: 200 });
391
392
  const ThemeVars = Type.Optional(Type.Record(Type.String({ maxLength: 60 }), Type.String({ maxLength: 400 })));
@@ -10,7 +10,8 @@ import { lobbyTopics } from "../../lobby/topics.ts";
10
10
  import { prefillModels } from "../../pi/model-settings.ts";
11
11
  import { kindLabel } from "../../pi/model-support.ts";
12
12
  import { pushNotice } from "../notices.ts";
13
- import type { SettingsGrants, SettingsInfo, SettingsLinter } from "../protocol.ts";
13
+ import type { SettingsGrants, SettingsHarnesses, SettingsInfo, SettingsLinter } from "../protocol.ts";
14
+ import { harnessStatuses } from "../../harness/status.ts";
14
15
  import type { ApiContext } from "./index.ts";
15
16
  import { fail } from "./index.ts";
16
17
 
@@ -88,6 +89,11 @@ export function settingsGrants(ctx: ApiContext): SettingsGrants {
88
89
  return ctx.service.grants?.() ?? { mcpTools: [], skills: [] };
89
90
  }
90
91
 
92
+ /** Each harness, found on PATH or not, with its models; the dev server's fake service answers for itself. */
93
+ export async function settingsHarnesses(ctx: ApiContext): Promise<SettingsHarnesses> {
94
+ return { harnesses: ctx.service.harnesses?.() ?? await harnessStatuses(readConfig(ctx).harnesses) };
95
+ }
96
+
91
97
  /** Merge, normalise and save the patch; the lobby rereads the config. */
92
98
  export function settingsSet(body: { patch: Record<string, unknown> }, ctx: ApiContext): { config: BotLobbyConfig } {
93
99
  checkPort(body.patch);
@@ -13,6 +13,8 @@ import { cleanSessionName } from "../../lobby/sessions.ts";
13
13
  import type { PlanComment } from "../../state/comments.ts";
14
14
  import type { LobbyService } from "../../lobby/host.ts";
15
15
  import { loadScenario, type ScenarioFixture } from "./fixtures.ts";
16
+ import { HARNESSES, harnessCommand, harnessModels } from "../../harness/catalog.ts";
17
+ import { HARNESS_IDS } from "../../schemas/harness.ts";
16
18
  import type { PlanRecord, PlanSummary } from "../../state/plan-history.ts";
17
19
 
18
20
  interface StreamState {
@@ -408,6 +410,17 @@ export function createFixtureService(name: string, feed = new LobbyFeed()): Lobb
408
410
  },
409
411
  configChanged: () => {},
410
412
  models: () => models.map((model) => ({ id: model.id, label: model.label, thinkingLevels: [...model.thinkingLevels] })),
413
+ // A fixed machine for screenshots and browser tests: Codex and Claude Code installed, the rest not.
414
+ harnesses: () => HARNESS_IDS.map((id) => {
415
+ const info = HARNESSES[id];
416
+ const installed: Partial<Record<string, string>> = { codex: "0.163.0", claude: "2.1.306" };
417
+ const command = harnessCommand(id, config.harnesses[id]).command;
418
+ return {
419
+ id, label: info.label, blurb: info.blurb, protocol: info.protocol, command, providers: info.providers, effort: info.effort,
420
+ ...(installed[id] ? { path: `/usr/local/bin/${command}`, version: installed[id] } : {}),
421
+ models: harnessModels(id, config.harnesses[id]),
422
+ };
423
+ }),
411
424
  classifierModels: () => [{ id: "opencode/jev-1.13-free", label: "Jev 1.13 (free)" }, { id: "openrouter/liquid/d1", label: "Liquid D1" }],
412
425
  grants: () => ({
413
426
  mcpTools: [
@@ -15,6 +15,8 @@ import type { BotLobbyConfig, PanelMember } from "../schemas/configuration.ts";
15
15
  import type { QaRiskAssessment } from "../schemas/task.ts";
16
16
  import type { MemberState, PanelNote, PanelQuestion, PlannerMessage } from "../lobby/planner.ts";
17
17
  import type { QuickFixJob } from "../lobby/quickfix.ts";
18
+ import type { HarnessStatus } from "../harness/status.ts";
19
+ import type { HarnessModel } from "../harness/catalog.ts";
18
20
 
19
21
  export interface ProjectInfo { id: string; name: string; cwd: string; port: number }
20
22
  export interface FolderListing { path: string; parent?: string; folders: Array<{ name: string; path: string }>; truncated: boolean }
@@ -23,6 +25,7 @@ export type { WebPrompt };
23
25
  export type { LobbyTopic };
24
26
  export type { DialogAnswer, SessionDialog, TaskRow, PlanComment };
25
27
  export type { LiveSession };
28
+ export type { HarnessStatus, HarnessModel };
26
29
  export type { PanelMember, MemberState, PanelNote, PanelQuestion, PlannerMessage, QuickFixJob, BotLobbyConfig };
27
30
 
28
31
  /** Every API answer: the result, or why not. */
@@ -232,6 +235,11 @@ export interface SettingsGrants {
232
235
  skills: SettingsSkill[];
233
236
  }
234
237
 
238
+ /** `settings.harnesses`: each third-party harness, whether it is installed, and the models it offers. */
239
+ export interface SettingsHarnesses {
240
+ harnesses: HarnessStatus[];
241
+ }
242
+
235
243
  /** One message on the event stream (`GET /api/events`, server-sent events). */
236
244
  export type StreamEvent =
237
245
  | { type: "hello"; versions: Partial<Record<LobbyTopic, number>> }
@@ -629,6 +637,7 @@ export interface Api {
629
637
  "settings.set": { request: { patch: Record<string, unknown> }; result: { config: BotLobbyConfig } };
630
638
  "settings.linters": { request: Record<string, never>; result: { linters: SettingsLinter[] } };
631
639
  "settings.grants": { request: Record<string, never>; result: SettingsGrants };
640
+ "settings.harnesses": { request: Record<string, never>; result: SettingsHarnesses };
632
641
  "themes.get": { request: Record<string, never>; result: ThemeStoreInfo };
633
642
  "themes.save": { request: { name: string; light?: Record<string, string>; dark?: Record<string, string> }; result: ThemeStoreInfo & { id: string } };
634
643
  "themes.rename": { request: { id: string; name: string }; result: ThemeStoreInfo };
@@ -1,4 +1,4 @@
1
- import{a as e,i as t,n,o as r,r as i,t as a}from"./index-DIM2-FUQ.js";var o=r(e(),1),s=Object.defineProperty,c=Object.getOwnPropertyDescriptor,l=(e,t)=>{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},u=(e,t,n,r)=>{for(var i=r>1?void 0:r?c(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&s(t,n,i),i},d=(e,t)=>(n,r)=>t(n,r,e),f=`Terminal input`,p={get:()=>f,set:e=>f=e},m=`Too much output to announce, navigate to rows manually to read`,h={get:()=>m,set:e=>m=e};function g(e){return e.replace(/\r?\n/g,`\r`)}function _(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ee(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function te(e,t,n,r){e.stopPropagation(),e.clipboardData&&ne(e.clipboardData.getData(`text/plain`),t,n,r)}function ne(e,t,n,r){e=g(e),e=_(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function re(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ie(e,t,n,r,i){re(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function ae(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function oe(e,t=0,n=e.length){let r=``;for(let i=t;i<n;++i){let t=e[i];t>65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var se=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a<n;++a){let i=e.charCodeAt(a);if(55296<=i&&i<=56319){if(++a>=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},ce=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l<u;){if(l>=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d<n;){for(;d<u&&!((i=e[d])&128)&&!((a=e[d+1])&128)&&!((o=e[d+2])&128)&&!((s=e[d+3])&128);)t[r++]=i,t[r++]=a,t[r++]=o,t[r++]=s,d+=4;if(i=e[d++],i<128)t[r++]=i;else if((i&224)==192){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},v=``,le=` `,ue=class e{constructor(){this.fg=0,this.bg=0,this.extended=new de}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return!(this.fg&50331648)}isBgDefault(){return!(this.bg&50331648)}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?!(this.extended.underlineColor&50331648):this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},de=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},y=class e extends ue{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new de,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?ae(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},fe=`di$target`,pe=`di$dependencies`,me=new Map;function b(e){return e[pe]||[]}function x(e){if(me.has(e))return me.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);he(t,e,r)};return t._id=e,me.set(e,t),t}function he(e,t,n){t[fe]===t?t[pe].push({id:e,index:n}):(t[pe]=[{id:e,index:n}],t[fe]=t)}var S=x(`BufferService`),ge=x(`CoreMouseService`),_e=x(`CoreService`),C=x(`CharsetService`),ve=x(`InstantiationService`),w=x(`LogService`),T=x(`OptionsService`),ye=x(`OscLinkService`),be=x(`UnicodeService`),xe=x(`DecorationService`),Se=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new y,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;t<o;t++)if(c!==-1||n.hasContent(t)){if(n.loadCell(t,a),a.hasExtendedAttrs()&&a.extended.urlId){if(c===-1){c=t,s=a.extended.urlId;continue}l=a.extended.urlId!==s}else c!==-1&&(l=!0);if(l||c!==-1&&t===o-1){let n=this._oscLinkService.getLinkData(s)?.uri;if(n){let a={start:{x:c+1,y:e},end:{x:t+ +(!l&&t===o-1),y:e}},s=!1;if(!i?.allowNonHttpProtocols)try{let e=new URL(n);[`http:`,`https:`].includes(e.protocol)||(s=!0)}catch{s=!0}s||r.push({text:n,range:a,activate:(e,t)=>i?i.activate(e,t,a):Ce(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};Se=u([d(0,S),d(1,T),d(2,ye)],Se);function Ce(e,t){if(confirm(`Do you want to navigate to ${t}?
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./index-BKiKxUUG.js";var o=r(e(),1),s=Object.defineProperty,c=Object.getOwnPropertyDescriptor,l=(e,t)=>{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},u=(e,t,n,r)=>{for(var i=r>1?void 0:r?c(t,n):t,a=e.length-1,o;a>=0;a--)(o=e[a])&&(i=(r?o(t,n,i):o(i))||i);return r&&i&&s(t,n,i),i},d=(e,t)=>(n,r)=>t(n,r,e),f=`Terminal input`,p={get:()=>f,set:e=>f=e},m=`Too much output to announce, navigate to rows manually to read`,h={get:()=>m,set:e=>m=e};function g(e){return e.replace(/\r?\n/g,`\r`)}function _(e,t){return t?`\x1B[200~`+e+`\x1B[201~`:e}function ee(e,t){e.clipboardData&&e.clipboardData.setData(`text/plain`,t.selectionText),e.preventDefault()}function te(e,t,n,r){e.stopPropagation(),e.clipboardData&&ne(e.clipboardData.getData(`text/plain`),t,n,r)}function ne(e,t,n,r){e=g(e),e=_(e,n.decPrivateModes.bracketedPasteMode&&r.rawOptions.ignoreBracketedPasteMode!==!0),n.triggerDataEvent(e,!0),t.value=``}function re(e,t,n){let r=n.getBoundingClientRect(),i=e.clientX-r.left-10,a=e.clientY-r.top-10;t.style.width=`20px`,t.style.height=`20px`,t.style.left=`${i}px`,t.style.top=`${a}px`,t.style.zIndex=`1000`,t.focus()}function ie(e,t,n,r,i){re(e,t,n),i&&r.rightClickSelect(e),t.value=r.selectionText,t.select()}function ae(e){return e>65535?(e-=65536,String.fromCharCode((e>>10)+55296)+String.fromCharCode(e%1024+56320)):String.fromCharCode(e)}function oe(e,t=0,n=e.length){let r=``;for(let i=t;i<n;++i){let t=e[i];t>65535?(t-=65536,r+=String.fromCharCode((t>>10)+55296)+String.fromCharCode(t%1024+56320)):r+=String.fromCharCode(t)}return r}var se=class{constructor(){this._interim=0}clear(){this._interim=0}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i=0;if(this._interim){let n=e.charCodeAt(i++);56320<=n&&n<=57343?t[r++]=(this._interim-55296)*1024+n-56320+65536:(t[r++]=this._interim,t[r++]=n),this._interim=0}for(let a=i;a<n;++a){let i=e.charCodeAt(a);if(55296<=i&&i<=56319){if(++a>=n)return this._interim=i,r;let o=e.charCodeAt(a);56320<=o&&o<=57343?t[r++]=(i-55296)*1024+o-56320+65536:(t[r++]=i,t[r++]=o);continue}i!==65279&&(t[r++]=i)}return r}},ce=class{constructor(){this.interim=new Uint8Array(3)}clear(){this.interim.fill(0)}decode(e,t){let n=e.length;if(!n)return 0;let r=0,i,a,o,s,c=0,l=0;if(this.interim[0]){let i=!1,a=this.interim[0];a&=(a&224)==192?31:(a&240)==224?15:7;let o=0,s;for(;(s=this.interim[++o]&63)&&o<4;)a<<=6,a|=s;let c=(this.interim[0]&224)==192?2:(this.interim[0]&240)==224?3:4,u=c-o;for(;l<u;){if(l>=n)return 0;if(s=e[l++],(s&192)!=128){l--,i=!0;break}this.interim[o++]=s,a<<=6,a|=s&63}i||(c===2?a<128?l--:t[r++]=a:c===3?a<2048||a>=55296&&a<=57343||a===65279||(t[r++]=a):a<65536||a>1114111||(t[r++]=a)),this.interim.fill(0)}let u=n-4,d=l;for(;d<n;){for(;d<u&&!((i=e[d])&128)&&!((a=e[d+1])&128)&&!((o=e[d+2])&128)&&!((s=e[d+3])&128);)t[r++]=i,t[r++]=a,t[r++]=o,t[r++]=s,d+=4;if(i=e[d++],i<128)t[r++]=i;else if((i&224)==192){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(c=(i&31)<<6|a&63,c<128){d--;continue}t[r++]=c}else if((i&240)==224){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(c=(i&15)<<12|(a&63)<<6|o&63,c<2048||c>=55296&&c<=57343||c===65279)continue;t[r++]=c}else if((i&248)==240){if(d>=n)return this.interim[0]=i,r;if(a=e[d++],(a&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,r;if(o=e[d++],(o&192)!=128){d--;continue}if(d>=n)return this.interim[0]=i,this.interim[1]=a,this.interim[2]=o,r;if(s=e[d++],(s&192)!=128){d--;continue}if(c=(i&7)<<18|(a&63)<<12|(o&63)<<6|s&63,c<65536||c>1114111)continue;t[r++]=c}}return r}},v=``,le=` `,ue=class e{constructor(){this.fg=0,this.bg=0,this.extended=new de}static toColorRGB(e){return[e>>>16&255,e>>>8&255,e&255]}static fromColorRGB(e){return(e[0]&255)<<16|(e[1]&255)<<8|e[2]&255}clone(){let t=new e;return t.fg=this.fg,t.bg=this.bg,t.extended=this.extended.clone(),t}isInverse(){return this.fg&67108864}isBold(){return this.fg&134217728}isUnderline(){return this.hasExtendedAttrs()&&this.extended.underlineStyle!==0?1:this.fg&268435456}isBlink(){return this.fg&536870912}isInvisible(){return this.fg&1073741824}isItalic(){return this.bg&67108864}isDim(){return this.bg&134217728}isStrikethrough(){return this.fg&2147483648}isProtected(){return this.bg&536870912}isOverline(){return this.bg&1073741824}getFgColorMode(){return this.fg&50331648}getBgColorMode(){return this.bg&50331648}isFgRGB(){return(this.fg&50331648)==50331648}isBgRGB(){return(this.bg&50331648)==50331648}isFgPalette(){return(this.fg&50331648)==16777216||(this.fg&50331648)==33554432}isBgPalette(){return(this.bg&50331648)==16777216||(this.bg&50331648)==33554432}isFgDefault(){return!(this.fg&50331648)}isBgDefault(){return!(this.bg&50331648)}isAttributeDefault(){return this.fg===0&&this.bg===0}getFgColor(){switch(this.fg&50331648){case 16777216:case 33554432:return this.fg&255;case 50331648:return this.fg&16777215;default:return-1}}getBgColor(){switch(this.bg&50331648){case 16777216:case 33554432:return this.bg&255;case 50331648:return this.bg&16777215;default:return-1}}hasExtendedAttrs(){return this.bg&268435456}updateExtended(){this.extended.isEmpty()?this.bg&=-268435457:this.bg|=268435456}getUnderlineColor(){if(this.bg&268435456&&~this.extended.underlineColor)switch(this.extended.underlineColor&50331648){case 16777216:case 33554432:return this.extended.underlineColor&255;case 50331648:return this.extended.underlineColor&16777215;default:return this.getFgColor()}return this.getFgColor()}getUnderlineColorMode(){return this.bg&268435456&&~this.extended.underlineColor?this.extended.underlineColor&50331648:this.getFgColorMode()}isUnderlineColorRGB(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==50331648:this.isFgRGB()}isUnderlineColorPalette(){return this.bg&268435456&&~this.extended.underlineColor?(this.extended.underlineColor&50331648)==16777216||(this.extended.underlineColor&50331648)==33554432:this.isFgPalette()}isUnderlineColorDefault(){return this.bg&268435456&&~this.extended.underlineColor?!(this.extended.underlineColor&50331648):this.isFgDefault()}getUnderlineStyle(){return this.fg&268435456?this.bg&268435456?this.extended.underlineStyle:1:0}getUnderlineVariantOffset(){return this.extended.underlineVariantOffset}},de=class e{constructor(e=0,t=0){this._ext=0,this._urlId=0,this._ext=e,this._urlId=t}get ext(){return this._urlId?this._ext&-469762049|this.underlineStyle<<26:this._ext}set ext(e){this._ext=e}get underlineStyle(){return this._urlId?5:(this._ext&469762048)>>26}set underlineStyle(e){this._ext&=-469762049,this._ext|=e<<26&469762048}get underlineColor(){return this._ext&67108863}set underlineColor(e){this._ext&=-67108864,this._ext|=e&67108863}get urlId(){return this._urlId}set urlId(e){this._urlId=e}get underlineVariantOffset(){let e=(this._ext&3758096384)>>29;return e<0?e^4294967288:e}set underlineVariantOffset(e){this._ext&=536870911,this._ext|=e<<29&3758096384}clone(){return new e(this._ext,this._urlId)}isEmpty(){return this.underlineStyle===0&&this._urlId===0}},y=class e extends ue{constructor(){super(...arguments),this.content=0,this.fg=0,this.bg=0,this.extended=new de,this.combinedData=``}static fromCharData(t){let n=new e;return n.setFromCharData(t),n}isCombined(){return this.content&2097152}getWidth(){return this.content>>22}getChars(){return this.content&2097152?this.combinedData:this.content&2097151?ae(this.content&2097151):``}getCode(){return this.isCombined()?this.combinedData.charCodeAt(this.combinedData.length-1):this.content&2097151}setFromCharData(e){this.fg=e[0],this.bg=0;let t=!1;if(e[1].length>2)t=!0;else if(e[1].length===2){let n=e[1].charCodeAt(0);if(55296<=n&&n<=56319){let r=e[1].charCodeAt(1);56320<=r&&r<=57343?this.content=(n-55296)*1024+r-56320+65536|e[2]<<22:t=!0}else t=!0}else this.content=e[1].charCodeAt(0)|e[2]<<22;t&&(this.combinedData=e[1],this.content=2097152|e[2]<<22)}getAsCharData(){return[this.fg,this.getChars(),this.getWidth(),this.getCode()]}},fe=`di$target`,pe=`di$dependencies`,me=new Map;function b(e){return e[pe]||[]}function x(e){if(me.has(e))return me.get(e);let t=function(e,n,r){if(arguments.length!==3)throw Error(`@IServiceName-decorator can only be used to decorate a parameter`);he(t,e,r)};return t._id=e,me.set(e,t),t}function he(e,t,n){t[fe]===t?t[pe].push({id:e,index:n}):(t[pe]=[{id:e,index:n}],t[fe]=t)}var S=x(`BufferService`),ge=x(`CoreMouseService`),_e=x(`CoreService`),C=x(`CharsetService`),ve=x(`InstantiationService`),w=x(`LogService`),T=x(`OptionsService`),ye=x(`OscLinkService`),be=x(`UnicodeService`),xe=x(`DecorationService`),Se=class{constructor(e,t,n){this._bufferService=e,this._optionsService=t,this._oscLinkService=n}provideLinks(e,t){let n=this._bufferService.buffer.lines.get(e-1);if(!n){t(void 0);return}let r=[],i=this._optionsService.rawOptions.linkHandler,a=new y,o=n.getTrimmedLength(),s=-1,c=-1,l=!1;for(let t=0;t<o;t++)if(c!==-1||n.hasContent(t)){if(n.loadCell(t,a),a.hasExtendedAttrs()&&a.extended.urlId){if(c===-1){c=t,s=a.extended.urlId;continue}l=a.extended.urlId!==s}else c!==-1&&(l=!0);if(l||c!==-1&&t===o-1){let n=this._oscLinkService.getLinkData(s)?.uri;if(n){let a={start:{x:c+1,y:e},end:{x:t+ +(!l&&t===o-1),y:e}},s=!1;if(!i?.allowNonHttpProtocols)try{let e=new URL(n);[`http:`,`https:`].includes(e.protocol)||(s=!0)}catch{s=!0}s||r.push({text:n,range:a,activate:(e,t)=>i?i.activate(e,t,a):Ce(e,t),hover:(e,t)=>i?.hover?.(e,t,a),leave:(e,t)=>i?.leave?.(e,t,a)})}l=!1,a.hasExtendedAttrs()&&a.extended.urlId?(c=t,s=a.extended.urlId):(c=-1,s=-1)}}t(r)}};Se=u([d(0,S),d(1,T),d(2,ye)],Se);function Ce(e,t){if(confirm(`Do you want to navigate to ${t}?
2
2
 
3
3
  WARNING: This link could potentially be dangerous`)){let e=window.open();if(e){try{e.opener=null}catch{}e.location.href=t}else console.warn(`Opening link blocked as opener could not be cleared`)}}var we=x(`CharSizeService`),Te=x(`CoreBrowserService`),Ee=x(`MouseService`),De=x(`RenderService`),Oe=x(`SelectionService`),ke=x(`CharacterJoinerService`),Ae=x(`ThemeService`),je=x(`LinkProviderService`),Me=new class{constructor(){this.listeners=[],this.unexpectedErrorHandler=function(e){setTimeout(()=>{throw e.stack?Re.isErrorNoTelemetry(e)?new Re(e.message+`
4
4