Core 런처
SNA 서버를 시작하기 위한 Node 및 Electron 실행 표면입니다.
Core 런처
런처는 호스트 애플리케이션의 생명주기 안에서 SNA를 함께 시작해야 할 때 사용합니다. 포트 선택, 프로세스 처리, Electron 패키징 세부 사항을 숨기고, client나 React integration이 사용할 server URL을 만들 수 있게 해줍니다.
| import path | 표면 | 목적 |
|---|---|---|
@sna-sdk/core/node | startSnaServer(options) | Node host에서 SNA를 시작합니다. |
@sna-sdk/core/electron | startSnaServer(options) | Electron host에서 SNA를 forked child process로 시작합니다. |
@sna-sdk/core/electron | startSnaServerInProcess(options) | 현재 Electron main process 안에서 SNA를 실행합니다. |
@sna-sdk/core/node, @sna-sdk/core/electron | resolveClaudeCli, resolveCodexCli, resolveOpenCodeCli | setup 및 diagnostics 화면에서 사용할 런타임 CLI 설치를 찾습니다. |
Launcher handle은 서버를 중지하고 발견된 URL을 @sna-sdk/client 또는 @sna-sdk/react에 전달하기에 충분한 정보를 노출합니다.
Options
dbPath는 필수입니다. 나머지 field는 optional입니다.
type SnaServerOptions = {
port?: number;
host?: string;
appId?: string;
authToken?: string;
allowedOrigins?: string[];
dbPath: string;
cwd?: string;
maxSessions?: number;
permissionMode?: "acceptEdits" | "bypassPermissions" | "default";
model?: string;
permissionTimeoutMs?: number;
nativeBinding?: string;
env?: Record<string, string>;
readyTimeout?: number;
onLog?: (line: string) => void;
dataDir?: string;
logLevel?: "info" | "warn" | "error" | "silent";
runtimePaths?: RuntimePaths;
langfuse?: { publicKey: string; secretKey: string; baseUrl?: string };
};
type RuntimePaths = {
claudeCode?: string;
codex?: string;
opencode?: string;
grok?: string;
cursor?: string;
};| Field | Default | 설명 |
|---|---|---|
port | 3099 | Server에 전달할 API port. |
host | 127.0.0.1 | Bind host. Host app에 더 강한 transport boundary가 없다면 loopback을 유지하는 편이 안전합니다. |
appId | sna-sdk | 이 server instance의 owner ID입니다. 이 서버가 만든 session metadata에 붙습니다. |
authToken | generated | Protected HTTP route와 WebSocket upgrade에 필요한 bearer token. |
allowedOrigins | [] | Browser Origin 요청 중 허용할 값. Origin을 보내지 않는 native client는 허용됩니다. |
dbPath | required | Absolute SQLite path. cwd가 없으면 launcher가 이 path에서 cwd를 계산합니다. |
cwd | dirname(dbPath) | Server process와 runtime session의 working directory. |
maxSessions | 5 | 동시에 유지할 수 있는 agent session 수. |
permissionMode | SDK default | 새 agent session의 기본 permission mode. |
model | SDK default | Runtime call의 기본 model. |
permissionTimeoutMs | 0 | 0이면 permission prompt 응답을 host가 직접 관리합니다. 양수면 timeout 뒤 자동 deny됩니다. |
nativeBinding | auto-detected | 명시적인 better-sqlite3 native binding path. Custom Electron build에서 사용합니다. |
env | {} | 추가 환경 변수. 여기에 둔 runtime command 환경 변수는 runtimePaths에서 생성된 값을 덮어씁니다. 단 SNA_APP_ID, SNA_AUTH_TOKEN, SNA_HOST, SNA_ALLOWED_ORIGINS 같은 launcher 소유 값은 typed option이 최종값입니다. |
readyTimeout | 15000 | Standalone process가 ready line을 출력할 때까지 기다리는 시간(ms). |
onLog | none | Child process의 stdout/stderr line, 또는 in-process mode의 SDK logger line을 받습니다. |
dataDir | dbPath에서 계산 | Image와 asset storage의 base directory. |
logLevel | info | In-process logger output을 filter합니다. Forked server의 file log는 모든 level을 계속 기록합니다. |
runtimePaths | auto-detect | 명시적인 런타임 CLI 명령 또는 절대 경로입니다. 각각 SNA_CLAUDE_COMMAND, SNA_CODEX_COMMAND, SNA_OPENCODE_COMMAND, SNA_GROK_COMMAND, SNA_CURSOR_COMMAND로 변환됩니다. |
langfuse | none | Metadata로 tracing을 opt-in한 session에서 Langfuse tracing을 켭니다. |
Launcher는 authToken과 connection: { baseUrl, authToken }을 함께
반환합니다. Token을 저장하거나 environment variable에서 다시 만들지 말고
connection을 SnaClient나 SnaProvider에 전달하는 편이 안전합니다.
생성된 token은 server handle이 소유합니다. Token rotation이 필요하면 새 token으로
서버를 다시 시작하면 됩니다.
호스트 앱에 설정 화면이 있거나 사용자가 선택한 CLI 위치를 저장한다면
runtimePaths를 사용하면 됩니다. env는 여전히 마지막 우회 수단으로 남아
있으며, runtimePaths에서 생성된 값을 덮어씁니다. Server identity, auth,
bind host, origin policy는 typed launcher field로 지정합니다.
Forked vs in-process
| Mode | 사용 시점 | Tradeoff |
|---|---|---|
Forked startSnaServer | 프로세스 격리가 필요하고 standalone child server를 두고 싶을 때. | Packaged Electron app은 @sna-sdk/core를 unpack해야 하며, child process가 정상적으로 시작되어야 ready가 됩니다. |
startSnaServerInProcess | asar path, environment propagation, orphaned child 문제 때문에 Electron fork()가 불안정할 때. | Caller의 Node event loop을 공유합니다. Host가 shutdown 시점에 stop()을 호출해야 합니다. |
In-process mode는 default agent를 자동으로 spawn하지 않습니다. Host가 HTTP, WebSocket 또는 반환된 sessionManager로 session을 시작합니다.
Standalone server를 직접 실행하는 방식은 개발/디버깅용 경로입니다. Product
integration에서는 startSnaServer() 또는 startSnaServerInProcess()를
우선 사용하십시오. 그래야 token, owner identity, bind host, shutdown lifecycle을
host app이 직접 소유할 수 있습니다.
함수 레퍼런스
@sna-sdk/core/node의 startSnaServer(options)
일반 Node host에서 SNA를 시작하고 연결 정보와 종료 동작을 가진 handle을 반환합니다. CLI, desktop host, local development process에 사용합니다.
const handle = await startSnaServer({
appId: "my-app",
dbPath: "/Users/me/Library/Application Support/MyApp/sna.db",
port: 3099,
allowedOrigins: ["http://localhost:5173"],
runtimePaths: {
claudeCode: "/opt/homebrew/bin/claude",
},
});
const client = new SnaClient(handle.connection);
handle.stop();Node launcher는 Electron launcher와 같은 standalone server implementation을 사용합니다. Host가 HTTP app을 직접 import하지 않고 SNA를 sibling process로 두고 싶을 때 적합합니다.
@sna-sdk/core/electron의 startSnaServer(options)
Electron host에서 SNA를 시작합니다. Packaged application 제약을 고려하므로 Electron main process 안에서는 Node launcher보다 이 launcher를 우선 사용하십시오.
Forked mode에서 packaged app을 만들 때는 Node가 실행해야 하는 SDK file을 asar 밖으로 빼야 합니다.
// electron-builder example
asarUnpack: ["node_modules/@sna-sdk/core/**"]Launcher는 .asar path를 .asar.unpacked로 remap하고, NODE_PATH를 구성하고, better-sqlite3를 찾고, log를 forward한 뒤 server가 API server ready를 출력할 때까지 기다립니다.
Returns:
type SnaServerHandle = {
process: ChildProcess;
port: number;
host: string;
appId: string;
baseUrl: string;
authToken: string;
connection: { baseUrl: string; authToken: string };
stop(): void;
};startSnaServerInProcess(options)
현재 Electron process 안에서 SNA를 실행합니다. 프로세스 격리보다 더 긴밀한 생명주기 통합이 중요할 때만 사용하십시오.
Returns:
type InProcessSnaServerHandle = {
process: null;
port: number;
host: string;
appId: string;
baseUrl: string;
authToken: string;
connection: { baseUrl: string; authToken: string };
sessionManager: SessionManager;
httpServer: http.Server;
initLangfuse(config: { publicKey: string; secretKey: string; baseUrl?: string }): Promise<void>;
setTracerUser(userId?: string, userEmail?: string): void;
stop(): Promise<void>;
};stop()은 session을 종료하고, runtime을 dispose하고, tracing을 flush하고, logger callback을 정리한 뒤 HTTP server를 닫습니다. Host shutdown path에서 호출하십시오.
resolveClaudeCli(options?)
사용 가능한 Claude Code CLI path를 찾습니다. Provider를 시작할 수 없는 이유를 setup 또는 diagnostics 화면에서 설명할 때 사용합니다.
resolveCodexCli(options?)
같은 env/cache/static/shell 순서로 사용 가능한 Codex CLI path를 찾습니다.
resolveOpenCodeCli(options?)
같은 env/cache/static/shell 순서로 사용 가능한 OpenCode CLI path를 찾습니다.
validateClaudePath(path)
특정 Claude CLI path가 사용 가능한지 확인합니다. 사용자가 제공한 CLI path를 저장하기 전에 사용하십시오.
cacheClaudePath(path)
해결된 Claude CLI path를 이후 launch를 위해 저장합니다. Validation에 성공한 뒤 사용하십시오.
parseCommandVOutput(output)
shell command discovery output을 normalized path result로 파싱합니다. 주로 CLI resolution internal과 diagnostics에 유용합니다.