diff --git a/apps/control-plane/src/db/schema.ts b/apps/control-plane/src/db/schema.ts index 32687ed..daa8e88 100644 --- a/apps/control-plane/src/db/schema.ts +++ b/apps/control-plane/src/db/schema.ts @@ -25,6 +25,7 @@ export const daemons = sqliteTable('daemons', { status: text('status').notNull().default('active'), snapshot: text('snapshot').notNull(), trigger: text('trigger', { mode: 'json' }).notNull(), + workspace: text('workspace'), workload: text('workload', { mode: 'json' }), agent: text('agent', { mode: 'json' }), resources: text('resources', { mode: 'json' }), diff --git a/apps/control-plane/src/store/daemons.ts b/apps/control-plane/src/store/daemons.ts index 838378d..d96c66e 100644 --- a/apps/control-plane/src/store/daemons.ts +++ b/apps/control-plane/src/store/daemons.ts @@ -15,6 +15,7 @@ export interface StoredDaemon { status: DaemonStatus; snapshot: string; trigger: Trigger; + workspace?: string | undefined; workload?: Workload | undefined; agent?: AgentConfig | undefined; resources?: Resources | undefined; @@ -51,6 +52,7 @@ export function createDaemonStore(): DaemonStore { status: 'active', snapshot: request.snapshot, trigger: request.trigger, + workspace: request.workspace, workload: request.workload, agent: request.agent, resources: request.resources, @@ -126,6 +128,7 @@ function rowToStoredDaemon(row: DaemonRow): StoredDaemon { status: row.status as DaemonStatus, snapshot: row.snapshot, trigger: row.trigger as Trigger, + workspace: (row as { workspace?: string | null }).workspace ?? undefined, workload: (row.workload as Workload) ?? undefined, agent: (row.agent as AgentConfig) ?? undefined, resources: (row.resources as Resources) ?? undefined, @@ -154,6 +157,7 @@ export function createSqliteDaemonStore(db: PawsDatabase): DaemonStore { status: 'active', snapshot: request.snapshot, trigger: request.trigger, + workspace: request.workspace ?? null, workload: request.workload ?? null, agent: request.agent ?? null, resources: request.resources ?? null, @@ -183,6 +187,7 @@ export function createSqliteDaemonStore(db: PawsDatabase): DaemonStore { if (patch.status !== undefined) values['status'] = patch.status; if (patch.snapshot !== undefined) values['snapshot'] = patch.snapshot; if (patch.trigger !== undefined) values['trigger'] = patch.trigger; + if (patch.workspace !== undefined) values['workspace'] = patch.workspace; if (patch.workload !== undefined) values['workload'] = patch.workload; if (patch.agent !== undefined) values['agent'] = patch.agent; if (patch.resources !== undefined) values['resources'] = patch.resources; diff --git a/packages/domains/workspace/src/types.ts b/packages/domains/workspace/src/types.ts index 040c825..66bc4ca 100644 --- a/packages/domains/workspace/src/types.ts +++ b/packages/domains/workspace/src/types.ts @@ -64,7 +64,7 @@ export const UpdateWorkspaceRequestSchema = z repos: z.array(WorkspaceRepoSchema).min(1).optional(), settings: WorkspaceSettingsSchema.optional(), }) - .refine((data) => Object.keys(data).length > 0, { + .refine((data) => Object.values(data).some((v) => v !== undefined), { message: 'At least one field must be provided', }); diff --git a/packages/domains/workspace/tsconfig.json b/packages/domains/workspace/tsconfig.json index a5102fb..ad8a8ba 100644 --- a/packages/domains/workspace/tsconfig.json +++ b/packages/domains/workspace/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "composite": true, "outDir": "dist", - "rootDir": "src", - "types": [] + "rootDir": "src" }, "include": ["src"] } diff --git a/packages/proxy/src/server.ts b/packages/proxy/src/server.ts index 2967767..d4d38a3 100644 --- a/packages/proxy/src/server.ts +++ b/packages/proxy/src/server.ts @@ -42,10 +42,15 @@ export function createProxy(config: ProxyConfig): ProxyInstance { const hostname = url.hostname; if (!matchesDomain(hostname, allowlist)) { + const durationMs = Math.round(performance.now() - startTime); log.warn('domain blocked', { domain: hostname, method: req.method, path: url.pathname, + statusCode: 403, + durationMs, + credentialsInjected: false, + protocol, }); return new Response('Blocked by network policy', { status: 403 }); } @@ -108,6 +113,7 @@ export function createProxy(config: ProxyConfig): ProxyInstance { domain: hostname, method: req.method, path: url.pathname, + statusCode: 502, durationMs, credentialsInjected, protocol, @@ -153,7 +159,7 @@ export function createProxy(config: ProxyConfig): ProxyInstance { log.info('proxy started', { host: config.listen.host, httpPort: actualHttpPort, - httpsPort: caCert ? config.listen.port + 1 : null, + httpsPort: caCert && caKey ? config.listen.port + 1 : null, allowlistedDomains: allowlist.length, }); },