haltija 1.3.0-beta.8 → 1.3.0-beta.9
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/apps/desktop/main.js +14 -0
- package/apps/desktop/package.json +2 -1
- package/apps/desktop/resources/component.js +2 -2
- package/bin/cli-subcommand.mjs +53 -12
- package/dist/component.js +2 -2
- package/dist/hj.js +40 -12
- package/dist/index.js +2 -1
- package/dist/server.js +2 -1
- package/package.json +1 -1
package/apps/desktop/main.js
CHANGED
|
@@ -1387,6 +1387,13 @@ if (!gotTheLock) {
|
|
|
1387
1387
|
// App lifecycle
|
|
1388
1388
|
app.whenReady().then(async () => {
|
|
1389
1389
|
console.log('[Haltija Desktop] App ready, starting initialization...')
|
|
1390
|
+
|
|
1391
|
+
// Clear the "manually quit" marker — user is explicitly starting Haltija,
|
|
1392
|
+
// so hj should resume auto-launching when needed.
|
|
1393
|
+
try {
|
|
1394
|
+
const quitMarker = path.join(os.homedir(), '.haltija', 'last-quit')
|
|
1395
|
+
if (fs.existsSync(quitMarker)) fs.rmSync(quitMarker, { force: true })
|
|
1396
|
+
} catch {}
|
|
1390
1397
|
|
|
1391
1398
|
try {
|
|
1392
1399
|
// Start or connect to server first
|
|
@@ -1444,6 +1451,13 @@ if (!gotTheLock) {
|
|
|
1444
1451
|
}
|
|
1445
1452
|
embeddedServers.length = 0
|
|
1446
1453
|
}
|
|
1454
|
+
// Drop a marker so hj's auto-launch knows the user explicitly quit.
|
|
1455
|
+
// Cleared next time the user manually starts Haltija.
|
|
1456
|
+
try {
|
|
1457
|
+
const dir = path.join(os.homedir(), '.haltija')
|
|
1458
|
+
fs.mkdirSync(dir, { recursive: true })
|
|
1459
|
+
fs.writeFileSync(path.join(dir, 'last-quit'), String(Date.now()))
|
|
1460
|
+
} catch {}
|
|
1447
1461
|
})
|
|
1448
1462
|
|
|
1449
1463
|
// Handle certificate errors (for self-signed certs in dev)
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/version.ts
|
|
49
|
-
var VERSION = "1.3.0-beta.
|
|
49
|
+
var VERSION = "1.3.0-beta.9";
|
|
50
50
|
|
|
51
51
|
// src/text-selector.ts
|
|
52
52
|
var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
|
|
@@ -6113,7 +6113,7 @@ ${elementSummary}${moreText}`;
|
|
|
6113
6113
|
}
|
|
6114
6114
|
} else if (isContentEditable) {
|
|
6115
6115
|
document.execCommand("insertText", false, char);
|
|
6116
|
-
}
|
|
6116
|
+
}
|
|
6117
6117
|
el.dispatchEvent(new InputEvent("input", {
|
|
6118
6118
|
bubbles: true,
|
|
6119
6119
|
inputType: "insertText",
|
package/bin/cli-subcommand.mjs
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { spawn } from 'child_process'
|
|
20
20
|
import { existsSync, readFileSync, readdirSync, statSync } from 'fs'
|
|
21
|
+
import { homedir } from 'os'
|
|
21
22
|
import { dirname, join } from 'path'
|
|
22
23
|
import { fileURLToPath } from 'url'
|
|
23
24
|
import { formatTree } from './format-tree.mjs'
|
|
@@ -455,28 +456,39 @@ async function isServerRunning(port) {
|
|
|
455
456
|
}
|
|
456
457
|
|
|
457
458
|
/**
|
|
458
|
-
* Resolve the server path
|
|
459
|
+
* Resolve the server path. Search order:
|
|
460
|
+
* 1. Next to the hj binary (compiled distribution).
|
|
461
|
+
* 2. `../dist/server.js` (running from a source checkout).
|
|
462
|
+
* 3. Inside an installed `/Applications/Haltija.app` (the bundled
|
|
463
|
+
* server binary lives in Contents/Resources/haltija-server-<arch>).
|
|
464
|
+
* 4. Same under `~/Applications/`.
|
|
459
465
|
* Exported for testing.
|
|
460
466
|
*/
|
|
461
467
|
export function resolveServerPath() {
|
|
462
468
|
const arch = process.arch === 'arm64' ? 'arm64' : 'x64'
|
|
463
469
|
const execDir = dirname(process.execPath)
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
470
|
+
const candidates = [
|
|
471
|
+
{ type: 'bundled', path: join(execDir, `haltija-server-${arch}`) },
|
|
472
|
+
{ type: 'dev', path: join(__dirname, '../dist/server.js') },
|
|
473
|
+
{ type: 'app', path: `/Applications/Haltija.app/Contents/Resources/haltija-server-${arch}` },
|
|
474
|
+
{ type: 'app', path: join(homedir(), `Applications/Haltija.app/Contents/Resources/haltija-server-${arch}`) },
|
|
475
|
+
]
|
|
476
|
+
for (const c of candidates) {
|
|
477
|
+
if (existsSync(c.path)) return c
|
|
471
478
|
}
|
|
472
479
|
return null
|
|
473
480
|
}
|
|
474
481
|
|
|
475
482
|
async function startServerInBackground(port) {
|
|
476
483
|
const resolved = resolveServerPath()
|
|
477
|
-
|
|
484
|
+
|
|
478
485
|
if (!resolved) {
|
|
479
|
-
console.error('Error:
|
|
486
|
+
console.error('Error: no haltija server found.')
|
|
487
|
+
console.error('')
|
|
488
|
+
console.error('Install one of these:')
|
|
489
|
+
console.error(' • Haltija desktop app: https://github.com/tonioloewald/haltija/releases')
|
|
490
|
+
console.error(' • Or run a server in another shell: bunx haltija --server')
|
|
491
|
+
console.error(' • Or, if you are developing haltija from source: bun run build')
|
|
480
492
|
process.exit(1)
|
|
481
493
|
}
|
|
482
494
|
|
|
@@ -551,14 +563,31 @@ async function launchElectronApp() {
|
|
|
551
563
|
}
|
|
552
564
|
|
|
553
565
|
async function ensureBrowserConnected(port) {
|
|
566
|
+
let status
|
|
554
567
|
try {
|
|
555
568
|
const resp = await fetch(`http://localhost:${port}/status`, {
|
|
556
569
|
signal: AbortSignal.timeout(2000)
|
|
557
570
|
})
|
|
558
|
-
|
|
571
|
+
status = await resp.json()
|
|
559
572
|
if (status.ok) return true
|
|
560
573
|
} catch { return false }
|
|
561
|
-
|
|
574
|
+
|
|
575
|
+
// Server is up but no tabs yet. If this server is hosted by the Haltija
|
|
576
|
+
// desktop app, it will open a tab itself when the agent's command hits
|
|
577
|
+
// (via __NEED_WINDOW__). Launching /Applications/Haltija.app on top would
|
|
578
|
+
// produce two app instances side by side — skip the launch.
|
|
579
|
+
if (status?.desktopApp) return true
|
|
580
|
+
|
|
581
|
+
// Respect "user explicitly quit" — don't auto-relaunch on every agent
|
|
582
|
+
// call. Cleared when the user starts Haltija manually.
|
|
583
|
+
try {
|
|
584
|
+
const quitMarker = join(homedir(), '.haltija', 'last-quit')
|
|
585
|
+
if (existsSync(quitMarker)) {
|
|
586
|
+
process.stderr.write('\x1b[2m(Haltija was quit by user; not auto-launching. Open Haltija manually to resume.)\x1b[0m\n')
|
|
587
|
+
return false
|
|
588
|
+
}
|
|
589
|
+
} catch {}
|
|
590
|
+
|
|
562
591
|
// No windows connected — try to launch Electron app (macOS only)
|
|
563
592
|
if (process.platform !== 'darwin') return false
|
|
564
593
|
|
|
@@ -611,6 +640,18 @@ export async function runSubcommand(subcommand, subArgs, port = '8700', options
|
|
|
611
640
|
|
|
612
641
|
// Check if server is running, auto-start if not
|
|
613
642
|
if (!(await isServerRunning(port))) {
|
|
643
|
+
// Respect "user manually quit Haltija" before we try to spawn anything.
|
|
644
|
+
// The marker is dropped by the desktop app on will-quit and cleared on
|
|
645
|
+
// its next launch — agent calls in between should not bring it back.
|
|
646
|
+
try {
|
|
647
|
+
const quitMarker = join(homedir(), '.haltija', 'last-quit')
|
|
648
|
+
if (!noLaunch && existsSync(quitMarker)) {
|
|
649
|
+
console.error('Haltija was quit by user; not auto-launching.')
|
|
650
|
+
console.error('Open Haltija manually to resume — or run `hj --no-launch` to bypass this check.')
|
|
651
|
+
process.exit(1)
|
|
652
|
+
}
|
|
653
|
+
} catch {}
|
|
654
|
+
|
|
614
655
|
process.stderr.write('\x1b[2mStarting Haltija server...\x1b[0m')
|
|
615
656
|
const started = await startServerInBackground(port)
|
|
616
657
|
if (started) {
|
package/dist/component.js
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/version.ts
|
|
49
|
-
var VERSION = "1.3.0-beta.
|
|
49
|
+
var VERSION = "1.3.0-beta.9";
|
|
50
50
|
|
|
51
51
|
// src/text-selector.ts
|
|
52
52
|
var TEXT_PSEUDO_RE = /:(?:text-is|has-text|text)\(/;
|
|
@@ -6113,7 +6113,7 @@ ${elementSummary}${moreText}`;
|
|
|
6113
6113
|
}
|
|
6114
6114
|
} else if (isContentEditable) {
|
|
6115
6115
|
document.execCommand("insertText", false, char);
|
|
6116
|
-
}
|
|
6116
|
+
}
|
|
6117
6117
|
el.dispatchEvent(new InputEvent("input", {
|
|
6118
6118
|
bubbles: true,
|
|
6119
6119
|
inputType: "insertText",
|
package/dist/hj.js
CHANGED
|
@@ -5,6 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
5
5
|
// bin/cli-subcommand.mjs
|
|
6
6
|
import { spawn } from "child_process";
|
|
7
7
|
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
8
|
+
import { homedir } from "os";
|
|
8
9
|
import { dirname, join } from "path";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
10
11
|
|
|
@@ -1235,19 +1236,27 @@ async function isServerRunning(port) {
|
|
|
1235
1236
|
function resolveServerPath() {
|
|
1236
1237
|
const arch = process.arch === "arm64" ? "arm64" : "x64";
|
|
1237
1238
|
const execDir = dirname(process.execPath);
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1239
|
+
const candidates = [
|
|
1240
|
+
{ type: "bundled", path: join(execDir, `haltija-server-${arch}`) },
|
|
1241
|
+
{ type: "dev", path: join(__dirname2, "../dist/server.js") },
|
|
1242
|
+
{ type: "app", path: `/Applications/Haltija.app/Contents/Resources/haltija-server-${arch}` },
|
|
1243
|
+
{ type: "app", path: join(homedir(), `Applications/Haltija.app/Contents/Resources/haltija-server-${arch}`) }
|
|
1244
|
+
];
|
|
1245
|
+
for (const c of candidates) {
|
|
1246
|
+
if (existsSync(c.path))
|
|
1247
|
+
return c;
|
|
1244
1248
|
}
|
|
1245
1249
|
return null;
|
|
1246
1250
|
}
|
|
1247
1251
|
async function startServerInBackground(port) {
|
|
1248
1252
|
const resolved = resolveServerPath();
|
|
1249
1253
|
if (!resolved) {
|
|
1250
|
-
console.error("Error:
|
|
1254
|
+
console.error("Error: no haltija server found.");
|
|
1255
|
+
console.error("");
|
|
1256
|
+
console.error("Install one of these:");
|
|
1257
|
+
console.error(" • Haltija desktop app: https://github.com/tonioloewald/haltija/releases");
|
|
1258
|
+
console.error(" • Or run a server in another shell: bunx haltija --server");
|
|
1259
|
+
console.error(" • Or, if you are developing haltija from source: bun run build");
|
|
1251
1260
|
process.exit(1);
|
|
1252
1261
|
}
|
|
1253
1262
|
let command, cmdArgs;
|
|
@@ -1305,16 +1314,27 @@ async function launchElectronApp() {
|
|
|
1305
1314
|
return false;
|
|
1306
1315
|
}
|
|
1307
1316
|
async function ensureBrowserConnected(port) {
|
|
1317
|
+
let status;
|
|
1308
1318
|
try {
|
|
1309
1319
|
const resp = await fetch(`http://localhost:${port}/status`, {
|
|
1310
1320
|
signal: AbortSignal.timeout(2000)
|
|
1311
1321
|
});
|
|
1312
|
-
|
|
1322
|
+
status = await resp.json();
|
|
1313
1323
|
if (status.ok)
|
|
1314
1324
|
return true;
|
|
1315
1325
|
} catch {
|
|
1316
1326
|
return false;
|
|
1317
1327
|
}
|
|
1328
|
+
if (status?.desktopApp)
|
|
1329
|
+
return true;
|
|
1330
|
+
try {
|
|
1331
|
+
const quitMarker = join(homedir(), ".haltija", "last-quit");
|
|
1332
|
+
if (existsSync(quitMarker)) {
|
|
1333
|
+
process.stderr.write(`\x1B[2m(Haltija was quit by user; not auto-launching. Open Haltija manually to resume.)\x1B[0m
|
|
1334
|
+
`);
|
|
1335
|
+
return false;
|
|
1336
|
+
}
|
|
1337
|
+
} catch {}
|
|
1318
1338
|
if (process.platform !== "darwin")
|
|
1319
1339
|
return false;
|
|
1320
1340
|
process.stderr.write("\x1B[2mLaunching Haltija browser...\x1B[0m");
|
|
@@ -1331,8 +1351,8 @@ async function ensureBrowserConnected(port) {
|
|
|
1331
1351
|
const resp = await fetch(`http://localhost:${port}/status`, {
|
|
1332
1352
|
signal: AbortSignal.timeout(1000)
|
|
1333
1353
|
});
|
|
1334
|
-
const
|
|
1335
|
-
if (
|
|
1354
|
+
const status2 = await resp.json();
|
|
1355
|
+
if (status2.ok) {
|
|
1336
1356
|
process.stderr.write(`\x1B[2m ready\x1B[0m
|
|
1337
1357
|
`);
|
|
1338
1358
|
return true;
|
|
@@ -1357,6 +1377,14 @@ async function runSubcommand(subcommand, subArgs, port = "8700", options = {}) {
|
|
|
1357
1377
|
filteredArgs = [...filteredArgs.slice(0, windowIdx), ...filteredArgs.slice(windowIdx + 2)];
|
|
1358
1378
|
}
|
|
1359
1379
|
if (!await isServerRunning(port)) {
|
|
1380
|
+
try {
|
|
1381
|
+
const quitMarker = join(homedir(), ".haltija", "last-quit");
|
|
1382
|
+
if (!noLaunch && existsSync(quitMarker)) {
|
|
1383
|
+
console.error("Haltija was quit by user; not auto-launching.");
|
|
1384
|
+
console.error("Open Haltija manually to resume — or run `hj --no-launch` to bypass this check.");
|
|
1385
|
+
process.exit(1);
|
|
1386
|
+
}
|
|
1387
|
+
} catch {}
|
|
1360
1388
|
process.stderr.write("\x1B[2mStarting Haltija server...\x1B[0m");
|
|
1361
1389
|
const started = await startServerInBackground(port);
|
|
1362
1390
|
if (started) {
|
|
@@ -1687,11 +1715,11 @@ function dim2(s) {
|
|
|
1687
1715
|
|
|
1688
1716
|
// bin/hj.mjs
|
|
1689
1717
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
1690
|
-
import { homedir } from "node:os";
|
|
1718
|
+
import { homedir as homedir2 } from "node:os";
|
|
1691
1719
|
import { join as join2 } from "node:path";
|
|
1692
1720
|
var args = process.argv.slice(2);
|
|
1693
1721
|
function lookupNamedInstance(name) {
|
|
1694
|
-
const path = join2(
|
|
1722
|
+
const path = join2(homedir2(), ".haltija", "servers", `${name}.json`);
|
|
1695
1723
|
if (!existsSync2(path))
|
|
1696
1724
|
return null;
|
|
1697
1725
|
let entry;
|
package/dist/index.js
CHANGED
|
@@ -674,7 +674,7 @@ var injectorCode = `
|
|
|
674
674
|
`;
|
|
675
675
|
|
|
676
676
|
// src/version.ts
|
|
677
|
-
var VERSION = "1.3.0-beta.
|
|
677
|
+
var VERSION = "1.3.0-beta.9";
|
|
678
678
|
|
|
679
679
|
// src/embedded-assets.ts
|
|
680
680
|
var APP_MD = `# Haltija App
|
|
@@ -8736,6 +8736,7 @@ async function handleRest(req) {
|
|
|
8736
8736
|
serverVersion: SERVER_VERSION,
|
|
8737
8737
|
recording: activeRecordings > 0,
|
|
8738
8738
|
activeRecordings,
|
|
8739
|
+
desktopApp: isDesktopApp,
|
|
8739
8740
|
browsers: browsers.size,
|
|
8740
8741
|
agents: agents.size,
|
|
8741
8742
|
mcp: {
|
package/dist/server.js
CHANGED
|
@@ -674,7 +674,7 @@ var injectorCode = `
|
|
|
674
674
|
`;
|
|
675
675
|
|
|
676
676
|
// src/version.ts
|
|
677
|
-
var VERSION = "1.3.0-beta.
|
|
677
|
+
var VERSION = "1.3.0-beta.9";
|
|
678
678
|
|
|
679
679
|
// src/embedded-assets.ts
|
|
680
680
|
var APP_MD = `# Haltija App
|
|
@@ -8736,6 +8736,7 @@ async function handleRest(req) {
|
|
|
8736
8736
|
serverVersion: SERVER_VERSION,
|
|
8737
8737
|
recording: activeRecordings > 0,
|
|
8738
8738
|
activeRecordings,
|
|
8739
|
+
desktopApp: isDesktopApp,
|
|
8739
8740
|
browsers: browsers.size,
|
|
8740
8741
|
agents: agents.size,
|
|
8741
8742
|
mcp: {
|