@ash-cloud/ash-ai 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/schema.cjs CHANGED
@@ -43,6 +43,22 @@ var configDeploymentTriggerEnum = pgCore.pgEnum("config_deployment_trigger", [
43
43
  "initial",
44
44
  "rollback"
45
45
  ]);
46
+ var eventCategoryEnum = pgCore.pgEnum("event_category", [
47
+ "lifecycle",
48
+ // session_start, session_end, turn_complete
49
+ "content",
50
+ // text_stream (aggregated), thinking_stream
51
+ "tool",
52
+ // tool_use, tool_result
53
+ "system",
54
+ // mcp_status, sandbox_log
55
+ "error",
56
+ // error events
57
+ "file",
58
+ // file_push, file_pull, file_sync (file sync operations)
59
+ "input"
60
+ // user_input (user prompts/messages)
61
+ ]);
46
62
  var sessions = pgCore.pgTable(
47
63
  "sessions",
48
64
  {
@@ -198,6 +214,32 @@ var configDeployments = pgCore.pgTable(
198
214
  pgCore.index("idx_config_deployments_created").on(table.agentId, table.createdAt)
199
215
  ]
200
216
  );
217
+ var sessionEvents = pgCore.pgTable(
218
+ "session_events",
219
+ {
220
+ id: pgCore.uuid("id").defaultRandom().primaryKey(),
221
+ sessionId: pgCore.uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
222
+ eventType: pgCore.text("event_type").notNull(),
223
+ category: eventCategoryEnum("category").notNull(),
224
+ startedAt: pgCore.timestamp("started_at", { withTimezone: true }).notNull(),
225
+ endedAt: pgCore.timestamp("ended_at", { withTimezone: true }),
226
+ durationMs: pgCore.integer("duration_ms"),
227
+ eventData: pgCore.jsonb("event_data").default({}).$type(),
228
+ // Tool-specific fields
229
+ toolUseId: pgCore.text("tool_use_id"),
230
+ toolName: pgCore.text("tool_name"),
231
+ // Aggregation fields (for text_stream events)
232
+ isAggregated: pgCore.boolean("is_aggregated").default(false),
233
+ aggregatedCount: pgCore.integer("aggregated_count"),
234
+ // Ordering
235
+ sequenceNumber: pgCore.integer("sequence_number").notNull(),
236
+ createdAt: pgCore.timestamp("created_at", { withTimezone: true }).defaultNow().notNull()
237
+ },
238
+ (table) => [
239
+ pgCore.index("idx_session_events_session").on(table.sessionId, table.sequenceNumber),
240
+ pgCore.index("idx_session_events_category").on(table.sessionId, table.category)
241
+ ]
242
+ );
201
243
  var sessionsRelations = drizzleOrm.relations(sessions, ({ one, many }) => ({
202
244
  parentSession: one(sessions, {
203
245
  fields: [sessions.parentSessionId],
@@ -207,7 +249,14 @@ var sessionsRelations = drizzleOrm.relations(sessions, ({ one, many }) => ({
207
249
  childSessions: many(sessions, {
208
250
  relationName: "parentSession"
209
251
  }),
210
- messages: many(messages)
252
+ messages: many(messages),
253
+ events: many(sessionEvents)
254
+ }));
255
+ var sessionEventsRelations = drizzleOrm.relations(sessionEvents, ({ one }) => ({
256
+ session: one(sessions, {
257
+ fields: [sessionEvents.sessionId],
258
+ references: [sessions.id]
259
+ })
211
260
  }));
212
261
  var messagesRelations = drizzleOrm.relations(messages, ({ one, many }) => ({
213
262
  session: one(sessions, {
@@ -242,11 +291,14 @@ exports.configDeploymentStatusEnum = configDeploymentStatusEnum;
242
291
  exports.configDeploymentTriggerEnum = configDeploymentTriggerEnum;
243
292
  exports.configDeployments = configDeployments;
244
293
  exports.configDeploymentsRelations = configDeploymentsRelations;
294
+ exports.eventCategoryEnum = eventCategoryEnum;
245
295
  exports.messageRoleEnum = messageRoleEnum;
246
296
  exports.messages = messages;
247
297
  exports.messagesRelations = messagesRelations;
248
298
  exports.queueItemStatusEnum = queueItemStatusEnum;
249
299
  exports.queueItems = queueItems;
300
+ exports.sessionEvents = sessionEvents;
301
+ exports.sessionEventsRelations = sessionEventsRelations;
250
302
  exports.sessionStatusEnum = sessionStatusEnum;
251
303
  exports.sessions = sessions;
252
304
  exports.sessionsRelations = sessionsRelations;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage-postgres/schema.ts"],"names":["pgEnum","pgTable","uuid","text","integer","jsonb","timestamp","index","relations"],"mappings":"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","file":"schema.cjs","sourcesContent":["/**\n * PostgreSQL Schema for Agent SDK Harness\n *\n * This schema is designed to be:\n * 1. Compatible with @conviction-labs/harness-core types\n * 2. Tenant-agnostic - no multi-tenancy concepts in core\n * 3. Usable standalone for self-hosted deployments\n *\n * Multi-tenancy (organizations, API keys, billing) should be implemented\n * in the cloud layer by:\n * - Creating separate tables that reference these via foreign keys\n * - Or extending these tables in cloud-specific migrations\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uuid,\n jsonb,\n integer,\n index,\n pgEnum,\n} from 'drizzle-orm/pg-core';\nimport { relations } from 'drizzle-orm';\n\n// ============================================================================\n// Enums\n// ============================================================================\n\nexport const sessionStatusEnum = pgEnum('session_status', [\n 'active',\n 'completed',\n 'error',\n 'suspended',\n]);\n\nexport const messageRoleEnum = pgEnum('message_role', [\n 'user',\n 'assistant',\n 'tool',\n 'system',\n]);\n\nexport const agentStatusEnum = pgEnum('agent_status', [\n 'active',\n 'paused',\n 'deleted',\n]);\n\nexport const agentBackendEnum = pgEnum('agent_backend', [\n 'claude',\n 'gemini',\n]);\n\nexport const queueItemStatusEnum = pgEnum('queue_item_status', [\n 'pending',\n 'processing',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\n// Claude config deployment enums (for .claude directory sync from GitHub)\nexport const configDeploymentStatusEnum = pgEnum('config_deployment_status', [\n 'pending',\n 'success',\n 'failed',\n]);\n\nexport const configDeploymentTriggerEnum = pgEnum('config_deployment_trigger', [\n 'webhook',\n 'manual',\n 'initial',\n 'rollback',\n]);\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nexport const sessions = pgTable(\n 'sessions',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n agentName: text('agent_name').notNull(),\n status: sessionStatusEnum('status').default('active').notNull(),\n sdkSessionId: text('sdk_session_id'), // Claude Agent SDK session ID for resume\n parentSessionId: uuid('parent_session_id'),\n totalTokens: integer('total_tokens'),\n totalCost: integer('total_cost'), // In cents\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_sessions_tenant').on(table.tenantId),\n index('idx_sessions_agent').on(table.agentName),\n index('idx_sessions_sdk').on(table.sdkSessionId),\n index('idx_sessions_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Messages\n// ============================================================================\n\nexport const messages = pgTable(\n 'messages',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n role: messageRoleEnum('role').notNull(),\n content: jsonb('content').notNull().$type<unknown[]>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_messages_session').on(table.sessionId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Attachments\n// ============================================================================\n\nexport const attachments = pgTable(\n 'attachments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n messageId: uuid('message_id')\n .notNull()\n .references(() => messages.id, { onDelete: 'cascade' }),\n filename: text('filename').notNull(),\n mimeType: text('mime_type').notNull(),\n size: integer('size').notNull(),\n storagePath: text('storage_path').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [index('idx_attachments_message').on(table.messageId)]\n);\n\n// ============================================================================\n// Agents\n// ============================================================================\n\nexport const agents = pgTable(\n 'agents',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n description: text('description'),\n model: text('model').notNull().default('claude-sonnet-4-5'),\n backend: agentBackendEnum('backend').default('claude').notNull(),\n systemPrompt: text('system_prompt'),\n allowedTools: jsonb('allowed_tools').default([]).$type<string[]>(),\n disallowedTools: jsonb('disallowed_tools').default([]).$type<string[]>(),\n maxTurns: integer('max_turns'),\n permissionMode: text('permission_mode'),\n mcpServers: jsonb('mcp_servers').default({}).$type<Record<string, { command: string; args?: string[] }>>(),\n envVars: jsonb('env_vars').default({}).$type<Record<string, string>>(),\n startupScript: text('startup_script'),\n configFileUrl: text('config_file_url'), // .claude directory zip (skills, commands, agents, hooks, mcp)\n configFileUpdatedAt: timestamp('config_file_updated_at', { withTimezone: true }), // When config was last updated (for cache busting)\n config: jsonb('config').default({}).$type<Record<string, unknown>>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: agentStatusEnum('status').default('active').notNull(),\n // Webhook configuration for execution completion notifications (outbound)\n executionWebhookUrl: text('execution_webhook_url'),\n executionWebhookSecret: text('execution_webhook_secret'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n deletedAt: timestamp('deleted_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_agents_tenant').on(table.tenantId),\n index('idx_agents_slug').on(table.slug),\n index('idx_agents_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Queue Items\n// ============================================================================\n\nexport const queueItems = pgTable(\n 'queue_items',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n sessionId: uuid('session_id').references(() => sessions.id, {\n onDelete: 'cascade',\n }),\n agentName: text('agent_name').notNull(),\n prompt: text('prompt').notNull(),\n files: jsonb('files').$type<Array<{\n filename: string;\n content: string;\n mimeType: string;\n }>>(),\n sessionContext: text('session_context'),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: queueItemStatusEnum('status').default('pending').notNull(),\n priority: integer('priority').default(0).notNull(),\n retryCount: integer('retry_count').default(0).notNull(),\n maxRetries: integer('max_retries').default(3).notNull(),\n error: text('error'),\n resultMessageId: uuid('result_message_id'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_queue_items_tenant').on(table.tenantId),\n index('idx_queue_items_agent').on(table.agentName),\n index('idx_queue_items_session').on(table.sessionId),\n index('idx_queue_items_status').on(table.status),\n index('idx_queue_items_pending').on(table.agentName, table.sessionId, table.status, table.priority, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Config Deployments (history for GitHub-synced .claude directory)\n// ============================================================================\n\nexport const configDeployments = pgTable(\n 'config_deployments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n agentId: uuid('agent_id')\n .notNull()\n .references(() => agents.id, { onDelete: 'cascade' }),\n\n // Git commit info\n commitSha: text('commit_sha').notNull(),\n commitMessage: text('commit_message'),\n commitAuthor: text('commit_author'),\n commitTimestamp: timestamp('commit_timestamp', { withTimezone: true }),\n\n // Deployment status\n status: configDeploymentStatusEnum('status').default('pending').notNull(),\n errorMessage: text('error_message'),\n\n // Config file info (zipped .claude directory)\n configFileUrl: text('config_file_url'),\n configFileSize: integer('config_file_size'),\n\n // Content manifest - what's included in this deployment\n manifest: jsonb('manifest').default({}).$type<{\n hasSkills?: boolean;\n skillsCount?: number;\n hasCommands?: boolean;\n commandsCount?: number;\n hasAgents?: boolean;\n agentsCount?: number;\n hasHooks?: boolean;\n hasMcpConfig?: boolean;\n mcpServersCount?: number;\n }>(),\n\n // Trigger info\n triggeredBy: configDeploymentTriggerEnum('triggered_by').notNull(),\n rollbackFromId: uuid('rollback_from_id'), // If this was a rollback, which deployment it came from\n\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_config_deployments_agent').on(table.agentId),\n index('idx_config_deployments_status').on(table.status),\n index('idx_config_deployments_created').on(table.agentId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Relations\n// ============================================================================\n\nexport const sessionsRelations = relations(sessions, ({ one, many }) => ({\n parentSession: one(sessions, {\n fields: [sessions.parentSessionId],\n references: [sessions.id],\n relationName: 'parentSession',\n }),\n childSessions: many(sessions, {\n relationName: 'parentSession',\n }),\n messages: many(messages),\n}));\n\nexport const messagesRelations = relations(messages, ({ one, many }) => ({\n session: one(sessions, {\n fields: [messages.sessionId],\n references: [sessions.id],\n }),\n attachments: many(attachments),\n}));\n\nexport const attachmentsRelations = relations(attachments, ({ one }) => ({\n message: one(messages, {\n fields: [attachments.messageId],\n references: [messages.id],\n }),\n}));\n\nexport const configDeploymentsRelations = relations(configDeployments, ({ one }) => ({\n agent: one(agents, {\n fields: [configDeployments.agentId],\n references: [agents.id],\n }),\n}));\n\nexport const agentsRelations = relations(agents, ({ many }) => ({\n configDeployments: many(configDeployments),\n}));\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SessionRow = typeof sessions.$inferSelect;\nexport type NewSessionRow = typeof sessions.$inferInsert;\n\nexport type MessageRow = typeof messages.$inferSelect;\nexport type NewMessageRow = typeof messages.$inferInsert;\n\nexport type AttachmentRow = typeof attachments.$inferSelect;\nexport type NewAttachmentRow = typeof attachments.$inferInsert;\n\nexport type AgentRow = typeof agents.$inferSelect;\nexport type NewAgentRow = typeof agents.$inferInsert;\n\nexport type QueueItemRow = typeof queueItems.$inferSelect;\nexport type NewQueueItemRow = typeof queueItems.$inferInsert;\n\nexport type ConfigDeploymentRow = typeof configDeployments.$inferSelect;\nexport type NewConfigDeploymentRow = typeof configDeployments.$inferInsert;\n"]}
1
+ {"version":3,"sources":["../src/storage-postgres/schema.ts"],"names":["pgEnum","pgTable","uuid","text","integer","jsonb","timestamp","index","boolean","relations"],"mappings":"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","file":"schema.cjs","sourcesContent":["/**\n * PostgreSQL Schema for Agent SDK Harness\n *\n * This schema is designed to be:\n * 1. Compatible with @conviction-labs/harness-core types\n * 2. Tenant-agnostic - no multi-tenancy concepts in core\n * 3. Usable standalone for self-hosted deployments\n *\n * Multi-tenancy (organizations, API keys, billing) should be implemented\n * in the cloud layer by:\n * - Creating separate tables that reference these via foreign keys\n * - Or extending these tables in cloud-specific migrations\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uuid,\n jsonb,\n integer,\n index,\n pgEnum,\n boolean,\n} from 'drizzle-orm/pg-core';\nimport { relations } from 'drizzle-orm';\n\n// ============================================================================\n// Enums\n// ============================================================================\n\nexport const sessionStatusEnum = pgEnum('session_status', [\n 'active',\n 'completed',\n 'error',\n 'suspended',\n]);\n\nexport const messageRoleEnum = pgEnum('message_role', [\n 'user',\n 'assistant',\n 'tool',\n 'system',\n]);\n\nexport const agentStatusEnum = pgEnum('agent_status', [\n 'active',\n 'paused',\n 'deleted',\n]);\n\nexport const agentBackendEnum = pgEnum('agent_backend', [\n 'claude',\n 'gemini',\n]);\n\nexport const queueItemStatusEnum = pgEnum('queue_item_status', [\n 'pending',\n 'processing',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\n// Claude config deployment enums (for .claude directory sync from GitHub)\nexport const configDeploymentStatusEnum = pgEnum('config_deployment_status', [\n 'pending',\n 'success',\n 'failed',\n]);\n\nexport const configDeploymentTriggerEnum = pgEnum('config_deployment_trigger', [\n 'webhook',\n 'manual',\n 'initial',\n 'rollback',\n]);\n\n// Event category enum for session events timeline\nexport const eventCategoryEnum = pgEnum('event_category', [\n 'lifecycle', // session_start, session_end, turn_complete\n 'content', // text_stream (aggregated), thinking_stream\n 'tool', // tool_use, tool_result\n 'system', // mcp_status, sandbox_log\n 'error', // error events\n 'file', // file_push, file_pull, file_sync (file sync operations)\n 'input', // user_input (user prompts/messages)\n]);\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nexport const sessions = pgTable(\n 'sessions',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n agentName: text('agent_name').notNull(),\n status: sessionStatusEnum('status').default('active').notNull(),\n sdkSessionId: text('sdk_session_id'), // Claude Agent SDK session ID for resume\n parentSessionId: uuid('parent_session_id'),\n totalTokens: integer('total_tokens'),\n totalCost: integer('total_cost'), // In cents\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_sessions_tenant').on(table.tenantId),\n index('idx_sessions_agent').on(table.agentName),\n index('idx_sessions_sdk').on(table.sdkSessionId),\n index('idx_sessions_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Messages\n// ============================================================================\n\nexport const messages = pgTable(\n 'messages',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n role: messageRoleEnum('role').notNull(),\n content: jsonb('content').notNull().$type<unknown[]>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_messages_session').on(table.sessionId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Attachments\n// ============================================================================\n\nexport const attachments = pgTable(\n 'attachments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n messageId: uuid('message_id')\n .notNull()\n .references(() => messages.id, { onDelete: 'cascade' }),\n filename: text('filename').notNull(),\n mimeType: text('mime_type').notNull(),\n size: integer('size').notNull(),\n storagePath: text('storage_path').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [index('idx_attachments_message').on(table.messageId)]\n);\n\n// ============================================================================\n// Agents\n// ============================================================================\n\nexport const agents = pgTable(\n 'agents',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n description: text('description'),\n model: text('model').notNull().default('claude-sonnet-4-5'),\n backend: agentBackendEnum('backend').default('claude').notNull(),\n systemPrompt: text('system_prompt'),\n allowedTools: jsonb('allowed_tools').default([]).$type<string[]>(),\n disallowedTools: jsonb('disallowed_tools').default([]).$type<string[]>(),\n maxTurns: integer('max_turns'),\n permissionMode: text('permission_mode'),\n mcpServers: jsonb('mcp_servers').default({}).$type<Record<string, { command: string; args?: string[] }>>(),\n envVars: jsonb('env_vars').default({}).$type<Record<string, string>>(),\n startupScript: text('startup_script'),\n configFileUrl: text('config_file_url'), // .claude directory zip (skills, commands, agents, hooks, mcp)\n configFileUpdatedAt: timestamp('config_file_updated_at', { withTimezone: true }), // When config was last updated (for cache busting)\n config: jsonb('config').default({}).$type<Record<string, unknown>>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: agentStatusEnum('status').default('active').notNull(),\n // Webhook configuration for execution completion notifications (outbound)\n executionWebhookUrl: text('execution_webhook_url'),\n executionWebhookSecret: text('execution_webhook_secret'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n deletedAt: timestamp('deleted_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_agents_tenant').on(table.tenantId),\n index('idx_agents_slug').on(table.slug),\n index('idx_agents_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Queue Items\n// ============================================================================\n\nexport const queueItems = pgTable(\n 'queue_items',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n sessionId: uuid('session_id').references(() => sessions.id, {\n onDelete: 'cascade',\n }),\n agentName: text('agent_name').notNull(),\n prompt: text('prompt').notNull(),\n files: jsonb('files').$type<Array<{\n filename: string;\n content: string;\n mimeType: string;\n }>>(),\n sessionContext: text('session_context'),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: queueItemStatusEnum('status').default('pending').notNull(),\n priority: integer('priority').default(0).notNull(),\n retryCount: integer('retry_count').default(0).notNull(),\n maxRetries: integer('max_retries').default(3).notNull(),\n error: text('error'),\n resultMessageId: uuid('result_message_id'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_queue_items_tenant').on(table.tenantId),\n index('idx_queue_items_agent').on(table.agentName),\n index('idx_queue_items_session').on(table.sessionId),\n index('idx_queue_items_status').on(table.status),\n index('idx_queue_items_pending').on(table.agentName, table.sessionId, table.status, table.priority, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Config Deployments (history for GitHub-synced .claude directory)\n// ============================================================================\n\nexport const configDeployments = pgTable(\n 'config_deployments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n agentId: uuid('agent_id')\n .notNull()\n .references(() => agents.id, { onDelete: 'cascade' }),\n\n // Git commit info\n commitSha: text('commit_sha').notNull(),\n commitMessage: text('commit_message'),\n commitAuthor: text('commit_author'),\n commitTimestamp: timestamp('commit_timestamp', { withTimezone: true }),\n\n // Deployment status\n status: configDeploymentStatusEnum('status').default('pending').notNull(),\n errorMessage: text('error_message'),\n\n // Config file info (zipped .claude directory)\n configFileUrl: text('config_file_url'),\n configFileSize: integer('config_file_size'),\n\n // Content manifest - what's included in this deployment\n manifest: jsonb('manifest').default({}).$type<{\n hasSkills?: boolean;\n skillsCount?: number;\n hasCommands?: boolean;\n commandsCount?: number;\n hasAgents?: boolean;\n agentsCount?: number;\n hasHooks?: boolean;\n hasMcpConfig?: boolean;\n mcpServersCount?: number;\n }>(),\n\n // Trigger info\n triggeredBy: configDeploymentTriggerEnum('triggered_by').notNull(),\n rollbackFromId: uuid('rollback_from_id'), // If this was a rollback, which deployment it came from\n\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_config_deployments_agent').on(table.agentId),\n index('idx_config_deployments_status').on(table.status),\n index('idx_config_deployments_created').on(table.agentId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Session Events (Timeline)\n// ============================================================================\n\nexport const sessionEvents = pgTable(\n 'session_events',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n eventType: text('event_type').notNull(),\n category: eventCategoryEnum('category').notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }).notNull(),\n endedAt: timestamp('ended_at', { withTimezone: true }),\n durationMs: integer('duration_ms'),\n eventData: jsonb('event_data').default({}).$type<Record<string, unknown>>(),\n // Tool-specific fields\n toolUseId: text('tool_use_id'),\n toolName: text('tool_name'),\n // Aggregation fields (for text_stream events)\n isAggregated: boolean('is_aggregated').default(false),\n aggregatedCount: integer('aggregated_count'),\n // Ordering\n sequenceNumber: integer('sequence_number').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_session_events_session').on(table.sessionId, table.sequenceNumber),\n index('idx_session_events_category').on(table.sessionId, table.category),\n ]\n);\n\n// ============================================================================\n// Relations\n// ============================================================================\n\nexport const sessionsRelations = relations(sessions, ({ one, many }) => ({\n parentSession: one(sessions, {\n fields: [sessions.parentSessionId],\n references: [sessions.id],\n relationName: 'parentSession',\n }),\n childSessions: many(sessions, {\n relationName: 'parentSession',\n }),\n messages: many(messages),\n events: many(sessionEvents),\n}));\n\nexport const sessionEventsRelations = relations(sessionEvents, ({ one }) => ({\n session: one(sessions, {\n fields: [sessionEvents.sessionId],\n references: [sessions.id],\n }),\n}));\n\nexport const messagesRelations = relations(messages, ({ one, many }) => ({\n session: one(sessions, {\n fields: [messages.sessionId],\n references: [sessions.id],\n }),\n attachments: many(attachments),\n}));\n\nexport const attachmentsRelations = relations(attachments, ({ one }) => ({\n message: one(messages, {\n fields: [attachments.messageId],\n references: [messages.id],\n }),\n}));\n\nexport const configDeploymentsRelations = relations(configDeployments, ({ one }) => ({\n agent: one(agents, {\n fields: [configDeployments.agentId],\n references: [agents.id],\n }),\n}));\n\nexport const agentsRelations = relations(agents, ({ many }) => ({\n configDeployments: many(configDeployments),\n}));\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SessionRow = typeof sessions.$inferSelect;\nexport type NewSessionRow = typeof sessions.$inferInsert;\n\nexport type MessageRow = typeof messages.$inferSelect;\nexport type NewMessageRow = typeof messages.$inferInsert;\n\nexport type AttachmentRow = typeof attachments.$inferSelect;\nexport type NewAttachmentRow = typeof attachments.$inferInsert;\n\nexport type AgentRow = typeof agents.$inferSelect;\nexport type NewAgentRow = typeof agents.$inferInsert;\n\nexport type QueueItemRow = typeof queueItems.$inferSelect;\nexport type NewQueueItemRow = typeof queueItems.$inferInsert;\n\nexport type ConfigDeploymentRow = typeof configDeployments.$inferSelect;\nexport type NewConfigDeploymentRow = typeof configDeployments.$inferInsert;\n\nexport type SessionEventRow = typeof sessionEvents.$inferSelect;\nexport type NewSessionEventRow = typeof sessionEvents.$inferInsert;\n"]}
package/dist/schema.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { w as AgentRow, A as AttachmentRow, C as ConfigDeploymentRow, M as MessageRow, x as NewAgentRow, b as NewAttachmentRow, y as NewConfigDeploymentRow, a as NewMessageRow, c as NewQueueItemRow, N as NewSessionRow, Q as QueueItemRow, S as SessionRow, f as agentBackendEnum, e as agentStatusEnum, l as agents, v as agentsRelations, k as attachments, t as attachmentsRelations, g as configDeploymentStatusEnum, h as configDeploymentTriggerEnum, o as configDeployments, u as configDeploymentsRelations, m as messageRoleEnum, j as messages, r as messagesRelations, q as queueItemStatusEnum, n as queueItems, d as sessionStatusEnum, i as sessions, p as sessionsRelations } from './schema-B_CVsJm5.cjs';
1
+ export { C as AgentRow, A as AttachmentRow, E as ConfigDeploymentRow, M as MessageRow, D as NewAgentRow, b as NewAttachmentRow, F as NewConfigDeploymentRow, a as NewMessageRow, c as NewQueueItemRow, e as NewSessionEventRow, N as NewSessionRow, Q as QueueItemRow, d as SessionEventRow, S as SessionRow, h as agentBackendEnum, g as agentStatusEnum, p as agents, B as agentsRelations, o as attachments, y as attachmentsRelations, i as configDeploymentStatusEnum, j as configDeploymentTriggerEnum, t as configDeployments, z as configDeploymentsRelations, k as eventCategoryEnum, m as messageRoleEnum, n as messages, x as messagesRelations, q as queueItemStatusEnum, r as queueItems, u as sessionEvents, w as sessionEventsRelations, f as sessionStatusEnum, l as sessions, v as sessionsRelations } from './schema-B7RbjHWi.cjs';
2
2
  import 'drizzle-orm';
3
3
  import 'drizzle-orm/pg-core';
package/dist/schema.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { w as AgentRow, A as AttachmentRow, C as ConfigDeploymentRow, M as MessageRow, x as NewAgentRow, b as NewAttachmentRow, y as NewConfigDeploymentRow, a as NewMessageRow, c as NewQueueItemRow, N as NewSessionRow, Q as QueueItemRow, S as SessionRow, f as agentBackendEnum, e as agentStatusEnum, l as agents, v as agentsRelations, k as attachments, t as attachmentsRelations, g as configDeploymentStatusEnum, h as configDeploymentTriggerEnum, o as configDeployments, u as configDeploymentsRelations, m as messageRoleEnum, j as messages, r as messagesRelations, q as queueItemStatusEnum, n as queueItems, d as sessionStatusEnum, i as sessions, p as sessionsRelations } from './schema-B_CVsJm5.js';
1
+ export { C as AgentRow, A as AttachmentRow, E as ConfigDeploymentRow, M as MessageRow, D as NewAgentRow, b as NewAttachmentRow, F as NewConfigDeploymentRow, a as NewMessageRow, c as NewQueueItemRow, e as NewSessionEventRow, N as NewSessionRow, Q as QueueItemRow, d as SessionEventRow, S as SessionRow, h as agentBackendEnum, g as agentStatusEnum, p as agents, B as agentsRelations, o as attachments, y as attachmentsRelations, i as configDeploymentStatusEnum, j as configDeploymentTriggerEnum, t as configDeployments, z as configDeploymentsRelations, k as eventCategoryEnum, m as messageRoleEnum, n as messages, x as messagesRelations, q as queueItemStatusEnum, r as queueItems, u as sessionEvents, w as sessionEventsRelations, f as sessionStatusEnum, l as sessions, v as sessionsRelations } from './schema-B7RbjHWi.js';
2
2
  import 'drizzle-orm';
3
3
  import 'drizzle-orm/pg-core';
package/dist/schema.js CHANGED
@@ -1,4 +1,4 @@
1
- import { pgEnum, pgTable, timestamp, jsonb, integer, uuid, text, index } from 'drizzle-orm/pg-core';
1
+ import { pgEnum, pgTable, timestamp, jsonb, integer, uuid, text, index, boolean } from 'drizzle-orm/pg-core';
2
2
  import { relations } from 'drizzle-orm';
3
3
 
4
4
  // src/storage-postgres/schema.ts
@@ -41,6 +41,22 @@ var configDeploymentTriggerEnum = pgEnum("config_deployment_trigger", [
41
41
  "initial",
42
42
  "rollback"
43
43
  ]);
44
+ var eventCategoryEnum = pgEnum("event_category", [
45
+ "lifecycle",
46
+ // session_start, session_end, turn_complete
47
+ "content",
48
+ // text_stream (aggregated), thinking_stream
49
+ "tool",
50
+ // tool_use, tool_result
51
+ "system",
52
+ // mcp_status, sandbox_log
53
+ "error",
54
+ // error events
55
+ "file",
56
+ // file_push, file_pull, file_sync (file sync operations)
57
+ "input"
58
+ // user_input (user prompts/messages)
59
+ ]);
44
60
  var sessions = pgTable(
45
61
  "sessions",
46
62
  {
@@ -196,6 +212,32 @@ var configDeployments = pgTable(
196
212
  index("idx_config_deployments_created").on(table.agentId, table.createdAt)
197
213
  ]
198
214
  );
215
+ var sessionEvents = pgTable(
216
+ "session_events",
217
+ {
218
+ id: uuid("id").defaultRandom().primaryKey(),
219
+ sessionId: uuid("session_id").notNull().references(() => sessions.id, { onDelete: "cascade" }),
220
+ eventType: text("event_type").notNull(),
221
+ category: eventCategoryEnum("category").notNull(),
222
+ startedAt: timestamp("started_at", { withTimezone: true }).notNull(),
223
+ endedAt: timestamp("ended_at", { withTimezone: true }),
224
+ durationMs: integer("duration_ms"),
225
+ eventData: jsonb("event_data").default({}).$type(),
226
+ // Tool-specific fields
227
+ toolUseId: text("tool_use_id"),
228
+ toolName: text("tool_name"),
229
+ // Aggregation fields (for text_stream events)
230
+ isAggregated: boolean("is_aggregated").default(false),
231
+ aggregatedCount: integer("aggregated_count"),
232
+ // Ordering
233
+ sequenceNumber: integer("sequence_number").notNull(),
234
+ createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull()
235
+ },
236
+ (table) => [
237
+ index("idx_session_events_session").on(table.sessionId, table.sequenceNumber),
238
+ index("idx_session_events_category").on(table.sessionId, table.category)
239
+ ]
240
+ );
199
241
  var sessionsRelations = relations(sessions, ({ one, many }) => ({
200
242
  parentSession: one(sessions, {
201
243
  fields: [sessions.parentSessionId],
@@ -205,7 +247,14 @@ var sessionsRelations = relations(sessions, ({ one, many }) => ({
205
247
  childSessions: many(sessions, {
206
248
  relationName: "parentSession"
207
249
  }),
208
- messages: many(messages)
250
+ messages: many(messages),
251
+ events: many(sessionEvents)
252
+ }));
253
+ var sessionEventsRelations = relations(sessionEvents, ({ one }) => ({
254
+ session: one(sessions, {
255
+ fields: [sessionEvents.sessionId],
256
+ references: [sessions.id]
257
+ })
209
258
  }));
210
259
  var messagesRelations = relations(messages, ({ one, many }) => ({
211
260
  session: one(sessions, {
@@ -230,6 +279,6 @@ var agentsRelations = relations(agents, ({ many }) => ({
230
279
  configDeployments: many(configDeployments)
231
280
  }));
232
281
 
233
- export { agentBackendEnum, agentStatusEnum, agents, agentsRelations, attachments, attachmentsRelations, configDeploymentStatusEnum, configDeploymentTriggerEnum, configDeployments, configDeploymentsRelations, messageRoleEnum, messages, messagesRelations, queueItemStatusEnum, queueItems, sessionStatusEnum, sessions, sessionsRelations };
282
+ export { agentBackendEnum, agentStatusEnum, agents, agentsRelations, attachments, attachmentsRelations, configDeploymentStatusEnum, configDeploymentTriggerEnum, configDeployments, configDeploymentsRelations, eventCategoryEnum, messageRoleEnum, messages, messagesRelations, queueItemStatusEnum, queueItems, sessionEvents, sessionEventsRelations, sessionStatusEnum, sessions, sessionsRelations };
234
283
  //# sourceMappingURL=schema.js.map
235
284
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/storage-postgres/schema.ts"],"names":[],"mappings":"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","file":"schema.js","sourcesContent":["/**\n * PostgreSQL Schema for Agent SDK Harness\n *\n * This schema is designed to be:\n * 1. Compatible with @conviction-labs/harness-core types\n * 2. Tenant-agnostic - no multi-tenancy concepts in core\n * 3. Usable standalone for self-hosted deployments\n *\n * Multi-tenancy (organizations, API keys, billing) should be implemented\n * in the cloud layer by:\n * - Creating separate tables that reference these via foreign keys\n * - Or extending these tables in cloud-specific migrations\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uuid,\n jsonb,\n integer,\n index,\n pgEnum,\n} from 'drizzle-orm/pg-core';\nimport { relations } from 'drizzle-orm';\n\n// ============================================================================\n// Enums\n// ============================================================================\n\nexport const sessionStatusEnum = pgEnum('session_status', [\n 'active',\n 'completed',\n 'error',\n 'suspended',\n]);\n\nexport const messageRoleEnum = pgEnum('message_role', [\n 'user',\n 'assistant',\n 'tool',\n 'system',\n]);\n\nexport const agentStatusEnum = pgEnum('agent_status', [\n 'active',\n 'paused',\n 'deleted',\n]);\n\nexport const agentBackendEnum = pgEnum('agent_backend', [\n 'claude',\n 'gemini',\n]);\n\nexport const queueItemStatusEnum = pgEnum('queue_item_status', [\n 'pending',\n 'processing',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\n// Claude config deployment enums (for .claude directory sync from GitHub)\nexport const configDeploymentStatusEnum = pgEnum('config_deployment_status', [\n 'pending',\n 'success',\n 'failed',\n]);\n\nexport const configDeploymentTriggerEnum = pgEnum('config_deployment_trigger', [\n 'webhook',\n 'manual',\n 'initial',\n 'rollback',\n]);\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nexport const sessions = pgTable(\n 'sessions',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n agentName: text('agent_name').notNull(),\n status: sessionStatusEnum('status').default('active').notNull(),\n sdkSessionId: text('sdk_session_id'), // Claude Agent SDK session ID for resume\n parentSessionId: uuid('parent_session_id'),\n totalTokens: integer('total_tokens'),\n totalCost: integer('total_cost'), // In cents\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_sessions_tenant').on(table.tenantId),\n index('idx_sessions_agent').on(table.agentName),\n index('idx_sessions_sdk').on(table.sdkSessionId),\n index('idx_sessions_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Messages\n// ============================================================================\n\nexport const messages = pgTable(\n 'messages',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n role: messageRoleEnum('role').notNull(),\n content: jsonb('content').notNull().$type<unknown[]>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_messages_session').on(table.sessionId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Attachments\n// ============================================================================\n\nexport const attachments = pgTable(\n 'attachments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n messageId: uuid('message_id')\n .notNull()\n .references(() => messages.id, { onDelete: 'cascade' }),\n filename: text('filename').notNull(),\n mimeType: text('mime_type').notNull(),\n size: integer('size').notNull(),\n storagePath: text('storage_path').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [index('idx_attachments_message').on(table.messageId)]\n);\n\n// ============================================================================\n// Agents\n// ============================================================================\n\nexport const agents = pgTable(\n 'agents',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n description: text('description'),\n model: text('model').notNull().default('claude-sonnet-4-5'),\n backend: agentBackendEnum('backend').default('claude').notNull(),\n systemPrompt: text('system_prompt'),\n allowedTools: jsonb('allowed_tools').default([]).$type<string[]>(),\n disallowedTools: jsonb('disallowed_tools').default([]).$type<string[]>(),\n maxTurns: integer('max_turns'),\n permissionMode: text('permission_mode'),\n mcpServers: jsonb('mcp_servers').default({}).$type<Record<string, { command: string; args?: string[] }>>(),\n envVars: jsonb('env_vars').default({}).$type<Record<string, string>>(),\n startupScript: text('startup_script'),\n configFileUrl: text('config_file_url'), // .claude directory zip (skills, commands, agents, hooks, mcp)\n configFileUpdatedAt: timestamp('config_file_updated_at', { withTimezone: true }), // When config was last updated (for cache busting)\n config: jsonb('config').default({}).$type<Record<string, unknown>>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: agentStatusEnum('status').default('active').notNull(),\n // Webhook configuration for execution completion notifications (outbound)\n executionWebhookUrl: text('execution_webhook_url'),\n executionWebhookSecret: text('execution_webhook_secret'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n deletedAt: timestamp('deleted_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_agents_tenant').on(table.tenantId),\n index('idx_agents_slug').on(table.slug),\n index('idx_agents_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Queue Items\n// ============================================================================\n\nexport const queueItems = pgTable(\n 'queue_items',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n sessionId: uuid('session_id').references(() => sessions.id, {\n onDelete: 'cascade',\n }),\n agentName: text('agent_name').notNull(),\n prompt: text('prompt').notNull(),\n files: jsonb('files').$type<Array<{\n filename: string;\n content: string;\n mimeType: string;\n }>>(),\n sessionContext: text('session_context'),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: queueItemStatusEnum('status').default('pending').notNull(),\n priority: integer('priority').default(0).notNull(),\n retryCount: integer('retry_count').default(0).notNull(),\n maxRetries: integer('max_retries').default(3).notNull(),\n error: text('error'),\n resultMessageId: uuid('result_message_id'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_queue_items_tenant').on(table.tenantId),\n index('idx_queue_items_agent').on(table.agentName),\n index('idx_queue_items_session').on(table.sessionId),\n index('idx_queue_items_status').on(table.status),\n index('idx_queue_items_pending').on(table.agentName, table.sessionId, table.status, table.priority, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Config Deployments (history for GitHub-synced .claude directory)\n// ============================================================================\n\nexport const configDeployments = pgTable(\n 'config_deployments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n agentId: uuid('agent_id')\n .notNull()\n .references(() => agents.id, { onDelete: 'cascade' }),\n\n // Git commit info\n commitSha: text('commit_sha').notNull(),\n commitMessage: text('commit_message'),\n commitAuthor: text('commit_author'),\n commitTimestamp: timestamp('commit_timestamp', { withTimezone: true }),\n\n // Deployment status\n status: configDeploymentStatusEnum('status').default('pending').notNull(),\n errorMessage: text('error_message'),\n\n // Config file info (zipped .claude directory)\n configFileUrl: text('config_file_url'),\n configFileSize: integer('config_file_size'),\n\n // Content manifest - what's included in this deployment\n manifest: jsonb('manifest').default({}).$type<{\n hasSkills?: boolean;\n skillsCount?: number;\n hasCommands?: boolean;\n commandsCount?: number;\n hasAgents?: boolean;\n agentsCount?: number;\n hasHooks?: boolean;\n hasMcpConfig?: boolean;\n mcpServersCount?: number;\n }>(),\n\n // Trigger info\n triggeredBy: configDeploymentTriggerEnum('triggered_by').notNull(),\n rollbackFromId: uuid('rollback_from_id'), // If this was a rollback, which deployment it came from\n\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_config_deployments_agent').on(table.agentId),\n index('idx_config_deployments_status').on(table.status),\n index('idx_config_deployments_created').on(table.agentId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Relations\n// ============================================================================\n\nexport const sessionsRelations = relations(sessions, ({ one, many }) => ({\n parentSession: one(sessions, {\n fields: [sessions.parentSessionId],\n references: [sessions.id],\n relationName: 'parentSession',\n }),\n childSessions: many(sessions, {\n relationName: 'parentSession',\n }),\n messages: many(messages),\n}));\n\nexport const messagesRelations = relations(messages, ({ one, many }) => ({\n session: one(sessions, {\n fields: [messages.sessionId],\n references: [sessions.id],\n }),\n attachments: many(attachments),\n}));\n\nexport const attachmentsRelations = relations(attachments, ({ one }) => ({\n message: one(messages, {\n fields: [attachments.messageId],\n references: [messages.id],\n }),\n}));\n\nexport const configDeploymentsRelations = relations(configDeployments, ({ one }) => ({\n agent: one(agents, {\n fields: [configDeployments.agentId],\n references: [agents.id],\n }),\n}));\n\nexport const agentsRelations = relations(agents, ({ many }) => ({\n configDeployments: many(configDeployments),\n}));\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SessionRow = typeof sessions.$inferSelect;\nexport type NewSessionRow = typeof sessions.$inferInsert;\n\nexport type MessageRow = typeof messages.$inferSelect;\nexport type NewMessageRow = typeof messages.$inferInsert;\n\nexport type AttachmentRow = typeof attachments.$inferSelect;\nexport type NewAttachmentRow = typeof attachments.$inferInsert;\n\nexport type AgentRow = typeof agents.$inferSelect;\nexport type NewAgentRow = typeof agents.$inferInsert;\n\nexport type QueueItemRow = typeof queueItems.$inferSelect;\nexport type NewQueueItemRow = typeof queueItems.$inferInsert;\n\nexport type ConfigDeploymentRow = typeof configDeployments.$inferSelect;\nexport type NewConfigDeploymentRow = typeof configDeployments.$inferInsert;\n"]}
1
+ {"version":3,"sources":["../src/storage-postgres/schema.ts"],"names":[],"mappings":"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","file":"schema.js","sourcesContent":["/**\n * PostgreSQL Schema for Agent SDK Harness\n *\n * This schema is designed to be:\n * 1. Compatible with @conviction-labs/harness-core types\n * 2. Tenant-agnostic - no multi-tenancy concepts in core\n * 3. Usable standalone for self-hosted deployments\n *\n * Multi-tenancy (organizations, API keys, billing) should be implemented\n * in the cloud layer by:\n * - Creating separate tables that reference these via foreign keys\n * - Or extending these tables in cloud-specific migrations\n */\n\nimport {\n pgTable,\n text,\n timestamp,\n uuid,\n jsonb,\n integer,\n index,\n pgEnum,\n boolean,\n} from 'drizzle-orm/pg-core';\nimport { relations } from 'drizzle-orm';\n\n// ============================================================================\n// Enums\n// ============================================================================\n\nexport const sessionStatusEnum = pgEnum('session_status', [\n 'active',\n 'completed',\n 'error',\n 'suspended',\n]);\n\nexport const messageRoleEnum = pgEnum('message_role', [\n 'user',\n 'assistant',\n 'tool',\n 'system',\n]);\n\nexport const agentStatusEnum = pgEnum('agent_status', [\n 'active',\n 'paused',\n 'deleted',\n]);\n\nexport const agentBackendEnum = pgEnum('agent_backend', [\n 'claude',\n 'gemini',\n]);\n\nexport const queueItemStatusEnum = pgEnum('queue_item_status', [\n 'pending',\n 'processing',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\n// Claude config deployment enums (for .claude directory sync from GitHub)\nexport const configDeploymentStatusEnum = pgEnum('config_deployment_status', [\n 'pending',\n 'success',\n 'failed',\n]);\n\nexport const configDeploymentTriggerEnum = pgEnum('config_deployment_trigger', [\n 'webhook',\n 'manual',\n 'initial',\n 'rollback',\n]);\n\n// Event category enum for session events timeline\nexport const eventCategoryEnum = pgEnum('event_category', [\n 'lifecycle', // session_start, session_end, turn_complete\n 'content', // text_stream (aggregated), thinking_stream\n 'tool', // tool_use, tool_result\n 'system', // mcp_status, sandbox_log\n 'error', // error events\n 'file', // file_push, file_pull, file_sync (file sync operations)\n 'input', // user_input (user prompts/messages)\n]);\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\nexport const sessions = pgTable(\n 'sessions',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n agentName: text('agent_name').notNull(),\n status: sessionStatusEnum('status').default('active').notNull(),\n sdkSessionId: text('sdk_session_id'), // Claude Agent SDK session ID for resume\n parentSessionId: uuid('parent_session_id'),\n totalTokens: integer('total_tokens'),\n totalCost: integer('total_cost'), // In cents\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_sessions_tenant').on(table.tenantId),\n index('idx_sessions_agent').on(table.agentName),\n index('idx_sessions_sdk').on(table.sdkSessionId),\n index('idx_sessions_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Messages\n// ============================================================================\n\nexport const messages = pgTable(\n 'messages',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n role: messageRoleEnum('role').notNull(),\n content: jsonb('content').notNull().$type<unknown[]>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_messages_session').on(table.sessionId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Attachments\n// ============================================================================\n\nexport const attachments = pgTable(\n 'attachments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n messageId: uuid('message_id')\n .notNull()\n .references(() => messages.id, { onDelete: 'cascade' }),\n filename: text('filename').notNull(),\n mimeType: text('mime_type').notNull(),\n size: integer('size').notNull(),\n storagePath: text('storage_path').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [index('idx_attachments_message').on(table.messageId)]\n);\n\n// ============================================================================\n// Agents\n// ============================================================================\n\nexport const agents = pgTable(\n 'agents',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n description: text('description'),\n model: text('model').notNull().default('claude-sonnet-4-5'),\n backend: agentBackendEnum('backend').default('claude').notNull(),\n systemPrompt: text('system_prompt'),\n allowedTools: jsonb('allowed_tools').default([]).$type<string[]>(),\n disallowedTools: jsonb('disallowed_tools').default([]).$type<string[]>(),\n maxTurns: integer('max_turns'),\n permissionMode: text('permission_mode'),\n mcpServers: jsonb('mcp_servers').default({}).$type<Record<string, { command: string; args?: string[] }>>(),\n envVars: jsonb('env_vars').default({}).$type<Record<string, string>>(),\n startupScript: text('startup_script'),\n configFileUrl: text('config_file_url'), // .claude directory zip (skills, commands, agents, hooks, mcp)\n configFileUpdatedAt: timestamp('config_file_updated_at', { withTimezone: true }), // When config was last updated (for cache busting)\n config: jsonb('config').default({}).$type<Record<string, unknown>>(),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: agentStatusEnum('status').default('active').notNull(),\n // Webhook configuration for execution completion notifications (outbound)\n executionWebhookUrl: text('execution_webhook_url'),\n executionWebhookSecret: text('execution_webhook_secret'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n deletedAt: timestamp('deleted_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_agents_tenant').on(table.tenantId),\n index('idx_agents_slug').on(table.slug),\n index('idx_agents_status').on(table.status),\n ]\n);\n\n// ============================================================================\n// Queue Items\n// ============================================================================\n\nexport const queueItems = pgTable(\n 'queue_items',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n // Optional tenant isolation - null for single-tenant, set for multi-tenant\n tenantId: text('tenant_id'),\n sessionId: uuid('session_id').references(() => sessions.id, {\n onDelete: 'cascade',\n }),\n agentName: text('agent_name').notNull(),\n prompt: text('prompt').notNull(),\n files: jsonb('files').$type<Array<{\n filename: string;\n content: string;\n mimeType: string;\n }>>(),\n sessionContext: text('session_context'),\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n status: queueItemStatusEnum('status').default('pending').notNull(),\n priority: integer('priority').default(0).notNull(),\n retryCount: integer('retry_count').default(0).notNull(),\n maxRetries: integer('max_retries').default(3).notNull(),\n error: text('error'),\n resultMessageId: uuid('result_message_id'),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n updatedAt: timestamp('updated_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n },\n (table) => [\n index('idx_queue_items_tenant').on(table.tenantId),\n index('idx_queue_items_agent').on(table.agentName),\n index('idx_queue_items_session').on(table.sessionId),\n index('idx_queue_items_status').on(table.status),\n index('idx_queue_items_pending').on(table.agentName, table.sessionId, table.status, table.priority, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Config Deployments (history for GitHub-synced .claude directory)\n// ============================================================================\n\nexport const configDeployments = pgTable(\n 'config_deployments',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n agentId: uuid('agent_id')\n .notNull()\n .references(() => agents.id, { onDelete: 'cascade' }),\n\n // Git commit info\n commitSha: text('commit_sha').notNull(),\n commitMessage: text('commit_message'),\n commitAuthor: text('commit_author'),\n commitTimestamp: timestamp('commit_timestamp', { withTimezone: true }),\n\n // Deployment status\n status: configDeploymentStatusEnum('status').default('pending').notNull(),\n errorMessage: text('error_message'),\n\n // Config file info (zipped .claude directory)\n configFileUrl: text('config_file_url'),\n configFileSize: integer('config_file_size'),\n\n // Content manifest - what's included in this deployment\n manifest: jsonb('manifest').default({}).$type<{\n hasSkills?: boolean;\n skillsCount?: number;\n hasCommands?: boolean;\n commandsCount?: number;\n hasAgents?: boolean;\n agentsCount?: number;\n hasHooks?: boolean;\n hasMcpConfig?: boolean;\n mcpServersCount?: number;\n }>(),\n\n // Trigger info\n triggeredBy: configDeploymentTriggerEnum('triggered_by').notNull(),\n rollbackFromId: uuid('rollback_from_id'), // If this was a rollback, which deployment it came from\n\n metadata: jsonb('metadata').default({}).$type<Record<string, unknown>>(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_config_deployments_agent').on(table.agentId),\n index('idx_config_deployments_status').on(table.status),\n index('idx_config_deployments_created').on(table.agentId, table.createdAt),\n ]\n);\n\n// ============================================================================\n// Session Events (Timeline)\n// ============================================================================\n\nexport const sessionEvents = pgTable(\n 'session_events',\n {\n id: uuid('id').defaultRandom().primaryKey(),\n sessionId: uuid('session_id')\n .notNull()\n .references(() => sessions.id, { onDelete: 'cascade' }),\n eventType: text('event_type').notNull(),\n category: eventCategoryEnum('category').notNull(),\n startedAt: timestamp('started_at', { withTimezone: true }).notNull(),\n endedAt: timestamp('ended_at', { withTimezone: true }),\n durationMs: integer('duration_ms'),\n eventData: jsonb('event_data').default({}).$type<Record<string, unknown>>(),\n // Tool-specific fields\n toolUseId: text('tool_use_id'),\n toolName: text('tool_name'),\n // Aggregation fields (for text_stream events)\n isAggregated: boolean('is_aggregated').default(false),\n aggregatedCount: integer('aggregated_count'),\n // Ordering\n sequenceNumber: integer('sequence_number').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true })\n .defaultNow()\n .notNull(),\n },\n (table) => [\n index('idx_session_events_session').on(table.sessionId, table.sequenceNumber),\n index('idx_session_events_category').on(table.sessionId, table.category),\n ]\n);\n\n// ============================================================================\n// Relations\n// ============================================================================\n\nexport const sessionsRelations = relations(sessions, ({ one, many }) => ({\n parentSession: one(sessions, {\n fields: [sessions.parentSessionId],\n references: [sessions.id],\n relationName: 'parentSession',\n }),\n childSessions: many(sessions, {\n relationName: 'parentSession',\n }),\n messages: many(messages),\n events: many(sessionEvents),\n}));\n\nexport const sessionEventsRelations = relations(sessionEvents, ({ one }) => ({\n session: one(sessions, {\n fields: [sessionEvents.sessionId],\n references: [sessions.id],\n }),\n}));\n\nexport const messagesRelations = relations(messages, ({ one, many }) => ({\n session: one(sessions, {\n fields: [messages.sessionId],\n references: [sessions.id],\n }),\n attachments: many(attachments),\n}));\n\nexport const attachmentsRelations = relations(attachments, ({ one }) => ({\n message: one(messages, {\n fields: [attachments.messageId],\n references: [messages.id],\n }),\n}));\n\nexport const configDeploymentsRelations = relations(configDeployments, ({ one }) => ({\n agent: one(agents, {\n fields: [configDeployments.agentId],\n references: [agents.id],\n }),\n}));\n\nexport const agentsRelations = relations(agents, ({ many }) => ({\n configDeployments: many(configDeployments),\n}));\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SessionRow = typeof sessions.$inferSelect;\nexport type NewSessionRow = typeof sessions.$inferInsert;\n\nexport type MessageRow = typeof messages.$inferSelect;\nexport type NewMessageRow = typeof messages.$inferInsert;\n\nexport type AttachmentRow = typeof attachments.$inferSelect;\nexport type NewAttachmentRow = typeof attachments.$inferInsert;\n\nexport type AgentRow = typeof agents.$inferSelect;\nexport type NewAgentRow = typeof agents.$inferInsert;\n\nexport type QueueItemRow = typeof queueItems.$inferSelect;\nexport type NewQueueItemRow = typeof queueItems.$inferInsert;\n\nexport type ConfigDeploymentRow = typeof configDeployments.$inferSelect;\nexport type NewConfigDeploymentRow = typeof configDeployments.$inferInsert;\n\nexport type SessionEventRow = typeof sessionEvents.$inferSelect;\nexport type NewSessionEventRow = typeof sessionEvents.$inferInsert;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ash-cloud/ash-ai",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Agent SDK Harness - Complete framework for Claude Agent SDK session management",
5
5
  "repository": {
6
6
  "type": "git",
@@ -64,7 +64,8 @@
64
64
  "nanoid": "^5.0.9",
65
65
  "postgres": "^3.4.4",
66
66
  "wouter": "^3.0.0",
67
- "zod": "^3.24.1"
67
+ "zod": "^3.24.1",
68
+ "chokidar": "^3.6.0"
68
69
  },
69
70
  "peerDependencies": {
70
71
  "@anthropic-ai/claude-agent-sdk": ">=0.2.0",