@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.
Files changed (78) hide show
  1. package/README.md +1053 -0
  2. package/bin/openbuilder.js +31 -0
  3. package/dist/chunks/Banner-D4tqKfzA.js +113 -0
  4. package/dist/chunks/Banner-D4tqKfzA.js.map +1 -0
  5. package/dist/chunks/auto-update-Dj3lWPWO.js +350 -0
  6. package/dist/chunks/auto-update-Dj3lWPWO.js.map +1 -0
  7. package/dist/chunks/build-D0qYqIq0.js +116 -0
  8. package/dist/chunks/build-D0qYqIq0.js.map +1 -0
  9. package/dist/chunks/cleanup-qVTsA3tk.js +141 -0
  10. package/dist/chunks/cleanup-qVTsA3tk.js.map +1 -0
  11. package/dist/chunks/cli-error-BjQwvWtK.js +140 -0
  12. package/dist/chunks/cli-error-BjQwvWtK.js.map +1 -0
  13. package/dist/chunks/config-BGP1jZJ4.js +167 -0
  14. package/dist/chunks/config-BGP1jZJ4.js.map +1 -0
  15. package/dist/chunks/config-manager-BkbjtN-H.js +133 -0
  16. package/dist/chunks/config-manager-BkbjtN-H.js.map +1 -0
  17. package/dist/chunks/database-BvAbD4sP.js +68 -0
  18. package/dist/chunks/database-BvAbD4sP.js.map +1 -0
  19. package/dist/chunks/database-setup-BYjIRAmT.js +253 -0
  20. package/dist/chunks/database-setup-BYjIRAmT.js.map +1 -0
  21. package/dist/chunks/exports-ij9sv4UM.js +7793 -0
  22. package/dist/chunks/exports-ij9sv4UM.js.map +1 -0
  23. package/dist/chunks/init-CZoN6soU.js +468 -0
  24. package/dist/chunks/init-CZoN6soU.js.map +1 -0
  25. package/dist/chunks/init-tui-BNzk_7Yx.js +1127 -0
  26. package/dist/chunks/init-tui-BNzk_7Yx.js.map +1 -0
  27. package/dist/chunks/logger-ZpJi7chw.js +38 -0
  28. package/dist/chunks/logger-ZpJi7chw.js.map +1 -0
  29. package/dist/chunks/main-tui-Cq1hLCx-.js +644 -0
  30. package/dist/chunks/main-tui-Cq1hLCx-.js.map +1 -0
  31. package/dist/chunks/manager-CvGX9qqe.js +1161 -0
  32. package/dist/chunks/manager-CvGX9qqe.js.map +1 -0
  33. package/dist/chunks/port-allocator-BRFzgH9b.js +749 -0
  34. package/dist/chunks/port-allocator-BRFzgH9b.js.map +1 -0
  35. package/dist/chunks/process-killer-CaUL7Kpl.js +87 -0
  36. package/dist/chunks/process-killer-CaUL7Kpl.js.map +1 -0
  37. package/dist/chunks/prompts-1QbE_bRr.js +128 -0
  38. package/dist/chunks/prompts-1QbE_bRr.js.map +1 -0
  39. package/dist/chunks/repo-cloner-CpOQjFSo.js +219 -0
  40. package/dist/chunks/repo-cloner-CpOQjFSo.js.map +1 -0
  41. package/dist/chunks/repo-detector-B_oj696o.js +66 -0
  42. package/dist/chunks/repo-detector-B_oj696o.js.map +1 -0
  43. package/dist/chunks/run-D23hg4xy.js +630 -0
  44. package/dist/chunks/run-D23hg4xy.js.map +1 -0
  45. package/dist/chunks/runner-logger-instance-nDWv2h2T.js +899 -0
  46. package/dist/chunks/runner-logger-instance-nDWv2h2T.js.map +1 -0
  47. package/dist/chunks/spinner-BJL9zWAJ.js +53 -0
  48. package/dist/chunks/spinner-BJL9zWAJ.js.map +1 -0
  49. package/dist/chunks/start-BygPCbvw.js +1708 -0
  50. package/dist/chunks/start-BygPCbvw.js.map +1 -0
  51. package/dist/chunks/start-traditional-uoLZXdxm.js +255 -0
  52. package/dist/chunks/start-traditional-uoLZXdxm.js.map +1 -0
  53. package/dist/chunks/status-cS8YwtUx.js +97 -0
  54. package/dist/chunks/status-cS8YwtUx.js.map +1 -0
  55. package/dist/chunks/theme-DhorI2Hb.js +44 -0
  56. package/dist/chunks/theme-DhorI2Hb.js.map +1 -0
  57. package/dist/chunks/upgrade-CT6w0lKp.js +323 -0
  58. package/dist/chunks/upgrade-CT6w0lKp.js.map +1 -0
  59. package/dist/chunks/useBuildState-CdBSu9y_.js +331 -0
  60. package/dist/chunks/useBuildState-CdBSu9y_.js.map +1 -0
  61. package/dist/cli/index.js +694 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/index.js +14358 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/instrument.js +64226 -0
  66. package/dist/instrument.js.map +1 -0
  67. package/dist/templates.json +295 -0
  68. package/package.json +98 -0
  69. package/scripts/install-vendor-deps.js +34 -0
  70. package/scripts/install-vendor.js +167 -0
  71. package/scripts/prepare-release.js +71 -0
  72. package/templates/config.template.json +18 -0
  73. package/templates.json +295 -0
  74. package/vendor/ai-sdk-provider-claude-code-LOCAL.tgz +0 -0
  75. package/vendor/sentry-core-LOCAL.tgz +0 -0
  76. package/vendor/sentry-nextjs-LOCAL.tgz +0 -0
  77. package/vendor/sentry-node-LOCAL.tgz +0 -0
  78. 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