Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ RUN useradd -m -s /bin/bash dev
# sshd runtime dir
RUN mkdir -p /run/sshd

# Harden sshd: disable password auth and root login
# sshd: password auth enabled so users can connect without key setup
RUN printf "%s\n" \
"PasswordAuthentication no" \
"PasswordAuthentication yes" \
"PermitRootLogin no" \
"PubkeyAuthentication yes" \
"AllowUsers dev" \
> /etc/ssh/sshd_config.d/dev.conf

# Default password = username (works out of the box; key auth still accepted if authorized_keys provided)
RUN echo "dev:dev" | chpasswd

# Workspace in dev home
RUN mkdir -p /home/dev/app && chown -R dev:dev /home/dev

Expand Down
17 changes: 16 additions & 1 deletion docker-compose.api.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
services:
dind:
image: docker:27-dind
container_name: docker-git-dind
privileged: true
environment:
DOCKER_TLS_CERTDIR: ""
volumes:
- docker-git-dind-storage:/var/lib/docker
restart: unless-stopped

api:
build:
context: .
Expand All @@ -9,9 +19,14 @@ services:
DOCKER_GIT_PROJECTS_ROOT: ${DOCKER_GIT_PROJECTS_ROOT:-/home/dev/.docker-git}
DOCKER_GIT_FEDERATION_PUBLIC_ORIGIN: ${DOCKER_GIT_FEDERATION_PUBLIC_ORIGIN:-}
DOCKER_GIT_FEDERATION_ACTOR: ${DOCKER_GIT_FEDERATION_ACTOR:-docker-git}
DOCKER_HOST: tcp://dind:2375
ports:
- "${DOCKER_GIT_API_BIND_HOST:-127.0.0.1}:${DOCKER_GIT_API_PORT:-3334}:${DOCKER_GIT_API_PORT:-3334}"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${DOCKER_GIT_PROJECTS_ROOT_HOST:-/home/dev/.docker-git}:${DOCKER_GIT_PROJECTS_ROOT:-/home/dev/.docker-git}
depends_on:
- dind
restart: unless-stopped

volumes:
docker-git-dind-storage:
115 changes: 115 additions & 0 deletions packages/api/src/api/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,118 @@ export type ApiEvent = {
readonly at: string
readonly payload: unknown
}

// Auth
export type AuthStatusResponse = { readonly message: string }

export type AuthGithubLoginRequest = {
readonly label?: string | null | undefined
readonly token?: string | null | undefined
readonly scopes?: string | null | undefined
readonly envGlobalPath: string
}

export type AuthGithubStatusRequest = {
readonly envGlobalPath: string
}

export type AuthGithubLogoutRequest = {
readonly label?: string | null | undefined
readonly envGlobalPath: string
}

export type AuthCodexLoginRequest = {
readonly label?: string | null | undefined
readonly codexAuthPath: string
}

export type AuthCodexStatusRequest = {
readonly label?: string | null | undefined
readonly codexAuthPath: string
}

export type AuthCodexLogoutRequest = {
readonly label?: string | null | undefined
readonly codexAuthPath: string
}

export type AuthClaudeLoginRequest = {
readonly label?: string | null | undefined
readonly claudeAuthPath: string
}

export type AuthClaudeStatusRequest = {
readonly label?: string | null | undefined
readonly claudeAuthPath: string
}

export type AuthClaudeLogoutRequest = {
readonly label?: string | null | undefined
readonly claudeAuthPath: string
}

// State
export type StateInitRequest = {
readonly repoUrl: string
readonly repoRef?: string | undefined
}

export type StateCommitRequest = {
readonly message: string
}

export type StateSyncRequest = {
readonly message?: string | null | undefined
}

export type StatePathResponse = { readonly path: string }

export type StateOutputResponse = { readonly output: string }

// Scrap
export type ScrapExportRequest = {
readonly projectDir: string
readonly archivePath?: string | undefined
}

export type ScrapImportRequest = {
readonly projectDir: string
readonly archivePath: string
readonly wipe?: boolean | undefined
}

// Sessions
export type SessionsListRequest = {
readonly projectDir: string
readonly includeDefault?: boolean | undefined
}

export type SessionsKillRequest = {
readonly projectDir: string
readonly pid: number
}

export type SessionsLogsRequest = {
readonly projectDir: string
readonly pid: number
readonly lines?: number | undefined
}

export type SessionsOutput = { readonly output: string }

// MCP Playwright
export type McpPlaywrightUpRequest = {
readonly projectDir: string
readonly runUp?: boolean | undefined
}

// Apply (project config)
export type ApplyRequest = {
readonly runUp?: boolean | undefined
readonly gitTokenLabel?: string | undefined
readonly codexTokenLabel?: string | undefined
readonly claudeTokenLabel?: string | undefined
readonly cpuLimit?: string | undefined
readonly ramLimit?: string | undefined
readonly enableMcpPlaywright?: boolean | undefined
}
101 changes: 101 additions & 0 deletions packages/api/src/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,104 @@ export const AgentLogLineSchema = Schema.Struct({
export type CreateProjectRequestInput = Schema.Schema.Type<typeof CreateProjectRequestSchema>
export type CreateAgentRequestInput = Schema.Schema.Type<typeof CreateAgentRequestSchema>
export type CreateFollowRequestInput = Schema.Schema.Type<typeof CreateFollowRequestSchema>

export const AuthGithubLoginRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
token: Schema.optional(Schema.NullOr(Schema.String)),
scopes: Schema.optional(Schema.NullOr(Schema.String)),
envGlobalPath: Schema.String
})

export const AuthGithubStatusRequestSchema = Schema.Struct({
envGlobalPath: Schema.String
})

export const AuthGithubLogoutRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
envGlobalPath: Schema.String
})

export const AuthCodexLoginRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
codexAuthPath: Schema.String
})

export const AuthCodexStatusRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
codexAuthPath: Schema.String
})

export const AuthCodexLogoutRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
codexAuthPath: Schema.String
})

export const AuthClaudeLoginRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
claudeAuthPath: Schema.String
})

export const AuthClaudeStatusRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
claudeAuthPath: Schema.String
})

export const AuthClaudeLogoutRequestSchema = Schema.Struct({
label: Schema.optional(Schema.NullOr(Schema.String)),
claudeAuthPath: Schema.String
})

export const StateInitRequestSchema = Schema.Struct({
repoUrl: Schema.String,
repoRef: OptionalString
})

export const StateCommitRequestSchema = Schema.Struct({
message: Schema.String
})

export const StateSyncRequestSchema = Schema.Struct({
message: Schema.optional(Schema.NullOr(Schema.String))
})

export const ScrapExportRequestSchema = Schema.Struct({
projectDir: Schema.String,
archivePath: OptionalString
})

export const ScrapImportRequestSchema = Schema.Struct({
projectDir: Schema.String,
archivePath: Schema.String,
wipe: OptionalBoolean
})

export const SessionsListRequestSchema = Schema.Struct({
projectDir: Schema.String,
includeDefault: OptionalBoolean
})

export const SessionsKillRequestSchema = Schema.Struct({
projectDir: Schema.String,
pid: Schema.Number
})

export const SessionsLogsRequestSchema = Schema.Struct({
projectDir: Schema.String,
pid: Schema.Number,
lines: Schema.optional(Schema.Number)
})

export const McpPlaywrightUpRequestSchema = Schema.Struct({
projectDir: Schema.String,
runUp: OptionalBoolean
})

export const ApplyRequestSchema = Schema.Struct({
runUp: OptionalBoolean,
gitTokenLabel: OptionalString,
codexTokenLabel: OptionalString,
claudeTokenLabel: OptionalString,
cpuLimit: OptionalString,
ramLimit: OptionalString,
enableMcpPlaywright: OptionalBoolean
})
Loading
Loading