API 레퍼런스
@deplite/sdk가 공개하는 모든 심볼을 시그니처와 함께 정리해요.
처음 보신다면 개요·Quickstart부터 읽어주세요.
진입 클래스
Deplite— External 모드 (Deplite를 호출)DepliteAgent— Embedded 모드 (내 앱이 작업 노드)
이 페이지의 모든 메소드는 4xx/5xx 응답 시 DepliteApiError, 401·403 응답 시 DepliteAuthError를 던질 수 있어요.
처리 방법은 예외 섹션을 참고해주세요.
class Deplite
new Deplite(options)
new Deplite(options: DepliteOptions)External 모드 클라이언트를 만들어요.
| 옵션 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
apiToken | string | ✓ | — | dpl_... 토큰 |
baseUrl | string | https://api.deplite.io/v1 | 호출할 API 베이스 | |
fetch | typeof fetch | 전역 fetch | 사용자 정의 fetch (테스트·프록시용) |
생성 즉시 triggers·files 서브 매니저가 attach 돼요.
Deplite.enroll(options)
static Deplite.enroll(options): Promise<Enrollment>Embedded 모드용 1회 등록.
새 키쌍을 만들고 /agent/enroll을 호출해 Agent ID와 서버 공개키를 받아와요.
| 옵션 | 타입 | 필수 | 설명 |
|---|---|---|---|
installCode | string | ✓ | 대시보드에서 발급한 1회용 설치 코드 (en_...) |
name | string | ✓ | 에이전트 표시 이름 |
hostname | string | 호스트네임 | |
os | string | 'linux' | 'darwin' | 'android' | ... | |
agentVersion | string | 에이전트 버전 | |
baseUrl | string | API 베이스 오버라이드 | |
fetch | typeof fetch | 사용자 정의 fetch |
결과는 Enrollment 객체로 받아요.
포함된 identity와 privateKey는 SDK가 저장하지 않으므로, 호출 측이 암호화 후 저장하는 것을 추천드려요.
const enrollment = await Deplite.enroll({
installCode: process.env.INSTALL_CODE!,
name: 'kiosk-seoul-01',
})
// 반환값을 먼저 저장한 뒤 후속 로직 시작
await secureStore.save(enrollment) // { identity, privateKey }설치 코드는 1회용이라 enroll 성공 후 폐기돼요.
저장 실패에 대비해 반환값을 먼저 저장한 뒤 후속 로직을 시작하는 게 안전해요.
class Triggers — deplite.triggers
triggers.run(options)
triggers.run(options): Promise<TriggerRunResult>POST /triggers/{triggerId}/run을 호출해 트리거를 실행해요.
| 옵션 | 타입 | 필수 | 설명 |
|---|---|---|---|
triggerId | string | ✓ | 트리거 UUID |
params | unknown | 워크플로우에 그대로 전달될 페이로드 | |
workflowName | string | agent-scope 트리거에서는 필수 | |
ref | string | git ref | |
debug | boolean | verbose 실행 | |
idempotencyKey | string | 중복 실행 방지 키 |
호출 결과는 TriggerRunResult로 받아요.
const job = await deplite.triggers.run({
triggerId: process.env.TRIGGER_ID!,
params: { ref: 'main', actor: 'sehyun' },
idempotencyKey: `release-${Date.now()}`,
})
console.log(job.jobId, job.status)
// sync 트리거였다면 job.output 도 사용 가능responseMode: sync로 만들어진 트리거여야 응답에 exitCode·output이 와요.
async 트리거는 jobId만 즉시 반환되고, 결과는 알림이나 워크플로우 콜백으로 받아야 해요.
class Files — deplite.files
External 모드에서 스토리지 파일을 다뤄요.
기본 CleanupRule은 { kind: 'ttl', ttlSeconds: 86400 }(24시간)이에요.
files.upload(options)
files.upload(options): Promise<FileMeta>presign + PUT + complete를 하나의 호출로 처리해요(내부적으로 HTTP 3회).
| 옵션 | 타입 | 필수 | 설명 |
|---|---|---|---|
file | UploadInput | ✓ | 업로드할 파일 소스 |
cleanupRule | CleanupRule | 기본 24h TTL | |
filename | string | path 입력 시 자동 추론 | |
contentType | string | MIME 타입 | |
bindingId | string | 토큰이 여러 binding을 허용할 때 필수 |
업로드가 끝나면 FileMeta 객체로 활성화된 파일 정보를 돌려줘요.
const uploaded = await deplite.files.upload({
file: { path: './build/app.apk' },
cleanupRule: { kind: 'ttl', ttlSeconds: 3600 },
contentType: 'application/vnd.android.package-archive',
})
// uploaded.id 를 트리거 params 로 전달
await deplite.triggers.run({
triggerId: TRIGGER_ID,
params: { apkFileId: uploaded.id },
})files.presignUpload(options)
files.presignUpload(options): Promise<PresignedUpload>업로드 URL만 발급받아 직접 PUT 한 뒤 completeUpload로 마무리하는 저수준 흐름이에요.
| 옵션 | 타입 | 필수 | 설명 |
|---|---|---|---|
cleanupRule | CleanupRule | ✓ | TTL·persistent 등 |
filename | string | 저장 파일명 | |
contentType | string | MIME 타입 | |
bindingId | string | 토큰이 여러 binding을 허용할 때 필수 |
응답은 PresignedUpload로 받아오고, 이걸 가지고 직접 PUT 후 completeUpload를 호출하면 끝나요.
External 모드에서는 cleanupRule.kind === 'on_job_end'를 쓸 수 없어요(잡 컨텍스트가 없으므로).
Agent Files 전용이에요.
files.completeUpload(options)
files.completeUpload(options: { fileId: string }): Promise<FileMeta>업로드 URL로 바이트 PUT을 마친 뒤 호출해 파일을 활성 상태로 만들어요.
files.downloadUrl(options)
files.downloadUrl(options: { fileId: string }): Promise<string>짧은 만료의 다운로드 URL을 받아오므로, 다운로드 직전에 새로 발급받는 게 안전해요.
files.download(options)
files.download(options: { fileId: string; to: string }): Promise<string>Node.js 전용 메소드예요.
다운로드 URL을 받아 to 경로로 직접 저장해요.
상위 디렉토리가 없으면 자동으로 만들어주고, 저장이 끝나면 to 경로 문자열을 그대로 돌려줘요.
files.get / files.list / files.delete
files.get(options: { fileId: string }): Promise<FileMeta>
files.list(options?: { bindingId?: string; status?: string }): Promise<FileMeta[]>
files.delete(options: { fileId: string }): Promise<void>각각 단건 메타 조회·목록 조회·즉시 삭제.
list는 토큰이 접근 가능한 binding 내 파일만 보여요.
class DepliteAgent
new DepliteAgent(options)
new DepliteAgent(options: DepliteAgentOptions)Embedded 모드 클라이언트를 만들어요.
enroll() 결과를 별도 저장소에서 꺼내 넘기면 돼요.
| 옵션 | 타입 | 필수 | 설명 |
|---|---|---|---|
identity | AgentIdentity | ✓ | agentId·organizationId·baseUrl·serverPublicKeyPem 포함 |
privateKey | Uint8Array | ✓ | 정확히 32바이트 (다르면 즉시 DepliteError) |
fetch | typeof fetch | 사용자 정의 fetch |
생성 후 workflows·jobs·files 서브 매니저가 attach 돼요.
agent.heartbeat()
agent.heartbeat(): Promise<void>서명된 heartbeat를 1회 송신해요(추천 주기 30초).
agent.updateIdentity(patch)
agent.updateIdentity(patch: { hostname?; os?; agentVersion? }): Promise<void>호스트네임·OS·버전 변경 시 PATCH로 알려요.
agent.events(options?)
agent.events(options?: { signal?: AbortSignal }): AsyncIterable<AgentEvent>SSE 스트림을 비동기 이터러블로 노출해요.
서버 → Agent 명령(deploy 등)의 서명 검증은 SDK가 자동 처리하므로 호출 측은 이벤트 타입만 분기하면 돼요.
이벤트 종류는 AgentEvent를 참고해주세요.
for await (const ev of agent.events()) {
switch (ev.type) {
case 'deploy':
await handleDeploy(ev.payload)
break
case 'sync_workflows':
await reportWorkflows()
break
case 'revoke':
return // 루프 종료
case 'ping':
break // keep-alive 무시
}
}전체 시나리오는 예제 페이지에 있어요.
class AgentJobs — agent.jobs
jobs.appendLogs(options)
jobs.appendLogs(options: { jobId: string; items: LogItem[] }): Promise<number>LogItem 배열을 한 번에 보내요.
서버가 실제로 수락한 라인 수가 숫자로 돌아오고, 추천 배치 크기는 64KB 또는 1초 간격 중 빠른 쪽이에요.
jobs.reportResult(options)
jobs.reportResult(options: { jobId: string; result: JobResult }): Promise<void>잡당 1회만 호출해요.
JobResult는 직접 만들기보다 팩토리(JobResult.success 등)를 추천드려요.
import { JobResult } from '@deplite/sdk'
try {
const output = await runWorkflow(payload)
await agent.jobs.reportResult({
jobId: payload.jobId,
result: JobResult.success({ exitCode: 0, output }),
})
} catch (e) {
await agent.jobs.reportResult({
jobId: payload.jobId,
result: JobResult.failed({ exitCode: 1, errorMessage: String(e) }),
})
}class AgentFiles — agent.files
Job 컨텍스트 안에서 산출물 파일을 다뤄요.
기본 CleanupRule은 { kind: 'on_job_end' }라 잡 종료 시 자동 정리돼요.
API는 External의 Files와 동일하지만 모든 메소드가 jobId를 요구하고, list는 없어요.
agentFiles.upload(options): Promise<FileMeta>
agentFiles.presignUpload(options): Promise<PresignedUpload>
agentFiles.complete(options: { fileId }): Promise<FileMeta>
agentFiles.downloadUrl(options: { fileId }): Promise<string>
agentFiles.download(options: { fileId, to }): Promise<string>
agentFiles.get(options: { fileId }): Promise<FileMeta>
agentFiles.delete(options: { fileId }): Promise<void>각 메소드의 옵션과 반환값은 External Files와 동일하고, 모든 호출에 jobId가 추가로 필요한 점만 달라요.
class AgentWorkflows — agent.workflows
workflows.report(workflows)
workflows.report(workflows: WorkflowReport[]): Promise<number>서버에 알려진 워크플로우 인벤토리를 WorkflowReport 배열로 완전히 교체해요.
보고된 워크플로우 수가 숫자로 돌아와요.
실제 YAML·step run 명령·시크릿 값은 보내지 않는 것을 추천드려요.
이름·메타만 보고하는 게 격리 모델의 핵심이에요.
타입 참조
Enrollment
interface Enrollment {
identity: AgentIdentity
privateKey: Uint8Array // raw 32-byte 개인키
}Deplite.enroll의 반환. 두 필드 모두 호출 측이 암호화 후 저장하는 것을 추천드려요.
AgentIdentity
interface AgentIdentity {
agentId: string
organizationId: string
baseUrl: string
serverPublicKeyPem: string // deploy 이벤트 서명 검증용
}비밀이 아니라 일반 저장소에 두어도 무방해요.
AgentEvent
type AgentEvent =
| { type: 'deploy'; payload: DeployPayload; signature: string }
| { type: 'revoke' }
| { type: 'sync_workflows' }
| { type: 'ping' }
| { type: 'unknown'; name: string; data: string }type | 의미 |
|---|---|
deploy | 워크플로우 실행 명령 (payload에 jobId·workflowName·params 등) |
revoke | Agent 자격 회수 |
sync_workflows | 워크플로우 인벤토리 재보고 요청 |
ping | keep-alive |
unknown | 알 수 없는 이벤트 또는 서명 검증 실패 |
DeployPayload
interface DeployPayload {
jobId: string
workflowName: string
debug: boolean
ref?: string
params?: unknown
issuedAt: number
nonce: string
force: boolean
forceReason?: string
}TriggerRunResult
interface TriggerRunResult {
jobId: string
status: string // 'running' | 'success' | 'failed' | 'timeout' | 'rejected'
idempotent: boolean // 동일 키 재사용 여부
timedOut: boolean
exitCode?: number
errorMessage?: string
output?: unknown
statusUrl?: string
}CleanupRule
type CleanupRule =
| { kind: 'ttl'; ttlSeconds: number } // 60s ≤ ttl ≤ 90일
| { kind: 'persistent' }
| { kind: 'on_job_end' } // Agent Files 전용UploadInput
type UploadInput =
| { path: string }
| { stream: ReadableStream<Uint8Array>; size?: number }
| { buffer: Uint8Array }FileMeta
interface FileMeta {
id: string
bindingId?: string
jobId?: string
filename?: string
contentType?: string
size?: number
status?: string // 'pending' | 'active' | 'deleted' ...
cleanupRule?: string
expiresAt?: string // ISO 8601
createdAt?: string
}PresignedUpload
interface PresignedUpload {
fileId: string
uploadUrl: string // 짧은 만료 PUT URL
uploadHeaders?: Record<string, string>
expiresInSeconds?: number
}LogItem
interface LogItem {
seq: number // 잡 안에서 단조 증가
stream: 'raw' | 'system' // raw = stdout/stderr, system = SDK 메타
content: string
stepName?: string
level?: 'info' | 'warn' | 'error' // system 스트림에서 주로 사용
}JobResult
interface JobResult {
status: 'running' | 'success' | 'failed' | 'timeout' | 'rejected'
exitCode?: number
errorMessage?: string
output?: unknown
rejection?: Rejection
}JobResult 객체를 직접 만들기보다 팩토리 사용을 추천드려요.
import { JobResult } from '@deplite/sdk'
JobResult.success({ exitCode: 0, output: { url } })
JobResult.failed({ exitCode: 1, errorMessage: 'build failed' })
JobResult.timeout()
JobResult.rejected({ reason: 'rate_limited', retryAfterSeconds: 120 })Rejection
interface Rejection {
reason: string // Agent가 보고한 자유 형식 사유 (예: 'rate_limited')
limitType?: string
retryAfterSeconds?: number
bypassedLimits?: string[]
}WorkflowReport
interface WorkflowReport {
name: string
verboseSteps?: string[] // step 이름 목록 (메타데이터만)
secretsKeys?: string[] // 사용하는 시크릿 키 이름 목록
}예외
DepliteError
class DepliteError extends Error {
readonly cause?: unknown
}네트워크·키·디스크 등 SDK 내부 오류의 베이스 클래스예요.
DepliteApiError
class DepliteApiError extends DepliteError {
readonly statusCode: number
readonly body: string
}서버가 비-2xx HTTP 응답을 반환했을 때 던져져요(401·403 제외).
DepliteAuthError
class DepliteAuthError extends DepliteApiError {
// 401 또는 403
}401/403 전용. 토큰 회수·교체가 필요해요(재시도 무의미).
추천 처리 패턴
import { DepliteAuthError, DepliteApiError, DepliteError } from '@deplite/sdk'
try {
await deplite.triggers.run({ triggerId, params: {} })
} catch (err) {
if (err instanceof DepliteAuthError) {
// 토큰 회수·교체 필요. 재시도 무의미
} else if (err instanceof DepliteApiError) {
if (err.statusCode === 429 || err.statusCode >= 500) {
// 백오프 후 재시도
}
} else if (err instanceof DepliteError) {
// 네트워크·키·디스크
} else throw err
}