@phenx-inc/ctlsurf 0.3.14 → 0.3.16
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/out/headless/index.mjs +57 -8
- package/out/headless/index.mjs.map +2 -2
- package/out/main/index.js +56 -7
- package/out/preload/index.js +6 -0
- package/out/renderer/assets/{cssMode-G_SDogBL.js → cssMode-D5dPwEy5.js} +3 -3
- package/out/renderer/assets/{freemarker2-BzEus0h2.js → freemarker2-c5jJjQ9s.js} +1 -1
- package/out/renderer/assets/{handlebars-Et995f6O.js → handlebars-BTbmOxx9.js} +1 -1
- package/out/renderer/assets/{html-D4wgKxPD.js → html-3cIIQcxO.js} +1 -1
- package/out/renderer/assets/{htmlMode-DSxpefzL.js → htmlMode-DYbpW1yY.js} +3 -3
- package/out/renderer/assets/{index-AQ346NMi.css → index-6KvOnYL1.css} +18 -0
- package/out/renderer/assets/{index-ByJTqkiQ.js → index-D2MUZin7.js} +36 -23
- package/out/renderer/assets/{javascript-CzLoo8aq.js → javascript-CDuCMm-6.js} +2 -2
- package/out/renderer/assets/{jsonMode-BrwPy7fY.js → jsonMode-COLqbq0s.js} +3 -3
- package/out/renderer/assets/{liquid-BsfPf6YG.js → liquid-BFcqZizB.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-CxLZ421s.js → lspLanguageFeatures-CbkEcL-z.js} +1 -1
- package/out/renderer/assets/{mdx-CPvHIsAR.js → mdx-DyK93oEE.js} +1 -1
- package/out/renderer/assets/{python-Dr7dCUjG.js → python-D4lCwSVr.js} +1 -1
- package/out/renderer/assets/{razor-a7zjD7Y3.js → razor-DdkE9XVt.js} +1 -1
- package/out/renderer/assets/{tsMode-B7KLV2X6.js → tsMode-BrQ4Fsc-.js} +1 -1
- package/out/renderer/assets/{typescript-Cjuzf37q.js → typescript-BakbYMnC.js} +1 -1
- package/out/renderer/assets/{xml-Yz9xINtk.js → xml-DHDW9Xhp.js} +1 -1
- package/out/renderer/assets/{yaml-DtKnp5J0.js → yaml-1Ayv_J3q.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/src/main/agents.ts +36 -1
- package/src/main/headless.ts +5 -3
- package/src/main/index.ts +4 -2
- package/src/main/orchestrator.ts +29 -0
- package/src/main/workerWs.ts +8 -6
- package/src/preload/index.ts +7 -0
- package/src/renderer/App.tsx +19 -1
- package/src/renderer/styles.css +18 -0
package/out/main/index.js
CHANGED
|
@@ -59,6 +59,21 @@ function getShellCommand() {
|
|
|
59
59
|
if (process.platform === "win32") return "powershell.exe";
|
|
60
60
|
return process.env.SHELL || "/bin/zsh";
|
|
61
61
|
}
|
|
62
|
+
function isCommandAvailable(command) {
|
|
63
|
+
const dirs = (process.env.PATH || "").split(path.delimiter).filter(Boolean);
|
|
64
|
+
const isWin = process.platform === "win32";
|
|
65
|
+
const exts = isWin ? (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean) : [""];
|
|
66
|
+
for (const dir of dirs) {
|
|
67
|
+
for (const ext of exts) {
|
|
68
|
+
try {
|
|
69
|
+
fs.accessSync(path.join(dir, command + ext), isWin ? fs.constants.F_OK : fs.constants.X_OK);
|
|
70
|
+
return true;
|
|
71
|
+
} catch {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
62
77
|
function getBuiltinAgents() {
|
|
63
78
|
return [
|
|
64
79
|
{
|
|
@@ -85,8 +100,14 @@ function getBuiltinAgents() {
|
|
|
85
100
|
}
|
|
86
101
|
];
|
|
87
102
|
}
|
|
103
|
+
function getAvailableAgents() {
|
|
104
|
+
const all = getBuiltinAgents();
|
|
105
|
+
const coding = all.filter((a) => isCodingAgent(a) && isCommandAvailable(a.command));
|
|
106
|
+
const shell = all.filter((a) => !isCodingAgent(a));
|
|
107
|
+
return [...coding, ...shell];
|
|
108
|
+
}
|
|
88
109
|
function getDefaultAgent() {
|
|
89
|
-
return
|
|
110
|
+
return getAvailableAgents()[0];
|
|
90
111
|
}
|
|
91
112
|
function isCodingAgent(agent) {
|
|
92
113
|
return agent.id !== "shell";
|
|
@@ -9932,11 +9953,9 @@ class WorkerWsClient {
|
|
|
9932
9953
|
workerId = null;
|
|
9933
9954
|
_status = "disconnected";
|
|
9934
9955
|
shouldReconnect = false;
|
|
9935
|
-
fingerprint;
|
|
9936
9956
|
constructor(events, baseUrl) {
|
|
9937
9957
|
this.events = events;
|
|
9938
9958
|
this.baseUrl = baseUrl || "wss://app.ctlsurf.com";
|
|
9939
|
-
this.fingerprint = this.generateFingerprint();
|
|
9940
9959
|
}
|
|
9941
9960
|
get status() {
|
|
9942
9961
|
return this._status;
|
|
@@ -9950,8 +9969,12 @@ class WorkerWsClient {
|
|
|
9950
9969
|
setBaseUrl(url) {
|
|
9951
9970
|
this.baseUrl = url;
|
|
9952
9971
|
}
|
|
9953
|
-
|
|
9954
|
-
|
|
9972
|
+
// Per-directory fingerprint: each working directory is a distinct worker, so
|
|
9973
|
+
// multiple instances on the same machine (one per project) don't collide as a
|
|
9974
|
+
// single worker server-side. cwd is included so the same folder maps to the
|
|
9975
|
+
// same worker across restarts.
|
|
9976
|
+
generateFingerprint(cwd) {
|
|
9977
|
+
const data = `${os.hostname()}:${os.userInfo().username}:${os.platform()}:${os.arch()}:${cwd}`;
|
|
9955
9978
|
return require$$1.createHash("sha256").update(data).digest("hex").slice(0, 32);
|
|
9956
9979
|
}
|
|
9957
9980
|
setStatus(status) {
|
|
@@ -9961,7 +9984,8 @@ class WorkerWsClient {
|
|
|
9961
9984
|
}
|
|
9962
9985
|
}
|
|
9963
9986
|
connect(registration) {
|
|
9964
|
-
|
|
9987
|
+
const fingerprint = this.generateFingerprint(registration.cwd);
|
|
9988
|
+
this.registration = { ...registration, fingerprint };
|
|
9965
9989
|
this.shouldReconnect = true;
|
|
9966
9990
|
this.doConnect();
|
|
9967
9991
|
}
|
|
@@ -10694,6 +10718,7 @@ class Orchestrator {
|
|
|
10694
10718
|
};
|
|
10695
10719
|
noProjectPollTimer = null;
|
|
10696
10720
|
noProjectPollCwd = null;
|
|
10721
|
+
currentProjectName = null;
|
|
10697
10722
|
constructor(settingsDir, events) {
|
|
10698
10723
|
this.settingsDir = settingsDir;
|
|
10699
10724
|
this.events = events;
|
|
@@ -10718,12 +10743,14 @@ class Orchestrator {
|
|
|
10718
10743
|
log$3(`[worker-ws] Registered: worker_id=${data.worker_id}, folder_id=${data.folder_id}, status=${data.status}`);
|
|
10719
10744
|
events.onWorkerRegistered(data);
|
|
10720
10745
|
if (!data.folder_id) {
|
|
10746
|
+
this.setProjectName(null);
|
|
10721
10747
|
events.onWorkerStatus("no_project");
|
|
10722
10748
|
if (this.currentCwd && data.status !== "pending_approval") {
|
|
10723
10749
|
this.startNoProjectPolling(this.currentCwd);
|
|
10724
10750
|
}
|
|
10725
10751
|
} else {
|
|
10726
10752
|
this.stopNoProjectPolling();
|
|
10753
|
+
this.resolveProjectName(data.folder_id);
|
|
10727
10754
|
}
|
|
10728
10755
|
},
|
|
10729
10756
|
onTerminalInput: (data) => {
|
|
@@ -10758,6 +10785,26 @@ class Orchestrator {
|
|
|
10758
10785
|
get cwd() {
|
|
10759
10786
|
return this.currentCwd;
|
|
10760
10787
|
}
|
|
10788
|
+
// Name of the connected ctlsurf project (folder) for the desktop header.
|
|
10789
|
+
get projectName() {
|
|
10790
|
+
return this.currentProjectName;
|
|
10791
|
+
}
|
|
10792
|
+
setProjectName(name) {
|
|
10793
|
+
if (this.currentProjectName === name) return;
|
|
10794
|
+
this.currentProjectName = name;
|
|
10795
|
+
this.events.onProjectChanged?.(name);
|
|
10796
|
+
}
|
|
10797
|
+
// Resolve the connected folder's human-readable name. Best-effort: a failed
|
|
10798
|
+
// lookup just leaves the project name unset rather than blocking anything.
|
|
10799
|
+
async resolveProjectName(folderId) {
|
|
10800
|
+
try {
|
|
10801
|
+
const folder = await this.ctlsurfApi.getFolder(folderId);
|
|
10802
|
+
const name = folder?.name ?? folder?.title;
|
|
10803
|
+
this.setProjectName(typeof name === "string" && name ? name : null);
|
|
10804
|
+
} catch (err) {
|
|
10805
|
+
log$3(`[worker-ws] Failed to resolve project name for folder ${folderId}: ${err}`);
|
|
10806
|
+
}
|
|
10807
|
+
}
|
|
10761
10808
|
get agent() {
|
|
10762
10809
|
return this.currentAgent;
|
|
10763
10810
|
}
|
|
@@ -11222,6 +11269,7 @@ const orchestrator = new Orchestrator(
|
|
|
11222
11269
|
onWorkerStatus: (status) => mainWindow?.webContents.send("worker:status", status),
|
|
11223
11270
|
onWorkerMessage: (message) => mainWindow?.webContents.send("worker:message", message),
|
|
11224
11271
|
onWorkerRegistered: (data) => mainWindow?.webContents.send("worker:registered", data),
|
|
11272
|
+
onProjectChanged: (name) => mainWindow?.webContents.send("app:projectChanged", name),
|
|
11225
11273
|
onCwdChanged: () => {
|
|
11226
11274
|
mainWindow?.webContents.send("app:cwdChanged");
|
|
11227
11275
|
updateProjectBadge(orchestrator.cwd);
|
|
@@ -11269,10 +11317,11 @@ electron.ipcMain.handle("pty:kill", async (_event, tabId) => {
|
|
|
11269
11317
|
electron.ipcMain.handle("pty:setActiveTab", (_event, tabId) => {
|
|
11270
11318
|
orchestrator.setActiveTab(tabId);
|
|
11271
11319
|
});
|
|
11272
|
-
electron.ipcMain.handle("agents:list", () =>
|
|
11320
|
+
electron.ipcMain.handle("agents:list", () => getAvailableAgents());
|
|
11273
11321
|
electron.ipcMain.handle("agents:default", () => getDefaultAgent());
|
|
11274
11322
|
electron.ipcMain.handle("app:homePath", () => electron.app.getPath("home"));
|
|
11275
11323
|
electron.ipcMain.handle("app:cwd", () => process.env.CTLSURF_WORKER_CWD || process.cwd());
|
|
11324
|
+
electron.ipcMain.handle("app:projectName", () => orchestrator.projectName);
|
|
11276
11325
|
electron.ipcMain.handle("app:browseCwd", async () => {
|
|
11277
11326
|
if (!mainWindow) return null;
|
|
11278
11327
|
const result = await electron.dialog.showOpenDialog(mainWindow, {
|
package/out/preload/index.js
CHANGED
|
@@ -24,6 +24,12 @@ const api = {
|
|
|
24
24
|
// App info
|
|
25
25
|
getHomePath: () => electron.ipcRenderer.invoke("app:homePath"),
|
|
26
26
|
getCwd: () => electron.ipcRenderer.invoke("app:cwd"),
|
|
27
|
+
getProjectName: () => electron.ipcRenderer.invoke("app:projectName"),
|
|
28
|
+
onProjectChanged: (callback) => {
|
|
29
|
+
const listener = (_event, name) => callback(name);
|
|
30
|
+
electron.ipcRenderer.on("app:projectChanged", listener);
|
|
31
|
+
return () => electron.ipcRenderer.removeListener("app:projectChanged", listener);
|
|
32
|
+
},
|
|
27
33
|
browseCwd: () => electron.ipcRenderer.invoke("app:browseCwd"),
|
|
28
34
|
getVersion: () => electron.ipcRenderer.invoke("app:getVersion"),
|
|
29
35
|
getUpdateInfo: () => electron.ipcRenderer.invoke("app:getUpdateInfo"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
2
|
-
import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-
|
|
3
|
-
import { h, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-D2MUZin7.js";
|
|
2
|
+
import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
3
|
+
import { h, i, j, t, k } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
2
|
-
import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-
|
|
3
|
-
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-D2MUZin7.js";
|
|
2
|
+
import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
3
|
+
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -7422,6 +7422,24 @@ html, body, #root {
|
|
|
7422
7422
|
.titlebar-title {
|
|
7423
7423
|
font-weight: 600;
|
|
7424
7424
|
color: #c0caf5;
|
|
7425
|
+
display: flex;
|
|
7426
|
+
align-items: center;
|
|
7427
|
+
gap: 6px;
|
|
7428
|
+
min-width: 0;
|
|
7429
|
+
}
|
|
7430
|
+
|
|
7431
|
+
.titlebar-title-sep {
|
|
7432
|
+
color: #565f89;
|
|
7433
|
+
font-weight: 400;
|
|
7434
|
+
}
|
|
7435
|
+
|
|
7436
|
+
.titlebar-project {
|
|
7437
|
+
color: #7aa2f7;
|
|
7438
|
+
font-weight: 600;
|
|
7439
|
+
white-space: nowrap;
|
|
7440
|
+
overflow: hidden;
|
|
7441
|
+
text-overflow: ellipsis;
|
|
7442
|
+
max-width: 280px;
|
|
7425
7443
|
}
|
|
7426
7444
|
|
|
7427
7445
|
.titlebar-controls {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./cssMode-D5dPwEy5.js","./lspLanguageFeatures-CbkEcL-z.js","./htmlMode-DYbpW1yY.js","./jsonMode-COLqbq0s.js","./javascript-CDuCMm-6.js","./typescript-BakbYMnC.js"])))=>i.map(i=>d[i]);
|
|
2
2
|
function getDefaultExportFromCjs(x) {
|
|
3
3
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
4
4
|
}
|
|
@@ -206558,7 +206558,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
|
|
|
206558
206558
|
modeConfigurationDefault$2
|
|
206559
206559
|
);
|
|
206560
206560
|
function getMode$3() {
|
|
206561
|
-
return __vitePreload(() => import("./cssMode-
|
|
206561
|
+
return __vitePreload(() => import("./cssMode-D5dPwEy5.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
|
|
206562
206562
|
}
|
|
206563
206563
|
languages.onLanguage("less", () => {
|
|
206564
206564
|
getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
|
|
@@ -206663,7 +206663,7 @@ const razorLanguageService = registerHTMLLanguageService(
|
|
|
206663
206663
|
);
|
|
206664
206664
|
const razorDefaults = razorLanguageService.defaults;
|
|
206665
206665
|
function getMode$2() {
|
|
206666
|
-
return __vitePreload(() => import("./htmlMode-
|
|
206666
|
+
return __vitePreload(() => import("./htmlMode-DYbpW1yY.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
|
|
206667
206667
|
}
|
|
206668
206668
|
function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
|
|
206669
206669
|
const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
|
|
@@ -206747,7 +206747,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
|
|
|
206747
206747
|
);
|
|
206748
206748
|
const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
|
|
206749
206749
|
function getMode$1() {
|
|
206750
|
-
return __vitePreload(() => import("./jsonMode-
|
|
206750
|
+
return __vitePreload(() => import("./jsonMode-COLqbq0s.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
|
|
206751
206751
|
}
|
|
206752
206752
|
languages.register({
|
|
206753
206753
|
id: "json",
|
|
@@ -206993,7 +206993,7 @@ const getJavaScriptWorker = () => {
|
|
|
206993
206993
|
return getMode().then((mode) => mode.getJavaScriptWorker());
|
|
206994
206994
|
};
|
|
206995
206995
|
function getMode() {
|
|
206996
|
-
return __vitePreload(() => import("./tsMode-
|
|
206996
|
+
return __vitePreload(() => import("./tsMode-BrQ4Fsc-.js"), true ? [] : void 0, import.meta.url);
|
|
206997
206997
|
}
|
|
206998
206998
|
languages.onLanguage("typescript", () => {
|
|
206999
206999
|
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
|
|
@@ -207188,49 +207188,49 @@ registerLanguage({
|
|
|
207188
207188
|
extensions: [".ftl", ".ftlh", ".ftlx"],
|
|
207189
207189
|
aliases: ["FreeMarker2", "Apache FreeMarker2"],
|
|
207190
207190
|
loader: () => {
|
|
207191
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207191
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207192
207192
|
}
|
|
207193
207193
|
});
|
|
207194
207194
|
registerLanguage({
|
|
207195
207195
|
id: "freemarker2.tag-angle.interpolation-dollar",
|
|
207196
207196
|
aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
|
|
207197
207197
|
loader: () => {
|
|
207198
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207198
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
|
|
207199
207199
|
}
|
|
207200
207200
|
});
|
|
207201
207201
|
registerLanguage({
|
|
207202
207202
|
id: "freemarker2.tag-bracket.interpolation-dollar",
|
|
207203
207203
|
aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
|
|
207204
207204
|
loader: () => {
|
|
207205
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207205
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
|
|
207206
207206
|
}
|
|
207207
207207
|
});
|
|
207208
207208
|
registerLanguage({
|
|
207209
207209
|
id: "freemarker2.tag-angle.interpolation-bracket",
|
|
207210
207210
|
aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
|
|
207211
207211
|
loader: () => {
|
|
207212
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207212
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
|
|
207213
207213
|
}
|
|
207214
207214
|
});
|
|
207215
207215
|
registerLanguage({
|
|
207216
207216
|
id: "freemarker2.tag-bracket.interpolation-bracket",
|
|
207217
207217
|
aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
|
|
207218
207218
|
loader: () => {
|
|
207219
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207219
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
|
|
207220
207220
|
}
|
|
207221
207221
|
});
|
|
207222
207222
|
registerLanguage({
|
|
207223
207223
|
id: "freemarker2.tag-auto.interpolation-dollar",
|
|
207224
207224
|
aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
|
|
207225
207225
|
loader: () => {
|
|
207226
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207226
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207227
207227
|
}
|
|
207228
207228
|
});
|
|
207229
207229
|
registerLanguage({
|
|
207230
207230
|
id: "freemarker2.tag-auto.interpolation-bracket",
|
|
207231
207231
|
aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
|
|
207232
207232
|
loader: () => {
|
|
207233
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207233
|
+
return __vitePreload(() => import("./freemarker2-c5jJjQ9s.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
|
|
207234
207234
|
}
|
|
207235
207235
|
});
|
|
207236
207236
|
registerLanguage({
|
|
@@ -207251,7 +207251,7 @@ registerLanguage({
|
|
|
207251
207251
|
extensions: [".handlebars", ".hbs"],
|
|
207252
207252
|
aliases: ["Handlebars", "handlebars", "hbs"],
|
|
207253
207253
|
mimetypes: ["text/x-handlebars-template"],
|
|
207254
|
-
loader: () => __vitePreload(() => import("./handlebars-
|
|
207254
|
+
loader: () => __vitePreload(() => import("./handlebars-BTbmOxx9.js"), true ? [] : void 0, import.meta.url)
|
|
207255
207255
|
});
|
|
207256
207256
|
registerLanguage({
|
|
207257
207257
|
id: "hcl",
|
|
@@ -207264,7 +207264,7 @@ registerLanguage({
|
|
|
207264
207264
|
extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
|
|
207265
207265
|
aliases: ["HTML", "htm", "html", "xhtml"],
|
|
207266
207266
|
mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
|
|
207267
|
-
loader: () => __vitePreload(() => import("./html-
|
|
207267
|
+
loader: () => __vitePreload(() => import("./html-3cIIQcxO.js"), true ? [] : void 0, import.meta.url)
|
|
207268
207268
|
});
|
|
207269
207269
|
registerLanguage({
|
|
207270
207270
|
id: "ini",
|
|
@@ -207287,7 +207287,7 @@ registerLanguage({
|
|
|
207287
207287
|
filenames: ["jakefile"],
|
|
207288
207288
|
aliases: ["JavaScript", "javascript", "js"],
|
|
207289
207289
|
mimetypes: ["text/javascript"],
|
|
207290
|
-
loader: () => __vitePreload(() => import("./javascript-
|
|
207290
|
+
loader: () => __vitePreload(() => import("./javascript-CDuCMm-6.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
|
|
207291
207291
|
});
|
|
207292
207292
|
registerLanguage({
|
|
207293
207293
|
id: "julia",
|
|
@@ -207326,7 +207326,7 @@ registerLanguage({
|
|
|
207326
207326
|
extensions: [".liquid", ".html.liquid"],
|
|
207327
207327
|
aliases: ["Liquid", "liquid"],
|
|
207328
207328
|
mimetypes: ["application/liquid"],
|
|
207329
|
-
loader: () => __vitePreload(() => import("./liquid-
|
|
207329
|
+
loader: () => __vitePreload(() => import("./liquid-BFcqZizB.js"), true ? [] : void 0, import.meta.url)
|
|
207330
207330
|
});
|
|
207331
207331
|
registerLanguage({
|
|
207332
207332
|
id: "m3",
|
|
@@ -207344,7 +207344,7 @@ registerLanguage({
|
|
|
207344
207344
|
id: "mdx",
|
|
207345
207345
|
extensions: [".mdx"],
|
|
207346
207346
|
aliases: ["MDX", "mdx"],
|
|
207347
|
-
loader: () => __vitePreload(() => import("./mdx-
|
|
207347
|
+
loader: () => __vitePreload(() => import("./mdx-DyK93oEE.js"), true ? [] : void 0, import.meta.url)
|
|
207348
207348
|
});
|
|
207349
207349
|
registerLanguage({
|
|
207350
207350
|
id: "mips",
|
|
@@ -207443,7 +207443,7 @@ registerLanguage({
|
|
|
207443
207443
|
extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
|
|
207444
207444
|
aliases: ["Python", "py"],
|
|
207445
207445
|
firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
|
|
207446
|
-
loader: () => __vitePreload(() => import("./python-
|
|
207446
|
+
loader: () => __vitePreload(() => import("./python-D4lCwSVr.js"), true ? [] : void 0, import.meta.url)
|
|
207447
207447
|
});
|
|
207448
207448
|
registerLanguage({
|
|
207449
207449
|
id: "qsharp",
|
|
@@ -207462,7 +207462,7 @@ registerLanguage({
|
|
|
207462
207462
|
extensions: [".cshtml"],
|
|
207463
207463
|
aliases: ["Razor", "razor"],
|
|
207464
207464
|
mimetypes: ["text/x-cshtml"],
|
|
207465
|
-
loader: () => __vitePreload(() => import("./razor-
|
|
207465
|
+
loader: () => __vitePreload(() => import("./razor-DdkE9XVt.js"), true ? [] : void 0, import.meta.url)
|
|
207466
207466
|
});
|
|
207467
207467
|
registerLanguage({
|
|
207468
207468
|
id: "redis",
|
|
@@ -207595,7 +207595,7 @@ registerLanguage({
|
|
|
207595
207595
|
aliases: ["TypeScript", "ts", "typescript"],
|
|
207596
207596
|
mimetypes: ["text/typescript"],
|
|
207597
207597
|
loader: () => {
|
|
207598
|
-
return __vitePreload(() => import("./typescript-
|
|
207598
|
+
return __vitePreload(() => import("./typescript-BakbYMnC.js"), true ? [] : void 0, import.meta.url);
|
|
207599
207599
|
}
|
|
207600
207600
|
});
|
|
207601
207601
|
registerLanguage({
|
|
@@ -207640,14 +207640,14 @@ registerLanguage({
|
|
|
207640
207640
|
firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
|
|
207641
207641
|
aliases: ["XML", "xml"],
|
|
207642
207642
|
mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
|
|
207643
|
-
loader: () => __vitePreload(() => import("./xml-
|
|
207643
|
+
loader: () => __vitePreload(() => import("./xml-DHDW9Xhp.js"), true ? [] : void 0, import.meta.url)
|
|
207644
207644
|
});
|
|
207645
207645
|
registerLanguage({
|
|
207646
207646
|
id: "yaml",
|
|
207647
207647
|
extensions: [".yaml", ".yml"],
|
|
207648
207648
|
aliases: ["YAML", "yaml", "YML", "yml"],
|
|
207649
207649
|
mimetypes: ["application/x-yaml", "text/x-yaml"],
|
|
207650
|
-
loader: () => __vitePreload(() => import("./yaml-
|
|
207650
|
+
loader: () => __vitePreload(() => import("./yaml-1Ayv_J3q.js"), true ? [] : void 0, import.meta.url)
|
|
207651
207651
|
});
|
|
207652
207652
|
var __defProp = Object.defineProperty;
|
|
207653
207653
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -212039,6 +212039,7 @@ function App() {
|
|
|
212039
212039
|
const [showSettings, setShowSettings] = reactExports.useState(false);
|
|
212040
212040
|
const [wsStatus, setWsStatus] = reactExports.useState("disconnected");
|
|
212041
212041
|
const [cwd2, setCwd] = reactExports.useState(null);
|
|
212042
|
+
const [projectName, setProjectName] = reactExports.useState(null);
|
|
212042
212043
|
const [updateInfo, setUpdateInfo] = reactExports.useState(null);
|
|
212043
212044
|
const [tabs, setTabs] = reactExports.useState(() => {
|
|
212044
212045
|
const id = nextTabId();
|
|
@@ -212059,9 +212060,15 @@ function App() {
|
|
|
212059
212060
|
const initialCwd = await window.worker.getCwd().catch(() => window.worker.getHomePath());
|
|
212060
212061
|
setCwd(initialCwd);
|
|
212061
212062
|
cwdRef.current = initialCwd;
|
|
212063
|
+
window.worker.getProjectName().then(setProjectName).catch(() => {
|
|
212064
|
+
});
|
|
212062
212065
|
}
|
|
212063
212066
|
init2();
|
|
212064
212067
|
}, []);
|
|
212068
|
+
reactExports.useEffect(() => {
|
|
212069
|
+
const unsub = window.worker.onProjectChanged((name) => setProjectName(name));
|
|
212070
|
+
return unsub;
|
|
212071
|
+
}, []);
|
|
212065
212072
|
reactExports.useEffect(() => {
|
|
212066
212073
|
const unsub = window.worker.onWorkerStatus((status2) => setWsStatus(status2));
|
|
212067
212074
|
return unsub;
|
|
@@ -212305,7 +212312,13 @@ function App() {
|
|
|
212305
212312
|
];
|
|
212306
212313
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "app", children: [
|
|
212307
212314
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "titlebar", children: [
|
|
212308
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
212315
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "titlebar-title", children: [
|
|
212316
|
+
"ctlsurf",
|
|
212317
|
+
projectName && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
212318
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-title-sep", children: "·" }),
|
|
212319
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-project", title: projectName, children: projectName })
|
|
212320
|
+
] })
|
|
212321
|
+
] }),
|
|
212309
212322
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "titlebar-controls", children: [
|
|
212310
212323
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "titlebar-btn", onClick: () => setShowSettings(true), title: "Settings", children: "Settings" }),
|
|
212311
212324
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { conf as conf$1, language as language$1 } from "./typescript-
|
|
2
|
-
import "./index-
|
|
1
|
+
import { conf as conf$1, language as language$1 } from "./typescript-BakbYMnC.js";
|
|
2
|
+
import "./index-D2MUZin7.js";
|
|
3
3
|
const conf = conf$1;
|
|
4
4
|
const language = {
|
|
5
5
|
// Set defaultToken to invalid to see what you do not tokenize yet
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages, e as editor } from "./index-
|
|
2
|
-
import { f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter, H as HoverAdapter, b as DocumentSymbolAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, S as SelectionRangeAdapter, e as DiagnosticsAdapter } from "./lspLanguageFeatures-
|
|
3
|
-
import { a, D, h, R, c, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages, e as editor } from "./index-D2MUZin7.js";
|
|
2
|
+
import { f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter, H as HoverAdapter, b as DocumentSymbolAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, S as SelectionRangeAdapter, e as DiagnosticsAdapter } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
3
|
+
import { a, D, h, R, c, i, j, t, k } from "./lspLanguageFeatures-CbkEcL-z.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
package/out/renderer/assets/{lspLanguageFeatures-CxLZ421s.js → lspLanguageFeatures-CbkEcL-z.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as Range$1, l as languages, e as editor, U as Uri, M as MarkerSeverity } from "./index-
|
|
1
|
+
import { R as Range$1, l as languages, e as editor, U as Uri, M as MarkerSeverity } from "./index-D2MUZin7.js";
|
|
2
2
|
var DocumentUri;
|
|
3
3
|
(function(DocumentUri2) {
|
|
4
4
|
function is(value) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as createWebWorker, e as editor, U as Uri, a as MarkerTag, M as MarkerSeverity, l as languages, t as typescriptDefaults, R as Range } from "./index-
|
|
1
|
+
import { c as createWebWorker, e as editor, U as Uri, a as MarkerTag, M as MarkerSeverity, l as languages, t as typescriptDefaults, R as Range } from "./index-D2MUZin7.js";
|
|
2
2
|
class WorkerManager {
|
|
3
3
|
constructor(_modeId, _defaults) {
|
|
4
4
|
this._modeId = _modeId;
|
package/out/renderer/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>ctlsurf-worker</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-D2MUZin7.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-6KvOnYL1.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phenx-inc/ctlsurf",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "Agent-agnostic terminal and desktop app for ctlsurf — run Claude Code, Codex, or any coding agent with live session logging and remote control",
|
|
5
5
|
"main": "out/main/index.js",
|
|
6
6
|
"bin": {
|
package/src/main/agents.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { accessSync, constants } from 'fs'
|
|
2
|
+
import { join, delimiter } from 'path'
|
|
3
|
+
|
|
1
4
|
export interface AgentConfig {
|
|
2
5
|
id: string
|
|
3
6
|
name: string
|
|
@@ -11,6 +14,27 @@ function getShellCommand(): string {
|
|
|
11
14
|
return process.env.SHELL || '/bin/zsh'
|
|
12
15
|
}
|
|
13
16
|
|
|
17
|
+
// Resolve a bare command name against PATH (like `which`/`where`), so we only
|
|
18
|
+
// offer coding agents whose CLI is actually installed. Both launch modes
|
|
19
|
+
// inherit the user's shell PATH (the `ctlsurf` launcher runs under their
|
|
20
|
+
// shell), so process.env.PATH is the right thing to scan.
|
|
21
|
+
function isCommandAvailable(command: string): boolean {
|
|
22
|
+
const dirs = (process.env.PATH || '').split(delimiter).filter(Boolean)
|
|
23
|
+
const isWin = process.platform === 'win32'
|
|
24
|
+
const exts = isWin
|
|
25
|
+
? (process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM').split(';').filter(Boolean)
|
|
26
|
+
: ['']
|
|
27
|
+
for (const dir of dirs) {
|
|
28
|
+
for (const ext of exts) {
|
|
29
|
+
try {
|
|
30
|
+
accessSync(join(dir, command + ext), isWin ? constants.F_OK : constants.X_OK)
|
|
31
|
+
return true
|
|
32
|
+
} catch { /* not in this dir */ }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
|
|
14
38
|
export function getBuiltinAgents(): AgentConfig[] {
|
|
15
39
|
return [
|
|
16
40
|
{
|
|
@@ -37,8 +61,19 @@ export function getBuiltinAgents(): AgentConfig[] {
|
|
|
37
61
|
]
|
|
38
62
|
}
|
|
39
63
|
|
|
64
|
+
// Builtin agents filtered to those actually usable: coding agents only when
|
|
65
|
+
// their CLI is installed (on PATH), with the shell always offered last. If no
|
|
66
|
+
// coding agent is installed the list collapses to just the shell.
|
|
67
|
+
export function getAvailableAgents(): AgentConfig[] {
|
|
68
|
+
const all = getBuiltinAgents()
|
|
69
|
+
const coding = all.filter(a => isCodingAgent(a) && isCommandAvailable(a.command))
|
|
70
|
+
const shell = all.filter(a => !isCodingAgent(a))
|
|
71
|
+
return [...coding, ...shell]
|
|
72
|
+
}
|
|
73
|
+
|
|
40
74
|
export function getDefaultAgent(): AgentConfig {
|
|
41
|
-
|
|
75
|
+
// First available coding agent, or the shell when none are installed.
|
|
76
|
+
return getAvailableAgents()[0]
|
|
42
77
|
}
|
|
43
78
|
|
|
44
79
|
export function isCodingAgent(agent: AgentConfig): boolean {
|
package/src/main/headless.ts
CHANGED
|
@@ -29,7 +29,7 @@ setSilent(true)
|
|
|
29
29
|
|
|
30
30
|
import { Orchestrator } from './orchestrator'
|
|
31
31
|
import { getSettingsDir } from './settingsDir'
|
|
32
|
-
import { getBuiltinAgents, isCodingAgent, type AgentConfig } from './agents'
|
|
32
|
+
import { getBuiltinAgents, getAvailableAgents, isCodingAgent, type AgentConfig } from './agents'
|
|
33
33
|
import { Tui } from './tui'
|
|
34
34
|
import { fetchLatestNpmVersion, compareSemver, NPM_PACKAGE } from './updateCheck'
|
|
35
35
|
|
|
@@ -103,7 +103,9 @@ async function main() {
|
|
|
103
103
|
await checkVersionAndNotify()
|
|
104
104
|
|
|
105
105
|
const tui = new Tui()
|
|
106
|
-
|
|
106
|
+
// Picker only offers installed coding agents (+ shell, last). Explicit
|
|
107
|
+
// --agent still resolves against the full builtin list below.
|
|
108
|
+
const agents = getAvailableAgents()
|
|
107
109
|
|
|
108
110
|
// ─── Orchestrator (loaded early so picker can read profile defaults) ──
|
|
109
111
|
|
|
@@ -140,7 +142,7 @@ async function main() {
|
|
|
140
142
|
let trackTimeOverride: boolean | undefined
|
|
141
143
|
|
|
142
144
|
if (args.agent) {
|
|
143
|
-
const found =
|
|
145
|
+
const found = getBuiltinAgents().find(a => a.id === args.agent)
|
|
144
146
|
agent = found || {
|
|
145
147
|
id: args.agent,
|
|
146
148
|
name: args.agent,
|