@eclipse-docks/extension-terminal 0.8.12 → 0.8.14
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/api.js +2 -3
- package/dist/{i18n.de-1gFRm90o.js → i18n.de-CXiNR_66.js} +2 -3
- package/dist/{i18n.de-1gFRm90o.js.map → i18n.de-CXiNR_66.js.map} +1 -1
- package/dist/{i18n.en-BpQpiXOC.js → i18n.en-L4uYF63V.js} +2 -3
- package/dist/{i18n.en-BpQpiXOC.js.map → i18n.en-L4uYF63V.js.map} +1 -1
- package/dist/index.js +4 -5
- package/dist/{js-terminal-backend-CRxDAwvr.js → js-terminal-backend-C6NeZIFc.js} +10 -17
- package/dist/{js-terminal-backend-CRxDAwvr.js.map → js-terminal-backend-C6NeZIFc.js.map} +1 -1
- package/dist/{terminal-extension-CnPHiXG4.js → terminal-extension-B0d4I4cK.js} +6 -10
- package/dist/{terminal-extension-CnPHiXG4.js.map → terminal-extension-B0d4I4cK.js.map} +1 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as TERMINAL_PANEL_SETTINGS_KEY, a as openJsSessionTerminal, b as TOPIC_TERMINAL_OPENED, c as LineInput, d as emptyTerminalState, f as parseTerminalState, g as TERMINAL_NEW_DROPDOWN, h as TERMINAL_INSTANCES_TABS_ID, i as createJsSessionBackend, l as registerTerminalProfile, m as TARGET_TERMINAL_PROFILES, n as JS_SESSION_PROFILE_ID, o as unbindJsSession, p as serializeTerminalState, r as JsReplBackend, s as CommandsBackend, t as JS_REPL_PROFILE_ID, u as terminalService, v as TOPIC_TERMINAL_ACTIVE_CHANGED, x as VIEW_TERMINAL, y as TOPIC_TERMINAL_CLOSED } from "./js-terminal-backend-
|
|
2
|
-
|
|
1
|
+
import { _ as TERMINAL_PANEL_SETTINGS_KEY, a as openJsSessionTerminal, b as TOPIC_TERMINAL_OPENED, c as LineInput, d as emptyTerminalState, f as parseTerminalState, g as TERMINAL_NEW_DROPDOWN, h as TERMINAL_INSTANCES_TABS_ID, i as createJsSessionBackend, l as registerTerminalProfile, m as TARGET_TERMINAL_PROFILES, n as JS_SESSION_PROFILE_ID, o as unbindJsSession, p as serializeTerminalState, r as JsReplBackend, s as CommandsBackend, t as JS_REPL_PROFILE_ID, u as terminalService, v as TOPIC_TERMINAL_ACTIVE_CHANGED, x as VIEW_TERMINAL, y as TOPIC_TERMINAL_CLOSED } from "./js-terminal-backend-C6NeZIFc.js";
|
|
2
|
+
// src/attached-terminal.ts
|
|
3
3
|
/**
|
|
4
4
|
* One terminal tab bound to a caller-owned session.
|
|
5
5
|
* Closing the tab forgets the tab only. release() also drops the session binding.
|
|
@@ -69,7 +69,6 @@ var AttachedTerminal = class {
|
|
|
69
69
|
terminal?.dispose({ confirm: false });
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
|
-
//#endregion
|
|
73
72
|
export { AttachedTerminal, CommandsBackend, JS_REPL_PROFILE_ID, JS_SESSION_PROFILE_ID, JsReplBackend, LineInput, TARGET_TERMINAL_PROFILES, TERMINAL_INSTANCES_TABS_ID, TERMINAL_NEW_DROPDOWN, TERMINAL_PANEL_SETTINGS_KEY, TOPIC_TERMINAL_ACTIVE_CHANGED, TOPIC_TERMINAL_CLOSED, TOPIC_TERMINAL_OPENED, VIEW_TERMINAL, createJsSessionBackend, emptyTerminalState, openJsSessionTerminal, parseTerminalState, registerTerminalProfile, serializeTerminalState, terminalService, terminalService as terminalTaskRunner, unbindJsSession };
|
|
74
73
|
|
|
75
74
|
//# sourceMappingURL=api.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/i18n.de.json
|
|
2
2
|
var EXT_TERMINAL_NAME = "Terminal";
|
|
3
3
|
var EXT_TERMINAL_DESC = "VS Code-ähnliches Terminal-Panel mit erweiterbaren Profilen.";
|
|
4
4
|
var TERMINAL_TAB_LABEL = "Terminal";
|
|
@@ -29,7 +29,6 @@ var i18n_de_default = {
|
|
|
29
29
|
TERMINAL_PROFILE_UNAVAILABLE,
|
|
30
30
|
TERMINAL_DEFAULT_JS_NAME
|
|
31
31
|
};
|
|
32
|
-
//#endregion
|
|
33
32
|
export { EXT_TERMINAL_DESC, EXT_TERMINAL_NAME, TERMINAL_CLEAR, TERMINAL_DEFAULT_JS_NAME, TERMINAL_KILL, TERMINAL_KILL_ALL, TERMINAL_KILL_CONFIRM, TERMINAL_NEW, TERMINAL_PROFILE_UNAVAILABLE, TERMINAL_RENAME, TERMINAL_RENAME_PROMPT, TERMINAL_SELECT_PROFILE, TERMINAL_SPLIT, TERMINAL_TAB_LABEL, i18n_de_default as default };
|
|
34
33
|
|
|
35
|
-
//# sourceMappingURL=i18n.de-
|
|
34
|
+
//# sourceMappingURL=i18n.de-CXiNR_66.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.de-
|
|
1
|
+
{"version":3,"file":"i18n.de-CXiNR_66.js","names":[],"sources":["../src/i18n.de.json"],"sourcesContent":["{\n \"EXT_TERMINAL_NAME\": \"Terminal\",\n \"EXT_TERMINAL_DESC\": \"VS Code-ähnliches Terminal-Panel mit erweiterbaren Profilen.\",\n \"TERMINAL_TAB_LABEL\": \"Terminal\",\n \"TERMINAL_NEW\": \"Neues Terminal\",\n \"TERMINAL_KILL\": \"Terminal beenden\",\n \"TERMINAL_KILL_CONFIRM\": \"Terminal \\\"{name}\\\" beenden?\",\n \"TERMINAL_KILL_ALL\": \"Alle Terminals beenden\",\n \"TERMINAL_CLEAR\": \"Leeren\",\n \"TERMINAL_RENAME\": \"Umbenennen\",\n \"TERMINAL_SPLIT\": \"Terminal teilen\",\n \"TERMINAL_SELECT_PROFILE\": \"Profil wählen\",\n \"TERMINAL_RENAME_PROMPT\": \"Terminalname\",\n \"TERMINAL_PROFILE_UNAVAILABLE\": \"Profil nicht verfügbar: {profileId}\",\n \"TERMINAL_DEFAULT_JS_NAME\": \"Befehle\"\n}\n"],"mappings":""}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/i18n.en.json
|
|
2
2
|
var EXT_TERMINAL_NAME = "Terminal";
|
|
3
3
|
var EXT_TERMINAL_DESC = "VS Code-style terminal panel with pluggable profiles.";
|
|
4
4
|
var TERMINAL_TAB_LABEL = "Terminal";
|
|
@@ -29,7 +29,6 @@ var i18n_en_default = {
|
|
|
29
29
|
TERMINAL_PROFILE_UNAVAILABLE,
|
|
30
30
|
TERMINAL_DEFAULT_JS_NAME
|
|
31
31
|
};
|
|
32
|
-
//#endregion
|
|
33
32
|
export { EXT_TERMINAL_DESC, EXT_TERMINAL_NAME, TERMINAL_CLEAR, TERMINAL_DEFAULT_JS_NAME, TERMINAL_KILL, TERMINAL_KILL_ALL, TERMINAL_KILL_CONFIRM, TERMINAL_NEW, TERMINAL_PROFILE_UNAVAILABLE, TERMINAL_RENAME, TERMINAL_RENAME_PROMPT, TERMINAL_SELECT_PROFILE, TERMINAL_SPLIT, TERMINAL_TAB_LABEL, i18n_en_default as default };
|
|
34
33
|
|
|
35
|
-
//# sourceMappingURL=i18n.en-
|
|
34
|
+
//# sourceMappingURL=i18n.en-L4uYF63V.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.en-
|
|
1
|
+
{"version":3,"file":"i18n.en-L4uYF63V.js","names":[],"sources":["../src/i18n.en.json"],"sourcesContent":["{\n \"EXT_TERMINAL_NAME\": \"Terminal\",\n \"EXT_TERMINAL_DESC\": \"VS Code-style terminal panel with pluggable profiles.\",\n \"TERMINAL_TAB_LABEL\": \"Terminal\",\n \"TERMINAL_NEW\": \"New Terminal\",\n \"TERMINAL_KILL\": \"Kill Terminal\",\n \"TERMINAL_KILL_CONFIRM\": \"Kill terminal \\\"{name}\\\"?\",\n \"TERMINAL_KILL_ALL\": \"Kill All Terminals\",\n \"TERMINAL_CLEAR\": \"Clear\",\n \"TERMINAL_RENAME\": \"Rename\",\n \"TERMINAL_SPLIT\": \"Split Terminal\",\n \"TERMINAL_SELECT_PROFILE\": \"Select Profile\",\n \"TERMINAL_RENAME_PROMPT\": \"Terminal name\",\n \"TERMINAL_PROFILE_UNAVAILABLE\": \"Profile unavailable: {profileId}\",\n \"TERMINAL_DEFAULT_JS_NAME\": \"Commands\"\n}\n"],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { extensionRegistry, i18n } from "@eclipse-docks/core";
|
|
2
2
|
import pkg from "../package.json";
|
|
3
|
-
|
|
3
|
+
// src/index.ts
|
|
4
4
|
var t = await i18n(/* #__PURE__ */ Object.assign({
|
|
5
|
-
"./i18n.de.json": () => import("./i18n.de-
|
|
6
|
-
"./i18n.en.json": () => import("./i18n.en-
|
|
5
|
+
"./i18n.de.json": () => import("./i18n.de-CXiNR_66.js"),
|
|
6
|
+
"./i18n.en.json": () => import("./i18n.en-L4uYF63V.js")
|
|
7
7
|
}), true);
|
|
8
8
|
extensionRegistry.registerExtension({
|
|
9
9
|
id: pkg.name,
|
|
10
10
|
name: t.EXT_TERMINAL_NAME,
|
|
11
11
|
description: t.EXT_TERMINAL_DESC,
|
|
12
|
-
loader: () => import("./terminal-extension-
|
|
12
|
+
loader: () => import("./terminal-extension-B0d4I4cK.js"),
|
|
13
13
|
icon: "terminal"
|
|
14
14
|
});
|
|
15
|
-
//#endregion
|
|
16
15
|
|
|
17
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PANEL_BOTTOM, commandRegistry, confirmDialog, contributionRegistry, createJsRuntime, i18n, publish, renderDropdownItem, rootContext, subscribe, unsubscribe } from "@eclipse-docks/core";
|
|
2
2
|
import { html } from "@eclipse-docks/core/externals/lit";
|
|
3
|
-
|
|
3
|
+
// src/terminal-api.ts
|
|
4
4
|
var TARGET_TERMINAL_PROFILES = "system.terminal.profiles";
|
|
5
5
|
var VIEW_TERMINAL = "view.terminal";
|
|
6
6
|
var TERMINAL_INSTANCES_TABS_ID = "terminal-instances";
|
|
@@ -10,8 +10,7 @@ var TERMINAL_PANEL_SETTINGS_KEY = "docks-terminal-panel";
|
|
|
10
10
|
var TOPIC_TERMINAL_OPENED = "events/terminal/opened";
|
|
11
11
|
var TOPIC_TERMINAL_CLOSED = "events/terminal/closed";
|
|
12
12
|
var TOPIC_TERMINAL_ACTIVE_CHANGED = "events/terminal/activeChanged";
|
|
13
|
-
|
|
14
|
-
//#region src/terminal-persistence.ts
|
|
13
|
+
// src/terminal-persistence.ts
|
|
15
14
|
var MAX_PERSISTED_ENV_KEYS = 32;
|
|
16
15
|
function serializeTerminalState(state) {
|
|
17
16
|
return {
|
|
@@ -68,11 +67,10 @@ function emptyTerminalState() {
|
|
|
68
67
|
preferredProfileId: null
|
|
69
68
|
};
|
|
70
69
|
}
|
|
71
|
-
|
|
72
|
-
//#region src/terminal-service.ts
|
|
70
|
+
// src/terminal-service.ts
|
|
73
71
|
var t = await i18n(/* #__PURE__ */ Object.assign({
|
|
74
|
-
"./i18n.de.json": () => import("./i18n.de-
|
|
75
|
-
"./i18n.en.json": () => import("./i18n.en-
|
|
72
|
+
"./i18n.de.json": () => import("./i18n.de-CXiNR_66.js"),
|
|
73
|
+
"./i18n.en.json": () => import("./i18n.en-L4uYF63V.js")
|
|
76
74
|
}), true);
|
|
77
75
|
async function confirmKillTerminal(name) {
|
|
78
76
|
return confirmDialog(t.TERMINAL_KILL_CONFIRM({ name }));
|
|
@@ -378,8 +376,7 @@ function registerTerminalProfile(contribution) {
|
|
|
378
376
|
})
|
|
379
377
|
});
|
|
380
378
|
}
|
|
381
|
-
|
|
382
|
-
//#region src/shell-parser.ts
|
|
379
|
+
// src/shell-parser.ts
|
|
383
380
|
var NAMED_PARAM_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*=.*$/;
|
|
384
381
|
function tokenize(segment) {
|
|
385
382
|
const tokens = [];
|
|
@@ -463,8 +460,7 @@ function parseShellLine(line, commandRegistry) {
|
|
|
463
460
|
};
|
|
464
461
|
});
|
|
465
462
|
}
|
|
466
|
-
|
|
467
|
-
//#region src/line-input.ts
|
|
463
|
+
// src/line-input.ts
|
|
468
464
|
/** Minimal readline-style editor for xterm-backed REPL backends. */
|
|
469
465
|
var LineInput = class {
|
|
470
466
|
constructor(write) {
|
|
@@ -609,8 +605,7 @@ var LineInput = class {
|
|
|
609
605
|
this.historyDraft = "";
|
|
610
606
|
}
|
|
611
607
|
};
|
|
612
|
-
|
|
613
|
-
//#region src/commands-backend.ts
|
|
608
|
+
// src/commands-backend.ts
|
|
614
609
|
function mapOutputToParams(output, producerCommand) {
|
|
615
610
|
if (output == null) return {};
|
|
616
611
|
if (typeof output === "object" && !Array.isArray(output)) return output;
|
|
@@ -705,8 +700,7 @@ var CommandsBackend = class {
|
|
|
705
700
|
this.emit(this.prompt);
|
|
706
701
|
}
|
|
707
702
|
};
|
|
708
|
-
|
|
709
|
-
//#region src/js-terminal-backend.ts
|
|
703
|
+
// src/js-terminal-backend.ts
|
|
710
704
|
var JS_REPL_PROFILE_ID = "terminal.javascript-repl";
|
|
711
705
|
var JS_SESSION_PROFILE_ID = "terminal.javascript-session";
|
|
712
706
|
var PROMPT = "> ";
|
|
@@ -804,7 +798,6 @@ var JsReplBackend = class {
|
|
|
804
798
|
}
|
|
805
799
|
}
|
|
806
800
|
};
|
|
807
|
-
//#endregion
|
|
808
801
|
export { TERMINAL_PANEL_SETTINGS_KEY as _, openJsSessionTerminal as a, TOPIC_TERMINAL_OPENED as b, LineInput as c, emptyTerminalState as d, parseTerminalState as f, TERMINAL_NEW_DROPDOWN as g, TERMINAL_INSTANCES_TABS_ID as h, createJsSessionBackend as i, registerTerminalProfile as l, TARGET_TERMINAL_PROFILES as m, JS_SESSION_PROFILE_ID as n, unbindJsSession as o, serializeTerminalState as p, JsReplBackend as r, CommandsBackend as s, JS_REPL_PROFILE_ID as t, terminalService as u, TOPIC_TERMINAL_ACTIVE_CHANGED as v, VIEW_TERMINAL as x, TOPIC_TERMINAL_CLOSED as y };
|
|
809
802
|
|
|
810
|
-
//# sourceMappingURL=js-terminal-backend-
|
|
803
|
+
//# sourceMappingURL=js-terminal-backend-C6NeZIFc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js-terminal-backend-CRxDAwvr.js","names":[],"sources":["../src/terminal-api.ts","../src/terminal-persistence.ts","../src/terminal-service.ts","../src/shell-parser.ts","../src/line-input.ts","../src/commands-backend.ts","../src/js-terminal-backend.ts"],"sourcesContent":["export const TARGET_TERMINAL_PROFILES = 'system.terminal.profiles';\n\nexport const VIEW_TERMINAL = 'view.terminal';\nexport const TERMINAL_INSTANCES_TABS_ID = 'terminal-instances';\n/** Dropdown target: contributors register items that create a terminal with a profile. */\nexport const TERMINAL_NEW_DROPDOWN = `${TERMINAL_INSTANCES_TABS_ID}-new`;\nexport const TERMINAL_PANEL_SETTINGS_KEY = 'docks-terminal-panel';\n\nexport const TOPIC_TERMINAL_OPENED = 'events/terminal/opened';\nexport const TOPIC_TERMINAL_CLOSED = 'events/terminal/closed';\nexport const TOPIC_TERMINAL_ACTIVE_CHANGED = 'events/terminal/activeChanged';\n\nexport interface TerminalDimensions {\n cols: number;\n rows: number;\n}\n\nexport interface TerminalCreationOptions {\n name?: string;\n profileId?: string;\n cwd?: string;\n env?: Record<string, string>;\n groupId?: string;\n hidden?: boolean;\n}\n\nexport interface TerminalBackend {\n open?(initialDimensions?: TerminalDimensions): void | Promise<void>;\n close?(): void | Promise<void>;\n onDidWrite(callback: (data: string) => void): () => void;\n handleInput(data: string): void;\n setDimensions?(dimensions: TerminalDimensions): void;\n}\n\nexport interface TerminalProfileContribution {\n id: string;\n label: string;\n icon?: string;\n isDefault?: boolean;\n hidden?: boolean;\n /**\n * When false, terminals of this profile are not saved or restored across reloads.\n * Defaults to true.\n */\n persist?: boolean;\n create(options?: TerminalCreationOptions): Promise<TerminalBackend>;\n}\n\nexport interface TerminalTaskPresentation {\n profileId: string;\n reveal?: 'always' | 'silent' | 'never';\n focus?: boolean;\n clear?: boolean;\n}\n\nexport interface Terminal {\n readonly id: string;\n name: string;\n readonly profileId: string;\n readonly creationOptions: TerminalCreationOptions;\n readonly groupId: string;\n hidden: boolean;\n sendText(text: string, addNewLine?: boolean): void;\n show(preserveFocus?: boolean): void;\n hide(): void;\n dispose(options?: { confirm?: boolean }): Promise<void>;\n clear?(): void;\n}\n\n/** Internal terminal handle used by the host UI (not for provider extensions). */\nexport interface TerminalRuntime extends Terminal {\n backend: TerminalBackend | null;\n clearScreen?: () => void;\n}\n\nexport interface TerminalTaskRunner {\n runTask(\n presentation: TerminalTaskPresentation,\n execute: (terminal: Terminal) => Promise<void>\n ): Promise<void>;\n}\n\nexport interface PersistedTerminalState {\n terminals: PersistedTerminalEntry[];\n activeTerminalId: string | null;\n preferredProfileId: string | null;\n}\n\nexport interface PersistedTerminalEntry {\n id: string;\n name: string;\n profileId: string;\n groupId: string;\n creationOptions: TerminalCreationOptions;\n}\n","import type { PersistedTerminalEntry, PersistedTerminalState, TerminalCreationOptions } from './terminal-api';\n\nconst MAX_PERSISTED_ENV_KEYS = 32;\n\nexport function serializeTerminalState(state: PersistedTerminalState): PersistedTerminalState {\n return {\n activeTerminalId: state.activeTerminalId,\n preferredProfileId: state.preferredProfileId,\n terminals: state.terminals.map(serializeTerminalEntry),\n };\n}\n\nfunction serializeTerminalEntry(entry: PersistedTerminalEntry): PersistedTerminalEntry {\n const opts = entry.creationOptions;\n const env = opts.env\n ? Object.fromEntries(Object.entries(opts.env).slice(0, MAX_PERSISTED_ENV_KEYS))\n : undefined;\n return {\n id: entry.id,\n name: entry.name,\n profileId: entry.profileId,\n groupId: entry.groupId,\n creationOptions: {\n name: opts.name,\n profileId: opts.profileId,\n cwd: opts.cwd,\n env,\n groupId: opts.groupId,\n },\n };\n}\n\nexport function parseTerminalState(raw: unknown): PersistedTerminalState | null {\n if (!raw || typeof raw !== 'object') return null;\n const obj = raw as Record<string, unknown>;\n if (!Array.isArray(obj.terminals)) return null;\n\n const terminals: PersistedTerminalEntry[] = [];\n for (const item of obj.terminals) {\n if (!item || typeof item !== 'object') continue;\n const t = item as Record<string, unknown>;\n if (typeof t.id !== 'string' || typeof t.name !== 'string' || typeof t.profileId !== 'string') {\n continue;\n }\n const creationOptions = (t.creationOptions ?? {}) as TerminalCreationOptions;\n terminals.push({\n id: t.id,\n name: t.name,\n profileId: t.profileId,\n groupId: typeof t.groupId === 'string' ? t.groupId : t.id,\n creationOptions,\n });\n }\n\n return {\n terminals,\n activeTerminalId: typeof obj.activeTerminalId === 'string' ? obj.activeTerminalId : null,\n preferredProfileId: typeof obj.preferredProfileId === 'string' ? obj.preferredProfileId : null,\n };\n}\n\nexport function emptyTerminalState(): PersistedTerminalState {\n return { terminals: [], activeTerminalId: null, preferredProfileId: null };\n}\n","import { html } from '@eclipse-docks/core/externals/lit';\nimport {\n confirmDialog,\n contributionRegistry,\n i18n,\n PANEL_BOTTOM,\n publish,\n renderDropdownItem,\n rootContext,\n subscribe,\n unsubscribe,\n type TabContribution,\n} from '@eclipse-docks/core';\nimport {\n TARGET_TERMINAL_PROFILES,\n TERMINAL_NEW_DROPDOWN,\n TOPIC_TERMINAL_ACTIVE_CHANGED,\n TOPIC_TERMINAL_CLOSED,\n TOPIC_TERMINAL_OPENED,\n VIEW_TERMINAL,\n type Terminal,\n type TerminalBackend,\n type TerminalCreationOptions,\n type TerminalProfileContribution,\n type TerminalTaskPresentation,\n type TerminalTaskRunner,\n type PersistedTerminalState,\n type TerminalRuntime,\n} from './terminal-api';\nimport { emptyTerminalState, parseTerminalState, serializeTerminalState } from './terminal-persistence';\n\nconst t = await i18n(import.meta.glob('./i18n*.json'), true);\n\nasync function confirmKillTerminal(name: string): Promise<boolean> {\n return confirmDialog(t.TERMINAL_KILL_CONFIRM({ name }));\n}\n\ninterface TerminalTabsHost {\n has(key: string): boolean;\n activate(key: string): void;\n open(contribution: TabContribution): void;\n closeTab(event: Event, tabName: string): Promise<void>;\n updateTabLabel(tabName: string, label: string): void;\n}\n\nexport type { TerminalTabsHost };\n\nlet terminalCounter = 0;\n\nfunction nextTerminalId(): string {\n terminalCounter += 1;\n return `terminal-${terminalCounter}`;\n}\n\nclass TerminalInstance implements TerminalRuntime {\n readonly id: string;\n name: string;\n readonly profileId: string;\n readonly creationOptions: TerminalCreationOptions;\n readonly groupId: string;\n hidden = false;\n backend: TerminalBackend | null = null;\n clearScreen?: () => void;\n private skipCloseConfirm = false;\n\n constructor(\n id: string,\n name: string,\n profileId: string,\n creationOptions: TerminalCreationOptions,\n groupId: string\n ) {\n this.id = id;\n this.name = name;\n this.profileId = profileId;\n this.creationOptions = creationOptions;\n this.groupId = groupId;\n }\n\n sendText(text: string, addNewLine = true): void {\n if (!this.backend) return;\n this.backend.handleInput(text + (addNewLine ? '\\r' : ''));\n }\n\n show(_preserveFocus?: boolean): void {\n terminalService.focusTerminalPanel();\n terminalService.activateTerminal(this.id);\n this.hidden = false;\n }\n\n hide(): void {\n this.hidden = true;\n }\n\n async dispose(options?: { confirm?: boolean }): Promise<void> {\n if (options?.confirm === false) this.skipCloseConfirm = true;\n await terminalService.disposeTerminal(this.id);\n }\n\n shouldConfirmClose(): boolean {\n return !this.skipCloseConfirm;\n }\n\n clear(): void {\n this.clearScreen?.();\n }\n}\n\nclass TerminalService implements TerminalTaskRunner {\n private terminals = new Map<string, TerminalInstance>();\n private activeTerminalId: string | null = null;\n private preferredProfileId: string | null = null;\n private persistenceHandler: (() => Promise<PersistedTerminalState | null>) | null = null;\n private persistCallback: ((state: PersistedTerminalState) => Promise<void>) | null = null;\n private restoreStarted = false;\n private instanceTabsHost: TerminalTabsHost | null = null;\n\n get activeTerminal(): Terminal | undefined {\n if (!this.activeTerminalId) return undefined;\n return this.terminals.get(this.activeTerminalId);\n }\n\n getTerminals(): Terminal[] {\n return [...this.terminals.values()];\n }\n\n onDidOpenTerminal(callback: (terminal: Terminal) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_OPENED, callback);\n return () => unsubscribe(token);\n }\n\n onDidCloseTerminal(callback: (terminal: Terminal) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_CLOSED, callback);\n return () => unsubscribe(token);\n }\n\n onDidChangeActiveTerminal(callback: (terminal: Terminal | undefined) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_ACTIVE_CHANGED, callback);\n return () => unsubscribe(token);\n }\n\n setPersistenceHandlers(\n load: () => Promise<PersistedTerminalState | null>,\n save: (state: PersistedTerminalState) => Promise<void>\n ): void {\n this.persistenceHandler = load;\n this.persistCallback = save;\n }\n\n async restorePersistedTerminals(): Promise<void> {\n if (this.restoreStarted || !this.persistenceHandler) return;\n this.restoreStarted = true;\n const raw = await this.persistenceHandler();\n const state = raw ? parseTerminalState(raw) : null;\n if (!state || state.terminals.length === 0) return;\n\n this.preferredProfileId = state.preferredProfileId;\n for (const entry of state.terminals) {\n if (!this.isProfilePersistent(entry.profileId)) continue;\n await this.createTerminal({\n ...entry.creationOptions,\n name: entry.name,\n profileId: entry.profileId,\n groupId: entry.groupId,\n }, entry.id);\n }\n if (state.activeTerminalId && this.terminals.has(state.activeTerminalId)) {\n this.setActiveTerminal(state.activeTerminalId);\n }\n }\n\n /** Profiles default to persistent; opt out with `persist: false`. */\n private isProfilePersistent(profileId: string): boolean {\n const profile = this.getProfiles().find((p) => p.id === profileId);\n return profile?.persist !== false;\n }\n\n getProfiles(): TerminalProfileContribution[] {\n return contributionRegistry.getContributions<TerminalProfileContribution>(TARGET_TERMINAL_PROFILES);\n }\n\n resolveDefaultProfileId(): string | null {\n if (this.preferredProfileId) {\n const preferred = this.getProfiles().find((p) => p.id === this.preferredProfileId);\n if (preferred) return preferred.id;\n }\n const profiles = this.getProfiles().filter((p) => !p.hidden);\n const defaultProfile = profiles.find((p) => p.isDefault) ?? profiles[0];\n return defaultProfile?.id ?? null;\n }\n\n setInstanceTabsHost(host: TerminalTabsHost | null): void {\n this.instanceTabsHost = host;\n }\n\n getInstanceTabs(): TerminalTabsHost | null {\n return this.instanceTabsHost;\n }\n\n focusTerminalPanel(): void {\n const panel = document.querySelector(`docks-tabs#${PANEL_BOTTOM}`) as TerminalTabsHost | null;\n panel?.activate(VIEW_TERMINAL);\n }\n\n activateTerminal(id: string): void {\n const tabs = this.getInstanceTabs();\n if (tabs?.has(id)) {\n tabs.activate(id);\n }\n this.setActiveTerminal(id);\n }\n\n private setActiveTerminal(id: string | null): void {\n if (this.activeTerminalId === id) return;\n this.activeTerminalId = id;\n publish(TOPIC_TERMINAL_ACTIVE_CHANGED, id ? this.terminals.get(id) : undefined);\n void this.persistState();\n }\n\n async createTerminal(\n options: TerminalCreationOptions = {},\n forcedId?: string\n ): Promise<Terminal | undefined> {\n const profileId = options.profileId ?? this.resolveDefaultProfileId();\n if (!profileId) return undefined;\n\n const profile = this.getProfiles().find((p) => p.id === profileId);\n if (!profile) return undefined;\n\n const id = forcedId ?? nextTerminalId();\n if (forcedId) syncTerminalCounterFromId(forcedId);\n const groupId = options.groupId ?? id;\n const name = options.name ?? profile.label;\n\n let backend: TerminalBackend;\n try {\n backend = await profile.create({ ...options, profileId, name, groupId });\n } catch {\n return undefined;\n }\n\n const terminal = new TerminalInstance(id, name, profileId, { ...options, profileId, name, groupId }, groupId);\n terminal.backend = backend;\n terminal.hidden = options.hidden ?? false;\n\n this.terminals.set(id, terminal);\n if (!terminal.hidden) {\n this.focusTerminalPanel();\n await this.whenTabsHostReady();\n }\n this.openTerminalTab(terminal, profile.icon);\n\n if (!terminal.hidden) {\n this.focusTerminalPanel();\n this.activateTerminal(id);\n }\n\n publish(TOPIC_TERMINAL_OPENED, terminal);\n void this.persistState();\n return terminal;\n }\n\n /** The panel binds its tab host after the bottom panel is shown. */\n private whenTabsHostReady(): Promise<void> {\n if (this.instanceTabsHost) return Promise.resolve();\n const started = performance.now();\n return new Promise((resolve) => {\n const check = () => {\n if (this.instanceTabsHost || performance.now() - started > 1000) {\n resolve();\n return;\n }\n requestAnimationFrame(check);\n };\n requestAnimationFrame(check);\n });\n }\n\n private openTerminalTab(terminal: TerminalInstance, icon?: string): void {\n const tabs = this.getInstanceTabs();\n if (!tabs) return;\n\n const contribution: TabContribution = {\n name: terminal.id,\n label: terminal.name,\n icon: icon ?? 'terminal',\n closable: true,\n toolbar: false,\n beforeClose: async () => terminal.shouldConfirmClose() ? confirmKillTerminal(terminal.name) : true,\n component: (tabId: string) =>\n html`<docks-terminal-view id=\"${tabId}\" .terminal=${terminal}></docks-terminal-view>`,\n };\n\n if (tabs.has(terminal.id)) {\n tabs.activate(terminal.id);\n return;\n }\n tabs.open(contribution);\n }\n\n async disposeTerminal(id: string, options?: { skipTabRemoval?: boolean }): Promise<void> {\n const terminal = this.terminals.get(id);\n if (!terminal) return;\n\n if (!options?.skipTabRemoval) {\n const tabs = this.getInstanceTabs();\n if (tabs?.has(id)) {\n await tabs.closeTab(new Event('close'), id);\n return;\n }\n }\n\n await terminal.backend?.close?.();\n terminal.backend = null;\n this.terminals.delete(id);\n\n if (this.activeTerminalId === id) {\n const remaining = [...this.terminals.keys()];\n this.setActiveTerminal(remaining.length > 0 ? remaining[remaining.length - 1] : null);\n }\n\n publish(TOPIC_TERMINAL_CLOSED, terminal);\n void this.persistState();\n }\n\n async killAll(): Promise<void> {\n const tabs = this.getInstanceTabs();\n const ids = [...this.terminals.keys()];\n for (const id of ids) {\n if (tabs?.has(id)) {\n await tabs.closeTab(new Event('close'), id);\n } else {\n await this.disposeTerminal(id, { skipTabRemoval: true });\n }\n }\n }\n\n renameActiveTerminal(name: string): void {\n const active = this.activeTerminal;\n if (!active || !(active instanceof TerminalInstance)) return;\n active.name = name;\n this.getInstanceTabs()?.updateTabLabel(active.id, name);\n void this.persistState();\n }\n\n setPreferredProfile(profileId: string): void {\n this.preferredProfileId = profileId;\n void this.persistState();\n }\n\n clearActiveTerminal(): void {\n this.activeTerminal?.clear?.();\n }\n\n async runTask(\n presentation: TerminalTaskPresentation,\n execute: (terminal: Terminal) => Promise<void>\n ): Promise<void> {\n let terminal = this.getTerminals().find((t) => t.profileId === presentation.profileId);\n if (!terminal) {\n terminal = await this.createTerminal({ profileId: presentation.profileId });\n }\n if (!terminal) return;\n\n if (presentation.reveal !== 'never') {\n if (presentation.focus !== false) {\n terminal.show();\n } else {\n this.focusTerminalPanel();\n }\n }\n if (presentation.clear) {\n terminal.clear?.();\n }\n await execute(terminal);\n }\n\n private async persistState(): Promise<void> {\n if (!this.persistCallback) return;\n const terminals = [...this.terminals.values()]\n .filter((t) => this.isProfilePersistent(t.profileId))\n .map((t) => ({\n id: t.id,\n name: t.name,\n profileId: t.profileId,\n groupId: t.groupId,\n creationOptions: t.creationOptions,\n }));\n const ids = new Set(terminals.map((t) => t.id));\n const state: PersistedTerminalState = {\n activeTerminalId:\n this.activeTerminalId && ids.has(this.activeTerminalId) ? this.activeTerminalId : null,\n preferredProfileId: this.preferredProfileId,\n terminals,\n };\n await this.persistCallback(serializeTerminalState(state));\n }\n\n handleTabActivated(tabName: string): void {\n if (this.terminals.has(tabName)) {\n this.setActiveTerminal(tabName);\n }\n }\n\n handleTabClosed(tabName: string): void {\n if (this.terminals.has(tabName)) {\n void this.disposeTerminal(tabName, { skipTabRemoval: true });\n }\n }\n}\n\nfunction syncTerminalCounterFromId(id: string): void {\n const match = /^terminal-(\\d+)$/.exec(id);\n if (!match) return;\n const n = Number.parseInt(match[1], 10);\n if (n > terminalCounter) terminalCounter = n;\n}\n\nexport const terminalService = new TerminalService();\nrootContext.put('terminalService', terminalService);\n\nexport function registerTerminalProfile(contribution: TerminalProfileContribution): void {\n contributionRegistry.registerContribution(TARGET_TERMINAL_PROFILES, contribution);\n if (contribution.hidden) return;\n const profileId = contribution.id;\n contributionRegistry.registerContribution(TERMINAL_NEW_DROPDOWN, {\n label: contribution.label,\n icon: contribution.icon ?? 'terminal',\n component: () => renderDropdownItem({\n icon: contribution.icon ?? 'terminal',\n label: contribution.label,\n title: contribution.label,\n action: () => {\n terminalService.setPreferredProfile(profileId);\n void terminalService.createTerminal({ profileId });\n },\n }),\n });\n}\n","import type { CommandRegistry, Command } from '@eclipse-docks/core';\n\nexport interface ParsedCommand {\n commandId: string;\n params: Record<string, string | boolean>;\n}\n\nexport interface ParsedSegment {\n command: ParsedCommand;\n operator: '&&' | '|' | null;\n}\n\nconst NAMED_PARAM_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*=.*$/;\n\nfunction tokenize(segment: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n const len = segment.length;\n\n while (i < len) {\n while (i < len && /\\s/.test(segment[i])) i++;\n if (i >= len) break;\n\n if (segment[i] === '\"') {\n let end = i + 1;\n while (end < len && segment[end] !== '\"') {\n if (segment[end] === '\\\\') end++;\n end++;\n }\n tokens.push(segment.slice(i + 1, end).replace(/\\\\\"/g, '\"'));\n i = end + 1;\n } else {\n let start = i;\n while (i < len && !/\\s/.test(segment[i]) && segment[i] !== '\"') i++;\n if (i > start) {\n tokens.push(segment.slice(start, i));\n }\n }\n }\n return tokens;\n}\n\nfunction splitChain(line: string): { segment: string; operator: '&&' | '|' | null }[] {\n const result: { segment: string; operator: '&&' | '|' | null }[] = [];\n const regex = /(\\s*&&\\s*|\\s*\\|\\s*)/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(line)) !== null) {\n const segment = line.slice(lastIndex, match.index).trim();\n if (segment) {\n const op = match[0].includes('|') ? ('|' as const) : ('&&' as const);\n result.push({ segment, operator: op });\n }\n lastIndex = regex.lastIndex;\n }\n const tail = line.slice(lastIndex).trim();\n if (tail) {\n result.push({ segment: tail, operator: null });\n }\n return result;\n}\n\nfunction resolveParams(\n tokens: string[],\n command: Command | undefined\n): Record<string, string | boolean> {\n const params: Record<string, string | boolean> = {};\n const positionals: string[] = [];\n const paramNames = command?.parameters?.map((p) => p.name) ?? [];\n\n for (const token of tokens) {\n if (NAMED_PARAM_REGEX.test(token)) {\n const eqIdx = token.indexOf('=');\n const name = token.slice(0, eqIdx);\n const value = token.slice(eqIdx + 1);\n params[name] = value === 'true' || value === 'false' ? value === 'true' : value;\n } else {\n positionals.push(token);\n }\n }\n\n paramNames.forEach((name, i) => {\n if (positionals[i] !== undefined && !(name in params)) {\n params[name] = positionals[i];\n }\n });\n\n return params;\n}\n\nexport function parseShellLine(line: string, commandRegistry: CommandRegistry): ParsedSegment[] {\n const segments = splitChain(line);\n return segments.map(({ segment, operator }) => {\n const tokens = tokenize(segment);\n if (tokens.length === 0) {\n return { command: { commandId: '', params: {} }, operator };\n }\n const commandId = tokens[0];\n const command = commandRegistry.hasCommand(commandId)\n ? commandRegistry.getCommand(commandId)\n : undefined;\n const params = resolveParams(tokens.slice(1), command);\n return { command: { commandId, params }, operator };\n });\n}\n","/** Minimal readline-style editor for xterm-backed REPL backends. */\nexport class LineInput {\n private buffer = '';\n private cursor = 0;\n private history: string[] = [];\n private historyDraft = '';\n private historyIndex = 0;\n\n constructor(private write: (data: string) => void) {}\n\n reset(): void {\n this.buffer = '';\n this.cursor = 0;\n this.historyDraft = '';\n this.historyIndex = this.history.length;\n }\n\n /** Returns the submitted line on Enter, otherwise null. */\n feed(data: string): string | null {\n if (data === '\\r') {\n const line = this.buffer;\n this.pushHistory(line);\n this.buffer = '';\n this.cursor = 0;\n this.write('\\r\\n');\n return line;\n }\n\n if (data === '\\u007f' || data === '\\b') {\n this.deleteBackward();\n return null;\n }\n\n if (data === '\\x1b[D' || data === '\\x1bOD') {\n this.move(-1);\n return null;\n }\n if (data === '\\x1b[C' || data === '\\x1bOC') {\n this.move(1);\n return null;\n }\n if (data === '\\x1b[A' || data === '\\x1bOA') {\n this.historyPrev();\n return null;\n }\n if (data === '\\x1b[B' || data === '\\x1bOB') {\n this.historyNext();\n return null;\n }\n if (data === '\\x1b[3~') {\n this.deleteForward();\n return null;\n }\n if (data === '\\x1b[H' || data === '\\x1bOH') {\n this.cursorHome();\n return null;\n }\n if (data === '\\x1b[F' || data === '\\x1bOF') {\n this.cursorEnd();\n return null;\n }\n\n if (data.startsWith('\\x1b')) return null;\n\n for (const char of data) {\n if (char < ' ') continue;\n this.insert(char);\n }\n return null;\n }\n\n private move(delta: number): void {\n const next = this.cursor + delta;\n if (next < 0 || next > this.buffer.length) return;\n const steps = Math.abs(delta);\n this.cursor = next;\n this.write(delta < 0 ? `\\x1b[${steps}D` : `\\x1b[${steps}C`);\n }\n\n private cursorHome(): void {\n if (this.cursor === 0) return;\n this.write(`\\x1b[${this.cursor}D`);\n this.cursor = 0;\n }\n\n private cursorEnd(): void {\n const steps = this.buffer.length - this.cursor;\n if (steps <= 0) return;\n this.write(`\\x1b[${steps}C`);\n this.cursor = this.buffer.length;\n }\n\n private insert(char: string): void {\n if (this.cursor === this.buffer.length) {\n this.buffer += char;\n this.cursor++;\n this.write(char);\n return;\n }\n const tail = this.buffer.slice(this.cursor);\n this.buffer = this.buffer.slice(0, this.cursor) + char + tail;\n this.cursor++;\n this.write(char + tail + `\\x1b[${tail.length}D`);\n }\n\n private deleteBackward(): void {\n if (this.cursor === 0) return;\n if (this.cursor === this.buffer.length) {\n this.buffer = this.buffer.slice(0, -1);\n this.cursor--;\n this.write('\\b \\b');\n return;\n }\n const after = this.buffer.slice(this.cursor);\n this.buffer = this.buffer.slice(0, this.cursor - 1) + after;\n this.cursor--;\n this.write(`\\b${after} ` + `\\x1b[${after.length + 1}D`);\n }\n\n private deleteForward(): void {\n if (this.cursor >= this.buffer.length) return;\n const after = this.buffer.slice(this.cursor + 1);\n this.write(`${after} ` + `\\x1b[${after.length + 1}D`);\n this.buffer = this.buffer.slice(0, this.cursor) + after;\n }\n\n private replaceBuffer(next: string): void {\n if (this.cursor > 0) this.write(`\\x1b[${this.cursor}D`);\n if (this.buffer.length > 0) this.write('\\x1b[K');\n this.buffer = next;\n this.cursor = next.length;\n if (next) this.write(next);\n }\n\n private historyPrev(): void {\n if (this.history.length === 0) return;\n if (this.historyIndex === this.history.length) {\n this.historyDraft = this.buffer;\n }\n if (this.historyIndex === 0) return;\n this.historyIndex--;\n this.replaceBuffer(this.history[this.historyIndex]);\n }\n\n private historyNext(): void {\n if (this.historyIndex >= this.history.length) return;\n this.historyIndex++;\n if (this.historyIndex === this.history.length) {\n this.replaceBuffer(this.historyDraft);\n this.historyDraft = '';\n return;\n }\n this.replaceBuffer(this.history[this.historyIndex]);\n }\n\n private pushHistory(line: string): void {\n if (line.length > 0 && this.history[this.history.length - 1] !== line) {\n this.history.push(line);\n }\n this.historyIndex = this.history.length;\n this.historyDraft = '';\n }\n}\n","import { commandRegistry, type CommandRegistry, type Command } from '@eclipse-docks/core';\nimport { parseShellLine } from './shell-parser';\nimport { LineInput } from './line-input';\n\nexport interface RunResult {\n success: boolean;\n results: unknown[];\n error?: string;\n}\n\nfunction mapOutputToParams(\n output: unknown,\n producerCommand: Command | undefined\n): Record<string, unknown> {\n if (output == null) return {};\n if (typeof output === 'object' && !Array.isArray(output)) {\n return output as Record<string, unknown>;\n }\n const firstOutput = producerCommand?.output?.[0];\n if (firstOutput) {\n return { [firstOutput.name]: output };\n }\n return {};\n}\n\nexport async function runShellLine(\n line: string,\n registry: CommandRegistry = commandRegistry\n): Promise<RunResult> {\n const segments = parseShellLine(line, registry);\n const results: unknown[] = [];\n let pipedOutput: Record<string, unknown> | null = null;\n let lastProducerCommand: Command | undefined;\n\n for (let i = 0; i < segments.length; i++) {\n const { command, operator } = segments[i];\n if (!command.commandId) continue;\n\n const cmd = registry.hasCommand(command.commandId)\n ? registry.getCommand(command.commandId)\n : undefined;\n if (!cmd) {\n return {\n success: false,\n results,\n error: `Command not found: ${command.commandId}`,\n };\n }\n\n const mergedParams = {\n ...mapOutputToParams(pipedOutput ?? undefined, lastProducerCommand),\n ...command.params,\n };\n\n const context = registry.createExecutionContext(mergedParams);\n\n try {\n const result = registry.execute(command.commandId, context);\n const resolved = result instanceof Promise ? await result : result;\n results.push(resolved);\n\n if (operator === '|') {\n pipedOutput = mapOutputToParams(resolved, cmd) as Record<string, unknown>;\n lastProducerCommand = cmd;\n } else {\n pipedOutput = null;\n lastProducerCommand = undefined;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, results, error: msg };\n }\n }\n\n return { success: true, results };\n}\n\nfunction formatResult(result: RunResult): string {\n if (result.error) return `\\r\\n\\x1b[31m${result.error}\\x1b[0m\\r\\n`;\n if (result.results.length === 0) return '';\n const last = result.results[result.results.length - 1];\n if (last == null) return '';\n if (typeof last === 'object') return JSON.stringify(last, null, 2) + '\\r\\n';\n return String(last) + '\\r\\n';\n}\n\nexport class CommandsBackend {\n private writeCallbacks = new Set<(data: string) => void>();\n private lineInput: LineInput;\n private prompt = '> ';\n\n constructor() {\n this.lineInput = new LineInput((data) => this.emit(data));\n }\n\n onDidWrite(callback: (data: string) => void): () => void {\n this.writeCallbacks.add(callback);\n return () => this.writeCallbacks.delete(callback);\n }\n\n private emit(data: string): void {\n for (const cb of this.writeCallbacks) cb(data);\n }\n\n async open(): Promise<void> {\n this.emit('Commands\\r\\nType commands (supports && and |)\\r\\n\\r\\n' + this.prompt);\n }\n\n close(): void {\n this.lineInput.reset();\n }\n\n setDimensions(_dimensions: { cols: number; rows: number }): void {}\n\n handleInput(data: string): void {\n const line = this.lineInput.feed(data);\n if (line === null) return;\n void this.runLine(line);\n }\n\n private async runLine(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed) {\n this.emit(this.prompt);\n return;\n }\n const result = await runShellLine(trimmed);\n this.emit(formatResult(result));\n this.emit(this.prompt);\n }\n}\n","import { createJsRuntime, type JsRuntime } from '@eclipse-docks/core';\nimport { terminalService } from './terminal-service';\nimport type { Terminal, TerminalBackend, TerminalCreationOptions } from './terminal-api';\nimport { LineInput } from './line-input';\n\nexport const JS_REPL_PROFILE_ID = 'terminal.javascript-repl';\nexport const JS_SESSION_PROFILE_ID = 'terminal.javascript-session';\n\nconst PROMPT = '> ';\n\nconst sessions = new Map<string, JsRuntime>();\n\nexport function unbindJsSession(sessionId: string): void {\n sessions.delete(sessionId);\n}\n\nexport function createJsSessionBackend(options?: TerminalCreationOptions): JsReplBackend {\n const sessionId = options?.env?.jsSessionId;\n const runtime = sessionId ? sessions.get(sessionId) : undefined;\n if (!runtime) throw new Error('JavaScript session is no longer available');\n return new JsReplBackend({\n runtime,\n ownsRuntime: false,\n sessionLabel: options?.env?.sessionLabel || 'session',\n });\n}\n\nexport function openJsSessionTerminal(\n runtime: JsRuntime,\n sessionId: string,\n name: string,\n sessionLabel = 'session',\n): Promise<Terminal | undefined> {\n sessions.set(sessionId, runtime);\n return terminalService.createTerminal({\n profileId: JS_SESSION_PROFILE_ID,\n name,\n env: { jsSessionId: sessionId, sessionLabel },\n });\n}\n\ninterface JsReplBackendOptions {\n runtime?: JsRuntime;\n /** When false, closing the terminal leaves the runtime running. */\n ownsRuntime?: boolean;\n sessionLabel?: string;\n}\n\nfunction formatJsResult(value: unknown): string {\n if (value === undefined) return '';\n if (value === null) return 'null\\r\\n';\n if (typeof value === 'object') return JSON.stringify(value, null, 2) + '\\r\\n';\n return String(value) + '\\r\\n';\n}\n\nexport class JsReplBackend implements TerminalBackend {\n private writeCallbacks = new Set<(data: string) => void>();\n private lineInput: LineInput;\n private runtime: JsRuntime | null;\n private ownsRuntime: boolean;\n private sessionLabel: string;\n private running = false;\n\n constructor(options?: JsReplBackendOptions) {\n this.lineInput = new LineInput((data) => this.emit(data));\n this.runtime = options?.runtime ?? null;\n this.ownsRuntime = options?.ownsRuntime ?? !options?.runtime;\n this.sessionLabel = options?.sessionLabel ?? 'session';\n }\n\n onDidWrite(callback: (data: string) => void): () => void {\n this.writeCallbacks.add(callback);\n return () => this.writeCallbacks.delete(callback);\n }\n\n private emit(data: string): void {\n for (const cb of this.writeCallbacks) cb(data);\n }\n\n private getRuntime(): JsRuntime {\n if (!this.runtime) {\n this.runtime = createJsRuntime();\n this.ownsRuntime = true;\n }\n return this.runtime;\n }\n\n async open(): Promise<void> {\n if (!this.runtime) {\n this.runtime = createJsRuntime();\n this.ownsRuntime = true;\n this.emit('JavaScript REPL\\r\\n\\r\\n' + PROMPT);\n return;\n }\n this.emit(`JavaScript (${this.sessionLabel})\\r\\n\\r\\n` + PROMPT);\n }\n\n close(): void {\n if (this.ownsRuntime) this.runtime?.close();\n this.runtime = null;\n this.lineInput.reset();\n }\n\n setDimensions(_dimensions: { cols: number; rows: number }): void {}\n\n handleInput(data: string): void {\n if (this.running) return;\n const line = this.lineInput.feed(data);\n if (line === null) return;\n void this.runLine(line);\n }\n\n private async runLine(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed) {\n this.emit(PROMPT);\n return;\n }\n\n this.running = true;\n try {\n const result = await this.getRuntime().execute(trimmed);\n const output = formatJsResult(result);\n if (output) this.emit(output);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit(`\\x1b[31m${msg}\\x1b[0m\\r\\n`);\n } finally {\n this.running = false;\n this.emit(PROMPT);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"js-terminal-backend-C6NeZIFc.js","names":[],"sources":["../src/terminal-api.ts","../src/terminal-persistence.ts","../src/terminal-service.ts","../src/shell-parser.ts","../src/line-input.ts","../src/commands-backend.ts","../src/js-terminal-backend.ts"],"sourcesContent":["export const TARGET_TERMINAL_PROFILES = 'system.terminal.profiles';\n\nexport const VIEW_TERMINAL = 'view.terminal';\nexport const TERMINAL_INSTANCES_TABS_ID = 'terminal-instances';\n/** Dropdown target: contributors register items that create a terminal with a profile. */\nexport const TERMINAL_NEW_DROPDOWN = `${TERMINAL_INSTANCES_TABS_ID}-new`;\nexport const TERMINAL_PANEL_SETTINGS_KEY = 'docks-terminal-panel';\n\nexport const TOPIC_TERMINAL_OPENED = 'events/terminal/opened';\nexport const TOPIC_TERMINAL_CLOSED = 'events/terminal/closed';\nexport const TOPIC_TERMINAL_ACTIVE_CHANGED = 'events/terminal/activeChanged';\n\nexport interface TerminalDimensions {\n cols: number;\n rows: number;\n}\n\nexport interface TerminalCreationOptions {\n name?: string;\n profileId?: string;\n cwd?: string;\n env?: Record<string, string>;\n groupId?: string;\n hidden?: boolean;\n}\n\nexport interface TerminalBackend {\n open?(initialDimensions?: TerminalDimensions): void | Promise<void>;\n close?(): void | Promise<void>;\n onDidWrite(callback: (data: string) => void): () => void;\n handleInput(data: string): void;\n setDimensions?(dimensions: TerminalDimensions): void;\n}\n\nexport interface TerminalProfileContribution {\n id: string;\n label: string;\n icon?: string;\n isDefault?: boolean;\n hidden?: boolean;\n /**\n * When false, terminals of this profile are not saved or restored across reloads.\n * Defaults to true.\n */\n persist?: boolean;\n create(options?: TerminalCreationOptions): Promise<TerminalBackend>;\n}\n\nexport interface TerminalTaskPresentation {\n profileId: string;\n reveal?: 'always' | 'silent' | 'never';\n focus?: boolean;\n clear?: boolean;\n}\n\nexport interface Terminal {\n readonly id: string;\n name: string;\n readonly profileId: string;\n readonly creationOptions: TerminalCreationOptions;\n readonly groupId: string;\n hidden: boolean;\n sendText(text: string, addNewLine?: boolean): void;\n show(preserveFocus?: boolean): void;\n hide(): void;\n dispose(options?: { confirm?: boolean }): Promise<void>;\n clear?(): void;\n}\n\n/** Internal terminal handle used by the host UI (not for provider extensions). */\nexport interface TerminalRuntime extends Terminal {\n backend: TerminalBackend | null;\n clearScreen?: () => void;\n}\n\nexport interface TerminalTaskRunner {\n runTask(\n presentation: TerminalTaskPresentation,\n execute: (terminal: Terminal) => Promise<void>\n ): Promise<void>;\n}\n\nexport interface PersistedTerminalState {\n terminals: PersistedTerminalEntry[];\n activeTerminalId: string | null;\n preferredProfileId: string | null;\n}\n\nexport interface PersistedTerminalEntry {\n id: string;\n name: string;\n profileId: string;\n groupId: string;\n creationOptions: TerminalCreationOptions;\n}\n","import type { PersistedTerminalEntry, PersistedTerminalState, TerminalCreationOptions } from './terminal-api';\n\nconst MAX_PERSISTED_ENV_KEYS = 32;\n\nexport function serializeTerminalState(state: PersistedTerminalState): PersistedTerminalState {\n return {\n activeTerminalId: state.activeTerminalId,\n preferredProfileId: state.preferredProfileId,\n terminals: state.terminals.map(serializeTerminalEntry),\n };\n}\n\nfunction serializeTerminalEntry(entry: PersistedTerminalEntry): PersistedTerminalEntry {\n const opts = entry.creationOptions;\n const env = opts.env\n ? Object.fromEntries(Object.entries(opts.env).slice(0, MAX_PERSISTED_ENV_KEYS))\n : undefined;\n return {\n id: entry.id,\n name: entry.name,\n profileId: entry.profileId,\n groupId: entry.groupId,\n creationOptions: {\n name: opts.name,\n profileId: opts.profileId,\n cwd: opts.cwd,\n env,\n groupId: opts.groupId,\n },\n };\n}\n\nexport function parseTerminalState(raw: unknown): PersistedTerminalState | null {\n if (!raw || typeof raw !== 'object') return null;\n const obj = raw as Record<string, unknown>;\n if (!Array.isArray(obj.terminals)) return null;\n\n const terminals: PersistedTerminalEntry[] = [];\n for (const item of obj.terminals) {\n if (!item || typeof item !== 'object') continue;\n const t = item as Record<string, unknown>;\n if (typeof t.id !== 'string' || typeof t.name !== 'string' || typeof t.profileId !== 'string') {\n continue;\n }\n const creationOptions = (t.creationOptions ?? {}) as TerminalCreationOptions;\n terminals.push({\n id: t.id,\n name: t.name,\n profileId: t.profileId,\n groupId: typeof t.groupId === 'string' ? t.groupId : t.id,\n creationOptions,\n });\n }\n\n return {\n terminals,\n activeTerminalId: typeof obj.activeTerminalId === 'string' ? obj.activeTerminalId : null,\n preferredProfileId: typeof obj.preferredProfileId === 'string' ? obj.preferredProfileId : null,\n };\n}\n\nexport function emptyTerminalState(): PersistedTerminalState {\n return { terminals: [], activeTerminalId: null, preferredProfileId: null };\n}\n","import { html } from '@eclipse-docks/core/externals/lit';\nimport {\n confirmDialog,\n contributionRegistry,\n i18n,\n PANEL_BOTTOM,\n publish,\n renderDropdownItem,\n rootContext,\n subscribe,\n unsubscribe,\n type TabContribution,\n} from '@eclipse-docks/core';\nimport {\n TARGET_TERMINAL_PROFILES,\n TERMINAL_NEW_DROPDOWN,\n TOPIC_TERMINAL_ACTIVE_CHANGED,\n TOPIC_TERMINAL_CLOSED,\n TOPIC_TERMINAL_OPENED,\n VIEW_TERMINAL,\n type Terminal,\n type TerminalBackend,\n type TerminalCreationOptions,\n type TerminalProfileContribution,\n type TerminalTaskPresentation,\n type TerminalTaskRunner,\n type PersistedTerminalState,\n type TerminalRuntime,\n} from './terminal-api';\nimport { emptyTerminalState, parseTerminalState, serializeTerminalState } from './terminal-persistence';\n\nconst t = await i18n(import.meta.glob('./i18n*.json'), true);\n\nasync function confirmKillTerminal(name: string): Promise<boolean> {\n return confirmDialog(t.TERMINAL_KILL_CONFIRM({ name }));\n}\n\ninterface TerminalTabsHost {\n has(key: string): boolean;\n activate(key: string): void;\n open(contribution: TabContribution): void;\n closeTab(event: Event, tabName: string): Promise<void>;\n updateTabLabel(tabName: string, label: string): void;\n}\n\nexport type { TerminalTabsHost };\n\nlet terminalCounter = 0;\n\nfunction nextTerminalId(): string {\n terminalCounter += 1;\n return `terminal-${terminalCounter}`;\n}\n\nclass TerminalInstance implements TerminalRuntime {\n readonly id: string;\n name: string;\n readonly profileId: string;\n readonly creationOptions: TerminalCreationOptions;\n readonly groupId: string;\n hidden = false;\n backend: TerminalBackend | null = null;\n clearScreen?: () => void;\n private skipCloseConfirm = false;\n\n constructor(\n id: string,\n name: string,\n profileId: string,\n creationOptions: TerminalCreationOptions,\n groupId: string\n ) {\n this.id = id;\n this.name = name;\n this.profileId = profileId;\n this.creationOptions = creationOptions;\n this.groupId = groupId;\n }\n\n sendText(text: string, addNewLine = true): void {\n if (!this.backend) return;\n this.backend.handleInput(text + (addNewLine ? '\\r' : ''));\n }\n\n show(_preserveFocus?: boolean): void {\n terminalService.focusTerminalPanel();\n terminalService.activateTerminal(this.id);\n this.hidden = false;\n }\n\n hide(): void {\n this.hidden = true;\n }\n\n async dispose(options?: { confirm?: boolean }): Promise<void> {\n if (options?.confirm === false) this.skipCloseConfirm = true;\n await terminalService.disposeTerminal(this.id);\n }\n\n shouldConfirmClose(): boolean {\n return !this.skipCloseConfirm;\n }\n\n clear(): void {\n this.clearScreen?.();\n }\n}\n\nclass TerminalService implements TerminalTaskRunner {\n private terminals = new Map<string, TerminalInstance>();\n private activeTerminalId: string | null = null;\n private preferredProfileId: string | null = null;\n private persistenceHandler: (() => Promise<PersistedTerminalState | null>) | null = null;\n private persistCallback: ((state: PersistedTerminalState) => Promise<void>) | null = null;\n private restoreStarted = false;\n private instanceTabsHost: TerminalTabsHost | null = null;\n\n get activeTerminal(): Terminal | undefined {\n if (!this.activeTerminalId) return undefined;\n return this.terminals.get(this.activeTerminalId);\n }\n\n getTerminals(): Terminal[] {\n return [...this.terminals.values()];\n }\n\n onDidOpenTerminal(callback: (terminal: Terminal) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_OPENED, callback);\n return () => unsubscribe(token);\n }\n\n onDidCloseTerminal(callback: (terminal: Terminal) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_CLOSED, callback);\n return () => unsubscribe(token);\n }\n\n onDidChangeActiveTerminal(callback: (terminal: Terminal | undefined) => void): () => void {\n const token = subscribe(TOPIC_TERMINAL_ACTIVE_CHANGED, callback);\n return () => unsubscribe(token);\n }\n\n setPersistenceHandlers(\n load: () => Promise<PersistedTerminalState | null>,\n save: (state: PersistedTerminalState) => Promise<void>\n ): void {\n this.persistenceHandler = load;\n this.persistCallback = save;\n }\n\n async restorePersistedTerminals(): Promise<void> {\n if (this.restoreStarted || !this.persistenceHandler) return;\n this.restoreStarted = true;\n const raw = await this.persistenceHandler();\n const state = raw ? parseTerminalState(raw) : null;\n if (!state || state.terminals.length === 0) return;\n\n this.preferredProfileId = state.preferredProfileId;\n for (const entry of state.terminals) {\n if (!this.isProfilePersistent(entry.profileId)) continue;\n await this.createTerminal({\n ...entry.creationOptions,\n name: entry.name,\n profileId: entry.profileId,\n groupId: entry.groupId,\n }, entry.id);\n }\n if (state.activeTerminalId && this.terminals.has(state.activeTerminalId)) {\n this.setActiveTerminal(state.activeTerminalId);\n }\n }\n\n /** Profiles default to persistent; opt out with `persist: false`. */\n private isProfilePersistent(profileId: string): boolean {\n const profile = this.getProfiles().find((p) => p.id === profileId);\n return profile?.persist !== false;\n }\n\n getProfiles(): TerminalProfileContribution[] {\n return contributionRegistry.getContributions<TerminalProfileContribution>(TARGET_TERMINAL_PROFILES);\n }\n\n resolveDefaultProfileId(): string | null {\n if (this.preferredProfileId) {\n const preferred = this.getProfiles().find((p) => p.id === this.preferredProfileId);\n if (preferred) return preferred.id;\n }\n const profiles = this.getProfiles().filter((p) => !p.hidden);\n const defaultProfile = profiles.find((p) => p.isDefault) ?? profiles[0];\n return defaultProfile?.id ?? null;\n }\n\n setInstanceTabsHost(host: TerminalTabsHost | null): void {\n this.instanceTabsHost = host;\n }\n\n getInstanceTabs(): TerminalTabsHost | null {\n return this.instanceTabsHost;\n }\n\n focusTerminalPanel(): void {\n const panel = document.querySelector(`docks-tabs#${PANEL_BOTTOM}`) as TerminalTabsHost | null;\n panel?.activate(VIEW_TERMINAL);\n }\n\n activateTerminal(id: string): void {\n const tabs = this.getInstanceTabs();\n if (tabs?.has(id)) {\n tabs.activate(id);\n }\n this.setActiveTerminal(id);\n }\n\n private setActiveTerminal(id: string | null): void {\n if (this.activeTerminalId === id) return;\n this.activeTerminalId = id;\n publish(TOPIC_TERMINAL_ACTIVE_CHANGED, id ? this.terminals.get(id) : undefined);\n void this.persistState();\n }\n\n async createTerminal(\n options: TerminalCreationOptions = {},\n forcedId?: string\n ): Promise<Terminal | undefined> {\n const profileId = options.profileId ?? this.resolveDefaultProfileId();\n if (!profileId) return undefined;\n\n const profile = this.getProfiles().find((p) => p.id === profileId);\n if (!profile) return undefined;\n\n const id = forcedId ?? nextTerminalId();\n if (forcedId) syncTerminalCounterFromId(forcedId);\n const groupId = options.groupId ?? id;\n const name = options.name ?? profile.label;\n\n let backend: TerminalBackend;\n try {\n backend = await profile.create({ ...options, profileId, name, groupId });\n } catch {\n return undefined;\n }\n\n const terminal = new TerminalInstance(id, name, profileId, { ...options, profileId, name, groupId }, groupId);\n terminal.backend = backend;\n terminal.hidden = options.hidden ?? false;\n\n this.terminals.set(id, terminal);\n if (!terminal.hidden) {\n this.focusTerminalPanel();\n await this.whenTabsHostReady();\n }\n this.openTerminalTab(terminal, profile.icon);\n\n if (!terminal.hidden) {\n this.focusTerminalPanel();\n this.activateTerminal(id);\n }\n\n publish(TOPIC_TERMINAL_OPENED, terminal);\n void this.persistState();\n return terminal;\n }\n\n /** The panel binds its tab host after the bottom panel is shown. */\n private whenTabsHostReady(): Promise<void> {\n if (this.instanceTabsHost) return Promise.resolve();\n const started = performance.now();\n return new Promise((resolve) => {\n const check = () => {\n if (this.instanceTabsHost || performance.now() - started > 1000) {\n resolve();\n return;\n }\n requestAnimationFrame(check);\n };\n requestAnimationFrame(check);\n });\n }\n\n private openTerminalTab(terminal: TerminalInstance, icon?: string): void {\n const tabs = this.getInstanceTabs();\n if (!tabs) return;\n\n const contribution: TabContribution = {\n name: terminal.id,\n label: terminal.name,\n icon: icon ?? 'terminal',\n closable: true,\n toolbar: false,\n beforeClose: async () => terminal.shouldConfirmClose() ? confirmKillTerminal(terminal.name) : true,\n component: (tabId: string) =>\n html`<docks-terminal-view id=\"${tabId}\" .terminal=${terminal}></docks-terminal-view>`,\n };\n\n if (tabs.has(terminal.id)) {\n tabs.activate(terminal.id);\n return;\n }\n tabs.open(contribution);\n }\n\n async disposeTerminal(id: string, options?: { skipTabRemoval?: boolean }): Promise<void> {\n const terminal = this.terminals.get(id);\n if (!terminal) return;\n\n if (!options?.skipTabRemoval) {\n const tabs = this.getInstanceTabs();\n if (tabs?.has(id)) {\n await tabs.closeTab(new Event('close'), id);\n return;\n }\n }\n\n await terminal.backend?.close?.();\n terminal.backend = null;\n this.terminals.delete(id);\n\n if (this.activeTerminalId === id) {\n const remaining = [...this.terminals.keys()];\n this.setActiveTerminal(remaining.length > 0 ? remaining[remaining.length - 1] : null);\n }\n\n publish(TOPIC_TERMINAL_CLOSED, terminal);\n void this.persistState();\n }\n\n async killAll(): Promise<void> {\n const tabs = this.getInstanceTabs();\n const ids = [...this.terminals.keys()];\n for (const id of ids) {\n if (tabs?.has(id)) {\n await tabs.closeTab(new Event('close'), id);\n } else {\n await this.disposeTerminal(id, { skipTabRemoval: true });\n }\n }\n }\n\n renameActiveTerminal(name: string): void {\n const active = this.activeTerminal;\n if (!active || !(active instanceof TerminalInstance)) return;\n active.name = name;\n this.getInstanceTabs()?.updateTabLabel(active.id, name);\n void this.persistState();\n }\n\n setPreferredProfile(profileId: string): void {\n this.preferredProfileId = profileId;\n void this.persistState();\n }\n\n clearActiveTerminal(): void {\n this.activeTerminal?.clear?.();\n }\n\n async runTask(\n presentation: TerminalTaskPresentation,\n execute: (terminal: Terminal) => Promise<void>\n ): Promise<void> {\n let terminal = this.getTerminals().find((t) => t.profileId === presentation.profileId);\n if (!terminal) {\n terminal = await this.createTerminal({ profileId: presentation.profileId });\n }\n if (!terminal) return;\n\n if (presentation.reveal !== 'never') {\n if (presentation.focus !== false) {\n terminal.show();\n } else {\n this.focusTerminalPanel();\n }\n }\n if (presentation.clear) {\n terminal.clear?.();\n }\n await execute(terminal);\n }\n\n private async persistState(): Promise<void> {\n if (!this.persistCallback) return;\n const terminals = [...this.terminals.values()]\n .filter((t) => this.isProfilePersistent(t.profileId))\n .map((t) => ({\n id: t.id,\n name: t.name,\n profileId: t.profileId,\n groupId: t.groupId,\n creationOptions: t.creationOptions,\n }));\n const ids = new Set(terminals.map((t) => t.id));\n const state: PersistedTerminalState = {\n activeTerminalId:\n this.activeTerminalId && ids.has(this.activeTerminalId) ? this.activeTerminalId : null,\n preferredProfileId: this.preferredProfileId,\n terminals,\n };\n await this.persistCallback(serializeTerminalState(state));\n }\n\n handleTabActivated(tabName: string): void {\n if (this.terminals.has(tabName)) {\n this.setActiveTerminal(tabName);\n }\n }\n\n handleTabClosed(tabName: string): void {\n if (this.terminals.has(tabName)) {\n void this.disposeTerminal(tabName, { skipTabRemoval: true });\n }\n }\n}\n\nfunction syncTerminalCounterFromId(id: string): void {\n const match = /^terminal-(\\d+)$/.exec(id);\n if (!match) return;\n const n = Number.parseInt(match[1], 10);\n if (n > terminalCounter) terminalCounter = n;\n}\n\nexport const terminalService = new TerminalService();\nrootContext.put('terminalService', terminalService);\n\nexport function registerTerminalProfile(contribution: TerminalProfileContribution): void {\n contributionRegistry.registerContribution(TARGET_TERMINAL_PROFILES, contribution);\n if (contribution.hidden) return;\n const profileId = contribution.id;\n contributionRegistry.registerContribution(TERMINAL_NEW_DROPDOWN, {\n label: contribution.label,\n icon: contribution.icon ?? 'terminal',\n component: () => renderDropdownItem({\n icon: contribution.icon ?? 'terminal',\n label: contribution.label,\n title: contribution.label,\n action: () => {\n terminalService.setPreferredProfile(profileId);\n void terminalService.createTerminal({ profileId });\n },\n }),\n });\n}\n","import type { CommandRegistry, Command } from '@eclipse-docks/core';\n\nexport interface ParsedCommand {\n commandId: string;\n params: Record<string, string | boolean>;\n}\n\nexport interface ParsedSegment {\n command: ParsedCommand;\n operator: '&&' | '|' | null;\n}\n\nconst NAMED_PARAM_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*=.*$/;\n\nfunction tokenize(segment: string): string[] {\n const tokens: string[] = [];\n let i = 0;\n const len = segment.length;\n\n while (i < len) {\n while (i < len && /\\s/.test(segment[i])) i++;\n if (i >= len) break;\n\n if (segment[i] === '\"') {\n let end = i + 1;\n while (end < len && segment[end] !== '\"') {\n if (segment[end] === '\\\\') end++;\n end++;\n }\n tokens.push(segment.slice(i + 1, end).replace(/\\\\\"/g, '\"'));\n i = end + 1;\n } else {\n let start = i;\n while (i < len && !/\\s/.test(segment[i]) && segment[i] !== '\"') i++;\n if (i > start) {\n tokens.push(segment.slice(start, i));\n }\n }\n }\n return tokens;\n}\n\nfunction splitChain(line: string): { segment: string; operator: '&&' | '|' | null }[] {\n const result: { segment: string; operator: '&&' | '|' | null }[] = [];\n const regex = /(\\s*&&\\s*|\\s*\\|\\s*)/g;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(line)) !== null) {\n const segment = line.slice(lastIndex, match.index).trim();\n if (segment) {\n const op = match[0].includes('|') ? ('|' as const) : ('&&' as const);\n result.push({ segment, operator: op });\n }\n lastIndex = regex.lastIndex;\n }\n const tail = line.slice(lastIndex).trim();\n if (tail) {\n result.push({ segment: tail, operator: null });\n }\n return result;\n}\n\nfunction resolveParams(\n tokens: string[],\n command: Command | undefined\n): Record<string, string | boolean> {\n const params: Record<string, string | boolean> = {};\n const positionals: string[] = [];\n const paramNames = command?.parameters?.map((p) => p.name) ?? [];\n\n for (const token of tokens) {\n if (NAMED_PARAM_REGEX.test(token)) {\n const eqIdx = token.indexOf('=');\n const name = token.slice(0, eqIdx);\n const value = token.slice(eqIdx + 1);\n params[name] = value === 'true' || value === 'false' ? value === 'true' : value;\n } else {\n positionals.push(token);\n }\n }\n\n paramNames.forEach((name, i) => {\n if (positionals[i] !== undefined && !(name in params)) {\n params[name] = positionals[i];\n }\n });\n\n return params;\n}\n\nexport function parseShellLine(line: string, commandRegistry: CommandRegistry): ParsedSegment[] {\n const segments = splitChain(line);\n return segments.map(({ segment, operator }) => {\n const tokens = tokenize(segment);\n if (tokens.length === 0) {\n return { command: { commandId: '', params: {} }, operator };\n }\n const commandId = tokens[0];\n const command = commandRegistry.hasCommand(commandId)\n ? commandRegistry.getCommand(commandId)\n : undefined;\n const params = resolveParams(tokens.slice(1), command);\n return { command: { commandId, params }, operator };\n });\n}\n","/** Minimal readline-style editor for xterm-backed REPL backends. */\nexport class LineInput {\n private buffer = '';\n private cursor = 0;\n private history: string[] = [];\n private historyDraft = '';\n private historyIndex = 0;\n\n constructor(private write: (data: string) => void) {}\n\n reset(): void {\n this.buffer = '';\n this.cursor = 0;\n this.historyDraft = '';\n this.historyIndex = this.history.length;\n }\n\n /** Returns the submitted line on Enter, otherwise null. */\n feed(data: string): string | null {\n if (data === '\\r') {\n const line = this.buffer;\n this.pushHistory(line);\n this.buffer = '';\n this.cursor = 0;\n this.write('\\r\\n');\n return line;\n }\n\n if (data === '\\u007f' || data === '\\b') {\n this.deleteBackward();\n return null;\n }\n\n if (data === '\\x1b[D' || data === '\\x1bOD') {\n this.move(-1);\n return null;\n }\n if (data === '\\x1b[C' || data === '\\x1bOC') {\n this.move(1);\n return null;\n }\n if (data === '\\x1b[A' || data === '\\x1bOA') {\n this.historyPrev();\n return null;\n }\n if (data === '\\x1b[B' || data === '\\x1bOB') {\n this.historyNext();\n return null;\n }\n if (data === '\\x1b[3~') {\n this.deleteForward();\n return null;\n }\n if (data === '\\x1b[H' || data === '\\x1bOH') {\n this.cursorHome();\n return null;\n }\n if (data === '\\x1b[F' || data === '\\x1bOF') {\n this.cursorEnd();\n return null;\n }\n\n if (data.startsWith('\\x1b')) return null;\n\n for (const char of data) {\n if (char < ' ') continue;\n this.insert(char);\n }\n return null;\n }\n\n private move(delta: number): void {\n const next = this.cursor + delta;\n if (next < 0 || next > this.buffer.length) return;\n const steps = Math.abs(delta);\n this.cursor = next;\n this.write(delta < 0 ? `\\x1b[${steps}D` : `\\x1b[${steps}C`);\n }\n\n private cursorHome(): void {\n if (this.cursor === 0) return;\n this.write(`\\x1b[${this.cursor}D`);\n this.cursor = 0;\n }\n\n private cursorEnd(): void {\n const steps = this.buffer.length - this.cursor;\n if (steps <= 0) return;\n this.write(`\\x1b[${steps}C`);\n this.cursor = this.buffer.length;\n }\n\n private insert(char: string): void {\n if (this.cursor === this.buffer.length) {\n this.buffer += char;\n this.cursor++;\n this.write(char);\n return;\n }\n const tail = this.buffer.slice(this.cursor);\n this.buffer = this.buffer.slice(0, this.cursor) + char + tail;\n this.cursor++;\n this.write(char + tail + `\\x1b[${tail.length}D`);\n }\n\n private deleteBackward(): void {\n if (this.cursor === 0) return;\n if (this.cursor === this.buffer.length) {\n this.buffer = this.buffer.slice(0, -1);\n this.cursor--;\n this.write('\\b \\b');\n return;\n }\n const after = this.buffer.slice(this.cursor);\n this.buffer = this.buffer.slice(0, this.cursor - 1) + after;\n this.cursor--;\n this.write(`\\b${after} ` + `\\x1b[${after.length + 1}D`);\n }\n\n private deleteForward(): void {\n if (this.cursor >= this.buffer.length) return;\n const after = this.buffer.slice(this.cursor + 1);\n this.write(`${after} ` + `\\x1b[${after.length + 1}D`);\n this.buffer = this.buffer.slice(0, this.cursor) + after;\n }\n\n private replaceBuffer(next: string): void {\n if (this.cursor > 0) this.write(`\\x1b[${this.cursor}D`);\n if (this.buffer.length > 0) this.write('\\x1b[K');\n this.buffer = next;\n this.cursor = next.length;\n if (next) this.write(next);\n }\n\n private historyPrev(): void {\n if (this.history.length === 0) return;\n if (this.historyIndex === this.history.length) {\n this.historyDraft = this.buffer;\n }\n if (this.historyIndex === 0) return;\n this.historyIndex--;\n this.replaceBuffer(this.history[this.historyIndex]);\n }\n\n private historyNext(): void {\n if (this.historyIndex >= this.history.length) return;\n this.historyIndex++;\n if (this.historyIndex === this.history.length) {\n this.replaceBuffer(this.historyDraft);\n this.historyDraft = '';\n return;\n }\n this.replaceBuffer(this.history[this.historyIndex]);\n }\n\n private pushHistory(line: string): void {\n if (line.length > 0 && this.history[this.history.length - 1] !== line) {\n this.history.push(line);\n }\n this.historyIndex = this.history.length;\n this.historyDraft = '';\n }\n}\n","import { commandRegistry, type CommandRegistry, type Command } from '@eclipse-docks/core';\nimport { parseShellLine } from './shell-parser';\nimport { LineInput } from './line-input';\n\nexport interface RunResult {\n success: boolean;\n results: unknown[];\n error?: string;\n}\n\nfunction mapOutputToParams(\n output: unknown,\n producerCommand: Command | undefined\n): Record<string, unknown> {\n if (output == null) return {};\n if (typeof output === 'object' && !Array.isArray(output)) {\n return output as Record<string, unknown>;\n }\n const firstOutput = producerCommand?.output?.[0];\n if (firstOutput) {\n return { [firstOutput.name]: output };\n }\n return {};\n}\n\nexport async function runShellLine(\n line: string,\n registry: CommandRegistry = commandRegistry\n): Promise<RunResult> {\n const segments = parseShellLine(line, registry);\n const results: unknown[] = [];\n let pipedOutput: Record<string, unknown> | null = null;\n let lastProducerCommand: Command | undefined;\n\n for (let i = 0; i < segments.length; i++) {\n const { command, operator } = segments[i];\n if (!command.commandId) continue;\n\n const cmd = registry.hasCommand(command.commandId)\n ? registry.getCommand(command.commandId)\n : undefined;\n if (!cmd) {\n return {\n success: false,\n results,\n error: `Command not found: ${command.commandId}`,\n };\n }\n\n const mergedParams = {\n ...mapOutputToParams(pipedOutput ?? undefined, lastProducerCommand),\n ...command.params,\n };\n\n const context = registry.createExecutionContext(mergedParams);\n\n try {\n const result = registry.execute(command.commandId, context);\n const resolved = result instanceof Promise ? await result : result;\n results.push(resolved);\n\n if (operator === '|') {\n pipedOutput = mapOutputToParams(resolved, cmd) as Record<string, unknown>;\n lastProducerCommand = cmd;\n } else {\n pipedOutput = null;\n lastProducerCommand = undefined;\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { success: false, results, error: msg };\n }\n }\n\n return { success: true, results };\n}\n\nfunction formatResult(result: RunResult): string {\n if (result.error) return `\\r\\n\\x1b[31m${result.error}\\x1b[0m\\r\\n`;\n if (result.results.length === 0) return '';\n const last = result.results[result.results.length - 1];\n if (last == null) return '';\n if (typeof last === 'object') return JSON.stringify(last, null, 2) + '\\r\\n';\n return String(last) + '\\r\\n';\n}\n\nexport class CommandsBackend {\n private writeCallbacks = new Set<(data: string) => void>();\n private lineInput: LineInput;\n private prompt = '> ';\n\n constructor() {\n this.lineInput = new LineInput((data) => this.emit(data));\n }\n\n onDidWrite(callback: (data: string) => void): () => void {\n this.writeCallbacks.add(callback);\n return () => this.writeCallbacks.delete(callback);\n }\n\n private emit(data: string): void {\n for (const cb of this.writeCallbacks) cb(data);\n }\n\n async open(): Promise<void> {\n this.emit('Commands\\r\\nType commands (supports && and |)\\r\\n\\r\\n' + this.prompt);\n }\n\n close(): void {\n this.lineInput.reset();\n }\n\n setDimensions(_dimensions: { cols: number; rows: number }): void {}\n\n handleInput(data: string): void {\n const line = this.lineInput.feed(data);\n if (line === null) return;\n void this.runLine(line);\n }\n\n private async runLine(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed) {\n this.emit(this.prompt);\n return;\n }\n const result = await runShellLine(trimmed);\n this.emit(formatResult(result));\n this.emit(this.prompt);\n }\n}\n","import { createJsRuntime, type JsRuntime } from '@eclipse-docks/core';\nimport { terminalService } from './terminal-service';\nimport type { Terminal, TerminalBackend, TerminalCreationOptions } from './terminal-api';\nimport { LineInput } from './line-input';\n\nexport const JS_REPL_PROFILE_ID = 'terminal.javascript-repl';\nexport const JS_SESSION_PROFILE_ID = 'terminal.javascript-session';\n\nconst PROMPT = '> ';\n\nconst sessions = new Map<string, JsRuntime>();\n\nexport function unbindJsSession(sessionId: string): void {\n sessions.delete(sessionId);\n}\n\nexport function createJsSessionBackend(options?: TerminalCreationOptions): JsReplBackend {\n const sessionId = options?.env?.jsSessionId;\n const runtime = sessionId ? sessions.get(sessionId) : undefined;\n if (!runtime) throw new Error('JavaScript session is no longer available');\n return new JsReplBackend({\n runtime,\n ownsRuntime: false,\n sessionLabel: options?.env?.sessionLabel || 'session',\n });\n}\n\nexport function openJsSessionTerminal(\n runtime: JsRuntime,\n sessionId: string,\n name: string,\n sessionLabel = 'session',\n): Promise<Terminal | undefined> {\n sessions.set(sessionId, runtime);\n return terminalService.createTerminal({\n profileId: JS_SESSION_PROFILE_ID,\n name,\n env: { jsSessionId: sessionId, sessionLabel },\n });\n}\n\ninterface JsReplBackendOptions {\n runtime?: JsRuntime;\n /** When false, closing the terminal leaves the runtime running. */\n ownsRuntime?: boolean;\n sessionLabel?: string;\n}\n\nfunction formatJsResult(value: unknown): string {\n if (value === undefined) return '';\n if (value === null) return 'null\\r\\n';\n if (typeof value === 'object') return JSON.stringify(value, null, 2) + '\\r\\n';\n return String(value) + '\\r\\n';\n}\n\nexport class JsReplBackend implements TerminalBackend {\n private writeCallbacks = new Set<(data: string) => void>();\n private lineInput: LineInput;\n private runtime: JsRuntime | null;\n private ownsRuntime: boolean;\n private sessionLabel: string;\n private running = false;\n\n constructor(options?: JsReplBackendOptions) {\n this.lineInput = new LineInput((data) => this.emit(data));\n this.runtime = options?.runtime ?? null;\n this.ownsRuntime = options?.ownsRuntime ?? !options?.runtime;\n this.sessionLabel = options?.sessionLabel ?? 'session';\n }\n\n onDidWrite(callback: (data: string) => void): () => void {\n this.writeCallbacks.add(callback);\n return () => this.writeCallbacks.delete(callback);\n }\n\n private emit(data: string): void {\n for (const cb of this.writeCallbacks) cb(data);\n }\n\n private getRuntime(): JsRuntime {\n if (!this.runtime) {\n this.runtime = createJsRuntime();\n this.ownsRuntime = true;\n }\n return this.runtime;\n }\n\n async open(): Promise<void> {\n if (!this.runtime) {\n this.runtime = createJsRuntime();\n this.ownsRuntime = true;\n this.emit('JavaScript REPL\\r\\n\\r\\n' + PROMPT);\n return;\n }\n this.emit(`JavaScript (${this.sessionLabel})\\r\\n\\r\\n` + PROMPT);\n }\n\n close(): void {\n if (this.ownsRuntime) this.runtime?.close();\n this.runtime = null;\n this.lineInput.reset();\n }\n\n setDimensions(_dimensions: { cols: number; rows: number }): void {}\n\n handleInput(data: string): void {\n if (this.running) return;\n const line = this.lineInput.feed(data);\n if (line === null) return;\n void this.runLine(line);\n }\n\n private async runLine(line: string): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed) {\n this.emit(PROMPT);\n return;\n }\n\n this.running = true;\n try {\n const result = await this.getRuntime().execute(trimmed);\n const output = formatJsResult(result);\n if (output) this.emit(output);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.emit(`\\x1b[31m${msg}\\x1b[0m\\r\\n`);\n } finally {\n this.running = false;\n this.emit(PROMPT);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { _ as TERMINAL_PANEL_SETTINGS_KEY, b as TOPIC_TERMINAL_OPENED, d as emptyTerminalState, f as parseTerminalState, g as TERMINAL_NEW_DROPDOWN, h as TERMINAL_INSTANCES_TABS_ID, i as createJsSessionBackend, l as registerTerminalProfile, n as JS_SESSION_PROFILE_ID, r as JsReplBackend, s as CommandsBackend, t as JS_REPL_PROFILE_ID, u as terminalService, v as TOPIC_TERMINAL_ACTIVE_CHANGED, x as VIEW_TERMINAL, y as TOPIC_TERMINAL_CLOSED } from "./js-terminal-backend-
|
|
1
|
+
import { _ as TERMINAL_PANEL_SETTINGS_KEY, b as TOPIC_TERMINAL_OPENED, d as emptyTerminalState, f as parseTerminalState, g as TERMINAL_NEW_DROPDOWN, h as TERMINAL_INSTANCES_TABS_ID, i as createJsSessionBackend, l as registerTerminalProfile, n as JS_SESSION_PROFILE_ID, r as JsReplBackend, s as CommandsBackend, t as JS_REPL_PROFILE_ID, u as terminalService, v as TOPIC_TERMINAL_ACTIVE_CHANGED, x as VIEW_TERMINAL, y as TOPIC_TERMINAL_CLOSED } from "./js-terminal-backend-C6NeZIFc.js";
|
|
2
2
|
import { DocksPart, PANEL_BOTTOM, appSettings, contributionRegistry, promptDialog, subscribe, unsubscribe } from "@eclipse-docks/core";
|
|
3
3
|
import { createRef, css, customElement, html, property, ref, unsafeCSS } from "@eclipse-docks/core/externals/lit";
|
|
4
4
|
import { Terminal } from "@xterm/xterm";
|
|
5
5
|
import { FitAddon } from "@xterm/addon-fit";
|
|
6
6
|
import xtermStyles from "@xterm/xterm/css/xterm.css?raw";
|
|
7
7
|
import _decorate from "@oxc-project/runtime/helpers/decorate";
|
|
8
|
-
|
|
8
|
+
// src/terminal-theme.ts
|
|
9
9
|
function cssVar(name, fallback) {
|
|
10
10
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
|
|
11
11
|
}
|
|
@@ -58,8 +58,7 @@ function observeTerminalTheme(onChange) {
|
|
|
58
58
|
});
|
|
59
59
|
return () => observer.disconnect();
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
//#region src/terminal-view.ts
|
|
61
|
+
// src/terminal-view.ts
|
|
63
62
|
var DocksTerminalView = class DocksTerminalView extends DocksPart {
|
|
64
63
|
constructor(..._args) {
|
|
65
64
|
super(..._args);
|
|
@@ -294,8 +293,7 @@ var DocksTerminalView = class DocksTerminalView extends DocksPart {
|
|
|
294
293
|
};
|
|
295
294
|
_decorate([property({ attribute: false })], DocksTerminalView.prototype, "terminal", void 0);
|
|
296
295
|
DocksTerminalView = _decorate([customElement("docks-terminal-view")], DocksTerminalView);
|
|
297
|
-
|
|
298
|
-
//#region src/terminal-panel.ts
|
|
296
|
+
// src/terminal-panel.ts
|
|
299
297
|
var DocksTerminalPanel = class DocksTerminalPanel extends DocksPart {
|
|
300
298
|
constructor(..._args) {
|
|
301
299
|
super(..._args);
|
|
@@ -410,8 +408,7 @@ var DocksTerminalPanel = class DocksTerminalPanel extends DocksPart {
|
|
|
410
408
|
}
|
|
411
409
|
};
|
|
412
410
|
DocksTerminalPanel = _decorate([customElement("docks-terminal-panel")], DocksTerminalPanel);
|
|
413
|
-
|
|
414
|
-
//#region src/terminal-extension.ts
|
|
411
|
+
// src/terminal-extension.ts
|
|
415
412
|
var COMMANDS_PROFILE_ID = "terminal.javascript-shell";
|
|
416
413
|
async function activate() {
|
|
417
414
|
registerTerminalProfile({
|
|
@@ -442,7 +439,6 @@ async function activate() {
|
|
|
442
439
|
component: (id) => html`<docks-terminal-panel id="${id}"></docks-terminal-panel>`
|
|
443
440
|
});
|
|
444
441
|
}
|
|
445
|
-
//#endregion
|
|
446
442
|
export { activate as default };
|
|
447
443
|
|
|
448
|
-
//# sourceMappingURL=terminal-extension-
|
|
444
|
+
//# sourceMappingURL=terminal-extension-B0d4I4cK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-extension-CnPHiXG4.js","names":[],"sources":["../src/terminal-theme.ts","../src/terminal-view.ts","../src/terminal-panel.ts","../src/terminal-extension.ts"],"sourcesContent":["import type { ITheme } from '@xterm/xterm';\n\nfunction cssVar(name: string, fallback: string): string {\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\nexport function isDarkTheme(): boolean {\n const root = document.documentElement;\n if (root.classList.contains('wa-dark')) return true;\n if (root.classList.contains('wa-light')) return false;\n return true;\n}\n\nexport function getTerminalTheme(): ITheme {\n const dark = isDarkTheme();\n return {\n background: cssVar('--wa-color-surface-lowered', dark ? '#1e1e1e' : '#f3f3f3'),\n foreground: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n cursor: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n cursorAccent: cssVar('--wa-color-surface-lowered', dark ? '#1e1e1e' : '#f3f3f3'),\n selectionBackground: cssVar('--wa-color-brand-fill-quiet', dark ? '#264f7840' : '#add6ff80'),\n selectionForeground: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n black: cssVar('--wa-color-neutral-10', dark ? '#000000' : '#1e1e1e'),\n red: cssVar('--wa-color-danger-fill-loud', '#cd3131'),\n green: cssVar('--wa-color-success-fill-loud', '#0dbc79'),\n yellow: cssVar('--wa-color-warning-fill-loud', '#e5e510'),\n blue: cssVar('--wa-color-brand-fill-loud', '#2472c8'),\n magenta: cssVar('--wa-color-purple-50', '#bc3fbc'),\n cyan: cssVar('--wa-color-cyan-50', '#11a8cd'),\n white: cssVar('--wa-color-neutral-90', dark ? '#e5e5e5' : '#ffffff'),\n brightBlack: cssVar('--wa-color-neutral-50', '#666666'),\n brightRed: cssVar('--wa-color-danger-50', '#f14c4c'),\n brightGreen: cssVar('--wa-color-success-50', '#23d18b'),\n brightYellow: cssVar('--wa-color-warning-50', '#f5f543'),\n brightBlue: cssVar('--wa-color-brand-50', '#3b8eea'),\n brightMagenta: cssVar('--wa-color-purple-40', '#d670d6'),\n brightCyan: cssVar('--wa-color-cyan-40', '#29b8db'),\n brightWhite: cssVar('--wa-color-neutral-95', '#ffffff'),\n };\n}\n\n/** Watches `wa-dark` / `wa-light` on `<html>`, same pattern as docks-monaco-widget. */\nexport function observeTerminalTheme(onChange: () => void): () => void {\n const root = document.documentElement;\n let dark = isDarkTheme();\n\n const observer = new MutationObserver(() => {\n const next = isDarkTheme();\n if (next === dark) return;\n dark = next;\n onChange();\n });\n\n observer.observe(root, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n}\n","import { css, createRef, customElement, html, property, ref, unsafeCSS, type Ref } from '@eclipse-docks/core/externals/lit';\nimport { Terminal } from '@xterm/xterm';\nimport { FitAddon } from '@xterm/addon-fit';\nimport { DocksPart } from '@eclipse-docks/core';\nimport { terminalService } from './terminal-service';\nimport type { TerminalRuntime } from './terminal-api';\nimport { getTerminalTheme, observeTerminalTheme } from './terminal-theme';\nimport xtermStyles from '@xterm/xterm/css/xterm.css?raw';\n\n@customElement('docks-terminal-view')\nexport class DocksTerminalView extends DocksPart {\n protected scrollMode: 'scroller' | 'native' | 'none' = 'none';\n\n @property({ attribute: false })\n terminal?: TerminalRuntime;\n\n private xtermRef: Ref<HTMLDivElement> = createRef();\n private xterm: Terminal | null = null;\n private fitAddon: FitAddon | null = null;\n private unsubscribeWrite: (() => void) | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private tabsHost: Element | null = null;\n private tabPanelName: string | null = null;\n private onTabShow: ((event: Event) => void) | null = null;\n private backendOpened = false;\n private unobserveTheme: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n void this.initTerminal();\n }\n\n disconnectedCallback(): void {\n this.teardownTerminal();\n super.disconnectedCallback();\n }\n\n close(): void {\n if (this.terminal) {\n terminalService.handleTabClosed(this.terminal.id);\n }\n this.teardownTerminal();\n }\n\n private findTabContext(): { panelName: string; tabPanel: HTMLElement; tabsHost: Element } | null {\n let panelName: string | null = null;\n let tabPanel: HTMLElement | null = null;\n let tabsHost: Element | null = null;\n let el: Element | null = this;\n\n while (el) {\n const tag = el.tagName?.toLowerCase();\n if (tag === 'wa-tab-panel' && !tabPanel) {\n tabPanel = el as HTMLElement;\n panelName = el.getAttribute('name');\n }\n if (tag === 'docks-tabs') {\n tabsHost = el;\n break;\n }\n const parent: Element | null = el.parentElement;\n if (parent) {\n el = parent;\n } else {\n const root = el.getRootNode();\n el = root instanceof ShadowRoot ? (root.host as Element) : null;\n }\n }\n\n if (!tabsHost || !tabPanel || !panelName) return null;\n return { panelName, tabPanel, tabsHost };\n }\n\n private isTabPanelActive(tabPanel: HTMLElement): boolean {\n return tabPanel.hasAttribute('active');\n }\n\n private attachTabVisibilityHandling(context: {\n panelName: string;\n tabsHost: Element;\n }): void {\n this.tabsHost = context.tabsHost;\n this.tabPanelName = context.panelName;\n this.onTabShow = (event: Event) => {\n const name = (event as CustomEvent<{ name?: string }>).detail?.name;\n if (name !== context.panelName) return;\n this.onTabShown();\n };\n context.tabsHost.addEventListener('wa-tab-show', this.onTabShow);\n }\n\n private detachTabVisibilityHandling(): void {\n if (this.tabsHost && this.onTabShow) {\n this.tabsHost.removeEventListener('wa-tab-show', this.onTabShow);\n }\n this.tabsHost = null;\n this.tabPanelName = null;\n this.onTabShow = null;\n }\n\n private scheduleFit(focus = false): void {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.applyFit();\n if (focus) this.xterm?.focus();\n });\n });\n }\n\n private async openBackendIfNeeded(): Promise<void> {\n if (this.backendOpened || !this.terminal?.backend) return;\n this.backendOpened = true;\n await this.terminal.backend.open?.(this.getDimensions());\n }\n\n private onTabShown(): void {\n this.scheduleFit(true);\n void this.openBackendIfNeeded();\n }\n\n private async initTerminal(): Promise<void> {\n if (!this.terminal?.backend) return;\n await this.updateComplete;\n\n const container = this.xtermRef.value;\n if (!container) return;\n\n this.xterm = new Terminal({\n cursorBlink: true,\n fontFamily: 'var(--wa-font-mono, monospace)',\n fontSize: 13,\n theme: getTerminalTheme(),\n });\n this.fitAddon = new FitAddon();\n this.xterm.loadAddon(this.fitAddon);\n this.xterm.open(container);\n\n const backend = this.terminal.backend;\n this.unsubscribeWrite = backend.onDidWrite((data) => {\n this.xterm?.write(data);\n });\n\n this.xterm.onData((data) => {\n backend.handleInput(data);\n });\n\n this.terminal.clearScreen = () => {\n this.xterm?.clear();\n };\n\n this.unobserveTheme = observeTerminalTheme(() => {\n if (!this.xterm) return;\n this.xterm.options.theme = getTerminalTheme();\n });\n\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.isVisible()) return;\n this.scheduleFit();\n });\n this.resizeObserver.observe(container);\n this.resizeObserver.observe(this);\n this.observeAncestorResizableGrids(container);\n\n const tabContext = this.findTabContext();\n if (tabContext) {\n this.attachTabVisibilityHandling(tabContext);\n }\n\n if (!tabContext || this.isTabPanelActive(tabContext.tabPanel)) {\n this.scheduleFit(true);\n void this.openBackendIfNeeded();\n }\n }\n\n private observeAncestorResizableGrids(from: Element): void {\n if (!this.resizeObserver) return;\n let el: Element | null = from;\n while (el) {\n if (el.tagName?.toLowerCase() === 'docks-resizable-grid') {\n this.resizeObserver.observe(el);\n }\n const parent: Element | null = el.parentElement;\n if (parent) {\n el = parent;\n } else {\n const root = el.getRootNode();\n el = root instanceof ShadowRoot ? (root.host as Element) : null;\n }\n }\n }\n\n private isVisible(): boolean {\n if (!this.tabPanelName) return true;\n return this.offsetParent !== null;\n }\n\n private applyFit(): void {\n if (!this.fitAddon || !this.xterm || !this.isVisible()) return;\n try {\n this.fitAddon.fit();\n } catch {\n return;\n }\n const dims = this.getDimensions();\n this.terminal?.backend?.setDimensions?.(dims);\n }\n\n private getDimensions(): { cols: number; rows: number } {\n return {\n cols: this.xterm?.cols ?? 80,\n rows: this.xterm?.rows ?? 24,\n };\n }\n\n private teardownTerminal(): void {\n this.detachTabVisibilityHandling();\n this.unobserveTheme?.();\n this.unobserveTheme = null;\n this.backendOpened = false;\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.unsubscribeWrite?.();\n this.unsubscribeWrite = null;\n this.xterm?.dispose();\n this.xterm = null;\n this.fitAddon = null;\n }\n\n protected renderContent() {\n return html`<div class=\"terminal-host\" ${ref(this.xtermRef)}></div>`;\n }\n\n static styles = [\n unsafeCSS(xtermStyles),\n css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0;\n }\n\n .part-shell {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n height: 100%;\n }\n\n .part-content {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .part-content-inner {\n flex: 1;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .terminal-host {\n flex: 1;\n min-height: 0;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--wa-color-surface-lowered);\n padding-left: var(--wa-space-s);\n box-sizing: border-box;\n }\n\n .terminal-host .xterm {\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-terminal-view': DocksTerminalView;\n }\n}\n","import { css, customElement, html } from '@eclipse-docks/core/externals/lit';\nimport {\n DocksPart,\n appSettings,\n promptDialog,\n subscribe,\n unsubscribe,\n} from '@eclipse-docks/core';\nimport {\n TERMINAL_INSTANCES_TABS_ID,\n TERMINAL_NEW_DROPDOWN,\n TERMINAL_PANEL_SETTINGS_KEY,\n TOPIC_TERMINAL_ACTIVE_CHANGED,\n TOPIC_TERMINAL_CLOSED,\n TOPIC_TERMINAL_OPENED,\n type PersistedTerminalState,\n} from './terminal-api';\nimport { emptyTerminalState, parseTerminalState } from './terminal-persistence';\nimport { terminalService, type TerminalTabsHost } from './terminal-service';\nimport './terminal-view';\n\n@customElement('docks-terminal-panel')\nexport class DocksTerminalPanel extends DocksPart {\n protected scrollMode: 'scroller' | 'native' | 'none' = 'none';\n\n private unsubscribeTerminalEvents: (() => void)[] = [];\n\n connectedCallback(): void {\n super.connectedCallback();\n terminalService.setPersistenceHandlers(\n () => this.loadPersistedState(),\n (state) => this.savePersistedState(state)\n );\n for (const topic of [TOPIC_TERMINAL_ACTIVE_CHANGED, TOPIC_TERMINAL_OPENED, TOPIC_TERMINAL_CLOSED]) {\n const token = subscribe(topic, () => this.requestUpdate());\n this.unsubscribeTerminalEvents.push(() => unsubscribe(token));\n }\n this.updateComplete.then(() => {\n this.bindInstanceTabsHost();\n this.attachTabActivationListener();\n void terminalService.restorePersistedTerminals();\n });\n }\n\n private bindInstanceTabsHost(): void {\n const tabs = this.renderRoot.querySelector(\n `docks-tabs#${TERMINAL_INSTANCES_TABS_ID}`\n ) as TerminalTabsHost | null;\n terminalService.setInstanceTabsHost(tabs);\n }\n\n private attachTabActivationListener(): void {\n const tabs = this.renderRoot.querySelector('docks-tabs');\n if (!tabs) return;\n tabs.addEventListener('wa-tab-show', (event: Event) => {\n const name = (event as CustomEvent<{ name?: string }>).detail?.name;\n if (name) terminalService.handleTabActivated(name);\n });\n }\n\n disconnectedCallback(): void {\n for (const off of this.unsubscribeTerminalEvents) off();\n this.unsubscribeTerminalEvents = [];\n terminalService.setInstanceTabsHost(null);\n super.disconnectedCallback();\n }\n\n private async loadPersistedState(): Promise<PersistedTerminalState | null> {\n const raw = await appSettings.getDialogSetting(TERMINAL_PANEL_SETTINGS_KEY);\n return parseTerminalState(raw) ?? emptyTerminalState();\n }\n\n private async savePersistedState(state: PersistedTerminalState): Promise<void> {\n await appSettings.setDialogSetting(TERMINAL_PANEL_SETTINGS_KEY, state);\n }\n\n protected renderToolbar() {\n const hasActive = !!terminalService.activeTerminal;\n return html`\n <docks-command\n icon=\"plus\"\n title=\"New Terminal\"\n dropdown=\"${TERMINAL_NEW_DROPDOWN}\"\n .action=${() => void terminalService.createTerminal()}\n >\n </docks-command>\n <docks-command\n icon=\"xmark\"\n title=\"Kill Terminal\"\n ?disabled=${!hasActive}\n .action=${async () => {\n await terminalService.activeTerminal?.dispose();\n }}\n ></docks-command>\n <docks-command\n icon=\"eraser\"\n title=\"Clear\"\n ?disabled=${!hasActive}\n .action=${() => {\n terminalService.activeTerminal?.clear?.();\n }}\n ></docks-command>\n <docks-command\n icon=\"pen\"\n title=\"Rename\"\n ?disabled=${!hasActive}\n .action=${async () => {\n const active = terminalService.activeTerminal;\n if (!active) return;\n const name = await promptDialog('Terminal name', active.name);\n if (name?.trim()) terminalService.renameActiveTerminal(name.trim());\n }}\n ></docks-command>\n `;\n }\n\n protected renderContent() {\n return html`\n <docks-tabs\n id=\"${TERMINAL_INSTANCES_TABS_ID}\"\n placement=\"start\"\n item-size=\"s\"\n ></docks-tabs>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0;\n }\n\n docks-tabs {\n flex: 1;\n min-height: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-terminal-panel': DocksTerminalPanel;\n }\n}\n","import { html } from '@eclipse-docks/core/externals/lit';\nimport { contributionRegistry, PANEL_BOTTOM, registerAll } from '@eclipse-docks/core';\nimport { VIEW_TERMINAL } from './terminal-api';\nimport { CommandsBackend } from './commands-backend';\nimport { createJsSessionBackend, JsReplBackend, JS_REPL_PROFILE_ID, JS_SESSION_PROFILE_ID } from './js-terminal-backend';\nimport { registerTerminalProfile, terminalService } from './terminal-service';\nimport './terminal-panel';\n\nconst COMMANDS_PROFILE_ID = 'terminal.javascript-shell';\n\nexport default async function activate() {\n registerTerminalProfile({\n id: COMMANDS_PROFILE_ID,\n label: 'Commands',\n icon: 'terminal',\n isDefault: true,\n create: async () => new CommandsBackend(),\n });\n\n registerTerminalProfile({\n id: JS_REPL_PROFILE_ID,\n label: 'JavaScript',\n icon: 'code',\n create: async () => new JsReplBackend(),\n });\n\n registerTerminalProfile({\n id: JS_SESSION_PROFILE_ID,\n label: 'JavaScript',\n icon: 'code',\n hidden: true,\n persist: false,\n create: async (options) => createJsSessionBackend(options),\n });\n\n contributionRegistry.registerContribution(PANEL_BOTTOM, {\n name: VIEW_TERMINAL,\n label: 'Terminal',\n icon: 'terminal',\n component: (id: string) => html`<docks-terminal-panel id=\"${id}\"></docks-terminal-panel>`,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terminal-extension-B0d4I4cK.js","names":[],"sources":["../src/terminal-theme.ts","../src/terminal-view.ts","../src/terminal-panel.ts","../src/terminal-extension.ts"],"sourcesContent":["import type { ITheme } from '@xterm/xterm';\n\nfunction cssVar(name: string, fallback: string): string {\n const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();\n return value || fallback;\n}\n\nexport function isDarkTheme(): boolean {\n const root = document.documentElement;\n if (root.classList.contains('wa-dark')) return true;\n if (root.classList.contains('wa-light')) return false;\n return true;\n}\n\nexport function getTerminalTheme(): ITheme {\n const dark = isDarkTheme();\n return {\n background: cssVar('--wa-color-surface-lowered', dark ? '#1e1e1e' : '#f3f3f3'),\n foreground: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n cursor: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n cursorAccent: cssVar('--wa-color-surface-lowered', dark ? '#1e1e1e' : '#f3f3f3'),\n selectionBackground: cssVar('--wa-color-brand-fill-quiet', dark ? '#264f7840' : '#add6ff80'),\n selectionForeground: cssVar('--wa-color-text-normal', dark ? '#d4d4d4' : '#1e1e1e'),\n black: cssVar('--wa-color-neutral-10', dark ? '#000000' : '#1e1e1e'),\n red: cssVar('--wa-color-danger-fill-loud', '#cd3131'),\n green: cssVar('--wa-color-success-fill-loud', '#0dbc79'),\n yellow: cssVar('--wa-color-warning-fill-loud', '#e5e510'),\n blue: cssVar('--wa-color-brand-fill-loud', '#2472c8'),\n magenta: cssVar('--wa-color-purple-50', '#bc3fbc'),\n cyan: cssVar('--wa-color-cyan-50', '#11a8cd'),\n white: cssVar('--wa-color-neutral-90', dark ? '#e5e5e5' : '#ffffff'),\n brightBlack: cssVar('--wa-color-neutral-50', '#666666'),\n brightRed: cssVar('--wa-color-danger-50', '#f14c4c'),\n brightGreen: cssVar('--wa-color-success-50', '#23d18b'),\n brightYellow: cssVar('--wa-color-warning-50', '#f5f543'),\n brightBlue: cssVar('--wa-color-brand-50', '#3b8eea'),\n brightMagenta: cssVar('--wa-color-purple-40', '#d670d6'),\n brightCyan: cssVar('--wa-color-cyan-40', '#29b8db'),\n brightWhite: cssVar('--wa-color-neutral-95', '#ffffff'),\n };\n}\n\n/** Watches `wa-dark` / `wa-light` on `<html>`, same pattern as docks-monaco-widget. */\nexport function observeTerminalTheme(onChange: () => void): () => void {\n const root = document.documentElement;\n let dark = isDarkTheme();\n\n const observer = new MutationObserver(() => {\n const next = isDarkTheme();\n if (next === dark) return;\n dark = next;\n onChange();\n });\n\n observer.observe(root, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n}\n","import { css, createRef, customElement, html, property, ref, unsafeCSS, type Ref } from '@eclipse-docks/core/externals/lit';\nimport { Terminal } from '@xterm/xterm';\nimport { FitAddon } from '@xterm/addon-fit';\nimport { DocksPart } from '@eclipse-docks/core';\nimport { terminalService } from './terminal-service';\nimport type { TerminalRuntime } from './terminal-api';\nimport { getTerminalTheme, observeTerminalTheme } from './terminal-theme';\nimport xtermStyles from '@xterm/xterm/css/xterm.css?raw';\n\n@customElement('docks-terminal-view')\nexport class DocksTerminalView extends DocksPart {\n protected scrollMode: 'scroller' | 'native' | 'none' = 'none';\n\n @property({ attribute: false })\n terminal?: TerminalRuntime;\n\n private xtermRef: Ref<HTMLDivElement> = createRef();\n private xterm: Terminal | null = null;\n private fitAddon: FitAddon | null = null;\n private unsubscribeWrite: (() => void) | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private tabsHost: Element | null = null;\n private tabPanelName: string | null = null;\n private onTabShow: ((event: Event) => void) | null = null;\n private backendOpened = false;\n private unobserveTheme: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n void this.initTerminal();\n }\n\n disconnectedCallback(): void {\n this.teardownTerminal();\n super.disconnectedCallback();\n }\n\n close(): void {\n if (this.terminal) {\n terminalService.handleTabClosed(this.terminal.id);\n }\n this.teardownTerminal();\n }\n\n private findTabContext(): { panelName: string; tabPanel: HTMLElement; tabsHost: Element } | null {\n let panelName: string | null = null;\n let tabPanel: HTMLElement | null = null;\n let tabsHost: Element | null = null;\n let el: Element | null = this;\n\n while (el) {\n const tag = el.tagName?.toLowerCase();\n if (tag === 'wa-tab-panel' && !tabPanel) {\n tabPanel = el as HTMLElement;\n panelName = el.getAttribute('name');\n }\n if (tag === 'docks-tabs') {\n tabsHost = el;\n break;\n }\n const parent: Element | null = el.parentElement;\n if (parent) {\n el = parent;\n } else {\n const root = el.getRootNode();\n el = root instanceof ShadowRoot ? (root.host as Element) : null;\n }\n }\n\n if (!tabsHost || !tabPanel || !panelName) return null;\n return { panelName, tabPanel, tabsHost };\n }\n\n private isTabPanelActive(tabPanel: HTMLElement): boolean {\n return tabPanel.hasAttribute('active');\n }\n\n private attachTabVisibilityHandling(context: {\n panelName: string;\n tabsHost: Element;\n }): void {\n this.tabsHost = context.tabsHost;\n this.tabPanelName = context.panelName;\n this.onTabShow = (event: Event) => {\n const name = (event as CustomEvent<{ name?: string }>).detail?.name;\n if (name !== context.panelName) return;\n this.onTabShown();\n };\n context.tabsHost.addEventListener('wa-tab-show', this.onTabShow);\n }\n\n private detachTabVisibilityHandling(): void {\n if (this.tabsHost && this.onTabShow) {\n this.tabsHost.removeEventListener('wa-tab-show', this.onTabShow);\n }\n this.tabsHost = null;\n this.tabPanelName = null;\n this.onTabShow = null;\n }\n\n private scheduleFit(focus = false): void {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n this.applyFit();\n if (focus) this.xterm?.focus();\n });\n });\n }\n\n private async openBackendIfNeeded(): Promise<void> {\n if (this.backendOpened || !this.terminal?.backend) return;\n this.backendOpened = true;\n await this.terminal.backend.open?.(this.getDimensions());\n }\n\n private onTabShown(): void {\n this.scheduleFit(true);\n void this.openBackendIfNeeded();\n }\n\n private async initTerminal(): Promise<void> {\n if (!this.terminal?.backend) return;\n await this.updateComplete;\n\n const container = this.xtermRef.value;\n if (!container) return;\n\n this.xterm = new Terminal({\n cursorBlink: true,\n fontFamily: 'var(--wa-font-mono, monospace)',\n fontSize: 13,\n theme: getTerminalTheme(),\n });\n this.fitAddon = new FitAddon();\n this.xterm.loadAddon(this.fitAddon);\n this.xterm.open(container);\n\n const backend = this.terminal.backend;\n this.unsubscribeWrite = backend.onDidWrite((data) => {\n this.xterm?.write(data);\n });\n\n this.xterm.onData((data) => {\n backend.handleInput(data);\n });\n\n this.terminal.clearScreen = () => {\n this.xterm?.clear();\n };\n\n this.unobserveTheme = observeTerminalTheme(() => {\n if (!this.xterm) return;\n this.xterm.options.theme = getTerminalTheme();\n });\n\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.isVisible()) return;\n this.scheduleFit();\n });\n this.resizeObserver.observe(container);\n this.resizeObserver.observe(this);\n this.observeAncestorResizableGrids(container);\n\n const tabContext = this.findTabContext();\n if (tabContext) {\n this.attachTabVisibilityHandling(tabContext);\n }\n\n if (!tabContext || this.isTabPanelActive(tabContext.tabPanel)) {\n this.scheduleFit(true);\n void this.openBackendIfNeeded();\n }\n }\n\n private observeAncestorResizableGrids(from: Element): void {\n if (!this.resizeObserver) return;\n let el: Element | null = from;\n while (el) {\n if (el.tagName?.toLowerCase() === 'docks-resizable-grid') {\n this.resizeObserver.observe(el);\n }\n const parent: Element | null = el.parentElement;\n if (parent) {\n el = parent;\n } else {\n const root = el.getRootNode();\n el = root instanceof ShadowRoot ? (root.host as Element) : null;\n }\n }\n }\n\n private isVisible(): boolean {\n if (!this.tabPanelName) return true;\n return this.offsetParent !== null;\n }\n\n private applyFit(): void {\n if (!this.fitAddon || !this.xterm || !this.isVisible()) return;\n try {\n this.fitAddon.fit();\n } catch {\n return;\n }\n const dims = this.getDimensions();\n this.terminal?.backend?.setDimensions?.(dims);\n }\n\n private getDimensions(): { cols: number; rows: number } {\n return {\n cols: this.xterm?.cols ?? 80,\n rows: this.xterm?.rows ?? 24,\n };\n }\n\n private teardownTerminal(): void {\n this.detachTabVisibilityHandling();\n this.unobserveTheme?.();\n this.unobserveTheme = null;\n this.backendOpened = false;\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.unsubscribeWrite?.();\n this.unsubscribeWrite = null;\n this.xterm?.dispose();\n this.xterm = null;\n this.fitAddon = null;\n }\n\n protected renderContent() {\n return html`<div class=\"terminal-host\" ${ref(this.xtermRef)}></div>`;\n }\n\n static styles = [\n unsafeCSS(xtermStyles),\n css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0;\n }\n\n .part-shell {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n height: 100%;\n }\n\n .part-content {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .part-content-inner {\n flex: 1;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n }\n\n .terminal-host {\n flex: 1;\n min-height: 0;\n height: 100%;\n width: 100%;\n overflow: hidden;\n background: var(--wa-color-surface-lowered);\n padding-left: var(--wa-space-s);\n box-sizing: border-box;\n }\n\n .terminal-host .xterm {\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-terminal-view': DocksTerminalView;\n }\n}\n","import { css, customElement, html } from '@eclipse-docks/core/externals/lit';\nimport {\n DocksPart,\n appSettings,\n promptDialog,\n subscribe,\n unsubscribe,\n} from '@eclipse-docks/core';\nimport {\n TERMINAL_INSTANCES_TABS_ID,\n TERMINAL_NEW_DROPDOWN,\n TERMINAL_PANEL_SETTINGS_KEY,\n TOPIC_TERMINAL_ACTIVE_CHANGED,\n TOPIC_TERMINAL_CLOSED,\n TOPIC_TERMINAL_OPENED,\n type PersistedTerminalState,\n} from './terminal-api';\nimport { emptyTerminalState, parseTerminalState } from './terminal-persistence';\nimport { terminalService, type TerminalTabsHost } from './terminal-service';\nimport './terminal-view';\n\n@customElement('docks-terminal-panel')\nexport class DocksTerminalPanel extends DocksPart {\n protected scrollMode: 'scroller' | 'native' | 'none' = 'none';\n\n private unsubscribeTerminalEvents: (() => void)[] = [];\n\n connectedCallback(): void {\n super.connectedCallback();\n terminalService.setPersistenceHandlers(\n () => this.loadPersistedState(),\n (state) => this.savePersistedState(state)\n );\n for (const topic of [TOPIC_TERMINAL_ACTIVE_CHANGED, TOPIC_TERMINAL_OPENED, TOPIC_TERMINAL_CLOSED]) {\n const token = subscribe(topic, () => this.requestUpdate());\n this.unsubscribeTerminalEvents.push(() => unsubscribe(token));\n }\n this.updateComplete.then(() => {\n this.bindInstanceTabsHost();\n this.attachTabActivationListener();\n void terminalService.restorePersistedTerminals();\n });\n }\n\n private bindInstanceTabsHost(): void {\n const tabs = this.renderRoot.querySelector(\n `docks-tabs#${TERMINAL_INSTANCES_TABS_ID}`\n ) as TerminalTabsHost | null;\n terminalService.setInstanceTabsHost(tabs);\n }\n\n private attachTabActivationListener(): void {\n const tabs = this.renderRoot.querySelector('docks-tabs');\n if (!tabs) return;\n tabs.addEventListener('wa-tab-show', (event: Event) => {\n const name = (event as CustomEvent<{ name?: string }>).detail?.name;\n if (name) terminalService.handleTabActivated(name);\n });\n }\n\n disconnectedCallback(): void {\n for (const off of this.unsubscribeTerminalEvents) off();\n this.unsubscribeTerminalEvents = [];\n terminalService.setInstanceTabsHost(null);\n super.disconnectedCallback();\n }\n\n private async loadPersistedState(): Promise<PersistedTerminalState | null> {\n const raw = await appSettings.getDialogSetting(TERMINAL_PANEL_SETTINGS_KEY);\n return parseTerminalState(raw) ?? emptyTerminalState();\n }\n\n private async savePersistedState(state: PersistedTerminalState): Promise<void> {\n await appSettings.setDialogSetting(TERMINAL_PANEL_SETTINGS_KEY, state);\n }\n\n protected renderToolbar() {\n const hasActive = !!terminalService.activeTerminal;\n return html`\n <docks-command\n icon=\"plus\"\n title=\"New Terminal\"\n dropdown=\"${TERMINAL_NEW_DROPDOWN}\"\n .action=${() => void terminalService.createTerminal()}\n >\n </docks-command>\n <docks-command\n icon=\"xmark\"\n title=\"Kill Terminal\"\n ?disabled=${!hasActive}\n .action=${async () => {\n await terminalService.activeTerminal?.dispose();\n }}\n ></docks-command>\n <docks-command\n icon=\"eraser\"\n title=\"Clear\"\n ?disabled=${!hasActive}\n .action=${() => {\n terminalService.activeTerminal?.clear?.();\n }}\n ></docks-command>\n <docks-command\n icon=\"pen\"\n title=\"Rename\"\n ?disabled=${!hasActive}\n .action=${async () => {\n const active = terminalService.activeTerminal;\n if (!active) return;\n const name = await promptDialog('Terminal name', active.name);\n if (name?.trim()) terminalService.renameActiveTerminal(name.trim());\n }}\n ></docks-command>\n `;\n }\n\n protected renderContent() {\n return html`\n <docks-tabs\n id=\"${TERMINAL_INSTANCES_TABS_ID}\"\n placement=\"start\"\n item-size=\"s\"\n ></docks-tabs>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0;\n }\n\n docks-tabs {\n flex: 1;\n min-height: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-terminal-panel': DocksTerminalPanel;\n }\n}\n","import { html } from '@eclipse-docks/core/externals/lit';\nimport { contributionRegistry, PANEL_BOTTOM, registerAll } from '@eclipse-docks/core';\nimport { VIEW_TERMINAL } from './terminal-api';\nimport { CommandsBackend } from './commands-backend';\nimport { createJsSessionBackend, JsReplBackend, JS_REPL_PROFILE_ID, JS_SESSION_PROFILE_ID } from './js-terminal-backend';\nimport { registerTerminalProfile, terminalService } from './terminal-service';\nimport './terminal-panel';\n\nconst COMMANDS_PROFILE_ID = 'terminal.javascript-shell';\n\nexport default async function activate() {\n registerTerminalProfile({\n id: COMMANDS_PROFILE_ID,\n label: 'Commands',\n icon: 'terminal',\n isDefault: true,\n create: async () => new CommandsBackend(),\n });\n\n registerTerminalProfile({\n id: JS_REPL_PROFILE_ID,\n label: 'JavaScript',\n icon: 'code',\n create: async () => new JsReplBackend(),\n });\n\n registerTerminalProfile({\n id: JS_SESSION_PROFILE_ID,\n label: 'JavaScript',\n icon: 'code',\n hidden: true,\n persist: false,\n create: async (options) => createJsSessionBackend(options),\n });\n\n contributionRegistry.registerContribution(PANEL_BOTTOM, {\n name: VIEW_TERMINAL,\n label: 'Terminal',\n icon: 'terminal',\n component: (id: string) => html`<docks-terminal-panel id=\"${id}\"></docks-terminal-panel>`,\n });\n}\n"],"mappings":"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"}
|