본문으로 건너뛰기
LVIS AI

Architecture

HostApi — 플러그인이 호스트와 대화하는 단일 통로

플러그인은 호스트 코드를 직접 import 하지 않고, context.hostApi.* 메서드만 호출합니다. SDK는 type-only로 lvis-plugin-sdk 에 정의되어 있고, 호스트 측 구현은 lvis-app/src/boot/steps/plugin-runtime.ts 에서 plugin별 인스턴스로 생성됩니다.

@lvis/plugin-sdk · runtime context
src/plugins/types.ts:750
static manifest, not runtime register
이 페이지의 사실 출처
모든 시그니처는 lvis-plugin-sdk/src/index.ts (정의) 와 lvis-app/src/plugins/types.ts (호스트 구현) 에서 확인된 것입니다. 도구 / Skill / UI 슬롯 / 이벤트는 runtime register API가 없습니다 — 모두 plugin.json manifest 에 정적으로 선언됩니다.

PluginHostApi 표면 (verbatim)

storage

PluginStorage sandboxed FS — resolve / read / readText / readJson / write / writeJson / rm / list / exists / mkdir. 모든 경로는 plugin namespace 내부에서만.

config

get<T>(key) / set<T>(key, value): Promise<void> / onChange<T>(key, cb) — plugin.json configSchema 로 선언된 키만.

registerKeywords

채팅 입력 Skill 트리거 등록. Array<{ keyword: string; skillId: string }>. 유일한 runtime register API.

emitEvent / onEvent

이벤트 발사/구독. eventType은 opaque dot-delimited 문자열 (예: meeting.ended, ms-graph.auth.changed).

callTool / callLlm

callTool<T>(toolName, payload) 다른 플러그인 도구 호출. callLlm(prompt, { maxTokens?, systemPrompt? }) 호스트 LLM 호출.

getSecret / resolveApiKey

getSecret(key) read-only secret 조회. resolveApiKey({ purpose: 'llm'|'stt'|'embedding'|'vision', vendor? }) 키 vendor 협상.

openAuthWindow / openAuthPartitionViewer

OAuth/세션 추출용 Electron BrowserWindow. cookie harvester 포함. lge-api / ms-graph 가 사용.

triggerConversation / showOverlay

채팅 본문에 proactive conversation spawn / overlay UI. work-assistant 의 proactive trigger가 사용.

agentApproval

위험 액션 표준 경로. request({ toolName, args, reason, scope })Promise<ApprovalChoice>. respond(requestId, choice, nonce?, hmac?).

logEvent / onShutdown

logEvent(level, message, data?) 구조화 로그. onShutdown(handler) shutdown 훅.

getInstalledPluginIds / onPluginsChanged

다른 plugin lifecycle 관찰. plugin 간 의존 (pluginAccess) 시 사용.

openExternalUrl? / getAppPreference?

optional. shell.openExternal / 호스트 prefs 읽기.
존재하지 않는 메서드
다음 메서드는 SDK 표면에 없습니다: registerTool, registerSkill, registerCommand,addTask, saveNote, saveFile, setSecret, readFile/writeFile (storage.* 사용),enqueueMessage, openCard, registerPluginUI. 도구/UI/이벤트는 manifest 정적 선언.

PluginRuntimeContext

// lvis-plugin-sdk/src/index.ts:1001
export interface PluginRuntimeContext {
  pluginId: string;
  pluginRoot: string;     // dist root
  hostRoot: string;       // host app root
  pluginDataDir: string;  // ~/.lvis/plugins/<id>/
  config?: Record<string, unknown>;
  log: (message: string, meta?: unknown) => void;
  hostApi: PluginHostApi;
}

Lifecycle — start / stop 둘 뿐

// lvis-plugin-sdk/src/index.ts:1036
export interface RuntimePlugin {
  start?: () => Promise<void> | void;
  stop?:  () => Promise<void> | void;
  handlers: Record<string, PluginToolHandler>;  // 도구명 -> 실행 함수
}

// Factory
export type RuntimePluginFactory =
  (context: PluginRuntimeContext) => Promise<RuntimePlugin> | RuntimePlugin;

onInstall/onActivate/onUninstall 같은 플러그인-측 hook은 없습니다. install/uninstall 은 hostApi.onPluginsChanged관찰 만 가능합니다.

plugin.json 의 핵심 필드

  • Required: id, name, version, entry, tools, description.
  • tools: string[] — 도구 이름. 정규식 ^[a-zA-Z_][a-zA-Z0-9_]*$, maxLength 64. 도트/하이픈 금지 (vendor 요구).
  • toolSchemas: 도구별 { description, category: "read"|"write"|"shell"|"network", pathFields?, writesToOwnSandbox?, version?, inputSchema }.
  • capabilities: 닫힌 enum 12종 — ms-graph-consumer, external-auth-consumer, mail-source, calendar-source, routine-provider, meeting-recorder, knowledge-index, background-watcher, worker-client, document-indexer, lifecycle-observer, host:overlay.
  • keywords, eventSubscriptions, emittedEvents, ui[], auth, pluginAccess, dependencies, configSchema, hostSecrets, llmKeySource, installPolicy, publisher.

실제 사용 예 — work-assistant 가 ms-graph 호출

// lvis-plugin-work-assistant/src/hostPlugin.ts:204
const today = await context.hostApi.callTool("msgraph_calendar_today", {});

// :753 — 미팅 종료 이벤트 구독
context.hostApi.onEvent("meeting.ended", (data) => { ... });

// :441 — 자기 알림 emit
context.hostApi.emitEvent(notificationEventForIntent(intent), payload);
HostApi 외 import 금지
플러그인 코드가 lvis-app/* 의 호스트 내부 모듈을 직접 import 하는 것은 SDK type-only 강제 + CI 단계에서 차단됩니다. 통합은 항상 hostApi 호출 + manifest 선언으로만.