@phenx-inc/ctlsurf 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/headless/index.mjs +320 -44
- package/out/headless/index.mjs.map +4 -4
- package/out/main/index.js +275 -15
- package/out/preload/index.js +3 -0
- package/out/renderer/assets/{cssMode-D3kH1Kju.js → cssMode-DiOmyihM.js} +3 -3
- package/out/renderer/assets/{freemarker2-BCHZUSLb.js → freemarker2-BAfv60yb.js} +1 -1
- package/out/renderer/assets/{handlebars-DKx-Fw-H.js → handlebars-Ult17NzQ.js} +1 -1
- package/out/renderer/assets/{html-BSCM04uL.js → html-DCxh4J-1.js} +1 -1
- package/out/renderer/assets/{htmlMode-BucU1MUc.js → htmlMode-CQ5Xenrg.js} +3 -3
- package/out/renderer/assets/{index-BsdOeO0U.js → index-BnCJ1IaZ.js} +106 -28
- package/out/renderer/assets/{index-BzF7I1my.css → index-CrTu3Z4M.css} +21 -0
- package/out/renderer/assets/{javascript-bPY5C4uq.js → javascript-U5dsRcHx.js} +2 -2
- package/out/renderer/assets/{jsonMode-BmJotb6E.js → jsonMode-DshPNyVy.js} +3 -3
- package/out/renderer/assets/{liquid-Cja_Pzh3.js → liquid-jHHLYTlB.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-hoVZfVKv.js → lspLanguageFeatures-CUafmPGy.js} +1 -1
- package/out/renderer/assets/{mdx-C0s81MOq.js → mdx-Ct-tiY6g.js} +1 -1
- package/out/renderer/assets/{python-CulkBOJr.js → python-wD3UwKPV.js} +1 -1
- package/out/renderer/assets/{razor-czmzhwVZ.js → razor-11ECS4oH.js} +1 -1
- package/out/renderer/assets/{tsMode-B90EqYGx.js → tsMode-D-7JexQ_.js} +1 -1
- package/out/renderer/assets/{typescript-Ckc6emP2.js → typescript-Cvna1mak.js} +1 -1
- package/out/renderer/assets/{xml-CKh-JyGN.js → xml-JsEaImjA.js} +1 -1
- package/out/renderer/assets/{yaml-B49zLim4.js → yaml-B8pCNDb_.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/src/main/ctlsurfApi.ts +26 -0
- package/src/main/headless.ts +33 -28
- package/src/main/index.ts +8 -0
- package/src/main/orchestrator.ts +63 -2
- package/src/main/timeTracker.ts +223 -0
- package/src/main/tui.ts +25 -5
- package/src/preload/index.ts +7 -1
- package/src/renderer/App.tsx +36 -0
- package/src/renderer/components/SettingsDialog.tsx +38 -1
- package/src/renderer/components/TerminalPanel.tsx +14 -6
- package/src/renderer/styles.css +21 -0
|
@@ -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-DiOmyihM.js","./lspLanguageFeatures-CUafmPGy.js","./htmlMode-CQ5Xenrg.js","./jsonMode-DshPNyVy.js","./javascript-U5dsRcHx.js","./typescript-Cvna1mak.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
|
}
|
|
@@ -18866,12 +18866,19 @@ function TerminalPanel({ tabId, agent, onSpawn, onExit, isActive }) {
|
|
|
18866
18866
|
}, [tabId, agent, onSpawn]);
|
|
18867
18867
|
reactExports.useEffect(() => {
|
|
18868
18868
|
if (isActive) {
|
|
18869
|
-
const state = _terminals.get(tabId);
|
|
18870
|
-
if (state) {
|
|
18871
|
-
state.fitAddon.fit();
|
|
18872
|
-
state.terminal.focus();
|
|
18873
|
-
}
|
|
18874
18869
|
window.worker.setActiveTab(tabId);
|
|
18870
|
+
requestAnimationFrame(() => {
|
|
18871
|
+
setTimeout(() => {
|
|
18872
|
+
const state = _terminals.get(tabId);
|
|
18873
|
+
if (state) {
|
|
18874
|
+
state.fitAddon.fit();
|
|
18875
|
+
state.terminal.focus();
|
|
18876
|
+
scrollIfPinned(tabId, state.terminal);
|
|
18877
|
+
const { cols, rows } = state.terminal;
|
|
18878
|
+
window.worker.resizePty(tabId, cols, rows);
|
|
18879
|
+
}
|
|
18880
|
+
}, 50);
|
|
18881
|
+
});
|
|
18875
18882
|
}
|
|
18876
18883
|
}, [isActive, tabId]);
|
|
18877
18884
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "terminal-container", ref: containerRef });
|
|
@@ -206549,7 +206556,7 @@ const lessDefaults = new LanguageServiceDefaultsImpl$3(
|
|
|
206549
206556
|
modeConfigurationDefault$2
|
|
206550
206557
|
);
|
|
206551
206558
|
function getMode$3() {
|
|
206552
|
-
return __vitePreload(() => import("./cssMode-
|
|
206559
|
+
return __vitePreload(() => import("./cssMode-DiOmyihM.js"), true ? __vite__mapDeps([0,1]) : void 0, import.meta.url);
|
|
206553
206560
|
}
|
|
206554
206561
|
languages.onLanguage("less", () => {
|
|
206555
206562
|
getMode$3().then((mode2) => mode2.setupMode(lessDefaults));
|
|
@@ -206654,7 +206661,7 @@ const razorLanguageService = registerHTMLLanguageService(
|
|
|
206654
206661
|
);
|
|
206655
206662
|
const razorDefaults = razorLanguageService.defaults;
|
|
206656
206663
|
function getMode$2() {
|
|
206657
|
-
return __vitePreload(() => import("./htmlMode-
|
|
206664
|
+
return __vitePreload(() => import("./htmlMode-CQ5Xenrg.js"), true ? __vite__mapDeps([2,1]) : void 0, import.meta.url);
|
|
206658
206665
|
}
|
|
206659
206666
|
function registerHTMLLanguageService(languageId, options = optionsDefault, modeConfiguration = getConfigurationDefault(languageId)) {
|
|
206660
206667
|
const defaults = new LanguageServiceDefaultsImpl$2(languageId, options, modeConfiguration);
|
|
@@ -206738,7 +206745,7 @@ const jsonDefaults = new LanguageServiceDefaultsImpl$1(
|
|
|
206738
206745
|
);
|
|
206739
206746
|
const getWorker$1 = () => getMode$1().then((mode2) => mode2.getWorker());
|
|
206740
206747
|
function getMode$1() {
|
|
206741
|
-
return __vitePreload(() => import("./jsonMode-
|
|
206748
|
+
return __vitePreload(() => import("./jsonMode-DshPNyVy.js"), true ? __vite__mapDeps([3,1]) : void 0, import.meta.url);
|
|
206742
206749
|
}
|
|
206743
206750
|
languages.register({
|
|
206744
206751
|
id: "json",
|
|
@@ -206984,7 +206991,7 @@ const getJavaScriptWorker = () => {
|
|
|
206984
206991
|
return getMode().then((mode) => mode.getJavaScriptWorker());
|
|
206985
206992
|
};
|
|
206986
206993
|
function getMode() {
|
|
206987
|
-
return __vitePreload(() => import("./tsMode-
|
|
206994
|
+
return __vitePreload(() => import("./tsMode-D-7JexQ_.js"), true ? [] : void 0, import.meta.url);
|
|
206988
206995
|
}
|
|
206989
206996
|
languages.onLanguage("typescript", () => {
|
|
206990
206997
|
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
|
|
@@ -207179,49 +207186,49 @@ registerLanguage({
|
|
|
207179
207186
|
extensions: [".ftl", ".ftlh", ".ftlx"],
|
|
207180
207187
|
aliases: ["FreeMarker2", "Apache FreeMarker2"],
|
|
207181
207188
|
loader: () => {
|
|
207182
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207189
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207183
207190
|
}
|
|
207184
207191
|
});
|
|
207185
207192
|
registerLanguage({
|
|
207186
207193
|
id: "freemarker2.tag-angle.interpolation-dollar",
|
|
207187
207194
|
aliases: ["FreeMarker2 (Angle/Dollar)", "Apache FreeMarker2 (Angle/Dollar)"],
|
|
207188
207195
|
loader: () => {
|
|
207189
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207196
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationDollar);
|
|
207190
207197
|
}
|
|
207191
207198
|
});
|
|
207192
207199
|
registerLanguage({
|
|
207193
207200
|
id: "freemarker2.tag-bracket.interpolation-dollar",
|
|
207194
207201
|
aliases: ["FreeMarker2 (Bracket/Dollar)", "Apache FreeMarker2 (Bracket/Dollar)"],
|
|
207195
207202
|
loader: () => {
|
|
207196
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207203
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationDollar);
|
|
207197
207204
|
}
|
|
207198
207205
|
});
|
|
207199
207206
|
registerLanguage({
|
|
207200
207207
|
id: "freemarker2.tag-angle.interpolation-bracket",
|
|
207201
207208
|
aliases: ["FreeMarker2 (Angle/Bracket)", "Apache FreeMarker2 (Angle/Bracket)"],
|
|
207202
207209
|
loader: () => {
|
|
207203
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207210
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAngleInterpolationBracket);
|
|
207204
207211
|
}
|
|
207205
207212
|
});
|
|
207206
207213
|
registerLanguage({
|
|
207207
207214
|
id: "freemarker2.tag-bracket.interpolation-bracket",
|
|
207208
207215
|
aliases: ["FreeMarker2 (Bracket/Bracket)", "Apache FreeMarker2 (Bracket/Bracket)"],
|
|
207209
207216
|
loader: () => {
|
|
207210
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207217
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagBracketInterpolationBracket);
|
|
207211
207218
|
}
|
|
207212
207219
|
});
|
|
207213
207220
|
registerLanguage({
|
|
207214
207221
|
id: "freemarker2.tag-auto.interpolation-dollar",
|
|
207215
207222
|
aliases: ["FreeMarker2 (Auto/Dollar)", "Apache FreeMarker2 (Auto/Dollar)"],
|
|
207216
207223
|
loader: () => {
|
|
207217
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207224
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationDollar);
|
|
207218
207225
|
}
|
|
207219
207226
|
});
|
|
207220
207227
|
registerLanguage({
|
|
207221
207228
|
id: "freemarker2.tag-auto.interpolation-bracket",
|
|
207222
207229
|
aliases: ["FreeMarker2 (Auto/Bracket)", "Apache FreeMarker2 (Auto/Bracket)"],
|
|
207223
207230
|
loader: () => {
|
|
207224
|
-
return __vitePreload(() => import("./freemarker2-
|
|
207231
|
+
return __vitePreload(() => import("./freemarker2-BAfv60yb.js"), true ? [] : void 0, import.meta.url).then((m) => m.TagAutoInterpolationBracket);
|
|
207225
207232
|
}
|
|
207226
207233
|
});
|
|
207227
207234
|
registerLanguage({
|
|
@@ -207242,7 +207249,7 @@ registerLanguage({
|
|
|
207242
207249
|
extensions: [".handlebars", ".hbs"],
|
|
207243
207250
|
aliases: ["Handlebars", "handlebars", "hbs"],
|
|
207244
207251
|
mimetypes: ["text/x-handlebars-template"],
|
|
207245
|
-
loader: () => __vitePreload(() => import("./handlebars-
|
|
207252
|
+
loader: () => __vitePreload(() => import("./handlebars-Ult17NzQ.js"), true ? [] : void 0, import.meta.url)
|
|
207246
207253
|
});
|
|
207247
207254
|
registerLanguage({
|
|
207248
207255
|
id: "hcl",
|
|
@@ -207255,7 +207262,7 @@ registerLanguage({
|
|
|
207255
207262
|
extensions: [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
|
|
207256
207263
|
aliases: ["HTML", "htm", "html", "xhtml"],
|
|
207257
207264
|
mimetypes: ["text/html", "text/x-jshtm", "text/template", "text/ng-template"],
|
|
207258
|
-
loader: () => __vitePreload(() => import("./html-
|
|
207265
|
+
loader: () => __vitePreload(() => import("./html-DCxh4J-1.js"), true ? [] : void 0, import.meta.url)
|
|
207259
207266
|
});
|
|
207260
207267
|
registerLanguage({
|
|
207261
207268
|
id: "ini",
|
|
@@ -207278,7 +207285,7 @@ registerLanguage({
|
|
|
207278
207285
|
filenames: ["jakefile"],
|
|
207279
207286
|
aliases: ["JavaScript", "javascript", "js"],
|
|
207280
207287
|
mimetypes: ["text/javascript"],
|
|
207281
|
-
loader: () => __vitePreload(() => import("./javascript-
|
|
207288
|
+
loader: () => __vitePreload(() => import("./javascript-U5dsRcHx.js"), true ? __vite__mapDeps([4,5]) : void 0, import.meta.url)
|
|
207282
207289
|
});
|
|
207283
207290
|
registerLanguage({
|
|
207284
207291
|
id: "julia",
|
|
@@ -207317,7 +207324,7 @@ registerLanguage({
|
|
|
207317
207324
|
extensions: [".liquid", ".html.liquid"],
|
|
207318
207325
|
aliases: ["Liquid", "liquid"],
|
|
207319
207326
|
mimetypes: ["application/liquid"],
|
|
207320
|
-
loader: () => __vitePreload(() => import("./liquid-
|
|
207327
|
+
loader: () => __vitePreload(() => import("./liquid-jHHLYTlB.js"), true ? [] : void 0, import.meta.url)
|
|
207321
207328
|
});
|
|
207322
207329
|
registerLanguage({
|
|
207323
207330
|
id: "m3",
|
|
@@ -207335,7 +207342,7 @@ registerLanguage({
|
|
|
207335
207342
|
id: "mdx",
|
|
207336
207343
|
extensions: [".mdx"],
|
|
207337
207344
|
aliases: ["MDX", "mdx"],
|
|
207338
|
-
loader: () => __vitePreload(() => import("./mdx-
|
|
207345
|
+
loader: () => __vitePreload(() => import("./mdx-Ct-tiY6g.js"), true ? [] : void 0, import.meta.url)
|
|
207339
207346
|
});
|
|
207340
207347
|
registerLanguage({
|
|
207341
207348
|
id: "mips",
|
|
@@ -207434,7 +207441,7 @@ registerLanguage({
|
|
|
207434
207441
|
extensions: [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
|
|
207435
207442
|
aliases: ["Python", "py"],
|
|
207436
207443
|
firstLine: "^#!/.*\\bpython[0-9.-]*\\b",
|
|
207437
|
-
loader: () => __vitePreload(() => import("./python-
|
|
207444
|
+
loader: () => __vitePreload(() => import("./python-wD3UwKPV.js"), true ? [] : void 0, import.meta.url)
|
|
207438
207445
|
});
|
|
207439
207446
|
registerLanguage({
|
|
207440
207447
|
id: "qsharp",
|
|
@@ -207453,7 +207460,7 @@ registerLanguage({
|
|
|
207453
207460
|
extensions: [".cshtml"],
|
|
207454
207461
|
aliases: ["Razor", "razor"],
|
|
207455
207462
|
mimetypes: ["text/x-cshtml"],
|
|
207456
|
-
loader: () => __vitePreload(() => import("./razor-
|
|
207463
|
+
loader: () => __vitePreload(() => import("./razor-11ECS4oH.js"), true ? [] : void 0, import.meta.url)
|
|
207457
207464
|
});
|
|
207458
207465
|
registerLanguage({
|
|
207459
207466
|
id: "redis",
|
|
@@ -207586,7 +207593,7 @@ registerLanguage({
|
|
|
207586
207593
|
aliases: ["TypeScript", "ts", "typescript"],
|
|
207587
207594
|
mimetypes: ["text/typescript"],
|
|
207588
207595
|
loader: () => {
|
|
207589
|
-
return __vitePreload(() => import("./typescript-
|
|
207596
|
+
return __vitePreload(() => import("./typescript-Cvna1mak.js"), true ? [] : void 0, import.meta.url);
|
|
207590
207597
|
}
|
|
207591
207598
|
});
|
|
207592
207599
|
registerLanguage({
|
|
@@ -207631,14 +207638,14 @@ registerLanguage({
|
|
|
207631
207638
|
firstLine: "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
|
|
207632
207639
|
aliases: ["XML", "xml"],
|
|
207633
207640
|
mimetypes: ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"],
|
|
207634
|
-
loader: () => __vitePreload(() => import("./xml-
|
|
207641
|
+
loader: () => __vitePreload(() => import("./xml-JsEaImjA.js"), true ? [] : void 0, import.meta.url)
|
|
207635
207642
|
});
|
|
207636
207643
|
registerLanguage({
|
|
207637
207644
|
id: "yaml",
|
|
207638
207645
|
extensions: [".yaml", ".yml"],
|
|
207639
207646
|
aliases: ["YAML", "yaml", "YML", "yml"],
|
|
207640
207647
|
mimetypes: ["application/x-yaml", "text/x-yaml"],
|
|
207641
|
-
loader: () => __vitePreload(() => import("./yaml-
|
|
207648
|
+
loader: () => __vitePreload(() => import("./yaml-B8pCNDb_.js"), true ? [] : void 0, import.meta.url)
|
|
207642
207649
|
});
|
|
207643
207650
|
var __defProp = Object.defineProperty;
|
|
207644
207651
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -211507,6 +211514,8 @@ function SettingsDialog({ open, onClose }) {
|
|
|
211507
211514
|
const [apiKey, setApiKey] = reactExports.useState("");
|
|
211508
211515
|
const [baseUrl, setBaseUrl] = reactExports.useState("");
|
|
211509
211516
|
const [dataspacePageId, setDataspacePageId] = reactExports.useState("");
|
|
211517
|
+
const [trackTime, setTrackTime] = reactExports.useState(false);
|
|
211518
|
+
const [idleTimeoutMin, setIdleTimeoutMin] = reactExports.useState(15);
|
|
211510
211519
|
const [saved, setSaved] = reactExports.useState(false);
|
|
211511
211520
|
const loadProfiles = async () => {
|
|
211512
211521
|
const data = await window.worker.listProfiles();
|
|
@@ -211526,6 +211535,8 @@ function SettingsDialog({ open, onClose }) {
|
|
|
211526
211535
|
setApiKey("");
|
|
211527
211536
|
setBaseUrl(profile.baseUrl);
|
|
211528
211537
|
setDataspacePageId(profile.dataspacePageId || "");
|
|
211538
|
+
setTrackTime(!!profile.trackTime);
|
|
211539
|
+
setIdleTimeoutMin(profile.idleTimeoutMin ?? 15);
|
|
211529
211540
|
setSaved(false);
|
|
211530
211541
|
};
|
|
211531
211542
|
const startNewProfile = () => {
|
|
@@ -211535,6 +211546,8 @@ function SettingsDialog({ open, onClose }) {
|
|
|
211535
211546
|
setApiKey("");
|
|
211536
211547
|
setBaseUrl("http://localhost:8000");
|
|
211537
211548
|
setDataspacePageId("");
|
|
211549
|
+
setTrackTime(true);
|
|
211550
|
+
setIdleTimeoutMin(15);
|
|
211538
211551
|
setSaved(false);
|
|
211539
211552
|
};
|
|
211540
211553
|
const handleSave = async () => {
|
|
@@ -211542,7 +211555,9 @@ function SettingsDialog({ open, onClose }) {
|
|
|
211542
211555
|
const data = {
|
|
211543
211556
|
name: name.trim(),
|
|
211544
211557
|
baseUrl: baseUrl.trim() || "https://app.ctlsurf.com",
|
|
211545
|
-
dataspacePageId: dataspacePageId.trim()
|
|
211558
|
+
dataspacePageId: dataspacePageId.trim(),
|
|
211559
|
+
trackTime,
|
|
211560
|
+
idleTimeoutMin: Math.max(1, Math.floor(idleTimeoutMin)) || 15
|
|
211546
211561
|
};
|
|
211547
211562
|
if (apiKey.trim()) {
|
|
211548
211563
|
data.apiKey = apiKey.trim();
|
|
@@ -211622,6 +211637,31 @@ function SettingsDialog({ open, onClose }) {
|
|
|
211622
211637
|
}
|
|
211623
211638
|
)
|
|
211624
211639
|
] }),
|
|
211640
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "settings-checkbox", children: [
|
|
211641
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
211642
|
+
"input",
|
|
211643
|
+
{
|
|
211644
|
+
type: "checkbox",
|
|
211645
|
+
checked: trackTime,
|
|
211646
|
+
onChange: (e) => setTrackTime(e.target.checked)
|
|
211647
|
+
}
|
|
211648
|
+
),
|
|
211649
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Track time per project" }),
|
|
211650
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "settings-hint", children: `Logs each session to a "Time Tracking" datastore on the project's Agent Datastore page.` })
|
|
211651
|
+
] }),
|
|
211652
|
+
trackTime && /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { children: [
|
|
211653
|
+
"Idle timeout (min)",
|
|
211654
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
211655
|
+
"input",
|
|
211656
|
+
{
|
|
211657
|
+
type: "number",
|
|
211658
|
+
min: 1,
|
|
211659
|
+
value: idleTimeoutMin,
|
|
211660
|
+
onChange: (e) => setIdleTimeoutMin(parseInt(e.target.value, 10) || 15)
|
|
211661
|
+
}
|
|
211662
|
+
),
|
|
211663
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "settings-hint", children: "Gaps longer than this without terminal activity are counted as idle, not work." })
|
|
211664
|
+
] }),
|
|
211625
211665
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "settings-actions", children: [
|
|
211626
211666
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn-secondary", onClick: () => setEditingId(null), children: "Back" }),
|
|
211627
211667
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn-primary", onClick: handleSave, children: saved ? "Saved!" : "Save" })
|
|
@@ -211687,6 +211727,7 @@ function App() {
|
|
|
211687
211727
|
return [{ id, label: "Terminal 1", agent: null, agentStatus: "idle" }];
|
|
211688
211728
|
});
|
|
211689
211729
|
const [activeTabId, setActiveTabId] = reactExports.useState(tabs[0].id);
|
|
211730
|
+
const [trackingActive, setTrackingActive] = reactExports.useState(false);
|
|
211690
211731
|
const [pickerTargetTabId, setPickerTargetTabId] = reactExports.useState(tabs[0].id);
|
|
211691
211732
|
const [showAgentPicker, setShowAgentPicker] = reactExports.useState(true);
|
|
211692
211733
|
const visiblePaneIds = findPaneIds(layout2);
|
|
@@ -211712,6 +211753,30 @@ function App() {
|
|
|
211712
211753
|
});
|
|
211713
211754
|
return unsub;
|
|
211714
211755
|
}, []);
|
|
211756
|
+
reactExports.useEffect(() => {
|
|
211757
|
+
let cancelled = false;
|
|
211758
|
+
const refresh = async () => {
|
|
211759
|
+
try {
|
|
211760
|
+
const r = await window.worker.getTracking();
|
|
211761
|
+
if (!cancelled) setTrackingActive(!!r?.active);
|
|
211762
|
+
} catch {
|
|
211763
|
+
}
|
|
211764
|
+
};
|
|
211765
|
+
refresh();
|
|
211766
|
+
const id = setInterval(refresh, 4e3);
|
|
211767
|
+
return () => {
|
|
211768
|
+
cancelled = true;
|
|
211769
|
+
clearInterval(id);
|
|
211770
|
+
};
|
|
211771
|
+
}, [activeTabId]);
|
|
211772
|
+
const handleToggleTracking = reactExports.useCallback(async () => {
|
|
211773
|
+
try {
|
|
211774
|
+
const r = await window.worker.setTracking(!trackingActive);
|
|
211775
|
+
setTrackingActive(!!r?.active);
|
|
211776
|
+
} catch (err) {
|
|
211777
|
+
console.error("[tracking] toggle failed", err);
|
|
211778
|
+
}
|
|
211779
|
+
}, [trackingActive]);
|
|
211715
211780
|
const cwdRef = reactExports.useRef(null);
|
|
211716
211781
|
const handleSpawn = reactExports.useCallback(async (tabId, agent) => {
|
|
211717
211782
|
setTabs((prev) => prev.map((t) => t.id === tabId ? { ...t, agentStatus: "active" } : t));
|
|
@@ -211912,6 +211977,19 @@ function App() {
|
|
|
211912
211977
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-title", children: "ctlsurf-worker" }),
|
|
211913
211978
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "titlebar-controls", children: [
|
|
211914
211979
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "titlebar-btn", onClick: () => setShowSettings(true), title: "Settings", children: "Settings" }),
|
|
211980
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
211981
|
+
"button",
|
|
211982
|
+
{
|
|
211983
|
+
className: `titlebar-btn titlebar-icon-btn ${trackingActive ? "active" : ""}`,
|
|
211984
|
+
onClick: handleToggleTracking,
|
|
211985
|
+
title: trackingActive ? "Time tracking on — click to stop" : "Time tracking off — click to start",
|
|
211986
|
+
"aria-label": "Time tracking",
|
|
211987
|
+
children: [
|
|
211988
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tracking-icon", children: "⏱" }),
|
|
211989
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `tracking-dot ${trackingActive ? "on" : "off"}` })
|
|
211990
|
+
]
|
|
211991
|
+
}
|
|
211992
|
+
),
|
|
211915
211993
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "titlebar-separator" }),
|
|
211916
211994
|
agents.map((a) => {
|
|
211917
211995
|
const activeTab = tabs.find((t) => t.id === activeTabId);
|
|
@@ -7904,6 +7904,27 @@ html, body, #root {
|
|
|
7904
7904
|
.status-dot.idle { background: #565f89; }
|
|
7905
7905
|
.status-dot.pending { background: #e0af68; }
|
|
7906
7906
|
|
|
7907
|
+
.tracking-dot {
|
|
7908
|
+
width: 6px;
|
|
7909
|
+
height: 6px;
|
|
7910
|
+
border-radius: 50%;
|
|
7911
|
+
display: inline-block;
|
|
7912
|
+
vertical-align: middle;
|
|
7913
|
+
}
|
|
7914
|
+
.tracking-dot.on { background: #9ece6a; box-shadow: 0 0 4px #9ece6a; }
|
|
7915
|
+
.tracking-dot.off { background: #565f89; }
|
|
7916
|
+
|
|
7917
|
+
.titlebar-icon-btn {
|
|
7918
|
+
display: inline-flex;
|
|
7919
|
+
align-items: center;
|
|
7920
|
+
gap: 5px;
|
|
7921
|
+
padding: 0 8px;
|
|
7922
|
+
}
|
|
7923
|
+
.tracking-icon {
|
|
7924
|
+
font-size: 14px;
|
|
7925
|
+
line-height: 1;
|
|
7926
|
+
}
|
|
7927
|
+
|
|
7907
7928
|
/* Editor panel */
|
|
7908
7929
|
.editor-panel {
|
|
7909
7930
|
display: flex;
|
|
@@ -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-Cvna1mak.js";
|
|
2
|
+
import "./index-BnCJ1IaZ.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-BnCJ1IaZ.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-CUafmPGy.js";
|
|
3
|
+
import { a, D, h, R, c, i, j, t, k } from "./lspLanguageFeatures-CUafmPGy.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
package/out/renderer/assets/{lspLanguageFeatures-hoVZfVKv.js → lspLanguageFeatures-CUafmPGy.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-BnCJ1IaZ.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-BnCJ1IaZ.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-BnCJ1IaZ.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CrTu3Z4M.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
|
+
"version": "0.3.0",
|
|
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/ctlsurfApi.ts
CHANGED
|
@@ -105,6 +105,32 @@ export class CtlsurfApi {
|
|
|
105
105
|
return folder?.pages || []
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
async getFolder(folderId: string): Promise<any> {
|
|
109
|
+
return this.request('GET', `/folders/${folderId}`)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─── Datastore ───────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
async getPageBlockSummaries(pageId: string): Promise<any[]> {
|
|
115
|
+
return this.request('GET', `/blocks/page/${pageId}/summary`)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async addRow(blockId: string, data: Record<string, unknown>): Promise<any> {
|
|
119
|
+
return this.request('POST', `/datastore/${blockId}/rows`, { data })
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async updateRow(blockId: string, rowId: string, data: Record<string, unknown>): Promise<any> {
|
|
123
|
+
return this.request('PUT', `/datastore/${blockId}/rows/${rowId}`, { data })
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async getDatastoreSchema(blockId: string): Promise<{ block_id: string; columns: Array<{ id: string; name: string; type: string }> }> {
|
|
127
|
+
return this.request('GET', `/datastore/${blockId}/schema`)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async updateDatastoreSchema(blockId: string, columns: Array<{ id: string; name: string; type: string }>): Promise<any> {
|
|
131
|
+
return this.request('PUT', `/datastore/${blockId}/schema`, { columns })
|
|
132
|
+
}
|
|
133
|
+
|
|
108
134
|
async findFolderByGitRemote(gitRemote: string): Promise<any> {
|
|
109
135
|
// Search folders by listing all and matching git_remote
|
|
110
136
|
const folders = await this.request('GET', '/folders')
|
package/src/main/headless.ts
CHANGED
|
@@ -70,33 +70,7 @@ async function main() {
|
|
|
70
70
|
const tui = new Tui()
|
|
71
71
|
const agents = getBuiltinAgents()
|
|
72
72
|
|
|
73
|
-
// ───
|
|
74
|
-
let agent: AgentConfig
|
|
75
|
-
|
|
76
|
-
if (args.agent) {
|
|
77
|
-
const found = agents.find(a => a.id === args.agent)
|
|
78
|
-
agent = found || {
|
|
79
|
-
id: args.agent,
|
|
80
|
-
name: args.agent,
|
|
81
|
-
command: args.agent,
|
|
82
|
-
args: [],
|
|
83
|
-
description: `Custom agent: ${args.agent}`,
|
|
84
|
-
}
|
|
85
|
-
} else {
|
|
86
|
-
// Show interactive picker
|
|
87
|
-
const selectedIdx = await tui.showAgentPicker(agents)
|
|
88
|
-
agent = agents[selectedIdx]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ─── Start TUI + agent ─────────────────────────
|
|
92
|
-
|
|
93
|
-
tui.update({
|
|
94
|
-
agentName: agent.name,
|
|
95
|
-
cwd: args.cwd,
|
|
96
|
-
mode: 'terminal',
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
tui.init()
|
|
73
|
+
// ─── Orchestrator (loaded early so picker can read profile defaults) ──
|
|
100
74
|
|
|
101
75
|
const orchestrator = new Orchestrator(settingsDir, {
|
|
102
76
|
onPtyData: (_tabId, data) => {
|
|
@@ -125,10 +99,41 @@ async function main() {
|
|
|
125
99
|
if (args.apiKey) orchestrator.overrideApiKey(args.apiKey)
|
|
126
100
|
if (args.baseUrl) orchestrator.overrideBaseUrl(args.baseUrl)
|
|
127
101
|
|
|
102
|
+
// ─── Agent selection ────────────────────────────
|
|
103
|
+
|
|
104
|
+
let agent: AgentConfig
|
|
105
|
+
let trackTimeOverride: boolean | undefined
|
|
106
|
+
|
|
107
|
+
if (args.agent) {
|
|
108
|
+
const found = agents.find(a => a.id === args.agent)
|
|
109
|
+
agent = found || {
|
|
110
|
+
id: args.agent,
|
|
111
|
+
name: args.agent,
|
|
112
|
+
command: args.agent,
|
|
113
|
+
args: [],
|
|
114
|
+
description: `Custom agent: ${args.agent}`,
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
const initialTrackTime = orchestrator.getActiveProfile().trackTime !== false
|
|
118
|
+
const picked = await tui.showAgentPicker(agents, { initialTrackTime })
|
|
119
|
+
agent = agents[picked.agentIdx]
|
|
120
|
+
trackTimeOverride = picked.trackTime
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ─── Start TUI + agent ─────────────────────────
|
|
124
|
+
|
|
125
|
+
tui.update({
|
|
126
|
+
agentName: agent.name,
|
|
127
|
+
cwd: args.cwd,
|
|
128
|
+
mode: 'terminal',
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
tui.init()
|
|
132
|
+
|
|
128
133
|
// Spawn agent with PTY sized to fit the TUI content area
|
|
129
134
|
const HEADLESS_TAB = 'headless'
|
|
130
135
|
const ptySize = tui.getPtySize()
|
|
131
|
-
await orchestrator.spawnAgent(HEADLESS_TAB, agent, args.cwd)
|
|
136
|
+
await orchestrator.spawnAgent(HEADLESS_TAB, agent, args.cwd, { trackTime: trackTimeOverride })
|
|
132
137
|
orchestrator.resizePty(HEADLESS_TAB, ptySize.cols, ptySize.rows)
|
|
133
138
|
|
|
134
139
|
// For coding agents, send an initial prompt to kick-start them
|
package/src/main/index.ts
CHANGED
|
@@ -309,6 +309,14 @@ ipcMain.handle('profiles:save', (_event, id: string, data: any) => {
|
|
|
309
309
|
ipcMain.handle('profiles:switch', (_event, id: string) => orchestrator.switchProfile(id))
|
|
310
310
|
ipcMain.handle('profiles:delete', (_event, id: string) => orchestrator.deleteProfile(id))
|
|
311
311
|
|
|
312
|
+
// ─── Tracking IPC ─────────────────────────────────
|
|
313
|
+
|
|
314
|
+
ipcMain.handle('tracking:get', () => ({ active: orchestrator.isActiveTabTracking() }))
|
|
315
|
+
ipcMain.handle('tracking:set', async (_event, enabled: boolean) => {
|
|
316
|
+
await orchestrator.setActiveTabTracking(enabled)
|
|
317
|
+
return { active: orchestrator.isActiveTabTracking() }
|
|
318
|
+
})
|
|
319
|
+
|
|
312
320
|
// ─── Legacy Settings IPC ──────────────────────────
|
|
313
321
|
|
|
314
322
|
ipcMain.handle('settings:get', (_event, key: string) => {
|