@openbuilder/cli 0.31.11
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/README.md +1053 -0
- package/bin/openbuilder.js +31 -0
- package/dist/chunks/Banner-D4tqKfzA.js +113 -0
- package/dist/chunks/Banner-D4tqKfzA.js.map +1 -0
- package/dist/chunks/auto-update-Dj3lWPWO.js +350 -0
- package/dist/chunks/auto-update-Dj3lWPWO.js.map +1 -0
- package/dist/chunks/build-D0qYqIq0.js +116 -0
- package/dist/chunks/build-D0qYqIq0.js.map +1 -0
- package/dist/chunks/cleanup-qVTsA3tk.js +141 -0
- package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
- package/dist/chunks/cli-error-BjQwvWtK.js +140 -0
- package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
- package/dist/chunks/config-BGP1jZJ4.js +167 -0
- package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
- package/dist/chunks/config-manager-BkbjtN-H.js +133 -0
- package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
- package/dist/chunks/database-BvAbD4sP.js +68 -0
- package/dist/chunks/database-BvAbD4sP.js.map +1 -0
- package/dist/chunks/database-setup-BYjIRAmT.js +253 -0
- package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
- package/dist/chunks/exports-ij9sv4UM.js +7793 -0
- package/dist/chunks/exports-ij9sv4UM.js.map +1 -0
- package/dist/chunks/init-CZoN6soU.js +468 -0
- package/dist/chunks/init-CZoN6soU.js.map +1 -0
- package/dist/chunks/init-tui-BNzk_7Yx.js +1127 -0
- package/dist/chunks/init-tui-BNzk_7Yx.js.map +1 -0
- package/dist/chunks/logger-ZpJi7chw.js +38 -0
- package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
- package/dist/chunks/main-tui-Cq1hLCx-.js +644 -0
- package/dist/chunks/main-tui-Cq1hLCx-.js.map +1 -0
- package/dist/chunks/manager-CvGX9qqe.js +1161 -0
- package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
- package/dist/chunks/port-allocator-BRFzgH9b.js +749 -0
- package/dist/chunks/port-allocator-BRFzgH9b.js.map +1 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js +87 -0
- package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
- package/dist/chunks/prompts-1QbE_bRr.js +128 -0
- package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js +219 -0
- package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
- package/dist/chunks/repo-detector-B_oj696o.js +66 -0
- package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
- package/dist/chunks/run-D23hg4xy.js +630 -0
- package/dist/chunks/run-D23hg4xy.js.map +1 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js +899 -0
- package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
- package/dist/chunks/spinner-BJL9zWAJ.js +53 -0
- package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
- package/dist/chunks/start-BygPCbvw.js +1708 -0
- package/dist/chunks/start-BygPCbvw.js.map +1 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js +255 -0
- package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
- package/dist/chunks/status-cS8YwtUx.js +97 -0
- package/dist/chunks/status-cS8YwtUx.js.map +1 -0
- package/dist/chunks/theme-DhorI2Hb.js +44 -0
- package/dist/chunks/theme-DhorI2Hb.js.map +1 -0
- package/dist/chunks/upgrade-CT6w0lKp.js +323 -0
- package/dist/chunks/upgrade-CT6w0lKp.js.map +1 -0
- package/dist/chunks/useBuildState-CdBSu9y_.js +331 -0
- package/dist/chunks/useBuildState-CdBSu9y_.js.map +1 -0
- package/dist/cli/index.js +694 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.js +14358 -0
- package/dist/index.js.map +1 -0
- package/dist/instrument.js +64226 -0
- package/dist/instrument.js.map +1 -0
- package/dist/templates.json +295 -0
- package/package.json +98 -0
- package/scripts/install-vendor-deps.js +34 -0
- package/scripts/install-vendor.js +167 -0
- package/scripts/prepare-release.js +71 -0
- package/templates/config.template.json +18 -0
- package/templates.json +295 -0
- package/vendor/ai-sdk-provider-claude-code-LOCAL.tgz +0 -0
- package/vendor/sentry-core-LOCAL.tgz +0 -0
- package/vendor/sentry-nextjs-LOCAL.tgz +0 -0
- package/vendor/sentry-node-LOCAL.tgz +0 -0
- package/vendor/sentry-node-core-LOCAL.tgz +0 -0
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
// OpenBuilder CLI - Built with Rollup
|
|
2
|
+
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
3
|
+
import pg from 'pg';
|
|
4
|
+
import { pgTable, timestamp, boolean, text, uuid, index, uniqueIndex, jsonb, integer } from 'drizzle-orm/pg-core';
|
|
5
|
+
import { sql } from 'drizzle-orm';
|
|
6
|
+
import 'net';
|
|
7
|
+
import { readFile } from 'fs/promises';
|
|
8
|
+
import { existsSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { ak as addBreadcrumb } from './exports-ij9sv4UM.js';
|
|
11
|
+
import 'node:util';
|
|
12
|
+
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/lib/db/schema.ts
|
|
20
|
+
var schema_exports = {};
|
|
21
|
+
__export(schema_exports, {
|
|
22
|
+
accounts: () => accounts,
|
|
23
|
+
generationNotes: () => generationNotes,
|
|
24
|
+
generationSessions: () => generationSessions,
|
|
25
|
+
generationTodos: () => generationTodos,
|
|
26
|
+
generationToolCalls: () => generationToolCalls,
|
|
27
|
+
messages: () => messages,
|
|
28
|
+
portAllocations: () => portAllocations,
|
|
29
|
+
projects: () => projects,
|
|
30
|
+
runnerKeys: () => runnerKeys,
|
|
31
|
+
runningProcesses: () => runningProcesses,
|
|
32
|
+
serverOperations: () => serverOperations,
|
|
33
|
+
sessions: () => sessions,
|
|
34
|
+
users: () => users,
|
|
35
|
+
verifications: () => verifications
|
|
36
|
+
});
|
|
37
|
+
var users = pgTable("users", {
|
|
38
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
39
|
+
name: text("name").notNull(),
|
|
40
|
+
email: text("email").notNull().unique(),
|
|
41
|
+
emailVerified: boolean("email_verified").notNull().default(false),
|
|
42
|
+
image: text("image"),
|
|
43
|
+
hasCompletedOnboarding: boolean("has_completed_onboarding").notNull().default(false),
|
|
44
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
45
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
46
|
+
});
|
|
47
|
+
var sessions = pgTable("sessions", {
|
|
48
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
49
|
+
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
50
|
+
token: text("token").notNull().unique(),
|
|
51
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
52
|
+
ipAddress: text("ip_address"),
|
|
53
|
+
userAgent: text("user_agent"),
|
|
54
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
55
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
56
|
+
}, (table) => ({
|
|
57
|
+
userIdIdx: index("sessions_user_id_idx").on(table.userId),
|
|
58
|
+
tokenIdx: index("sessions_token_idx").on(table.token)
|
|
59
|
+
}));
|
|
60
|
+
var accounts = pgTable("accounts", {
|
|
61
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
62
|
+
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
63
|
+
accountId: text("account_id").notNull(),
|
|
64
|
+
providerId: text("provider_id").notNull(),
|
|
65
|
+
// 'credential', 'google', etc.
|
|
66
|
+
accessToken: text("access_token"),
|
|
67
|
+
refreshToken: text("refresh_token"),
|
|
68
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
|
69
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
|
70
|
+
scope: text("scope"),
|
|
71
|
+
idToken: text("id_token"),
|
|
72
|
+
// ID token from OAuth providers
|
|
73
|
+
password: text("password"),
|
|
74
|
+
// Hashed password for credential provider
|
|
75
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
76
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
77
|
+
}, (table) => ({
|
|
78
|
+
userIdIdx: index("accounts_user_id_idx").on(table.userId),
|
|
79
|
+
providerAccountIdx: uniqueIndex("accounts_provider_account_idx").on(table.providerId, table.accountId)
|
|
80
|
+
}));
|
|
81
|
+
var verifications = pgTable("verifications", {
|
|
82
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
83
|
+
identifier: text("identifier").notNull(),
|
|
84
|
+
// email or other identifier
|
|
85
|
+
value: text("value").notNull(),
|
|
86
|
+
// verification token
|
|
87
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
88
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
89
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
90
|
+
}, (table) => ({
|
|
91
|
+
identifierIdx: index("verifications_identifier_idx").on(table.identifier)
|
|
92
|
+
}));
|
|
93
|
+
var runnerKeys = pgTable("runner_keys", {
|
|
94
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
95
|
+
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
|
96
|
+
name: text("name").notNull(),
|
|
97
|
+
// User-friendly name like "My MacBook"
|
|
98
|
+
keyHash: text("key_hash").notNull(),
|
|
99
|
+
// SHA-256 hash of the full key
|
|
100
|
+
keyPrefix: text("key_prefix").notNull(),
|
|
101
|
+
// First 8 chars for display: "sv_abc123..."
|
|
102
|
+
lastUsedAt: timestamp("last_used_at"),
|
|
103
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
104
|
+
revokedAt: timestamp("revoked_at")
|
|
105
|
+
// Soft delete - null means active
|
|
106
|
+
}, (table) => ({
|
|
107
|
+
userIdIdx: index("runner_keys_user_id_idx").on(table.userId),
|
|
108
|
+
keyHashIdx: uniqueIndex("runner_keys_key_hash_idx").on(table.keyHash)
|
|
109
|
+
}));
|
|
110
|
+
var projects = pgTable("projects", {
|
|
111
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
112
|
+
userId: uuid("user_id").references(() => users.id, { onDelete: "set null" }),
|
|
113
|
+
// Owner of the project (nullable for migration/local mode)
|
|
114
|
+
name: text("name").notNull(),
|
|
115
|
+
slug: text("slug").notNull().unique(),
|
|
116
|
+
description: text("description"),
|
|
117
|
+
originalPrompt: text("original_prompt"),
|
|
118
|
+
icon: text("icon").default("Folder"),
|
|
119
|
+
status: text("status").notNull().default("pending"),
|
|
120
|
+
projectType: text("project_type"),
|
|
121
|
+
detectedFramework: text("detected_framework"),
|
|
122
|
+
// Auto-detected framework (astro, next, vite, etc.)
|
|
123
|
+
path: text("path"),
|
|
124
|
+
// Nullable - deprecated, path should be calculated from slug
|
|
125
|
+
runCommand: text("run_command"),
|
|
126
|
+
port: integer("port"),
|
|
127
|
+
devServerPid: integer("dev_server_pid"),
|
|
128
|
+
devServerPort: integer("dev_server_port"),
|
|
129
|
+
devServerStatus: text("dev_server_status").default("stopped"),
|
|
130
|
+
devServerStatusUpdatedAt: timestamp("dev_server_status_updated_at").defaultNow(),
|
|
131
|
+
tunnelUrl: text("tunnel_url"),
|
|
132
|
+
runnerId: text("runner_id"),
|
|
133
|
+
// Runner that created/manages this project
|
|
134
|
+
generationState: text("generation_state"),
|
|
135
|
+
designPreferences: jsonb("design_preferences"),
|
|
136
|
+
// User-specified design constraints (deprecated - use tags)
|
|
137
|
+
tags: jsonb("tags"),
|
|
138
|
+
// Tag-based configuration system
|
|
139
|
+
lastActivityAt: timestamp("last_activity_at").defaultNow(),
|
|
140
|
+
errorMessage: text("error_message"),
|
|
141
|
+
// GitHub integration fields
|
|
142
|
+
githubRepo: text("github_repo"),
|
|
143
|
+
// e.g., "owner/repo-name"
|
|
144
|
+
githubUrl: text("github_url"),
|
|
145
|
+
// Full repository URL
|
|
146
|
+
githubBranch: text("github_branch"),
|
|
147
|
+
// Default branch (e.g., "main")
|
|
148
|
+
githubLastPushedAt: timestamp("github_last_pushed_at"),
|
|
149
|
+
// Last push timestamp
|
|
150
|
+
githubAutoPush: boolean("github_auto_push").default(false),
|
|
151
|
+
// Auto-push after builds
|
|
152
|
+
githubLastSyncAt: timestamp("github_last_sync_at"),
|
|
153
|
+
// Last time we synced repo info
|
|
154
|
+
githubMeta: jsonb("github_meta"),
|
|
155
|
+
// Additional metadata (issues count, recent commits, etc.)
|
|
156
|
+
// NeonDB integration fields
|
|
157
|
+
neondbConnectionString: text("neondb_connection_string"),
|
|
158
|
+
// DATABASE_URL (encrypted/partial)
|
|
159
|
+
neondbClaimUrl: text("neondb_claim_url"),
|
|
160
|
+
// URL to claim the database
|
|
161
|
+
neondbHost: text("neondb_host"),
|
|
162
|
+
// Database host endpoint
|
|
163
|
+
neondbDatabase: text("neondb_database"),
|
|
164
|
+
// Database name
|
|
165
|
+
neondbCreatedAt: timestamp("neondb_created_at"),
|
|
166
|
+
// When database was provisioned
|
|
167
|
+
neondbExpiresAt: timestamp("neondb_expires_at"),
|
|
168
|
+
// When unclaimed DB expires (72 hours)
|
|
169
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
170
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
171
|
+
}, (table) => ({
|
|
172
|
+
// Indexes for performance
|
|
173
|
+
userIdIdx: index("projects_user_id_idx").on(table.userId),
|
|
174
|
+
runnerIdIdx: index("projects_runner_id_idx").on(table.runnerId),
|
|
175
|
+
statusIdx: index("projects_status_idx").on(table.status),
|
|
176
|
+
lastActivityIdx: index("projects_last_activity_idx").on(table.lastActivityAt)
|
|
177
|
+
}));
|
|
178
|
+
var messages = pgTable("messages", {
|
|
179
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
180
|
+
projectId: uuid("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
181
|
+
role: text("role").notNull(),
|
|
182
|
+
content: text("content").notNull(),
|
|
183
|
+
createdAt: timestamp("created_at").notNull().defaultNow()
|
|
184
|
+
});
|
|
185
|
+
var portAllocations = pgTable("port_allocations", {
|
|
186
|
+
port: integer("port").primaryKey(),
|
|
187
|
+
framework: text("framework").notNull(),
|
|
188
|
+
projectId: uuid("project_id").references(() => projects.id, { onDelete: "set null" }),
|
|
189
|
+
reservedAt: timestamp("reserved_at").defaultNow()
|
|
190
|
+
});
|
|
191
|
+
var runningProcesses = pgTable("running_processes", {
|
|
192
|
+
projectId: uuid("project_id").primaryKey().notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
193
|
+
pid: integer("pid").notNull(),
|
|
194
|
+
port: integer("port"),
|
|
195
|
+
command: text("command"),
|
|
196
|
+
runnerId: text("runner_id"),
|
|
197
|
+
// Runner that manages this process
|
|
198
|
+
startedAt: timestamp("started_at").notNull().defaultNow(),
|
|
199
|
+
lastHealthCheck: timestamp("last_health_check"),
|
|
200
|
+
healthCheckFailCount: integer("health_check_fail_count").notNull().default(0)
|
|
201
|
+
}, (table) => ({
|
|
202
|
+
// Index for filtering by runner
|
|
203
|
+
runnerIdIdx: index("running_processes_runner_id_idx").on(table.runnerId)
|
|
204
|
+
}));
|
|
205
|
+
var generationSessions = pgTable("generation_sessions", {
|
|
206
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
207
|
+
projectId: uuid("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
208
|
+
buildId: text("build_id").notNull(),
|
|
209
|
+
operationType: text("operation_type"),
|
|
210
|
+
status: text("status").notNull().default("active"),
|
|
211
|
+
startedAt: timestamp("started_at").notNull().defaultNow(),
|
|
212
|
+
endedAt: timestamp("ended_at"),
|
|
213
|
+
summary: text("summary"),
|
|
214
|
+
rawState: jsonb("raw_state"),
|
|
215
|
+
isAutoFix: boolean("is_auto_fix").default(false),
|
|
216
|
+
// Flag for auto-fix sessions triggered by startup errors
|
|
217
|
+
autoFixError: text("auto_fix_error"),
|
|
218
|
+
// The error message that triggered the auto-fix
|
|
219
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
220
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
221
|
+
}, (table) => ({
|
|
222
|
+
projectIdIdx: index("generation_sessions_project_id_idx").on(table.projectId),
|
|
223
|
+
buildIdUnique: uniqueIndex("generation_sessions_build_id_unique").on(table.buildId)
|
|
224
|
+
}));
|
|
225
|
+
var generationTodos = pgTable("generation_todos", {
|
|
226
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
227
|
+
sessionId: uuid("session_id").notNull().references(() => generationSessions.id, { onDelete: "cascade" }),
|
|
228
|
+
todoIndex: integer("todo_index").notNull(),
|
|
229
|
+
content: text("content").notNull(),
|
|
230
|
+
activeForm: text("active_form"),
|
|
231
|
+
status: text("status").notNull(),
|
|
232
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
233
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
234
|
+
}, (table) => ({
|
|
235
|
+
sessionIdIdx: index("generation_todos_session_id_idx").on(table.sessionId),
|
|
236
|
+
sessionIndexUnique: uniqueIndex("generation_todos_session_index_unique").on(table.sessionId, table.todoIndex)
|
|
237
|
+
}));
|
|
238
|
+
var generationToolCalls = pgTable("generation_tool_calls", {
|
|
239
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
240
|
+
sessionId: uuid("session_id").notNull().references(() => generationSessions.id, { onDelete: "cascade" }),
|
|
241
|
+
todoIndex: integer("todo_index").notNull(),
|
|
242
|
+
toolCallId: text("tool_call_id").notNull(),
|
|
243
|
+
name: text("name").notNull(),
|
|
244
|
+
input: jsonb("input"),
|
|
245
|
+
output: jsonb("output"),
|
|
246
|
+
state: text("state").notNull(),
|
|
247
|
+
startedAt: timestamp("started_at").notNull().defaultNow(),
|
|
248
|
+
endedAt: timestamp("ended_at"),
|
|
249
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
250
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
251
|
+
}, (table) => ({
|
|
252
|
+
sessionIdIdx: index("generation_tool_calls_session_id_idx").on(table.sessionId),
|
|
253
|
+
toolCallUnique: uniqueIndex("generation_tool_calls_call_id_unique").on(table.sessionId, table.toolCallId)
|
|
254
|
+
}));
|
|
255
|
+
var generationNotes = pgTable("generation_notes", {
|
|
256
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
257
|
+
sessionId: uuid("session_id").notNull().references(() => generationSessions.id, { onDelete: "cascade" }),
|
|
258
|
+
todoIndex: integer("todo_index").notNull(),
|
|
259
|
+
textId: text("text_id"),
|
|
260
|
+
kind: text("kind").notNull().default("text"),
|
|
261
|
+
content: text("content").notNull(),
|
|
262
|
+
createdAt: timestamp("created_at").notNull().defaultNow()
|
|
263
|
+
}, (table) => ({
|
|
264
|
+
sessionIdIdx: index("generation_notes_session_id_idx").on(table.sessionId),
|
|
265
|
+
textIdUnique: uniqueIndex("generation_notes_text_id_unique").on(table.sessionId, table.textId).where(sql`${table.textId} is not null`)
|
|
266
|
+
}));
|
|
267
|
+
var serverOperations = pgTable("server_operations", {
|
|
268
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
269
|
+
projectId: uuid("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
270
|
+
operation: text("operation").notNull(),
|
|
271
|
+
// 'start', 'stop', 'restart'
|
|
272
|
+
status: text("status").notNull().default("pending"),
|
|
273
|
+
// 'pending', 'sent', 'ack', 'completed', 'failed', 'timeout'
|
|
274
|
+
runnerId: text("runner_id"),
|
|
275
|
+
port: integer("port"),
|
|
276
|
+
pid: integer("pid"),
|
|
277
|
+
error: text("error"),
|
|
278
|
+
failureReason: text("failure_reason"),
|
|
279
|
+
// 'port_in_use', 'health_check_timeout', 'immediate_crash', etc.
|
|
280
|
+
retryCount: integer("retry_count").notNull().default(0),
|
|
281
|
+
metadata: jsonb("metadata"),
|
|
282
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
283
|
+
sentAt: timestamp("sent_at"),
|
|
284
|
+
ackAt: timestamp("ack_at"),
|
|
285
|
+
completedAt: timestamp("completed_at")
|
|
286
|
+
}, (table) => ({
|
|
287
|
+
projectIdIdx: index("server_operations_project_id_idx").on(table.projectId),
|
|
288
|
+
statusIdx: index("server_operations_status_idx").on(table.status),
|
|
289
|
+
createdAtIdx: index("server_operations_created_at_idx").on(table.createdAt)
|
|
290
|
+
}));
|
|
291
|
+
|
|
292
|
+
// src/lib/db/client.ts
|
|
293
|
+
var { Pool } = pg;
|
|
294
|
+
function createPostgresClient() {
|
|
295
|
+
const connectionString = process.env.DATABASE_URL;
|
|
296
|
+
if (!connectionString) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
'DATABASE_URL is not set. Please configure your database connection:\n - Run "openbuilder init" to set up a Neon database\n - Or set DATABASE_URL environment variable to your PostgreSQL connection string'
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
const pool = new Pool({
|
|
302
|
+
connectionString,
|
|
303
|
+
ssl: process.env.PGSSLMODE === "disable" ? false : { rejectUnauthorized: false }
|
|
304
|
+
});
|
|
305
|
+
const client = drizzle(pool, { schema: schema_exports });
|
|
306
|
+
return client;
|
|
307
|
+
}
|
|
308
|
+
new Proxy({}, {
|
|
309
|
+
get(_target, prop) {
|
|
310
|
+
if (!global.__db) {
|
|
311
|
+
global.__db = createPostgresClient();
|
|
312
|
+
}
|
|
313
|
+
return global.__db[prop];
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
var BuildLogger = class {
|
|
317
|
+
buildId = null;
|
|
318
|
+
projectId = null;
|
|
319
|
+
/**
|
|
320
|
+
* Set correlation IDs for the current build
|
|
321
|
+
* Call this at the start of each build to enable correlation tracking
|
|
322
|
+
*/
|
|
323
|
+
setBuildContext(buildId, projectId) {
|
|
324
|
+
this.buildId = buildId;
|
|
325
|
+
this.projectId = projectId;
|
|
326
|
+
this.log("debug", "runner", `Build context set: ${buildId} / ${projectId}`);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Clear correlation IDs after build completes
|
|
330
|
+
*/
|
|
331
|
+
clearBuildContext() {
|
|
332
|
+
this.log("debug", "runner", "Build context cleared");
|
|
333
|
+
this.buildId = null;
|
|
334
|
+
this.projectId = null;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Core logging method - creates structured log entries
|
|
338
|
+
* Public for custom logging needs
|
|
339
|
+
*/
|
|
340
|
+
log(level, context, message, data) {
|
|
341
|
+
if (process.env.SILENT_MODE === "1") {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (level === "info" || level === "debug") {
|
|
345
|
+
if (process.env.DEBUG_BUILD === "0") {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
({
|
|
350
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
351
|
+
buildId: this.buildId ?? void 0,
|
|
352
|
+
projectId: this.projectId ?? void 0});
|
|
353
|
+
const prefix = `[${context}]`;
|
|
354
|
+
const icon = {
|
|
355
|
+
debug: "\u{1F50D}",
|
|
356
|
+
info: "\u{1F4CB}",
|
|
357
|
+
warn: "\u26A0\uFE0F ",
|
|
358
|
+
error: "\u274C"
|
|
359
|
+
}[level];
|
|
360
|
+
const logFn = level === "error" ? console.error : level === "warn" ? console.warn : console.log;
|
|
361
|
+
if (data && Object.keys(data).length > 0) {
|
|
362
|
+
logFn(`${icon} ${prefix} ${message}`, data);
|
|
363
|
+
} else {
|
|
364
|
+
logFn(`${icon} ${prefix} ${message}`);
|
|
365
|
+
}
|
|
366
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "test") {
|
|
367
|
+
try {
|
|
368
|
+
if (level === "warn" || level === "error") {
|
|
369
|
+
addBreadcrumb({
|
|
370
|
+
category: `build-logger.${context}`,
|
|
371
|
+
message,
|
|
372
|
+
level: level === "error" ? "error" : "warning",
|
|
373
|
+
data: {
|
|
374
|
+
...data,
|
|
375
|
+
buildId: this.buildId,
|
|
376
|
+
projectId: this.projectId
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
} catch {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Orchestrator-specific logging methods
|
|
386
|
+
*/
|
|
387
|
+
orchestrator = {
|
|
388
|
+
newProject: (operationType) => this.log("info", "orchestrator", `NEW PROJECT (operationType: ${operationType})`),
|
|
389
|
+
existingProject: (operationType) => this.log("info", "orchestrator", `EXISTING PROJECT (operationType: ${operationType})`),
|
|
390
|
+
templateProvided: (templateName, templateId, framework) => this.log("info", "orchestrator", `Frontend provided template: ${templateName}`, {
|
|
391
|
+
templateId,
|
|
392
|
+
framework
|
|
393
|
+
}),
|
|
394
|
+
templateSelecting: (method) => this.log("info", "orchestrator", `Template selection: ${method}`),
|
|
395
|
+
templateSelected: (templateName, templateId) => this.log("info", "orchestrator", `Selected template: ${templateName}`, { templateId }),
|
|
396
|
+
templateDownloading: (templateName, repository, target) => this.log("info", "orchestrator", `Downloading template: ${templateName}`, {
|
|
397
|
+
repository,
|
|
398
|
+
target
|
|
399
|
+
}),
|
|
400
|
+
templateDownloaded: (templateName, path, fileTreeSize) => this.log("info", "orchestrator", `Template downloaded: ${templateName}`, {
|
|
401
|
+
path,
|
|
402
|
+
fileTreeSize
|
|
403
|
+
}),
|
|
404
|
+
catalogPrepared: (catalogSize) => this.log("info", "orchestrator", `Template catalog prepared (${catalogSize} chars)`, {
|
|
405
|
+
catalogSize
|
|
406
|
+
}),
|
|
407
|
+
systemPromptGenerated: (size) => this.log("info", "orchestrator", `System prompt generated (${size} chars)`, { size }),
|
|
408
|
+
orchestrationComplete: (data) => this.log("info", "orchestrator", "Orchestration complete", data),
|
|
409
|
+
error: (message, error) => this.log("error", "orchestrator", message, {
|
|
410
|
+
error: error instanceof Error ? error.message : String(error)
|
|
411
|
+
})
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Message transformer-specific logging methods
|
|
415
|
+
*/
|
|
416
|
+
transformer = {
|
|
417
|
+
todoListFound: () => this.log("debug", "transformer", "Found Codex task list, parsing..."),
|
|
418
|
+
todoListParsed: (todoCount, completed, inProgress, pending) => this.log("info", "transformer", `Parsed ${todoCount} todos`, {
|
|
419
|
+
completed,
|
|
420
|
+
inProgress,
|
|
421
|
+
pending
|
|
422
|
+
}),
|
|
423
|
+
todoListInvalidFormat: (expected, got) => this.log("error", "transformer", "Invalid todo format from Codex", {
|
|
424
|
+
expected,
|
|
425
|
+
got: JSON.stringify(got).substring(0, 200)
|
|
426
|
+
}),
|
|
427
|
+
todoListParseError: (error, rawJson) => this.log("error", "transformer", "Failed to parse Codex todolist", {
|
|
428
|
+
error: String(error),
|
|
429
|
+
rawJson: rawJson.substring(0, 300)
|
|
430
|
+
}),
|
|
431
|
+
todoListRemoved: () => this.log("debug", "transformer", "Removed task list from chat text"),
|
|
432
|
+
toolStarted: (toolName, toolId) => this.log("debug", "transformer", `Tool started: ${toolName}`, { toolName, toolId }),
|
|
433
|
+
toolCompleted: (toolName, toolId) => this.log("debug", "transformer", `Tool completed: ${toolName}`, { toolName, toolId }),
|
|
434
|
+
pathViolationWarning: (toolName, path, workspace) => this.log("warn", "transformer", `Path outside workspace: ${path}`, {
|
|
435
|
+
toolName,
|
|
436
|
+
path,
|
|
437
|
+
workspace
|
|
438
|
+
}),
|
|
439
|
+
desktopPathDetected: (path) => this.log("error", "transformer", `DESKTOP PATH DETECTED - Likely hallucinated: ${path}`, { path })
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* Codex query-specific logging methods
|
|
443
|
+
*/
|
|
444
|
+
codexQuery = {
|
|
445
|
+
promptBuilding: (workingDirectory, systemPromptSize, userPromptSize) => this.log("info", "codex-query", "Building Codex prompt", {
|
|
446
|
+
workingDirectory,
|
|
447
|
+
systemPromptSize,
|
|
448
|
+
userPromptSize
|
|
449
|
+
}),
|
|
450
|
+
threadStarting: () => this.log("info", "codex-query", "Starting Codex thread (multi-turn)"),
|
|
451
|
+
turnStarted: (turnNumber, maxTurns, promptSize) => this.log("info", "codex-query", `\u2550\u2550\u2550 Turn ${turnNumber}/${maxTurns} \u2550\u2550\u2550`, {
|
|
452
|
+
turnNumber,
|
|
453
|
+
maxTurns,
|
|
454
|
+
promptSize
|
|
455
|
+
}),
|
|
456
|
+
taskListExtracted: () => this.log("info", "codex-query", "Task list extracted and updated"),
|
|
457
|
+
taskListStatus: (completed, inProgress, pending, total) => this.log("info", "codex-query", `Tasks: ${completed} completed | ${inProgress} in_progress | ${pending} pending (total: ${total})`, {
|
|
458
|
+
completed,
|
|
459
|
+
inProgress,
|
|
460
|
+
pending,
|
|
461
|
+
total
|
|
462
|
+
}),
|
|
463
|
+
taskListTask: (index2, content, status, icon) => this.log("debug", "codex-query", ` ${icon} ${index2 + 1}. ${content}`, { status }),
|
|
464
|
+
taskListParseError: (error, rawContent) => this.log("error", "codex-query", "PARSE ERROR: Could not parse task list JSON", {
|
|
465
|
+
error: String(error),
|
|
466
|
+
rawContent: rawContent.substring(0, 200)
|
|
467
|
+
}),
|
|
468
|
+
taskListMissing: (turnNumber) => this.log("warn", "codex-query", `WARNING: No <start-todolist> tags found in Turn ${turnNumber}`, {
|
|
469
|
+
turnNumber
|
|
470
|
+
}),
|
|
471
|
+
turnComplete: (turnNumber, hadToolCalls, messageLength) => this.log("info", "codex-query", `Turn ${turnNumber} complete`, {
|
|
472
|
+
hadToolCalls,
|
|
473
|
+
messageLength
|
|
474
|
+
}),
|
|
475
|
+
tasksComplete: (completed, total) => this.log("info", "codex-query", `Task status: ${completed}/${total} completed`, {
|
|
476
|
+
completed,
|
|
477
|
+
total
|
|
478
|
+
}),
|
|
479
|
+
allComplete: () => this.log("info", "codex-query", "\u2705 All MVP tasks complete!"),
|
|
480
|
+
allTasksComplete: () => this.log("info", "codex-query", "\u2705 All MVP tasks complete!"),
|
|
481
|
+
taskCompleteDetected: () => this.log("info", "codex-query", "\u2705 Task complete (detected completion signal)"),
|
|
482
|
+
continuePrompting: (reason) => this.log("warn", "codex-query", `No tools used but not done - ${reason}`),
|
|
483
|
+
continuing: () => this.log("info", "codex-query", "\u23ED\uFE0F Continuing to next turn (had tool calls)"),
|
|
484
|
+
loopExited: (turnCount, maxTurns) => this.log("info", "codex-query", `EXITED WHILE LOOP after ${turnCount} turns`, {
|
|
485
|
+
turnCount,
|
|
486
|
+
maxTurns
|
|
487
|
+
}),
|
|
488
|
+
sessionComplete: (turnCount) => this.log("info", "codex-query", `Session complete after ${turnCount} turns`, { turnCount }),
|
|
489
|
+
error: (message, error) => this.log("error", "codex-query", message, {
|
|
490
|
+
error: error instanceof Error ? error.message : String(error)
|
|
491
|
+
})
|
|
492
|
+
};
|
|
493
|
+
/**
|
|
494
|
+
* Claude query-specific logging methods
|
|
495
|
+
*/
|
|
496
|
+
claudeQuery = {
|
|
497
|
+
queryStarted: (model, cwd, maxTurns) => this.log("info", "claude-query", `Starting Claude query (${model})`, {
|
|
498
|
+
cwd,
|
|
499
|
+
maxTurns
|
|
500
|
+
}),
|
|
501
|
+
error: (message, error) => this.log("error", "claude-query", message, {
|
|
502
|
+
error: error instanceof Error ? error.message : String(error)
|
|
503
|
+
})
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Runner-specific logging methods
|
|
507
|
+
*/
|
|
508
|
+
runner = {
|
|
509
|
+
workspaceRoot: (path) => this.log("info", "runner", `Workspace root: ${path}`, { path }),
|
|
510
|
+
commandReceived: (commandType, projectId) => this.log("info", "runner", `Received command: ${commandType}`, { commandType, projectId }),
|
|
511
|
+
buildOperation: (operationType, projectSlug, agentId) => this.log("info", "runner", `Build operation: ${operationType}`, {
|
|
512
|
+
operationType,
|
|
513
|
+
projectSlug,
|
|
514
|
+
agentId
|
|
515
|
+
}),
|
|
516
|
+
templateProvided: (templateId) => this.log("info", "runner", `Template provided by frontend: ${templateId}`, { templateId }),
|
|
517
|
+
buildStreamCreated: () => this.log("info", "runner", "Build stream created, starting to process chunks..."),
|
|
518
|
+
firstChunkReceived: (agentLabel) => this.log("info", "runner", `First chunk received from ${agentLabel}`, { agentLabel }),
|
|
519
|
+
streamEnded: (chunkCount) => this.log("info", "runner", `Stream ended after ${chunkCount} chunks`, { chunkCount }),
|
|
520
|
+
buildCompleted: (projectId) => this.log("info", "runner", `Build completed successfully`, { projectId }),
|
|
521
|
+
buildFailed: (error) => this.log("error", "runner", `Build failed: ${error}`, { error }),
|
|
522
|
+
portDetected: (port) => this.log("info", "runner", `Port detected: ${port}`, { port }),
|
|
523
|
+
tunnelCreated: (port, tunnelUrl) => this.log("info", "runner", `Tunnel created: ${tunnelUrl} \u2192 localhost:${port}`, {
|
|
524
|
+
port,
|
|
525
|
+
tunnelUrl
|
|
526
|
+
}),
|
|
527
|
+
error: (message, error, context) => this.log("error", "runner", message, {
|
|
528
|
+
error: error instanceof Error ? error.message : String(error),
|
|
529
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
530
|
+
...context
|
|
531
|
+
})
|
|
532
|
+
};
|
|
533
|
+
/**
|
|
534
|
+
* Build stream-specific logging (tool calls, text, etc.)
|
|
535
|
+
*/
|
|
536
|
+
build = {
|
|
537
|
+
agentText: (agentLabel, text2) => {
|
|
538
|
+
const truncated = text2.length > 200 ? text2.slice(0, 200) + "..." : text2;
|
|
539
|
+
this.log("debug", "build", `${agentLabel}: ${truncated}`, {
|
|
540
|
+
agentLabel,
|
|
541
|
+
textLength: text2.length
|
|
542
|
+
});
|
|
543
|
+
},
|
|
544
|
+
agentThinking: (thinking) => {
|
|
545
|
+
const truncated = thinking.length > 300 ? thinking.slice(0, 300) + "..." : thinking;
|
|
546
|
+
this.log("debug", "build", `Thinking: ${truncated}`, {
|
|
547
|
+
thinkingLength: thinking.length
|
|
548
|
+
});
|
|
549
|
+
},
|
|
550
|
+
toolCalled: (toolName, toolId, inputSize) => this.log("info", "build", `Tool called: ${toolName} (${toolId})`, {
|
|
551
|
+
toolName,
|
|
552
|
+
toolId,
|
|
553
|
+
inputSize
|
|
554
|
+
}),
|
|
555
|
+
toolResult: (toolId, outputSize, isError) => this.log(isError ? "error" : "info", "build", `Tool result (${toolId})`, {
|
|
556
|
+
toolId,
|
|
557
|
+
outputSize,
|
|
558
|
+
isError
|
|
559
|
+
}),
|
|
560
|
+
runCommandDetected: (runCommand) => this.log("info", "build", `Detected runCommand: ${runCommand}`, { runCommand })
|
|
561
|
+
};
|
|
562
|
+
/**
|
|
563
|
+
* WebSocket-specific logging methods
|
|
564
|
+
*/
|
|
565
|
+
websocket = {
|
|
566
|
+
serverCreated: (instanceId) => this.log("info", "websocket", `WebSocket server instance created`, { instanceId }),
|
|
567
|
+
serverInitialized: (path, runnerPath) => this.log("info", "websocket", `Server initialized`, { path, runnerPath }),
|
|
568
|
+
clientConnected: (clientId, projectId, sessionId) => this.log("info", "websocket", `Client connected: ${clientId}`, { clientId, projectId, sessionId }),
|
|
569
|
+
clientDisconnected: (clientId) => this.log("info", "websocket", `Client disconnected: ${clientId}`, { clientId }),
|
|
570
|
+
clientSubscribed: (clientId, projectId) => this.log("info", "websocket", `Client subscribed to project: ${projectId}`, { clientId, projectId }),
|
|
571
|
+
clientTimeout: (clientId) => this.log("warn", "websocket", `Client timeout: ${clientId}`, { clientId }),
|
|
572
|
+
runnerConnected: (runnerId) => this.log("info", "websocket", `Runner connected: ${runnerId}`, { runnerId }),
|
|
573
|
+
runnerDisconnected: (runnerId, code) => this.log("info", "websocket", `Runner disconnected: ${runnerId}`, { runnerId, code }),
|
|
574
|
+
runnerNotConnected: (runnerId, commandType) => this.log("warn", "websocket", `Cannot send command to runner ${runnerId}: not connected`, {
|
|
575
|
+
runnerId,
|
|
576
|
+
commandType
|
|
577
|
+
}),
|
|
578
|
+
runnerAuthRejected: () => this.log("warn", "websocket", `Runner connection rejected: invalid auth`),
|
|
579
|
+
runnerAuthMissing: () => this.log("error", "websocket", `RUNNER_SHARED_SECRET is not configured`),
|
|
580
|
+
runnerStaleRemoved: (runnerId) => this.log("info", "websocket", `Removing stale runner connection: ${runnerId}`, { runnerId }),
|
|
581
|
+
commandSent: (runnerId, commandType, traceAttached) => this.log("debug", "websocket", `Sent command to runner: ${commandType}`, {
|
|
582
|
+
runnerId,
|
|
583
|
+
commandType,
|
|
584
|
+
traceAttached
|
|
585
|
+
}),
|
|
586
|
+
eventReceived: (runnerId, eventType) => this.log("debug", "websocket", `Received event from runner: ${eventType}`, {
|
|
587
|
+
runnerId,
|
|
588
|
+
eventType
|
|
589
|
+
}),
|
|
590
|
+
broadcastToolCall: (toolName, toolState, subscriberCount) => this.log("info", "websocket", `Broadcasting planning tool: ${toolName} (state=${toolState})`, {
|
|
591
|
+
toolName,
|
|
592
|
+
toolState,
|
|
593
|
+
subscriberCount
|
|
594
|
+
}),
|
|
595
|
+
broadcastBuildComplete: (projectId, sessionId, subscriberCount) => this.log("info", "websocket", `Broadcasting build-complete`, {
|
|
596
|
+
projectId,
|
|
597
|
+
sessionId,
|
|
598
|
+
subscriberCount
|
|
599
|
+
}),
|
|
600
|
+
unknownUpgradePath: (pathname) => this.log("warn", "websocket", `Unknown upgrade path: ${pathname}`, { pathname }),
|
|
601
|
+
shutdown: () => this.log("info", "websocket", `Shutting down server...`),
|
|
602
|
+
shutdownComplete: () => this.log("info", "websocket", `Server shut down`),
|
|
603
|
+
error: (message, error, context) => this.log("error", "websocket", message, {
|
|
604
|
+
error: error instanceof Error ? error.message : String(error),
|
|
605
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
606
|
+
...context
|
|
607
|
+
})
|
|
608
|
+
};
|
|
609
|
+
/**
|
|
610
|
+
* Port allocator-specific logging methods
|
|
611
|
+
*/
|
|
612
|
+
portAllocator = {
|
|
613
|
+
portAllocated: (port, projectId) => this.log("info", "port-allocator", `Port allocated: ${port}`, { port, projectId }),
|
|
614
|
+
portReleased: (port, projectId) => this.log("info", "port-allocator", `Port released: ${port}`, { port, projectId }),
|
|
615
|
+
portInUse: (port) => this.log("warn", "port-allocator", `Port ${port} is already in use`, { port }),
|
|
616
|
+
portRangeExhausted: (minPort, maxPort) => this.log("error", "port-allocator", `No available ports in range ${minPort}-${maxPort}`, {
|
|
617
|
+
minPort,
|
|
618
|
+
maxPort
|
|
619
|
+
}),
|
|
620
|
+
portConflict: (port, projectId, existingProjectId) => this.log("warn", "port-allocator", `Port ${port} conflict detected`, {
|
|
621
|
+
port,
|
|
622
|
+
projectId,
|
|
623
|
+
existingProjectId
|
|
624
|
+
}),
|
|
625
|
+
allocationsCleared: (count) => this.log("info", "port-allocator", `Cleared ${count} port allocations`, { count }),
|
|
626
|
+
error: (message, error, context) => this.log("error", "port-allocator", message, {
|
|
627
|
+
error: error instanceof Error ? error.message : String(error),
|
|
628
|
+
...context
|
|
629
|
+
})
|
|
630
|
+
};
|
|
631
|
+
/**
|
|
632
|
+
* Process manager-specific logging methods
|
|
633
|
+
*/
|
|
634
|
+
processManager = {
|
|
635
|
+
processStarting: (projectId, command, cwd) => this.log("info", "process-manager", `Starting process: ${command}`, {
|
|
636
|
+
projectId,
|
|
637
|
+
command,
|
|
638
|
+
cwd
|
|
639
|
+
}),
|
|
640
|
+
processStarted: (projectId, pid) => this.log("info", "process-manager", `Process started`, { projectId, pid }),
|
|
641
|
+
processOutput: (projectId, output) => this.log("debug", "process-manager", `Process output: ${output.substring(0, 100)}`, {
|
|
642
|
+
projectId,
|
|
643
|
+
outputLength: output.length
|
|
644
|
+
}),
|
|
645
|
+
processError: (projectId, error) => this.log("error", "process-manager", `Process error: ${error}`, { projectId, error }),
|
|
646
|
+
processExited: (projectId, code, signal) => this.log("info", "process-manager", `Process exited`, { projectId, code, signal }),
|
|
647
|
+
processStopped: (projectId) => this.log("info", "process-manager", `Process stopped`, { projectId }),
|
|
648
|
+
processNotFound: (projectId) => this.log("warn", "process-manager", `Process not found for project: ${projectId}`, { projectId }),
|
|
649
|
+
processKilled: (projectId, signal) => this.log("info", "process-manager", `Process killed with signal: ${signal}`, {
|
|
650
|
+
projectId,
|
|
651
|
+
signal
|
|
652
|
+
}),
|
|
653
|
+
processCleanup: (projectId) => this.log("info", "process-manager", `Cleaning up process`, { projectId }),
|
|
654
|
+
processListRetrieved: (count) => this.log("debug", "process-manager", `Retrieved ${count} running processes`, { count }),
|
|
655
|
+
error: (message, error, context) => this.log("error", "process-manager", message, {
|
|
656
|
+
error: error instanceof Error ? error.message : String(error),
|
|
657
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
658
|
+
...context
|
|
659
|
+
})
|
|
660
|
+
};
|
|
661
|
+
/**
|
|
662
|
+
* Build events-specific logging methods
|
|
663
|
+
*/
|
|
664
|
+
buildEvents = {
|
|
665
|
+
eventReceived: (eventType, projectId, sessionId) => this.log("info", "build-events", `Received event: ${eventType}`, {
|
|
666
|
+
eventType,
|
|
667
|
+
projectId,
|
|
668
|
+
sessionId
|
|
669
|
+
}),
|
|
670
|
+
eventProcessed: (eventType, projectId) => this.log("debug", "build-events", `Processed event: ${eventType}`, { eventType, projectId }),
|
|
671
|
+
buildStarted: (projectId, sessionId) => this.log("info", "build-events", `Build started`, { projectId, sessionId }),
|
|
672
|
+
buildCompleted: (projectId, sessionId, success) => this.log("info", "build-events", `Build ${success ? "completed" : "failed"}`, {
|
|
673
|
+
projectId,
|
|
674
|
+
sessionId,
|
|
675
|
+
success
|
|
676
|
+
}),
|
|
677
|
+
portDetected: (projectId, port) => this.log("info", "build-events", `Port detected: ${port}`, { projectId, port }),
|
|
678
|
+
devServerStarted: (projectId, port, url) => this.log("info", "build-events", `Dev server started: ${url}`, { projectId, port, url }),
|
|
679
|
+
devServerError: (projectId, error) => this.log("error", "build-events", `Dev server error: ${error}`, { projectId, error }),
|
|
680
|
+
toolCallReceived: (toolName, toolId) => this.log("debug", "build-events", `Tool call: ${toolName}`, { toolName, toolId }),
|
|
681
|
+
logChunkReceived: (projectId, chunkSize) => this.log("debug", "build-events", `Log chunk received`, { projectId, chunkSize }),
|
|
682
|
+
invalidEvent: (reason) => this.log("warn", "build-events", `Invalid event: ${reason}`, { reason }),
|
|
683
|
+
error: (message, error, context) => this.log("error", "build-events", message, {
|
|
684
|
+
error: error instanceof Error ? error.message : String(error),
|
|
685
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
686
|
+
...context
|
|
687
|
+
})
|
|
688
|
+
};
|
|
689
|
+
};
|
|
690
|
+
var buildLogger = new BuildLogger();
|
|
691
|
+
async function detectFrameworkFromFilesystem(projectPath) {
|
|
692
|
+
try {
|
|
693
|
+
let cachedPkg = null;
|
|
694
|
+
const loadPackageJson = async () => {
|
|
695
|
+
if (cachedPkg) return cachedPkg;
|
|
696
|
+
const pkgPath = join(projectPath, "package.json");
|
|
697
|
+
if (!existsSync(pkgPath)) {
|
|
698
|
+
cachedPkg = null;
|
|
699
|
+
return cachedPkg;
|
|
700
|
+
}
|
|
701
|
+
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
702
|
+
const pkg2 = JSON.parse(pkgContent);
|
|
703
|
+
cachedPkg = {
|
|
704
|
+
deps: { ...pkg2.dependencies ?? {}, ...pkg2.peerDependencies ?? {} },
|
|
705
|
+
devDeps: pkg2.devDependencies ?? {},
|
|
706
|
+
devScript: pkg2.scripts?.dev?.toLowerCase() ?? ""
|
|
707
|
+
};
|
|
708
|
+
return cachedPkg;
|
|
709
|
+
};
|
|
710
|
+
const hasTanStackDependency = async () => {
|
|
711
|
+
const pkg2 = await loadPackageJson();
|
|
712
|
+
if (!pkg2) return false;
|
|
713
|
+
const combined = { ...pkg2.deps, ...pkg2.devDeps };
|
|
714
|
+
if (combined["@tanstack/react-start"]) return true;
|
|
715
|
+
if (pkg2.devScript.includes("tanstack")) return true;
|
|
716
|
+
return false;
|
|
717
|
+
};
|
|
718
|
+
if (existsSync(join(projectPath, "astro.config.mjs")) || existsSync(join(projectPath, "astro.config.ts")) || existsSync(join(projectPath, "astro.config.js"))) {
|
|
719
|
+
return "astro";
|
|
720
|
+
}
|
|
721
|
+
if (existsSync(join(projectPath, "next.config.ts")) || existsSync(join(projectPath, "next.config.js")) || existsSync(join(projectPath, "next.config.mjs"))) {
|
|
722
|
+
return "next";
|
|
723
|
+
}
|
|
724
|
+
if (existsSync(join(projectPath, "vite.config.ts")) || existsSync(join(projectPath, "vite.config.js"))) {
|
|
725
|
+
if (await hasTanStackDependency()) {
|
|
726
|
+
return "tanstack";
|
|
727
|
+
}
|
|
728
|
+
return "vite";
|
|
729
|
+
}
|
|
730
|
+
const pkg = await loadPackageJson();
|
|
731
|
+
if (pkg) {
|
|
732
|
+
const allDeps = { ...pkg.deps, ...pkg.devDeps };
|
|
733
|
+
if (allDeps["astro"]) return "astro";
|
|
734
|
+
if (allDeps["@tanstack/react-start"]) return "tanstack";
|
|
735
|
+
if (allDeps["next"]) return "next";
|
|
736
|
+
if (allDeps["vite"]) return "vite";
|
|
737
|
+
if (pkg.devScript.includes("tanstack")) return "tanstack";
|
|
738
|
+
if (pkg.devScript.includes("astro")) return "astro";
|
|
739
|
+
if (pkg.devScript.includes("next")) return "next";
|
|
740
|
+
if (pkg.devScript.includes("vite")) return "vite";
|
|
741
|
+
}
|
|
742
|
+
} catch (error) {
|
|
743
|
+
buildLogger.portAllocator.error("Failed to detect framework from filesystem", error);
|
|
744
|
+
}
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
export { detectFrameworkFromFilesystem };
|
|
749
|
+
//# sourceMappingURL=port-allocator-BRFzgH9b.js.map
|