codekin 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/assets/index-C8GlUCii.js +182 -0
  2. package/dist/assets/index-DgeUVGjz.css +1 -0
  3. package/dist/index.html +2 -2
  4. package/package.json +1 -1
  5. package/server/dist/approval-manager.d.ts +7 -2
  6. package/server/dist/approval-manager.js +11 -3
  7. package/server/dist/approval-manager.js.map +1 -1
  8. package/server/dist/claude-process.js +11 -5
  9. package/server/dist/claude-process.js.map +1 -1
  10. package/server/dist/session-lifecycle.d.ts +1 -1
  11. package/server/dist/session-lifecycle.js +28 -11
  12. package/server/dist/session-lifecycle.js.map +1 -1
  13. package/server/dist/session-manager.d.ts +1 -1
  14. package/server/dist/session-manager.js +69 -58
  15. package/server/dist/session-manager.js.map +1 -1
  16. package/server/dist/session-naming.js +25 -2
  17. package/server/dist/session-naming.js.map +1 -1
  18. package/server/dist/session-persistence.js +1 -0
  19. package/server/dist/session-persistence.js.map +1 -1
  20. package/server/dist/session-restart-scheduler.d.ts +3 -0
  21. package/server/dist/session-restart-scheduler.js +13 -3
  22. package/server/dist/session-restart-scheduler.js.map +1 -1
  23. package/server/dist/tsconfig.tsbuildinfo +1 -1
  24. package/server/dist/types.d.ts +6 -1
  25. package/server/dist/types.js +0 -1
  26. package/server/dist/types.js.map +1 -1
  27. package/server/dist/upload-routes.js +8 -0
  28. package/server/dist/upload-routes.js.map +1 -1
  29. package/server/dist/webhook-config.d.ts +9 -0
  30. package/server/dist/webhook-config.js +41 -3
  31. package/server/dist/webhook-config.js.map +1 -1
  32. package/server/dist/webhook-github-setup.d.ts +48 -0
  33. package/server/dist/webhook-github-setup.js +172 -0
  34. package/server/dist/webhook-github-setup.js.map +1 -0
  35. package/server/dist/webhook-setup-routes.d.ts +14 -0
  36. package/server/dist/webhook-setup-routes.js +233 -0
  37. package/server/dist/webhook-setup-routes.js.map +1 -0
  38. package/server/dist/webhook-types.d.ts +65 -0
  39. package/server/dist/workflow-routes.js +1 -0
  40. package/server/dist/workflow-routes.js.map +1 -1
  41. package/server/dist/ws-server.js +2 -0
  42. package/server/dist/ws-server.js.map +1 -1
  43. package/dist/assets/index-BNU7FIQx.css +0 -1
  44. package/dist/assets/index-k7mgzd5O.js +0 -182
@@ -1,6 +1,7 @@
1
- import { existsSync, readFileSync } from 'fs';
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from 'fs';
2
2
  import { homedir } from 'os';
3
- import { join } from 'path';
3
+ import { join, dirname } from 'path';
4
+ import { randomBytes } from 'crypto';
4
5
  const CONFIG_FILE = join(homedir(), '.codekin', 'webhook-config.json');
5
6
  /**
6
7
  * Load webhook configuration from environment variables and optional config file.
@@ -12,6 +13,7 @@ export function loadWebhookConfig() {
12
13
  let maxConcurrentSessions = 3;
13
14
  let logLinesToInclude = 200;
14
15
  let actorAllowlist = [];
16
+ let secret = '';
15
17
  // Try loading config file
16
18
  if (existsSync(CONFIG_FILE)) {
17
19
  try {
@@ -26,6 +28,8 @@ export function loadWebhookConfig() {
26
28
  if (Array.isArray(file.actorAllowlist) && file.actorAllowlist.every(v => typeof v === 'string')) {
27
29
  actorAllowlist = file.actorAllowlist;
28
30
  }
31
+ if (typeof file.secret === 'string')
32
+ secret = file.secret;
29
33
  }
30
34
  catch (err) {
31
35
  console.warn('[webhook] Failed to parse config file:', err);
@@ -52,7 +56,10 @@ export function loadWebhookConfig() {
52
56
  if (envActorAllowlist !== undefined) {
53
57
  actorAllowlist = envActorAllowlist.split(',').map(s => s.trim()).filter(Boolean);
54
58
  }
55
- const secret = process.env.GITHUB_WEBHOOK_SECRET || '';
59
+ const envSecret = process.env.GITHUB_WEBHOOK_SECRET;
60
+ if (envSecret !== undefined) {
61
+ secret = envSecret;
62
+ }
56
63
  return {
57
64
  enabled,
58
65
  secret,
@@ -61,4 +68,35 @@ export function loadWebhookConfig() {
61
68
  actorAllowlist,
62
69
  };
63
70
  }
71
+ // ---------------------------------------------------------------------------
72
+ // Config persistence for auto-setup
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Generate a cryptographically random webhook secret.
76
+ */
77
+ export function generateWebhookSecret() {
78
+ return randomBytes(32).toString('hex');
79
+ }
80
+ /**
81
+ * Persist webhook config updates to the config file (atomic read-merge-write).
82
+ * Only writes fields that are explicitly provided; preserves existing values.
83
+ */
84
+ export function saveWebhookConfig(updates) {
85
+ let existing = {};
86
+ if (existsSync(CONFIG_FILE)) {
87
+ try {
88
+ existing = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
89
+ }
90
+ catch {
91
+ // Start fresh if file is corrupt
92
+ }
93
+ }
94
+ const merged = { ...existing, ...updates };
95
+ // Ensure directory exists
96
+ mkdirSync(dirname(CONFIG_FILE), { recursive: true });
97
+ // Atomic write: write to tmp file then rename
98
+ const tmpFile = CONFIG_FILE + '.tmp';
99
+ writeFileSync(tmpFile, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
100
+ renameSync(tmpFile, CONFIG_FILE);
101
+ }
64
102
  //# sourceMappingURL=webhook-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-config.js","sourceRoot":"","sources":["../webhook-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAA;AAMtE;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,WAAW;IACX,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,qBAAqB,GAAG,CAAC,CAAA;IAC7B,IAAI,iBAAiB,GAAG,GAAG,CAAA;IAC3B,IAAI,cAAc,GAAa,EAAE,CAAA;IAEjC,0BAA0B;IAC1B,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA2B,CAAA;YACtD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS;gBAAE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;YAC7D,IAAI,OAAO,IAAI,CAAC,qBAAqB,KAAK,QAAQ;gBAAE,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAA;YACtG,IAAI,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ;gBAAE,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAA;YAC1F,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAChG,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAA;IACrD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,GAAG,CAAA;IACvD,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAA;IAC9D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;QACtC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,qBAAqB,GAAG,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAA;IACxD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACnC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,iBAAiB,GAAG,CAAC,CAAA;IAC/C,CAAC;IAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;IACpE,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,cAAc,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAA;IAEtD,OAAO;QACL,OAAO;QACP,MAAM;QACN,qBAAqB;QACrB,iBAAiB;QACjB,cAAc;KACf,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"webhook-config.js","sourceRoot":"","sources":["../webhook-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * GitHub API helpers for webhook discovery and management.
3
+ *
4
+ * Used by the integration health-check and setup-wizard endpoints.
5
+ * Follows the same patterns as webhook-github.ts: injectable ghRunner,
6
+ * graceful degradation, console warnings on failure.
7
+ */
8
+ import type { GitHubWebhook, GitHubDelivery, SetupPreview } from './webhook-types.js';
9
+ type GhRunner = (args: string[]) => Promise<string>;
10
+ /** @internal Test-only: override the gh CLI runner */
11
+ export declare function _setGhRunner(runner: GhRunner): void;
12
+ /** @internal Test-only: reset to default gh CLI runner */
13
+ export declare function _resetGhRunner(): void;
14
+ /**
15
+ * List all webhooks configured on a GitHub repository.
16
+ * Requires admin access to the repo.
17
+ */
18
+ export declare function listRepoWebhooks(repo: string): Promise<GitHubWebhook[]>;
19
+ /**
20
+ * Find the Codekin webhook on a repo by matching the configured URL.
21
+ */
22
+ export declare function findCodekinWebhook(repo: string, webhookUrl: string): Promise<GitHubWebhook | null>;
23
+ /**
24
+ * Fetch recent webhook deliveries for a specific hook.
25
+ */
26
+ export declare function getWebhookDeliveries(repo: string, hookId: number, count?: number): Promise<GitHubDelivery[]>;
27
+ /**
28
+ * Create a new webhook on a GitHub repository.
29
+ */
30
+ export declare function createRepoWebhook(repo: string, url: string, secret: string, events: string[]): Promise<GitHubWebhook>;
31
+ /**
32
+ * Update an existing webhook on a GitHub repository.
33
+ */
34
+ export declare function updateRepoWebhook(repo: string, hookId: number, updates: {
35
+ url?: string;
36
+ events?: string[];
37
+ active?: boolean;
38
+ secret?: string;
39
+ }): Promise<GitHubWebhook>;
40
+ /**
41
+ * Send a ping event to a webhook.
42
+ */
43
+ export declare function pingWebhook(repo: string, hookId: number): Promise<boolean>;
44
+ /**
45
+ * Preview what a webhook setup would do (create vs update vs nothing).
46
+ */
47
+ export declare function previewWebhookSetup(repo: string, webhookUrl: string): Promise<SetupPreview>;
48
+ export {};
@@ -0,0 +1,172 @@
1
+ /**
2
+ * GitHub API helpers for webhook discovery and management.
3
+ *
4
+ * Used by the integration health-check and setup-wizard endpoints.
5
+ * Follows the same patterns as webhook-github.ts: injectable ghRunner,
6
+ * graceful degradation, console warnings on failure.
7
+ */
8
+ import { execFile } from 'child_process';
9
+ import { promisify } from 'util';
10
+ const execFileAsync = promisify(execFile);
11
+ const GH_TIMEOUT_MS = 30_000;
12
+ let ghRunner = async (args) => {
13
+ const { stdout } = await execFileAsync('gh', args, { timeout: GH_TIMEOUT_MS });
14
+ return stdout;
15
+ };
16
+ /** @internal Test-only: override the gh CLI runner */
17
+ export function _setGhRunner(runner) {
18
+ ghRunner = runner;
19
+ }
20
+ /** @internal Test-only: reset to default gh CLI runner */
21
+ export function _resetGhRunner() {
22
+ ghRunner = async (args) => {
23
+ const { stdout } = await execFileAsync('gh', args, { timeout: GH_TIMEOUT_MS });
24
+ return stdout;
25
+ };
26
+ }
27
+ // ---------------------------------------------------------------------------
28
+ // Phase 1: Discovery
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * List all webhooks configured on a GitHub repository.
32
+ * Requires admin access to the repo.
33
+ */
34
+ export async function listRepoWebhooks(repo) {
35
+ try {
36
+ const raw = await ghRunner(['api', `/repos/${repo}/hooks`, '--paginate']);
37
+ const hooks = JSON.parse(raw);
38
+ return Array.isArray(hooks) ? hooks : [];
39
+ }
40
+ catch (err) {
41
+ console.warn(`listRepoWebhooks: failed for ${repo}:`, err);
42
+ return [];
43
+ }
44
+ }
45
+ /**
46
+ * Find the Codekin webhook on a repo by matching the configured URL.
47
+ */
48
+ export async function findCodekinWebhook(repo, webhookUrl) {
49
+ const hooks = await listRepoWebhooks(repo);
50
+ return hooks.find(h => h.config.url === webhookUrl) ?? null;
51
+ }
52
+ /**
53
+ * Fetch recent webhook deliveries for a specific hook.
54
+ */
55
+ export async function getWebhookDeliveries(repo, hookId, count = 5) {
56
+ try {
57
+ const raw = await ghRunner([
58
+ 'api',
59
+ `/repos/${repo}/hooks/${hookId}/deliveries?per_page=${count}`,
60
+ ]);
61
+ const deliveries = JSON.parse(raw);
62
+ return Array.isArray(deliveries) ? deliveries : [];
63
+ }
64
+ catch (err) {
65
+ console.warn(`getWebhookDeliveries: failed for ${repo} hook ${hookId}:`, err);
66
+ return [];
67
+ }
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Phase 2: Setup & Management
71
+ // ---------------------------------------------------------------------------
72
+ /**
73
+ * Create a new webhook on a GitHub repository.
74
+ */
75
+ export async function createRepoWebhook(repo, url, secret, events) {
76
+ const body = JSON.stringify({
77
+ name: 'web',
78
+ active: true,
79
+ events,
80
+ config: { url, content_type: 'json', secret, insecure_ssl: '0' },
81
+ });
82
+ const raw = await ghRunnerWithStdin(['api', `/repos/${repo}/hooks`, '--method', 'POST', '--input', '-'], body);
83
+ return JSON.parse(raw);
84
+ }
85
+ /**
86
+ * Update an existing webhook on a GitHub repository.
87
+ */
88
+ export async function updateRepoWebhook(repo, hookId, updates) {
89
+ const body = {};
90
+ if (updates.events)
91
+ body.events = updates.events;
92
+ if (updates.active !== undefined)
93
+ body.active = updates.active;
94
+ const config = {};
95
+ if (updates.url)
96
+ config.url = updates.url;
97
+ if (updates.secret)
98
+ config.secret = updates.secret;
99
+ if (Object.keys(config).length > 0) {
100
+ config.content_type = 'json';
101
+ config.insecure_ssl = '0';
102
+ body.config = config;
103
+ }
104
+ const raw = await ghRunnerWithStdin(['api', `/repos/${repo}/hooks/${hookId}`, '--method', 'PATCH', '--input', '-'], JSON.stringify(body));
105
+ return JSON.parse(raw);
106
+ }
107
+ /**
108
+ * Send a ping event to a webhook.
109
+ */
110
+ export async function pingWebhook(repo, hookId) {
111
+ try {
112
+ await ghRunner([
113
+ 'api', `/repos/${repo}/hooks/${hookId}/pings`,
114
+ '--method', 'POST',
115
+ ]);
116
+ return true;
117
+ }
118
+ catch (err) {
119
+ console.warn(`pingWebhook: failed for ${repo} hook ${hookId}:`, err);
120
+ return false;
121
+ }
122
+ }
123
+ /**
124
+ * Preview what a webhook setup would do (create vs update vs nothing).
125
+ */
126
+ export async function previewWebhookSetup(repo, webhookUrl) {
127
+ const existing = await findCodekinWebhook(repo, webhookUrl);
128
+ const requiredEvents = ['pull_request', 'workflow_run'];
129
+ if (!existing) {
130
+ return {
131
+ action: 'create',
132
+ proposed: { url: webhookUrl, events: requiredEvents, active: true },
133
+ };
134
+ }
135
+ const changes = [];
136
+ if (!existing.active)
137
+ changes.push('Activate webhook (currently inactive)');
138
+ const missingEvents = requiredEvents.filter(e => !existing.events.includes(e));
139
+ if (missingEvents.length > 0) {
140
+ changes.push(`Add missing events: ${missingEvents.join(', ')}`);
141
+ }
142
+ if (changes.length === 0) {
143
+ return { action: 'none', existing, proposed: { url: webhookUrl, events: existing.events, active: true } };
144
+ }
145
+ return {
146
+ action: 'update',
147
+ existing,
148
+ proposed: {
149
+ url: webhookUrl,
150
+ events: [...new Set([...existing.events, ...requiredEvents])],
151
+ active: true,
152
+ },
153
+ changes,
154
+ };
155
+ }
156
+ // ---------------------------------------------------------------------------
157
+ // Internal: gh runner with stdin support (for POST/PATCH bodies)
158
+ // ---------------------------------------------------------------------------
159
+ async function ghRunnerWithStdin(args, stdin) {
160
+ return new Promise((resolve, reject) => {
161
+ const proc = execFile('gh', args, { timeout: GH_TIMEOUT_MS }, (err, stdout) => {
162
+ if (err) {
163
+ reject(err);
164
+ return;
165
+ }
166
+ resolve(stdout);
167
+ });
168
+ proc.stdin?.write(stdin);
169
+ proc.stdin?.end();
170
+ });
171
+ }
172
+ //# sourceMappingURL=webhook-github-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-github-setup.js","sourceRoot":"","sources":["../webhook-github-setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * REST routes for webhook integration health checks and setup.
3
+ *
4
+ * Mounted at the Express app root (routes carry their own /api/ prefixes).
5
+ * Provides health-check, auto-setup, and test-delivery endpoints for the
6
+ * GitHub PR review integration.
7
+ */
8
+ import { Router } from 'express';
9
+ import type { Request } from 'express';
10
+ import type { FullWebhookConfig } from './webhook-config.js';
11
+ type VerifyFn = (token: string | undefined) => boolean;
12
+ type ExtractFn = (req: Request) => string | undefined;
13
+ export declare function createWebhookSetupRouter(verifyToken: VerifyFn, extractToken: ExtractFn, getConfig: () => FullWebhookConfig): Router;
14
+ export {};
@@ -0,0 +1,233 @@
1
+ /**
2
+ * REST routes for webhook integration health checks and setup.
3
+ *
4
+ * Mounted at the Express app root (routes carry their own /api/ prefixes).
5
+ * Provides health-check, auto-setup, and test-delivery endpoints for the
6
+ * GitHub PR review integration.
7
+ */
8
+ import { Router } from 'express';
9
+ import { checkGhHealth } from './webhook-github.js';
10
+ import { findCodekinWebhook, getWebhookDeliveries, createRepoWebhook, updateRepoWebhook, pingWebhook, previewWebhookSetup as previewSetup, } from './webhook-github-setup.js';
11
+ import { generateWebhookSecret, saveWebhookConfig } from './webhook-config.js';
12
+ export function createWebhookSetupRouter(verifyToken, extractToken, getConfig) {
13
+ const router = Router();
14
+ const REPO_PATTERN = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
15
+ // --- Health check endpoint ---
16
+ router.get('/api/integrations/github/pr-review/health', async (req, res) => {
17
+ const token = extractToken(req);
18
+ if (!verifyToken(token))
19
+ return res.status(401).json({ error: 'Unauthorized' });
20
+ const repo = req.query.repo;
21
+ const webhookUrl = req.query.webhookUrl;
22
+ if (!repo || !webhookUrl) {
23
+ return res.status(400).json({ error: 'Missing required query params: repo, webhookUrl' });
24
+ }
25
+ if (!REPO_PATTERN.test(repo)) {
26
+ return res.status(400).json({ error: 'Invalid repo format. Expected owner/repo.' });
27
+ }
28
+ const config = getConfig();
29
+ const result = {
30
+ overall: 'healthy',
31
+ checks: {
32
+ ghCli: { ok: false, message: '' },
33
+ config: { ok: false, message: '' },
34
+ webhook: { ok: false, message: '' },
35
+ deliveries: { ok: false, message: '' },
36
+ },
37
+ };
38
+ // Check 1: Config
39
+ const secretSet = config.secret.length > 0;
40
+ if (!config.enabled) {
41
+ result.checks.config = {
42
+ ok: false,
43
+ message: 'Webhooks are disabled. Set GITHUB_WEBHOOK_ENABLED=true to enable.',
44
+ details: { enabled: false, secretSet },
45
+ };
46
+ result.overall = 'unconfigured';
47
+ // Still run other checks for diagnostic value
48
+ }
49
+ else if (!secretSet) {
50
+ result.checks.config = {
51
+ ok: false,
52
+ message: 'No webhook secret configured. Set GITHUB_WEBHOOK_SECRET to secure the endpoint.',
53
+ details: { enabled: true, secretSet: false },
54
+ };
55
+ result.overall = 'unconfigured';
56
+ }
57
+ else {
58
+ result.checks.config = {
59
+ ok: true,
60
+ message: 'Webhooks enabled with secret configured.',
61
+ details: { enabled: true, secretSet: true },
62
+ };
63
+ }
64
+ // Check 2: gh CLI
65
+ const ghHealth = await checkGhHealth();
66
+ if (!ghHealth.available) {
67
+ result.checks.ghCli = { ok: false, message: ghHealth.reason || 'gh CLI unavailable' };
68
+ result.checks.webhook = { ok: false, message: 'Skipped — gh CLI unavailable' };
69
+ result.checks.deliveries = { ok: false, message: 'Skipped — gh CLI unavailable' };
70
+ if (result.overall !== 'unconfigured')
71
+ result.overall = 'broken';
72
+ return res.json(result);
73
+ }
74
+ result.checks.ghCli = { ok: true, message: 'gh CLI authenticated and connected.' };
75
+ // Check 3: Webhook exists on GitHub
76
+ const hook = await findCodekinWebhook(repo, webhookUrl);
77
+ if (!hook) {
78
+ result.checks.webhook = { ok: false, message: `No webhook found on ${repo} pointing to this server.` };
79
+ result.checks.deliveries = { ok: false, message: 'Skipped — no webhook found' };
80
+ if (result.overall !== 'unconfigured')
81
+ result.overall = 'broken';
82
+ return res.json(result);
83
+ }
84
+ const requiredEvents = ['pull_request', 'workflow_run'];
85
+ const missingEvents = requiredEvents.filter(e => !hook.events.includes(e));
86
+ if (!hook.active) {
87
+ result.checks.webhook = {
88
+ ok: false,
89
+ message: 'Webhook exists but is inactive.',
90
+ details: { id: hook.id, active: false, events: hook.events, url: hook.config.url },
91
+ };
92
+ if (result.overall === 'healthy')
93
+ result.overall = 'degraded';
94
+ }
95
+ else if (missingEvents.length > 0) {
96
+ result.checks.webhook = {
97
+ ok: false,
98
+ message: `Webhook is missing events: ${missingEvents.join(', ')}.`,
99
+ details: { id: hook.id, active: true, events: hook.events, url: hook.config.url },
100
+ };
101
+ if (result.overall === 'healthy')
102
+ result.overall = 'degraded';
103
+ }
104
+ else {
105
+ result.checks.webhook = {
106
+ ok: true,
107
+ message: 'Webhook active with correct events.',
108
+ details: { id: hook.id, active: true, events: hook.events, url: hook.config.url },
109
+ };
110
+ }
111
+ // Check 4: Recent deliveries
112
+ const rawDeliveries = await getWebhookDeliveries(repo, hook.id, 5);
113
+ const deliveries = rawDeliveries.map(d => ({
114
+ id: d.id,
115
+ status: d.status,
116
+ statusCode: d.status_code,
117
+ deliveredAt: d.delivered_at,
118
+ event: d.event,
119
+ }));
120
+ if (deliveries.length === 0) {
121
+ result.checks.deliveries = {
122
+ ok: true,
123
+ message: 'No deliveries yet — webhook was recently created or no matching events have occurred.',
124
+ details: { recent: [] },
125
+ };
126
+ }
127
+ else {
128
+ const failures = deliveries.filter(d => d.statusCode >= 400 || d.status === 'error');
129
+ if (failures.length > 0) {
130
+ result.checks.deliveries = {
131
+ ok: false,
132
+ message: `${failures.length} of ${deliveries.length} recent deliveries failed.`,
133
+ details: { recent: deliveries },
134
+ };
135
+ if (result.overall === 'healthy')
136
+ result.overall = 'degraded';
137
+ }
138
+ else {
139
+ result.checks.deliveries = {
140
+ ok: true,
141
+ message: `All ${deliveries.length} recent deliveries succeeded.`,
142
+ details: { recent: deliveries },
143
+ };
144
+ }
145
+ }
146
+ res.json(result);
147
+ });
148
+ // --- Preview setup endpoint ---
149
+ router.post('/api/integrations/github/pr-review/setup', async (req, res) => {
150
+ const token = extractToken(req);
151
+ if (!verifyToken(token))
152
+ return res.status(401).json({ error: 'Unauthorized' });
153
+ const { repo, webhookUrl, dryRun } = req.body;
154
+ if (!repo || !webhookUrl) {
155
+ return res.status(400).json({ error: 'Missing required fields: repo, webhookUrl' });
156
+ }
157
+ if (!REPO_PATTERN.test(repo)) {
158
+ return res.status(400).json({ error: 'Invalid repo format. Expected owner/repo.' });
159
+ }
160
+ // Preview first
161
+ const preview = await previewSetup(repo, webhookUrl);
162
+ if (dryRun || preview.action === 'none') {
163
+ return res.json({ preview, secretGenerated: false });
164
+ }
165
+ // Ensure server is configured: generate secret if needed, enable if needed
166
+ let config = getConfig();
167
+ let secretGenerated = false;
168
+ const configUpdates = {};
169
+ if (!config.secret) {
170
+ configUpdates.secret = generateWebhookSecret();
171
+ secretGenerated = true;
172
+ }
173
+ if (!config.enabled) {
174
+ configUpdates.enabled = true;
175
+ }
176
+ if (Object.keys(configUpdates).length > 0) {
177
+ saveWebhookConfig(configUpdates);
178
+ config = getConfig();
179
+ }
180
+ try {
181
+ let webhook;
182
+ if (preview.action === 'create') {
183
+ webhook = await createRepoWebhook(repo, webhookUrl, config.secret, preview.proposed.events);
184
+ }
185
+ else {
186
+ // update
187
+ webhook = await updateRepoWebhook(repo, preview.existing.id, {
188
+ events: preview.proposed.events,
189
+ active: true,
190
+ secret: secretGenerated ? config.secret : undefined,
191
+ });
192
+ }
193
+ res.json({ preview, webhook, secretGenerated });
194
+ }
195
+ catch (err) {
196
+ const message = err instanceof Error ? err.message : 'Unknown error';
197
+ console.warn(`[webhook-setup] Failed to ${preview.action} webhook on ${repo}:`, err);
198
+ res.status(500).json({ error: `Failed to ${preview.action} webhook: ${message}`, preview });
199
+ }
200
+ });
201
+ // --- Test delivery endpoint ---
202
+ router.post('/api/integrations/github/pr-review/test', async (req, res) => {
203
+ const token = extractToken(req);
204
+ if (!verifyToken(token))
205
+ return res.status(401).json({ error: 'Unauthorized' });
206
+ const { repo, webhookUrl } = req.body;
207
+ if (!repo || !webhookUrl) {
208
+ return res.status(400).json({ error: 'Missing required fields: repo, webhookUrl' });
209
+ }
210
+ if (!REPO_PATTERN.test(repo)) {
211
+ return res.status(400).json({ error: 'Invalid repo format. Expected owner/repo.' });
212
+ }
213
+ const hook = await findCodekinWebhook(repo, webhookUrl);
214
+ if (!hook) {
215
+ return res.status(404).json({ error: `No Codekin webhook found on ${repo}` });
216
+ }
217
+ const success = await pingWebhook(repo, hook.id);
218
+ if (!success) {
219
+ return res.json({ success: false, message: 'Ping failed — check GitHub API access and repo permissions.' });
220
+ }
221
+ // Brief pause then fetch latest delivery to confirm receipt
222
+ await new Promise(r => setTimeout(r, 2000));
223
+ const deliveries = await getWebhookDeliveries(repo, hook.id, 1);
224
+ const latest = deliveries[0];
225
+ res.json({
226
+ success: true,
227
+ message: 'Ping sent successfully.',
228
+ delivery: latest ? { id: latest.id, statusCode: latest.status_code, event: latest.event } : undefined,
229
+ });
230
+ });
231
+ return router;
232
+ }
233
+ //# sourceMappingURL=webhook-setup-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-setup-routes.js","sourceRoot":"","sources":["../webhook-setup-routes.ts"],"names":[],"mappings":"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"}
@@ -141,6 +141,71 @@ export interface PullRequestPayload {
141
141
  login: string;
142
142
  };
143
143
  }
144
+ export interface GitHubWebhook {
145
+ id: number;
146
+ active: boolean;
147
+ config: {
148
+ url: string;
149
+ content_type: string;
150
+ insecure_ssl?: string;
151
+ };
152
+ events: string[];
153
+ created_at: string;
154
+ updated_at: string;
155
+ }
156
+ export interface GitHubDelivery {
157
+ id: number;
158
+ delivered_at: string;
159
+ status: string;
160
+ status_code: number;
161
+ event: string;
162
+ action: string | null;
163
+ }
164
+ export interface HealthCheckDetail {
165
+ ok: boolean;
166
+ message: string;
167
+ }
168
+ export interface HealthCheckResult {
169
+ overall: 'healthy' | 'degraded' | 'broken' | 'unconfigured';
170
+ checks: {
171
+ ghCli: HealthCheckDetail;
172
+ config: HealthCheckDetail & {
173
+ details?: {
174
+ enabled: boolean;
175
+ secretSet: boolean;
176
+ };
177
+ };
178
+ webhook: HealthCheckDetail & {
179
+ details?: {
180
+ id: number;
181
+ active: boolean;
182
+ events: string[];
183
+ url: string;
184
+ };
185
+ };
186
+ deliveries: HealthCheckDetail & {
187
+ details?: {
188
+ recent: Array<{
189
+ id: number;
190
+ status: string;
191
+ statusCode: number;
192
+ deliveredAt: string;
193
+ event: string;
194
+ }>;
195
+ };
196
+ };
197
+ };
198
+ }
199
+ export interface SetupPreview {
200
+ action: 'create' | 'update' | 'none';
201
+ existing?: GitHubWebhook;
202
+ proposed: {
203
+ url: string;
204
+ events: string[];
205
+ active: boolean;
206
+ };
207
+ changes?: string[];
208
+ }
144
209
  export interface PullRequestContext {
145
210
  repo: string;
146
211
  repoName: string;
@@ -280,6 +280,7 @@ export function createWorkflowRouter(verifyToken, extractToken, sessions, commit
280
280
  kind,
281
281
  customPrompt,
282
282
  model,
283
+ provider,
283
284
  });
284
285
  // Re-sync schedules and commit hooks with updated config
285
286
  try {