@semiont/cli 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -512,8 +512,8 @@ var init_parseUtil = __esm({
512
512
  init_errors();
513
513
  init_en();
514
514
  makeIssue = (params) => {
515
- const { data, path: path46, errorMaps, issueData } = params;
516
- const fullPath = [...path46, ...issueData.path || []];
515
+ const { data, path: path47, errorMaps, issueData } = params;
516
+ const fullPath = [...path47, ...issueData.path || []];
517
517
  const fullIssue = {
518
518
  ...issueData,
519
519
  path: fullPath
@@ -821,11 +821,11 @@ var init_types = __esm({
821
821
  init_parseUtil();
822
822
  init_util();
823
823
  ParseInputLazyPath = class {
824
- constructor(parent, value, path46, key) {
824
+ constructor(parent, value, path47, key) {
825
825
  this._cachedPath = [];
826
826
  this.parent = parent;
827
827
  this.data = value;
828
- this._path = path46;
828
+ this._path = path47;
829
829
  this._key = key;
830
830
  }
831
831
  get path() {
@@ -4398,6 +4398,7 @@ var init_cli_paths = __esm({
4398
4398
  import { execFileSync } from "child_process";
4399
4399
  import * as fs from "fs";
4400
4400
  import * as net from "net";
4401
+ import * as path2 from "path";
4401
4402
  function checkContainerRuntime(runtime) {
4402
4403
  try {
4403
4404
  execFileSync(runtime, ["--version"], { stdio: "ignore", timeout: 5e3 });
@@ -4406,12 +4407,32 @@ function checkContainerRuntime(runtime) {
4406
4407
  return { name: "container-runtime", pass: false, message: `${runtime} is not installed or not in PATH` };
4407
4408
  }
4408
4409
  }
4410
+ function findPortOwner(port) {
4411
+ const { execFileSync: execFileSync45 } = __require("child_process");
4412
+ try {
4413
+ if (process.platform === "darwin" || process.platform === "linux") {
4414
+ const out = execFileSync45("lsof", ["-ti", `:${port}`], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
4415
+ const pids = out.trim().split("\n").filter(Boolean);
4416
+ if (pids.length > 0) return `PID ${pids.join(", ")}`;
4417
+ }
4418
+ } catch {
4419
+ }
4420
+ try {
4421
+ const out = execFileSync45("fuser", [`${port}/tcp`], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
4422
+ const pids = out.trim().split(/\s+/).filter(Boolean);
4423
+ if (pids.length > 0) return `PID ${pids.join(", ")}`;
4424
+ } catch {
4425
+ }
4426
+ return null;
4427
+ }
4409
4428
  async function checkPortFree(port) {
4410
4429
  return new Promise((resolve9) => {
4411
4430
  const server = net.createServer();
4412
4431
  server.once("error", (err) => {
4413
4432
  if (err.code === "EADDRINUSE") {
4414
- resolve9({ name: `port-${port}`, pass: false, message: `Port ${port} is in use` });
4433
+ const owner = findPortOwner(port);
4434
+ const hint = owner ? ` (${owner})` : "";
4435
+ resolve9({ name: `port-${port}`, pass: false, message: `Port ${port} is in use${hint}` });
4415
4436
  } else {
4416
4437
  resolve9({ name: `port-${port}`, pass: false, message: `Cannot check port ${port}: ${err.message}` });
4417
4438
  }
@@ -4526,6 +4547,60 @@ function checkConfigNonEmptyArray(arr, fieldPath) {
4526
4547
  }
4527
4548
  return { name: `config-${fieldPath}`, pass: true, message: `${fieldPath} has ${arr.length} entries` };
4528
4549
  }
4550
+ function readEnvKey(filePath, key) {
4551
+ if (!fs.existsSync(filePath)) return void 0;
4552
+ const content = fs.readFileSync(filePath, "utf-8");
4553
+ for (const line of content.split("\n")) {
4554
+ if (line.startsWith("#") || !line.includes("=")) continue;
4555
+ const [k, ...rest] = line.split("=");
4556
+ if (k.trim() === key) return rest.join("=").trim();
4557
+ }
4558
+ return void 0;
4559
+ }
4560
+ function resolveSharedSecret(projectRoot, thisEnvFile, thisKey, peerEnvFile, peerKey, generate2, forceGenerate = false) {
4561
+ const peerFile = path2.join(projectRoot, peerEnvFile);
4562
+ const peerSecret = readEnvKey(peerFile, peerKey);
4563
+ const thisFile = path2.join(projectRoot, thisEnvFile);
4564
+ const thisSecret = readEnvKey(thisFile, thisKey);
4565
+ if (forceGenerate) {
4566
+ const secret = generate2();
4567
+ const peerWillBeOutOfSync = !!peerSecret && peerSecret !== secret;
4568
+ return { secret, message: `Generated new ${thisKey} (--rotate-secret)`, peerWillBeOutOfSync };
4569
+ }
4570
+ if (!peerSecret) {
4571
+ const secret = generate2();
4572
+ return { secret, message: `Generated new ${thisKey}`, peerWillBeOutOfSync: false };
4573
+ }
4574
+ if (!thisSecret) {
4575
+ return { secret: peerSecret, message: `Copied ${peerKey} from ${peerEnvFile} to ${thisKey}`, peerWillBeOutOfSync: false };
4576
+ }
4577
+ if (thisSecret !== peerSecret) {
4578
+ return { secret: peerSecret, message: `${thisKey} was out of sync with ${peerEnvFile} \u2014 updated to match`, peerWillBeOutOfSync: false };
4579
+ }
4580
+ return { secret: thisSecret, message: `${thisKey} is already in sync with ${peerEnvFile}`, peerWillBeOutOfSync: false };
4581
+ }
4582
+ function checkSecretsInSync(projectRoot) {
4583
+ const backendEnv = fs.existsSync(projectRoot + "/backend/.env") ? projectRoot + "/backend/.env" : null;
4584
+ const frontendEnv = fs.existsSync(projectRoot + "/frontend/.env.local") ? projectRoot + "/frontend/.env.local" : null;
4585
+ if (!backendEnv) {
4586
+ return { name: "secrets-in-sync", pass: false, message: "backend/.env not found \u2014 run: semiont provision --service backend" };
4587
+ }
4588
+ if (!frontendEnv) {
4589
+ return { name: "secrets-in-sync", pass: false, message: "frontend/.env.local not found \u2014 run: semiont provision --service frontend" };
4590
+ }
4591
+ const jwtSecret = readEnvKey(backendEnv, "JWT_SECRET");
4592
+ const nextAuthSecret = readEnvKey(frontendEnv, "NEXTAUTH_SECRET");
4593
+ if (!jwtSecret) {
4594
+ return { name: "secrets-in-sync", pass: false, message: "JWT_SECRET missing from backend/.env" };
4595
+ }
4596
+ if (!nextAuthSecret) {
4597
+ return { name: "secrets-in-sync", pass: false, message: "NEXTAUTH_SECRET missing from frontend/.env.local" };
4598
+ }
4599
+ if (jwtSecret !== nextAuthSecret) {
4600
+ return { name: "secrets-in-sync", pass: false, message: "JWT_SECRET (backend) and NEXTAUTH_SECRET (frontend) do not match \u2014 re-provision both services" };
4601
+ }
4602
+ return { name: "secrets-in-sync", pass: true, message: "JWT_SECRET and NEXTAUTH_SECRET are in sync" };
4603
+ }
4529
4604
  function passingPreflight() {
4530
4605
  return { pass: true, checks: [] };
4531
4606
  }
@@ -4981,7 +5056,7 @@ var init_service_command_capabilities = __esm({
4981
5056
  // src/services/backend-service.ts
4982
5057
  import { execFileSync as execFileSync2 } from "child_process";
4983
5058
  import { getNodeEnvForEnvironment } from "@semiont/core";
4984
- import * as path3 from "path";
5059
+ import * as path4 from "path";
4985
5060
  import * as fs3 from "fs";
4986
5061
  var BackendService;
4987
5062
  var init_backend_service = __esm({
@@ -5028,7 +5103,7 @@ var init_backend_service = __esm({
5028
5103
  },
5029
5104
  build: buildConfig || {
5030
5105
  dockerfile: "Dockerfile.backend",
5031
- buildContext: path3.join(this.projectRoot, "apps/backend"),
5106
+ buildContext: path4.join(this.projectRoot, "apps/backend"),
5032
5107
  buildArgs: {
5033
5108
  NODE_ENV: this.environment,
5034
5109
  VERSION: process.env.VERSION || "latest"
@@ -5140,7 +5215,7 @@ var init_backend_service = __esm({
5140
5215
  }
5141
5216
  }
5142
5217
  async collectProcessLogs() {
5143
- const logPath = path3.join(this.typedConfig.projectRoot || this.projectRoot, "backend", "logs", "app.log");
5218
+ const logPath = path4.join(this.typedConfig.projectRoot || this.projectRoot, "backend", "logs", "app.log");
5144
5219
  const recent = [];
5145
5220
  const errorLogs = [];
5146
5221
  try {
@@ -5352,7 +5427,7 @@ var init_frontend_service = __esm({
5352
5427
  // src/services/database-service.ts
5353
5428
  import { execFileSync as execFileSync4 } from "child_process";
5354
5429
  import * as fs5 from "fs";
5355
- import * as path4 from "path";
5430
+ import * as path5 from "path";
5356
5431
  var DatabaseService;
5357
5432
  var init_database_service = __esm({
5358
5433
  "src/services/database-service.ts"() {
@@ -5521,14 +5596,14 @@ var init_database_service = __esm({
5521
5596
  const possibleLogPaths = [
5522
5597
  "/var/log/postgresql/",
5523
5598
  "/usr/local/var/log/",
5524
- path4.join(this.projectRoot, "data/logs")
5599
+ path5.join(this.projectRoot, "data/logs")
5525
5600
  ];
5526
5601
  for (const logPath of possibleLogPaths) {
5527
5602
  if (fs5.existsSync(logPath)) {
5528
5603
  try {
5529
5604
  const logFiles = fs5.readdirSync(logPath).filter((f) => f.endsWith(".log"));
5530
5605
  if (logFiles.length === 0) continue;
5531
- const latestLogFile = path4.join(logPath, logFiles[logFiles.length - 1]);
5606
+ const latestLogFile = path5.join(logPath, logFiles[logFiles.length - 1]);
5532
5607
  const logs = execFileSync4("tail", ["-50", latestLogFile], { encoding: "utf-8" }).split("\n").filter((line) => line.trim());
5533
5608
  return {
5534
5609
  recent: logs.slice(-10),
@@ -5562,7 +5637,7 @@ var init_database_service = __esm({
5562
5637
  });
5563
5638
 
5564
5639
  // src/services/filesystem-service.ts
5565
- import * as path5 from "path";
5640
+ import * as path6 from "path";
5566
5641
  var FilesystemService;
5567
5642
  var init_filesystem_service = __esm({
5568
5643
  "src/services/filesystem-service.ts"() {
@@ -5649,7 +5724,7 @@ var init_filesystem_service = __esm({
5649
5724
  // Helper methods
5650
5725
  // =====================================================================
5651
5726
  getDataPath() {
5652
- return this.typedConfig.path || path5.join(this.projectRoot, "data");
5727
+ return this.typedConfig.path || path6.join(this.projectRoot, "data");
5653
5728
  }
5654
5729
  };
5655
5730
  }
@@ -5855,7 +5930,7 @@ var init_service_cli_behaviors = __esm({
5855
5930
  });
5856
5931
 
5857
5932
  // src/services/mcp-service.ts
5858
- import * as path6 from "path";
5933
+ import * as path7 from "path";
5859
5934
  import * as fs6 from "fs";
5860
5935
  var MCPService;
5861
5936
  var init_mcp_service = __esm({
@@ -5930,16 +6005,16 @@ var init_mcp_service = __esm({
5930
6005
  }
5931
6006
  findMCPServer() {
5932
6007
  const cliPath = new URL(import.meta.url).pathname;
5933
- const cliDir = path6.dirname(cliPath);
6008
+ const cliDir = path7.dirname(cliPath);
5934
6009
  const possiblePaths = [
5935
6010
  // Look for bundled MCP server in CLI dist directory
5936
- path6.join(cliDir, "mcp-server", "index.js"),
5937
- path6.join(cliDir, "..", "mcp-server", "index.js"),
6011
+ path7.join(cliDir, "mcp-server", "index.js"),
6012
+ path7.join(cliDir, "..", "mcp-server", "index.js"),
5938
6013
  // Development paths (when running from source)
5939
- path6.join(this.typedConfig.projectRoot || process.cwd(), "packages/mcp-server/dist/index.js"),
5940
- path6.join(this.typedConfig.projectRoot || process.cwd(), "apps/mcp-server/dist/index.js"),
6014
+ path7.join(this.typedConfig.projectRoot || process.cwd(), "packages/mcp-server/dist/index.js"),
6015
+ path7.join(this.typedConfig.projectRoot || process.cwd(), "apps/mcp-server/dist/index.js"),
5941
6016
  // Fallback to current directory
5942
- path6.join(process.cwd(), "mcp-server/index.js"),
6017
+ path7.join(process.cwd(), "mcp-server/index.js"),
5943
6018
  "mcp-server"
5944
6019
  // Global install
5945
6020
  ];
@@ -6349,26 +6424,26 @@ __export(state_manager_exports, {
6349
6424
  StateManager: () => StateManager
6350
6425
  });
6351
6426
  import * as fs7 from "fs";
6352
- import * as path7 from "path";
6427
+ import * as path8 from "path";
6353
6428
  var StateManager;
6354
6429
  var init_state_manager = __esm({
6355
6430
  "src/core/state-manager.ts"() {
6356
6431
  "use strict";
6357
6432
  StateManager = class {
6358
6433
  static getStateDir(projectRoot) {
6359
- return path7.join(projectRoot, "state");
6434
+ return path8.join(projectRoot, "state");
6360
6435
  }
6361
6436
  static getStateFile(projectRoot, environment, service) {
6362
6437
  const stateDir = this.getStateDir(projectRoot);
6363
- const envDir = path7.join(stateDir, environment);
6364
- return path7.join(envDir, `${service}.json`);
6438
+ const envDir = path8.join(stateDir, environment);
6439
+ return path8.join(envDir, `${service}.json`);
6365
6440
  }
6366
6441
  /**
6367
6442
  * Save service state after successful start
6368
6443
  */
6369
6444
  static async save(projectRoot, environment, service, state) {
6370
6445
  const stateFile = this.getStateFile(projectRoot, environment, service);
6371
- const stateDir = path7.dirname(stateFile);
6446
+ const stateDir = path8.dirname(stateFile);
6372
6447
  await fs7.promises.mkdir(stateDir, { recursive: true });
6373
6448
  await fs7.promises.writeFile(
6374
6449
  stateFile,
@@ -6402,14 +6477,14 @@ var init_state_manager = __esm({
6402
6477
  * List all services with saved state for an environment
6403
6478
  */
6404
6479
  static async list(projectRoot, environment) {
6405
- const envDir = path7.join(this.getStateDir(projectRoot), environment);
6480
+ const envDir = path8.join(this.getStateDir(projectRoot), environment);
6406
6481
  try {
6407
6482
  const files = await fs7.promises.readdir(envDir);
6408
6483
  const states = [];
6409
6484
  for (const file of files) {
6410
6485
  if (file.endsWith(".json")) {
6411
6486
  const content = await fs7.promises.readFile(
6412
- path7.join(envDir, file),
6487
+ path8.join(envDir, file),
6413
6488
  "utf-8"
6414
6489
  );
6415
6490
  try {
@@ -6427,7 +6502,7 @@ var init_state_manager = __esm({
6427
6502
  * Clear all state for an environment
6428
6503
  */
6429
6504
  static async clearEnvironment(projectRoot, environment) {
6430
- const envDir = path7.join(this.getStateDir(projectRoot), environment);
6505
+ const envDir = path8.join(this.getStateDir(projectRoot), environment);
6431
6506
  try {
6432
6507
  await fs7.promises.rm(envDir, { recursive: true, force: true });
6433
6508
  } catch {
@@ -6495,17 +6570,17 @@ var init_network_utils = __esm({
6495
6570
  });
6496
6571
 
6497
6572
  // src/platforms/posix/handlers/database-paths.ts
6498
- import * as path8 from "path";
6573
+ import * as path9 from "path";
6499
6574
  function getDatabasePaths(context) {
6500
6575
  const projectRoot = context.service.projectRoot;
6501
- const runtimeDir = path8.join(projectRoot, "database");
6502
- const dataDir = path8.join(runtimeDir, "data", context.service.name);
6576
+ const runtimeDir = path9.join(projectRoot, "database");
6577
+ const dataDir = path9.join(runtimeDir, "data", context.service.name);
6503
6578
  return {
6504
6579
  runtimeDir,
6505
- pidFile: path8.join(runtimeDir, "database.pid"),
6506
- logsDir: path8.join(runtimeDir, "logs"),
6507
- appLogFile: path8.join(runtimeDir, "logs", "app.log"),
6508
- errorLogFile: path8.join(runtimeDir, "logs", "error.log"),
6580
+ pidFile: path9.join(runtimeDir, "database.pid"),
6581
+ logsDir: path9.join(runtimeDir, "logs"),
6582
+ appLogFile: path9.join(runtimeDir, "logs", "app.log"),
6583
+ errorLogFile: path9.join(runtimeDir, "logs", "error.log"),
6509
6584
  dataDir
6510
6585
  };
6511
6586
  }
@@ -6629,7 +6704,7 @@ var init_database_check = __esm({
6629
6704
  });
6630
6705
 
6631
6706
  // src/platforms/posix/handlers/filesystem-paths.ts
6632
- import * as path9 from "path";
6707
+ import * as path10 from "path";
6633
6708
  function getFilesystemPaths(context) {
6634
6709
  const service = context.service;
6635
6710
  const config = service.config;
@@ -6637,13 +6712,13 @@ function getFilesystemPaths(context) {
6637
6712
  if (!basePath) {
6638
6713
  throw new Error("Filesystem path not configured");
6639
6714
  }
6640
- const baseDir = path9.isAbsolute(basePath) ? basePath : path9.join(service.projectRoot, basePath);
6715
+ const baseDir = path10.isAbsolute(basePath) ? basePath : path10.join(service.projectRoot, basePath);
6641
6716
  return {
6642
6717
  baseDir,
6643
- uploadsDir: path9.join(baseDir, "uploads"),
6644
- tempDir: path9.join(baseDir, "temp"),
6645
- cacheDir: path9.join(baseDir, "cache"),
6646
- logsDir: path9.join(baseDir, "logs")
6718
+ uploadsDir: path10.join(baseDir, "uploads"),
6719
+ tempDir: path10.join(baseDir, "temp"),
6720
+ cacheDir: path10.join(baseDir, "cache"),
6721
+ logsDir: path10.join(baseDir, "logs")
6647
6722
  };
6648
6723
  }
6649
6724
  var init_filesystem_paths = __esm({
@@ -6767,22 +6842,22 @@ var init_filesystem_check = __esm({
6767
6842
  });
6768
6843
 
6769
6844
  // src/platforms/posix/handlers/mcp-paths.ts
6770
- import * as path10 from "path";
6845
+ import * as path11 from "path";
6771
6846
  import * as os from "os";
6772
6847
  function getMCPPaths(context) {
6773
6848
  const service = context.service;
6774
- const configDir = path10.join(
6849
+ const configDir = path11.join(
6775
6850
  os.homedir(),
6776
6851
  ".config",
6777
6852
  "semiont"
6778
6853
  );
6779
- const authFile = path10.join(
6854
+ const authFile = path11.join(
6780
6855
  configDir,
6781
6856
  `mcp-auth-${service.environment}.json`
6782
6857
  );
6783
6858
  return {
6784
6859
  configDir,
6785
- pidFile: path10.join(configDir, "mcp.pid"),
6860
+ pidFile: path11.join(configDir, "mcp.pid"),
6786
6861
  authFile
6787
6862
  };
6788
6863
  }
@@ -7011,23 +7086,23 @@ var init_graph_check = __esm({
7011
7086
  });
7012
7087
 
7013
7088
  // src/platforms/posix/handlers/backend-paths.ts
7014
- import * as path11 from "path";
7089
+ import * as path12 from "path";
7015
7090
  import { createRequire } from "module";
7016
7091
  function resolveBackendNpmPackage(projectRoot) {
7017
7092
  try {
7018
- const require2 = createRequire(path11.join(projectRoot, "node_modules", ".package.json"));
7093
+ const require2 = createRequire(path12.join(projectRoot, "node_modules", ".package.json"));
7019
7094
  const pkgPath = require2.resolve("@semiont/backend/package.json");
7020
- return path11.dirname(pkgPath);
7095
+ return path12.dirname(pkgPath);
7021
7096
  } catch {
7022
7097
  return null;
7023
7098
  }
7024
7099
  }
7025
7100
  function getBackendPaths(context) {
7026
7101
  const projectRoot = context.service.projectRoot;
7027
- const runtimeDir = path11.join(projectRoot, "backend");
7102
+ const runtimeDir = path12.join(projectRoot, "backend");
7028
7103
  const semiontRepo = context.options?.semiontRepo;
7029
7104
  if (semiontRepo) {
7030
- const sourceDir = path11.join(semiontRepo, "apps", "backend");
7105
+ const sourceDir = path12.join(semiontRepo, "apps", "backend");
7031
7106
  return buildPaths(sourceDir, runtimeDir, false);
7032
7107
  }
7033
7108
  const npmDir = resolveBackendNpmPackage(projectRoot);
@@ -7042,13 +7117,13 @@ function buildPaths(sourceDir, runtimeDir, fromNpmPackage) {
7042
7117
  return {
7043
7118
  sourceDir,
7044
7119
  runtimeDir,
7045
- pidFile: path11.join(runtimeDir, "backend.pid"),
7046
- envFile: path11.join(runtimeDir, ".env"),
7047
- logsDir: path11.join(runtimeDir, "logs"),
7048
- appLogFile: path11.join(runtimeDir, "logs", "app.log"),
7049
- errorLogFile: path11.join(runtimeDir, "logs", "error.log"),
7050
- tmpDir: path11.join(runtimeDir, "tmp"),
7051
- distDir: path11.join(sourceDir, "dist"),
7120
+ pidFile: path12.join(runtimeDir, "backend.pid"),
7121
+ envFile: path12.join(runtimeDir, ".env"),
7122
+ logsDir: path12.join(runtimeDir, "logs"),
7123
+ appLogFile: path12.join(runtimeDir, "logs", "app.log"),
7124
+ errorLogFile: path12.join(runtimeDir, "logs", "error.log"),
7125
+ tmpDir: path12.join(runtimeDir, "tmp"),
7126
+ distDir: path12.join(sourceDir, "dist"),
7052
7127
  fromNpmPackage
7053
7128
  };
7054
7129
  }
@@ -7218,23 +7293,23 @@ var init_backend_check = __esm({
7218
7293
  });
7219
7294
 
7220
7295
  // src/platforms/posix/handlers/frontend-paths.ts
7221
- import * as path12 from "path";
7296
+ import * as path13 from "path";
7222
7297
  import { createRequire as createRequire2 } from "module";
7223
7298
  function resolveFrontendNpmPackage(projectRoot) {
7224
7299
  try {
7225
- const require2 = createRequire2(path12.join(projectRoot, "node_modules", ".package.json"));
7300
+ const require2 = createRequire2(path13.join(projectRoot, "node_modules", ".package.json"));
7226
7301
  const pkgPath = require2.resolve("@semiont/frontend/package.json");
7227
- return path12.dirname(pkgPath);
7302
+ return path13.dirname(pkgPath);
7228
7303
  } catch {
7229
7304
  return null;
7230
7305
  }
7231
7306
  }
7232
7307
  function getFrontendPaths(context) {
7233
7308
  const projectRoot = context.service.projectRoot;
7234
- const runtimeDir = path12.join(projectRoot, "frontend");
7309
+ const runtimeDir = path13.join(projectRoot, "frontend");
7235
7310
  const semiontRepo = context.options?.semiontRepo;
7236
7311
  if (semiontRepo) {
7237
- const sourceDir = path12.join(semiontRepo, "apps", "frontend");
7312
+ const sourceDir = path13.join(semiontRepo, "apps", "frontend");
7238
7313
  return buildPaths2(sourceDir, runtimeDir, false);
7239
7314
  }
7240
7315
  const npmDir = resolveFrontendNpmPackage(projectRoot);
@@ -7249,13 +7324,13 @@ function buildPaths2(sourceDir, runtimeDir, fromNpmPackage) {
7249
7324
  return {
7250
7325
  sourceDir,
7251
7326
  runtimeDir,
7252
- pidFile: path12.join(runtimeDir, "frontend.pid"),
7253
- envLocalFile: path12.join(runtimeDir, ".env.local"),
7254
- logsDir: path12.join(runtimeDir, "logs"),
7255
- appLogFile: path12.join(runtimeDir, "logs", "app.log"),
7256
- errorLogFile: path12.join(runtimeDir, "logs", "error.log"),
7257
- tmpDir: path12.join(runtimeDir, "tmp"),
7258
- nextDir: path12.join(sourceDir, ".next"),
7327
+ pidFile: path13.join(runtimeDir, "frontend.pid"),
7328
+ envLocalFile: path13.join(runtimeDir, ".env.local"),
7329
+ logsDir: path13.join(runtimeDir, "logs"),
7330
+ appLogFile: path13.join(runtimeDir, "logs", "app.log"),
7331
+ errorLogFile: path13.join(runtimeDir, "logs", "error.log"),
7332
+ tmpDir: path13.join(runtimeDir, "tmp"),
7333
+ nextDir: path13.join(sourceDir, ".next"),
7259
7334
  fromNpmPackage
7260
7335
  };
7261
7336
  }
@@ -7438,17 +7513,17 @@ var init_frontend_check = __esm({
7438
7513
  });
7439
7514
 
7440
7515
  // src/platforms/posix/handlers/proxy-paths.ts
7441
- import * as path13 from "path";
7516
+ import * as path14 from "path";
7442
7517
  function getProxyPaths(context) {
7443
7518
  const projectRoot = context.service.projectRoot;
7444
- const runtimeDir = path13.join(projectRoot, "proxy");
7519
+ const runtimeDir = path14.join(projectRoot, "proxy");
7445
7520
  return {
7446
7521
  runtimeDir,
7447
- pidFile: path13.join(runtimeDir, "proxy.pid"),
7448
- configFile: path13.join(runtimeDir, "envoy.yaml"),
7449
- logsDir: path13.join(runtimeDir, "logs"),
7450
- appLogFile: path13.join(runtimeDir, "logs", "proxy.log"),
7451
- accessLogFile: path13.join(runtimeDir, "logs", "access.log")
7522
+ pidFile: path14.join(runtimeDir, "proxy.pid"),
7523
+ configFile: path14.join(runtimeDir, "envoy.yaml"),
7524
+ logsDir: path14.join(runtimeDir, "logs"),
7525
+ appLogFile: path14.join(runtimeDir, "logs", "proxy.log"),
7526
+ accessLogFile: path14.join(runtimeDir, "logs", "access.log")
7452
7527
  };
7453
7528
  }
7454
7529
  var init_proxy_paths = __esm({
@@ -7940,7 +8015,7 @@ var init_mcp_start = __esm({
7940
8015
  });
7941
8016
 
7942
8017
  // src/platforms/posix/handlers/graph-paths.ts
7943
- import * as path14 from "path";
8018
+ import * as path15 from "path";
7944
8019
  function getGraphPaths(context) {
7945
8020
  const service = context.service;
7946
8021
  const serviceConfig = service.config;
@@ -7952,17 +8027,17 @@ function getGraphPaths(context) {
7952
8027
  if (!dataDir) {
7953
8028
  throw new Error("JANUSGRAPH_DATA_DIR not configured");
7954
8029
  }
7955
- const janusgraphDir = path14.join(dataDir, `janusgraph-${janusgraphVersion}`);
8030
+ const janusgraphDir = path15.join(dataDir, `janusgraph-${janusgraphVersion}`);
7956
8031
  return {
7957
8032
  dataDir,
7958
- pidFile: path14.join(dataDir, "graph.pid"),
8033
+ pidFile: path15.join(dataDir, "graph.pid"),
7959
8034
  janusgraphDir,
7960
- janusgraphZipPath: path14.join(dataDir, `janusgraph-${janusgraphVersion}.zip`),
7961
- configPath: path14.join(janusgraphDir, "conf", "gremlin-server", "custom-server.yaml"),
7962
- graphConfigPath: path14.join(janusgraphDir, "conf", "custom-graph.properties"),
7963
- gremlinServerScript: path14.join(janusgraphDir, "bin", "gremlin-server.sh"),
7964
- gremlinShellScript: path14.join(janusgraphDir, "bin", "gremlin.sh"),
7965
- dataStorageDir: path14.join(dataDir, "data")
8035
+ janusgraphZipPath: path15.join(dataDir, `janusgraph-${janusgraphVersion}.zip`),
8036
+ configPath: path15.join(janusgraphDir, "conf", "gremlin-server", "custom-server.yaml"),
8037
+ graphConfigPath: path15.join(janusgraphDir, "conf", "custom-graph.properties"),
8038
+ gremlinServerScript: path15.join(janusgraphDir, "bin", "gremlin-server.sh"),
8039
+ gremlinShellScript: path15.join(janusgraphDir, "bin", "gremlin.sh"),
8040
+ dataStorageDir: path15.join(dataDir, "data")
7966
8041
  };
7967
8042
  }
7968
8043
  var init_graph_paths = __esm({
@@ -8081,9 +8156,9 @@ async function startJanusGraph(context) {
8081
8156
  }
8082
8157
  };
8083
8158
  }
8084
- async function fileExists(path46) {
8159
+ async function fileExists(path47) {
8085
8160
  try {
8086
- await fs17.access(path46);
8161
+ await fs17.access(path47);
8087
8162
  return true;
8088
8163
  } catch {
8089
8164
  return false;
@@ -8130,7 +8205,7 @@ var init_graph_start = __esm({
8130
8205
  // src/platforms/posix/handlers/backend-start.ts
8131
8206
  import { spawn as spawn4 } from "child_process";
8132
8207
  import * as fs18 from "fs";
8133
- import * as path15 from "path";
8208
+ import * as path16 from "path";
8134
8209
  var startBackendService, preflightBackendStart, backendStartDescriptor;
8135
8210
  var init_backend_start = __esm({
8136
8211
  "src/platforms/posix/handlers/backend-start.ts"() {
@@ -8208,8 +8283,8 @@ var init_backend_start = __esm({
8208
8283
  TMP_DIR: tmpDir
8209
8284
  };
8210
8285
  fs18.mkdirSync(logsDir, { recursive: true });
8211
- const appLogPath = path15.join(logsDir, "app.log");
8212
- const errorLogPath = path15.join(logsDir, "error.log");
8286
+ const appLogPath = path16.join(logsDir, "app.log");
8287
+ const errorLogPath = path16.join(logsDir, "error.log");
8213
8288
  const appLogStream = fs18.createWriteStream(appLogPath, { flags: "a" });
8214
8289
  const errorLogStream = fs18.createWriteStream(errorLogPath, { flags: "a" });
8215
8290
  const startupMessage = `
@@ -8227,7 +8302,7 @@ var init_backend_start = __esm({
8227
8302
  let args;
8228
8303
  if (paths.fromNpmPackage) {
8229
8304
  command = "node";
8230
- args = [path15.join(backendSourceDir, "dist", "index.js")];
8305
+ args = [path16.join(backendSourceDir, "dist", "index.js")];
8231
8306
  } else if (config.devMode) {
8232
8307
  command = "npm";
8233
8308
  args = ["run", "dev"];
@@ -8334,6 +8409,7 @@ var init_backend_start = __esm({
8334
8409
  if (config.port) {
8335
8410
  checks.push(await checkPortFree(config.port));
8336
8411
  }
8412
+ checks.push(checkSecretsInSync(context.service.projectRoot));
8337
8413
  return preflightFromChecks(checks);
8338
8414
  };
8339
8415
  backendStartDescriptor = {
@@ -8349,7 +8425,7 @@ var init_backend_start = __esm({
8349
8425
  // src/platforms/posix/handlers/frontend-start.ts
8350
8426
  import { spawn as spawn5 } from "child_process";
8351
8427
  import * as fs19 from "fs";
8352
- import * as path16 from "path";
8428
+ import * as path17 from "path";
8353
8429
  var startFrontendService, preflightFrontendStart, frontendStartDescriptor;
8354
8430
  var init_frontend_start = __esm({
8355
8431
  "src/platforms/posix/handlers/frontend-start.ts"() {
@@ -8426,8 +8502,8 @@ var init_frontend_start = __esm({
8426
8502
  nextPublicVars.forEach((k) => printInfo(` ${k}=${env[k]}`));
8427
8503
  }
8428
8504
  fs19.mkdirSync(logsDir, { recursive: true });
8429
- const appLogPath = path16.join(logsDir, "app.log");
8430
- const errorLogPath = path16.join(logsDir, "error.log");
8505
+ const appLogPath = path17.join(logsDir, "app.log");
8506
+ const errorLogPath = path17.join(logsDir, "error.log");
8431
8507
  const appLogStream = fs19.createWriteStream(appLogPath, { flags: "a" });
8432
8508
  const errorLogStream = fs19.createWriteStream(errorLogPath, { flags: "a" });
8433
8509
  const startupMessage = `
@@ -8445,7 +8521,7 @@ var init_frontend_start = __esm({
8445
8521
  let args;
8446
8522
  if (paths.fromNpmPackage) {
8447
8523
  command = "node";
8448
- args = [path16.join(frontendSourceDir, "standalone", "apps", "frontend", "server.js")];
8524
+ args = [path17.join(frontendSourceDir, "standalone", "apps", "frontend", "server.js")];
8449
8525
  } else if (config.devMode) {
8450
8526
  command = "npm";
8451
8527
  args = ["run", "dev"];
@@ -8552,6 +8628,7 @@ var init_frontend_start = __esm({
8552
8628
  if (config.port) {
8553
8629
  checks.push(await checkPortFree(config.port));
8554
8630
  }
8631
+ checks.push(checkSecretsInSync(context.service.projectRoot));
8555
8632
  return preflightFromChecks(checks);
8556
8633
  };
8557
8634
  frontendStartDescriptor = {
@@ -8874,7 +8951,7 @@ var init_mcp_provision = __esm({
8874
8951
 
8875
8952
  // src/platforms/posix/handlers/filesystem-provision.ts
8876
8953
  import * as fs22 from "fs";
8877
- import * as path17 from "path";
8954
+ import * as path18 from "path";
8878
8955
  var provisionFilesystemService, preflightFilesystemProvision, filesystemProvisionDescriptor;
8879
8956
  var init_filesystem_provision = __esm({
8880
8957
  "src/platforms/posix/handlers/filesystem-provision.ts"() {
@@ -8906,7 +8983,7 @@ var init_filesystem_provision = __esm({
8906
8983
  }
8907
8984
  const standardDirs = ["uploads", "temp", "cache", "logs"];
8908
8985
  for (const dir of standardDirs) {
8909
- const dirPath = path17.join(absolutePath, dir);
8986
+ const dirPath = path18.join(absolutePath, dir);
8910
8987
  fs22.mkdirSync(dirPath, { recursive: true });
8911
8988
  metadata.directories.push(dirPath);
8912
8989
  }
@@ -8928,7 +9005,7 @@ var init_filesystem_provision = __esm({
8928
9005
  }
8929
9006
  } catch {
8930
9007
  }
8931
- const readmePath = path17.join(absolutePath, "README.md");
9008
+ const readmePath = path18.join(absolutePath, "README.md");
8932
9009
  if (!fs22.existsSync(readmePath)) {
8933
9010
  const readmeContent = `# Semiont Filesystem Storage
8934
9011
 
@@ -8999,7 +9076,7 @@ Files placed here will persist across service restarts.
8999
9076
  };
9000
9077
  preflightFilesystemProvision = async (context) => {
9001
9078
  const paths = getFilesystemPaths(context);
9002
- const parentDir = path17.dirname(paths.baseDir);
9079
+ const parentDir = path18.dirname(paths.baseDir);
9003
9080
  return preflightFromChecks([
9004
9081
  checkDirectoryWritable(parentDir)
9005
9082
  ]);
@@ -9017,9 +9094,9 @@ Files placed here will persist across service restarts.
9017
9094
  // src/platforms/posix/handlers/graph-provision.ts
9018
9095
  import * as fs23 from "fs/promises";
9019
9096
  import { execFileSync as execFileSync9 } from "child_process";
9020
- async function fileExists2(path46) {
9097
+ async function fileExists2(path47) {
9021
9098
  try {
9022
- await fs23.access(path46);
9099
+ await fs23.access(path47);
9023
9100
  return true;
9024
9101
  } catch {
9025
9102
  return false;
@@ -9202,7 +9279,7 @@ ssl: {
9202
9279
 
9203
9280
  // src/platforms/posix/handlers/backend-provision.ts
9204
9281
  import * as fs24 from "fs";
9205
- import * as path18 from "path";
9282
+ import * as path19 from "path";
9206
9283
  import * as crypto from "crypto";
9207
9284
  import { execFileSync as execFileSync10 } from "child_process";
9208
9285
  import { getNodeEnvForEnvironment as getNodeEnvForEnvironment2 } from "@semiont/core";
@@ -9271,7 +9348,7 @@ var init_backend_provision = __esm({
9271
9348
  const backupPath = `${envFile}.backup.${Date.now()}`;
9272
9349
  fs24.copyFileSync(envFile, backupPath);
9273
9350
  if (!service.quiet) {
9274
- printWarning(`.env already exists, backing up to: ${path18.basename(backupPath)}`);
9351
+ printWarning(`.env already exists, backing up to: ${path19.basename(backupPath)}`);
9275
9352
  printInfo("Creating new .env with updated configuration...");
9276
9353
  }
9277
9354
  }
@@ -9283,7 +9360,19 @@ var init_backend_provision = __esm({
9283
9360
  const allowedDomains = oauthAllowedDomains.join(",");
9284
9361
  const nodeEnv = getNodeEnvForEnvironment2(service.environmentConfig);
9285
9362
  const enableLocalAuth = service.environmentConfig.app?.security?.enableLocalAuth ?? nodeEnv === "development";
9286
- const jwtSecret = service.environmentConfig.app?.security?.jwtSecret ?? crypto.randomBytes(32).toString("base64");
9363
+ const { secret: jwtSecret, message: jwtSecretMessage, peerWillBeOutOfSync: jwtPeerOutOfSync } = resolveSharedSecret(
9364
+ projectRoot,
9365
+ "backend/.env",
9366
+ "JWT_SECRET",
9367
+ "frontend/.env.local",
9368
+ "NEXTAUTH_SECRET",
9369
+ () => service.environmentConfig.app?.security?.jwtSecret ?? crypto.randomBytes(32).toString("base64"),
9370
+ options.rotateSecret === true
9371
+ );
9372
+ printInfo(jwtSecretMessage);
9373
+ if (jwtPeerOutOfSync) {
9374
+ printWarning("frontend NEXTAUTH_SECRET is now out of sync \u2014 re-provision frontend to restore authentication");
9375
+ }
9287
9376
  const envUpdates = {
9288
9377
  "NODE_ENV": nodeEnv,
9289
9378
  "PORT": port.toString(),
@@ -9308,14 +9397,14 @@ var init_backend_provision = __esm({
9308
9397
  if (!service.quiet) {
9309
9398
  printSuccess("Created .env with configuration from environment file");
9310
9399
  }
9311
- const prismaSchemaPath = path18.join(backendSourceDir, "prisma", "schema.prisma");
9400
+ const prismaSchemaPath = path19.join(backendSourceDir, "prisma", "schema.prisma");
9312
9401
  if (!paths.fromNpmPackage) {
9313
- const staleEnv = path18.join(backendSourceDir, ".env");
9402
+ const staleEnv = path19.join(backendSourceDir, ".env");
9314
9403
  if (fs24.existsSync(staleEnv)) {
9315
9404
  const backupPath = `${staleEnv}.backup.${Date.now()}`;
9316
9405
  fs24.renameSync(staleEnv, backupPath);
9317
9406
  if (!service.quiet) {
9318
- printWarning(`Moved stale ${staleEnv} to ${path18.basename(backupPath)}`);
9407
+ printWarning(`Moved stale ${staleEnv} to ${path19.basename(backupPath)}`);
9319
9408
  printInfo(`Runtime .env is now at: ${envFile}`);
9320
9409
  }
9321
9410
  }
@@ -9349,8 +9438,8 @@ var init_backend_provision = __esm({
9349
9438
  if (!semiontRepo) {
9350
9439
  throw new Error("SEMIONT_REPO not configured");
9351
9440
  }
9352
- const monorepoRoot = path18.resolve(semiontRepo);
9353
- const rootPackageJsonPath = path18.join(monorepoRoot, "package.json");
9441
+ const monorepoRoot = path19.resolve(semiontRepo);
9442
+ const rootPackageJsonPath = path19.join(monorepoRoot, "package.json");
9354
9443
  if (fs24.existsSync(rootPackageJsonPath)) {
9355
9444
  const rootPackageJson = JSON.parse(fs24.readFileSync(rootPackageJsonPath, "utf-8"));
9356
9445
  if (rootPackageJson.workspaces) {
@@ -9401,8 +9490,8 @@ var init_backend_provision = __esm({
9401
9490
  printInfo("Building workspace dependencies...");
9402
9491
  }
9403
9492
  try {
9404
- const monorepoRoot = path18.dirname(path18.dirname(backendSourceDir));
9405
- const rootPackageJsonPath = path18.join(monorepoRoot, "package.json");
9493
+ const monorepoRoot = path19.dirname(path19.dirname(backendSourceDir));
9494
+ const rootPackageJsonPath = path19.join(monorepoRoot, "package.json");
9406
9495
  if (fs24.existsSync(rootPackageJsonPath)) {
9407
9496
  const rootPackageJson = JSON.parse(fs24.readFileSync(rootPackageJsonPath, "utf-8"));
9408
9497
  if (rootPackageJson.workspaces) {
@@ -9475,7 +9564,7 @@ var init_backend_provision = __esm({
9475
9564
  printInfo("You may need to run migrations manually: npx prisma migrate deploy");
9476
9565
  }
9477
9566
  }
9478
- const readmePath = path18.join(runtimeDir, "RUNTIME.md");
9567
+ const readmePath = path19.join(runtimeDir, "RUNTIME.md");
9479
9568
  if (!fs24.existsSync(readmePath)) {
9480
9569
  const readmeContent = `# Backend Runtime Directory
9481
9570
 
@@ -9542,11 +9631,11 @@ ${paths.fromNpmPackage ? `Installed npm package: ${backendSourceDir}` : `Semiont
9542
9631
  const db = envConfig.services?.database;
9543
9632
  const paths = getBackendPaths(context);
9544
9633
  const checks = paths.fromNpmPackage ? [
9545
- checkFileExists(path18.join(paths.sourceDir, "dist", "index.js"), "backend dist/index.js")
9634
+ checkFileExists(path19.join(paths.sourceDir, "dist", "index.js"), "backend dist/index.js")
9546
9635
  ] : [
9547
9636
  checkCommandAvailable("npm"),
9548
9637
  checkCommandAvailable("npx"),
9549
- checkFileExists(path18.join(paths.sourceDir, "package.json"), "backend package.json")
9638
+ checkFileExists(path19.join(paths.sourceDir, "package.json"), "backend package.json")
9550
9639
  ];
9551
9640
  checks.push(
9552
9641
  checkConfigPort(config.port, "backend.port"),
@@ -9573,7 +9662,7 @@ ${paths.fromNpmPackage ? `Installed npm package: ${backendSourceDir}` : `Semiont
9573
9662
 
9574
9663
  // src/platforms/posix/handlers/frontend-provision.ts
9575
9664
  import * as fs25 from "fs";
9576
- import * as path19 from "path";
9665
+ import * as path20 from "path";
9577
9666
  import * as crypto2 from "crypto";
9578
9667
  import { execFileSync as execFileSync11 } from "child_process";
9579
9668
  var provisionFrontendService, preflightFrontendProvision, frontendProvisionDescriptor;
@@ -9584,7 +9673,7 @@ var init_frontend_provision = __esm({
9584
9673
  init_frontend_paths();
9585
9674
  init_preflight_utils();
9586
9675
  provisionFrontendService = async (context) => {
9587
- const { service } = context;
9676
+ const { service, options } = context;
9588
9677
  const projectRoot = service.projectRoot;
9589
9678
  if (!context.options?.semiontRepo && !resolveFrontendNpmPackage(projectRoot)) {
9590
9679
  if (!service.quiet) {
@@ -9623,16 +9712,28 @@ var init_frontend_provision = __esm({
9623
9712
  if (!service.quiet) {
9624
9713
  printInfo(`Created runtime directories in: ${runtimeDir}`);
9625
9714
  }
9626
- const envExamplePath = path19.join(frontendSourceDir, ".env.example");
9715
+ const envExamplePath = path20.join(frontendSourceDir, ".env.example");
9627
9716
  if (fs25.existsSync(envFile)) {
9628
9717
  const backupPath = `${envFile}.backup.${Date.now()}`;
9629
9718
  fs25.copyFileSync(envFile, backupPath);
9630
9719
  if (!service.quiet) {
9631
- printWarning(`.env.local already exists, backing up to: ${path19.basename(backupPath)}`);
9720
+ printWarning(`.env.local already exists, backing up to: ${path20.basename(backupPath)}`);
9632
9721
  printInfo("Creating new .env.local with updated configuration...");
9633
9722
  }
9634
9723
  }
9635
- const nextAuthSecret = crypto2.randomBytes(32).toString("base64");
9724
+ const { secret: nextAuthSecret, message: nextAuthSecretMessage, peerWillBeOutOfSync: nextAuthPeerOutOfSync } = resolveSharedSecret(
9725
+ projectRoot,
9726
+ "frontend/.env.local",
9727
+ "NEXTAUTH_SECRET",
9728
+ "backend/.env",
9729
+ "JWT_SECRET",
9730
+ () => crypto2.randomBytes(32).toString("base64"),
9731
+ options.rotateSecret === true
9732
+ );
9733
+ printInfo(nextAuthSecretMessage);
9734
+ if (nextAuthPeerOutOfSync) {
9735
+ printWarning("backend JWT_SECRET is now out of sync \u2014 re-provision backend to restore authentication");
9736
+ }
9636
9737
  const config = service.config;
9637
9738
  const port = config.port;
9638
9739
  const siteName = config.siteName;
@@ -9707,12 +9808,12 @@ NEXT_PUBLIC_OAUTH_ALLOWED_DOMAINS=${oauthAllowedDomains.join(",")}
9707
9808
  }
9708
9809
  }
9709
9810
  if (!paths.fromNpmPackage) {
9710
- const staleEnvLocal = path19.join(frontendSourceDir, ".env.local");
9811
+ const staleEnvLocal = path20.join(frontendSourceDir, ".env.local");
9711
9812
  if (fs25.existsSync(staleEnvLocal)) {
9712
9813
  const backupPath = `${staleEnvLocal}.backup.${Date.now()}`;
9713
9814
  fs25.renameSync(staleEnvLocal, backupPath);
9714
9815
  if (!service.quiet) {
9715
- printWarning(`Moved stale ${staleEnvLocal} to ${path19.basename(backupPath)}`);
9816
+ printWarning(`Moved stale ${staleEnvLocal} to ${path20.basename(backupPath)}`);
9716
9817
  printInfo(`Runtime .env.local is now at: ${envFile}`);
9717
9818
  }
9718
9819
  }
@@ -9726,8 +9827,8 @@ NEXT_PUBLIC_OAUTH_ALLOWED_DOMAINS=${oauthAllowedDomains.join(",")}
9726
9827
  printInfo("Installing npm dependencies...");
9727
9828
  }
9728
9829
  try {
9729
- const monorepoRoot = path19.dirname(path19.dirname(frontendSourceDir));
9730
- const rootPackageJsonPath = path19.join(monorepoRoot, "package.json");
9830
+ const monorepoRoot = path20.dirname(path20.dirname(frontendSourceDir));
9831
+ const rootPackageJsonPath = path20.join(monorepoRoot, "package.json");
9731
9832
  if (fs25.existsSync(rootPackageJsonPath)) {
9732
9833
  const rootPackageJson = JSON.parse(fs25.readFileSync(rootPackageJsonPath, "utf-8"));
9733
9834
  if (rootPackageJson.workspaces) {
@@ -9762,8 +9863,8 @@ NEXT_PUBLIC_OAUTH_ALLOWED_DOMAINS=${oauthAllowedDomains.join(",")}
9762
9863
  printInfo("Building workspace dependencies...");
9763
9864
  }
9764
9865
  try {
9765
- const monorepoRoot = path19.dirname(path19.dirname(frontendSourceDir));
9766
- const rootPackageJsonPath = path19.join(monorepoRoot, "package.json");
9866
+ const monorepoRoot = path20.dirname(path20.dirname(frontendSourceDir));
9867
+ const rootPackageJsonPath = path20.join(monorepoRoot, "package.json");
9767
9868
  if (fs25.existsSync(rootPackageJsonPath)) {
9768
9869
  const rootPackageJson = JSON.parse(fs25.readFileSync(rootPackageJsonPath, "utf-8"));
9769
9870
  if (rootPackageJson.workspaces) {
@@ -9809,7 +9910,7 @@ NEXT_PUBLIC_OAUTH_ALLOWED_DOMAINS=${oauthAllowedDomains.join(",")}
9809
9910
  }
9810
9911
  }
9811
9912
  }
9812
- const readmePath = path19.join(runtimeDir, "RUNTIME.md");
9913
+ const readmePath = path20.join(runtimeDir, "RUNTIME.md");
9813
9914
  if (!fs25.existsSync(readmePath)) {
9814
9915
  const readmeContent = `# Frontend Runtime Directory
9815
9916
 
@@ -9875,10 +9976,10 @@ ${paths.fromNpmPackage ? `Installed npm package: ${frontendSourceDir}` : `Semion
9875
9976
  const envConfig = context.service.environmentConfig;
9876
9977
  const paths = getFrontendPaths(context);
9877
9978
  const checks = paths.fromNpmPackage ? [
9878
- checkFileExists(path19.join(paths.sourceDir, "standalone", "apps", "frontend", "server.js"), "frontend standalone server.js")
9979
+ checkFileExists(path20.join(paths.sourceDir, "standalone", "apps", "frontend", "server.js"), "frontend standalone server.js")
9879
9980
  ] : [
9880
9981
  checkCommandAvailable("npm"),
9881
- checkFileExists(path19.join(paths.sourceDir, "package.json"), "frontend package.json")
9982
+ checkFileExists(path20.join(paths.sourceDir, "package.json"), "frontend package.json")
9882
9983
  ];
9883
9984
  checks.push(
9884
9985
  checkConfigPort(config.port, "frontend.port"),
@@ -9900,7 +10001,7 @@ ${paths.fromNpmPackage ? `Installed npm package: ${frontendSourceDir}` : `Semion
9900
10001
 
9901
10002
  // src/platforms/posix/handlers/proxy-provision.ts
9902
10003
  import * as fs26 from "fs";
9903
- import * as path20 from "path";
10004
+ import * as path21 from "path";
9904
10005
  function processProxyConfig(templatePath, outputPath, replacements) {
9905
10006
  let content = fs26.readFileSync(templatePath, "utf-8");
9906
10007
  for (const [key, value] of Object.entries(replacements)) {
@@ -9934,7 +10035,7 @@ var init_proxy_provision = __esm({
9934
10035
  const backendPort = config.backendPort || 4e3;
9935
10036
  const frontendPort = config.frontendPort || 3e3;
9936
10037
  if (config.type === "envoy") {
9937
- const templatePath = path20.join(getTemplatesDir(import.meta.url), "envoy.yaml");
10038
+ const templatePath = path21.join(getTemplatesDir(import.meta.url), "envoy.yaml");
9938
10039
  if (!fs26.existsSync(templatePath)) {
9939
10040
  return {
9940
10041
  success: false,
@@ -10006,7 +10107,7 @@ var init_proxy_provision = __esm({
10006
10107
  });
10007
10108
 
10008
10109
  // src/platforms/posix/handlers/backend-publish.ts
10009
- import * as path21 from "path";
10110
+ import * as path22 from "path";
10010
10111
  import { execFileSync as execFileSync12 } from "child_process";
10011
10112
  var publishBackendService, backendPublishDescriptor;
10012
10113
  var init_backend_publish = __esm({
@@ -10056,7 +10157,7 @@ var init_backend_publish = __esm({
10056
10157
  success: true,
10057
10158
  metadata: { serviceType: "backend", devMode: false },
10058
10159
  artifacts: {
10059
- buildPath: path21.join(sourceDir, "dist")
10160
+ buildPath: path22.join(sourceDir, "dist")
10060
10161
  }
10061
10162
  };
10062
10163
  } catch (error) {
@@ -10078,7 +10179,7 @@ var init_backend_publish = __esm({
10078
10179
  });
10079
10180
 
10080
10181
  // src/platforms/posix/handlers/frontend-publish.ts
10081
- import * as path22 from "path";
10182
+ import * as path23 from "path";
10082
10183
  import { execFileSync as execFileSync13 } from "child_process";
10083
10184
  var publishFrontendService, frontendPublishDescriptor;
10084
10185
  var init_frontend_publish = __esm({
@@ -10128,7 +10229,7 @@ var init_frontend_publish = __esm({
10128
10229
  success: true,
10129
10230
  metadata: { serviceType: "frontend", devMode: false },
10130
10231
  artifacts: {
10131
- buildPath: path22.join(sourceDir, ".next")
10232
+ buildPath: path23.join(sourceDir, ".next")
10132
10233
  }
10133
10234
  };
10134
10235
  } catch (error) {
@@ -10268,9 +10369,9 @@ async function stopJanusGraph(context) {
10268
10369
  };
10269
10370
  }
10270
10371
  }
10271
- async function fileExists3(path46) {
10372
+ async function fileExists3(path47) {
10272
10373
  try {
10273
- await fs27.access(path46);
10374
+ await fs27.access(path47);
10274
10375
  return true;
10275
10376
  } catch {
10276
10377
  return false;
@@ -10311,7 +10412,7 @@ var init_graph_stop = __esm({
10311
10412
 
10312
10413
  // src/platforms/posix/handlers/filesystem-stop.ts
10313
10414
  import * as fs28 from "fs";
10314
- import * as path23 from "path";
10415
+ import * as path24 from "path";
10315
10416
  import { execFileSync as execFileSync14 } from "child_process";
10316
10417
  var stopFilesystemService, filesystemStopDescriptor;
10317
10418
  var init_filesystem_stop = __esm({
@@ -10383,7 +10484,7 @@ var init_filesystem_stop = __esm({
10383
10484
  }
10384
10485
  const tempFiles = fs28.readdirSync(tempDir);
10385
10486
  for (const file of tempFiles) {
10386
- const filePath = path23.join(tempDir, file);
10487
+ const filePath = path24.join(tempDir, file);
10387
10488
  try {
10388
10489
  if (fs28.statSync(filePath).isDirectory()) {
10389
10490
  fs28.rmSync(filePath, { recursive: true, force: true });
@@ -10402,7 +10503,7 @@ var init_filesystem_stop = __esm({
10402
10503
  }
10403
10504
  const cacheFiles = fs28.readdirSync(cacheDir);
10404
10505
  for (const file of cacheFiles) {
10405
- const filePath = path23.join(cacheDir, file);
10506
+ const filePath = path24.join(cacheDir, file);
10406
10507
  try {
10407
10508
  if (fs28.statSync(filePath).isDirectory()) {
10408
10509
  fs28.rmSync(filePath, { recursive: true, force: true });
@@ -11073,16 +11174,16 @@ var init_inference_check = __esm({
11073
11174
  });
11074
11175
 
11075
11176
  // src/platforms/posix/handlers/inference-paths.ts
11076
- import * as path24 from "path";
11177
+ import * as path25 from "path";
11077
11178
  function getInferencePaths(context) {
11078
11179
  const projectRoot = context.service.projectRoot;
11079
- const runtimeDir = path24.join(projectRoot, "inference");
11180
+ const runtimeDir = path25.join(projectRoot, "inference");
11080
11181
  return {
11081
11182
  runtimeDir,
11082
- pidFile: path24.join(runtimeDir, "ollama.pid"),
11083
- logsDir: path24.join(runtimeDir, "logs"),
11084
- appLogFile: path24.join(runtimeDir, "logs", "ollama.log"),
11085
- errorLogFile: path24.join(runtimeDir, "logs", "ollama-error.log")
11183
+ pidFile: path25.join(runtimeDir, "ollama.pid"),
11184
+ logsDir: path25.join(runtimeDir, "logs"),
11185
+ appLogFile: path25.join(runtimeDir, "logs", "ollama.log"),
11186
+ errorLogFile: path25.join(runtimeDir, "logs", "ollama-error.log")
11086
11187
  };
11087
11188
  }
11088
11189
  var init_inference_paths = __esm({
@@ -11506,7 +11607,7 @@ var init_handlers = __esm({
11506
11607
  // src/platforms/posix/platform.ts
11507
11608
  import { execFileSync as execFileSync17 } from "child_process";
11508
11609
  import * as fs35 from "fs";
11509
- import * as path25 from "path";
11610
+ import * as path26 from "path";
11510
11611
  var PosixPlatform;
11511
11612
  var init_platform2 = __esm({
11512
11613
  "src/platforms/posix/platform.ts"() {
@@ -11642,19 +11743,19 @@ var init_platform2 = __esm({
11642
11743
  }
11643
11744
  if (logs.length === 0) {
11644
11745
  const logPaths = [
11645
- path25.join("/var/log", service.name, "*.log"),
11646
- path25.join(service.projectRoot, "logs", "*.log"),
11647
- path25.join(service.projectRoot, ".logs", "*.log")
11746
+ path26.join("/var/log", service.name, "*.log"),
11747
+ path26.join(service.projectRoot, "logs", "*.log"),
11748
+ path26.join(service.projectRoot, ".logs", "*.log")
11648
11749
  ];
11649
11750
  for (const pattern of logPaths) {
11650
- const dir = path25.dirname(pattern);
11651
- const filePattern = path25.basename(pattern);
11751
+ const dir = path26.dirname(pattern);
11752
+ const filePattern = path26.basename(pattern);
11652
11753
  if (fs35.existsSync(dir)) {
11653
11754
  const files = fs35.readdirSync(dir).filter(
11654
11755
  (f) => f.match(filePattern.replace("*", ".*"))
11655
11756
  );
11656
11757
  for (const file of files) {
11657
- const fullPath = path25.join(dir, file);
11758
+ const fullPath = path26.join(dir, file);
11658
11759
  const content = this.tailFile(fullPath, tail);
11659
11760
  if (content) {
11660
11761
  const lines = content.split("\n");
@@ -11688,17 +11789,17 @@ var init_platform2 = __esm({
11688
11789
  "/var/log/postgresql/*.log",
11689
11790
  "/var/log/mysql/*.log",
11690
11791
  "/var/log/mongodb/*.log",
11691
- path25.join(service.projectRoot, "data", "logs", "*.log")
11792
+ path26.join(service.projectRoot, "data", "logs", "*.log")
11692
11793
  ];
11693
11794
  for (const pattern of logPaths) {
11694
- const dir = path25.dirname(pattern);
11695
- const filePattern = path25.basename(pattern);
11795
+ const dir = path26.dirname(pattern);
11796
+ const filePattern = path26.basename(pattern);
11696
11797
  if (fs35.existsSync(dir)) {
11697
11798
  const files = fs35.readdirSync(dir).filter(
11698
11799
  (f) => f.match(filePattern.replace("*", ".*"))
11699
11800
  );
11700
11801
  for (const file of files.slice(-1)) {
11701
- const fullPath = path25.join(dir, file);
11802
+ const fullPath = path26.join(dir, file);
11702
11803
  const content = this.tailFile(fullPath, tail);
11703
11804
  if (content) {
11704
11805
  const lines = content.split("\n");
@@ -12672,11 +12773,11 @@ var init_database_start2 = __esm({
12672
12773
 
12673
12774
  // src/platforms/container/handlers/graph-start.ts
12674
12775
  import * as fs36 from "fs/promises";
12675
- import * as path26 from "path";
12776
+ import * as path27 from "path";
12676
12777
  import { execFileSync as execFileSync23 } from "child_process";
12677
12778
  async function startJanusGraph2(context) {
12678
12779
  const { service, runtime, containerName } = context;
12679
- const composePath = path26.join(service.projectRoot, "docker-compose.janusgraph.yml");
12780
+ const composePath = path27.join(service.projectRoot, "docker-compose.janusgraph.yml");
12680
12781
  if (!await fileExists4(composePath)) {
12681
12782
  return {
12682
12783
  success: false,
@@ -12801,9 +12902,9 @@ async function startJanusGraph2(context) {
12801
12902
  };
12802
12903
  }
12803
12904
  }
12804
- async function fileExists4(path46) {
12905
+ async function fileExists4(path47) {
12805
12906
  try {
12806
- await fs36.access(path46);
12907
+ await fs36.access(path47);
12807
12908
  return true;
12808
12909
  } catch {
12809
12910
  return false;
@@ -12853,7 +12954,7 @@ var init_graph_start2 = __esm({
12853
12954
  // src/platforms/container/handlers/database-provision.ts
12854
12955
  import { execFileSync as execFileSync24 } from "child_process";
12855
12956
  import * as fs37 from "fs";
12856
- import * as path27 from "path";
12957
+ import * as path28 from "path";
12857
12958
  var provisionDatabaseContainer, preflightDatabaseProvision, databaseProvisionDescriptor;
12858
12959
  var init_database_provision = __esm({
12859
12960
  "src/platforms/container/handlers/database-provision.ts"() {
@@ -12889,9 +12990,9 @@ var init_database_provision = __esm({
12889
12990
  } catch (error) {
12890
12991
  printWarning(`Failed to pull image ${image}, will try to use local`);
12891
12992
  }
12892
- const initScriptsPath = path27.join(service.projectRoot, "db", "init");
12893
- const migrationsPath = path27.join(service.projectRoot, "db", "migrations");
12894
- const seedDataPath = path27.join(service.projectRoot, "db", "seed");
12993
+ const initScriptsPath = path28.join(service.projectRoot, "db", "init");
12994
+ const migrationsPath = path28.join(service.projectRoot, "db", "migrations");
12995
+ const seedDataPath = path28.join(service.projectRoot, "db", "seed");
12895
12996
  const hasInitScripts = fs37.existsSync(initScriptsPath);
12896
12997
  const hasMigrations = fs37.existsSync(migrationsPath);
12897
12998
  const hasSeedData = fs37.existsSync(seedDataPath);
@@ -15644,7 +15745,7 @@ var init_js_yaml = __esm({
15644
15745
 
15645
15746
  // src/platforms/container/handlers/graph-provision.ts
15646
15747
  import * as fs38 from "fs/promises";
15647
- import * as path28 from "path";
15748
+ import * as path29 from "path";
15648
15749
  import { execFileSync as execFileSync25 } from "child_process";
15649
15750
  var provisionGraphService2, preflightGraphProvision2, graphProvisionDescriptor2;
15650
15751
  var init_graph_provision2 = __esm({
@@ -15786,7 +15887,7 @@ var init_graph_provision2 = __esm({
15786
15887
  ...withElasticsearch && { "elasticsearch-data": {} }
15787
15888
  }
15788
15889
  };
15789
- const composePath = path28.join(service.projectRoot, "docker-compose.janusgraph.yml");
15890
+ const composePath = path29.join(service.projectRoot, "docker-compose.janusgraph.yml");
15790
15891
  await fs38.writeFile(
15791
15892
  composePath,
15792
15893
  `# Generated by semiont provision --service janusgraph
@@ -15855,12 +15956,12 @@ var init_graph_provision2 = __esm({
15855
15956
  });
15856
15957
 
15857
15958
  // src/platforms/container/handlers/graph-stop.ts
15858
- import * as path29 from "path";
15959
+ import * as path30 from "path";
15859
15960
  import { execFileSync as execFileSync26 } from "child_process";
15860
15961
  import * as fs39 from "fs/promises";
15861
15962
  async function stopJanusGraph2(context) {
15862
15963
  const { service, runtime, options, containerName } = context;
15863
- const composePath = path29.join(service.projectRoot, "docker-compose.janusgraph.yml");
15964
+ const composePath = path30.join(service.projectRoot, "docker-compose.janusgraph.yml");
15864
15965
  if (!await fileExists5(composePath)) {
15865
15966
  if (!service.quiet) {
15866
15967
  printWarning("JanusGraph is not provisioned.");
@@ -15956,9 +16057,9 @@ async function stopJanusGraph2(context) {
15956
16057
  };
15957
16058
  }
15958
16059
  }
15959
- async function fileExists5(path46) {
16060
+ async function fileExists5(path47) {
15960
16061
  try {
15961
- await fs39.access(path46);
16062
+ await fs39.access(path47);
15962
16063
  return true;
15963
16064
  } catch {
15964
16065
  return false;
@@ -16159,18 +16260,18 @@ var init_database_stop = __esm({
16159
16260
  });
16160
16261
 
16161
16262
  // src/platforms/container/handlers/proxy-paths.ts
16162
- import * as path30 from "path";
16263
+ import * as path31 from "path";
16163
16264
  function getProxyPaths2(context) {
16164
16265
  const projectRoot = context.service.projectRoot;
16165
- const runtimeDir = path30.join(projectRoot, "proxy");
16266
+ const runtimeDir = path31.join(projectRoot, "proxy");
16166
16267
  return {
16167
16268
  runtimeDir,
16168
- logsDir: path30.join(runtimeDir, "logs"),
16169
- pidFile: path30.join(runtimeDir, "proxy.pid"),
16170
- configFile: path30.join(runtimeDir, "envoy.yaml"),
16171
- containerLogFile: path30.join(runtimeDir, "logs", "container.log"),
16172
- accessLogFile: path30.join(runtimeDir, "logs", "access.log"),
16173
- adminLogFile: path30.join(runtimeDir, "logs", "admin.log")
16269
+ logsDir: path31.join(runtimeDir, "logs"),
16270
+ pidFile: path31.join(runtimeDir, "proxy.pid"),
16271
+ configFile: path31.join(runtimeDir, "envoy.yaml"),
16272
+ containerLogFile: path31.join(runtimeDir, "logs", "container.log"),
16273
+ accessLogFile: path31.join(runtimeDir, "logs", "access.log"),
16274
+ adminLogFile: path31.join(runtimeDir, "logs", "admin.log")
16174
16275
  };
16175
16276
  }
16176
16277
  var init_proxy_paths2 = __esm({
@@ -16181,7 +16282,7 @@ var init_proxy_paths2 = __esm({
16181
16282
 
16182
16283
  // src/platforms/container/handlers/proxy-provision.ts
16183
16284
  import * as fs40 from "fs";
16184
- import * as path31 from "path";
16285
+ import * as path32 from "path";
16185
16286
  import { execFileSync as execFileSync28 } from "child_process";
16186
16287
  function getHostAddress(runtime) {
16187
16288
  const platform = process.platform;
@@ -16248,7 +16349,7 @@ var init_proxy_provision2 = __esm({
16248
16349
  const backendPort = config.backendPort || 4e3;
16249
16350
  const frontendPort = config.frontendPort || 3e3;
16250
16351
  if (config.type === "envoy") {
16251
- const templatePath = path31.join(getTemplatesDir(import.meta.url), "envoy.yaml");
16352
+ const templatePath = path32.join(getTemplatesDir(import.meta.url), "envoy.yaml");
16252
16353
  if (!fs40.existsSync(templatePath)) {
16253
16354
  return {
16254
16355
  success: false,
@@ -16441,6 +16542,8 @@ var init_proxy_start2 = __esm({
16441
16542
  `${adminPort}:9901`,
16442
16543
  "-v",
16443
16544
  `${paths.runtimeDir}:/etc/envoy:ro`,
16545
+ "--add-host=host.docker.internal:host-gateway",
16546
+ // Ensure IPv4 resolution for upstream services
16444
16547
  "--restart",
16445
16548
  "unless-stopped",
16446
16549
  "--log-driver",
@@ -16653,7 +16756,10 @@ import { execFileSync as execFileSync31 } from "child_process";
16653
16756
  import * as fs42 from "fs";
16654
16757
  async function checkUrl(url, timeout = 5e3) {
16655
16758
  try {
16656
- execFileSync31("curl", ["-s", "-f", "-m", Math.floor(timeout / 1e3).toString(), "-o", "/dev/null", url], { stdio: "pipe" });
16759
+ const controller = new AbortController();
16760
+ const timer = setTimeout(() => controller.abort(), timeout);
16761
+ await fetch(url, { signal: controller.signal, redirect: "follow" });
16762
+ clearTimeout(timer);
16657
16763
  return true;
16658
16764
  } catch {
16659
16765
  return false;
@@ -16810,7 +16916,7 @@ var init_proxy_check2 = __esm({
16810
16916
  healthCheck.logs = getRecentLogs(runtime, containerName, 10);
16811
16917
  if (healthCheck.logs && !service.quiet && service.verbose) {
16812
16918
  printInfo("\nRecent container logs:");
16813
- console.log(healthCheck.logs);
16919
+ printInfo(healthCheck.logs);
16814
16920
  }
16815
16921
  }
16816
16922
  const isHealthy = healthCheck.containerRunning && (config.type !== "envoy" || healthCheck.adminHealthy);
@@ -16859,8 +16965,7 @@ Proxy service ${service.name} is healthy`);
16859
16965
  };
16860
16966
  preflightProxyCheck2 = async (context) => {
16861
16967
  return preflightFromChecks([
16862
- checkContainerRuntime(context.runtime),
16863
- checkCommandAvailable("curl")
16968
+ checkContainerRuntime(context.runtime)
16864
16969
  ]);
16865
16970
  };
16866
16971
  proxyCheckDescriptor2 = {
@@ -17440,11 +17545,11 @@ var init_platform3 = __esm({
17440
17545
  */
17441
17546
  detectContainerRuntime() {
17442
17547
  try {
17443
- execFileSync36("docker", ["version"], { stdio: "ignore" });
17548
+ execFileSync36("docker", ["--version"], { stdio: "ignore" });
17444
17549
  return "docker";
17445
17550
  } catch {
17446
17551
  try {
17447
- execFileSync36("podman", ["version"], { stdio: "ignore" });
17552
+ execFileSync36("podman", ["--version"], { stdio: "ignore" });
17448
17553
  return "podman";
17449
17554
  } catch {
17450
17555
  throw new Error("No container runtime (Docker or Podman) found");
@@ -18613,7 +18718,7 @@ var init_rds_start = __esm({
18613
18718
 
18614
18719
  // src/platforms/aws/handlers/stack-provision.ts
18615
18720
  import { spawnSync as spawnSync2 } from "child_process";
18616
- import * as path32 from "path";
18721
+ import * as path33 from "path";
18617
18722
  import * as fs43 from "fs";
18618
18723
  var provisionStackService, preflightStackProvision, stackProvisionDescriptor;
18619
18724
  var init_stack_provision = __esm({
@@ -18684,7 +18789,7 @@ var init_stack_provision = __esm({
18684
18789
  continue;
18685
18790
  }
18686
18791
  try {
18687
- const cdkContextPath = path32.join(projectRoot, "cdk.context.json");
18792
+ const cdkContextPath = path33.join(projectRoot, "cdk.context.json");
18688
18793
  const cdkContext = fs43.existsSync(cdkContextPath) ? JSON.parse(fs43.readFileSync(cdkContextPath, "utf-8")) : {};
18689
18794
  cdkContext[`availability-zones:account=${awsConfig.accountId}:region=${awsConfig.region}`] = cdkContext[`availability-zones:account=${awsConfig.accountId}:region=${awsConfig.region}`] || [`${awsConfig.region}a`, `${awsConfig.region}b`];
18690
18795
  fs43.writeFileSync(cdkContextPath, JSON.stringify(cdkContext, null, 2));
@@ -18788,7 +18893,7 @@ var init_stack_provision = __esm({
18788
18893
 
18789
18894
  // src/platforms/aws/handlers/ecs-publish.ts
18790
18895
  import { execFileSync as execFileSync41, spawnSync as spawnSync3 } from "child_process";
18791
- import * as path33 from "path";
18896
+ import * as path34 from "path";
18792
18897
  import * as fs44 from "fs";
18793
18898
  async function createNewTaskDefinition(service, imageUri, region, _accountId, cfnDiscoveredResources, resourceName) {
18794
18899
  if (!service || !imageUri) return "";
@@ -18945,7 +19050,7 @@ var init_ecs_publish = __esm({
18945
19050
  }
18946
19051
  }
18947
19052
  try {
18948
- const apiTypesPath = path33.join(buildContext, "packages", "api-types");
19053
+ const apiTypesPath = path34.join(buildContext, "packages", "api-types");
18949
19054
  if (fs44.existsSync(apiTypesPath)) {
18950
19055
  execFileSync41("npm", ["run", "build"], {
18951
19056
  cwd: apiTypesPath,
@@ -18953,7 +19058,7 @@ var init_ecs_publish = __esm({
18953
19058
  stdio: service.verbose ? "inherit" : "pipe"
18954
19059
  });
18955
19060
  }
18956
- const appPath = path33.join(buildContext, "apps", service.name);
19061
+ const appPath = path34.join(buildContext, "apps", service.name);
18957
19062
  if (fs44.existsSync(appPath)) {
18958
19063
  execFileSync41("npm", ["run", "build"], {
18959
19064
  cwd: appPath,
@@ -22001,17 +22106,17 @@ var init_headers = __esm({
22001
22106
  function encodeURIPath(str2) {
22002
22107
  return str2.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
22003
22108
  }
22004
- var EMPTY, createPathTagFunction, path34;
22109
+ var EMPTY, createPathTagFunction, path35;
22005
22110
  var init_path = __esm({
22006
22111
  "node_modules/@anthropic-ai/sdk/internal/utils/path.mjs"() {
22007
22112
  init_error();
22008
22113
  EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
22009
- createPathTagFunction = (pathEncoder = encodeURIPath) => function path46(statics, ...params) {
22114
+ createPathTagFunction = (pathEncoder = encodeURIPath) => function path47(statics, ...params) {
22010
22115
  if (statics.length === 1)
22011
22116
  return statics[0];
22012
22117
  let postPath = false;
22013
22118
  const invalidSegments = [];
22014
- const path47 = statics.reduce((previousValue, currentValue, index) => {
22119
+ const path48 = statics.reduce((previousValue, currentValue, index) => {
22015
22120
  if (/[?#]/.test(currentValue)) {
22016
22121
  postPath = true;
22017
22122
  }
@@ -22028,7 +22133,7 @@ var init_path = __esm({
22028
22133
  }
22029
22134
  return previousValue + currentValue + (index === params.length ? "" : encoded);
22030
22135
  }, "");
22031
- const pathOnly = path47.split(/[?#]/, 1)[0];
22136
+ const pathOnly = path48.split(/[?#]/, 1)[0];
22032
22137
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
22033
22138
  let match;
22034
22139
  while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -22049,12 +22154,12 @@ var init_path = __esm({
22049
22154
  }, "");
22050
22155
  throw new AnthropicError(`Path parameters result in path with invalid segments:
22051
22156
  ${invalidSegments.map((e) => e.error).join("\n")}
22052
- ${path47}
22157
+ ${path48}
22053
22158
  ${underline}`);
22054
22159
  }
22055
- return path47;
22160
+ return path48;
22056
22161
  };
22057
- path34 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
22162
+ path35 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
22058
22163
  }
22059
22164
  });
22060
22165
 
@@ -22102,7 +22207,7 @@ var init_files = __esm({
22102
22207
  */
22103
22208
  delete(fileID, params = {}, options) {
22104
22209
  const { betas } = params ?? {};
22105
- return this._client.delete(path34`/v1/files/${fileID}`, {
22210
+ return this._client.delete(path35`/v1/files/${fileID}`, {
22106
22211
  ...options,
22107
22212
  headers: buildHeaders([
22108
22213
  { "anthropic-beta": [...betas ?? [], "files-api-2025-04-14"].toString() },
@@ -22125,7 +22230,7 @@ var init_files = __esm({
22125
22230
  */
22126
22231
  download(fileID, params = {}, options) {
22127
22232
  const { betas } = params ?? {};
22128
- return this._client.get(path34`/v1/files/${fileID}/content`, {
22233
+ return this._client.get(path35`/v1/files/${fileID}/content`, {
22129
22234
  ...options,
22130
22235
  headers: buildHeaders([
22131
22236
  {
@@ -22148,7 +22253,7 @@ var init_files = __esm({
22148
22253
  */
22149
22254
  retrieveMetadata(fileID, params = {}, options) {
22150
22255
  const { betas } = params ?? {};
22151
- return this._client.get(path34`/v1/files/${fileID}`, {
22256
+ return this._client.get(path35`/v1/files/${fileID}`, {
22152
22257
  ...options,
22153
22258
  headers: buildHeaders([
22154
22259
  { "anthropic-beta": [...betas ?? [], "files-api-2025-04-14"].toString() },
@@ -22205,7 +22310,7 @@ var init_models = __esm({
22205
22310
  */
22206
22311
  retrieve(modelID, params = {}, options) {
22207
22312
  const { betas } = params ?? {};
22208
- return this._client.get(path34`/v1/models/${modelID}?beta=true`, {
22313
+ return this._client.get(path35`/v1/models/${modelID}?beta=true`, {
22209
22314
  ...options,
22210
22315
  headers: buildHeaders([
22211
22316
  { ...betas?.toString() != null ? { "anthropic-beta": betas?.toString() } : void 0 },
@@ -22358,7 +22463,7 @@ var init_batches = __esm({
22358
22463
  */
22359
22464
  retrieve(messageBatchID, params = {}, options) {
22360
22465
  const { betas } = params ?? {};
22361
- return this._client.get(path34`/v1/messages/batches/${messageBatchID}?beta=true`, {
22466
+ return this._client.get(path35`/v1/messages/batches/${messageBatchID}?beta=true`, {
22362
22467
  ...options,
22363
22468
  headers: buildHeaders([
22364
22469
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -22411,7 +22516,7 @@ var init_batches = __esm({
22411
22516
  */
22412
22517
  delete(messageBatchID, params = {}, options) {
22413
22518
  const { betas } = params ?? {};
22414
- return this._client.delete(path34`/v1/messages/batches/${messageBatchID}?beta=true`, {
22519
+ return this._client.delete(path35`/v1/messages/batches/${messageBatchID}?beta=true`, {
22415
22520
  ...options,
22416
22521
  headers: buildHeaders([
22417
22522
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -22443,7 +22548,7 @@ var init_batches = __esm({
22443
22548
  */
22444
22549
  cancel(messageBatchID, params = {}, options) {
22445
22550
  const { betas } = params ?? {};
22446
- return this._client.post(path34`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, {
22551
+ return this._client.post(path35`/v1/messages/batches/${messageBatchID}/cancel?beta=true`, {
22447
22552
  ...options,
22448
22553
  headers: buildHeaders([
22449
22554
  { "anthropic-beta": [...betas ?? [], "message-batches-2024-09-24"].toString() },
@@ -24347,7 +24452,7 @@ var init_batches2 = __esm({
24347
24452
  * ```
24348
24453
  */
24349
24454
  retrieve(messageBatchID, options) {
24350
- return this._client.get(path34`/v1/messages/batches/${messageBatchID}`, options);
24455
+ return this._client.get(path35`/v1/messages/batches/${messageBatchID}`, options);
24351
24456
  }
24352
24457
  /**
24353
24458
  * List all Message Batches within a Workspace. Most recently created batches are
@@ -24383,7 +24488,7 @@ var init_batches2 = __esm({
24383
24488
  * ```
24384
24489
  */
24385
24490
  delete(messageBatchID, options) {
24386
- return this._client.delete(path34`/v1/messages/batches/${messageBatchID}`, options);
24491
+ return this._client.delete(path35`/v1/messages/batches/${messageBatchID}`, options);
24387
24492
  }
24388
24493
  /**
24389
24494
  * Batches may be canceled any time before processing ends. Once cancellation is
@@ -24407,7 +24512,7 @@ var init_batches2 = __esm({
24407
24512
  * ```
24408
24513
  */
24409
24514
  cancel(messageBatchID, options) {
24410
- return this._client.post(path34`/v1/messages/batches/${messageBatchID}/cancel`, options);
24515
+ return this._client.post(path35`/v1/messages/batches/${messageBatchID}/cancel`, options);
24411
24516
  }
24412
24517
  /**
24413
24518
  * Streams the results of a Message Batch as a `.jsonl` file.
@@ -24534,7 +24639,7 @@ var init_models2 = __esm({
24534
24639
  */
24535
24640
  retrieve(modelID, params = {}, options) {
24536
24641
  const { betas } = params ?? {};
24537
- return this._client.get(path34`/v1/models/${modelID}`, {
24642
+ return this._client.get(path35`/v1/models/${modelID}`, {
24538
24643
  ...options,
24539
24644
  headers: buildHeaders([
24540
24645
  { ...betas?.toString() != null ? { "anthropic-beta": betas?.toString() } : void 0 },
@@ -24735,9 +24840,9 @@ var init_client = __esm({
24735
24840
  makeStatusError(status, error, message, headers) {
24736
24841
  return APIError.generate(status, error, message, headers);
24737
24842
  }
24738
- buildURL(path46, query, defaultBaseURL) {
24843
+ buildURL(path47, query, defaultBaseURL) {
24739
24844
  const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
24740
- const url = isAbsoluteURL(path46) ? new URL(path46) : new URL(baseURL + (baseURL.endsWith("/") && path46.startsWith("/") ? path46.slice(1) : path46));
24845
+ const url = isAbsoluteURL(path47) ? new URL(path47) : new URL(baseURL + (baseURL.endsWith("/") && path47.startsWith("/") ? path47.slice(1) : path47));
24741
24846
  const defaultQuery = this.defaultQuery();
24742
24847
  if (!isEmptyObj(defaultQuery)) {
24743
24848
  query = { ...defaultQuery, ...query };
@@ -24768,24 +24873,24 @@ var init_client = __esm({
24768
24873
  */
24769
24874
  async prepareRequest(request, { url, options }) {
24770
24875
  }
24771
- get(path46, opts) {
24772
- return this.methodRequest("get", path46, opts);
24876
+ get(path47, opts) {
24877
+ return this.methodRequest("get", path47, opts);
24773
24878
  }
24774
- post(path46, opts) {
24775
- return this.methodRequest("post", path46, opts);
24879
+ post(path47, opts) {
24880
+ return this.methodRequest("post", path47, opts);
24776
24881
  }
24777
- patch(path46, opts) {
24778
- return this.methodRequest("patch", path46, opts);
24882
+ patch(path47, opts) {
24883
+ return this.methodRequest("patch", path47, opts);
24779
24884
  }
24780
- put(path46, opts) {
24781
- return this.methodRequest("put", path46, opts);
24885
+ put(path47, opts) {
24886
+ return this.methodRequest("put", path47, opts);
24782
24887
  }
24783
- delete(path46, opts) {
24784
- return this.methodRequest("delete", path46, opts);
24888
+ delete(path47, opts) {
24889
+ return this.methodRequest("delete", path47, opts);
24785
24890
  }
24786
- methodRequest(method, path46, opts) {
24891
+ methodRequest(method, path47, opts) {
24787
24892
  return this.request(Promise.resolve(opts).then((opts2) => {
24788
- return { method, path: path46, ...opts2 };
24893
+ return { method, path: path47, ...opts2 };
24789
24894
  }));
24790
24895
  }
24791
24896
  request(options, remainingRetries = null) {
@@ -24889,8 +24994,8 @@ var init_client = __esm({
24889
24994
  }));
24890
24995
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
24891
24996
  }
24892
- getAPIList(path46, Page2, opts) {
24893
- return this.requestAPIList(Page2, { method: "get", path: path46, ...opts });
24997
+ getAPIList(path47, Page2, opts) {
24998
+ return this.requestAPIList(Page2, { method: "get", path: path47, ...opts });
24894
24999
  }
24895
25000
  requestAPIList(Page2, options) {
24896
25001
  const request = this.makeRequest(options, null, void 0);
@@ -24977,8 +25082,8 @@ var init_client = __esm({
24977
25082
  }
24978
25083
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
24979
25084
  const options = { ...inputOptions };
24980
- const { method, path: path46, query, defaultBaseURL } = options;
24981
- const url = this.buildURL(path46, query, defaultBaseURL);
25085
+ const { method, path: path47, query, defaultBaseURL } = options;
25086
+ const url = this.buildURL(path47, query, defaultBaseURL);
24982
25087
  if ("timeout" in options)
24983
25088
  validatePositiveInteger("timeout", options.timeout);
24984
25089
  options.timeout = options.timeout ?? this.timeout;
@@ -25730,7 +25835,7 @@ __export(config_loader_exports, {
25730
25835
  loadEnvironmentConfig: () => loadEnvironmentConfig
25731
25836
  });
25732
25837
  import * as fs45 from "fs";
25733
- import * as path35 from "path";
25838
+ import * as path36 from "path";
25734
25839
  import { createConfigLoader, listEnvironmentNames, ConfigurationError } from "@semiont/core";
25735
25840
  function findProjectRoot() {
25736
25841
  const root = process.env.SEMIONT_ROOT;
@@ -25748,8 +25853,8 @@ function findProjectRoot() {
25748
25853
  "Check that SEMIONT_ROOT environment variable is set correctly"
25749
25854
  );
25750
25855
  }
25751
- const hasSemiontJson = fs45.existsSync(path35.join(root, "semiont.json"));
25752
- const hasEnvironments = fs45.existsSync(path35.join(root, "environments"));
25856
+ const hasSemiontJson = fs45.existsSync(path36.join(root, "semiont.json"));
25857
+ const hasEnvironments = fs45.existsSync(path36.join(root, "environments"));
25753
25858
  if (!hasSemiontJson && !hasEnvironments) {
25754
25859
  throw new ConfigurationError(
25755
25860
  `SEMIONT_ROOT does not point to a valid Semiont project: ${root}`,
@@ -25762,7 +25867,7 @@ function findProjectRoot() {
25762
25867
  function getAvailableEnvironments() {
25763
25868
  try {
25764
25869
  const projectRoot = findProjectRoot();
25765
- const configDir = path35.join(projectRoot, "environments");
25870
+ const configDir = path36.join(projectRoot, "environments");
25766
25871
  if (!fs45.existsSync(configDir)) {
25767
25872
  return [];
25768
25873
  }
@@ -25781,11 +25886,11 @@ var init_config_loader = __esm({
25781
25886
  "use strict";
25782
25887
  nodeFileReader = {
25783
25888
  readIfExists: (filePath) => {
25784
- const absolutePath = path35.resolve(filePath);
25889
+ const absolutePath = path36.resolve(filePath);
25785
25890
  return fs45.existsSync(absolutePath) ? fs45.readFileSync(absolutePath, "utf-8") : null;
25786
25891
  },
25787
25892
  readRequired: (filePath) => {
25788
- const absolutePath = path35.resolve(filePath);
25893
+ const absolutePath = path36.resolve(filePath);
25789
25894
  if (!fs45.existsSync(absolutePath)) {
25790
25895
  throw new ConfigurationError(
25791
25896
  `Configuration file not found: ${absolutePath}`,
@@ -26945,7 +27050,7 @@ import express from "express";
26945
27050
  import { createServer as createServer4 } from "http";
26946
27051
  import { Server as SocketIOServer } from "socket.io";
26947
27052
  import { fileURLToPath as fileURLToPath2 } from "url";
26948
- import { dirname as dirname11, join as join35 } from "path";
27053
+ import { dirname as dirname11, join as join36 } from "path";
26949
27054
  import fs46 from "fs";
26950
27055
  var __filename, __dirname, embeddedJS, embeddedCSS, WebDashboardServer;
26951
27056
  var init_web_dashboard_server = __esm({
@@ -26996,15 +27101,15 @@ var init_web_dashboard_server = __esm({
26996
27101
  });
26997
27102
  } else {
26998
27103
  const possibleDirs = [
26999
- join35(__dirname, "..", "..", "..", "dist", "dashboard"),
27000
- join35(__dirname, "dashboard"),
27001
- join35(__dirname, "..", "dashboard"),
27002
- join35(process.cwd(), "dist", "dashboard"),
27003
- join35(process.cwd(), "apps", "cli", "dist", "dashboard")
27104
+ join36(__dirname, "..", "..", "..", "dist", "dashboard"),
27105
+ join36(__dirname, "dashboard"),
27106
+ join36(__dirname, "..", "dashboard"),
27107
+ join36(process.cwd(), "dist", "dashboard"),
27108
+ join36(process.cwd(), "apps", "cli", "dist", "dashboard")
27004
27109
  ];
27005
27110
  let distDir = null;
27006
27111
  for (const dir of possibleDirs) {
27007
- if (fs46.existsSync(join35(dir, "dashboard.js"))) {
27112
+ if (fs46.existsSync(join36(dir, "dashboard.js"))) {
27008
27113
  distDir = dir;
27009
27114
  bundleExists = true;
27010
27115
  console.log(`Found dashboard bundle at: ${dir}`);
@@ -27405,7 +27510,7 @@ var require_package = __commonJS({
27405
27510
  "package.json"(exports, module) {
27406
27511
  module.exports = {
27407
27512
  name: "@semiont/cli",
27408
- version: "0.3.1",
27513
+ version: "0.3.3",
27409
27514
  description: "Semiont CLI - Unified environment management tool",
27410
27515
  _comment: "AWS SDK dependencies (@aws-sdk/*) are only used by platforms/aws",
27411
27516
  type: "module",
@@ -27469,12 +27574,12 @@ var require_package = __commonJS({
27469
27574
  "@aws-sdk/client-secrets-manager": "^3.600.0",
27470
27575
  "@aws-sdk/client-sts": "^3.859.0",
27471
27576
  "@aws-sdk/client-wafv2": "^3.859.0",
27472
- "@semiont/api-client": "^0.3.1",
27473
- "@semiont/content": "^0.3.1",
27474
- "@semiont/core": "^0.3.1",
27475
- "@semiont/event-sourcing": "^0.3.1",
27476
- "@semiont/graph": "^0.3.1",
27477
- "@semiont/make-meaning": "^0.3.1",
27577
+ "@semiont/api-client": "^0.3.3",
27578
+ "@semiont/content": "^0.3.3",
27579
+ "@semiont/core": "^0.3.3",
27580
+ "@semiont/event-sourcing": "^0.3.3",
27581
+ "@semiont/graph": "^0.3.3",
27582
+ "@semiont/make-meaning": "^0.3.3",
27478
27583
  arg: "^5.0.2",
27479
27584
  argon2: "^0.43.0",
27480
27585
  express: "^4.18.2",
@@ -27515,7 +27620,7 @@ init_base_options_schema();
27515
27620
  init_cli_paths();
27516
27621
  init_preflight_utils();
27517
27622
  import * as fs2 from "fs";
27518
- import * as path2 from "path";
27623
+ import * as path3 from "path";
27519
27624
  var InitOptionsSchema = BaseOptionsSchema.extend({
27520
27625
  name: external_exports.string().optional(),
27521
27626
  directory: external_exports.string().optional(),
@@ -27536,12 +27641,12 @@ function getTemplatesDir2() {
27536
27641
  }
27537
27642
  function copyTemplate(source, dest, replacements) {
27538
27643
  const templatesDir = getTemplatesDir2();
27539
- const sourcePath = path2.join(templatesDir, source);
27644
+ const sourcePath = path3.join(templatesDir, source);
27540
27645
  if (fs2.statSync(sourcePath).isDirectory()) {
27541
27646
  fs2.mkdirSync(dest, { recursive: true });
27542
27647
  const files = fs2.readdirSync(sourcePath);
27543
27648
  for (const file of files) {
27544
- copyTemplate(path2.join(source, file), path2.join(dest, file), replacements);
27649
+ copyTemplate(path3.join(source, file), path3.join(dest, file), replacements);
27545
27650
  }
27546
27651
  } else {
27547
27652
  let content = fs2.readFileSync(sourcePath, "utf8");
@@ -27550,14 +27655,14 @@ function copyTemplate(source, dest, replacements) {
27550
27655
  content = content.replace(new RegExp(key, "g"), value);
27551
27656
  }
27552
27657
  }
27553
- fs2.mkdirSync(path2.dirname(dest), { recursive: true });
27658
+ fs2.mkdirSync(path3.dirname(dest), { recursive: true });
27554
27659
  fs2.writeFileSync(dest, content);
27555
27660
  }
27556
27661
  }
27557
27662
  async function init(options) {
27558
27663
  const startTime = Date.now();
27559
27664
  const projectDir = options.directory || process.cwd();
27560
- const projectName = options.name || path2.basename(projectDir);
27665
+ const projectName = options.name || path3.basename(projectDir);
27561
27666
  let environments = options.environments;
27562
27667
  if (environments.length === 1 && environments[0].includes(",")) {
27563
27668
  environments = environments[0].split(",").map((env) => env.trim());
@@ -27581,7 +27686,7 @@ async function init(options) {
27581
27686
  }
27582
27687
  };
27583
27688
  try {
27584
- const configPath = path2.join(projectDir, "semiont.json");
27689
+ const configPath = path3.join(projectDir, "semiont.json");
27585
27690
  if (fs2.existsSync(configPath) && !options.force) {
27586
27691
  throw new Error("semiont.json already exists. Use --force to overwrite.");
27587
27692
  }
@@ -27605,19 +27710,19 @@ async function init(options) {
27605
27710
  dryRun: true
27606
27711
  };
27607
27712
  } else {
27608
- copyTemplate("semiont.json", path2.join(projectDir, "semiont.json"), {
27713
+ copyTemplate("semiont.json", path3.join(projectDir, "semiont.json"), {
27609
27714
  "my-semiont-project": projectName
27610
27715
  });
27611
27716
  if (!options.quiet) {
27612
27717
  console.log(`${colors.green}\u2705 Created semiont.json${colors.reset}`);
27613
27718
  }
27614
- const envDir = path2.join(projectDir, "environments");
27719
+ const envDir = path3.join(projectDir, "environments");
27615
27720
  fs2.mkdirSync(envDir, { recursive: true });
27616
27721
  for (const envName of environments) {
27617
27722
  const templatesDir = getTemplatesDir2();
27618
- const templatePath = path2.join(templatesDir, "environments", `${envName}.json`);
27723
+ const templatePath = path3.join(templatesDir, "environments", `${envName}.json`);
27619
27724
  if (fs2.existsSync(templatePath)) {
27620
- copyTemplate(`environments/${envName}.json`, path2.join(envDir, `${envName}.json`));
27725
+ copyTemplate(`environments/${envName}.json`, path3.join(envDir, `${envName}.json`));
27621
27726
  if (!options.quiet) {
27622
27727
  console.log(`${colors.green}\u2705 Created environments/${envName}.json${colors.reset}`);
27623
27728
  }
@@ -27627,15 +27732,15 @@ async function init(options) {
27627
27732
  }
27628
27733
  }
27629
27734
  }
27630
- copyTemplate("cdk", path2.join(projectDir, "cdk"));
27631
- copyTemplate("package.json", path2.join(projectDir, "package.json"));
27632
- copyTemplate("tsconfig.json", path2.join(projectDir, "tsconfig.json"));
27633
- copyTemplate("cdk.json", path2.join(projectDir, "cdk.json"));
27735
+ copyTemplate("cdk", path3.join(projectDir, "cdk"));
27736
+ copyTemplate("package.json", path3.join(projectDir, "package.json"));
27737
+ copyTemplate("tsconfig.json", path3.join(projectDir, "tsconfig.json"));
27738
+ copyTemplate("cdk.json", path3.join(projectDir, "cdk.json"));
27634
27739
  if (!options.quiet) {
27635
27740
  console.log(`${colors.green}\u2705 Created CDK infrastructure files${colors.reset}`);
27636
27741
  }
27637
27742
  for (const envName of environments) {
27638
- const envFilePath = path2.join(envDir, `${envName}.json`);
27743
+ const envFilePath = path3.join(envDir, `${envName}.json`);
27639
27744
  if (fs2.existsSync(envFilePath)) {
27640
27745
  try {
27641
27746
  const envContent = JSON.parse(fs2.readFileSync(envFilePath, "utf8"));
@@ -27754,6 +27859,7 @@ var startDescriptor = createCommandDescriptor({
27754
27859
  serviceType
27755
27860
  }
27756
27861
  }, {
27862
+ status: handlerResult.success ? "running" : "unknown",
27757
27863
  startTime: startResult.startTime,
27758
27864
  endpoint: startResult.endpoint,
27759
27865
  resources: startResult.resources
@@ -27830,6 +27936,7 @@ var stopDescriptor = createCommandDescriptor({
27830
27936
  serviceType
27831
27937
  }
27832
27938
  }, {
27939
+ status: handlerResult.success ? "stopped" : "unknown",
27833
27940
  stop: {
27834
27941
  stopTime: stopResult.stopTime,
27835
27942
  graceful: stopResult.graceful
@@ -27897,7 +28004,8 @@ var ProvisionOptionsSchema = BaseOptionsSchema.extend({
27897
28004
  skipValidation: external_exports.boolean().default(false),
27898
28005
  skipDependencies: external_exports.boolean().default(false),
27899
28006
  destroy: external_exports.boolean().default(false),
27900
- semiontRepo: external_exports.string().optional()
28007
+ semiontRepo: external_exports.string().optional(),
28008
+ rotateSecret: external_exports.boolean().default(false)
27901
28009
  });
27902
28010
  var provisionDescriptor = createCommandDescriptor({
27903
28011
  name: "provision",
@@ -27958,6 +28066,9 @@ var provisionDescriptor = createCommandDescriptor({
27958
28066
  if (options.stack && options.all) {
27959
28067
  throw new Error("Cannot specify both --stack and --all");
27960
28068
  }
28069
+ if (options.rotateSecret && options.service && !["frontend", "backend"].includes(options.service)) {
28070
+ throw new Error("--rotate-secret only applies to frontend and backend services");
28071
+ }
27961
28072
  },
27962
28073
  continueOnError: true,
27963
28074
  // Continue provisioning all services even if one fails
@@ -28007,6 +28118,11 @@ var provisionCommand = new CommandBuilder().name("provision").description("Provi
28007
28118
  "--semiont-repo": {
28008
28119
  type: "string",
28009
28120
  description: "Path to semiont repository (for local development)"
28121
+ },
28122
+ "--rotate-secret": {
28123
+ type: "boolean",
28124
+ description: "Force generation of a new shared secret for frontend/backend (JWT_SECRET / NEXTAUTH_SECRET). Has no effect on other services. Warns if the peer service will be left out of sync.",
28125
+ default: false
28010
28126
  }
28011
28127
  },
28012
28128
  aliases: {
@@ -28541,10 +28657,10 @@ init_cli_logger();
28541
28657
  init_config_loader();
28542
28658
  import * as crypto3 from "crypto";
28543
28659
  import * as argon2 from "argon2";
28544
- import * as path36 from "path";
28660
+ import * as path37 from "path";
28545
28661
  import { createRequire as createRequire3 } from "module";
28546
28662
  function loadPrismaClient(projectRoot) {
28547
- const req = createRequire3(path36.join(projectRoot, "node_modules", ".package.json"));
28663
+ const req = createRequire3(path37.join(projectRoot, "node_modules", ".package.json"));
28548
28664
  try {
28549
28665
  const backendPkgPath = req.resolve("@semiont/backend/package.json");
28550
28666
  const backendReq = createRequire3(backendPkgPath);
@@ -28787,7 +28903,7 @@ init_base_options_schema();
28787
28903
  init_cli_logger();
28788
28904
  init_config_loader();
28789
28905
  import * as fs47 from "fs";
28790
- import * as path37 from "path";
28906
+ import * as path38 from "path";
28791
28907
  import { createEventStore } from "@semiont/event-sourcing";
28792
28908
  import { FilesystemRepresentationStore } from "@semiont/content";
28793
28909
  import { exportBackup } from "@semiont/make-meaning";
@@ -28818,7 +28934,7 @@ async function runBackup(options) {
28818
28934
  if (!baseUrl3) {
28819
28935
  throw new Error("services.backend.publicURL is required in environment config");
28820
28936
  }
28821
- const basePath = path37.isAbsolute(configuredPath) ? configuredPath : path37.resolve(projectRoot, configuredPath);
28937
+ const basePath = path38.isAbsolute(configuredPath) ? configuredPath : path38.resolve(projectRoot, configuredPath);
28822
28938
  const logger = createCliLogger(options.verbose ?? false);
28823
28939
  const eventStore = createEventStore(basePath, void 0, void 0, logger);
28824
28940
  const contentStore = new FilesystemRepresentationStore(
@@ -28826,7 +28942,7 @@ async function runBackup(options) {
28826
28942
  projectRoot,
28827
28943
  logger.child({ component: "representation-store" })
28828
28944
  );
28829
- const outPath = path37.resolve(options.out);
28945
+ const outPath = path38.resolve(options.out);
28830
28946
  if (!options.quiet) {
28831
28947
  printInfo(`Creating backup at ${outPath}`);
28832
28948
  }
@@ -28876,7 +28992,7 @@ init_base_options_schema();
28876
28992
  init_cli_logger();
28877
28993
  init_config_loader();
28878
28994
  import * as fs48 from "fs";
28879
- import * as path38 from "path";
28995
+ import * as path39 from "path";
28880
28996
  import { EventBus } from "@semiont/core";
28881
28997
  import { createEventStore as createEventStore2 } from "@semiont/event-sourcing";
28882
28998
  import { importBackup, Stower, createKnowledgeBase } from "@semiont/make-meaning";
@@ -28945,9 +29061,9 @@ async function runRestore(options) {
28945
29061
  if (!configuredPath) {
28946
29062
  throw new Error("services.filesystem.path is required in environment config");
28947
29063
  }
28948
- const basePath = path38.isAbsolute(configuredPath) ? configuredPath : path38.resolve(projectRoot, configuredPath);
29064
+ const basePath = path39.isAbsolute(configuredPath) ? configuredPath : path39.resolve(projectRoot, configuredPath);
28949
29065
  const logger = createCliLogger2(options.verbose ?? false);
28950
- const filePath = path38.resolve(options.file);
29066
+ const filePath = path39.resolve(options.file);
28951
29067
  if (!fs48.existsSync(filePath)) {
28952
29068
  throw new Error(`File not found: ${filePath}`);
28953
29069
  }
@@ -29012,7 +29128,7 @@ init_command_definition();
29012
29128
  init_base_options_schema();
29013
29129
  init_cli_logger();
29014
29130
  import * as fs49 from "fs";
29015
- import * as path39 from "path";
29131
+ import * as path40 from "path";
29016
29132
  import { isBackupManifest, validateManifestVersion, BACKUP_FORMAT } from "@semiont/make-meaning";
29017
29133
  import { createGunzip } from "node:zlib";
29018
29134
  var BLOCK_SIZE = 512;
@@ -29049,7 +29165,7 @@ var VerifyOptionsSchema = BaseOptionsSchema.extend({
29049
29165
  });
29050
29166
  async function runVerify(options) {
29051
29167
  const startTime = Date.now();
29052
- const filePath = path39.resolve(options.file);
29168
+ const filePath = path40.resolve(options.file);
29053
29169
  if (!fs49.existsSync(filePath)) {
29054
29170
  throw new Error(`File not found: ${filePath}`);
29055
29171
  }
@@ -29186,7 +29302,7 @@ init_base_options_schema();
29186
29302
  init_cli_logger();
29187
29303
  init_config_loader();
29188
29304
  import * as fs50 from "fs";
29189
- import * as path40 from "path";
29305
+ import * as path41 from "path";
29190
29306
  import { createEventStore as createEventStore3 } from "@semiont/event-sourcing";
29191
29307
  import { FilesystemRepresentationStore as FilesystemRepresentationStore2 } from "@semiont/content";
29192
29308
  import { exportLinkedData } from "@semiont/make-meaning";
@@ -29219,7 +29335,7 @@ async function runExport(options) {
29219
29335
  if (!baseUrl3) {
29220
29336
  throw new Error("services.backend.publicURL is required in environment config");
29221
29337
  }
29222
- const basePath = path40.isAbsolute(configuredPath) ? configuredPath : path40.resolve(projectRoot, configuredPath);
29338
+ const basePath = path41.isAbsolute(configuredPath) ? configuredPath : path41.resolve(projectRoot, configuredPath);
29223
29339
  const logger = createCliLogger3(options.verbose ?? false);
29224
29340
  const eventStore = createEventStore3(basePath, void 0, void 0, logger);
29225
29341
  const contentStore = new FilesystemRepresentationStore2(
@@ -29231,7 +29347,7 @@ async function runExport(options) {
29231
29347
  services: { filesystem: envConfig.services.filesystem },
29232
29348
  _metadata: { projectRoot }
29233
29349
  });
29234
- const outPath = path40.resolve(options.out);
29350
+ const outPath = path41.resolve(options.out);
29235
29351
  if (!options.quiet) {
29236
29352
  printInfo(`Exporting knowledge base as JSON-LD to ${outPath}`);
29237
29353
  if (options.includeArchived) {
@@ -29295,7 +29411,7 @@ init_base_options_schema();
29295
29411
  init_cli_logger();
29296
29412
  init_config_loader();
29297
29413
  import * as fs51 from "fs";
29298
- import * as path41 from "path";
29414
+ import * as path42 from "path";
29299
29415
  import { EventBus as EventBus2 } from "@semiont/core";
29300
29416
  import { createEventStore as createEventStore4 } from "@semiont/event-sourcing";
29301
29417
  import { importLinkedData, Stower as Stower2, createKnowledgeBase as createKnowledgeBase2 } from "@semiont/make-meaning";
@@ -29365,9 +29481,9 @@ async function runImport(options) {
29365
29481
  if (!configuredPath) {
29366
29482
  throw new Error("services.filesystem.path is required in environment config");
29367
29483
  }
29368
- const basePath = path41.isAbsolute(configuredPath) ? configuredPath : path41.resolve(projectRoot, configuredPath);
29484
+ const basePath = path42.isAbsolute(configuredPath) ? configuredPath : path42.resolve(projectRoot, configuredPath);
29369
29485
  const logger = createCliLogger4(options.verbose ?? false);
29370
- const filePath = path41.resolve(options.file);
29486
+ const filePath = path42.resolve(options.file);
29371
29487
  if (!fs51.existsSync(filePath)) {
29372
29488
  throw new Error(`File not found: ${filePath}`);
29373
29489
  }
@@ -29439,7 +29555,7 @@ init_cli_colors();
29439
29555
  init_command_definition();
29440
29556
  init_base_options_schema();
29441
29557
  import * as fs52 from "fs";
29442
- import * as path42 from "path";
29558
+ import * as path43 from "path";
29443
29559
  import * as readline from "readline";
29444
29560
  import { execFileSync as execFileSync44 } from "child_process";
29445
29561
  var LocalOptionsSchema = BaseOptionsSchema.extend({
@@ -29538,11 +29654,11 @@ function parseCheckOutput(jsonOutput) {
29538
29654
  function isProvisioned(serviceName, semiotRoot) {
29539
29655
  switch (serviceName) {
29540
29656
  case "backend":
29541
- return fs52.existsSync(path42.join(semiotRoot, "backend", ".env"));
29657
+ return fs52.existsSync(path43.join(semiotRoot, "backend", ".env"));
29542
29658
  case "frontend":
29543
- return fs52.existsSync(path42.join(semiotRoot, "frontend", ".env"));
29659
+ return fs52.existsSync(path43.join(semiotRoot, "frontend", ".env"));
29544
29660
  case "filesystem":
29545
- return fs52.existsSync(path42.join(semiotRoot, "data"));
29661
+ return fs52.existsSync(path43.join(semiotRoot, "data"));
29546
29662
  case "database":
29547
29663
  case "proxy":
29548
29664
  // For these, rely on check result only — we don't have a simple local sentinel
@@ -29573,7 +29689,7 @@ ${colors.bright}\u{1F310} Semiont Local Setup${colors.reset}
29573
29689
  try {
29574
29690
  let semiotRoot = process.env.SEMIONT_ROOT || "";
29575
29691
  if (!semiotRoot) {
29576
- const defaultPath = path42.join(process.env.HOME || process.cwd(), "semiont");
29692
+ const defaultPath = path43.join(process.env.HOME || process.cwd(), "semiont");
29577
29693
  const answer = await prompt(
29578
29694
  `${colors.cyan}SEMIONT_ROOT is not set.${colors.reset}
29579
29695
  Press Enter to use ${colors.bright}${defaultPath}${colors.reset}, or type a path: `
@@ -29600,8 +29716,8 @@ Press Enter to use ${colors.bright}${defaultPath}${colors.reset}, or type a path
29600
29716
  `);
29601
29717
  }
29602
29718
  const env = { ...process.env };
29603
- const semiontJsonPath = path42.join(semiotRoot, "semiont.json");
29604
- const envFilePath = path42.join(semiotRoot, "environments", `${semiotEnv}.json`);
29719
+ const semiontJsonPath = path43.join(semiotRoot, "semiont.json");
29720
+ const envFilePath = path43.join(semiotRoot, "environments", `${semiotEnv}.json`);
29605
29721
  const isInitialized = fs52.existsSync(semiontJsonPath) && fs52.existsSync(envFilePath);
29606
29722
  if (isInitialized) {
29607
29723
  console.log(`${colors.green}\u2713${colors.reset} Project already initialized
@@ -29681,7 +29797,7 @@ Press Enter to use ${colors.bright}${defaultPath}${colors.reset}, or type a path
29681
29797
  }
29682
29798
  }
29683
29799
  console.log("");
29684
- const credentialsPath = path42.join(semiotRoot, "credentials.txt");
29800
+ const credentialsPath = path43.join(semiotRoot, "credentials.txt");
29685
29801
  if (fs52.existsSync(credentialsPath)) {
29686
29802
  console.log(`${colors.green}\u2713${colors.reset} Credentials file already exists at ${credentialsPath}
29687
29803
  `);
@@ -29837,7 +29953,7 @@ function isCommandDefinition(obj) {
29837
29953
 
29838
29954
  // src/core/service-discovery.ts
29839
29955
  init_config_loader();
29840
- import * as path43 from "path";
29956
+ import * as path44 from "path";
29841
29957
  import * as fs53 from "fs";
29842
29958
  var BUILT_IN_SERVICES = ["frontend", "backend", "database", "filesystem"];
29843
29959
  var environmentServicesCache = /* @__PURE__ */ new Map();
@@ -29847,7 +29963,7 @@ async function loadEnvironmentServices(environment) {
29847
29963
  }
29848
29964
  try {
29849
29965
  const PROJECT_ROOT = findProjectRoot();
29850
- const configPath = path43.join(PROJECT_ROOT, "environments", `${environment}.json`);
29966
+ const configPath = path44.join(PROJECT_ROOT, "environments", `${environment}.json`);
29851
29967
  if (!fs53.existsSync(configPath)) {
29852
29968
  return [...BUILT_IN_SERVICES];
29853
29969
  }
@@ -29882,7 +29998,7 @@ async function isValidService(service, environment) {
29882
29998
  import { parseEnvironment as parseEnvironment2 } from "@semiont/core";
29883
29999
 
29884
30000
  // src/core/service-resolver.ts
29885
- import * as path44 from "path";
30001
+ import * as path45 from "path";
29886
30002
  import { ConfigurationError as ConfigurationError2 } from "@semiont/core";
29887
30003
  function getServicePlatform(serviceName, config) {
29888
30004
  const environment = config._metadata?.environment;
@@ -29930,7 +30046,7 @@ function resolveServiceDeployments(serviceNames, config) {
29930
30046
  const serviceConfig = config.services?.[serviceName];
29931
30047
  if (!serviceConfig) {
29932
30048
  const availableServices = Object.keys(config.services || {});
29933
- const configPath = path44.join(projectRoot, "environments", `${environment}.json`);
30049
+ const configPath = path45.join(projectRoot, "environments", `${environment}.json`);
29934
30050
  console.warn(`\u274C Service '${serviceName}' not found in environment '${environment}'`);
29935
30051
  if (availableServices.length > 0) {
29936
30052
  console.warn(` Available services: ${availableServices.join(", ")}`);
@@ -29969,7 +30085,7 @@ function resolveServiceDeployments(serviceNames, config) {
29969
30085
  // src/core/command-service-matcher.ts
29970
30086
  init_service_factory();
29971
30087
  init_service_command_capabilities();
29972
- import * as path45 from "path";
30088
+ import * as path46 from "path";
29973
30089
  async function checkServiceSupportsCommand(serviceName, command, envConfig) {
29974
30090
  try {
29975
30091
  const projectRoot = envConfig._metadata?.projectRoot;
@@ -30053,7 +30169,7 @@ async function resolveServiceSelector(selector, capability, envConfig) {
30053
30169
  if (!projectRoot) {
30054
30170
  throw new Error("Project root is required in envConfig._metadata");
30055
30171
  }
30056
- const configPath = path45.join(projectRoot, "environments", `${environment}.json`);
30172
+ const configPath = path46.join(projectRoot, "environments", `${environment}.json`);
30057
30173
  const errorMessage = [
30058
30174
  `Unknown service '${selector}' in environment '${environment}'`,
30059
30175
  `Available services: ${availableServices.join(", ")}`,
@@ -30549,14 +30665,14 @@ var OutputFormatter = class {
30549
30665
  /**
30550
30666
  * Get nested value from object using dot notation
30551
30667
  */
30552
- static getNestedValue(obj, path46) {
30553
- return path46.split(".").reduce((current, key) => current?.[key], obj);
30668
+ static getNestedValue(obj, path47) {
30669
+ return path47.split(".").reduce((current, key) => current?.[key], obj);
30554
30670
  }
30555
30671
  /**
30556
30672
  * Set nested value in object using dot notation
30557
30673
  */
30558
- static setNestedValue(obj, path46, value) {
30559
- const keys = path46.split(".");
30674
+ static setNestedValue(obj, path47, value) {
30675
+ const keys = path47.split(".");
30560
30676
  const lastKey = keys.pop();
30561
30677
  const target = keys.reduce((current, key) => {
30562
30678
  if (!(key in current)) {
@@ -30714,6 +30830,16 @@ function printPreamble(options) {
30714
30830
  console.log(getPreamble(version));
30715
30831
  console.log(getPreambleSeparator());
30716
30832
  }
30833
+ function printVerboseEnv(options) {
30834
+ if (!options.verbose) return;
30835
+ const vars = ["SEMIONT_ROOT", "SEMIONT_ENV", "SEMIONT_REPO"];
30836
+ for (const v of vars) {
30837
+ const val = process.env[v];
30838
+ if (val !== void 0) {
30839
+ printInfo(`${v}=${val}`);
30840
+ }
30841
+ }
30842
+ }
30717
30843
  async function executeCommand(commandName, argv) {
30718
30844
  try {
30719
30845
  const command = await loadCommand(commandName);
@@ -30766,6 +30892,7 @@ async function executeCommand(commandName, argv) {
30766
30892
  }
30767
30893
  }
30768
30894
  printPreamble(options);
30895
+ printVerboseEnv(options);
30769
30896
  if (command.requiresEnvironment) {
30770
30897
  if (!options.environment) {
30771
30898
  const envFromVariable = process.env.SEMIONT_ENV;