@rulemetric/cli 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-command.js +4 -3
- package/dist/{chunk-SZ7VDCD6.js → chunk-2HK7RGZB.js} +22 -3
- package/dist/chunk-2HK7RGZB.js.map +7 -0
- package/dist/{chunk-RUCSRN7F.js → chunk-2ORJWTNZ.js} +2 -2
- package/dist/{chunk-SLL3OBKN.js → chunk-37LN5O7M.js} +2 -2
- package/dist/{chunk-RCMXTLQF.js → chunk-3LKVS6W5.js} +5 -5
- package/dist/{chunk-XN23W5HL.js → chunk-4KRMZLQV.js} +91 -7
- package/dist/chunk-4KRMZLQV.js.map +7 -0
- package/dist/{chunk-DAJNO4OI.js → chunk-4LYCDS2N.js} +28 -16
- package/dist/chunk-4LYCDS2N.js.map +7 -0
- package/dist/{chunk-UPXIO7CG.js → chunk-4XAWK6S2.js} +8 -8
- package/dist/{chunk-N5A2IQAK.js → chunk-4YAP7RT7.js} +5 -5
- package/dist/{chunk-QD6X4L4L.js → chunk-5BAOGNUH.js} +4 -4
- package/dist/chunk-5EDMGK3W.js +39 -0
- package/dist/chunk-5EDMGK3W.js.map +7 -0
- package/dist/{chunk-5ADHO5QF.js → chunk-6NBS5XFS.js} +6 -6
- package/dist/chunk-7LVVKQMZ.js +98 -0
- package/dist/chunk-7LVVKQMZ.js.map +7 -0
- package/dist/{chunk-PXVQLD7S.js → chunk-7NNFYWKK.js} +48 -1
- package/dist/chunk-7NNFYWKK.js.map +7 -0
- package/dist/{chunk-BBLTN35F.js → chunk-7UDETV3P.js} +49 -20
- package/dist/chunk-7UDETV3P.js.map +7 -0
- package/dist/{chunk-DTFXCHHI.js → chunk-DNKSVWMD.js} +4 -4
- package/dist/{chunk-6EMZI4Y3.js → chunk-EI5BHWXA.js} +437 -401
- package/dist/chunk-EI5BHWXA.js.map +7 -0
- package/dist/{chunk-HNZLEEG2.js → chunk-EJ3YAFDP.js} +4 -4
- package/dist/{chunk-HNZLEEG2.js.map → chunk-EJ3YAFDP.js.map} +2 -2
- package/dist/{chunk-YSEQWCN4.js → chunk-EYPAAGN5.js} +2 -2
- package/dist/{chunk-JEJ3J5J6.js → chunk-GIUBARWS.js} +2 -2
- package/dist/chunk-GQNJO2P2.js +102 -0
- package/dist/chunk-GQNJO2P2.js.map +7 -0
- package/dist/{chunk-CNMWYYSV.js → chunk-HZK43UCF.js} +6 -6
- package/dist/chunk-ILYDELUE.js +46 -0
- package/dist/chunk-ILYDELUE.js.map +7 -0
- package/dist/chunk-J6QFW4LD.js +55 -0
- package/dist/chunk-J6QFW4LD.js.map +7 -0
- package/dist/{chunk-OTOWLUOJ.js → chunk-JULOLTZS.js} +2 -2
- package/dist/{chunk-DR5WLIOU.js → chunk-KJKBDQ4D.js} +2 -2
- package/dist/{chunk-AHDRN6NE.js → chunk-OO7JDFS4.js} +5 -5
- package/dist/{chunk-N2X35ITW.js → chunk-OQBBVTDG.js} +11 -1
- package/dist/{chunk-N2X35ITW.js.map → chunk-OQBBVTDG.js.map} +2 -2
- package/dist/{chunk-3QH73QOQ.js → chunk-PED7L5GX.js} +2 -2
- package/dist/{chunk-VBGUNFKY.js → chunk-PMI56ED5.js} +5 -5
- package/dist/{chunk-XNNOXGP6.js → chunk-POFTPB33.js} +38 -19
- package/dist/chunk-POFTPB33.js.map +7 -0
- package/dist/{chunk-W4MZXKZ2.js → chunk-UKMLICWS.js} +2 -2
- package/dist/{chunk-3POYC5NA.js → chunk-XK42ZBDE.js} +3 -3
- package/dist/{chunk-ZSGKRCKD.js → chunk-XUV6DDBF.js} +2 -2
- package/dist/{chunk-LAKZUE35.js → chunk-Y3WD5CSW.js} +2 -2
- package/dist/{chunk-3QVMIJUL.js → chunk-YOBA3NAM.js} +5 -5
- package/dist/{chunk-ZRLYHBPN.js → chunk-ZUJBM6HE.js} +20 -2
- package/dist/chunk-ZUJBM6HE.js.map +7 -0
- package/dist/commands/antigravity/backfill.js +5 -4
- package/dist/commands/antigravity/backfill.js.map +1 -1
- package/dist/commands/auth/create-key.js +4 -3
- package/dist/commands/auth/create-key.js.map +1 -1
- package/dist/commands/auth/login.js +13 -9
- package/dist/commands/auth/login.js.map +2 -2
- package/dist/commands/auth/logout.js +4 -3
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/auth/revoke-key.js +4 -3
- package/dist/commands/auth/revoke-key.js.map +1 -1
- package/dist/commands/auth/signup.js +13 -9
- package/dist/commands/auth/signup.js.map +2 -2
- package/dist/commands/auth/status.js +4 -3
- package/dist/commands/auth/status.js.map +1 -1
- package/dist/commands/catalog/index.js +4 -3
- package/dist/commands/catalog/index.js.map +1 -1
- package/dist/commands/catalog/recommend.js +4 -3
- package/dist/commands/catalog/recommend.js.map +1 -1
- package/dist/commands/convert.js +4 -3
- package/dist/commands/convert.js.map +1 -1
- package/dist/commands/converters.js +4 -3
- package/dist/commands/converters.js.map +1 -1
- package/dist/commands/crons/list.js +4 -3
- package/dist/commands/crons/list.js.map +1 -1
- package/dist/commands/crons/run.js +4 -3
- package/dist/commands/crons/run.js.map +1 -1
- package/dist/commands/dashboard.js +4 -3
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/diagnostics.js +117 -0
- package/dist/commands/diagnostics.js.map +7 -0
- package/dist/commands/eval-targets/create.js +4 -3
- package/dist/commands/eval-targets/create.js.map +1 -1
- package/dist/commands/eval-targets/list.js +4 -3
- package/dist/commands/eval-targets/list.js.map +1 -1
- package/dist/commands/evals/agent.js +44 -23
- package/dist/commands/evals/agent.js.map +2 -2
- package/dist/commands/evals/benchmark.js +5 -4
- package/dist/commands/evals/benchmark.js.map +1 -1
- package/dist/commands/evals/compare.js +4 -3
- package/dist/commands/evals/compare.js.map +1 -1
- package/dist/commands/evals/create.js +4 -3
- package/dist/commands/evals/create.js.map +1 -1
- package/dist/commands/evals/optimize-description.js +4 -3
- package/dist/commands/evals/optimize-description.js.map +1 -1
- package/dist/commands/evals/optimize.js +4 -3
- package/dist/commands/evals/optimize.js.map +1 -1
- package/dist/commands/evals/run.js +4 -3
- package/dist/commands/evals/run.js.map +1 -1
- package/dist/commands/gateway/ensure.js +58 -5
- package/dist/commands/gateway/ensure.js.map +2 -2
- package/dist/commands/hooks/install.js +76 -23
- package/dist/commands/hooks/install.js.map +2 -2
- package/dist/commands/hooks/run.js +9 -5
- package/dist/commands/hooks/run.js.map +2 -2
- package/dist/commands/hooks/uninstall.js +31 -40
- package/dist/commands/hooks/uninstall.js.map +2 -2
- package/dist/commands/import.js +4 -3
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/instructions/create.js +4 -3
- package/dist/commands/instructions/create.js.map +1 -1
- package/dist/commands/instructions/delete.js +4 -3
- package/dist/commands/instructions/delete.js.map +1 -1
- package/dist/commands/instructions/fork.js +4 -3
- package/dist/commands/instructions/fork.js.map +1 -1
- package/dist/commands/instructions/get.js +4 -3
- package/dist/commands/instructions/get.js.map +1 -1
- package/dist/commands/instructions/list.js +4 -3
- package/dist/commands/instructions/list.js.map +1 -1
- package/dist/commands/instructions/promote.js +4 -3
- package/dist/commands/instructions/promote.js.map +1 -1
- package/dist/commands/instructions/pull.js +4 -3
- package/dist/commands/instructions/pull.js.map +1 -1
- package/dist/commands/instructions/upstream.js +4 -3
- package/dist/commands/instructions/upstream.js.map +1 -1
- package/dist/commands/instructions/versions.js +4 -3
- package/dist/commands/instructions/versions.js.map +1 -1
- package/dist/commands/launcher.js +4 -3
- package/dist/commands/launcher.js.map +1 -1
- package/dist/commands/org/current.js +4 -3
- package/dist/commands/org/current.js.map +1 -1
- package/dist/commands/org/list.js +4 -3
- package/dist/commands/org/list.js.map +1 -1
- package/dist/commands/org/switch.js +4 -3
- package/dist/commands/org/switch.js.map +1 -1
- package/dist/commands/packs/add-instruction.js +4 -3
- package/dist/commands/packs/add-instruction.js.map +1 -1
- package/dist/commands/packs/apply.js +4 -3
- package/dist/commands/packs/apply.js.map +1 -1
- package/dist/commands/packs/create.js +4 -3
- package/dist/commands/packs/create.js.map +1 -1
- package/dist/commands/packs/fork.js +4 -3
- package/dist/commands/packs/fork.js.map +1 -1
- package/dist/commands/packs/get.js +4 -3
- package/dist/commands/packs/get.js.map +1 -1
- package/dist/commands/packs/list.js +4 -3
- package/dist/commands/packs/list.js.map +1 -1
- package/dist/commands/packs/remove-instruction.js +4 -3
- package/dist/commands/packs/remove-instruction.js.map +1 -1
- package/dist/commands/proxy/env.js +7 -4
- package/dist/commands/proxy/env.js.map +1 -1
- package/dist/commands/proxy/logs.js +4 -3
- package/dist/commands/proxy/logs.js.map +1 -1
- package/dist/commands/proxy/restart.js +4 -3
- package/dist/commands/proxy/restart.js.map +1 -1
- package/dist/commands/proxy/setup.js +20 -14
- package/dist/commands/proxy/setup.js.map +2 -2
- package/dist/commands/proxy/start.js +18 -14
- package/dist/commands/proxy/start.js.map +2 -2
- package/dist/commands/proxy/status.js +16 -13
- package/dist/commands/proxy/status.js.map +2 -2
- package/dist/commands/proxy/stop.js +21 -12
- package/dist/commands/proxy/stop.js.map +2 -2
- package/dist/commands/research/backfill.js +5 -4
- package/dist/commands/research/backfill.js.map +1 -1
- package/dist/commands/research/tail-transcript.js +5 -4
- package/dist/commands/research/tail-transcript.js.map +1 -1
- package/dist/commands/service/install.js +6 -6
- package/dist/commands/service/status.js +4 -3
- package/dist/commands/service/status.js.map +1 -1
- package/dist/commands/service/uninstall.js +4 -3
- package/dist/commands/service/uninstall.js.map +1 -1
- package/dist/commands/sessions/analyze.js +4 -3
- package/dist/commands/sessions/analyze.js.map +1 -1
- package/dist/commands/sessions/end.js +4 -3
- package/dist/commands/sessions/end.js.map +1 -1
- package/dist/commands/sessions/import.js +4 -3
- package/dist/commands/sessions/import.js.map +1 -1
- package/dist/commands/sessions/list.js +4 -3
- package/dist/commands/sessions/list.js.map +1 -1
- package/dist/commands/sessions/start.js +4 -3
- package/dist/commands/sessions/start.js.map +1 -1
- package/dist/commands/setup.js +10 -6
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skills/export-approved.js +4 -3
- package/dist/commands/skills/export-approved.js.map +1 -1
- package/dist/commands/skills/install.js +4 -3
- package/dist/commands/skills/install.js.map +1 -1
- package/dist/commands/skills/list.js +4 -3
- package/dist/commands/skills/list.js.map +1 -1
- package/dist/commands/skills/publish.js +4 -3
- package/dist/commands/skills/publish.js.map +1 -1
- package/dist/commands/skills/search.js +4 -3
- package/dist/commands/skills/search.js.map +1 -1
- package/dist/commands/skills/update.js +4 -3
- package/dist/commands/skills/update.js.map +1 -1
- package/dist/commands/suggestions/accept.js +4 -3
- package/dist/commands/suggestions/accept.js.map +1 -1
- package/dist/commands/suggestions/dismiss.js +4 -3
- package/dist/commands/suggestions/dismiss.js.map +1 -1
- package/dist/commands/suggestions/list.js +4 -3
- package/dist/commands/suggestions/list.js.map +1 -1
- package/dist/commands/suggestions/refresh.js +4 -3
- package/dist/commands/suggestions/refresh.js.map +1 -1
- package/dist/dashboard/Dashboard.js +16 -16
- package/dist/dashboard/data.js +2 -2
- package/dist/dashboard/launcher/ActiveJobsList.js +2 -2
- package/dist/dashboard/launcher/LauncherOverlay.js +7 -7
- package/dist/dashboard/launcher/NewLaunchForm.js +2 -2
- package/dist/dashboard/launcher/api.js +2 -2
- package/dist/dashboard/launcher/useLaunchJobs.js +3 -3
- package/dist/lib/active-org-refresh.js +2 -2
- package/dist/lib/agent-loop.js +20 -18
- package/dist/lib/antigravity-transcript.js +2 -2
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/diagnostics.js +12 -0
- package/dist/lib/diagnostics.js.map +7 -0
- package/dist/lib/ensure-api-key.js +3 -3
- package/dist/lib/eval-benchmark.js +2 -2
- package/dist/lib/eval-conversation-handler.js +2 -2
- package/dist/lib/gateway-entry.js +39 -1
- package/dist/lib/gateway-entry.js.map +2 -2
- package/dist/lib/gateway-identity.js +16 -0
- package/dist/lib/gateway-identity.js.map +7 -0
- package/dist/lib/gateway-lifecycle.js +9 -3
- package/dist/lib/gateway.js +3 -1
- package/dist/lib/handlers/cron-suggest-instructions.js +3 -3
- package/dist/lib/handlers/process-announcement.js +3 -3
- package/dist/lib/handlers/process-changelog.js +3 -3
- package/dist/lib/handlers/process-conversation.js +3 -3
- package/dist/lib/handlers/process-eval.js +3 -3
- package/dist/lib/handlers/process-insights.js +3 -3
- package/dist/lib/handlers/process-launch.js +2 -2
- package/dist/lib/handlers/process-run-cleanup.js +2 -2
- package/dist/lib/handlers/process-session-goal.js +2 -2
- package/dist/lib/hooks-config.js +14 -1
- package/dist/lib/manual-tasks.js +6 -6
- package/dist/lib/pid-identity.js +14 -0
- package/dist/lib/pid-identity.js.map +7 -0
- package/dist/lib/proxy-respawn.js +12 -0
- package/dist/lib/proxy-respawn.js.map +7 -0
- package/dist/lib/research-client.js +2 -2
- package/dist/lib/setup-steps.js +7 -4
- package/dist/lib/statusline-shim.js +3 -1
- package/dist/lib/telemetry.js +4 -2
- package/dist/lib/terminal-target-heartbeat.js +2 -2
- package/oclif.manifest.json +34 -1
- package/package.json +6 -6
- package/dist/chunk-6EMZI4Y3.js.map +0 -7
- package/dist/chunk-BBLTN35F.js.map +0 -7
- package/dist/chunk-DAJNO4OI.js.map +0 -7
- package/dist/chunk-PXVQLD7S.js.map +0 -7
- package/dist/chunk-SZ7VDCD6.js.map +0 -7
- package/dist/chunk-TX2HKJLA.js +0 -55
- package/dist/chunk-TX2HKJLA.js.map +0 -7
- package/dist/chunk-XN23W5HL.js.map +0 -7
- package/dist/chunk-XNNOXGP6.js.map +0 -7
- package/dist/chunk-ZRLYHBPN.js.map +0 -7
- /package/dist/{chunk-RUCSRN7F.js.map → chunk-2ORJWTNZ.js.map} +0 -0
- /package/dist/{chunk-SLL3OBKN.js.map → chunk-37LN5O7M.js.map} +0 -0
- /package/dist/{chunk-RCMXTLQF.js.map → chunk-3LKVS6W5.js.map} +0 -0
- /package/dist/{chunk-UPXIO7CG.js.map → chunk-4XAWK6S2.js.map} +0 -0
- /package/dist/{chunk-N5A2IQAK.js.map → chunk-4YAP7RT7.js.map} +0 -0
- /package/dist/{chunk-QD6X4L4L.js.map → chunk-5BAOGNUH.js.map} +0 -0
- /package/dist/{chunk-5ADHO5QF.js.map → chunk-6NBS5XFS.js.map} +0 -0
- /package/dist/{chunk-DTFXCHHI.js.map → chunk-DNKSVWMD.js.map} +0 -0
- /package/dist/{chunk-YSEQWCN4.js.map → chunk-EYPAAGN5.js.map} +0 -0
- /package/dist/{chunk-JEJ3J5J6.js.map → chunk-GIUBARWS.js.map} +0 -0
- /package/dist/{chunk-CNMWYYSV.js.map → chunk-HZK43UCF.js.map} +0 -0
- /package/dist/{chunk-OTOWLUOJ.js.map → chunk-JULOLTZS.js.map} +0 -0
- /package/dist/{chunk-DR5WLIOU.js.map → chunk-KJKBDQ4D.js.map} +0 -0
- /package/dist/{chunk-AHDRN6NE.js.map → chunk-OO7JDFS4.js.map} +0 -0
- /package/dist/{chunk-3QH73QOQ.js.map → chunk-PED7L5GX.js.map} +0 -0
- /package/dist/{chunk-VBGUNFKY.js.map → chunk-PMI56ED5.js.map} +0 -0
- /package/dist/{chunk-W4MZXKZ2.js.map → chunk-UKMLICWS.js.map} +0 -0
- /package/dist/{chunk-3POYC5NA.js.map → chunk-XK42ZBDE.js.map} +0 -0
- /package/dist/{chunk-ZSGKRCKD.js.map → chunk-XUV6DDBF.js.map} +0 -0
- /package/dist/{chunk-LAKZUE35.js.map → chunk-Y3WD5CSW.js.map} +0 -0
- /package/dist/{chunk-3QVMIJUL.js.map → chunk-YOBA3NAM.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/db/src/schema/tables/profiles.ts", "../../../packages/db/src/schema/tables/organizations.ts", "../../../packages/db/src/schema/tables/agent-runs.ts", "../../../packages/db/src/schema/tables/projects.ts", "../../../packages/db/src/schema/tables/instructions.ts", "../../../packages/db/src/schema/tables/sessions.ts", "../../../packages/db/src/schema/tables/announcements.ts", "../../../packages/db/src/schema/tables/org-invitations.ts", "../../../packages/db/src/schema/tables/instruction-events.ts", "../../../packages/db/src/schema/tables/session-terminal-targets.ts", "../../../packages/db/src/schema/tables/session-send-jobs.ts", "../../../packages/db/src/schema/tables/packs.ts", "../../../packages/db/src/schema/tables/usage-events.ts", "../../../packages/db/src/schema/tables/worker-connections.ts", "../../../packages/db/src/schema/tables/cli-setup-events.ts", "../../../packages/db/src/schema/tables/eval-targets.ts", "../../../packages/db/src/schema/tables/optimization.ts", "../../../packages/db/src/schema/tables/context-snapshots.ts", "../../../packages/db/src/schema/tables/content-blobs.ts", "../../../packages/db/src/schema/tables/eval-jobs.ts", "../../../packages/db/src/schema/tables/agent-jobs.ts", "../../../packages/db/src/schema/tables/insights.ts", "../../../packages/db/src/schema/tables/api-keys.ts", "../../../packages/db/src/schema/tables/extension-auth-codes.ts", "../../../packages/db/src/schema/tables/eval-conversations.ts", "../../../packages/db/src/schema/tables/security-events.ts", "../../../packages/db/src/schema/tables/tasks.ts", "../../../packages/db/src/schema/tables/skill-submissions.ts", "../../../packages/db/src/schema/tables/harness-releases.ts", "../../../packages/db/src/schema/tables/notifications.ts", "../../../packages/db/src/schema/tables/launch-jobs.ts", "../../../packages/db/src/schema/tables/instruction-suggestions.ts", "../../../packages/db/src/schema/tables/model-pricing.ts", "../../../packages/db/src/schema/tables/limit-observations.ts", "../../../packages/db/src/schema/tables/provider-docs-snapshots.ts", "../../../packages/db/src/schema/tables/plan-limits-active.ts", "../../../packages/db/src/schema/tables/alert-dispatches.ts", "../../../packages/db/src/client.ts", "../../../packages/db/src/schema/index.ts", "../../../packages/db/src/schema/relations.ts", "../../../packages/db/src/db-load.ts"],
|
|
4
|
-
"sourcesContent": ["import { boolean, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core';\nimport { organizations } from './organizations.js';\n\nexport const profiles = pgTable('profiles', {\n id: uuid('id').primaryKey(),\n email: text('email'),\n displayName: text('display_name'),\n avatarUrl: text('avatar_url'),\n activeOrgId: uuid('active_org_id').references(() => organizations.id, { onDelete: 'set null' }),\n isSuperadmin: boolean('is_superadmin').notNull().default(false),\n claudeCodePlan: text('claude_code_plan'),\n planSource: text('plan_source').notNull().default('detected'),\n setupCompletedAt: timestamp('setup_completed_at', { withTimezone: true }),\n liveSendSkipped: boolean('live_send_skipped').notNull().default(false),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n});\n", "import { pgTable, text, timestamp, jsonb, uuid, primaryKey } from 'drizzle-orm/pg-core';\n\nexport const organizations = pgTable('organizations', {\n id: uuid('id').primaryKey().defaultRandom(),\n name: text('name').unique().notNull(),\n slug: text('slug').unique().notNull(),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n});\n\nexport const teams = pgTable('teams', {\n id: uuid('id').primaryKey().defaultRandom(),\n orgId: uuid('org_id').references(() => organizations.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n slug: text('slug').notNull(),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n});\n\nexport const userOrganizations = pgTable('user_organizations', {\n userId: uuid('user_id').notNull(),\n orgId: uuid('org_id').references(() => organizations.id, { onDelete: 'cascade' }).notNull(),\n role: text('role').notNull().default('member'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n primaryKey({ columns: [table.userId, table.orgId] }),\n]);\n\nexport const userTeams = pgTable('user_teams', {\n userId: uuid('user_id').notNull(),\n teamId: uuid('team_id').references(() => teams.id, { onDelete: 'cascade' }).notNull(),\n role: text('role').notNull().default('member'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n primaryKey({ columns: [table.userId, table.teamId] }),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, boolean, index } from 'drizzle-orm/pg-core';\nimport { profiles } from './profiles.js';\nimport { organizations } from './organizations.js';\nimport { projects } from './projects.js';\n\n// Groups N coordinated agentic coding sessions on one project into a single\n// \"run\". sessions.runId and launchJobs.runId (both nullable, ON DELETE SET\n// NULL) tie children back to the parent run. Mirrors migration\n// 00092_agent_runs.sql \u2014 see docs/plans/2026-06-17-multi-session-orchestration.md.\nexport const agentRuns = pgTable('agent_runs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n orgId: uuid('org_id').references(() => organizations.id, { onDelete: 'set null' }),\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),\n projectPath: text('project_path'),\n gitRemote: text('git_remote'),\n baseBranch: text('base_branch'),\n title: text('title'),\n prompt: text('prompt'), // the shared task fanned out to each session\n toolSpec: jsonb('tool_spec').notNull().default([]), // [{tool, model?, label?}] one entry per session\n autoWorktree: boolean('auto_worktree').notNull().default(true),\n // 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' (DB CHECK enforces)\n status: text('status').notNull().default('pending'),\n sessionCount: integer('session_count').notNull().default(0),\n metadata: jsonb('metadata').notNull().default({}),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n}, (table) => [\n index('idx_agent_runs_user').on(table.userId),\n index('idx_agent_runs_org_created').on(table.orgId, table.createdAt),\n index('idx_agent_runs_project').on(table.projectId),\n]);\n", "import { boolean, jsonb, pgTable, primaryKey, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport { organizations } from './organizations.js';\nimport { instructions } from './instructions.js';\n\nexport const projects = pgTable('projects', {\n id: uuid('id').primaryKey().defaultRandom(),\n orgId: uuid('org_id').references(() => organizations.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n description: text('description'),\n // Legacy display field. No longer used as a primary lookup key \u2014 see\n // gitRemoteUrl below. Kept for backward compat on existing UI forms.\n githubRepo: text('github_repo'),\n // Canonicalized git remote URL (e.g. 'github.com/owner/repo'). Primary\n // identity for project matching, set via canonicalizeRemote() server-side.\n gitRemoteUrl: text('git_remote_url'),\n // SHA of the repo's first commit. Stability anchor \u2014 survives URL renames\n // (transferred repos keep the same root commit). Used as fallback lookup\n // when remote URL doesn't match.\n gitRootCommit: text('git_root_commit'),\n // Old URLs this project has been known by. Populated when a URL rename\n // is detected via root-commit match. Future sessions with the old URL\n // still resolve to this project.\n gitRemoteAliases: text('git_remote_aliases').array().notNull().default([]),\n metadata: jsonb('metadata'),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n uniqueIndex('projects_org_name_idx').on(table.orgId, table.name),\n // Partial unique index \u2014 NULLs are allowed (legacy projects with no\n // remote). See migration 00054.\n uniqueIndex('projects_git_remote_url_unique')\n .on(table.gitRemoteUrl)\n .where(sql`${table.gitRemoteUrl} IS NOT NULL`),\n]);\n\nexport const projectInstructions = pgTable('project_instructions', {\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'cascade' }).notNull(),\n instructionId: uuid('instruction_id').references(() => instructions.id, { onDelete: 'cascade' }).notNull(),\n addedAt: timestamp('added_at', { withTimezone: true }).defaultNow(),\n addedBy: uuid('added_by'),\n}, (table) => [\n primaryKey({ columns: [table.projectId, table.instructionId] }),\n]);\n\n// Every local path where a project is checked out. A single project can\n// have many rows: multiple clones, worktrees, or directory moves. Sessions\n// whose remote/root-commit don't match anything fall through to a\n// project_checkouts.path lookup.\n//\n// `path` is globally UNIQUE (migration 00052): a directory on disk has\n// exactly one git context, so it can only legitimately belong to one\n// project at a time. Without this constraint, the matcher's path-fallback\n// step picks non-deterministically when duplicates exist, and historical\n// sessions get stamped with the wrong project_id.\nexport const projectCheckouts = pgTable('project_checkouts', {\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'cascade' }).notNull(),\n path: text('path').notNull(),\n isWorktree: boolean('is_worktree').notNull().default(false),\n firstSeen: timestamp('first_seen', { withTimezone: true }).notNull().defaultNow(),\n lastSeen: timestamp('last_seen', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n primaryKey({ columns: [table.projectId, table.path] }),\n uniqueIndex('project_checkouts_path_unique').on(table.path),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, boolean, uniqueIndex, index } from 'drizzle-orm/pg-core';\n\nexport const instructions = pgTable('instructions', {\n id: uuid('id').primaryKey().defaultRandom(),\n name: text('name').notNull(),\n description: text('description').notNull(),\n type: text('type').notNull().default('instruction'),\n scope: text('scope').notNull(),\n scopeRef: uuid('scope_ref'),\n version: text('version').notNull(),\n content: text('content').notNull(),\n frontmatter: jsonb('frontmatter').notNull(),\n slots: jsonb('slots'),\n tags: text('tags').array(),\n compatibility: text('compatibility').array(),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n archived: boolean('archived').default(false),\n archivedAt: timestamp('archived_at', { withTimezone: true }),\n archivedBy: uuid('archived_by'),\n forkedFromId: uuid('forked_from_id').references((): any => instructions.id, { onDelete: 'set null' }),\n upstreamVersion: text('upstream_version'),\n badge: text('badge'),\n contentHash: text('content_hash'),\n contextIdentity: text('context_identity'),\n scanScore: integer('scan_score'),\n scanFindings: jsonb('scan_findings'),\n popularityScore: integer('popularity_score'),\n // Source file's last git-commit date (from the skills registry). Distinct\n // from updatedAt, which is the local row's last-sync time. Used to sort the\n // public catalog by genuine recency. NULL for non-registry rows and until\n // the next registry sync populates it.\n sourceUpdatedAt: timestamp('source_updated_at', { withTimezone: true }),\n}, (table) => [\n uniqueIndex('instructions_name_scope_ref_idx').on(table.name, table.scope, table.scopeRef),\n index('idx_instructions_scope').on(table.scope, table.scopeRef),\n index('idx_instructions_created_by').on(table.createdBy),\n index('idx_instructions_context_identity').on(table.createdBy, table.contextIdentity),\n // Recency sort for the public catalog: COALESCE(source_updated_at, updated_at) DESC.\n index('idx_instructions_public_recency').on(table.scope, table.sourceUpdatedAt.desc()),\n]);\n\nexport const instructionVersions = pgTable('instruction_versions', {\n id: uuid('id').primaryKey().defaultRandom(),\n instructionId: uuid('instruction_id').references(() => instructions.id, { onDelete: 'cascade' }),\n versionNumber: integer('version_number').notNull(),\n content: text('content').notNull(),\n frontmatter: jsonb('frontmatter').notNull(),\n changeSummary: text('change_summary'),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n uniqueIndex('instruction_versions_instruction_version_idx').on(table.instructionId, table.versionNumber),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, uniqueIndex, index } from 'drizzle-orm/pg-core';\nimport { instructions } from './instructions.js';\nimport { projects } from './projects.js';\nimport { profiles } from './profiles.js';\nimport { organizations } from './organizations.js';\nimport { agentRuns } from './agent-runs.js';\n\nexport const sessions = pgTable('sessions', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n externalSessionId: text('external_session_id'),\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),\n orgId: uuid('org_id').references(() => organizations.id, { onDelete: 'set null' }),\n tool: text('tool').notNull(),\n projectPath: text('project_path'),\n gitBranch: text('git_branch'),\n startedAt: timestamp('started_at', { withTimezone: true }).notNull(),\n endedAt: timestamp('ended_at', { withTimezone: true }),\n eventCount: integer('event_count').default(0),\n tokenUsage: jsonb('token_usage'),\n analysis: jsonb('analysis'),\n analyzedAt: timestamp('analyzed_at', { withTimezone: true }),\n analyzedEventCount: integer('analyzed_event_count'),\n analyzedTurnCount: integer('analyzed_turn_count'),\n metadata: jsonb('metadata').default({}),\n // 'hook' | 'mcp' | 'proxy' | 'internal_worker' | 'import' | 'unknown'\n // Set on insert in POST /api/sessions. GET /api/sessions defaults to\n // excluding 'internal_worker' so insights/eval pipeline auto-captures\n // never appear in the user's Sessions tab. See migration 00050.\n origin: text('origin').notNull().default('unknown'),\n runId: uuid('run_id').references(() => agentRuns.id, { onDelete: 'set null' }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_sessions_user').on(table.userId),\n index('idx_sessions_tool').on(table.tool),\n index('idx_sessions_started_at').on(table.startedAt),\n index('idx_sessions_project').on(table.projectId),\n index('idx_sessions_org_started_at').on(table.orgId, table.startedAt),\n index('idx_sessions_run').on(table.runId),\n uniqueIndex('idx_sessions_user_external').on(table.userId, table.externalSessionId),\n]);\n\nexport const sessionEvents = pgTable('session_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n sessionId: uuid('session_id').notNull().references(() => sessions.id, { onDelete: 'cascade' }),\n sequence: integer('sequence').notNull(),\n eventType: text('event_type').notNull(),\n content: text('content'),\n toolName: text('tool_name'),\n toolInput: jsonb('tool_input'),\n toolOutput: jsonb('tool_output'),\n tokenUsage: jsonb('token_usage'),\n model: text('model'),\n timestamp: timestamp('timestamp', { withTimezone: true }).notNull(),\n metadata: jsonb('metadata').default({}),\n}, (table) => [\n uniqueIndex('session_events_session_sequence_idx').on(table.sessionId, table.sequence),\n index('idx_session_events_session_id').on(table.sessionId),\n index('idx_session_events_event_type').on(table.eventType),\n index('idx_session_events_model').on(table.model),\n]);\n\nexport const sessionInstructions = pgTable('session_instructions', {\n sessionId: uuid('session_id').notNull().references(() => sessions.id, { onDelete: 'cascade' }),\n instructionId: uuid('instruction_id').notNull().references(() => instructions.id, { onDelete: 'cascade' }),\n linkMethod: text('link_method').notNull(),\n}, (table) => [\n index('idx_session_instructions_instruction_id').on(table.instructionId),\n]);\n", "import { boolean, date, index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';\n\nexport const announcements = pgTable('announcements', {\n id: uuid('id').primaryKey().defaultRandom(),\n version: text('version').notNull().unique(),\n releaseDate: date('release_date').notNull(),\n subject: text('subject').notNull(),\n htmlBody: text('html_body').notNull(),\n textBody: text('text_body').notNull(),\n sections: jsonb('sections').notNull().default({}),\n status: text('status').notNull().default('draft'),\n recipientCount: integer('recipient_count'),\n sentAt: timestamp('sent_at', { withTimezone: true }),\n sentBy: uuid('sent_by'),\n error: text('error'),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n index('idx_announcements_status').on(table.status),\n index('idx_announcements_created').on(table.createdAt),\n]);\n\nexport const announcementDeliveries = pgTable('announcement_deliveries', {\n id: uuid('id').primaryKey().defaultRandom(),\n announcementId: uuid('announcement_id').notNull(),\n userId: uuid('user_id').notNull(),\n email: text('email').notNull(),\n status: text('status').notNull().default('pending'),\n providerId: text('provider_id'),\n error: text('error'),\n sentAt: timestamp('sent_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n uniqueIndex('uniq_announcement_deliveries_announcement_user')\n .on(table.announcementId, table.userId),\n index('idx_announcement_deliveries_user').on(table.userId, table.createdAt),\n]);\n\nexport const notificationPreferences = pgTable('notification_preferences', {\n userId: uuid('user_id').primaryKey(),\n productAnnouncements: boolean('product_announcements').notNull().default(true),\n unsubscribeToken: text('unsubscribe_token').notNull().unique(),\n unsubscribedAt: timestamp('unsubscribed_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n});\n", "import { pgTable, text, timestamp, uuid, index } from 'drizzle-orm/pg-core';\nimport { organizations, teams } from './organizations.js';\nimport { profiles } from './profiles.js';\n\nexport const orgInvitations = pgTable('org_invitations', {\n id: uuid('id').primaryKey().defaultRandom(),\n orgId: uuid('org_id').notNull().references(() => organizations.id, { onDelete: 'cascade' }),\n email: text('email').notNull(),\n role: text('role').notNull().default('member'),\n teamId: uuid('team_id').references(() => teams.id, { onDelete: 'set null' }),\n invitedBy: uuid('invited_by').notNull().references(() => profiles.id),\n token: text('token').notNull().unique(),\n // expires_at is generated by Postgres via `default (now() + interval '7 days')`,\n // so no Drizzle-side default \u2014 just notNull.\n expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),\n acceptedAt: timestamp('accepted_at', { withTimezone: true }),\n revokedAt: timestamp('revoked_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (t) => [\n index('idx_org_invitations_token').on(t.token),\n index('idx_org_invitations_org').on(t.orgId),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index } from 'drizzle-orm/pg-core';\nimport { instructions } from './instructions.js';\n\nexport const instructionEvents = pgTable('instruction_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n instructionId: uuid('instruction_id').notNull().references(() => instructions.id, { onDelete: 'cascade' }),\n eventType: text('event_type').notNull(),\n actorId: uuid('actor_id').notNull(),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_instruction_events_instruction').on(table.instructionId),\n index('idx_instruction_events_type').on(table.eventType),\n]);\n", "import { pgTable, text, timestamp, uuid, jsonb, uniqueIndex, index } from 'drizzle-orm/pg-core';\nimport { profiles } from './profiles.js';\nimport { sessions } from './sessions.js';\n\nexport const sessionTerminalTargets = pgTable('session_terminal_targets', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n sessionId: uuid('session_id').references(() => sessions.id, { onDelete: 'set null' }),\n externalSessionId: text('external_session_id'),\n kind: text('kind').notNull(),\n target: text('target').notNull(),\n status: text('status').notNull().default('active'),\n attachCommand: text('attach_command').notNull(),\n projectPath: text('project_path'),\n metadata: jsonb('metadata').notNull().default({}),\n lastSeenAt: timestamp('last_seen_at', { withTimezone: true }).defaultNow(),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n uniqueIndex('idx_session_terminal_targets_user_target').on(table.userId, table.target),\n index('idx_session_terminal_targets_session').on(table.sessionId),\n index('idx_session_terminal_targets_user_status').on(table.userId, table.status),\n]);\n", "import { boolean, bigint, index, jsonb, pgTable, text, timestamp, uuid, integer } from 'drizzle-orm/pg-core';\nimport { sessions } from './sessions.js';\nimport { sessionTerminalTargets } from './session-terminal-targets.js';\n\nexport const sessionSendJobs = pgTable('session_send_jobs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n sessionId: uuid('session_id').notNull().references(() => sessions.id, { onDelete: 'cascade' }),\n terminalTargetId: uuid('terminal_target_id').references(() => sessionTerminalTargets.id, { onDelete: 'set null' }),\n target: text('target').notNull(),\n message: text('message').notNull(),\n submit: boolean('submit').notNull().default(true),\n delivery: text('delivery').notNull().default('live'),\n status: text('status').notNull().default('pending'),\n result: jsonb('result'),\n error: text('error'),\n attempts: integer('attempts').notNull().default(0),\n graphileJobId: bigint('graphile_job_id', { mode: 'number' }),\n taskKind: text('task_kind'),\n payload: jsonb('payload'),\n claimedBy: text('claimed_by'),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n leaseExpiresAt: timestamp('lease_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n}, (table) => [\n index('idx_session_send_jobs_user').on(table.userId),\n index('idx_session_send_jobs_session').on(table.sessionId),\n index('idx_session_send_jobs_status').on(table.status),\n index('idx_session_send_jobs_pending').on(table.userId, table.status),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, boolean, uniqueIndex, index, primaryKey } from 'drizzle-orm/pg-core';\nimport { instructions } from './instructions.js';\n\nexport const packs = pgTable('packs', {\n id: uuid('id').primaryKey().defaultRandom(),\n name: text('name').notNull(),\n description: text('description').notNull(),\n scope: text('scope').notNull(),\n scopeRef: uuid('scope_ref'),\n version: text('version').notNull().default('1.0.0'),\n tags: text('tags').array(),\n badge: text('badge'),\n metadata: jsonb('metadata'),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n archived: boolean('archived').default(false),\n archivedAt: timestamp('archived_at', { withTimezone: true }),\n archivedBy: uuid('archived_by'),\n forkedFromId: uuid('forked_from_id').references((): any => packs.id, { onDelete: 'set null' }),\n upstreamVersion: text('upstream_version'),\n}, (table) => [\n uniqueIndex('packs_name_scope_ref_idx').on(table.name, table.scope, table.scopeRef),\n index('idx_packs_scope').on(table.scope, table.scopeRef),\n index('idx_packs_created_by').on(table.createdBy),\n]);\n\nexport const packInstructions = pgTable('pack_instructions', {\n packId: uuid('pack_id').references(() => packs.id, { onDelete: 'cascade' }).notNull(),\n instructionId: uuid('instruction_id').references(() => instructions.id, { onDelete: 'cascade' }).notNull(),\n position: integer('position').notNull().default(0),\n slotOverrides: jsonb('slot_overrides'),\n addedAt: timestamp('added_at', { withTimezone: true }).defaultNow(),\n addedBy: uuid('added_by'),\n}, (table) => [\n primaryKey({ columns: [table.packId, table.instructionId] }),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index } from 'drizzle-orm/pg-core';\nimport { instructions } from './instructions.js';\n\nexport const instructionUsageEvents = pgTable('instruction_usage_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n instructionId: uuid('instruction_id').references(() => instructions.id, { onDelete: 'set null' }),\n userId: uuid('user_id').notNull(),\n surface: text('surface').notNull(),\n action: text('action').notNull(),\n metadata: jsonb('metadata'),\n traceId: text('trace_id'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_usage_events_instruction').on(table.instructionId),\n index('idx_usage_events_user').on(table.userId),\n index('idx_usage_events_surface').on(table.surface),\n index('idx_usage_events_action').on(table.action),\n index('idx_usage_events_created_at').on(table.createdAt),\n index('idx_usage_events_user_created').on(table.userId, table.createdAt),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index } from 'drizzle-orm/pg-core';\n\nexport const workerConnections = pgTable('worker_connections', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n workerType: text('worker_type').notNull().default('mcp'),\n clientName: text('client_name').notNull(),\n clientVersion: text('client_version'),\n workerVersion: text('worker_version'),\n lastHeartbeat: timestamp('last_heartbeat', { withTimezone: true }).notNull().defaultNow(),\n connectedAt: timestamp('connected_at', { withTimezone: true }).notNull().defaultNow(),\n metadata: jsonb('metadata'),\n}, (table) => [\n index('idx_worker_connections_user').on(table.userId),\n index('idx_worker_connections_heartbeat').on(table.userId, table.lastHeartbeat),\n index('idx_worker_connections_type').on(table.userId, table.workerType),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index } from 'drizzle-orm/pg-core';\n\n// Remote CLI onboarding telemetry \u2014 one row per setup lifecycle event\n// (install/auth/hooks/worker/capture) per device. See migration 00109.\nexport const cliSetupEvents = pgTable('cli_setup_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n deviceId: text('device_id').notNull(),\n event: text('event').notNull(),\n cliVersion: text('cli_version'),\n os: text('os'),\n props: jsonb('props').notNull().default({}),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n index('idx_cli_setup_events_user').on(table.userId, table.createdAt),\n index('idx_cli_setup_events_device').on(table.deviceId, table.createdAt),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, index } from 'drizzle-orm/pg-core';\n\nexport const evalTargets = pgTable('eval_targets', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n name: text('name').notNull(),\n type: text('type').notNull(),\n content: text('content').notNull(),\n description: text('description').notNull().default(''),\n metadata: jsonb('metadata').notNull().default({}),\n version: integer('version').notNull().default(1),\n parentId: uuid('parent_id').references((): any => evalTargets.id, { onDelete: 'set null' }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('eval_targets_name_user_idx').on(table.name, table.userId),\n index('idx_eval_targets_user').on(table.userId),\n index('idx_eval_targets_type').on(table.type),\n index('idx_eval_targets_parent').on(table.parentId),\n]);\n\nexport const evals = pgTable('evals', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n prompt: text('prompt').notNull(),\n expectedOutput: text('expected_output').notNull().default(''),\n files: jsonb('files').notNull().default([]),\n expectations: jsonb('expectations').notNull().default([]),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_evals_target').on(table.evalTargetId),\n]);\n\nexport const evalRuns = pgTable('eval_runs', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalId: uuid('eval_id').notNull().references(() => evals.id, { onDelete: 'cascade' }),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n evalTargetVersion: integer('eval_target_version').notNull(),\n configuration: text('configuration').notNull(),\n runNumber: integer('run_number').notNull().default(1),\n iteration: integer('iteration').notNull().default(1),\n status: text('status').notNull().default('completed'),\n outputs: jsonb('outputs').notNull().default({}),\n timing: jsonb('timing').notNull().default({}),\n grading: jsonb('grading').notNull().default({}),\n comparison: jsonb('comparison'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_eval_runs_eval').on(table.evalId),\n index('idx_eval_runs_target').on(table.evalTargetId),\n index('idx_eval_runs_iteration').on(table.evalTargetId, table.iteration),\n]);\n\nexport const benchmarks = pgTable('benchmarks', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n iteration: integer('iteration').notNull().default(1),\n runSummary: jsonb('run_summary').notNull().default({}),\n notes: jsonb('notes').notNull().default([]),\n feedback: jsonb('feedback'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_benchmarks_target').on(table.evalTargetId),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, index, real } from 'drizzle-orm/pg-core';\nimport { evalTargets } from './eval-targets.js';\n\nexport const triggerEvals = pgTable('trigger_evals', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n userId: uuid('user_id').notNull(),\n queries: jsonb('queries').notNull().default([]),\n status: text('status').notNull().default('pending_review'),\n trainIndices: integer('train_indices').array().default([]),\n testIndices: integer('test_indices').array().default([]),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_trigger_evals_target').on(table.evalTargetId),\n index('idx_trigger_evals_user').on(table.userId),\n]);\n\nexport const optimizationRuns = pgTable('optimization_runs', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n userId: uuid('user_id').notNull(),\n type: text('type').notNull(),\n iteration: integer('iteration').notNull(),\n inputVersion: integer('input_version').notNull(),\n outputVersion: integer('output_version'),\n trainScore: real('train_score'),\n testScore: real('test_score'),\n analysis: jsonb('analysis').notNull().default({}),\n status: text('status').notNull().default('running'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_optimization_runs_target').on(table.evalTargetId),\n index('idx_optimization_runs_user').on(table.userId),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, real, index, uniqueIndex } from 'drizzle-orm/pg-core';\nimport { sessions } from './sessions.js';\nimport { profiles } from './profiles.js';\n\nexport const contextSnapshots = pgTable('context_snapshots', {\n id: uuid('id').primaryKey().defaultRandom(),\n sessionId: uuid('session_id').references(() => sessions.id, { onDelete: 'cascade' }),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n sequence: integer('sequence').notNull().default(0),\n provider: text('provider').notNull(),\n model: text('model').notNull(),\n systemPrompt: text('system_prompt').notNull(),\n injectedInstructions: jsonb('injected_instructions').notNull().default([]),\n messagesSummary: jsonb('messages_summary').notNull(),\n tools: jsonb('tools').notNull().default([]), // Deprecated: use content_blobs via tools_hash\n systemHash: text('system_hash').notNull(),\n requestHash: text('request_hash').notNull().default(''),\n toolsHash: text('tools_hash'),\n injectedHash: text('injected_hash'),\n messagesDelta: jsonb('messages_delta').default([]),\n // Storage pointer set when messages_delta is offloaded to the snapshot-deltas\n // bucket (Stage 1+). NULL = inline (messages_delta populated) OR pruned (both\n // NULL \u2014 see 00101). docs/plans/2026-06-24-messages-delta-object-storage-offload.md\n messagesDeltaRef: text('messages_delta_ref'),\n maxTokens: integer('max_tokens'),\n temperature: real('temperature'),\n estimatedTokens: integer('estimated_tokens'),\n capturedAt: timestamp('captured_at', { withTimezone: true }).notNull().defaultNow(),\n metadata: jsonb('metadata').default({}),\n}, (table) => [\n index('idx_context_snapshots_session').on(table.sessionId),\n index('idx_context_snapshots_user').on(table.userId),\n index('idx_context_snapshots_hash').on(table.systemHash),\n index('idx_context_snapshots_request_hash').on(table.requestHash),\n uniqueIndex('idx_snapshots_session_request').on(table.sessionId, table.requestHash),\n // Concurrent snapshot POSTs for one session must not reuse a sequence \u2014 stops\n // the live duplicate-sequence corruption. Built via migration 00095.\n // Pool/perf audit 2026-06-22.\n uniqueIndex('idx_snapshots_session_sequence').on(table.sessionId, table.sequence),\n // \"Latest snapshot per session for a user\" read (DISTINCT ON (session_id)\n // WHERE user_id ORDER BY session_id, captured_at DESC). Matches the ORDER BY so\n // the planner drops the Incremental Sort (the ~11s-max, temp-spill-prone step);\n // verified 60.6ms -> 26.3ms. Built CONCURRENTLY via migration 00106.\n index('idx_context_snapshots_user_session_captured').on(\n table.userId,\n table.sessionId,\n table.capturedAt.desc(),\n ),\n]);\n", "import { pgTable, text, timestamp, jsonb, integer, index } from 'drizzle-orm/pg-core';\n\nexport const contentBlobs = pgTable('content_blobs', {\n hash: text('hash').primaryKey(),\n contentType: text('content_type').notNull(),\n content: jsonb('content').notNull(),\n sizeBytes: integer('size_bytes').notNull().default(0),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_content_blobs_type').on(table.contentType),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index, integer, bigint } from 'drizzle-orm/pg-core';\nimport { evalTargets } from './eval-targets.js';\n\nexport const evalJobs = pgTable('eval_jobs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n status: text('status').notNull().default('pending'),\n config: jsonb('config').notNull().default({}),\n progress: jsonb('progress').notNull().default({}),\n result: jsonb('result'),\n error: text('error'),\n attempts: integer('attempts').notNull().default(0),\n graphileJobId: bigint('graphile_job_id', { mode: 'number' }),\n taskKind: text('task_kind'),\n payload: jsonb('payload'),\n claimedBy: text('claimed_by'),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n leaseExpiresAt: timestamp('lease_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n}, (table) => [\n index('idx_eval_jobs_user').on(table.userId),\n index('idx_eval_jobs_target').on(table.evalTargetId),\n index('idx_eval_jobs_status').on(table.status),\n index('idx_eval_jobs_pending').on(table.userId, table.status),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, integer, index } from 'drizzle-orm/pg-core';\n\n// Agent work-queue rows for task kinds that have no dedicated mirror table\n// (cron_suggest_instructions, process_session_goal, process_announcement).\n// Claimed via GET /api/work/next like the other three mirror tables; see\n// migration 00083 and apps/api/src/routes/work.ts.\nexport const agentJobs = pgTable('agent_jobs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n taskKind: text('task_kind').notNull(),\n status: text('status').notNull().default('pending'),\n payload: jsonb('payload').notNull(),\n dedupeKey: text('dedupe_key'),\n result: jsonb('result'),\n error: text('error'),\n attempts: integer('attempts').notNull().default(0),\n claimedBy: text('claimed_by'),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n leaseExpiresAt: timestamp('lease_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n}, (table) => [\n index('idx_agent_jobs_claim').on(table.userId, table.status, table.taskKind, table.createdAt),\n index('idx_agent_jobs_dedupe').on(table.userId, table.taskKind, table.dedupeKey),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index, uniqueIndex, integer, bigint } from 'drizzle-orm/pg-core';\nimport { projects } from './projects.js';\n\nexport const insightsJobs = pgTable('insights_jobs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n status: text('status').notNull().default('pending'),\n projectPath: text('project_path'),\n // Canonical project identity (project_path-keying fragments one project across\n // worktrees/subdirs/cwds \u2014 migration 00104). Nullable: legacy/unlinked rows fall\n // back to project_path. Stamped at enqueue when resolvable.\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),\n config: jsonb('config').notNull().default({}),\n progress: jsonb('progress').notNull().default({}),\n result: jsonb('result'),\n error: text('error'),\n attempts: integer('attempts').notNull().default(0),\n graphileJobId: bigint('graphile_job_id', { mode: 'number' }),\n taskKind: text('task_kind'),\n payload: jsonb('payload'),\n claimedBy: text('claimed_by'),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n leaseExpiresAt: timestamp('lease_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n}, (table) => [\n index('idx_insights_jobs_user').on(table.userId),\n index('idx_insights_jobs_status').on(table.status),\n index('idx_insights_jobs_pending').on(table.userId, table.status),\n index('idx_insights_jobs_project').on(table.projectId),\n]);\n\nexport const insightsReports = pgTable('insights_reports', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n projectPath: text('project_path'),\n data: jsonb('data').notNull(),\n reportHtml: text('report_html'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_insights_user').on(table.userId),\n index('idx_insights_created').on(table.createdAt),\n uniqueIndex('idx_insights_user_project').on(table.userId, table.projectPath),\n]);\n", "import { pgTable, text, timestamp, uuid, index, uniqueIndex } from 'drizzle-orm/pg-core';\nimport { profiles } from './profiles.js';\n\nexport const apiKeys = pgTable('api_keys', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n name: text('name').notNull(),\n keyHash: text('key_hash').notNull(),\n keyPrefix: text('key_prefix').notNull(),\n lastUsedAt: timestamp('last_used_at', { withTimezone: true }),\n expiresAt: timestamp('expires_at', { withTimezone: true }),\n revokedAt: timestamp('revoked_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_api_keys_user').on(table.userId),\n uniqueIndex('idx_api_keys_hash').on(table.keyHash),\n]);\n", "import { pgTable, text, timestamp, uuid, index } from 'drizzle-orm/pg-core';\nimport { profiles } from './profiles.js';\n\n// Short-lived, single-use handoff codes for the editor sign-in flow.\n//\n// The browser hits POST /api/auth/extension/code (authenticated) which writes\n// one row here; the editor then redeems it at POST /auth/extension/exchange,\n// which DELETE-RETURNINGs the row (atomic single-use) and mints the API key.\n//\n// This MUST be a shared store, not in-process memory: prod runs multiple Fly\n// machines, so /code and /exchange routinely land on different instances. An\n// in-memory Map dropped ~1-in-4 handoffs. The row is deleted on redemption;\n// unredeemed rows expire after 60s and are swept periodically.\nexport const extensionAuthCodes = pgTable('extension_auth_codes', {\n code: text('code').primaryKey(),\n userId: uuid('user_id')\n .notNull()\n .references(() => profiles.id, { onDelete: 'cascade' }),\n editor: text('editor'),\n email: text('email'),\n expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_ext_auth_codes_expiry').on(table.expiresAt),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index } from 'drizzle-orm/pg-core';\nimport { evalTargets } from './eval-targets.js';\n\nexport const evalConversations = pgTable('eval_conversations', {\n id: uuid('id').primaryKey().defaultRandom(),\n evalTargetId: uuid('eval_target_id').notNull().references(() => evalTargets.id, { onDelete: 'cascade' }),\n userId: uuid('user_id').notNull(),\n messages: jsonb('messages').notNull().default([]),\n status: text('status').notNull().default('active'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('idx_eval_conversations_target').on(table.evalTargetId),\n index('idx_eval_conversations_user').on(table.userId),\n]);\n", "import { pgTable, uuid, text, jsonb, timestamp, index } from 'drizzle-orm/pg-core';\n\nexport const securityEvents = pgTable('security_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n eventType: text('event_type').notNull(),\n severity: text('severity').notNull(),\n category: text('category').notNull(),\n source: text('source').notNull(),\n entityType: text('entity_type'),\n entityId: uuid('entity_id'),\n userId: uuid('user_id'),\n details: jsonb('details').notNull().default({}),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n index('idx_security_events_type').on(table.eventType),\n index('idx_security_events_user').on(table.userId),\n index('idx_security_events_created').on(table.createdAt),\n index('idx_security_events_severity').on(table.severity),\n index('idx_security_events_source').on(table.source),\n]);\n", "import { pgTable, text, timestamp, uuid, index } from 'drizzle-orm/pg-core';\n\nexport const tasks = pgTable('tasks', {\n id: uuid('id').primaryKey().defaultRandom(),\n title: text('title').notNull(),\n description: text('description'),\n status: text('status').notNull().default('pending'),\n createdBy: uuid('created_by'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n index('tasks_created_by_idx').on(table.createdBy),\n index('tasks_status_idx').on(table.status),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid } from 'drizzle-orm/pg-core';\n\nexport const skillSubmissions = pgTable('skill_submissions', {\n id: uuid('id').primaryKey().defaultRandom(),\n skillId: text('skill_id').notNull(),\n name: text('name').notNull(),\n description: text('description').notNull(),\n category: text('category').notNull(),\n tools: text('tools').array().notNull(),\n tags: text('tags').array().default([]),\n content: text('content').notNull(),\n status: text('status').notNull().default('pending'), // pending | approved | rejected\n submittedBy: uuid('submitted_by').notNull(),\n reviewedBy: uuid('reviewed_by'),\n reviewNote: text('review_note'),\n metadata: jsonb('metadata'),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n});\n", "import { pgTable, text, timestamp, jsonb, uuid, uniqueIndex, index } from 'drizzle-orm/pg-core';\n\nexport const harnessReleases = pgTable('harness_releases', {\n id: uuid('id').primaryKey().defaultRandom(),\n harness: text('harness').notNull(), // \"claude_code\", \"cursor\", \"copilot\"\n version: text('version').notNull(), // \"v2.1.119\"\n publishedAt: timestamp('published_at', { withTimezone: true }).notNull(),\n title: text('title'), // release name\n body: text('body'), // raw markdown\n categories: jsonb('categories').default({}), // { features: string[], fixes: string[], security: string[] }\n url: text('url'), // link to release page\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n}, (table) => [\n uniqueIndex('idx_harness_releases_unique').on(table.harness, table.version),\n index('idx_harness_releases_harness').on(table.harness),\n index('idx_harness_releases_published').on(table.publishedAt),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index, uniqueIndex } from 'drizzle-orm/pg-core';\n\nexport const notifications = pgTable('notifications', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n type: text('type').notNull(),\n title: text('title').notNull(),\n body: text('body'),\n url: text('url'),\n sourceTable: text('source_table'),\n sourceId: text('source_id'),\n metadata: jsonb('metadata').notNull().default({}),\n readAt: timestamp('read_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n index('idx_notifications_user_created').on(table.userId, table.createdAt),\n index('idx_notifications_user_unread').on(table.userId),\n uniqueIndex('idx_notifications_source_dedup').on(table.userId, table.sourceTable, table.sourceId),\n]);\n", "import { pgTable, text, timestamp, jsonb, uuid, index, integer, bigint } from 'drizzle-orm/pg-core';\nimport { agentRuns } from './agent-runs.js';\n\nexport const launchJobs = pgTable('launch_jobs', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n tool: text('tool').notNull(),\n status: text('status').notNull().default('pending'),\n config: jsonb('config').notNull().default({}),\n result: jsonb('result'),\n error: text('error'),\n attempts: integer('attempts').notNull().default(0),\n graphileJobId: bigint('graphile_job_id', { mode: 'number' }),\n taskKind: text('task_kind'),\n payload: jsonb('payload'),\n claimedBy: text('claimed_by'),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n leaseExpiresAt: timestamp('lease_expires_at', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow(),\n completedAt: timestamp('completed_at', { withTimezone: true }),\n runId: uuid('run_id').references(() => agentRuns.id, { onDelete: 'set null' }),\n}, (table) => [\n index('idx_launch_jobs_user').on(table.userId),\n index('idx_launch_jobs_status').on(table.status),\n index('idx_launch_jobs_pending').on(table.userId, table.status),\n index('idx_launch_jobs_run').on(table.runId),\n]);\n", "import { pgTable, uuid, text, real, timestamp, boolean, uniqueIndex, index } from 'drizzle-orm/pg-core';\nimport { profiles } from './profiles.js';\nimport { instructions } from './instructions.js';\nimport { projects } from './projects.js';\n\nexport const instructionSuggestions = pgTable('instruction_suggestions', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n instructionId: uuid('instruction_id').notNull().references(() => instructions.id, { onDelete: 'cascade' }),\n projectPath: text('project_path').notNull(),\n // Canonical project identity (migration 00104). Additive + nullable; the\n // unique index below stays on project_path (NOT NULL) so upserts are\n // unchanged. Readers prefer project_id to aggregate across path variants.\n projectId: uuid('project_id').references(() => projects.id, { onDelete: 'set null' }),\n score: real('score').notNull(),\n reason: text('reason').notNull(),\n generatedAt: timestamp('generated_at', { withTimezone: true }).notNull().defaultNow(),\n isStale: boolean('is_stale').notNull().default(false),\n dismissedAt: timestamp('dismissed_at', { withTimezone: true }),\n acceptedAt: timestamp('accepted_at', { withTimezone: true }),\n promotedToInstructionId: uuid('promoted_to_instruction_id').references((): any => instructions.id, { onDelete: 'set null' }),\n}, (table) => [\n uniqueIndex('idx_instruction_suggestions_user_project_instruction')\n .on(table.userId, table.projectPath, table.instructionId),\n index('idx_instruction_suggestions_user_project')\n .on(table.userId, table.projectPath),\n index('idx_instruction_suggestions_user_proj_id')\n .on(table.userId, table.projectId),\n index('idx_instruction_suggestions_generated_at')\n .on(table.generatedAt),\n]);\n\nexport const instructionSuggestionEvents = pgTable('instruction_suggestion_events', {\n id: uuid('id').primaryKey().defaultRandom(),\n suggestionId: uuid('suggestion_id').notNull().references(() => instructionSuggestions.id, { onDelete: 'cascade' }),\n userId: uuid('user_id').notNull().references(() => profiles.id, { onDelete: 'cascade' }),\n eventType: text('event_type').notNull(),\n tool: text('tool'),\n sessionId: uuid('session_id'),\n projectPath: text('project_path').notNull(),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n}, (table) => [\n index('idx_instruction_suggestion_events_suggestion_id').on(table.suggestionId),\n index('idx_instruction_suggestion_events_user_id').on(table.userId),\n]);\n", "import { pgTable, text, integer, numeric, timestamp, index, primaryKey } from 'drizzle-orm/pg-core';\n\n// Append-only versioned pricing for LLM model usage.\n// Cost lookup at time T picks the row where\n// effective_from <= T AND (effective_until IS NULL OR effective_until > T).\n// To change pricing: INSERT a new row, never UPDATE.\nexport const modelPricing = pgTable('model_pricing', {\n provider: text('provider').notNull(),\n modelId: text('model_id').notNull(),\n inputPerM: numeric('input_per_m').notNull(),\n outputPerM: numeric('output_per_m').notNull(),\n cacheReadPerM: numeric('cache_read_per_m').notNull(),\n cacheWrite5mPerM: numeric('cache_write_5m_per_m').notNull(),\n cacheWrite1hPerM: numeric('cache_write_1h_per_m').notNull(),\n contextWindow: integer('context_window'),\n effectiveFrom: timestamp('effective_from', { withTimezone: true }).notNull(),\n effectiveUntil: timestamp('effective_until', { withTimezone: true }),\n source: text('source').notNull(),\n}, (table) => [\n primaryKey({ columns: [table.provider, table.modelId, table.effectiveFrom] }),\n index('idx_model_pricing_active').on(table.provider, table.modelId, table.effectiveFrom.desc()),\n]);\n", "import { pgTable, text, numeric, timestamp, uuid, jsonb, index } from 'drizzle-orm/pg-core';\n\n// Append-only log of every signal we receive about a provider rate-limit.\n// Sources include `oauth_usage` (authoritative, Anthropic's own counter),\n// `self_observed_429`, `official_docs`, and `self_observed_lower_bound`.\n// Fused into `plan_limits_active` by `cron_fuse_observations`.\nexport const limitObservations = pgTable('limit_observations', {\n id: uuid('id').primaryKey().defaultRandom(),\n observedAt: timestamp('observed_at', { withTimezone: true }).notNull().defaultNow(),\n provider: text('provider').notNull(),\n plan: text('plan').notNull(),\n limitType: text('limit_type').notNull(),\n value: numeric('value').notNull(),\n unit: text('unit').notNull(),\n comparator: text('comparator').notNull().default('='),\n resetsAt: timestamp('resets_at', { withTimezone: true }),\n sourceType: text('source_type').notNull(),\n sourceUrl: text('source_url'),\n sourceEvidence: jsonb('source_evidence'),\n confidence: numeric('confidence').notNull(),\n userId: uuid('user_id'),\n}, (table) => [\n index('idx_limit_obs_lookup').on(table.provider, table.plan, table.limitType, table.observedAt.desc()),\n index('idx_limit_obs_user').on(table.userId, table.observedAt.desc()),\n]);\n", "import { pgTable, text, timestamp, uuid, jsonb, boolean, uniqueIndex } from 'drizzle-orm/pg-core';\n\n// Raw scraped HTML/text from provider docs (Anthropic rate-limits page, etc.).\n// Dedup by content_hash so a no-change re-scrape is a no-op. Parses produce\n// `official_docs` observations in `limit_observations`.\nexport const providerDocsSnapshots = pgTable('provider_docs_snapshots', {\n id: uuid('id').primaryKey().defaultRandom(),\n fetchedAt: timestamp('fetched_at', { withTimezone: true }).notNull().defaultNow(),\n provider: text('provider').notNull(),\n docUrl: text('doc_url').notNull(),\n contentHash: text('content_hash').notNull(),\n content: text('content').notNull(),\n parseSuccess: boolean('parse_success').notNull(),\n parseErrors: jsonb('parse_errors'),\n}, (table) => [\n uniqueIndex('idx_docs_dedup').on(table.provider, table.docUrl, table.contentHash),\n]);\n", "import { pgTable, text, numeric, timestamp, uuid, primaryKey, index } from 'drizzle-orm/pg-core';\n\n// The \"answer\" table \u2014 fused, time-versioned best-known limit for each\n// (provider, plan, limit_type). Read by the UI and burn-rate alerting.\n// Written by `cron_fuse_observations`; never hand-edited.\nexport const planLimitsActive = pgTable('plan_limits_active', {\n provider: text('provider').notNull(),\n plan: text('plan').notNull(),\n limitType: text('limit_type').notNull(),\n value: numeric('value').notNull(),\n unit: text('unit').notNull(),\n effectiveFrom: timestamp('effective_from', { withTimezone: true }).notNull(),\n effectiveUntil: timestamp('effective_until', { withTimezone: true }),\n confidence: numeric('confidence').notNull(),\n sourceObservationIds: uuid('source_observation_ids').array().notNull(),\n}, (table) => [\n primaryKey({ columns: [table.provider, table.plan, table.limitType, table.effectiveFrom] }),\n index('idx_plan_limits_lookup').on(table.provider, table.plan, table.limitType, table.effectiveFrom.desc()),\n]);\n", "import { pgTable, text, timestamp, uuid, jsonb, index } from 'drizzle-orm/pg-core';\n\n// Phase 7 \u2014 server-side record of every alert that was actually dispatched.\n// Read on the next evaluation tick to enforce hysteresis (don't re-fire\n// \"approaching\" while still above threshold) and cooldown (\u22655 min between\n// same-key dispatches). One row per dispatch, never updated in place \u2014 the\n// most-recent row per (user_id, alert_key) is the live state.\nexport const alertDispatches = pgTable('alert_dispatches', {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n alertKey: text('alert_key').notNull(),\n // 'soft' | 'approaching' | 'imminent' | 'hit'\n severity: text('severity').notNull(),\n lastDispatchedAt: timestamp('last_dispatched_at', { withTimezone: true }).notNull().defaultNow(),\n // { used_percentage, resets_at, ... } \u2014 snapshot of the input that fired this alert.\n lastState: jsonb('last_state').notNull(),\n // 'in_app' | 'vscode' | 'banner'\n channel: text('channel').notNull(),\n}, (table) => [\n index('idx_alert_user_key').on(table.userId, table.alertKey, table.lastDispatchedAt.desc()),\n]);\n", "import { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport * as schema from './schema/index.js';\nimport { trackDbOpStart, trackDbOpEnd } from './db-load.js';\n\nlet _db: PostgresJsDatabase<typeof schema> | undefined;\n// Module-scoped handle on the postgres-js client so closeDb() can drain the\n// pool on shutdown. Holding it here (vs. local to getDb) is load-bearing: a\n// bare process.exit() abandons the pool's Supavisor *client* sessions as\n// half-open ghosts that the pooler does not promptly reap \u2014 the prime\n// substrate of the recurring EMAXCONN 200-client saturation. See the\n// pool-exhaustion RCA (2026-06-21).\nlet _client: ReturnType<typeof postgres> | undefined;\n// Shutdown latch. Once closeDb() runs, the lazy `db` proxy must NOT re-spin a\n// fresh pool (getDb throws on _closed) and concurrent/repeat closeDb() callers\n// share ONE in-flight drain (_closing). Without this, a reconciler/watchdog tick\n// or in-flight request during the drain window allocated a NEW, never-closed\n// pool \u2014 re-orphaning the very Supavisor ghosts closeDb exists to release; and a\n// second concurrent caller could resolve early and let process.exit() fire\n// mid-drain. See docs/incidents/2026-06-21-pool-exhaustion.md.\nlet _closed = false;\nlet _closing: Promise<void> | undefined;\n// Dedicated single-connection client used ONLY by the db-wedge watchdog's\n// liveness probe. The watchdog must NOT probe through the shared `db` pool:\n// under pool starvation (heavy reads pinning all PG_POOL_MAX slots) a SELECT 1\n// on the shared pool queues behind them and times out \u2014 measuring pool\n// AVAILABILITY, not DB reachability. That false-positive is what drove the\n// restart crash-loop. A separate max:1 client answers the real question \u2014 \"can\n// a FRESH connection complete a trivial query?\" \u2014 so probe-fast + app-slow ==\n// saturation (load, never restart-worthy) and probe-fails == genuine DB/\n// connectivity loss. See docs/plans/2026-06-23-db-wedge-structural-review-and-roadmap.md.\nlet _probeClient: ReturnType<typeof postgres> | undefined;\n// Heavy-read BULKHEAD. A second, tiny pool reserved for the few intrinsically\n// expensive reads \u2014 full message-history reconstruction (de-TOASTing many\n// per-snapshot deltas) and in-process insights aggregations. These can hold a\n// connection for seconds; on the shared 8-slot pool a burst of them starves the\n// sub-millisecond auth/ingest queries behind them (a quarter of the recurring\n// \"DB wedge\" \u2014 see docs/plans/2026-06-23-db-wedge-structural-review-and-roadmap.md).\n// Isolating them here means a slow reconstruction can only ever exhaust the\n// 2-slot heavy pool, never the main pool; and it lets the MAIN pool safely run a\n// tight PG_STATEMENT_TIMEOUT_MS (which would otherwise abort these legit-long\n// aggregations \u2014 the reason fly.toml left it off).\nlet _heavyClient: ReturnType<typeof postgres> | undefined;\nlet _heavyDb: PostgresJsDatabase<typeof schema> | undefined;\n\nfunction getEnv(name: string): string {\n const value = process.env[name];\n if (!value) throw new Error(`Missing required env var: ${name}`);\n return value;\n}\n\n// Drizzle client \u2014 type-safe queries via postgres-js driver\n// IMPORTANT: prepare: false required for Supabase connection pooler (Transaction mode)\n// `application_name` lets pg_stat_activity attribute each connection back to a\n// specific process; `max` caps per-process Supavisor footprint (default 10 is\n// wasteful on the 200-slot shared pooler).\nexport function getDb(): PostgresJsDatabase<typeof schema> {\n if (_closed) {\n // The pool was drained for shutdown. Re-creating it here would leak a fresh,\n // never-closed pool (the exact regression that re-orphaned ghosts). Fail\n // loudly so the offending timer/request is fixed to stop before the drain.\n throw new Error(\n 'getDb() called after closeDb(): the connection pool is closed for shutdown. ' +\n 'Stop issuing queries (timers/requests) before draining the pool.',\n );\n }\n if (!_db) {\n const appName = process.env.PG_APPLICATION_NAME || 'rulemetric';\n const max = Number(process.env.PG_POOL_MAX) || 3;\n // Bound the blast radius of a wedged Supavisor socket. Without a query\n // timeout, a single stuck connection is held forever; on a small pool\n // that means a few wedged sockets hang EVERY authenticated request\n // (30s+ login hangs, only cleared by a process restart \u2014 see the\n // 2026-06-09 login-hang investigation and incidents 2026-05-20/21).\n //\n // - connect_timeout (always on): cap how long a NEW connection to a stale\n // pooler can block before erroring + retrying.\n // - statement_timeout (opt-in via env, server-side, verified honored\n // through the Supavisor transaction pooler): Postgres cancels a stuck\n // query, freeing the connection back to the pool \u2014 a transient wedge\n // now self-heals instead of permanently exhausting the pool. Left OFF\n // by default (0) so worker processes running legitimately long\n // analytics queries are unaffected; the always-on API opts in with a\n // tight value via PG_STATEMENT_TIMEOUT_MS.\n const connectTimeoutS = Number(process.env.PG_CONNECT_TIMEOUT_S) || 10;\n const statementTimeoutMs = Number(process.env.PG_STATEMENT_TIMEOUT_MS) || 0;\n // idle_timeout: how long an idle pooled connection is kept before close.\n // Originally pinned to 5s to beat Supavisor's server-side reap. But the\n // 2026-06-09 investigation showed that aggressive churn is itself the\n // problem: with sparse traffic + a worker polling every ~36s, a 5s idle\n // close forces a fresh getaddrinfo + TCP connect on nearly EVERY request,\n // maximizing exposure to an intermittently-flaky path to the rotating\n // pooler ELB (the source of the CONNECT_TIMEOUT/ENOTFOUND storms). A warmer\n // pool (kept alive by keep_alive TCP probes) reconnects far less often, so\n // it hits the bad network windows far less often. Env-configurable: the\n // always-on API sets a higher PG_IDLE_TIMEOUT; workers/tests keep the\n // conservative default. Paired with withDbRetry() so a connection that DOES\n // get reaped server-side is retried, not surfaced as a hard failure.\n const idleTimeoutS = Number(process.env.PG_IDLE_TIMEOUT) || 5;\n // TCP keepalive (postgres-js default is 60s; set explicitly). Keeps an\n // otherwise-idle socket from being seen as dead by intermediaries and lets\n // the OS detect a half-open connection sooner.\n const keepAliveS = Number(process.env.PG_KEEP_ALIVE_S) || 60;\n _client = postgres(getEnv('DATABASE_URL'), {\n prepare: false,\n max,\n connect_timeout: connectTimeoutS,\n idle_timeout: idleTimeoutS,\n keep_alive: keepAliveS,\n // Hard rotation cap. Even active connections get closed and replaced\n // after 5 minutes, defending against long-lived sockets that Supavisor\n // marks stale for reasons unrelated to idleness (max-lifetime, server\n // restart, network blip).\n max_lifetime: 300,\n connection: {\n application_name: appName,\n // postgres-js applies this as the server-side statement_timeout (ms).\n ...(statementTimeoutMs > 0 ? { statement_timeout: statementTimeoutMs } : {}),\n },\n });\n _db = drizzle(_client, { schema });\n }\n return _db;\n}\n\n/**\n * Heavy-read pool (BULKHEAD). Same Supavisor target as getDb() but a tiny,\n * isolated pool with NO statement_timeout \u2014 reserved for the few intrinsically\n * slow reads (full message-history reconstruction, insights aggregations) that\n * (a) must not compete with auth/ingest for the main pool's slots, and (b)\n * legitimately run longer than the main pool's tight PG_STATEMENT_TIMEOUT_MS.\n * Reach it via the `heavyDb` export. See the _heavyClient comment above.\n */\nexport function getHeavyDb(): PostgresJsDatabase<typeof schema> {\n if (_closed) {\n throw new Error(\n 'getHeavyDb() called after closeDb(): the connection pool is closed for shutdown. ' +\n 'Stop issuing queries (timers/requests) before draining the pool.',\n );\n }\n if (!_heavyDb) {\n const appName = (process.env.PG_APPLICATION_NAME || 'rulemetric') + ':heavy';\n // Small by design: a slow reconstruction can only ever exhaust THIS pool,\n // never the main auth/ingest pool. Default 2; env-tunable.\n const max = Number(process.env.PG_HEAVY_POOL_MAX) || 2;\n _heavyClient = postgres(getEnv('DATABASE_URL'), {\n prepare: false,\n max,\n connect_timeout: Number(process.env.PG_CONNECT_TIMEOUT_S) || 10,\n idle_timeout: Number(process.env.PG_IDLE_TIMEOUT) || 5,\n keep_alive: Number(process.env.PG_KEEP_ALIVE_S) || 60,\n max_lifetime: 300,\n connection: {\n application_name: appName,\n // Deliberately NO statement_timeout \u2014 these ARE the legitimately-long\n // reads this pool exists to host. The DB role's 120s timeout is the\n // ultimate backstop.\n },\n });\n _heavyDb = drizzle(_heavyClient, { schema });\n }\n return _heavyDb;\n}\n\n/**\n * Gracefully drain the connection pool. postgres-js keeps its Supavisor client\n * sessions open until `end()` sends the protocol Terminate; a bare\n * `process.exit()` leaves them as half-open pooler ghosts that Supavisor does\n * NOT promptly reap (root cause of the recurring `(EMAXCONN) max client\n * connections reached, limit: 200` saturation \u2014 see\n * docs/incidents/2026-06-21-pool-exhaustion.md). Call this on every CONTROLLED\n * exit: SIGTERM/SIGINT handlers, the db-wedge watchdog restart, fatal handlers.\n *\n * CAVEAT: SIGKILL, OOM-jetsam, and a launchd unload-timeout terminate the\n * process WITHOUT running this. That residual is bounded by PG_POOL_MAX +\n * PG_IDLE_TIMEOUT and ultimately depends on Supavisor reaping (a finite\n * client_idle_timeout) or a pooler restart \u2014 closeDb is NOT a guarantee, it\n * removes the dominant *controlled-exit* leak.\n *\n * Bounded + concurrency-safe: a 5s `end()` timeout caps the drain; the `_closing`\n * latch makes concurrent/repeat callers share one in-flight drain (a second\n * caller can no longer resolve early and let process.exit() fire mid-drain);\n * `_closed` poisons getDb() so nothing re-spins a fresh pool during the window.\n */\nexport async function closeDb(): Promise<void> {\n if (_closing) return _closing;\n _closed = true;\n const c = _client;\n const p = _probeClient;\n const h = _heavyClient;\n _client = undefined;\n _db = undefined;\n _probeClient = undefined;\n _heavyClient = undefined;\n _heavyDb = undefined;\n // Drain the shared pool, the watchdog's dedicated probe connection, AND the\n // heavy-read bulkhead pool so none is orphaned as a Supavisor ghost on a\n // controlled exit.\n _closing = Promise.allSettled([\n c ? c.end({ timeout: 5 }) : Promise.resolve(),\n p ? p.end({ timeout: 5 }) : Promise.resolve(),\n h ? h.end({ timeout: 5 }) : Promise.resolve(),\n ]).then(() => {\n // best-effort drain \u2014 the process is exiting anyway\n });\n return _closing;\n}\n\n/**\n * Liveness probe over a DEDICATED single connection (never the shared pool).\n * Resolves `{ ok: true }` only if a fresh connection can complete `SELECT 1`\n * within `timeoutMs`. Because it does not compete for the shared pool's slots,\n * a `false` result means the DB/network is genuinely unreachable (or the\n * Supavisor tenant is fully saturated so even a new connect is refused) \u2014 NOT\n * merely that the application pool is busy with legitimate slow reads. This is\n * the signal that lets the watchdog stop false-positiving a wedge under load.\n */\nexport async function probeDbReachable(\n timeoutMs: number,\n): Promise<{ ok: boolean; ms: number; err?: unknown }> {\n const t0 = Date.now();\n if (_closed) return { ok: false, ms: 0, err: new Error('pool closed for shutdown') };\n // Capture the client THIS probe uses in a scope the catch can see, so teardown\n // acts on the exact client we queried \u2014 never on whatever the global points at\n // by the time we fail (see the compare-and-swap teardown below).\n let client = _probeClient;\n try {\n if (!client) {\n client = postgres(getEnv('DATABASE_URL'), {\n prepare: false,\n max: 1,\n connect_timeout: Number(process.env.PG_CONNECT_TIMEOUT_S) || 10,\n idle_timeout: 20,\n max_lifetime: 300,\n connection: {\n application_name: (process.env.PG_APPLICATION_NAME || 'rulemetric') + ':probe',\n // Server-side backstop (Fix 2): cancel a stuck SELECT 1 a beat before\n // the Promise.race timer fires, so a hung query can't pin the socket.\n // Honored through the Supavisor txn pooler (see getDb's note). Best-\n // effort only: if the stall is at the pooler's transaction-assignment\n // layer no backend is reached, so this does NOT replace the\n // catch-teardown below.\n statement_timeout: Math.max(2000, timeoutMs - 2000),\n },\n });\n _probeClient = client;\n }\n await Promise.race([\n client`SELECT 1`,\n new Promise((_, reject) =>\n setTimeout(() => reject(new Error('db probe timeout')), timeoutMs),\n ),\n ]);\n return { ok: true, ms: Date.now() - t0 };\n } catch (err) {\n // ROOT-CAUSE FIX (Fix 1; see db-wedge-rca-probe-singleton-2026-06-28): tear\n // down the probe client on EVERY failure so the next tick dials a genuinely\n // fresh connection. Promise.race ABANDONS (does not cancel) a hung SELECT 1;\n // reusing this client would let that orphaned query pin the single max:1\n // socket forever, so the probe could never recover \u2014 a permanent NOT-READY\n // wedge cleared only by a process restart.\n //\n // Compare-and-swap on the LOCAL client: only clear the global if it still\n // points at the client we used, and only end THAT client. Overlapping probes\n // are real (the unguarded GET /health/deep route + the 30s watchdog), and a\n // naive `_probeClient = undefined; _probeClient.end()` would let a late-\n // failing probe on a dead client tear down a fresh, healthy, in-use one \u2014\n // a spurious {ok:false} plus reconnect churn. End our own client in the\n // background (best-effort); the next call rebuilds immediately.\n if (_probeClient === client) _probeClient = undefined;\n void client?.end({ timeout: 1 }).catch(() => {});\n return { ok: false, ms: Date.now() - t0, err };\n }\n}\n\n// True when an error is a getDb()/getHeavyDb()-after-closeDb() guard firing \u2014 i.e.\n// an in-flight request or timer touched the DB during the shutdown drain window.\n// The HTTP error handler maps this to a quiet 503 (\"server draining\") instead of\n// logging it as an \"Unhandled error\" 500 \u2014 the source of the multi-thousand-line\n// error storms seen during the watchdog crash-loop. See the structural-review doc.\n// Marker is the shared suffix so it matches BOTH getDb() and getHeavyDb() (the\n// bulkhead pool) \u2014 'getDb() ...' is NOT a substring of 'getHeavyDb() ...'.\nconst POOL_CLOSED_MARKER = 'called after closeDb()';\nexport function isPoolClosedError(err: unknown): boolean {\n const m = (err as { message?: unknown } | null)?.message;\n return typeof m === 'string' && m.includes(POOL_CLOSED_MARKER);\n}\n\n// Connection-ESTABLISHMENT error codes only. These all occur BEFORE any query\n// bytes are written to the socket, so retrying the operation cannot double-\n// apply a write \u2014 it is safe for reads AND writes. ECONNRESET is deliberately\n// EXCLUDED: a reset can happen mid-stream (after a query was sent), where a\n// blind retry of a write could double-apply. The dominant failures in the\n// 2026-06-09 incident were CONNECT_TIMEOUT (4709) and ENOTFOUND (360), both\n// covered here.\nconst RETRYABLE_CONNECT_CODES = new Set([\n 'CONNECT_TIMEOUT',\n 'ETIMEDOUT',\n 'ENOTFOUND',\n 'ECONNREFUSED',\n 'EAI_AGAIN',\n]);\n\nexport function isRetryableConnectError(err: unknown): boolean {\n const e = err as { code?: string; errno?: string; cause?: { code?: string } } | null;\n const code = e?.code ?? e?.cause?.code ?? e?.errno;\n return code !== undefined && RETRYABLE_CONNECT_CODES.has(code);\n}\n\n// Mid-stream connection-RESET codes. These can fire AFTER a query was written to\n// the socket (the Supavisor pooler reaping a connection the client still holds \u2014\n// the dead-socket \"wedge\"), so a blind retry of a WRITE could double-apply. They\n// are therefore retried ONLY for reads (idempotent SELECTs), gated by\n// `opts.retryResets`, which `wrapBuilder` sets true exclusively for read-entry\n// query builders. This is the dominant local-API wedge signature (the API holds\n// a Supavisor-reaped socket and the next read hangs/throws CONNECTION_CLOSED).\nconst RETRYABLE_RESET_CODES = new Set(['CONNECTION_CLOSED', 'ECONNRESET', 'EPIPE']);\n\nexport function isRetryableResetError(err: unknown): boolean {\n const e = err as { code?: string; errno?: string; cause?: { code?: string } } | null;\n const code = e?.code ?? e?.cause?.code ?? e?.errno;\n return code !== undefined && RETRYABLE_RESET_CODES.has(code);\n}\n\n/**\n * Retry a DB operation on transient connection failures. By default retries ONLY\n * connection-establishment errors (timeouts / DNS / refused) \u2014 these happen\n * BEFORE the query reaches Postgres, so retrying is safe even for writes.\n *\n * With `opts.retryResets`, ALSO retries mid-stream resets (CONNECTION_CLOSED /\n * ECONNRESET) \u2014 the dead-socket wedge where the Supavisor pooler closed a\n * connection the client still had pooled. This is safe ONLY for idempotent reads\n * (re-running a SELECT cannot double-apply), so `wrapBuilder` enables it for\n * read-entry builders and NEVER for insert/update/delete/execute. postgres-js\n * evicts the dead socket on error, so the retried attempt acquires a fresh one.\n *\n * Bounded exponential backoff; anything non-retryable propagates at once.\n */\nexport async function withDbRetry<T>(\n fn: () => Promise<T>,\n opts: { attempts?: number; baseMs?: number; retryResets?: boolean } = {},\n): Promise<T> {\n const attempts = opts.attempts ?? 3;\n const baseMs = opts.baseMs ?? 100;\n let lastErr: unknown;\n for (let i = 0; i < attempts; i++) {\n try {\n return await fn();\n } catch (err) {\n lastErr = err;\n const retryable =\n isRetryableConnectError(err) || (opts.retryResets === true && isRetryableResetError(err));\n if (i === attempts - 1 || !retryable) throw err;\n await new Promise((resolve) => setTimeout(resolve, baseMs * 2 ** i));\n }\n }\n throw lastErr;\n}\n\n/**\n * Client-side query deadline (MAIN pool only). `statement_timeout` bounds a query\n * once it is EXECUTING, but a query WAITING for a pool slot (postgres-js's\n * unbounded acquire-queue) or stuck on a half-open Supavisor-reaped socket never\n * reaches \"executing\", so nothing bounds it \u2014 the caller hangs until its own HTTP\n * timeout, or forever, pinning the request (this is the DB-wedge: authed requests\n * hung 20s while the pool was saturated by a capture write-storm). This deadline\n * makes such a query FAIL FAST (reject) so the caller returns an error instead of\n * hanging. Set GENEROUSLY above `statement_timeout` so it only ever catches true\n * hangs \u2014 a legit executing query is killed by `statement_timeout` first and\n * rejects before this fires. Default 20s; `0` disables. Deliberately NOT applied\n * to `heavyDb` (intrinsically-long reads run with no statement_timeout by design).\n */\nexport class QueryDeadlineError extends Error {\n code = 'QUERY_DEADLINE';\n constructor(ms: number) {\n super(\n `Query exceeded the client-side deadline of ${ms}ms \u2014 the DB pool is likely ` +\n `saturated (acquire-wait) or holding a dead socket; failing fast to avoid ` +\n `pinning the caller. See client.ts.`,\n );\n this.name = 'QueryDeadlineError';\n }\n}\n\nexport function isQueryDeadlineError(err: unknown): boolean {\n return (err as { code?: unknown } | null)?.code === 'QUERY_DEADLINE';\n}\n\nexport function queryDeadlineMs(): number {\n const explicit = Number(process.env.PG_QUERY_DEADLINE_MS);\n // `0` explicitly disables; any other non-finite/negative \u2192 the 20s default.\n if (Number.isFinite(explicit) && explicit >= 0) return explicit;\n return 20_000;\n}\n\n// Race a query promise against the client-side deadline. On timeout the query is\n// ABANDONED, not cancelled, and the caller is freed immediately. Two sub-cases:\n// an already-EXECUTING query is bounded server-side by statement_timeout; but an\n// ACQUIRE-WAIT query (the primary wedge case) has NOT been sent yet \u2014 when a slot\n// later frees it still executes and commits, so a retried WRITE can double-apply.\n// That window is inherent to any client-side timeout over postgres-js's acquire\n// queue (it already existed at the HTTP-timeout layer), only opens during a true\n// wedge, and is kept rare by the generous 20s default + admission shedding. It is\n// SAFE only because the write paths that a caller retries are idempotent by design\n// (the session-end hook's reimport = DELETE+re-INSERT keyed by sequence, enrich +\n// derive-enrichment = overwrite/recompute); a non-retried write cannot double-apply.\n// `unref()` so the timer never keeps the process alive; `clearTimeout` on settle\n// avoids a dangling handle.\nfunction raceWithDeadline<T>(p: Promise<T>, ms: number): Promise<T> {\n let timer: ReturnType<typeof setTimeout>;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new QueryDeadlineError(ms)), ms);\n const t = timer as unknown as { unref?: () => void };\n if (typeof t.unref === 'function') t.unref();\n });\n return Promise.race([p, deadline]).finally(() => clearTimeout(timer));\n}\n\n// Drizzle's query builders are lazy and re-runnable: awaiting one a second time\n// re-executes the query (verified). That lets us make EVERY query connect-retry\n// aware in one place instead of wrapping ~400 call sites in withDbRetry by hand.\n//\n// `wrapBuilder` returns a transparent Proxy over a builder that:\n// - intercepts the terminal `then` and runs the execution through withDbRetry,\n// so a transient CONNECT_TIMEOUT/ENOTFOUND blip against the Supavisor pooler\n// becomes a sub-second retried success instead of a 500 / hung request;\n// - re-wraps the builders returned by chained methods (.from/.where/.limit/\u2026)\n// so the chain stays retry-aware all the way to the terminal await.\n// All other property access (including drizzle's internal `entityKind`/`is()`\n// brand symbols, used for subquery embedding) is forwarded untouched via\n// Reflect, so query semantics are unchanged \u2014 only connection-establishment\n// failures are retried (never mid-stream resets or query errors).\nconst RETRY_ENTRY_METHODS = new Set([\n 'select',\n 'selectDistinct',\n 'selectDistinctOn',\n 'insert',\n 'update',\n 'delete',\n 'execute',\n 'with',\n '$count',\n 'refreshMaterializedView',\n]);\n\n// READ-ONLY entry methods: their builders only ever produce SELECTs, so retrying\n// a mid-stream reset is idempotent (safe). Everything else in RETRY_ENTRY_METHODS\n// (insert/update/delete/execute/with/refreshMaterializedView) keeps\n// establishment-only retry \u2014 `execute` and `with` are excluded because raw SQL\n// and CTEs can carry writes. The read/write split is the entire safety boundary\n// for reset-retry.\nconst READ_ONLY_ENTRY_METHODS = new Set([\n 'select',\n 'selectDistinct',\n 'selectDistinctOn',\n '$count',\n]);\n\n// `readSafe` propagates down the builder chain (.from/.where/.limit/\u2026) so the\n// terminal `then` knows whether reset-retry is allowed for THIS query.\nexport function wrapBuilder<T>(value: T, readSafe = false, deadlineMs = 0): T {\n if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {\n return value;\n }\n return new Proxy(value as object, {\n get(target, prop, receiver) {\n if (prop === 'then') {\n const then = Reflect.get(target, prop, receiver);\n if (typeof then !== 'function') return then;\n return (onFulfilled?: unknown, onRejected?: unknown) => {\n // Gauge one in-flight DB op for the whole logical query (retries\n // included) so the API's admission gate (dbLoadShed) can fast-503\n // before the pool's acquire-queue grows unbounded. Decrement on\n // settle, success or failure. See db-load.ts.\n trackDbOpStart();\n const exec = withDbRetry(\n () =>\n new Promise((resolve, reject) =>\n (then as (...a: unknown[]) => unknown).call(target, resolve, reject),\n ),\n { retryResets: readSafe },\n );\n // Client-side deadline (main pool only): a hung acquire-wait / dead\n // socket rejects fast instead of pinning the caller. trackDbOpEnd fires\n // once, on whichever settles first (query or deadline) \u2014 no double-dec,\n // no leak. See queryDeadlineMs / raceWithDeadline above.\n const guarded = deadlineMs > 0 ? raceWithDeadline(exec, deadlineMs) : exec;\n return guarded\n .finally(trackDbOpEnd)\n .then(onFulfilled as never, onRejected as never);\n };\n }\n const v = Reflect.get(target, prop, receiver);\n if (typeof v === 'function') {\n return (...args: unknown[]) =>\n wrapBuilder((v as (...a: unknown[]) => unknown).apply(target, args), readSafe, deadlineMs);\n }\n return v;\n },\n }) as T;\n}\n\n// Gauge a `db.transaction(...)` as ONE in-flight DB op for its whole duration.\n// A transaction holds exactly one pool connection from BEGIN to COMMIT/ROLLBACK,\n// but its queries run on the tx-scoped client and so bypass `wrapBuilder` \u2014 i.e.\n// transaction-based pool usage is invisible to the gauge unless counted here.\n// Counting the transaction itself as 1 (not each inner query) matches the single\n// connection it actually holds. Decrement on settle, success or failure.\nexport function gaugeTransaction<T>(run: () => Promise<T>): Promise<T> {\n trackDbOpStart();\n try {\n return Promise.resolve(run()).finally(trackDbOpEnd);\n } catch (err) {\n // run() threw synchronously (before returning a promise) \u2014 don't leak the gauge.\n trackDbOpEnd();\n throw err;\n }\n}\n\n// Convenience getters that match the original export names. Query-entry methods\n// (select/insert/execute/\u2026) return retry-wrapped builders; `transaction` is\n// gauged for admission control; everything else is forwarded straight through to\n// the live drizzle instance. Read-entry builders additionally get mid-stream\n// reset-retry (the dead-socket wedge fix).\nexport const db = new Proxy({} as PostgresJsDatabase<typeof schema>, {\n get(_target, prop) {\n const real = getDb() as unknown as Record<string | symbol, unknown>;\n const value = real[prop];\n if (\n typeof prop === 'string' &&\n RETRY_ENTRY_METHODS.has(prop) &&\n typeof value === 'function'\n ) {\n const readSafe = READ_ONLY_ENTRY_METHODS.has(prop);\n // Main pool \u2192 apply the client-side query deadline. (heavyDb does NOT.)\n const deadlineMs = queryDeadlineMs();\n return (...args: unknown[]) =>\n wrapBuilder((value as (...a: unknown[]) => unknown).apply(real, args), readSafe, deadlineMs);\n }\n // Transactions bypass wrapBuilder but still hold a pool connection \u2014 gauge them\n // so dbLoadShed sees transaction-heavy load (sessions/instructions/skills/\u2026).\n if (prop === 'transaction' && typeof value === 'function') {\n return (...args: unknown[]) =>\n gaugeTransaction(() => (value as (...a: unknown[]) => unknown).apply(real, args) as Promise<unknown>);\n }\n return value;\n },\n});\n\n// Heavy-read bulkhead, same retry-wrapping as `db` but backed by the isolated\n// getHeavyDb() pool. Use ONLY for intrinsically slow reads (message-history\n// reconstruction, insights aggregations) so they cannot starve the main pool.\nexport const heavyDb = new Proxy({} as PostgresJsDatabase<typeof schema>, {\n get(_target, prop) {\n const real = getHeavyDb() as unknown as Record<string | symbol, unknown>;\n const value = real[prop];\n if (\n typeof prop === 'string' &&\n RETRY_ENTRY_METHODS.has(prop) &&\n typeof value === 'function'\n ) {\n const readSafe = READ_ONLY_ENTRY_METHODS.has(prop);\n return (...args: unknown[]) =>\n wrapBuilder((value as (...a: unknown[]) => unknown).apply(real, args), readSafe);\n }\n // Heavy transactions (e.g. the sessions reimport) hold a heavy-pool\n // connection from BEGIN to COMMIT but bypass wrapBuilder \u2014 gauge them so\n // getDbLoad()/dbLoadShed can see a reimport storm. Observability ONLY:\n // deliberately NO client-side query deadline here (heavyDb hosts the\n // intrinsically-long operations that run deadline-free by design).\n if (prop === 'transaction' && typeof value === 'function') {\n return (...args: unknown[]) =>\n gaugeTransaction(() => (value as (...a: unknown[]) => unknown).apply(real, args) as Promise<unknown>);\n }\n return value;\n },\n});\n", "export * from './tables/index.js';\nexport * from './relations.js';\n", "import { relations } from 'drizzle-orm';\nimport {\n profiles,\n organizations,\n teams,\n userOrganizations,\n userTeams,\n orgInvitations,\n instructions,\n instructionVersions,\n instructionEvents,\n projects,\n projectInstructions,\n sessions,\n sessionEvents,\n sessionInstructions,\n packs,\n packInstructions,\n instructionUsageEvents,\n evalTargets,\n evals,\n evalRuns,\n benchmarks,\n triggerEvals,\n optimizationRuns,\n contextSnapshots,\n evalJobs,\n apiKeys,\n evalConversations,\n securityEvents,\n harnessReleases,\n agentRuns,\n launchJobs,\n} from './tables/index.js';\n\nexport const profilesRelations = relations(profiles, ({ many }) => ({\n sessions: many(sessions),\n contextSnapshots: many(contextSnapshots),\n apiKeys: many(apiKeys),\n}));\n\nexport const apiKeysRelations = relations(apiKeys, ({ one }) => ({\n profile: one(profiles, {\n fields: [apiKeys.userId],\n references: [profiles.id],\n }),\n}));\n\nexport const organizationsRelations = relations(organizations, ({ many }) => ({\n teams: many(teams),\n userOrganizations: many(userOrganizations),\n projects: many(projects),\n invitations: many(orgInvitations),\n}));\n\nexport const teamsRelations = relations(teams, ({ one, many }) => ({\n organization: one(organizations, {\n fields: [teams.orgId],\n references: [organizations.id],\n }),\n userTeams: many(userTeams),\n invitations: many(orgInvitations),\n}));\n\nexport const orgInvitationsRelations = relations(orgInvitations, ({ one }) => ({\n organization: one(organizations, {\n fields: [orgInvitations.orgId],\n references: [organizations.id],\n }),\n team: one(teams, {\n fields: [orgInvitations.teamId],\n references: [teams.id],\n }),\n inviter: one(profiles, {\n fields: [orgInvitations.invitedBy],\n references: [profiles.id],\n }),\n}));\n\nexport const userOrganizationsRelations = relations(userOrganizations, ({ one }) => ({\n organization: one(organizations, {\n fields: [userOrganizations.orgId],\n references: [organizations.id],\n }),\n}));\n\nexport const userTeamsRelations = relations(userTeams, ({ one }) => ({\n team: one(teams, {\n fields: [userTeams.teamId],\n references: [teams.id],\n }),\n}));\n\nexport const instructionsRelations = relations(instructions, ({ one, many }) => ({\n versions: many(instructionVersions),\n projectInstructions: many(projectInstructions),\n events: many(instructionEvents),\n usageEvents: many(instructionUsageEvents),\n sessionInstructions: many(sessionInstructions),\n packInstructions: many(packInstructions),\n forkedFrom: one(instructions, {\n fields: [instructions.forkedFromId],\n references: [instructions.id],\n }),\n}));\n\nexport const instructionEventsRelations = relations(instructionEvents, ({ one }) => ({\n instruction: one(instructions, {\n fields: [instructionEvents.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const instructionVersionsRelations = relations(instructionVersions, ({ one }) => ({\n instruction: one(instructions, {\n fields: [instructionVersions.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const projectsRelations = relations(projects, ({ one, many }) => ({\n organization: one(organizations, {\n fields: [projects.orgId],\n references: [organizations.id],\n }),\n projectInstructions: many(projectInstructions),\n sessions: many(sessions),\n}));\n\nexport const projectInstructionsRelations = relations(projectInstructions, ({ one }) => ({\n project: one(projects, {\n fields: [projectInstructions.projectId],\n references: [projects.id],\n }),\n instruction: one(instructions, {\n fields: [projectInstructions.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const sessionsRelations = relations(sessions, ({ one, many }) => ({\n profile: one(profiles, {\n fields: [sessions.userId],\n references: [profiles.id],\n }),\n project: one(projects, {\n fields: [sessions.projectId],\n references: [projects.id],\n }),\n run: one(agentRuns, {\n fields: [sessions.runId],\n references: [agentRuns.id],\n }),\n events: many(sessionEvents),\n sessionInstructions: many(sessionInstructions),\n contextSnapshots: many(contextSnapshots),\n}));\n\nexport const agentRunsRelations = relations(agentRuns, ({ one, many }) => ({\n profile: one(profiles, {\n fields: [agentRuns.userId],\n references: [profiles.id],\n }),\n organization: one(organizations, {\n fields: [agentRuns.orgId],\n references: [organizations.id],\n }),\n project: one(projects, {\n fields: [agentRuns.projectId],\n references: [projects.id],\n }),\n sessions: many(sessions),\n launchJobs: many(launchJobs),\n}));\n\nexport const launchJobsRelations = relations(launchJobs, ({ one }) => ({\n run: one(agentRuns, {\n fields: [launchJobs.runId],\n references: [agentRuns.id],\n }),\n}));\n\nexport const sessionEventsRelations = relations(sessionEvents, ({ one }) => ({\n session: one(sessions, {\n fields: [sessionEvents.sessionId],\n references: [sessions.id],\n }),\n}));\n\nexport const sessionInstructionsRelations = relations(sessionInstructions, ({ one }) => ({\n session: one(sessions, {\n fields: [sessionInstructions.sessionId],\n references: [sessions.id],\n }),\n instruction: one(instructions, {\n fields: [sessionInstructions.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const packsRelations = relations(packs, ({ one, many }) => ({\n packInstructions: many(packInstructions),\n forkedFrom: one(packs, {\n fields: [packs.forkedFromId],\n references: [packs.id],\n }),\n}));\n\nexport const packInstructionsRelations = relations(packInstructions, ({ one }) => ({\n pack: one(packs, {\n fields: [packInstructions.packId],\n references: [packs.id],\n }),\n instruction: one(instructions, {\n fields: [packInstructions.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const instructionUsageEventsRelations = relations(instructionUsageEvents, ({ one }) => ({\n instruction: one(instructions, {\n fields: [instructionUsageEvents.instructionId],\n references: [instructions.id],\n }),\n}));\n\nexport const evalTargetsRelations = relations(evalTargets, ({ one, many }) => ({\n parent: one(evalTargets, {\n fields: [evalTargets.parentId],\n references: [evalTargets.id],\n }),\n evals: many(evals),\n evalRuns: many(evalRuns),\n benchmarks: many(benchmarks),\n triggerEvals: many(triggerEvals),\n optimizationRuns: many(optimizationRuns),\n evalJobs: many(evalJobs),\n evalConversations: many(evalConversations),\n}));\n\nexport const evalsRelations = relations(evals, ({ one, many }) => ({\n evalTarget: one(evalTargets, {\n fields: [evals.evalTargetId],\n references: [evalTargets.id],\n }),\n runs: many(evalRuns),\n}));\n\nexport const evalRunsRelations = relations(evalRuns, ({ one }) => ({\n eval: one(evals, {\n fields: [evalRuns.evalId],\n references: [evals.id],\n }),\n evalTarget: one(evalTargets, {\n fields: [evalRuns.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const benchmarksRelations = relations(benchmarks, ({ one }) => ({\n evalTarget: one(evalTargets, {\n fields: [benchmarks.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const triggerEvalsRelations = relations(triggerEvals, ({ one }) => ({\n evalTarget: one(evalTargets, {\n fields: [triggerEvals.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const optimizationRunsRelations = relations(optimizationRuns, ({ one }) => ({\n evalTarget: one(evalTargets, {\n fields: [optimizationRuns.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const evalJobsRelations = relations(evalJobs, ({ one }) => ({\n evalTarget: one(evalTargets, {\n fields: [evalJobs.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const evalConversationsRelations = relations(evalConversations, ({ one }) => ({\n evalTarget: one(evalTargets, {\n fields: [evalConversations.evalTargetId],\n references: [evalTargets.id],\n }),\n}));\n\nexport const contextSnapshotsRelations = relations(contextSnapshots, ({ one }) => ({\n session: one(sessions, {\n fields: [contextSnapshots.sessionId],\n references: [sessions.id],\n }),\n profile: one(profiles, {\n fields: [contextSnapshots.userId],\n references: [profiles.id],\n }),\n}));\n", "// In-flight DB-operation gauge. Two instrumentation points in client.ts feed it:\n// `wrapBuilder` increments on every logical query (the chokepoint all ~400\n// select/insert/execute call sites pass through), and `gaugeTransaction` counts\n// each `db.transaction(...)` once (transactions bypass wrapBuilder but still hold\n// a pool connection). Both decrement on settle (retries included: one logical\n// query counts once). The API's `dbLoadShed` middleware READS `getDbLoad()` to\n// fast-503 a transient capture spike BEFORE it piles up as unbounded postgres-js\n// acquire-waiters (the 30s-spinner-then-500 that looks like a wedge), closing the\n// gap between \"healthy\" and the SUSTAINED-failure readiness shed (`dbShed`).\n//\n// Process-local, intentionally: it measures THIS process's concurrent demand on\n// the shared pool, which is what the per-process admission gate acts on. It does\n// NOT bound the cross-process total (that's Phase 3 of the plan). The dedicated\n// watchdog probe (probeDbReachable) uses a raw client that never flows through\n// wrapBuilder, so it is correctly excluded from this count.\n// See docs/plans/2026-06-28-db-ingest-load-admission-control.md.\n\nlet _inFlight = 0;\n// High-water mark + shed count: the observability needed to TUNE PG_INFLIGHT_MAX\n// from real numbers instead of guessing. Peak is the max concurrency this process\n// has seen since boot (set the cap comfortably above the normal peak); shedCount\n// is how many requests the gate has rejected (a non-zero, climbing value means\n// the cap is too low OR there is a real saturation event). Exposed via\n// GET /api/diag/pg-health.\nlet _peak = 0;\nlet _shedCount = 0;\n// Ingest-gate sheds are counted SEPARATELY from the global gate: the write-path\n// gate (`ingestLoadShed`) fires at a lower, ingest-only ceiling, so a climbing\n// `_ingestShedCount` while `_shedCount` stays flat is the specific signal that a\n// context-snapshot burst is being backpressured (the wedge this closes).\nlet _ingestShedCount = 0;\n\n/** Increment the in-flight gauge. Called once per logical query by wrapBuilder. */\nexport function trackDbOpStart(): void {\n _inFlight++;\n if (_inFlight > _peak) _peak = _inFlight;\n}\n\n/** Decrement the in-flight gauge. Called when a logical query settles. Floored\n * at 0 so an unbalanced decrement can never drive the gauge negative. */\nexport function trackDbOpEnd(): void {\n if (_inFlight > 0) _inFlight--;\n}\n\n/** Current number of in-flight DB operations in this process. */\nexport function getDbLoad(): number {\n return _inFlight;\n}\n\n/** Record that the global admission gate shed one request. Called by `dbLoadShed`. */\nexport function recordDbShed(): void {\n _shedCount++;\n}\n\n/** Record that the write-path ingest gate shed one request. Called by `ingestLoadShed`. */\nexport function recordIngestShed(): void {\n _ingestShedCount++;\n}\n\n/** Snapshot of the gauge for diagnostics: current load, since-boot peak, and the\n * cumulative counts of requests shed by the global gate and the ingest gate. */\nexport function getDbLoadStats(): {\n current: number;\n peak: number;\n shedCount: number;\n ingestShedCount: number;\n} {\n return {\n current: _inFlight,\n peak: _peak,\n shedCount: _shedCount,\n ingestShedCount: _ingestShedCount,\n };\n}\n\n/**\n * The admission ceiling the gate compares `getDbLoad()` against. Centralized here\n * (rather than in the middleware) so the gate and the diag endpoint agree on one\n * value. Default = PG_POOL_MAX x 4; an explicit positive PG_INFLIGHT_MAX wins.\n * Read live so it stays runtime-tunable without a redeploy.\n */\nexport function dbInflightMax(): number {\n const explicit = Number(process.env.PG_INFLIGHT_MAX);\n if (Number.isFinite(explicit) && explicit > 0) return explicit;\n const poolMax = Number(process.env.PG_POOL_MAX) || 3;\n return poolMax * 4;\n}\n\n/**\n * The STRICTER ceiling the write-path ingest gate (`ingestLoadShed`) compares\n * `getDbLoad()` against \u2014 set BELOW `dbInflightMax()` so a context-snapshot burst\n * is shed while total in-flight is still climbing, RESERVING the upper half of the\n * admission budget for auth + dashboard reads (the reserved-slots pattern:\n * ingest can never monopolize the whole pool and starve login).\n *\n * Default = half the global cap, floored at PG_POOL_MAX so ingest can always use\n * at least the pool's worth of slots (e.g. pool 10 \u2192 global 40, ingest 20). An\n * explicit positive PG_INGEST_INFLIGHT_MAX wins. Read live so it stays\n * runtime-tunable from the `inflight_peak` / `ingest_shed_count` telemetry\n * (GET /api/diag/pg-health) without a redeploy. Expressed relative to the SAME\n * baseline as the global gate to avoid confusing logical-queries with pool\n * connections \u2014 it is a fraction of the admission budget, not a raw slot count.\n *\n * INVARIANT: the result is ALWAYS clamped to `<= dbInflightMax()`. The ingest\n * gate runs AFTER the (lower-by-design) global gate in the middleware chain, so\n * an ingest ceiling above the global one could never fire \u2014 the global gate\n * would shed ingest first, silently defeating the reserve. Both the explicit\n * override and the poolMax floor can otherwise push the ingest ceiling above the\n * global cap (e.g. a hand-tightened PG_INFLIGHT_MAX below PG_POOL_MAX), so we\n * clamp unconditionally.\n */\nexport function dbIngestInflightMax(): number {\n const global = dbInflightMax();\n const explicit = Number(process.env.PG_INGEST_INFLIGHT_MAX);\n if (Number.isFinite(explicit) && explicit > 0) return Math.min(explicit, global);\n const poolMax = Number(process.env.PG_POOL_MAX) || 3;\n return Math.min(global, Math.max(poolMax, Math.floor(global / 2)));\n}\n\n/** Test-only: force the gauge to a value (clamped at 0). Updates the peak. */\nexport function __setDbLoad(n: number): void {\n _inFlight = n > 0 ? n : 0;\n if (_inFlight > _peak) _peak = _inFlight;\n}\n\n/** Test-only reset of current, peak, and both shed counts. */\nexport function __resetDbLoad(): void {\n _inFlight = 0;\n _peak = 0;\n _shedCount = 0;\n _ingestShedCount = 0;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["pgTable", "text", "timestamp", "uuid", "pgTable", "uuid", "text", "timestamp", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "boolean", "index", "boolean", "jsonb", "pgTable", "primaryKey", "text", "timestamp", "uniqueIndex", "uuid", "pgTable", "text", "timestamp", "jsonb", "uuid", "boolean", "pgTable", "uuid", "text", "jsonb", "timestamp", "uniqueIndex", "primaryKey", "boolean", "pgTable", "uuid", "text", "jsonb", "boolean", "integer", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "uniqueIndex", "index", "pgTable", "uuid", "text", "timestamp", "integer", "jsonb", "index", "uniqueIndex", "boolean", "index", "integer", "jsonb", "pgTable", "text", "timestamp", "uniqueIndex", "uuid", "pgTable", "text", "timestamp", "uuid", "index", "pgTable", "uuid", "text", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "pgTable", "uuid", "text", "jsonb", "timestamp", "index", "pgTable", "text", "timestamp", "uuid", "jsonb", "uniqueIndex", "index", "pgTable", "uuid", "text", "jsonb", "timestamp", "uniqueIndex", "index", "boolean", "index", "jsonb", "pgTable", "text", "timestamp", "uuid", "integer", "pgTable", "uuid", "text", "boolean", "jsonb", "integer", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "boolean", "uniqueIndex", "index", "primaryKey", "pgTable", "uuid", "text", "jsonb", "timestamp", "boolean", "uniqueIndex", "index", "integer", "primaryKey", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "pgTable", "uuid", "text", "jsonb", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "index", "pgTable", "uuid", "jsonb", "text", "integer", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "real", "index", "uniqueIndex", "pgTable", "uuid", "integer", "text", "jsonb", "real", "timestamp", "index", "uniqueIndex", "pgTable", "text", "timestamp", "jsonb", "integer", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "integer", "bigint", "pgTable", "uuid", "text", "jsonb", "integer", "bigint", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "integer", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "uniqueIndex", "integer", "bigint", "pgTable", "uuid", "text", "jsonb", "integer", "bigint", "timestamp", "index", "uniqueIndex", "pgTable", "text", "timestamp", "uuid", "index", "uniqueIndex", "pgTable", "uuid", "text", "timestamp", "index", "uniqueIndex", "pgTable", "text", "timestamp", "uuid", "index", "pgTable", "text", "uuid", "timestamp", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "pgTable", "uuid", "jsonb", "text", "timestamp", "index", "pgTable", "uuid", "text", "jsonb", "timestamp", "index", "pgTable", "text", "timestamp", "uuid", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "pgTable", "text", "timestamp", "jsonb", "uuid", "uniqueIndex", "index", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "uniqueIndex", "pgTable", "text", "timestamp", "jsonb", "uuid", "index", "integer", "bigint", "pgTable", "uuid", "text", "jsonb", "integer", "bigint", "timestamp", "index", "pgTable", "uuid", "text", "real", "timestamp", "boolean", "uniqueIndex", "index", "pgTable", "uuid", "text", "real", "timestamp", "boolean", "uniqueIndex", "index", "pgTable", "text", "integer", "timestamp", "index", "primaryKey", "pgTable", "text", "numeric", "timestamp", "uuid", "jsonb", "index", "pgTable", "text", "timestamp", "uuid", "jsonb", "boolean", "uniqueIndex", "pgTable", "text", "numeric", "timestamp", "uuid", "primaryKey", "index", "pgTable", "text", "timestamp", "uuid", "jsonb", "index", "real"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/agent-loop.ts"],
|
|
4
|
-
"sourcesContent": ["// Phase 4b thin-agent migration: the parallel-run worker loop that replaces\n// graphile-worker's LISTEN/NOTIFY pickup with HTTP long-polling against the\n// Phase 4a /api/work endpoints. See docs/plans/2026-05-25-thin-agent-migration.md.\n//\n// This file is invoked exclusively by `rulemetric evals agent` \u2014 the only\n// worker mode since Phase 4c deleted the graphile path.\n//\n// Lifecycle for one cycle:\n// 1. Long-poll GET /api/work/next?capabilities=...&waitMs=...\n// 2. If 204 (returned as \"\" by api-client because no JSON body), increment\n// a small backoff capped at 5s and re-poll.\n// 3. If 200, dispatch by `kind` to the matching handler from HANDLERS.\n// 4. Start a heartbeat timer that POSTs /api/work/:id/heartbeat at\n// heartbeatIntervalMs while the handler runs.\n// 5. On success: POST /api/work/:id/complete with { result, leaseToken }.\n// On PermanentJobError: POST /fail with terminal=true (server will not\n// requeue regardless of attempts). On any other error: POST /fail with\n// terminal=false (server requeues if attempts < max).\n//\n// Abort behavior: an AbortSignal short-circuits the next long-poll and any\n// backoff sleep. An in-flight handler can't be cancelled (it has already\n// spawned `claude` subprocesses), so we await it to natural completion and\n// then exit. This matches listen.ts's 10s shutdown grace pattern, except we\n// don't need an outer hard-kill timer here \u2014 the caller (the oclif command)\n// owns the process.exit.\n\nimport type { JobHelpers } from './job-helpers.js';\nimport { apiGet, apiPost, ApiError } from './api-client.js';\nimport { isPermanentJobError } from './permanent-job-error.js';\nimport { processEval } from './handlers/process-eval.js';\nimport { processInsights } from './handlers/process-insights.js';\nimport { processLaunch } from './handlers/process-launch.js';\nimport { processConversation } from './handlers/process-conversation.js';\nimport { processSendMessage } from './handlers/process-send-message.js';\nimport { processSessionGoal } from './handlers/process-session-goal.js';\nimport { processAnnouncement } from './handlers/process-announcement.js';\nimport { processRunCleanup } from './handlers/process-run-cleanup.js';\nimport { cronSuggestInstructions } from './handlers/cron-suggest-instructions.js';\nimport { cronRefreshSkills } from './handlers/cron-refresh-skills.js';\nimport { startTerminalTargetHeartbeat } from './terminal-target-heartbeat.js';\n\n// Handler dispatch table. Keys MUST match the API's CAPABILITY_TO_TABLE keys\n// in apps/api/src/routes/work.ts; mismatches would cause the API to silently\n// drop the capability and starve this kind of work.\ntype Handler = (\n payload: Record<string, unknown>,\n helpers: JobHelpers,\n) => Promise<Record<string, unknown> | undefined | void>;\n\nexport const HANDLERS: Record<string, Handler> = {\n process_eval: processEval as unknown as Handler,\n process_insights: processInsights as unknown as Handler,\n process_launch: processLaunch as unknown as Handler,\n process_send_message: processSendMessage as unknown as Handler,\n process_conversation: processConversation as unknown as Handler,\n // agent_jobs kinds (Phase 4c Stage 3b, migration 00083). processSessionGoal\n // and processAnnouncement take an optional deps object in the helpers\n // position \u2014 every key is optional, so JobHelpers passing through is\n // harmless and they fall back to their defaults.\n process_session_goal: processSessionGoal as unknown as Handler,\n process_announcement: processAnnouncement as unknown as Handler,\n // Multi-session orchestration (\"runs\") worktree cleanup (Task 5.2). agent_jobs\n // kind \u2014 no mirror table. Enqueued by POST /api/runs/:id/cleanup; prunes the\n // worktrees of a run's ended sessions, guarding against uncommitted work.\n process_run_cleanup: processRunCleanup as unknown as Handler,\n cron_suggest_instructions: cronSuggestInstructions as unknown as Handler,\n // Dropped by accident in the Phase 4c graphile\u2192agent_jobs migration: the\n // handler survived but lost its registration + schedule, so the skills\n // registry froze (last refresh 2026-05-21) and the suggest cron marked\n // every suggestion stale on each run. Re-scheduled by migration 00086.\n cron_refresh_skills: cronRefreshSkills as unknown as Handler,\n};\n\nexport const CAPABILITIES: readonly string[] = Object.keys(HANDLERS);\n\ninterface NextWorkResponse {\n id: string;\n kind: string;\n payload: Record<string, unknown>;\n attempts: number;\n leaseToken: string;\n leaseDurationSeconds: number;\n table: string;\n}\n\nexport interface RunAgentLoopOptions {\n signal: AbortSignal;\n log?: (msg: string) => void;\n /** Long-poll wait passed to GET /api/work/next?waitMs= */\n pollWaitMs?: number;\n /** How often to POST /api/work/:id/heartbeat while a handler runs */\n heartbeatIntervalMs?: number;\n /** Capability list to advertise. Defaults to all known handlers. */\n capabilities?: readonly string[];\n /** Running CLI version, reported as `clientVersion` in the presence heartbeat\n * so the dashboard can detect an outdated CLI and nudge an upgrade. */\n version?: string;\n}\n\nconst DEFAULT_POLL_WAIT_MS = 30_000;\nconst DEFAULT_HEARTBEAT_MS = 30_000;\nconst PRESENCE_HEARTBEAT_MS = 30_000;\nconst BACKOFF_INITIAL_MS = 250;\nconst BACKOFF_MAX_MS = 5_000;\n\n// Stable per-process identifier so worker_connections groups the same agent\n// across heartbeats (the unique key is (userId, workerType, clientName)).\nconst PRESENCE_CLIENT_NAME = `thin-agent-${process.pid}`;\n\n/**\n * Background presence heartbeat. Posts to /api/workers/heartbeat every 30s so\n * worker_connections has a fresh row \u2014 that's what the dashboard's\n * useWorkerStatus reads to decide \"Worker online\" for live-send gating.\n * Distinct from the per-job heartbeat in runOne, which only extends a\n * specific job's lease. The graphile-worker runner had this since day one;\n * the thin agent was missing it, so the dashboard showed \"Worker offline\"\n * even when the agent was actively processing jobs.\n */\nfunction startPresenceHeartbeat(\n capabilities: readonly string[],\n signal: AbortSignal,\n log: (msg: string) => void,\n version: string | undefined,\n): void {\n const send = (status: 'alive' | 'shutting_down') => {\n void apiPost('/api/workers/heartbeat', {\n workerType: 'cli-worker',\n clientName: PRESENCE_CLIENT_NAME,\n clientVersion: version,\n workerVersion: '0.1.0',\n currentJobId: null,\n inFlightCount: 0,\n lastError: null,\n status,\n metadata: { capabilities, mode: 'thin-agent' },\n }).catch((err) => {\n structuredLog(log, {\n event: 'presence_heartbeat_error',\n error: err instanceof Error ? err.message : String(err),\n });\n });\n };\n send('alive');\n const timer = setInterval(() => send('alive'), PRESENCE_HEARTBEAT_MS);\n signal.addEventListener('abort', () => {\n clearInterval(timer);\n send('shutting_down');\n }, { once: true });\n}\n\nfunction structuredLog(\n log: (msg: string) => void,\n event: Record<string, unknown>,\n): void {\n try {\n log(JSON.stringify({ ts: new Date().toISOString(), ...event }));\n } catch {\n // JSON.stringify can throw on a circular structure; fall back to a\n // best-effort string so a log failure never takes down the loop.\n log(`[agent-loop] log_error event=${event['event']}`);\n }\n}\n\n/** Sleep that resolves early when the abort signal fires. Returns true if\n * the full duration elapsed, false if aborted. */\nfunction abortableSleep(ms: number, signal: AbortSignal): Promise<boolean> {\n if (signal.aborted) return Promise.resolve(false);\n if (ms <= 0) return Promise.resolve(true);\n return new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve(true);\n }, ms);\n const onAbort = () => {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n resolve(false);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\n/** Poll once for work. Returns the parsed response or null on 204. api-client\n * returns \"\" for an empty response body (Content-Type is not JSON on 204), so\n * we use that as the 204 sentinel. */\nexport async function pollForWork(\n capabilities: readonly string[],\n waitMs: number,\n): Promise<NextWorkResponse | null> {\n const qs = `capabilities=${encodeURIComponent(capabilities.join(','))}&waitMs=${waitMs}`;\n const result = await apiGet<NextWorkResponse | string>(`/api/work/next?${qs}`);\n if (result == null || typeof result === 'string') return null;\n return result;\n}\n\n/** Construct a minimal JobHelpers shim. Handlers only touch\n * helpers.logger.{info,warn,error}(msg) and helpers.job.attempts \u2014 verified\n * by grep against apps/cli/src/lib/handlers/. We cast through `unknown` so\n * TS accepts the structurally smaller object as the full JobHelpers type;\n * pulling graphile-worker into this hot path would defeat the Phase 4c\n * cleanup that removes the dep entirely. */\nfunction makeHelpers(attempts: number, log: (msg: string) => void): JobHelpers {\n return {\n logger: {\n info: (msg: string) => log(msg),\n warn: (msg: string) => log(msg),\n error: (msg: string) => log(msg),\n },\n job: { attempts },\n };\n}\n\nasync function runOne(\n job: NextWorkResponse,\n heartbeatIntervalMs: number,\n log: (msg: string) => void,\n): Promise<void> {\n const handler = HANDLERS[job.kind];\n const startedAt = Date.now();\n structuredLog(log, {\n event: 'claim',\n jobId: job.id,\n kind: job.kind,\n attempts: job.attempts,\n });\n\n // Defensive: if the API returned a kind the agent doesn't know about\n // (capability filter mismatch, schema drift), fail terminally so the row\n // doesn't bounce forever. The /api/work/next filter should already prevent\n // this, but failing closed at the dispatcher means a single new kind on\n // the API side can't wedge an older agent.\n if (!handler) {\n const msg = `unknown kind: ${job.kind}`;\n structuredLog(log, {\n event: 'fail',\n jobId: job.id,\n kind: job.kind,\n terminal: true,\n error: msg,\n });\n await apiPost(`/api/work/${job.id}/fail`, {\n leaseToken: job.leaseToken,\n error: msg,\n terminal: true,\n }).catch(() => {\n // best-effort: the lease will expire and the reconciler reclaims it\n });\n return;\n }\n\n // Heartbeat timer. Starts after the first heartbeatIntervalMs elapses so\n // we don't spam an extra request for sub-second jobs. Errors are swallowed\n // \u2014 a single failed heartbeat doesn't abort the run; the server's\n // 5-minute lease gives us up to ten chances at 30s intervals before we\n // lose the claim.\n const heartbeatTimer = setInterval(() => {\n structuredLog(log, { event: 'heartbeat', jobId: job.id });\n apiPost(`/api/work/${job.id}/heartbeat`, {\n leaseToken: job.leaseToken,\n }).catch((err) => {\n structuredLog(log, {\n event: 'heartbeat_error',\n jobId: job.id,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n }, heartbeatIntervalMs);\n\n try {\n const helpers = makeHelpers(job.attempts, log);\n const result = (await handler(job.payload, helpers)) ?? {};\n clearInterval(heartbeatTimer);\n structuredLog(log, {\n event: 'complete',\n jobId: job.id,\n kind: job.kind,\n durationMs: Date.now() - startedAt,\n });\n await apiPost(`/api/work/${job.id}/complete`, {\n leaseToken: job.leaseToken,\n result,\n });\n } catch (err) {\n clearInterval(heartbeatTimer);\n const terminal = isPermanentJobError(err);\n const message = err instanceof Error ? err.message : String(err);\n structuredLog(log, {\n event: 'fail',\n jobId: job.id,\n kind: job.kind,\n durationMs: Date.now() - startedAt,\n terminal,\n error: message,\n });\n await apiPost(`/api/work/${job.id}/fail`, {\n leaseToken: job.leaseToken,\n error: message,\n terminal,\n }).catch((postErr) => {\n structuredLog(log, {\n event: 'fail_post_error',\n jobId: job.id,\n error: postErr instanceof Error ? postErr.message : String(postErr),\n });\n });\n }\n}\n\nexport async function runAgentLoop(opts: RunAgentLoopOptions): Promise<void> {\n const log = opts.log ?? (() => undefined);\n const pollWaitMs = opts.pollWaitMs ?? DEFAULT_POLL_WAIT_MS;\n const heartbeatIntervalMs = opts.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_MS;\n const capabilities = opts.capabilities ?? CAPABILITIES;\n\n let backoffMs = BACKOFF_INITIAL_MS;\n structuredLog(log, {\n event: 'agent_start',\n capabilities,\n pollWaitMs,\n heartbeatIntervalMs,\n });\n\n // Background presence heartbeat \u2014 writes to worker_connections so the\n // dashboard's \"Worker online\" indicator turns on. Fire-and-forget; failures\n // are logged but don't block the work poll.\n startPresenceHeartbeat(capabilities, opts.signal, log, opts.version);\n\n // Fire-and-forget the terminal-target liveness heartbeat. It runs on its\n // own interval (default 60s) and shuts down on the same abort signal.\n // Errors are caught internally \u2014 we don't await it so a slow tmux probe\n // can't delay the work poll.\n void startTerminalTargetHeartbeat({ signal: opts.signal, log }).catch((err) => {\n structuredLog(log, {\n event: 'tt_heartbeat_fatal',\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n while (!opts.signal.aborted) {\n let job: NextWorkResponse | null = null;\n try {\n job = await pollForWork(capabilities, pollWaitMs);\n } catch (err) {\n // Network/API errors during poll: log + backoff. The API may be\n // restarting, the laptop may have just woken, etc. Don't crash the\n // loop \u2014 that's the whole point of this migration.\n const status = err instanceof ApiError ? err.statusCode : undefined;\n structuredLog(log, {\n event: 'poll_error',\n status,\n error: err instanceof Error ? err.message : String(err),\n });\n const completed = await abortableSleep(backoffMs, opts.signal);\n if (!completed) break;\n backoffMs = Math.min(backoffMs * 2, BACKOFF_MAX_MS);\n continue;\n }\n\n if (!job) {\n structuredLog(log, { event: 'poll_204' });\n const completed = await abortableSleep(backoffMs, opts.signal);\n if (!completed) break;\n backoffMs = Math.min(backoffMs * 2, BACKOFF_MAX_MS);\n continue;\n }\n\n // Got work \u2014 reset the backoff and run it. An in-flight handler is\n // intentionally not abort-cancellable; we await its natural completion\n // even if the signal fires mid-run.\n backoffMs = BACKOFF_INITIAL_MS;\n await runOne(job, heartbeatIntervalMs, log);\n }\n\n structuredLog(log, { event: 'agent_stop' });\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/gateway-lifecycle.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Gateway process lifecycle helpers \u2014 spawn, stop, check status.\n * Used by hooks install/uninstall, session-start hook, and proxy status.\n */\nimport { spawn } from 'node:child_process';\nimport { createConnection } from 'node:net';\nimport { existsSync, mkdirSync, openSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n// `import.meta.dirname` only exists on Node >= 20.11 \u2014 on Node 18.x/\u226420.10 it is\n// `undefined`, and `resolve(undefined, \u2026)` throws, surfacing as a spurious\n// \"Could not find gateway-entry.js\" on fresh npm installs (the launchd gateway\n// masks it in dev). Derive the dir portably instead. See onboarding field report\n// 2026-07-07 F1.\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nexport const GATEWAY_PID_FILE = join(CONFIG_DIR, 'gateway.pid');\nexport const GATEWAY_LOG_FILE = join(CONFIG_DIR, 'gateway.log');\nexport const GATEWAY_PORT = 8787;\nexport const MITMPROXY_PORT = 8788;\n\n/**\n * TCP liveness probe: does something actually ACCEPT a connection on the port?\n * Distinct from isGatewayRunning() (which only checks the PID is alive) \u2014 a\n * process can be \"running\" per its pidfile while :8787 accepts nothing. This is\n * the check that must gate writing HTTPS_PROXY: never pin Claude Code's proxy\n * at a port with nothing behind it (the fresh-laptop ConnectionRefused footgun).\n */\nexport function isGatewayListening(port: number = GATEWAY_PORT, timeoutMs = 1500): Promise<boolean> {\n return new Promise((resolveProbe) => {\n const socket = createConnection({ host: '127.0.0.1', port });\n const finish = (result: boolean) => {\n socket.destroy();\n resolveProbe(result);\n };\n socket.setTimeout(timeoutMs);\n socket.once('connect', () => finish(true));\n socket.once('timeout', () => finish(false));\n socket.once('error', () => finish(false));\n });\n}\n\n/**\n * Poll isGatewayListening() until it's true or the window elapses. spawnGateway()\n * returns as soon as it writes the PID file \u2014 the detached child hasn't bound\n * :8787 yet (Node bootstrap + module load). A one-shot probe microseconds later\n * fails-closed on every fresh install, so the proxy/deep-capture layer silently\n * never turns on. This tolerates a normal cold-start bind delay.\n */\nexport async function waitForGatewayListening(\n port: number = GATEWAY_PORT,\n { timeoutMs = 3000, intervalMs = 150 }: { timeoutMs?: number; intervalMs?: number } = {},\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n if (await isGatewayListening(port, Math.min(1500, timeoutMs))) return true;\n if (Date.now() >= deadline) return false;\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n}\n\nexport function isGatewayRunning(): boolean {\n if (!existsSync(GATEWAY_PID_FILE)) return false;\n\n const content = readFileSync(GATEWAY_PID_FILE, 'utf-8').trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid)) return false;\n\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getGatewayPid(): number | null {\n if (!existsSync(GATEWAY_PID_FILE)) return null;\n const content = readFileSync(GATEWAY_PID_FILE, 'utf-8').trim();\n const pid = parseInt(content, 10);\n return isNaN(pid) ? null : pid;\n}\n\nfunction findGatewayEntry(): string {\n // Resolve the compiled gateway-entry.js across BOTH layouts:\n // - unbundled (dev/tsx, or tsc output): this module sits in dist/lib, so\n // gateway-entry.js is a sibling (`./gateway-entry.js`).\n // - BUNDLED (published build): esbuild flattens this module into\n // dist/chunk-*.js at the dist ROOT, so MODULE_DIR is dist/ and the entry\n // (kept as a separate build entry) is at dist/lib/gateway-entry.js\n // (`./lib/gateway-entry.js`). Without this candidate the gateway never\n // spawns on a clean npm install \u2014 masked in dev by the launchd gateway\n // short-circuiting before this runs. See onboarding field report F1.\n const candidates = [\n resolve(MODULE_DIR, './gateway-entry.js'), // sibling (unbundled)\n resolve(MODULE_DIR, './lib/gateway-entry.js'), // bundled chunk at dist root\n resolve(MODULE_DIR, '../lib/gateway-entry.js'), // nested command dir \u2192 dist/lib\n resolve(MODULE_DIR, '../../lib/gateway-entry.js'),\n ];\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n throw new Error(\n 'Could not find gateway-entry.js. Is the CLI built?\\n' +\n 'Searched:\\n' + candidates.map(c => ` ${c}`).join('\\n'),\n );\n}\n\nexport function spawnGateway(cliVersion?: string): number {\n if (isGatewayRunning()) {\n const pid = getGatewayPid();\n if (pid) return pid;\n }\n\n mkdirSync(CONFIG_DIR, { recursive: true });\n\n const entryPath = findGatewayEntry();\n const logFd = openSync(GATEWAY_LOG_FILE, 'a');\n\n const child = spawn(process.execPath, [entryPath], {\n detached: true,\n stdio: ['ignore', logFd, logFd],\n // The gateway inherits the spawning CLI's env. RULEMETRIC_CLI_VERSION\n // identifies the CLI version that started this gateway \u2014 used to\n // detect drift when a newer CLI starts mitmproxy with a different\n // version. RULEMETRIC_CLI_ENTRY is the path to the oclif entry point\n // (process.argv[1]) so the gateway can re-invoke the CLI for\n // `proxy restart` without needing the binary in PATH. Falls back to\n // \"unknown\" if the caller didn't pass them.\n env: {\n ...process.env,\n RULEMETRIC_CLI_VERSION: cliVersion ?? 'unknown',\n RULEMETRIC_CLI_ENTRY: process.argv[1] ?? '',\n },\n });\n\n child.unref();\n\n if (!child.pid) {\n throw new Error('Failed to spawn gateway process');\n }\n\n writeFileSync(GATEWAY_PID_FILE, String(child.pid));\n return child.pid;\n}\n\nexport function stopGateway(): boolean {\n const pid = getGatewayPid();\n if (pid === null) return false;\n\n try {\n process.kill(pid, 'SIGTERM');\n } catch {\n // Process already gone\n }\n\n try { unlinkSync(GATEWAY_PID_FILE); } catch { /* already gone */ }\n return true;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["resolve"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/gateway.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Resilient HTTP proxy gateway that always accepts connections on GATEWAY_PORT.\n * Routes through mitmproxy when it's alive, direct to upstream when it's not.\n */\nimport { spawn } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as http from 'node:http';\nimport * as net from 'node:net';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nexport const GATEWAY_PORT = 8787;\nexport const MITMPROXY_PORT = 8788;\nconst HEALTH_INTERVAL = 3000;\nconst HEALTH_TIMEOUT = 500;\n// Floor on auto-restarts so a misconfigured drift can't trigger a restart\n// loop. Plenty long for the user to fix any underlying problem manually.\nconst RESTART_COOLDOWN_MS = 60_000;\nconst VERSION_FILE = path.join(os.homedir(), '.config', 'rulemetric', 'proxy-addon.version');\n\nlet isProxyAlive = false;\nlet lastState: boolean | null = null;\n// Drift state \u2014 tracked across health-check ticks. lastSeenAddonVersion is\n// what the file said last time we read it; lastRestartAt prevents loops.\nlet lastSeenAddonVersion: string | null = null;\nlet lastRestartAt = 0;\n\nfunction log(msg: string): void {\n const ts = new Date().toISOString();\n console.log(`[${ts}] ${msg}`);\n}\n\nfunction readAddonVersion(): string | null {\n try {\n return fs.readFileSync(VERSION_FILE, 'utf-8').trim() || null;\n } catch {\n // File may not exist yet (proxy not started, or older addon that doesn't\n // write the file). Returning null disables drift checks for this tick.\n return null;\n }\n}\n\nfunction maybeRestartOnDrift(gatewayCliVersion: string, cliEntry: string | null): void {\n // No reference version means we can't compare \u2014 skip.\n if (gatewayCliVersion === 'unknown' || !cliEntry) return;\n const addonVersion = readAddonVersion();\n if (!addonVersion || addonVersion === 'unknown') return;\n // Same as last tick \u2014 nothing changed, no need to log or act.\n if (addonVersion === lastSeenAddonVersion) return;\n lastSeenAddonVersion = addonVersion;\n\n if (addonVersion === gatewayCliVersion) {\n // Drift cleared (e.g. proxy was just restarted). Quiet log, no action.\n log(`addon version matches gateway (${gatewayCliVersion})`);\n return;\n }\n\n const sinceLast = Date.now() - lastRestartAt;\n if (sinceLast < RESTART_COOLDOWN_MS) {\n log(\n `addon version drift (gateway=${gatewayCliVersion}, addon=${addonVersion}); ` +\n `restart cooldown active (${Math.round((RESTART_COOLDOWN_MS - sinceLast) / 1000)}s left)`,\n );\n return;\n }\n\n log(\n `addon version drift detected (gateway=${gatewayCliVersion}, addon=${addonVersion}). ` +\n `Restarting proxy to pick up latest code.`,\n );\n lastRestartAt = Date.now();\n // Detached spawn \u2014 we don't want the gateway to block on the restart\n // completing. Output goes to /dev/null; the proxy.log captures the\n // restart events from mitmproxy itself.\n try {\n const child = spawn(process.execPath, [cliEntry, 'proxy', 'restart'], {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n } catch (err) {\n log(`restart spawn failed: ${(err as Error).message}`);\n }\n}\n\nfunction checkProxyHealth(mitmproxyPort: number): void {\n const sock = net.connect({ port: mitmproxyPort, timeout: HEALTH_TIMEOUT });\n sock.on('connect', () => {\n sock.destroy();\n if (!isProxyAlive) {\n isProxyAlive = true;\n log(`mitmproxy up on :${mitmproxyPort}, routing through proxy`);\n }\n });\n sock.on('error', () => {\n if (isProxyAlive) {\n isProxyAlive = false;\n log(`mitmproxy down on :${mitmproxyPort}, routing direct`);\n }\n });\n sock.on('timeout', () => {\n sock.destroy();\n if (isProxyAlive) {\n isProxyAlive = false;\n log(`mitmproxy timeout on :${mitmproxyPort}, routing direct`);\n }\n });\n}\n\nfunction handleConnect(\n req: http.IncomingMessage,\n clientSocket: net.Socket,\n head: Buffer,\n mitmproxyPort: number,\n): void {\n const [targetHost, targetPortStr] = (req.url ?? '').split(':');\n const targetPort = parseInt(targetPortStr, 10) || 443;\n\n if (isProxyAlive) {\n // Forward CONNECT to mitmproxy\n const proxySocket = net.connect({ port: mitmproxyPort, host: '127.0.0.1' });\n\n proxySocket.on('connect', () => {\n // Send the CONNECT request to mitmproxy\n proxySocket.write(\n `CONNECT ${req.url} HTTP/1.1\\r\\nHost: ${req.url}\\r\\n\\r\\n`,\n );\n });\n\n // Wait for mitmproxy's 200 response before piping\n let responseBuffer = Buffer.alloc(0);\n const onData = (chunk: Buffer) => {\n responseBuffer = Buffer.concat([responseBuffer, chunk]);\n const responseStr = responseBuffer.toString();\n if (responseStr.includes('\\r\\n\\r\\n')) {\n proxySocket.removeListener('data', onData);\n // Forward the 200 to client\n clientSocket.write('HTTP/1.1 200 Connection Established\\r\\n\\r\\n');\n // Pipe remaining data and head\n if (head.length > 0) proxySocket.write(head);\n clientSocket.pipe(proxySocket);\n proxySocket.pipe(clientSocket);\n }\n };\n proxySocket.on('data', onData);\n\n proxySocket.on('error', (err) => {\n log(`proxy socket error for ${req.url}: ${err.message}, falling back to direct`);\n // Mitmproxy failed mid-connect, fall back to direct\n connectDirect(req, clientSocket, head, targetHost, targetPort);\n });\n\n clientSocket.on('error', () => {\n proxySocket.destroy();\n });\n } else {\n connectDirect(req, clientSocket, head, targetHost, targetPort);\n }\n}\n\nfunction connectDirect(\n req: http.IncomingMessage,\n clientSocket: net.Socket,\n head: Buffer,\n targetHost: string,\n targetPort: number,\n): void {\n const upstream = net.connect({ port: targetPort, host: targetHost });\n\n upstream.on('connect', () => {\n clientSocket.write('HTTP/1.1 200 Connection Established\\r\\n\\r\\n');\n if (head.length > 0) upstream.write(head);\n clientSocket.pipe(upstream);\n upstream.pipe(clientSocket);\n });\n\n upstream.on('error', (err) => {\n log(`upstream error for ${req.url}: ${err.message}`);\n clientSocket.end('HTTP/1.1 502 Bad Gateway\\r\\n\\r\\n');\n });\n\n clientSocket.on('error', () => {\n upstream.destroy();\n });\n}\n\nfunction handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n mitmproxyPort: number,\n): void {\n // Plain HTTP proxy (non-CONNECT)\n const targetUrl = req.url ?? '';\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(targetUrl);\n } catch {\n res.writeHead(400);\n res.end('Bad Request');\n return;\n }\n\n const options: http.RequestOptions = {\n hostname: isProxyAlive ? '127.0.0.1' : parsedUrl.hostname,\n port: isProxyAlive ? mitmproxyPort : (parseInt(parsedUrl.port, 10) || 80),\n path: isProxyAlive ? targetUrl : parsedUrl.pathname + parsedUrl.search,\n method: req.method,\n headers: req.headers,\n };\n\n const proxyReq = http.request(options, (proxyRes) => {\n res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);\n proxyRes.pipe(res);\n });\n\n proxyReq.on('error', (err) => {\n log(`HTTP proxy error for ${targetUrl}: ${err.message}`);\n res.writeHead(502);\n res.end('Bad Gateway');\n });\n\n req.pipe(proxyReq);\n}\n\nexport function startGateway(\n port: number = GATEWAY_PORT,\n mitmproxyPort: number = MITMPROXY_PORT,\n options: { cliVersion?: string; cliEntry?: string } = {},\n): { server: http.Server; healthInterval: NodeJS.Timeout } {\n const cliVersion = options.cliVersion ?? process.env.RULEMETRIC_CLI_VERSION ?? 'unknown';\n const cliEntry = options.cliEntry ?? process.env.RULEMETRIC_CLI_ENTRY ?? null;\n const server = http.createServer((req, res) => {\n handleRequest(req, res, mitmproxyPort);\n });\n\n server.on('connect', (req, clientSocket, head) => {\n handleConnect(req, clientSocket as net.Socket, head as Buffer, mitmproxyPort);\n });\n\n // Don't crash on client socket errors\n server.on('clientError', (_err, socket) => {\n if (socket.writable) {\n socket.end('HTTP/1.1 400 Bad Request\\r\\n\\r\\n');\n }\n });\n\n const healthInterval = setInterval(() => {\n checkProxyHealth(mitmproxyPort);\n maybeRestartOnDrift(cliVersion, cliEntry);\n }, HEALTH_INTERVAL);\n\n // Do an immediate check\n checkProxyHealth(mitmproxyPort);\n maybeRestartOnDrift(cliVersion, cliEntry);\n\n server.listen(port, '127.0.0.1', () => {\n log(\n `gateway listening on 127.0.0.1:${port} (mitmproxy target: :${mitmproxyPort}, ` +\n `cli version: ${cliVersion})`,\n );\n });\n\n return { server, healthInterval };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/base-command.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command, Flags } from '@oclif/core';\nimport { isAuthenticated } from './lib/auth.js';\nimport { ApiError } from './lib/api-client.js';\nimport { maybeRefreshActiveOrg } from './lib/active-org-refresh.js';\nimport { getUpgradeBanner, refreshVersionCacheInBackground } from './lib/version-check.js';\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n 'api-url': Flags.string({\n description: 'Override API base URL',\n env: 'RULEMETRIC_API_URL',\n hidden: true,\n }),\n };\n\n protected override async init(): Promise<void> {\n await super.init();\n const { flags } = await this.parse(this.constructor as typeof BaseCommand);\n if (flags['api-url']) {\n process.env.RULEMETRIC_API_URL = flags['api-url'];\n }\n // Print the upgrade banner from the cache (populated by the previous\n // command). To stderr so it doesn't pollute scriptable stdout. Then\n // kick off a background refresh for the *next* invocation. Suppressed\n // on commands meant to be machine-readable (`hooks run`, etc.) since\n // a banner there would corrupt JSON output piped to other tools.\n const banner = getUpgradeBanner(this.config.version);\n if (banner && !this.argv.includes('--quiet') && !process.env.RULEMETRIC_QUIET) {\n process.stderr.write(`\\n${banner}\\n\\n`);\n }\n refreshVersionCacheInBackground();\n }\n\n protected requireAuth(): void {\n if (!isAuthenticated()) {\n this.error('Not logged in. Run `rulemetric auth login` to authenticate.');\n }\n // Fire-and-forget refresh of the local active-org cache. Doesn't block\n // the command \u2014 its only side effect is rewriting the cache file.\n void maybeRefreshActiveOrg();\n }\n\n protected override async catch(err: Error & { exitCode?: number }): Promise<void> {\n if (err instanceof ApiError) {\n if (err.statusCode === 401) {\n this.error('Session expired. Run `rulemetric auth login` to re-authenticate.');\n }\n\n this.error(err.message);\n }\n\n if (err.message?.includes('fetch failed') || err.message?.includes('ECONNREFUSED')) {\n this.error('Could not connect to the API server. Is it running?');\n }\n\n throw err;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;AAAA,SAAS,SAAS,aAAa;AAMxB,IAAe,cAAf,cAAmC,QAAQ;AAAA,EAChD,OAAgB,YAAY;AAAA,IAC1B,WAAW,MAAM,OAAO;AAAA,MACtB,aAAa;AAAA,MACb,KAAK;AAAA,MACL,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAyB,OAAsB;AAC7C,UAAM,MAAM,KAAK;AACjB,UAAM,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,KAAK,WAAiC;AACzE,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,IAAI,qBAAqB,MAAM,SAAS;AAAA,IAClD;AAMA,UAAM,SAAS,iBAAiB,KAAK,OAAO,OAAO;AACnD,QAAI,UAAU,CAAC,KAAK,KAAK,SAAS,SAAS,KAAK,CAAC,QAAQ,IAAI,kBAAkB;AAC7E,cAAQ,OAAO,MAAM;AAAA,EAAK,MAAM;AAAA;AAAA,CAAM;AAAA,IACxC;AACA,oCAAgC;AAAA,EAClC;AAAA,EAEU,cAAoB;AAC5B,QAAI,CAAC,gBAAgB,GAAG;AACtB,WAAK,MAAM,6DAA6D;AAAA,IAC1E;AAGA,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEA,MAAyB,MAAM,KAAmD;AAChF,QAAI,eAAe,UAAU;AAC3B,UAAI,IAAI,eAAe,KAAK;AAC1B,aAAK,MAAM,kEAAkE;AAAA,MAC/E;AAEA,WAAK,MAAM,IAAI,OAAO;AAAA,IACxB;AAEA,QAAI,IAAI,SAAS,SAAS,cAAc,KAAK,IAAI,SAAS,SAAS,cAAc,GAAG;AAClF,WAAK,MAAM,qDAAqD;AAAA,IAClE;AAEA,UAAM;AAAA,EACR;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|