devchain-cli 0.12.2 → 0.12.4

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.
Files changed (78) hide show
  1. package/README.md +4 -0
  2. package/dist/cli.js +207 -40
  3. package/dist/server/common/config/env.config.d.ts +1 -1
  4. package/dist/server/common/config/env.config.js +9 -1
  5. package/dist/server/common/config/env.config.js.map +1 -1
  6. package/dist/server/common/config/host-helpers.d.ts +7 -0
  7. package/dist/server/common/config/host-helpers.js +34 -0
  8. package/dist/server/common/config/host-helpers.js.map +1 -0
  9. package/dist/server/main.js +5 -3
  10. package/dist/server/main.js.map +1 -1
  11. package/dist/server/modules/core/core-normal.module.js +3 -2
  12. package/dist/server/modules/core/core-normal.module.js.map +1 -1
  13. package/dist/server/modules/core/services/gemini-trusted-folders.service.d.ts +26 -0
  14. package/dist/server/modules/core/services/gemini-trusted-folders.service.js +181 -0
  15. package/dist/server/modules/core/services/gemini-trusted-folders.service.js.map +1 -0
  16. package/dist/server/modules/core/services/preflight.service.js +2 -1
  17. package/dist/server/modules/core/services/preflight.service.js.map +1 -1
  18. package/dist/server/modules/core/services/provider-mcp-ensure.service.d.ts +10 -1
  19. package/dist/server/modules/core/services/provider-mcp-ensure.service.js +86 -19
  20. package/dist/server/modules/core/services/provider-mcp-ensure.service.js.map +1 -1
  21. package/dist/server/modules/events/catalog/epic.created.d.ts +2 -2
  22. package/dist/server/modules/events/catalog/index.d.ts +2 -2
  23. package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +4 -4
  24. package/dist/server/modules/mcp/services/mcp-provider-registration.service.d.ts +1 -0
  25. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js +91 -4
  26. package/dist/server/modules/mcp/services/mcp-provider-registration.service.js.map +1 -1
  27. package/dist/server/modules/projects/controllers/projects.controller.d.ts +4 -1
  28. package/dist/server/modules/projects/controllers/projects.controller.js +1 -1
  29. package/dist/server/modules/projects/controllers/projects.controller.js.map +1 -1
  30. package/dist/server/modules/projects/projects.module.js +11 -2
  31. package/dist/server/modules/projects/projects.module.js.map +1 -1
  32. package/dist/server/modules/projects/services/project-provider-provisioning.service.d.ts +18 -0
  33. package/dist/server/modules/projects/services/project-provider-provisioning.service.js +92 -0
  34. package/dist/server/modules/projects/services/project-provider-provisioning.service.js.map +1 -0
  35. package/dist/server/modules/projects/services/projects.service.d.ts +9 -2
  36. package/dist/server/modules/projects/services/projects.service.js +31 -4
  37. package/dist/server/modules/projects/services/projects.service.js.map +1 -1
  38. package/dist/server/modules/providers/adapters/gemini.adapter.d.ts +5 -0
  39. package/dist/server/modules/providers/adapters/gemini.adapter.js +9 -3
  40. package/dist/server/modules/providers/adapters/gemini.adapter.js.map +1 -1
  41. package/dist/server/modules/providers/adapters/provider-adapter.factory.d.ts +4 -1
  42. package/dist/server/modules/providers/adapters/provider-adapter.factory.js +28 -2
  43. package/dist/server/modules/providers/adapters/provider-adapter.factory.js.map +1 -1
  44. package/dist/server/modules/providers/adapters/provider-adapter.interface.d.ts +6 -0
  45. package/dist/server/modules/providers/adapters/provider-adapters.module.js +2 -0
  46. package/dist/server/modules/providers/adapters/provider-adapters.module.js.map +1 -1
  47. package/dist/server/modules/providers/controllers/providers.controller.d.ts +1 -0
  48. package/dist/server/modules/providers/controllers/providers.controller.js +1 -0
  49. package/dist/server/modules/providers/controllers/providers.controller.js.map +1 -1
  50. package/dist/server/modules/sessions/services/sessions-message-pool.service.d.ts +3 -1
  51. package/dist/server/modules/sessions/services/sessions-message-pool.service.js +9 -2
  52. package/dist/server/modules/sessions/services/sessions-message-pool.service.js.map +1 -1
  53. package/dist/server/modules/sessions/services/sessions.service.js +16 -2
  54. package/dist/server/modules/sessions/services/sessions.service.js.map +1 -1
  55. package/dist/server/modules/terminal/services/confirmed-delivery.helper.d.ts +1 -0
  56. package/dist/server/modules/terminal/services/confirmed-delivery.helper.js +6 -1
  57. package/dist/server/modules/terminal/services/confirmed-delivery.helper.js.map +1 -1
  58. package/dist/server/modules/terminal/services/tmux.service.d.ts +1 -0
  59. package/dist/server/modules/terminal/services/tmux.service.js +16 -3
  60. package/dist/server/modules/terminal/services/tmux.service.js.map +1 -1
  61. package/dist/server/templates/3-agents-dev.json +111 -64
  62. package/dist/server/templates/5-agents-dev.json +152 -105
  63. package/dist/server/templates/teams-dev.json +155 -104
  64. package/dist/server/test-setup-node.js +7 -1
  65. package/dist/server/test-setup-node.js.map +1 -1
  66. package/dist/server/test-setup.js +7 -1
  67. package/dist/server/test-setup.js.map +1 -1
  68. package/dist/server/tsconfig.tsbuildinfo +1 -1
  69. package/dist/server/ui/assets/{ReviewDetailPage-D0vzq3rI.js → ReviewDetailPage-CoOg-QZq.js} +1 -1
  70. package/dist/server/ui/assets/{ReviewsPage-aX6m8vW_.js → ReviewsPage-DVBA6KIu.js} +1 -1
  71. package/dist/server/ui/assets/{index-BzphIngp.css → index-D6-SAeCU.css} +1 -1
  72. package/dist/server/ui/assets/{index-Cut7Gl_8.js → index-DylwMbnX.js} +223 -218
  73. package/dist/server/ui/assets/{useReviewSubscription-CrgRqMXe.js → useReviewSubscription-CnFCUxkN.js} +1 -1
  74. package/dist/server/ui/index.html +2 -2
  75. package/dist/templates/3-agents-dev.json +111 -64
  76. package/dist/templates/5-agents-dev.json +152 -105
  77. package/dist/templates/teams-dev.json +155 -104
  78. package/package.json +19 -3
package/README.md CHANGED
@@ -89,6 +89,9 @@ devchain start --project /path/to/your/project
89
89
  # Run in foreground with logs
90
90
  devchain start --foreground
91
91
 
92
+ # Bind to all interfaces for VM/remote browser access (prints loud security warning)
93
+ devchain start --host 0.0.0.0
94
+
92
95
  # Stop the server
93
96
  devchain stop
94
97
  ```
@@ -108,6 +111,7 @@ On first run, import a template from the project page to provision your agent te
108
111
  | Option | Description |
109
112
  |--------|-------------|
110
113
  | `-p, --port <number>` | Port to run on (default: 3000 or next available) |
114
+ | `--host <address>` | Bind address (default: `127.0.0.1`; use `0.0.0.0` for remote/VM access — see [docs/setup.md](docs/setup.md)) |
111
115
  | `-f, --foreground` | Run in foreground with visible logs |
112
116
  | `--no-open` | Don't open browser automatically |
113
117
  | `--db <path>` | Custom database directory path |
package/dist/cli.js CHANGED
@@ -62,6 +62,87 @@ function isNewerVersion(latest, current) {
62
62
  return false;
63
63
  }
64
64
 
65
+ // ── Host normalization + URL builder helpers ──────────────────────────────────
66
+
67
+ function normalizeHost(input) {
68
+ const raw = input ?? '';
69
+
70
+ // Check for control characters before trimming (trim strips \n, \t, etc.)
71
+ for (let i = 0; i < raw.length; i++) {
72
+ const code = raw.charCodeAt(i);
73
+ if (code < 0x20 || code === 0x7f) {
74
+ throw new Error(`Invalid host: contains control characters`);
75
+ }
76
+ }
77
+
78
+ const trimmed = raw.trim();
79
+ if (!trimmed) return '127.0.0.1';
80
+
81
+ if (/^https?:\/\//i.test(trimmed)) {
82
+ throw new Error(`Invalid host "${trimmed}": pass a hostname or IP, not a URL`);
83
+ }
84
+
85
+ if (trimmed === '*') {
86
+ throw new Error(
87
+ 'Invalid host "*": use 0.0.0.0 for all IPv4 interfaces or :: for all IPv6 interfaces',
88
+ );
89
+ }
90
+
91
+ if (/^\[.*\]$/.test(trimmed)) {
92
+ const inner = trimmed.slice(1, -1);
93
+ throw new Error(`Invalid host "${trimmed}": drop the brackets — use ${inner}`);
94
+ }
95
+
96
+ // Distinguish IPv6 from host:port — IPv6 has 2+ colons or starts with : or contains ::
97
+ const colonCount = (trimmed.match(/:/g) || []).length;
98
+ const looksLikeIpv6 = colonCount >= 2 || trimmed.startsWith(':') || trimmed.includes('::');
99
+
100
+ if (!looksLikeIpv6 && colonCount === 1) {
101
+ throw new Error(
102
+ `Invalid host "${trimmed}": looks like host:port — pass only the host part`,
103
+ );
104
+ }
105
+
106
+ return trimmed;
107
+ }
108
+
109
+ function isWildcardHost(host) {
110
+ return host === '0.0.0.0' || host === '::';
111
+ }
112
+
113
+ function isNonLoopbackHost(host) {
114
+ if (isWildcardHost(host)) return true;
115
+ const lower = host.toLowerCase();
116
+ return lower !== '127.0.0.1' && lower !== '::1' && lower !== 'localhost';
117
+ }
118
+
119
+ function connectableHost(host) {
120
+ if (host === '0.0.0.0') return '127.0.0.1';
121
+ if (host === '::') return '::1';
122
+ return host;
123
+ }
124
+
125
+ function formatHostForUrl(host) {
126
+ if (/^\[.*\]$/.test(host)) {
127
+ throw new Error(`formatHostForUrl received already-bracketed input: ${host}`);
128
+ }
129
+ // IPv6 detection: contains colon(s)
130
+ if (host.includes(':')) return `[${host}]`;
131
+ return host;
132
+ }
133
+
134
+ function buildInternalBaseUrl({ host, port }) {
135
+ return `http://${formatHostForUrl(connectableHost(host))}:${port}`;
136
+ }
137
+
138
+ function buildDisplayUrls({ host, port }) {
139
+ return {
140
+ primary: buildInternalBaseUrl({ host, port }),
141
+ };
142
+ }
143
+
144
+ // ── End host helpers ──────────────────────────────────────────────────────────
145
+
65
146
  function getChangelogBetweenVersions(changelog, fromVersion, toVersion) {
66
147
  if (!changelog || typeof changelog !== 'object') return [];
67
148
 
@@ -486,7 +567,7 @@ function resolveDevchainApiBaseUrlForRestart({
486
567
  );
487
568
  }
488
569
 
489
- return `http://127.0.0.1:${port}`;
570
+ return buildInternalBaseUrl({ host: pidData.host || '127.0.0.1', port });
490
571
  }
491
572
 
492
573
  function normalizeWorktreeListPayload(payload) {
@@ -956,9 +1037,9 @@ function getPidFilePath() {
956
1037
  return join(devchainDir, 'devchain.pid');
957
1038
  }
958
1039
 
959
- function writePidFile(port) {
1040
+ function writePidFile(port, host) {
960
1041
  const pidFile = getPidFilePath();
961
- const data = JSON.stringify({ pid: process.pid, port, timestamp: Date.now() });
1042
+ const data = JSON.stringify({ pid: process.pid, port, host: host || '127.0.0.1', timestamp: Date.now() });
962
1043
  writeFileSync(pidFile, data, 'utf8');
963
1044
  }
964
1045
 
@@ -969,7 +1050,9 @@ function readPidFile() {
969
1050
  }
970
1051
  try {
971
1052
  const data = readFileSync(pidFile, 'utf8');
972
- return JSON.parse(data);
1053
+ const parsed = JSON.parse(data);
1054
+ if (parsed && !parsed.host) parsed.host = '127.0.0.1';
1055
+ return parsed;
973
1056
  } catch {
974
1057
  return null;
975
1058
  }
@@ -1287,6 +1370,7 @@ async function main(argv) {
1287
1370
  .command('start [args...]')
1288
1371
  .description('Start the Devchain local app')
1289
1372
  .option('-p, --port <number>', 'Port to listen on (default: 3000 or next free)')
1373
+ .option('--host <address>', 'Host/bind address (default: 127.0.0.1; use 0.0.0.0 for all IPv4 interfaces, :: for all IPv6)')
1290
1374
  .option('-f, --foreground', 'Run in foreground (attached to terminal). Shows startup output with colors and spinners.')
1291
1375
  .option('-d, --detach', 'Run in background as a detached process (default). Use "devchain stop" to stop it.')
1292
1376
  .option('--no-open', 'Do not open a browser window')
@@ -1337,7 +1421,7 @@ async function main(argv) {
1337
1421
  const existingPid = readPidFile();
1338
1422
  if (existingPid && isProcessRunning(existingPid.pid)) {
1339
1423
  console.error(`Devchain is already running (PID ${existingPid.pid}, port ${existingPid.port})`);
1340
- console.error(`Access it at: http://127.0.0.1:${existingPid.port}`);
1424
+ console.error(`Access it at: ${buildDisplayUrls({ host: existingPid.host || '127.0.0.1', port: existingPid.port }).primary}`);
1341
1425
  console.error('Use "devchain stop" to stop it first.');
1342
1426
  process.exit(1);
1343
1427
  }
@@ -1435,6 +1519,35 @@ async function main(argv) {
1435
1519
  port = await getPort({ port: preferPort });
1436
1520
  }
1437
1521
 
1522
+ // Resolve effective host before detach so child inherits normalized HOST env.
1523
+ // The --host flag also flows through childArgs (detach filter only strips --port
1524
+ // and --detach), so the child receives the effective host via two independent paths.
1525
+ let effectiveHost;
1526
+ try {
1527
+ effectiveHost = normalizeHost(opts.host ?? process.env.HOST ?? '');
1528
+ } catch (e) {
1529
+ console.error(e.message);
1530
+ process.exit(1);
1531
+ }
1532
+ process.env.HOST = effectiveHost;
1533
+
1534
+ // Security warning for non-loopback bind (before detach so parent terminal sees it)
1535
+ if (!worktreeRuntimeMode && isNonLoopbackHost(effectiveHost)) {
1536
+ console.error('');
1537
+ console.error(`⚠ DevChain is binding to ${effectiveHost}. There is no remote authentication`);
1538
+ console.error(' boundary; the API, terminals, MCP, and project files are exposed');
1539
+ console.error(' to anyone who can reach this address. Use only on a trusted');
1540
+ console.error(' network, VPN, or behind firewall rules.');
1541
+ if (opts.dev) {
1542
+ console.error('');
1543
+ console.error(' Note: --dev mode runs the UI on a separate Vite dev server bound to');
1544
+ console.error(' 127.0.0.1 only. Remote access affects the API server only. For full');
1545
+ console.error(' remote access including the UI dev server, use production mode');
1546
+ console.error(' (no --dev flag).');
1547
+ }
1548
+ console.error('');
1549
+ }
1550
+
1438
1551
  // === DETACH POINT ===
1439
1552
  // All interactive prompts are done. Now spawn the detached child if needed.
1440
1553
  if (shouldDetach) {
@@ -1473,9 +1586,8 @@ async function main(argv) {
1473
1586
  process.exit(0);
1474
1587
  }
1475
1588
 
1476
- // Apply env before requiring the server
1589
+ // Apply env before requiring the server (HOST already set pre-detach)
1477
1590
  process.env.PORT = String(port);
1478
- process.env.HOST = process.env.HOST || '127.0.0.1';
1479
1591
  process.env.NODE_ENV = process.env.NODE_ENV || 'production';
1480
1592
  const dbEnv = parseDbPath(opts.db);
1481
1593
  if (dbEnv.DB_PATH) process.env.DB_PATH = dbEnv.DB_PATH;
@@ -1505,20 +1617,36 @@ async function main(argv) {
1505
1617
  cli.info('Starting API (dev mode)...');
1506
1618
  cli.blank();
1507
1619
 
1508
- // Helper to kill process group (all children)
1509
- const killProcessGroup = (proc) => {
1620
+ // Signal entire process group (all children). On Unix, a negative PID
1621
+ // targets the PG; on Windows we fall back to signalling the child directly.
1622
+ const signalProcessGroup = (proc, signal) => {
1510
1623
  if (!proc || !proc.pid) return;
1511
1624
  try {
1512
- // On Unix, negative PID kills the entire process group
1513
1625
  if (platform() !== 'win32') {
1514
- process.kill(-proc.pid, 'SIGTERM');
1626
+ process.kill(-proc.pid, signal);
1515
1627
  } else {
1516
- proc.kill('SIGTERM');
1628
+ proc.kill(signal);
1517
1629
  }
1518
1630
  } catch (e) {
1519
1631
  // Process may already be dead
1520
1632
  }
1521
1633
  };
1634
+ const killProcessGroup = (proc) => signalProcessGroup(proc, 'SIGTERM');
1635
+
1636
+ // Resolve when the child process emits 'exit' (or immediately if it
1637
+ // already exited). Lets cleanup await actual termination.
1638
+ const waitForExit = (proc) => new Promise((resolve) => {
1639
+ if (!proc || proc.exitCode !== null || proc.signalCode !== null) {
1640
+ resolve();
1641
+ return;
1642
+ }
1643
+ proc.once('exit', () => resolve());
1644
+ });
1645
+
1646
+ const waitWithTimeout = (promise, ms) => Promise.race([
1647
+ promise,
1648
+ new Promise((resolve) => setTimeout(resolve, ms)),
1649
+ ]);
1522
1650
 
1523
1651
  // Spawn NestJS in watch mode (detached to create process group)
1524
1652
  const devSpawnConfig = getDevModeSpawnConfig({
@@ -1534,10 +1662,11 @@ async function main(argv) {
1534
1662
  detached: platform() !== 'win32', // Create process group on Unix
1535
1663
  });
1536
1664
 
1537
- const baseUrl = `http://${process.env.HOST}:${port}`;
1665
+ const internalBaseUrl = buildInternalBaseUrl({ host: effectiveHost, port });
1666
+ const displayUrl = buildDisplayUrls({ host: effectiveHost, port }).primary;
1538
1667
 
1539
1668
  // Wait for API to be ready (longer timeout for dev mode compilation)
1540
- const ready = await waitForHealth(`${baseUrl}/health`, { timeoutMs: 60000 });
1669
+ const ready = await waitForHealth(`${internalBaseUrl}/health`, { timeoutMs: 60000 });
1541
1670
  if (!ready) {
1542
1671
  cli.error('API did not become ready in time');
1543
1672
  killProcessGroup(nestProcess);
@@ -1545,8 +1674,8 @@ async function main(argv) {
1545
1674
  }
1546
1675
 
1547
1676
  cli.blank();
1548
- cli.success(`API ready at ${baseUrl}`);
1549
- cli.info(`API docs: ${baseUrl}/api/docs`);
1677
+ cli.success(`API ready at ${displayUrl}`);
1678
+ cli.info(`API docs: ${displayUrl}/api/docs`);
1550
1679
 
1551
1680
  // Ensure provider rows exist
1552
1681
  if (
@@ -1554,7 +1683,7 @@ async function main(argv) {
1554
1683
  && opts.__providersDetected
1555
1684
  && opts.__providersDetected.size > 0
1556
1685
  ) {
1557
- await ensureProvidersInDb(baseUrl, opts.__providersDetected, log);
1686
+ await ensureProvidersInDb(internalBaseUrl, opts.__providersDetected, log);
1558
1687
  }
1559
1688
 
1560
1689
  // Determine startup path for MCP validation
@@ -1564,7 +1693,7 @@ async function main(argv) {
1564
1693
 
1565
1694
  // Validate MCP for all providers
1566
1695
  if (!worktreeRuntimeMode) {
1567
- await validateMcpForProviders(baseUrl, cli, opts, log, startupPath);
1696
+ await validateMcpForProviders(internalBaseUrl, cli, opts, log, startupPath);
1568
1697
  }
1569
1698
 
1570
1699
  // Note: Claude bypass prompt already handled before server start
@@ -1585,19 +1714,49 @@ async function main(argv) {
1585
1714
  cli.blank();
1586
1715
  cli.success('Development servers running');
1587
1716
  cli.info(`${devUiConfig.logLabel}: ${devUiConfig.url}`);
1588
- cli.info(`API: ${baseUrl}`);
1717
+ cli.info(`API: ${displayUrl}`);
1589
1718
  cli.blank();
1590
1719
 
1591
1720
  // Write PID file for top-level runtime only
1592
1721
  if (!worktreeRuntimeMode) {
1593
- writePidFile(port);
1722
+ writePidFile(port, effectiveHost);
1594
1723
  }
1595
1724
 
1596
- // Handle cleanup on exit - kill entire process groups
1597
- const cleanup = () => {
1725
+ // Handle cleanup on exit - kill entire process groups, then wait for
1726
+ // children to actually exit before removing the PID file and exiting.
1727
+ // Re-entrancy: a second Ctrl+C escalates to SIGKILL immediately instead
1728
+ // of waiting again.
1729
+ let cleanupStarted = false;
1730
+ const SIGTERM_GRACE_MS = 5000;
1731
+ const SIGKILL_GRACE_MS = 2000;
1732
+ const cleanup = async () => {
1733
+ if (cleanupStarted) {
1734
+ // Second signal: stop being polite
1735
+ signalProcessGroup(nestProcess, 'SIGKILL');
1736
+ signalProcessGroup(viteProcess, 'SIGKILL');
1737
+ return;
1738
+ }
1739
+ cleanupStarted = true;
1598
1740
  console.log('\nShutting down development servers...');
1741
+
1742
+ const nestExited = waitForExit(nestProcess);
1743
+ const viteExited = waitForExit(viteProcess);
1744
+
1599
1745
  killProcessGroup(nestProcess);
1600
1746
  killProcessGroup(viteProcess);
1747
+
1748
+ await waitWithTimeout(Promise.all([nestExited, viteExited]), SIGTERM_GRACE_MS);
1749
+
1750
+ // Anything still alive after the grace period gets SIGKILL.
1751
+ const stillAlive = [nestProcess, viteProcess].filter(
1752
+ (p) => p && p.exitCode === null && p.signalCode === null,
1753
+ );
1754
+ if (stillAlive.length > 0) {
1755
+ console.log(`Forcing shutdown of ${stillAlive.length} unresponsive process(es)...`);
1756
+ for (const p of stillAlive) signalProcessGroup(p, 'SIGKILL');
1757
+ await waitWithTimeout(Promise.all([nestExited, viteExited]), SIGKILL_GRACE_MS);
1758
+ }
1759
+
1601
1760
  if (!worktreeRuntimeMode) {
1602
1761
  removePidFile();
1603
1762
  }
@@ -1640,10 +1799,11 @@ async function main(argv) {
1640
1799
  // eslint-disable-next-line @typescript-eslint/no-var-requires
1641
1800
  require(serverEntry);
1642
1801
 
1643
- const baseUrl = `http://${process.env.HOST}:${port}`;
1644
- const ready = await waitForHealth(`${baseUrl}/health`);
1802
+ const internalBaseUrl = buildInternalBaseUrl({ host: effectiveHost, port });
1803
+ const displayUrl = buildDisplayUrls({ host: effectiveHost, port }).primary;
1804
+ const ready = await waitForHealth(`${internalBaseUrl}/health`);
1645
1805
  if (!ready) {
1646
- log('error', 'Server did not become ready in time', { url: baseUrl });
1806
+ log('error', 'Server did not become ready in time', { url: internalBaseUrl });
1647
1807
  if (spinner) {
1648
1808
  spinner.stop('✗ timeout');
1649
1809
  cli.blank();
@@ -1656,15 +1816,15 @@ async function main(argv) {
1656
1816
  }
1657
1817
 
1658
1818
  if (opts.foreground) {
1659
- log('info', `Devchain is running at ${baseUrl}`);
1660
- log('info', `API docs: ${baseUrl}/api/docs`);
1661
- console.log(`\nDevchain is running at ${baseUrl}`);
1662
- console.log(`API docs: ${baseUrl}/api/docs`);
1819
+ log('info', `Devchain is running at ${displayUrl}`);
1820
+ log('info', `API docs: ${displayUrl}/api/docs`);
1821
+ console.log(`\nDevchain is running at ${displayUrl}`);
1822
+ console.log(`API docs: ${displayUrl}/api/docs`);
1663
1823
  console.log('Press Ctrl+C to stop.\n');
1664
1824
  } else {
1665
1825
  cli.blank();
1666
- cli.success(`Server ready at ${baseUrl}`);
1667
- cli.info(`API docs: ${baseUrl}/api/docs`);
1826
+ cli.success(`Server ready at ${displayUrl}`);
1827
+ cli.info(`API docs: ${displayUrl}/api/docs`);
1668
1828
  }
1669
1829
 
1670
1830
  // Ensure provider rows exist (idempotent) before opening UI
@@ -1673,7 +1833,7 @@ async function main(argv) {
1673
1833
  && opts.__providersDetected
1674
1834
  && opts.__providersDetected.size > 0
1675
1835
  ) {
1676
- await ensureProvidersInDb(baseUrl, opts.__providersDetected, log);
1836
+ await ensureProvidersInDb(internalBaseUrl, opts.__providersDetected, log);
1677
1837
  }
1678
1838
 
1679
1839
  // Determine startup path for MCP validation and URL
@@ -1683,19 +1843,19 @@ async function main(argv) {
1683
1843
 
1684
1844
  // Validate MCP for all providers (with project context)
1685
1845
  if (!worktreeRuntimeMode) {
1686
- await validateMcpForProviders(baseUrl, cli, opts, log, startupPath);
1846
+ await validateMcpForProviders(internalBaseUrl, cli, opts, log, startupPath);
1687
1847
  }
1688
1848
 
1689
1849
  // Note: Claude bypass prompt already handled before server start (in parent process for detach mode)
1690
1850
 
1691
1851
  // Determine URL to open based on project path
1692
- let urlToOpen = baseUrl;
1852
+ let urlToOpen = displayUrl;
1693
1853
  try {
1694
- const byPathUrl = `${baseUrl}/api/projects/by-path?path=${encodeURIComponent(startupPath)}`;
1854
+ const byPathUrl = `${internalBaseUrl}/api/projects/by-path?path=${encodeURIComponent(startupPath)}`;
1695
1855
  const resByPath = await fetchWithTimeout(byPathUrl, {}, 2500);
1696
1856
  if (resByPath.ok) {
1697
1857
  const project = await resByPath.json();
1698
- urlToOpen = `${baseUrl}/projects?projectId=${encodeURIComponent(project.id)}`;
1858
+ urlToOpen = `${displayUrl}/projects?projectId=${encodeURIComponent(project.id)}`;
1699
1859
  if (opts.foreground) {
1700
1860
  log('info', 'Resolved startup path to existing project', { startupPath, projectId: project.id });
1701
1861
  } else if (opts.open) {
@@ -1703,7 +1863,7 @@ async function main(argv) {
1703
1863
  }
1704
1864
  } else {
1705
1865
  // 404 or invalid — fall back to newProjectPath to prefill dialog
1706
- urlToOpen = `${baseUrl}/projects?newProjectPath=${encodeURIComponent(startupPath)}`;
1866
+ urlToOpen = `${displayUrl}/projects?newProjectPath=${encodeURIComponent(startupPath)}`;
1707
1867
  if (opts.foreground) {
1708
1868
  log('info', 'No project at startup path; prefill create dialog', { startupPath });
1709
1869
  } else if (opts.open) {
@@ -1712,7 +1872,7 @@ async function main(argv) {
1712
1872
  }
1713
1873
  } catch (e) {
1714
1874
  // Network/timeouts: still prefer prefilled create dialog
1715
- urlToOpen = `${baseUrl}/projects?newProjectPath=${encodeURIComponent(startupPath)}`;
1875
+ urlToOpen = `${displayUrl}/projects?newProjectPath=${encodeURIComponent(startupPath)}`;
1716
1876
  if (opts.foreground) {
1717
1877
  log('warn', 'Failed to resolve startup path; opening create dialog', {
1718
1878
  error: e instanceof Error ? e.message : String(e),
@@ -1736,7 +1896,7 @@ async function main(argv) {
1736
1896
 
1737
1897
  if (!worktreeRuntimeMode) {
1738
1898
  // Write PID file for stop command
1739
- writePidFile(port);
1899
+ writePidFile(port, effectiveHost);
1740
1900
 
1741
1901
  // Clean up PID file on exit (main.ts handles SIGINT/SIGTERM and graceful shutdown)
1742
1902
  process.on('exit', () => {
@@ -1820,7 +1980,7 @@ async function main(argv) {
1820
1980
  console.log('No running Devchain instance found.');
1821
1981
  process.exit(1);
1822
1982
  } else {
1823
- const { pid, port } = pidData;
1983
+ const { pid, port, host } = pidData;
1824
1984
 
1825
1985
  if (!isProcessRunning(pid)) {
1826
1986
  console.log(`Devchain process (PID ${pid}) is not running. Cleaning up stale PID file.`);
@@ -1877,6 +2037,13 @@ module.exports = {
1877
2037
  main,
1878
2038
  normalizeCliArgv,
1879
2039
  __test__: {
2040
+ normalizeHost,
2041
+ isWildcardHost,
2042
+ isNonLoopbackHost,
2043
+ connectableHost,
2044
+ formatHostForUrl,
2045
+ buildInternalBaseUrl,
2046
+ buildDisplayUrls,
1880
2047
  ensureDockerAvailable,
1881
2048
  isDockerAvailable,
1882
2049
  deriveRepoRootFromGit,
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  declare const envSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3
3
  NODE_ENV: z.ZodDefault<z.ZodEnum<["development", "production", "test"]>>;
4
4
  PORT: z.ZodDefault<z.ZodEffects<z.ZodString, number, string>>;
5
- HOST: z.ZodDefault<z.ZodString>;
5
+ HOST: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, string, string | undefined>, string, string | undefined>, string, string | undefined>, string, string | undefined>;
6
6
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<["silent", "fatal", "error", "warn", "info", "debug", "trace"]>>;
7
7
  DEVCHAIN_MODE: z.ZodDefault<z.ZodEnum<["normal", "main"]>>;
8
8
  DATABASE_URL: z.ZodOptional<z.ZodString>;
@@ -44,7 +44,15 @@ const envSchema = zod_1.z
44
44
  .object({
45
45
  NODE_ENV: zod_1.z.enum(['development', 'production', 'test']).default('development'),
46
46
  PORT: zod_1.z.string().regex(/^\d+$/).transform(Number).default('3000'),
47
- HOST: zod_1.z.string().default('127.0.0.1'),
47
+ HOST: zod_1.z
48
+ .string()
49
+ .default('127.0.0.1')
50
+ .transform((v) => v.trim())
51
+ .refine((v) => v.length > 0, { message: 'HOST must not be empty' })
52
+ .refine((v) => v !== '*', { message: 'HOST must not be "*"' })
53
+ .refine((v) => !/[\x00-\x1f\x7f]/.test(v), {
54
+ message: 'HOST must not contain control characters',
55
+ }),
48
56
  LOG_LEVEL: zod_1.z
49
57
  .enum(['silent', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'])
50
58
  .default('info'),
@@ -1 +1 @@
1
- {"version":3,"file":"env.config.js","sourceRoot":"","sources":["../../../src/common/config/env.config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"env.config.js","sourceRoot":"","sources":["../../../src/common/config/env.config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function isWildcardHost(host: string): boolean;
2
+ export declare function connectableHost(host: string): string;
3
+ export declare function formatHostForUrl(host: string): string;
4
+ export declare function getRuntimeInternalBaseUrl(config: {
5
+ HOST: string;
6
+ PORT: number;
7
+ }): string;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isWildcardHost = isWildcardHost;
4
+ exports.connectableHost = connectableHost;
5
+ exports.formatHostForUrl = formatHostForUrl;
6
+ exports.getRuntimeInternalBaseUrl = getRuntimeInternalBaseUrl;
7
+ const IPV4_WILDCARDS = new Set(['0.0.0.0', '']);
8
+ const IPV6_WILDCARDS = new Set(['::', '[::]']);
9
+ function isWildcardHost(host) {
10
+ const trimmed = host.trim().toLowerCase();
11
+ return IPV4_WILDCARDS.has(trimmed) || IPV6_WILDCARDS.has(trimmed);
12
+ }
13
+ function connectableHost(host) {
14
+ const trimmed = host.trim();
15
+ if (isWildcardHost(trimmed)) {
16
+ if (IPV6_WILDCARDS.has(trimmed.toLowerCase())) {
17
+ return '::1';
18
+ }
19
+ return '127.0.0.1';
20
+ }
21
+ const unwrapped = trimmed.startsWith('[') && trimmed.endsWith(']') ? trimmed.slice(1, -1) : trimmed;
22
+ return unwrapped;
23
+ }
24
+ function formatHostForUrl(host) {
25
+ if (host.includes(':') && !host.startsWith('[')) {
26
+ return `[${host}]`;
27
+ }
28
+ return host;
29
+ }
30
+ function getRuntimeInternalBaseUrl(config) {
31
+ const host = connectableHost(config.HOST);
32
+ return `http://${formatHostForUrl(host)}:${config.PORT}`;
33
+ }
34
+ //# sourceMappingURL=host-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-helpers.js","sourceRoot":"","sources":["../../../src/common/config/host-helpers.ts"],"names":[],"mappings":";;AAGA,wCAGC;AAED,0CAWC;AAED,4CAKC;AAED,8DAGC;AA/BD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;AAChD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/C,SAAgB,cAAc,CAAC,IAAY;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACpE,CAAC;AAED,SAAgB,eAAe,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,SAAS,GACb,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACpF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,IAAI,GAAG,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,yBAAyB,CAAC,MAAsC;IAC9E,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,UAAU,gBAAgB,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;AAC3D,CAAC"}
@@ -38,6 +38,7 @@ const platform_fastify_1 = require("@nestjs/platform-fastify");
38
38
  const swagger_1 = require("@nestjs/swagger");
39
39
  const common_1 = require("@nestjs/common");
40
40
  const env_config_1 = require("./common/config/env.config");
41
+ const host_helpers_1 = require("./common/config/host-helpers");
41
42
  const logger_1 = require("./common/logging/logger");
42
43
  const path_1 = require("path");
43
44
  const fs_1 = require("fs");
@@ -144,13 +145,14 @@ async function bootstrap() {
144
145
  appLogger.error({ error, portFile: config.RUNTIME_PORT_FILE }, 'Failed to write runtime port file');
145
146
  }
146
147
  }
148
+ const displayUrl = (0, host_helpers_1.getRuntimeInternalBaseUrl)({ HOST: config.HOST, PORT: actualPort });
147
149
  appLogger.info({
148
150
  mode,
149
151
  port: actualPort,
150
- host: config.HOST,
152
+ bindHost: config.HOST,
151
153
  env: config.NODE_ENV,
152
- }, `Application is running on: http://${config.HOST}:${actualPort}`);
153
- appLogger.info(`API Documentation: http://${config.HOST}:${actualPort}/api/docs`);
154
+ }, `Application is running on: ${displayUrl}`);
155
+ appLogger.info(`API Documentation: ${displayUrl}/api/docs`);
154
156
  }
155
157
  bootstrap().catch((error) => {
156
158
  logger_1.logger.fatal(error, 'Failed to start application');
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAA2C;AAC3C,+DAAkF;AAClF,6CAAiE;AACjE,2CAAgD;AAChD,2DAA0D;AAC1D,+DAAyE;AACzE,oDAA+D;AAC/D,+BAA4B;AAC5B,2BAAgC;AAEhC,KAAK,UAAU,SAAS;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtE,MAAM,UAAU,GACd,IAAI,KAAK,MAAM;QACb,CAAC,CAAC,CAAC,wDAAa,mBAAmB,GAAC,CAAC,CAAC,aAAa;QACnD,CAAC,CAAC,CAAC,wDAAa,qBAAqB,GAAC,CAAC,CAAC,eAAe,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAA,yBAAY,GAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAA,qBAAY,EAAC,WAAW,CAAC,CAAC;IAI5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,MAAM,CAAC;IAChE,MAAM,SAAS,GAAkE,CAAC,GAAG,EAAE;QACrF,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ,CAAC;YACd,KAAK,OAAO;gBACV,OAAO,KAAK,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,CAAC,OAAO,CAAC,CAAC;YACnB,KAAK,MAAM;gBACT,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC3B,KAAK,MAAM,CAAC;YACZ,KAAK,KAAK;gBACR,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAClC,KAAK,OAAO;gBACV,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC3C,KAAK,OAAO,CAAC;YACb,KAAK,SAAS;gBACZ,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YACtD;gBACE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAIL,MAAM,aAAa,GACjB,QAAQ,KAAK,OAAO;QAClB,CAAC,CAAC,KAAK;QACP,CAAC,CAAC;YACE,KAAK,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;SAC9E,CAAC;IAER,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAClC,UAAU,EACV,IAAI,iCAAc,CAAC;QACjB,MAAM,EAAE,aAAa;QACrB,iBAAiB,EAAE,WAAW;QAC9B,qBAAqB,EAAE,QAAQ,KAAK,OAAO;KAC5C,CAAC,EACF;QACE,MAAM,EAAE,SAAS;KAClB,CACF,CAAC;IAGF,MAAM,MAAM,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,KAAK,YAAY,CAAC;IAEtD,IAAI,YAAY,IAAI,IAAA,eAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QAEvC,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE;YAC7C,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,GAAG;YACX,aAAa,EAAE,KAAK;YACpB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,6BAA6B,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QACzB,SAAS,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;IAC5F,CAAC;SAAM,CAAC;QACN,SAAS,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IAChF,CAAC;IAGD,GAAG,CAAC,cAAc,CAChB,IAAI,uBAAc,CAAC;QACjB,SAAS,EAAE,IAAI;QACf,oBAAoB,EAAE,IAAI;QAC1B,SAAS,EAAE,IAAI;KAChB,CAAC,CACH,CAAC;IAGF,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QAChD,IAAI,cAAc;YAAE,OAAO;QAC3B,cAAc,GAAG,IAAI,CAAC;QACtB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,yDAAyD,CAAC,CAAC;QACtF,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,gCAAgC,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IAGzD,MAAM,aAAa,GAAG,IAAI,yBAAe,EAAE;SACxC,QAAQ,CAAC,wBAAwB,CAAC;SAClC,cAAc,CAAC,wCAAwC,CAAC;SACxD,UAAU,CAAC,OAAO,CAAC;SACnB,MAAM,CAAC,QAAQ,EAAE,wBAAwB,CAAC;SAC1C,KAAK,EAAE,CAAC;IAEX,MAAM,QAAQ,GAAG,uBAAa,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAClE,uBAAa,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAG/C,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAG3C,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;IACpD,MAAM,UAAU,GACd,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;IAGxF,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,wDAAa,IAAI,GAAC,CAAC;QACxD,MAAM,EAAE,OAAO,EAAE,GAAG,wDAAa,MAAM,GAAC,CAAC;QACzC,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,aAAa,CACX,MAAM,CAAC,iBAAiB,EACxB,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC,CACjF,CAAC;YACF,SAAS,CAAC,IAAI,CACZ,EAAE,QAAQ,EAAE,MAAM,CAAC,iBAAiB,EAAE,UAAU,EAAE,EAClD,2BAA2B,CAC5B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,KAAK,CACb,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,iBAAiB,EAAE,EAC7C,mCAAmC,CACpC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,wCAAyB,EAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IACtF,SAAS,CAAC,IAAI,CACZ;QACE,IAAI;QACJ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,MAAM,CAAC,IAAI;QACrB,GAAG,EAAE,MAAM,CAAC,QAAQ;KACrB,EACD,8BAA8B,UAAU,EAAE,CAC3C,CAAC;IACF,SAAS,CAAC,IAAI,CAAC,sBAAsB,UAAU,WAAW,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC1B,eAAM,CAAC,KAAK,CAAC,KAAK,EAAE,6BAA6B,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -11,6 +11,7 @@ const common_1 = require("@nestjs/common");
11
11
  const preflight_controller_1 = require("./controllers/preflight.controller");
12
12
  const preflight_service_1 = require("./services/preflight.service");
13
13
  const provider_mcp_ensure_service_1 = require("./services/provider-mcp-ensure.service");
14
+ const gemini_trusted_folders_service_1 = require("./services/gemini-trusted-folders.service");
14
15
  const storage_module_1 = require("../storage/storage.module");
15
16
  const mcp_module_1 = require("../mcp/mcp.module");
16
17
  const adapters_1 = require("../providers/adapters");
@@ -21,8 +22,8 @@ exports.CoreNormalModule = CoreNormalModule = __decorate([
21
22
  (0, common_1.Module)({
22
23
  imports: [storage_module_1.StorageModule, (0, common_1.forwardRef)(() => mcp_module_1.McpModule), adapters_1.ProviderAdaptersModule],
23
24
  controllers: [preflight_controller_1.PreflightController],
24
- providers: [preflight_service_1.PreflightService, provider_mcp_ensure_service_1.ProviderMcpEnsureService],
25
- exports: [preflight_service_1.PreflightService, provider_mcp_ensure_service_1.ProviderMcpEnsureService],
25
+ providers: [preflight_service_1.PreflightService, provider_mcp_ensure_service_1.ProviderMcpEnsureService, gemini_trusted_folders_service_1.GeminiTrustedFoldersService],
26
+ exports: [preflight_service_1.PreflightService, provider_mcp_ensure_service_1.ProviderMcpEnsureService, gemini_trusted_folders_service_1.GeminiTrustedFoldersService],
26
27
  })
27
28
  ], CoreNormalModule);
28
29
  //# sourceMappingURL=core-normal.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"core-normal.module.js","sourceRoot":"","sources":["../../../src/modules/core/core-normal.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoD;AACpD,6EAAyE;AACzE,oEAAgE;AAChE,wFAAkF;AAClF,8DAA0D;AAC1D,kDAA8C;AAC9C,oDAA+D;AAQxD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,4CAAgB;2BAAhB,gBAAgB;IAN5B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,8BAAa,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,sBAAS,CAAC,EAAE,iCAAsB,CAAC;QAC7E,WAAW,EAAE,CAAC,0CAAmB,CAAC;QAClC,SAAS,EAAE,CAAC,oCAAgB,EAAE,sDAAwB,CAAC;QACvD,OAAO,EAAE,CAAC,oCAAgB,EAAE,sDAAwB,CAAC;KACtD,CAAC;GACW,gBAAgB,CAAG"}
1
+ {"version":3,"file":"core-normal.module.js","sourceRoot":"","sources":["../../../src/modules/core/core-normal.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoD;AACpD,6EAAyE;AACzE,oEAAgE;AAChE,wFAAkF;AAClF,8FAAwF;AACxF,8DAA0D;AAC1D,kDAA8C;AAC9C,oDAA+D;AAQxD,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,4CAAgB;2BAAhB,gBAAgB;IAN5B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,8BAAa,EAAE,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,sBAAS,CAAC,EAAE,iCAAsB,CAAC;QAC7E,WAAW,EAAE,CAAC,0CAAmB,CAAC;QAClC,SAAS,EAAE,CAAC,oCAAgB,EAAE,sDAAwB,EAAE,4DAA2B,CAAC;QACpF,OAAO,EAAE,CAAC,oCAAgB,EAAE,sDAAwB,EAAE,4DAA2B,CAAC;KACnF,CAAC;GACW,gBAAgB,CAAG"}
@@ -0,0 +1,26 @@
1
+ type TrustLevel = 'TRUST_FOLDER' | 'TRUST_PARENT' | 'DO_NOT_TRUST';
2
+ export type EffectiveTrust = {
3
+ kind: 'trusted';
4
+ via: 'exact' | 'ancestor' | 'parent_rule';
5
+ } | {
6
+ kind: 'distrusted';
7
+ via: 'exact' | 'ancestor';
8
+ } | {
9
+ kind: 'no_rule';
10
+ };
11
+ export type EnsureTrustResult = {
12
+ success: boolean;
13
+ action: 'added' | 'already_trusted' | 'distrusted_warning' | 'malformed_warning';
14
+ message: string;
15
+ warnings?: string[];
16
+ };
17
+ export declare function getEffectiveTrust(projectPath: string, rules: Record<string, TrustLevel>): EffectiveTrust;
18
+ export declare class GeminiTrustedFoldersService {
19
+ private writeTail;
20
+ private get filePath();
21
+ ensure(projectPath: string): Promise<EnsureTrustResult>;
22
+ private doEnsure;
23
+ private atomicWrite;
24
+ private normalizePath;
25
+ }
26
+ export {};