iranti-control-plane 0.5.4 → 0.5.5

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/README.md CHANGED
@@ -1,15 +1,17 @@
1
1
  # Iranti Control Plane
2
2
 
3
- Local-first operator dashboard for [Iranti](https://github.com/nfemmanuel/iranti) - inspect memory, watch Staff activity, manage instances, and diagnose your setup without raw SQL.
3
+ Local-first operator dashboard for [Iranti](https://github.com/nfemmanuel/iranti) inspect memory, watch Staff activity, manage instances, and diagnose your setup without raw SQL.
4
4
 
5
5
  ## Status
6
6
 
7
- Current package version: `0.4.3`.
8
- The operator surface is live and under active UX hardening.
7
+ Current package version: `0.5.5`.
8
+ The operator surface is live and under active development.
9
9
 
10
- ## Install
10
+ Available on npm and mirrored by jsDelivr:
11
+ - npm: `npm install -g iranti-control-plane`
12
+ - jsDelivr CDN: `https://cdn.jsdelivr.net/npm/iranti-control-plane/`
11
13
 
12
- For the packaged control-plane CLI path (after npm publish, or from a locally packed tarball):
14
+ ## Install
13
15
 
14
16
  ```bash
15
17
  npm install -g iranti-control-plane
package/bin/iranti-cp.js CHANGED
@@ -309,6 +309,25 @@ function spawnControlPlane({ port, openBrowser, detached }) {
309
309
  if (port) env.CONTROL_PLANE_PORT = String(port);
310
310
  if (!openBrowser) env.IRANTI_CP_NO_OPEN = '1';
311
311
 
312
+ // On Windows, spawning node.exe directly causes Windows Terminal (wt.exe)
313
+ // to intercept the new console process and flash a tab, even with
314
+ // windowsHide:true. windowsHide suppresses a standalone console window but
315
+ // does not prevent Windows Terminal from attaching.
316
+ //
317
+ // Routing through `cmd /c start "" /b node bundle.cjs` creates the child
318
+ // with the DETACHED_PROCESS flag implicitly, so no console is allocated and
319
+ // Windows Terminal never attaches. This is only needed for the detached
320
+ // (background) case; foreground start keeps stdio:inherit as usual.
321
+ if (process.platform === 'win32' && detached) {
322
+ const child = spawn(
323
+ 'cmd',
324
+ ['/d', '/s', '/c', 'start', '', '/b', process.execPath, BUNDLE],
325
+ { env, detached: true, stdio: 'ignore', windowsHide: true },
326
+ );
327
+ child.unref();
328
+ return child;
329
+ }
330
+
312
331
  const child = spawn(process.execPath, [BUNDLE], {
313
332
  env,
314
333
  stdio: detached ? 'ignore' : 'inherit',
@@ -28093,6 +28093,11 @@ var init_db = __esm({
28093
28093
  init_path_utils();
28094
28094
  ({ Pool: Pool2 } = esm_default);
28095
28095
  env = loadEnv();
28096
+ for (const [k, v] of Object.entries(env)) {
28097
+ if (process.env[k] === void 0) {
28098
+ process.env[k] = v;
28099
+ }
28100
+ }
28096
28101
  databaseUrl = env.DATABASE_URL ?? process.env.DATABASE_URL;
28097
28102
  if (!databaseUrl) {
28098
28103
  console.warn("[db] No DATABASE_URL found in .env.iranti or environment \u2014 DB queries will fail until configured");
@@ -35355,7 +35360,7 @@ var require_cross_spawn = __commonJS({
35355
35360
  var cp2 = require("child_process");
35356
35361
  var parse3 = require_parse2();
35357
35362
  var enoent = require_enoent();
35358
- function spawn8(command, args, options) {
35363
+ function spawn9(command, args, options) {
35359
35364
  const parsed = parse3(command, args, options);
35360
35365
  const spawned = cp2.spawn(parsed.command, parsed.args, parsed.options);
35361
35366
  enoent.hookChildProcess(spawned, parsed);
@@ -35367,8 +35372,8 @@ var require_cross_spawn = __commonJS({
35367
35372
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
35368
35373
  return result;
35369
35374
  }
35370
- module2.exports = spawn8;
35371
- module2.exports.spawn = spawn8;
35375
+ module2.exports = spawn9;
35376
+ module2.exports.spawn = spawn9;
35372
35377
  module2.exports.sync = spawnSync;
35373
35378
  module2.exports._parse = parse3;
35374
35379
  module2.exports._enoent = enoent;
@@ -35382,8 +35387,8 @@ __export(runner_exports, {
35382
35387
  });
35383
35388
  function resolveMigrationPath(file2) {
35384
35389
  const candidates = [
35385
- (0, import_path20.resolve)(__dirname2, file2),
35386
- (0, import_path20.resolve)(__dirname2, "..", "..", "migrations", file2)
35390
+ (0, import_path20.resolve)(__dirname, file2),
35391
+ (0, import_path20.resolve)(__dirname, "..", "..", "migrations", file2)
35387
35392
  ];
35388
35393
  for (const candidate of candidates) {
35389
35394
  if ((0, import_fs14.existsSync)(candidate)) return candidate;
@@ -35410,7 +35415,7 @@ async function run() {
35410
35415
  await migrationPool.end();
35411
35416
  }
35412
35417
  }
35413
- var import_fs14, import_path20, import_url2, __dirname2;
35418
+ var import_fs14, import_path20, import_url2, __dirname;
35414
35419
  var init_runner = __esm({
35415
35420
  "src/server/migrations/runner.ts"() {
35416
35421
  "use strict";
@@ -35419,7 +35424,7 @@ var init_runner = __esm({
35419
35424
  import_url2 = require("url");
35420
35425
  init_esm();
35421
35426
  init_db();
35422
- __dirname2 = (0, import_path20.dirname)((0, import_url2.fileURLToPath)(__importmeta_url));
35427
+ __dirname = (0, import_path20.dirname)((0, import_url2.fileURLToPath)(__importmeta_url));
35423
35428
  if (process.argv[1] && (0, import_path20.resolve)(process.argv[1]) === (0, import_url2.fileURLToPath)(__importmeta_url)) {
35424
35429
  run().catch((err) => {
35425
35430
  console.error("[migrate] Failed:", err);
@@ -35429,345 +35434,6 @@ var init_runner = __esm({
35429
35434
  }
35430
35435
  });
35431
35436
 
35432
- // src/server/node_modules/is-docker/index.js
35433
- var require_is_docker = __commonJS({
35434
- "src/server/node_modules/is-docker/index.js"(exports2, module2) {
35435
- "use strict";
35436
- var fs2 = require("fs");
35437
- var isDocker;
35438
- function hasDockerEnv() {
35439
- try {
35440
- fs2.statSync("/.dockerenv");
35441
- return true;
35442
- } catch (_) {
35443
- return false;
35444
- }
35445
- }
35446
- function hasDockerCGroup() {
35447
- try {
35448
- return fs2.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
35449
- } catch (_) {
35450
- return false;
35451
- }
35452
- }
35453
- module2.exports = () => {
35454
- if (isDocker === void 0) {
35455
- isDocker = hasDockerEnv() || hasDockerCGroup();
35456
- }
35457
- return isDocker;
35458
- };
35459
- }
35460
- });
35461
-
35462
- // src/server/node_modules/is-wsl/index.js
35463
- var require_is_wsl = __commonJS({
35464
- "src/server/node_modules/is-wsl/index.js"(exports2, module2) {
35465
- "use strict";
35466
- var os = require("os");
35467
- var fs2 = require("fs");
35468
- var isDocker = require_is_docker();
35469
- var isWsl = () => {
35470
- if (process.platform !== "linux") {
35471
- return false;
35472
- }
35473
- if (os.release().toLowerCase().includes("microsoft")) {
35474
- if (isDocker()) {
35475
- return false;
35476
- }
35477
- return true;
35478
- }
35479
- try {
35480
- return fs2.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
35481
- } catch (_) {
35482
- return false;
35483
- }
35484
- };
35485
- if (process.env.__IS_WSL_TEST__) {
35486
- module2.exports = isWsl;
35487
- } else {
35488
- module2.exports = isWsl();
35489
- }
35490
- }
35491
- });
35492
-
35493
- // src/server/node_modules/define-lazy-prop/index.js
35494
- var require_define_lazy_prop = __commonJS({
35495
- "src/server/node_modules/define-lazy-prop/index.js"(exports2, module2) {
35496
- "use strict";
35497
- module2.exports = (object3, propertyName, fn) => {
35498
- const define = (value) => Object.defineProperty(object3, propertyName, { value, enumerable: true, writable: true });
35499
- Object.defineProperty(object3, propertyName, {
35500
- configurable: true,
35501
- enumerable: true,
35502
- get() {
35503
- const result = fn();
35504
- define(result);
35505
- return result;
35506
- },
35507
- set(value) {
35508
- define(value);
35509
- }
35510
- });
35511
- return object3;
35512
- };
35513
- }
35514
- });
35515
-
35516
- // src/server/node_modules/open/index.js
35517
- var require_open = __commonJS({
35518
- "src/server/node_modules/open/index.js"(exports2, module2) {
35519
- var path3 = require("path");
35520
- var childProcess = require("child_process");
35521
- var { promises: fs2, constants: fsConstants } = require("fs");
35522
- var isWsl = require_is_wsl();
35523
- var isDocker = require_is_docker();
35524
- var defineLazyProperty = require_define_lazy_prop();
35525
- var localXdgOpenPath = path3.join(__dirname, "xdg-open");
35526
- var { platform, arch } = process;
35527
- var hasContainerEnv = () => {
35528
- try {
35529
- fs2.statSync("/run/.containerenv");
35530
- return true;
35531
- } catch {
35532
- return false;
35533
- }
35534
- };
35535
- var cachedResult;
35536
- function isInsideContainer() {
35537
- if (cachedResult === void 0) {
35538
- cachedResult = hasContainerEnv() || isDocker();
35539
- }
35540
- return cachedResult;
35541
- }
35542
- var getWslDrivesMountPoint = /* @__PURE__ */ (() => {
35543
- const defaultMountPoint = "/mnt/";
35544
- let mountPoint;
35545
- return async function() {
35546
- if (mountPoint) {
35547
- return mountPoint;
35548
- }
35549
- const configFilePath = "/etc/wsl.conf";
35550
- let isConfigFileExists = false;
35551
- try {
35552
- await fs2.access(configFilePath, fsConstants.F_OK);
35553
- isConfigFileExists = true;
35554
- } catch {
35555
- }
35556
- if (!isConfigFileExists) {
35557
- return defaultMountPoint;
35558
- }
35559
- const configContent = await fs2.readFile(configFilePath, { encoding: "utf8" });
35560
- const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
35561
- if (!configMountPoint) {
35562
- return defaultMountPoint;
35563
- }
35564
- mountPoint = configMountPoint.groups.mountPoint.trim();
35565
- mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
35566
- return mountPoint;
35567
- };
35568
- })();
35569
- var pTryEach = async (array2, mapper) => {
35570
- let latestError;
35571
- for (const item of array2) {
35572
- try {
35573
- return await mapper(item);
35574
- } catch (error2) {
35575
- latestError = error2;
35576
- }
35577
- }
35578
- throw latestError;
35579
- };
35580
- var baseOpen = async (options) => {
35581
- options = {
35582
- wait: false,
35583
- background: false,
35584
- newInstance: false,
35585
- allowNonzeroExitCode: false,
35586
- ...options
35587
- };
35588
- if (Array.isArray(options.app)) {
35589
- return pTryEach(options.app, (singleApp) => baseOpen({
35590
- ...options,
35591
- app: singleApp
35592
- }));
35593
- }
35594
- let { name: app2, arguments: appArguments = [] } = options.app || {};
35595
- appArguments = [...appArguments];
35596
- if (Array.isArray(app2)) {
35597
- return pTryEach(app2, (appName) => baseOpen({
35598
- ...options,
35599
- app: {
35600
- name: appName,
35601
- arguments: appArguments
35602
- }
35603
- }));
35604
- }
35605
- let command;
35606
- const cliArguments = [];
35607
- const childProcessOptions = {};
35608
- if (platform === "darwin") {
35609
- command = "open";
35610
- if (options.wait) {
35611
- cliArguments.push("--wait-apps");
35612
- }
35613
- if (options.background) {
35614
- cliArguments.push("--background");
35615
- }
35616
- if (options.newInstance) {
35617
- cliArguments.push("--new");
35618
- }
35619
- if (app2) {
35620
- cliArguments.push("-a", app2);
35621
- }
35622
- } else if (platform === "win32" || isWsl && !isInsideContainer() && !app2) {
35623
- const mountPoint = await getWslDrivesMountPoint();
35624
- command = isWsl ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
35625
- cliArguments.push(
35626
- "-NoProfile",
35627
- "-NonInteractive",
35628
- "\u2013ExecutionPolicy",
35629
- "Bypass",
35630
- "-EncodedCommand"
35631
- );
35632
- if (!isWsl) {
35633
- childProcessOptions.windowsVerbatimArguments = true;
35634
- }
35635
- const encodedArguments = ["Start"];
35636
- if (options.wait) {
35637
- encodedArguments.push("-Wait");
35638
- }
35639
- if (app2) {
35640
- encodedArguments.push(`"\`"${app2}\`""`, "-ArgumentList");
35641
- if (options.target) {
35642
- appArguments.unshift(options.target);
35643
- }
35644
- } else if (options.target) {
35645
- encodedArguments.push(`"${options.target}"`);
35646
- }
35647
- if (appArguments.length > 0) {
35648
- appArguments = appArguments.map((arg) => `"\`"${arg}\`""`);
35649
- encodedArguments.push(appArguments.join(","));
35650
- }
35651
- options.target = Buffer.from(encodedArguments.join(" "), "utf16le").toString("base64");
35652
- } else {
35653
- if (app2) {
35654
- command = app2;
35655
- } else {
35656
- const isBundled = !__dirname || __dirname === "/";
35657
- let exeLocalXdgOpen = false;
35658
- try {
35659
- await fs2.access(localXdgOpenPath, fsConstants.X_OK);
35660
- exeLocalXdgOpen = true;
35661
- } catch {
35662
- }
35663
- const useSystemXdgOpen = process.versions.electron || platform === "android" || isBundled || !exeLocalXdgOpen;
35664
- command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
35665
- }
35666
- if (appArguments.length > 0) {
35667
- cliArguments.push(...appArguments);
35668
- }
35669
- if (!options.wait) {
35670
- childProcessOptions.stdio = "ignore";
35671
- childProcessOptions.detached = true;
35672
- }
35673
- }
35674
- if (options.target) {
35675
- cliArguments.push(options.target);
35676
- }
35677
- if (platform === "darwin" && appArguments.length > 0) {
35678
- cliArguments.push("--args", ...appArguments);
35679
- }
35680
- const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
35681
- if (options.wait) {
35682
- return new Promise((resolve10, reject) => {
35683
- subprocess.once("error", reject);
35684
- subprocess.once("close", (exitCode) => {
35685
- if (!options.allowNonzeroExitCode && exitCode > 0) {
35686
- reject(new Error(`Exited with code ${exitCode}`));
35687
- return;
35688
- }
35689
- resolve10(subprocess);
35690
- });
35691
- });
35692
- }
35693
- subprocess.unref();
35694
- return subprocess;
35695
- };
35696
- var open = (target, options) => {
35697
- if (typeof target !== "string") {
35698
- throw new TypeError("Expected a `target`");
35699
- }
35700
- return baseOpen({
35701
- ...options,
35702
- target
35703
- });
35704
- };
35705
- var openApp = (name, options) => {
35706
- if (typeof name !== "string") {
35707
- throw new TypeError("Expected a `name`");
35708
- }
35709
- const { arguments: appArguments = [] } = options || {};
35710
- if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
35711
- throw new TypeError("Expected `appArguments` as Array type");
35712
- }
35713
- return baseOpen({
35714
- ...options,
35715
- app: {
35716
- name,
35717
- arguments: appArguments
35718
- }
35719
- });
35720
- };
35721
- function detectArchBinary(binary) {
35722
- if (typeof binary === "string" || Array.isArray(binary)) {
35723
- return binary;
35724
- }
35725
- const { [arch]: archBinary } = binary;
35726
- if (!archBinary) {
35727
- throw new Error(`${arch} is not supported`);
35728
- }
35729
- return archBinary;
35730
- }
35731
- function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
35732
- if (wsl && isWsl) {
35733
- return detectArchBinary(wsl);
35734
- }
35735
- if (!platformBinary) {
35736
- throw new Error(`${platform} is not supported`);
35737
- }
35738
- return detectArchBinary(platformBinary);
35739
- }
35740
- var apps = {};
35741
- defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
35742
- darwin: "google chrome",
35743
- win32: "chrome",
35744
- linux: ["google-chrome", "google-chrome-stable", "chromium"]
35745
- }, {
35746
- wsl: {
35747
- ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
35748
- x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
35749
- }
35750
- }));
35751
- defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
35752
- darwin: "firefox",
35753
- win32: "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
35754
- linux: "firefox"
35755
- }, {
35756
- wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
35757
- }));
35758
- defineLazyProperty(apps, "edge", () => detectPlatformBinary({
35759
- darwin: "microsoft edge",
35760
- win32: "msedge",
35761
- linux: ["microsoft-edge", "microsoft-edge-dev"]
35762
- }, {
35763
- wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
35764
- }));
35765
- open.apps = apps;
35766
- open.openApp = openApp;
35767
- module2.exports = open;
35768
- }
35769
- });
35770
-
35771
35437
  // src/server/index.ts
35772
35438
  var index_exports = {};
35773
35439
  __export(index_exports, {
@@ -35779,6 +35445,7 @@ var import_cors = __toESM(require_lib3(), 1);
35779
35445
  var import_net = __toESM(require("net"), 1);
35780
35446
  var import_path21 = require("path");
35781
35447
  var import_fs15 = require("fs");
35448
+ var import_child_process9 = require("child_process");
35782
35449
  var import_url3 = require("url");
35783
35450
  var import_module = require("module");
35784
35451
 
@@ -35886,19 +35553,6 @@ function deriveInstanceId(instanceDir) {
35886
35553
  const normalized = instanceDir.toLowerCase().replace(/\\/g, "/");
35887
35554
  return (0, import_crypto.createHash)("sha256").update(normalized).digest("hex").slice(0, 8);
35888
35555
  }
35889
- function parseSimpleEnv2(content) {
35890
- const result = {};
35891
- for (const line of content.split("\n")) {
35892
- const trimmed = line.trim();
35893
- if (!trimmed || trimmed.startsWith("#")) continue;
35894
- const idx = trimmed.indexOf("=");
35895
- if (idx === -1) continue;
35896
- const key = trimmed.slice(0, idx).trim();
35897
- const value = trimmed.slice(idx + 1).trim().replace(/^["']|["']$/g, "");
35898
- if (key) result[key] = value;
35899
- }
35900
- return result;
35901
- }
35902
35556
  function isRecord(value) {
35903
35557
  return typeof value === "object" && value !== null;
35904
35558
  }
@@ -35979,7 +35633,7 @@ function cwdProjectBinding(instanceName, instanceEnvPath) {
35979
35633
  const bindingPath = (0, import_path3.join)(process.cwd(), ".env.iranti");
35980
35634
  if (!(0, import_fs3.existsSync)(bindingPath)) return null;
35981
35635
  try {
35982
- const binding = parseSimpleEnv2((0, import_fs3.readFileSync)(bindingPath, "utf8"));
35636
+ const binding = parseSimpleEnv((0, import_fs3.readFileSync)(bindingPath, "utf8"));
35983
35637
  const bindingInstance = binding["IRANTI_INSTANCE"]?.trim() ?? "";
35984
35638
  const bindingEnvPath = binding["IRANTI_INSTANCE_ENV"]?.trim() ?? "";
35985
35639
  const matches = bindingInstance === instanceName || bindingEnvPath && (0, import_path3.resolve)(bindingEnvPath) === (0, import_path3.resolve)(instanceEnvPath);
@@ -36011,7 +35665,7 @@ async function resolveInstanceAuthority(instanceRef) {
36011
35665
  const match = await findInstanceDir(instanceRef);
36012
35666
  if (!match) return null;
36013
35667
  const instanceEnvPath = (0, import_path3.join)(match.instanceDir, ".env");
36014
- const parsedEnv = parseSimpleEnv2(await (0, import_promises.readFile)(instanceEnvPath, "utf8"));
35668
+ const parsedEnv = parseSimpleEnv(await (0, import_promises.readFile)(instanceEnvPath, "utf8"));
36015
35669
  const rawPort = parsedEnv["IRANTI_PORT"] ?? parsedEnv["PORT"] ?? "";
36016
35670
  const port = parseInt(rawPort, 10);
36017
35671
  const apiBaseUrl = Number.isNaN(port) ? parsedEnv["IRANTI_URL"]?.trim() || "http://localhost:3001" : `http://localhost:${port}`;
@@ -52082,7 +51736,7 @@ async function probeIrantiMcpInitialize(input) {
52082
51736
  }
52083
51737
  const client = new Client2({
52084
51738
  name: "iranti-control-plane",
52085
- version: "0.4.3"
51739
+ version: "1.0.0"
52086
51740
  });
52087
51741
  const timeoutMs = input.timeoutMs ?? 5e3;
52088
51742
  let initialized = false;
@@ -59723,7 +59377,7 @@ async function moveDirectory(fromPath, toPath) {
59723
59377
  async function rewriteProjectBindingInstanceEnv(projectPath, oldEnvPath, newEnvPath) {
59724
59378
  const bindingPath = (0, import_path14.join)(projectPath, ".env.iranti");
59725
59379
  if (!(0, import_fs9.existsSync)(bindingPath)) return;
59726
- const parsed = parseSimpleEnv2(await (0, import_promises8.readFile)(bindingPath, "utf8"));
59380
+ const parsed = parseSimpleEnv(await (0, import_promises8.readFile)(bindingPath, "utf8"));
59727
59381
  const current = parsed["IRANTI_INSTANCE_ENV"]?.trim() ?? "";
59728
59382
  if (!current) return;
59729
59383
  if ((0, import_path14.resolve)(current) !== (0, import_path14.resolve)(oldEnvPath)) return;
@@ -59733,7 +59387,7 @@ async function rewriteProjectBindingInstanceEnv(projectPath, oldEnvPath, newEnvP
59733
59387
  async function rewriteMovedInstanceEnv(instanceDir, previousInstanceDir) {
59734
59388
  const envPath = (0, import_path14.join)(instanceDir, ".env");
59735
59389
  if (!(0, import_fs9.existsSync)(envPath)) return;
59736
- const parsed = parseSimpleEnv2(await (0, import_promises8.readFile)(envPath, "utf8"));
59390
+ const parsed = parseSimpleEnv(await (0, import_promises8.readFile)(envPath, "utf8"));
59737
59391
  const oldBase = (0, import_path14.resolve)(previousInstanceDir);
59738
59392
  const nextEscalation = (0, import_path14.join)(instanceDir, "escalation");
59739
59393
  const nextRequestLog = (0, import_path14.join)(instanceDir, "logs", "api-requests.log");
@@ -61949,7 +61603,6 @@ function mapRowToWatermark(row) {
61949
61603
  }
61950
61604
  async function upsertMirroredEvents(events) {
61951
61605
  if (events.length === 0) return 0;
61952
- const COLS = 15;
61953
61606
  const params = [];
61954
61607
  const valueClauses = [];
61955
61608
  for (const ev of events) {
@@ -61990,7 +61643,6 @@ async function upsertMirroredEvents(events) {
61990
61643
  ev.metadata !== null && ev.metadata !== void 0 ? JSON.stringify(ev.metadata) : null
61991
61644
  // $base+14
61992
61645
  );
61993
- void COLS;
61994
61646
  }
61995
61647
  const sql = `
61996
61648
  INSERT INTO mirrored_staff_events
@@ -62120,11 +61772,15 @@ function parseLimit(value, defaultVal = 100, max = 250) {
62120
61772
  if (!Number.isFinite(n) || n < 1) throw new Error("limit must be a positive integer");
62121
61773
  return Math.min(n, max);
62122
61774
  }
61775
+ function queryString(value) {
61776
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
61777
+ }
61778
+ var INGESTION_FAILING_THRESHOLD = 3;
62123
61779
  function deriveIngestionStatus(w) {
62124
61780
  if (!w.lastPolledAt) return "never_polled";
62125
61781
  const failures = w.consecutiveFailures ?? 0;
62126
61782
  if (failures === 0) return "healthy";
62127
- if (failures < 3) return "degraded";
61783
+ if (failures < INGESTION_FAILING_THRESHOLD) return "degraded";
62128
61784
  return "failing";
62129
61785
  }
62130
61786
  sessionLedgerRouter.get("/", async (req, res) => {
@@ -62146,14 +61802,14 @@ sessionLedgerRouter.get("/", async (req, res) => {
62146
61802
  }
62147
61803
  const filters = {
62148
61804
  limit,
62149
- instanceId: typeof req.query["instanceId"] === "string" && req.query["instanceId"].trim() ? req.query["instanceId"].trim() : void 0,
62150
- source: typeof req.query["source"] === "string" && req.query["source"].trim() ? req.query["source"].trim() : void 0,
62151
- host: typeof req.query["host"] === "string" && req.query["host"].trim() ? req.query["host"].trim() : void 0,
62152
- agentId: typeof req.query["agentId"] === "string" && req.query["agentId"].trim() ? req.query["agentId"].trim() : void 0,
62153
- sessionId: typeof req.query["sessionId"] === "string" && req.query["sessionId"].trim() ? req.query["sessionId"].trim() : void 0,
62154
- actionType: typeof req.query["actionType"] === "string" && req.query["actionType"].trim() ? req.query["actionType"].trim() : void 0,
62155
- since: typeof req.query["since"] === "string" && req.query["since"].trim() ? req.query["since"].trim() : void 0,
62156
- until: typeof req.query["until"] === "string" && req.query["until"].trim() ? req.query["until"].trim() : void 0,
61805
+ instanceId: queryString(req.query["instanceId"]),
61806
+ source: queryString(req.query["source"]),
61807
+ host: queryString(req.query["host"]),
61808
+ agentId: queryString(req.query["agentId"]),
61809
+ sessionId: queryString(req.query["sessionId"]),
61810
+ actionType: queryString(req.query["actionType"]),
61811
+ since: queryString(req.query["since"]),
61812
+ until: queryString(req.query["until"]),
62157
61813
  level
62158
61814
  };
62159
61815
  const { items, total } = await queryFleetLedger(filters);
@@ -62674,6 +62330,7 @@ function stopFleetLedgerPoller() {
62674
62330
  init_db();
62675
62331
 
62676
62332
  // src/server/lib/portSelection.ts
62333
+ var PORT_SEARCH_WINDOW = 10;
62677
62334
  function parsePort(raw) {
62678
62335
  if (!raw) return null;
62679
62336
  const value = Number.parseInt(raw, 10);
@@ -62685,15 +62342,15 @@ function buildPortSelectionPlan(params) {
62685
62342
  return { start: explicitPort, end: explicitPort, strict: true };
62686
62343
  }
62687
62344
  const basePort = parsePort(params.fallbackBasePort) ?? 3e3;
62688
- return { start: basePort, end: basePort + 10, strict: false };
62345
+ return { start: basePort, end: basePort + PORT_SEARCH_WINDOW, strict: false };
62689
62346
  }
62690
62347
 
62691
62348
  // src/server/index.ts
62692
62349
  var _isSea = typeof process.isSea === "function" && process.isSea();
62693
- var __dirname3 = _isSea ? (0, import_path21.dirname)(process.execPath) : (0, import_path21.dirname)((0, import_url3.fileURLToPath)(__importmeta_url));
62350
+ var __dirname2 = _isSea ? (0, import_path21.dirname)(process.execPath) : (0, import_path21.dirname)((0, import_url3.fileURLToPath)(__importmeta_url));
62694
62351
  var clientDistCandidates = process.env.IRANTI_CP_ASSETS_DIR ? [(0, import_path21.resolve)(process.env.IRANTI_CP_ASSETS_DIR)] : _isSea ? [(0, import_path21.resolve)((0, import_path21.dirname)(process.execPath), "public", "control-plane")] : [
62695
- (0, import_path21.resolve)(__dirname3, "../../../public/control-plane"),
62696
- (0, import_path21.resolve)(__dirname3, "../../public/control-plane"),
62352
+ (0, import_path21.resolve)(__dirname2, "../../../public/control-plane"),
62353
+ (0, import_path21.resolve)(__dirname2, "../../public/control-plane"),
62697
62354
  (0, import_path21.resolve)(process.cwd(), "../../public/control-plane"),
62698
62355
  (0, import_path21.resolve)(process.cwd(), "../public/control-plane")
62699
62356
  ];
@@ -62793,10 +62450,21 @@ async function main() {
62793
62450
  });
62794
62451
  startFleetLedgerPoller();
62795
62452
  if (!process.env["IRANTI_CP_NO_OPEN"]) {
62796
- Promise.resolve().then(() => __toESM(require_open(), 1)).then(({ default: open }) => {
62797
- void open(`http://localhost:${PORT}`);
62798
- }).catch(() => {
62799
- });
62453
+ const url2 = `http://localhost:${PORT}`;
62454
+ try {
62455
+ if (process.platform === "win32") {
62456
+ (0, import_child_process9.spawn)("cmd", ["/c", "start", "", url2], {
62457
+ detached: true,
62458
+ stdio: "ignore",
62459
+ windowsHide: true
62460
+ }).unref();
62461
+ } else if (process.platform === "darwin") {
62462
+ (0, import_child_process9.spawn)("open", [url2], { detached: true, stdio: "ignore" }).unref();
62463
+ } else {
62464
+ (0, import_child_process9.spawn)("xdg-open", [url2], { detached: true, stdio: "ignore" }).unref();
62465
+ }
62466
+ } catch {
62467
+ }
62800
62468
  }
62801
62469
  });
62802
62470
  function shutdown(signal) {
@@ -62816,6 +62484,13 @@ main().catch((err) => {
62816
62484
  console.error("[iranti-cp] Fatal startup error:", err.message ?? err);
62817
62485
  process.exit(1);
62818
62486
  });
62487
+ process.on("unhandledRejection", (reason) => {
62488
+ console.error("[iranti-cp] Unhandled rejection:", reason instanceof Error ? reason.message : reason);
62489
+ });
62490
+ process.on("uncaughtException", (err) => {
62491
+ console.error("[iranti-cp] Uncaught exception:", err.message);
62492
+ console.error(err.stack);
62493
+ });
62819
62494
  // Annotate the CommonJS export names for ESM import in node:
62820
62495
  0 && (module.exports = {
62821
62496
  VERSION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iranti-control-plane",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Operator control plane for Iranti - local-first agent memory management",
5
5
  "bin": {
6
6
  "iranti-cp": "bin/iranti-cp.js"