Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit7f992cdunknown_key

fix: resolve post-merge TypeScript errors and integration wiring

fix: resolve post-merge TypeScript errors and integration wiring

- Remove duplicate wrong-numbered migrations (0088_pr_visits, 0088_repo_onboarding,
  0089_smart_digest_pref) — correct versions already exist at 0096-0100
- schema.ts: add depUpdaterEnabled column to repositories (was in migration 0092
  but missing from Drizzle definition)
- schema.ts: add "migrate" and "deployments" to RepoNavActive type union
- pulls.tsx: restore all imports removed during merge — codeowners
  (getCodeownersForRepo, reviewersForChangedFiles), pattern-detector
  (Pattern, getPatternWarning), pr-splitter (suggestPrSplit, SplitSuggestion),
  bus-factor (getBusFactorWarning, BusFactorFile), branch-rules (checkMergeEligible),
  pr-presence (getRoomUsers, pingSession, updatePresence + WebSocket setup)
- pulls.tsx: restore presenceWebsocket export via createBunWebSocket()
- pulls.tsx: restore busRiskFiles and splitSuggestion variable computation
- post-receive.ts: add missing fireCloudDeploys import from cloud-deploy
- autopilot.ts: add missing runDepUpdateSweepOnce import from dep-updater-sweep

https://claude.ai/code/session_01DzJMTFASjMHt2f5ze4cNLR
Claude committed on June 7, 2026Parent: 0410f22
8 files changed+61227f992cd57d96fae881d93d9ce8696349c5051f38
8 changed files+61−26
Deleteddrizzle/0088_pr_visits.sql+0−6View fileUnifiedSplit
1CREATE TABLE IF NOT EXISTS pr_visits (
2 pr_id UUID NOT NULL REFERENCES pull_requests(id) ON DELETE CASCADE,
3 user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
4 visited_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
5 PRIMARY KEY (pr_id, user_id)
6);
Deleteddrizzle/0088_repo_onboarding.sql+0−17View fileUnifiedSplit
1
2ALTER TABLE repositories ADD COLUMN IF NOT EXISTS onboarding_shown BOOLEAN NOT NULL DEFAULT false;
3
4CREATE TABLE IF NOT EXISTS repo_onboarding_data (
5 repository_id UUID PRIMARY KEY REFERENCES repositories(id) ON DELETE CASCADE,
6 detected_language TEXT,
7 detected_framework TEXT,
8 suggested_readme TEXT,
9 suggested_labels JSONB NOT NULL DEFAULT '[]',
10 suggested_gates_config TEXT,
11 first_commit_suggestions JSONB NOT NULL DEFAULT '[]',
12 generated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
13);
Deleteddrizzle/0089_smart_digest_pref.sql+0−2View fileUnifiedSplit
1ALTER TABLE users ADD COLUMN IF NOT EXISTS notify_smart_digest BOOLEAN NOT NULL DEFAULT true;
2ALTER TABLE users ADD COLUMN IF NOT EXISTS last_smart_digest_sent_at TIMESTAMPTZ;
Modifiedsrc/db/schema.ts+1−0View fileUnifiedSplit
246246 // Migration 0088 — smart empty states. Set to true once the onboarding
247247 // card has been dismissed by the repo owner. Generated on first push.
248248 onboardingShown: boolean("onboarding_shown").default(false).notNull(),
249 depUpdaterEnabled: boolean("dep_updater_enabled").default(false).notNull(),
249250 },
250251 (table) => [
251252 // Partial: uniqueness only in the user namespace (org-owned rows exempt).
Modifiedsrc/hooks/post-receive.ts+1−0View fileUnifiedSplit
3636 startDeployRow,
3737} from "../lib/server-target-store";
3838import { deployToTarget } from "../lib/server-targets";
39import { fireCloudDeploys } from "../lib/cloud-deploy";
3940import { ensureRepoOnboarding } from "../lib/repo-onboarding";
4041
4142interface PushRef {
Modifiedsrc/lib/autopilot.ts+1−0View fileUnifiedSplit
7373import { runOnboardingDripTaskOnce } from "./onboarding-drip";
7474import { sendSmartDigestsToAll } from "./smart-digest";
7575import { runAiLoopSweepOnce } from "./ai-loop";
76import { runDepUpdateSweepOnce } from "./dep-updater-sweep";
7677
7778export interface AutopilotTaskResult {
7879 name: string;
Modifiedsrc/routes/pulls.tsx+55−0View fileUnifiedSplit
127127import { BOT_USERNAME } from "../lib/bot-user";
128128import { analyzeImpact, type ImpactAnalysis } from "../lib/pr-impact";
129129import { getPreviewDir, isPreviewExpired } from "../lib/pr-stage";
130import {
131 getCodeownersForRepo,
132 reviewersForChangedFiles,
133} from "../lib/codeowners";
134import { getPatternWarning, type Pattern } from "../lib/pattern-detector";
135import { suggestPrSplit, type SplitSuggestion } from "../lib/pr-splitter";
136import {
137 joinRoom,
138 leaveRoom,
139 broadcastToRoom,
140 registerSocket,
141 unregisterSocket,
142 getRoomUsers,
143 pingSession,
144 updatePresence,
145} from "../lib/pr-presence";
146import { getBusFactorWarning, type BusFactorFile } from "../lib/bus-factor";
147import { checkMergeEligible } from "../lib/branch-rules";
148import { createBunWebSocket } from "hono/bun";
149
150const { upgradeWebSocket, websocket: presenceWebsocket } = createBunWebSocket();
151export { presenceWebsocket };
130152
131153const pulls = new Hono<AuthEnv>();
132154
42754297 // Non-blocking — swallow
42764298 }
42774299
4300 // Bus factor warning — flag files dominated by a single author.
4301 let busRiskFiles: BusFactorFile[] = [];
4302 try {
4303 const repoDir2 = getRepoPath(ownerName, repoName);
4304 const bf2Proc = Bun.spawn(
4305 ["git", "diff", "--name-only", `${pr.baseBranch}...${pr.headBranch}`],
4306 { cwd: repoDir2, stdout: "pipe", stderr: "pipe" }
4307 );
4308 const bf2Raw = await new Response(bf2Proc.stdout).text();
4309 await bf2Proc.exited;
4310 const bf2Files = bf2Raw.trim().split("\n").filter(Boolean);
4311 if (bf2Files.length > 0) {
4312 busRiskFiles = await getBusFactorWarning(resolved.repo.id, ownerName, repoName, bf2Files);
4313 }
4314 } catch {
4315 // Non-blocking
4316 }
4317
4318 // PR split suggestion — AI recommends sub-PR decomposition for large PRs.
4319 let splitSuggestion: SplitSuggestion | null = null;
4320 try {
4321 splitSuggestion = await suggestPrSplit(
4322 pr.id,
4323 pr.title,
4324 ownerName,
4325 repoName,
4326 pr.baseBranch,
4327 pr.headBranch
4328 );
4329 } catch {
4330 // Non-blocking
4331 }
4332
42784333 // ─── Derived visual state ───
42794334 const stateKey =
42804335 pr.state === "open"
Modifiedsrc/views/components.tsx+3−1View fileUnifiedSplit
151151 | "discussions"
152152 | "security"
153153 | "settings"
154 | "debt-map";
154 | "debt-map"
155 | "migrate"
156 | "deployments";
155157}> = ({ owner, repo, active }) => (
156158 <div class="repo-nav">
157159 <a href={`/${owner}/${repo}`} class={active === "code" ? "active" : ""}>
158160