MCPcopy
hub / github.com/inkeep/open-knowledge / startUiServer

Function startUiServer

packages/cli/src/commands/ui.ts:66–380  ·  view source on GitHub ↗
(opts: StartUiServerOptions)

Source from the content-addressed store, hash-verified

64}
65
66export async function startUiServer(opts: StartUiServerOptions): Promise<UiServerHandle> {
67 const { existsSync } = await import('node:fs');
68 const { createServer: createHttpServer } = await import('node:http');
69 const { resolve } = await import('node:path');
70 const {
71 acquireUiLock,
72 clearArmedPaneTarget,
73 createAssetServeMiddleware,
74 createContentFilter,
75 readArmedPaneTarget,
76 readServerLock,
77 releaseUiLock,
78 updateUiLockPort,
79 } = await import('@inkeep/open-knowledge-server');
80 const { default: sirv } = await import('sirv');
81 const { resolveContentDir, resolveLockDir } = await import('@inkeep/open-knowledge-server');
82
83 const contentDir = resolveContentDir(opts.config, opts.cwd);
84 const lockDir = resolveLockDir(opts.cwd);
85
86 acquireUiLock(lockDir, { port: 0, worktreeRoot: opts.cwd });
87
88 const cliDir = import.meta.dirname ?? new URL('.', import.meta.url).pathname;
89 const assetPaths = [
90 resolve(cliDir, 'public'), // npm install: dist/public/ (bundled)
91 resolve(cliDir, '../../app/dist'), // monorepo dev from src/
92 resolve(cliDir, '../../../app/dist'), // monorepo dev from dist/
93 ];
94 const assetDir = opts.assetDir ?? assetPaths.find((p) => existsSync(p));
95 const staticHandler = assetDir
96 ? sirv(assetDir, { single: true, gzip: true, etag: true, dev: true, extensions: [] })
97 : null;
98
99 const assetServeMiddleware = existsSync(contentDir)
100 ? createAssetServeMiddleware({
101 contentFilter: createContentFilter({
102 projectDir: opts.cwd,
103 contentDir,
104 }),
105 contentSirv: sirv(contentDir, { dotfiles: false, dev: true, extensions: [] }),
106 inlineExtensions: INLINE_RENDERABLE_EXTENSIONS,
107 assetExtensions: ASSET_EXTENSIONS,
108 blocklistExtensions: EXECUTABLE_BLOCKLIST_EXTENSIONS,
109 })
110 : null;
111
112 let resolvedPort = opts.port;
113
114 let apiConfigNudge: (() => void) | null = null;
115
116 const requestHandler = (req: import('node:http').IncomingMessage, res: ServerResponse) => {
117 const url = req.url?.split('?')[0];
118
119 if (req.method === 'GET' && (url === '/' || url === '')) {
120 const armed = readArmedPaneTarget(lockDir);
121 if (armed && !/[\r\n]/.test(armed)) {
122 clearArmedPaneTarget(lockDir);
123 res.statusCode = 302;

Callers 3

start.test.tsFile · 0.90
ui.test.tsFile · 0.90
uiCommandFunction · 0.85

Calls 11

acquireUiLockFunction · 0.85
createContentFilterFunction · 0.85
runBindLoopFunction · 0.85
isEAddrInUseFunction · 0.85
tearDownPartialBindsFunction · 0.85
releaseUiLockFunction · 0.85
updateUiLockPortFunction · 0.85
armSafetyNetFunction · 0.85
resolveContentDirFunction · 0.50
resolveLockDirFunction · 0.50

Tested by

no test coverage detected