expxagents 0.30.21 → 0.30.23

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 (72) hide show
  1. package/dist/dashboard/assets/{BufferResource-CNVLxaqR.js → BufferResource-D_4NxDi0.js} +1 -1
  2. package/dist/dashboard/assets/{CanvasRenderer-CxVnsrzD.js → CanvasRenderer-BvvtfkUO.js} +1 -1
  3. package/dist/dashboard/assets/{JarvisView-Bk0QwZWW.js → JarvisView-DWUg6uy9.js} +1 -1
  4. package/dist/dashboard/assets/{RenderTargetSystem-CtHj6v7J.js → RenderTargetSystem-KLqqlDII.js} +1 -1
  5. package/dist/dashboard/assets/{ThreeBackground-DPSa33_n.js → ThreeBackground-CQg8JfT9.js} +1 -1
  6. package/dist/dashboard/assets/{WebGLRenderer-C2UGtfFx.js → WebGLRenderer-C-rFQnEK.js} +1 -1
  7. package/dist/dashboard/assets/{WebGPURenderer-CmDaV5xR.js → WebGPURenderer-BgcywHHz.js} +1 -1
  8. package/dist/dashboard/assets/{browserAll-DuOXddzq.js → browserAll-DxxBcVq_.js} +1 -1
  9. package/dist/dashboard/assets/index-ChTJhFG1.js +1203 -0
  10. package/dist/dashboard/assets/{webworkerAll-BlC_rD-w.js → webworkerAll-CKsuA5y-.js} +1 -1
  11. package/dist/dashboard/index.html +1 -1
  12. package/dist/server/api/__tests__/github-oauth-routes.test.d.ts +2 -0
  13. package/dist/server/api/__tests__/github-oauth-routes.test.d.ts.map +1 -0
  14. package/dist/server/api/__tests__/github-oauth-routes.test.js +119 -0
  15. package/dist/server/api/__tests__/github-oauth-routes.test.js.map +1 -0
  16. package/dist/server/api/__tests__/github-webhook.test.d.ts +2 -0
  17. package/dist/server/api/__tests__/github-webhook.test.d.ts.map +1 -0
  18. package/dist/server/api/__tests__/github-webhook.test.js +111 -0
  19. package/dist/server/api/__tests__/github-webhook.test.js.map +1 -0
  20. package/dist/server/api/__tests__/log-routes.test.js +8 -1
  21. package/dist/server/api/__tests__/log-routes.test.js.map +1 -1
  22. package/dist/server/api/github-oauth-routes.d.ts +9 -0
  23. package/dist/server/api/github-oauth-routes.d.ts.map +1 -0
  24. package/dist/server/api/github-oauth-routes.js +174 -0
  25. package/dist/server/api/github-oauth-routes.js.map +1 -0
  26. package/dist/server/api/integration-routes.d.ts.map +1 -1
  27. package/dist/server/api/integration-routes.js +6 -3
  28. package/dist/server/api/integration-routes.js.map +1 -1
  29. package/dist/server/api/webhook-routes.d.ts.map +1 -1
  30. package/dist/server/api/webhook-routes.js +88 -0
  31. package/dist/server/api/webhook-routes.js.map +1 -1
  32. package/dist/server/app.d.ts +2 -0
  33. package/dist/server/app.d.ts.map +1 -1
  34. package/dist/server/app.js +18 -2
  35. package/dist/server/app.js.map +1 -1
  36. package/dist/server/bridge/chat-handler.d.ts +2 -0
  37. package/dist/server/bridge/chat-handler.d.ts.map +1 -1
  38. package/dist/server/bridge/chat-handler.js +75 -0
  39. package/dist/server/bridge/chat-handler.js.map +1 -1
  40. package/dist/server/db/migrations.d.ts.map +1 -1
  41. package/dist/server/db/migrations.js +27 -0
  42. package/dist/server/db/migrations.js.map +1 -1
  43. package/dist/server/db/schema.d.ts +1 -1
  44. package/dist/server/db/schema.d.ts.map +1 -1
  45. package/dist/server/db/schema.js +21 -0
  46. package/dist/server/db/schema.js.map +1 -1
  47. package/dist/server/scheduler/debug-routes.d.ts +10 -0
  48. package/dist/server/scheduler/debug-routes.d.ts.map +1 -0
  49. package/dist/server/scheduler/debug-routes.js +69 -0
  50. package/dist/server/scheduler/debug-routes.js.map +1 -0
  51. package/dist/server/scheduler/scheduler-service.d.ts +40 -0
  52. package/dist/server/scheduler/scheduler-service.d.ts.map +1 -1
  53. package/dist/server/scheduler/scheduler-service.js +209 -0
  54. package/dist/server/scheduler/scheduler-service.js.map +1 -1
  55. package/dist/server/services/__tests__/github-action-service.test.d.ts +2 -0
  56. package/dist/server/services/__tests__/github-action-service.test.d.ts.map +1 -0
  57. package/dist/server/services/__tests__/github-action-service.test.js +89 -0
  58. package/dist/server/services/__tests__/github-action-service.test.js.map +1 -0
  59. package/dist/server/services/__tests__/github-credential-service.test.d.ts +2 -0
  60. package/dist/server/services/__tests__/github-credential-service.test.d.ts.map +1 -0
  61. package/dist/server/services/__tests__/github-credential-service.test.js +95 -0
  62. package/dist/server/services/__tests__/github-credential-service.test.js.map +1 -0
  63. package/dist/server/services/github-action-service.d.ts +21 -0
  64. package/dist/server/services/github-action-service.d.ts.map +1 -0
  65. package/dist/server/services/github-action-service.js +105 -0
  66. package/dist/server/services/github-action-service.js.map +1 -0
  67. package/dist/server/services/github-credential-service.d.ts +34 -0
  68. package/dist/server/services/github-credential-service.d.ts.map +1 -0
  69. package/dist/server/services/github-credential-service.js +158 -0
  70. package/dist/server/services/github-credential-service.js.map +1 -0
  71. package/package.json +1 -1
  72. package/dist/dashboard/assets/index-CgAs6Rfr.js +0 -1203
@@ -1,4 +1,4 @@
1
- import{a1 as G,a3 as I,a4 as B,l as _,M as k,W as O,N as A,a9 as m,T as v,as as C,R as E,w as z,a8 as U,v as w}from"./index-CgAs6Rfr.js";var M=`in vec2 aPosition;
1
+ import{a1 as G,a3 as I,a4 as B,l as _,M as k,W as O,N as A,a9 as m,T as v,as as C,R as E,w as z,a8 as U,v as w}from"./index-ChTJhFG1.js";var M=`in vec2 aPosition;
2
2
  out vec2 vTextureCoord;
3
3
 
4
4
  uniform vec4 uInputSize;
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>ExpxAgents — Mission Control</title>
7
- <script type="module" crossorigin src="/assets/index-CgAs6Rfr.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-ChTJhFG1.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-DtbIzZ5n.css">
9
9
  </head>
10
10
  <body>
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=github-oauth-routes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-oauth-routes.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/github-oauth-routes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { buildApp } from '../../app.js';
3
+ describe('github oauth routes', () => {
4
+ let app;
5
+ let cookie;
6
+ beforeEach(async () => {
7
+ app = await buildApp({
8
+ config: {
9
+ jwtSecret: 'test-secret-github-oauth-32chars!!',
10
+ },
11
+ });
12
+ await app.ready();
13
+ const loginRes = await app.inject({
14
+ method: 'POST',
15
+ url: '/api/auth/login',
16
+ payload: { username: 'admin', password: 'admin' },
17
+ });
18
+ const cookies = loginRes.cookies;
19
+ const access = cookies.find((c) => c.name === 'access_token');
20
+ const refresh = cookies.find((c) => c.name === 'refresh_token');
21
+ cookie = `access_token=${access.value}; refresh_token=${refresh.value}`;
22
+ });
23
+ afterEach(async () => {
24
+ vi.unstubAllGlobals();
25
+ vi.restoreAllMocks();
26
+ await app.close();
27
+ });
28
+ it('GET /api/integrations/github/oauth/start — redirects to GitHub', async () => {
29
+ process.env.GITHUB_CLIENT_ID = 'test_client_id';
30
+ const res = await app.inject({
31
+ method: 'GET',
32
+ url: '/api/integrations/github/oauth/start',
33
+ headers: { cookie },
34
+ });
35
+ expect(res.statusCode).toBe(302);
36
+ expect(res.headers.location).toContain('github.com/login/oauth/authorize');
37
+ expect(res.headers.location).toContain('client_id=test_client_id');
38
+ delete process.env.GITHUB_CLIENT_ID;
39
+ });
40
+ it('GET /api/integrations/github/oauth/start — 400 if GITHUB_CLIENT_ID not set', async () => {
41
+ delete process.env.GITHUB_CLIENT_ID;
42
+ const res = await app.inject({
43
+ method: 'GET',
44
+ url: '/api/integrations/github/oauth/start',
45
+ headers: { cookie },
46
+ });
47
+ expect(res.statusCode).toBe(400);
48
+ });
49
+ it('GET /api/integrations/github/oauth/callback — exchanges code for token', async () => {
50
+ process.env.GITHUB_CLIENT_ID = 'test_client_id';
51
+ process.env.GITHUB_CLIENT_SECRET = 'test_client_secret';
52
+ const mockFetch = vi.fn()
53
+ .mockResolvedValueOnce({
54
+ ok: true,
55
+ json: async () => ({
56
+ access_token: 'gho_test_token',
57
+ scope: 'repo,read:org',
58
+ token_type: 'bearer',
59
+ }),
60
+ })
61
+ .mockResolvedValueOnce({
62
+ ok: true,
63
+ json: async () => ({ login: 'octocat', type: 'User' }),
64
+ });
65
+ vi.stubGlobal('fetch', mockFetch);
66
+ // First get the state token from /start
67
+ const startRes = await app.inject({
68
+ method: 'GET',
69
+ url: '/api/integrations/github/oauth/start',
70
+ headers: { cookie },
71
+ });
72
+ const location = startRes.headers.location;
73
+ const stateParam = new URL(location).searchParams.get('state');
74
+ const callbackRes = await app.inject({
75
+ method: 'GET',
76
+ url: `/api/integrations/github/oauth/callback?code=test_code&state=${stateParam}`,
77
+ headers: { cookie },
78
+ });
79
+ expect(callbackRes.statusCode).toBe(302);
80
+ expect(callbackRes.headers.location).toContain('connected=github');
81
+ const db = app.db;
82
+ const row = db.prepare("SELECT * FROM github_installations WHERE id = 'oauth'").get();
83
+ expect(row).toBeDefined();
84
+ expect(row.account_login).toBe('octocat');
85
+ delete process.env.GITHUB_CLIENT_ID;
86
+ delete process.env.GITHUB_CLIENT_SECRET;
87
+ });
88
+ it('GET /api/integrations/github/installations — returns installations list', async () => {
89
+ const res = await app.inject({
90
+ method: 'GET',
91
+ url: '/api/integrations/github/installations',
92
+ headers: { cookie },
93
+ });
94
+ expect(res.statusCode).toBe(200);
95
+ expect(res.json().installations).toBeInstanceOf(Array);
96
+ });
97
+ it('DELETE /api/integrations/github/oauth — revokes and removes oauth', async () => {
98
+ const db = app.db;
99
+ const jwtSecret = 'test-secret-github-oauth-32chars!!';
100
+ const crypto = await import('node:crypto');
101
+ const key = crypto.createHash('sha256').update(jwtSecret).digest();
102
+ const iv = crypto.randomBytes(12);
103
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, { authTagLength: 16 });
104
+ const enc = Buffer.concat([cipher.update('gho_fake', 'utf8'), cipher.final()]);
105
+ const authTag = cipher.getAuthTag();
106
+ const stored = Buffer.concat([iv, authTag, enc]).toString('base64');
107
+ db.prepare("INSERT OR REPLACE INTO github_installations (id, type, account_login, account_type, access_token) VALUES ('oauth', 'oauth', 'octocat', 'User', ?)").run(stored);
108
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: true }));
109
+ const res = await app.inject({
110
+ method: 'DELETE',
111
+ url: '/api/integrations/github/oauth',
112
+ headers: { cookie },
113
+ });
114
+ expect(res.statusCode).toBe(200);
115
+ const row = db.prepare("SELECT * FROM github_installations WHERE id = 'oauth'").get();
116
+ expect(row).toBeUndefined();
117
+ });
118
+ });
119
+ //# sourceMappingURL=github-oauth-routes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-oauth-routes.test.js","sourceRoot":"","sources":["../../../src/api/__tests__/github-oauth-routes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=github-webhook.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-webhook.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/github-webhook.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { buildApp } from '../../app.js';
3
+ import crypto from 'node:crypto';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import os from 'node:os';
7
+ import YAML from 'yaml';
8
+ function makeSignature(body, secret) {
9
+ return 'sha256=' + crypto.createHmac('sha256', secret).update(body).digest('hex');
10
+ }
11
+ describe('POST /api/webhooks/github', () => {
12
+ let app;
13
+ let squadsDir;
14
+ beforeEach(async () => {
15
+ squadsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'squads-'));
16
+ process.env.GITHUB_WEBHOOK_SECRET = 'test-webhook-secret';
17
+ app = await buildApp({ config: { squadsDir } });
18
+ await app.ready();
19
+ });
20
+ afterEach(async () => {
21
+ fs.rmSync(squadsDir, { recursive: true });
22
+ delete process.env.GITHUB_WEBHOOK_SECRET;
23
+ vi.restoreAllMocks();
24
+ await app.close();
25
+ });
26
+ it('returns 401 for invalid HMAC signature', async () => {
27
+ const body = JSON.stringify({ ref: 'refs/heads/main' });
28
+ const res = await app.inject({
29
+ method: 'POST',
30
+ url: '/api/webhooks/github',
31
+ headers: {
32
+ 'x-github-event': 'push',
33
+ 'x-hub-signature-256': 'sha256=invalidsignature',
34
+ 'content-type': 'application/json',
35
+ },
36
+ body,
37
+ });
38
+ expect(res.statusCode).toBe(401);
39
+ });
40
+ it('returns 200 with no triggered squads when none match', async () => {
41
+ const body = JSON.stringify({ ref: 'refs/heads/main', repository: { full_name: 'org/repo' } });
42
+ const sig = makeSignature(body, 'test-webhook-secret');
43
+ const res = await app.inject({
44
+ method: 'POST',
45
+ url: '/api/webhooks/github',
46
+ headers: {
47
+ 'x-github-event': 'push',
48
+ 'x-hub-signature-256': sig,
49
+ 'content-type': 'application/json',
50
+ },
51
+ body,
52
+ });
53
+ expect(res.statusCode).toBe(200);
54
+ expect(res.json()).toEqual({ received: true, triggered: [] });
55
+ });
56
+ it('triggers squad matching push event with branch filter', async () => {
57
+ const squadDir = path.join(squadsDir, 'test-squad');
58
+ fs.mkdirSync(squadDir, { recursive: true });
59
+ fs.writeFileSync(path.join(squadDir, 'squad.yaml'), YAML.stringify({
60
+ squad: {
61
+ code: 'test-squad',
62
+ name: 'Test Squad',
63
+ github: {
64
+ triggers: [
65
+ { event: 'push', branch: 'main', action: 'run_pipeline' }
66
+ ]
67
+ }
68
+ }
69
+ }));
70
+ const body = JSON.stringify({ ref: 'refs/heads/main', repository: { full_name: 'org/repo' } });
71
+ const sig = makeSignature(body, 'test-webhook-secret');
72
+ const res = await app.inject({
73
+ method: 'POST',
74
+ url: '/api/webhooks/github',
75
+ headers: {
76
+ 'x-github-event': 'push',
77
+ 'x-hub-signature-256': sig,
78
+ 'content-type': 'application/json',
79
+ },
80
+ body,
81
+ });
82
+ expect(res.statusCode).toBe(200);
83
+ expect(res.json().triggered).toContain('test-squad');
84
+ });
85
+ it('does NOT trigger squad when branch does not match', async () => {
86
+ const squadDir = path.join(squadsDir, 'branch-squad');
87
+ fs.mkdirSync(squadDir, { recursive: true });
88
+ fs.writeFileSync(path.join(squadDir, 'squad.yaml'), YAML.stringify({
89
+ squad: {
90
+ code: 'branch-squad',
91
+ name: 'Branch Squad',
92
+ github: { triggers: [{ event: 'push', branch: 'main', action: 'run_pipeline' }] }
93
+ }
94
+ }));
95
+ const body = JSON.stringify({ ref: 'refs/heads/feature', repository: { full_name: 'org/repo' } });
96
+ const sig = makeSignature(body, 'test-webhook-secret');
97
+ const res = await app.inject({
98
+ method: 'POST',
99
+ url: '/api/webhooks/github',
100
+ headers: {
101
+ 'x-github-event': 'push',
102
+ 'x-hub-signature-256': sig,
103
+ 'content-type': 'application/json',
104
+ },
105
+ body,
106
+ });
107
+ expect(res.statusCode).toBe(200);
108
+ expect(res.json().triggered).toEqual([]);
109
+ });
110
+ });
111
+ //# sourceMappingURL=github-webhook.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-webhook.test.js","sourceRoot":"","sources":["../../../src/api/__tests__/github-webhook.test.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,19 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ import { runMigrations, seedDefaultAdmin } from '../../db/migrations.js';
2
4
  import { buildApp } from '../../app.js';
3
5
  describe('log-routes', () => {
4
6
  let app;
7
+ let db;
5
8
  beforeEach(async () => {
6
- app = await buildApp();
9
+ db = new Database(':memory:');
10
+ runMigrations(db);
11
+ await seedDefaultAdmin(db);
12
+ app = await buildApp({ db });
7
13
  });
8
14
  afterEach(async () => {
9
15
  await app.close();
16
+ db.close();
10
17
  });
11
18
  async function getAuthCookie() {
12
19
  const loginRes = await app.inject({
@@ -1 +1 @@
1
- {"version":3,"file":"log-routes.test.js","sourceRoot":"","sources":["../../../src/api/__tests__/log-routes.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,GAAoB,CAAC;IAEzB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,KAAK,UAAU,aAAa;QAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;YAChC,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,iBAAiB;YACtB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;SAClD,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;YAC3B,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,WAAW;YAChB,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"log-routes.test.js","sourceRoot":"","sources":["../../../src/api/__tests__/log-routes.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGxC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,GAAoB,CAAC;IACzB,IAAI,EAAqB,CAAC;IAE1B,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9B,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC3B,GAAG,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QAClB,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,KAAK,UAAU,aAAa;QAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;YAChC,MAAM,EAAE,MAAM;YACd,GAAG,EAAE,iBAAiB;YACtB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;SAClD,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;YAC3B,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,WAAW;YAChB,OAAO,EAAE,EAAE,MAAM,EAAE;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
2
+ import type Database from 'better-sqlite3';
3
+ interface GitHubOAuthRoutesOptions extends FastifyPluginOptions {
4
+ db: Database.Database;
5
+ jwtSecret: string;
6
+ }
7
+ export declare function githubOAuthRoutes(app: FastifyInstance, opts: GitHubOAuthRoutesOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=github-oauth-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-oauth-routes.d.ts","sourceRoot":"","sources":["../../src/api/github-oauth-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,UAAU,wBAAyB,SAAQ,oBAAoB;IAC7D,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA6Of"}
@@ -0,0 +1,174 @@
1
+ import { signAccessToken, verifyAccessToken } from '../auth/jwt.js';
2
+ import { GitHubCredentialService } from '../services/github-credential-service.js';
3
+ export async function githubOAuthRoutes(app, opts) {
4
+ const { db, jwtSecret } = opts;
5
+ const credentials = new GitHubCredentialService(db, jwtSecret);
6
+ // GET /api/integrations/github/oauth/start — redirect to GitHub OAuth
7
+ app.get('/api/integrations/github/oauth/start', {
8
+ preHandler: [app.requireAuth],
9
+ }, async (request, reply) => {
10
+ const clientId = process.env.GITHUB_CLIENT_ID;
11
+ if (!clientId) {
12
+ return reply.status(400).send({ error: 'GITHUB_CLIENT_ID not configured' });
13
+ }
14
+ const user = request.user;
15
+ const state = signAccessToken({ userId: user.userId, role: 'oauth-state' }, jwtSecret, '10m');
16
+ const params = new URLSearchParams({
17
+ client_id: clientId,
18
+ scope: 'repo,read:org,workflow',
19
+ state,
20
+ });
21
+ return reply.redirect(`https://github.com/login/oauth/authorize?${params.toString()}`);
22
+ });
23
+ // GET /api/integrations/github/oauth/callback — receive GitHub OAuth code
24
+ app.get('/api/integrations/github/oauth/callback', async (request, reply) => {
25
+ const { code, state, error } = request.query;
26
+ if (error) {
27
+ return reply.redirect(`/settings?tab=integrations&error=${encodeURIComponent(error)}`);
28
+ }
29
+ if (!code || !state) {
30
+ return reply.status(400).send({ error: 'Missing code or state' });
31
+ }
32
+ try {
33
+ verifyAccessToken(state, jwtSecret);
34
+ }
35
+ catch {
36
+ return reply.status(400).send({ error: 'Invalid state parameter' });
37
+ }
38
+ const clientId = process.env.GITHUB_CLIENT_ID;
39
+ const clientSecret = process.env.GITHUB_CLIENT_SECRET;
40
+ if (!clientId || !clientSecret) {
41
+ return reply.status(500).send({ error: 'GitHub OAuth not configured' });
42
+ }
43
+ const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
44
+ method: 'POST',
45
+ headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
46
+ body: JSON.stringify({ client_id: clientId, client_secret: clientSecret, code }),
47
+ });
48
+ const tokenData = await tokenRes.json();
49
+ if (!tokenData.access_token) {
50
+ return reply.redirect(`/settings?tab=integrations&error=${encodeURIComponent(tokenData.error ?? 'oauth_failed')}`);
51
+ }
52
+ const userRes = await fetch('https://api.github.com/user', {
53
+ headers: { Authorization: `Bearer ${tokenData.access_token}` },
54
+ });
55
+ const userData = await userRes.json();
56
+ await credentials.saveOAuthToken({
57
+ accessToken: tokenData.access_token,
58
+ scope: tokenData.scope ?? '',
59
+ accountLogin: userData.login,
60
+ accountType: userData.type,
61
+ });
62
+ return reply.redirect('/settings?tab=integrations&connected=github');
63
+ });
64
+ // GET /api/integrations/github/app/callback — GitHub App installation callback
65
+ app.get('/api/integrations/github/app/callback', async (request, reply) => {
66
+ const { installation_id, setup_action } = request.query;
67
+ if (!installation_id || setup_action !== 'install') {
68
+ return reply.redirect('/settings?tab=integrations');
69
+ }
70
+ const appId = process.env.GITHUB_APP_ID;
71
+ const privateKey = process.env.GITHUB_APP_PRIVATE_KEY;
72
+ if (!appId || !privateKey) {
73
+ return reply.status(500).send({ error: 'GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY not configured' });
74
+ }
75
+ const appJwt = credentials.makeAppJwt(appId, privateKey);
76
+ const tokenRes = await fetch(`https://api.github.com/app/installations/${installation_id}/access_tokens`, {
77
+ method: 'POST',
78
+ headers: {
79
+ Authorization: `Bearer ${appJwt}`,
80
+ Accept: 'application/vnd.github+json',
81
+ },
82
+ });
83
+ if (!tokenRes.ok) {
84
+ return reply.redirect('/settings?tab=integrations&error=app_token_failed');
85
+ }
86
+ const tokenData = await tokenRes.json();
87
+ const instRes = await fetch(`https://api.github.com/app/installations/${installation_id}`, { headers: { Authorization: `Bearer ${appJwt}`, Accept: 'application/vnd.github+json' } });
88
+ const instData = await instRes.json();
89
+ await credentials.saveAppInstallation({
90
+ installationId: installation_id,
91
+ accessToken: tokenData.token,
92
+ tokenExpiresAt: tokenData.expires_at,
93
+ accountLogin: instData.account.login,
94
+ accountType: instData.account.type,
95
+ });
96
+ return reply.redirect('/settings?tab=integrations&connected=github-app');
97
+ });
98
+ // GET /api/integrations/github/installations — list all installations
99
+ app.get('/api/integrations/github/installations', {
100
+ preHandler: [app.requireAuth],
101
+ }, async (_request, reply) => {
102
+ const installations = await credentials.getInstallations();
103
+ return reply.send({ installations });
104
+ });
105
+ // GET /api/integrations/github/webhooks — list registered webhooks
106
+ app.get('/api/integrations/github/webhooks', {
107
+ preHandler: [app.requireAuth],
108
+ }, async (_request, reply) => {
109
+ const rows = db.prepare('SELECT repo_full_name, webhook_id, squad_code FROM github_webhook_registrations ORDER BY created_at DESC').all();
110
+ return reply.send({ webhooks: rows });
111
+ });
112
+ // DELETE /api/integrations/github/oauth — revoke OAuth
113
+ app.delete('/api/integrations/github/oauth', {
114
+ preHandler: [app.requireAuth],
115
+ }, async (_request, reply) => {
116
+ await credentials.revokeOAuth();
117
+ return reply.send({ ok: true });
118
+ });
119
+ // DELETE /api/integrations/github/app/:installationId — remove App installation
120
+ app.delete('/api/integrations/github/app/:installationId', { preHandler: [app.requireAuth] }, async (request, reply) => {
121
+ await credentials.removeAppInstallation(request.params.installationId);
122
+ return reply.send({ ok: true });
123
+ });
124
+ // POST /api/integrations/github/repos/:owner/:repo/webhook/install
125
+ app.post('/api/integrations/github/repos/:owner/:repo/webhook/install', { preHandler: [app.requireAuth] }, async (request, reply) => {
126
+ const { owner, repo } = request.params;
127
+ const serverUrl = process.env.SERVER_URL;
128
+ const webhookSecret = process.env.GITHUB_WEBHOOK_SECRET;
129
+ if (!serverUrl || !webhookSecret) {
130
+ return reply.status(400).send({ error: 'SERVER_URL and GITHUB_WEBHOOK_SECRET must be set' });
131
+ }
132
+ const token = await credentials.getToken();
133
+ const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/hooks`, {
134
+ method: 'POST',
135
+ headers: {
136
+ Authorization: `Bearer ${token}`,
137
+ Accept: 'application/vnd.github+json',
138
+ 'Content-Type': 'application/json',
139
+ },
140
+ body: JSON.stringify({
141
+ name: 'web',
142
+ active: true,
143
+ events: ['push', 'pull_request', 'issues', 'workflow_run'],
144
+ config: {
145
+ url: `${serverUrl}/api/webhooks/github`,
146
+ content_type: 'json',
147
+ secret: webhookSecret,
148
+ },
149
+ }),
150
+ });
151
+ if (!res.ok) {
152
+ const err = await res.json();
153
+ return reply.status(res.status).send({ error: err.message ?? 'Failed to create webhook' });
154
+ }
155
+ const hook = await res.json();
156
+ db.prepare('INSERT INTO github_webhook_registrations (repo_full_name, webhook_id, squad_code) VALUES (?, ?, ?)').run(`${owner}/${repo}`, hook.id, request.body?.squad_code ?? null);
157
+ return reply.send({ ok: true, webhook_id: hook.id });
158
+ });
159
+ // DELETE /api/integrations/github/repos/:owner/:repo/webhook
160
+ app.delete('/api/integrations/github/repos/:owner/:repo/webhook', { preHandler: [app.requireAuth] }, async (request, reply) => {
161
+ const { owner, repo } = request.params;
162
+ const row = db.prepare('SELECT webhook_id FROM github_webhook_registrations WHERE repo_full_name = ?').get(`${owner}/${repo}`);
163
+ if (!row)
164
+ return reply.status(404).send({ error: 'Webhook not registered' });
165
+ const token = await credentials.getToken();
166
+ await fetch(`https://api.github.com/repos/${owner}/${repo}/hooks/${row.webhook_id}`, {
167
+ method: 'DELETE',
168
+ headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json' },
169
+ });
170
+ db.prepare('DELETE FROM github_webhook_registrations WHERE repo_full_name = ?').run(`${owner}/${repo}`);
171
+ return reply.send({ ok: true });
172
+ });
173
+ }
174
+ //# sourceMappingURL=github-oauth-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-oauth-routes.js","sourceRoot":"","sources":["../../src/api/github-oauth-routes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAOnF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAoB,EACpB,IAA8B;IAE9B,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,uBAAuB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAE/D,sEAAsE;IACtE,GAAG,CAAC,GAAG,CAAC,sCAAsC,EAAE;QAC9C,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;KAC9B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,MAAM,IAAI,GAAI,OAAmD,CAAC,IAAI,CAAC;QACvE,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAE9F,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,SAAS,EAAE,QAAQ;YACnB,KAAK,EAAE,wBAAwB;YAC/B,KAAK;SACN,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,QAAQ,CAAC,4CAA4C,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,GAAG,CAAC,GAAG,CAEJ,yCAAyC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACrE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAE7C,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,QAAQ,CAAC,oCAAoC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC;YACH,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;QACtD,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;YAC/B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,6CAA6C,EAAE;YAC1E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC3E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;SACjF,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAIpC,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,oCAAoC,kBAAkB,CAAC,SAAS,CAAC,KAAK,IAAI,cAAc,CAAC,EAAE,CAAC,CAAC;QACrH,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,6BAA6B,EAAE;YACzD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,SAAS,CAAC,YAAY,EAAE,EAAE;SAC/D,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAqC,CAAC;QAEzE,MAAM,WAAW,CAAC,cAAc,CAAC;YAC/B,WAAW,EAAE,SAAS,CAAC,YAAY;YACnC,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE;YAC5B,YAAY,EAAE,QAAQ,CAAC,KAAK;YAC5B,WAAW,EAAE,QAAQ,CAAC,IAAI;SAC3B,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,QAAQ,CAAC,6CAA6C,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,GAAG,CAAC,GAAG,CAEJ,uCAAuC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACnE,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAExD,IAAI,CAAC,eAAe,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACtD,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yDAAyD,EAAE,CAAC,CAAC;QACtG,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAEzD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,4CAA4C,eAAe,gBAAgB,EAC3E;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,EAAE;gBACjC,MAAM,EAAE,6BAA6B;aACtC;SACF,CACF,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,QAAQ,CAAC,mDAAmD,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA2C,CAAC;QAEjF,MAAM,OAAO,GAAG,MAAM,KAAK,CACzB,4CAA4C,eAAe,EAAE,EAC7D,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE,EAAE,CAC1F,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAkD,CAAC;QAEtF,MAAM,WAAW,CAAC,mBAAmB,CAAC;YACpC,cAAc,EAAE,eAAe;YAC/B,WAAW,EAAE,SAAS,CAAC,KAAK;YAC5B,cAAc,EAAE,SAAS,CAAC,UAAU;YACpC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK;YACpC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI;SACnC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,QAAQ,CAAC,iDAAiD,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,sEAAsE;IACtE,GAAG,CAAC,GAAG,CAAC,wCAAwC,EAAE;QAChD,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;KAC9B,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,gBAAgB,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,mEAAmE;IACnE,GAAG,CAAC,GAAG,CAAC,mCAAmC,EAAE;QAC3C,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;KAC9B,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB,0GAA0G,CAC3G,CAAC,GAAG,EAAE,CAAC;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,GAAG,CAAC,MAAM,CAAC,gCAAgC,EAAE;QAC3C,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;KAC9B,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,WAAW,CAAC,WAAW,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,gFAAgF;IAChF,GAAG,CAAC,MAAM,CACR,8CAA8C,EAC9C,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EACjC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,WAAW,CAAC,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACvE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC,CACF,CAAC;IAEF,mEAAmE;IACnE,GAAG,CAAC,IAAI,CACN,6DAA6D,EAC7D,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EACjC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACzC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QACxD,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;QAC/F,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,gCAAgC,KAAK,IAAI,IAAI,QAAQ,EAAE;YAC7E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,MAAM,EAAE,6BAA6B;gBACrC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,CAAC;gBAC1D,MAAM,EAAE;oBACN,GAAG,EAAE,GAAG,SAAS,sBAAsB;oBACvC,YAAY,EAAE,MAAM;oBACpB,MAAM,EAAE,aAAa;iBACtB;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAA0B,CAAC;YACrD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,0BAA0B,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAoB,CAAC;QAChD,EAAE,CAAC,OAAO,CACR,oGAAoG,CACrG,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI,CAAC,CAAC;QAErE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC,CACF,CAAC;IAEF,6DAA6D;IAC7D,GAAG,CAAC,MAAM,CACR,qDAAqD,EACrD,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EACjC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACvC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,8EAA8E,CAC/E,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAuC,CAAC;QAEhE,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAE7E,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,KAAK,CAAC,gCAAgC,KAAK,IAAI,IAAI,UAAU,GAAG,CAAC,UAAU,EAAE,EAAE;YACnF,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,MAAM,EAAE,6BAA6B,EAAE;SACrF,CAAC,CAAC;QAEH,EAAE,CAAC,OAAO,CAAC,mEAAmE,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QACxG,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration-routes.d.ts","sourceRoot":"","sources":["../../src/api/integration-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,UAAU,wBAAyB,SAAQ,oBAAoB;IAC7D,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;CACvB;AAUD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzH,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAoKhD,CAAC;AAqFF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAqHf"}
1
+ {"version":3,"file":"integration-routes.d.ts","sourceRoot":"","sources":["../../src/api/integration-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,UAAU,wBAAyB,SAAQ,oBAAoB;IAC7D,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;CACvB;AAUD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzH,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAuKhD,CAAC;AAqFF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAqHf"}
@@ -44,10 +44,13 @@ export const PROVIDER_CATALOG = [
44
44
  { key: 'team_id', label: 'Team ID', type: 'text' },
45
45
  { key: 'default_file_key', label: 'Default File Key', type: 'text' },
46
46
  ] },
47
- { key: 'github', name: 'GitHub', category: 'dev', description: 'Repositórios, issues e pull requests', fields: [
48
- { key: 'token', label: 'Personal Access Token', type: 'password', required: true, placeholder: 'ghp_...' },
47
+ { key: 'github', name: 'GitHub', category: 'dev', description: 'Repositórios, issues, PRs e GitHub Actions', fields: [
48
+ { key: 'token', label: 'Personal Access Token (PAT)', type: 'password', placeholder: 'ghp_...' },
49
49
  { key: 'org', label: 'Organization', type: 'text', placeholder: 'my-org' },
50
- { key: 'default_repo', label: 'Default Repository', type: 'text', placeholder: 'my-repo' },
50
+ { key: 'default_repo', label: 'Default Repository', type: 'text', placeholder: 'owner/repo' },
51
+ { key: 'oauth_client_id', label: 'OAuth App Client ID', type: 'text', placeholder: 'Iv1.abc...' },
52
+ { key: 'oauth_client_secret', label: 'OAuth App Client Secret', type: 'password' },
53
+ { key: 'webhook_secret', label: 'Webhook Secret', type: 'password' },
51
54
  ] },
52
55
  { key: 'gitlab', name: 'GitLab', category: 'dev', description: 'Repositórios, CI/CD e DevOps', fields: [
53
56
  { key: 'token', label: 'Personal Access Token', type: 'password', required: true, placeholder: 'glpat-...' },