notican 1.0.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.
Files changed (56) hide show
  1. package/.env.example +14 -0
  2. package/README.md +175 -0
  3. package/dist/__fixtures__/index.d.ts +11 -0
  4. package/dist/__fixtures__/index.d.ts.map +1 -0
  5. package/dist/__fixtures__/index.js +160 -0
  6. package/dist/__fixtures__/index.js.map +1 -0
  7. package/dist/config.d.ts +17 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +37 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/github/client.d.ts +29 -0
  12. package/dist/github/client.d.ts.map +1 -0
  13. package/dist/github/client.js +121 -0
  14. package/dist/github/client.js.map +1 -0
  15. package/dist/handlers/index.d.ts +11 -0
  16. package/dist/handlers/index.d.ts.map +1 -0
  17. package/dist/handlers/index.js +35 -0
  18. package/dist/handlers/index.js.map +1 -0
  19. package/dist/handlers/issue.d.ts +6 -0
  20. package/dist/handlers/issue.d.ts.map +1 -0
  21. package/dist/handlers/issue.js +114 -0
  22. package/dist/handlers/issue.js.map +1 -0
  23. package/dist/handlers/pr.d.ts +6 -0
  24. package/dist/handlers/pr.d.ts.map +1 -0
  25. package/dist/handlers/pr.js +126 -0
  26. package/dist/handlers/pr.js.map +1 -0
  27. package/dist/handlers/push.d.ts +7 -0
  28. package/dist/handlers/push.d.ts.map +1 -0
  29. package/dist/handlers/push.js +151 -0
  30. package/dist/handlers/push.js.map +1 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +37 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/notion/client.d.ts +40 -0
  36. package/dist/notion/client.d.ts.map +1 -0
  37. package/dist/notion/client.js +289 -0
  38. package/dist/notion/client.js.map +1 -0
  39. package/dist/processors/claude.d.ts +29 -0
  40. package/dist/processors/claude.d.ts.map +1 -0
  41. package/dist/processors/claude.js +245 -0
  42. package/dist/processors/claude.js.map +1 -0
  43. package/dist/server/index.d.ts +4 -0
  44. package/dist/server/index.d.ts.map +1 -0
  45. package/dist/server/index.js +77 -0
  46. package/dist/server/index.js.map +1 -0
  47. package/dist/types/index.d.ts +142 -0
  48. package/dist/types/index.d.ts.map +1 -0
  49. package/dist/types/index.js +12 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/watcher/notion-tasks.d.ts +10 -0
  52. package/dist/watcher/notion-tasks.d.ts.map +1 -0
  53. package/dist/watcher/notion-tasks.js +135 -0
  54. package/dist/watcher/notion-tasks.js.map +1 -0
  55. package/package.json +61 -0
  56. package/scripts/setup-notion.ts +216 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/handlers/issue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAczE"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleIssueEvent = handleIssueEvent;
4
+ const config_1 = require("../config");
5
+ const client_1 = require("../notion/client");
6
+ /**
7
+ * Handle GitHub issue events.
8
+ */
9
+ async function handleIssueEvent(payload) {
10
+ const { action, issue } = payload;
11
+ console.log(`[Issue Handler] action=${action} issue=#${issue.number} "${issue.title}"`);
12
+ if (action === 'opened') {
13
+ await handleIssueOpened(payload);
14
+ }
15
+ else if (action === 'closed') {
16
+ await handleIssueClosed(payload);
17
+ }
18
+ else if (action === 'reopened') {
19
+ await handleIssueReopened(payload);
20
+ }
21
+ else {
22
+ console.log(`[Issue Handler] Ignoring action: ${action}`);
23
+ }
24
+ }
25
+ /**
26
+ * When a GitHub issue is opened: create a linked task in Notion Tasks database.
27
+ */
28
+ async function handleIssueOpened(payload) {
29
+ const { issue, repository } = payload;
30
+ const labels = issue.labels.map((l) => l.name);
31
+ const assignees = issue.assignees.map((a) => a.login);
32
+ const content = [
33
+ `## GitHub Issue #${issue.number}`,
34
+ `**URL:** ${issue.html_url}`,
35
+ `**Author:** ${issue.user.login}`,
36
+ `**Repository:** ${repository.full_name}`,
37
+ `**Labels:** ${labels.length > 0 ? labels.join(', ') : 'none'}`,
38
+ `**Assignees:** ${assignees.length > 0 ? assignees.join(', ') : 'unassigned'}`,
39
+ '',
40
+ '---',
41
+ '',
42
+ '## Description',
43
+ '',
44
+ issue.body ?? '*(no description provided)*',
45
+ ].join('\n');
46
+ try {
47
+ const pageId = await (0, client_1.createPage)(config_1.config.NOTION_DATABASE_TASKS, issue.title, content, {
48
+ github_issue_number: issue.number,
49
+ github_issue_url: issue.html_url,
50
+ github_repo: repository.full_name,
51
+ github_sync: false, // Already synced — this came FROM GitHub
52
+ status: 'Open',
53
+ author: issue.user.login,
54
+ labels: labels.join(', '),
55
+ });
56
+ console.log(`[Issue Handler] Notion task created for issue #${issue.number}: page ${pageId}`);
57
+ }
58
+ catch (err) {
59
+ const error = err;
60
+ throw new Error(`Failed to create Notion task for issue #${issue.number}: ${error.message}`);
61
+ }
62
+ }
63
+ /**
64
+ * When a GitHub issue is closed: update the linked Notion task status to Done.
65
+ */
66
+ async function handleIssueClosed(payload) {
67
+ const { issue } = payload;
68
+ try {
69
+ const pageId = await (0, client_1.findPageByExternalId)(config_1.config.NOTION_DATABASE_TASKS, String(issue.number), 'github_issue_number');
70
+ if (!pageId) {
71
+ console.warn(`[Issue Handler] No Notion task found for issue #${issue.number} — skipping update`);
72
+ return;
73
+ }
74
+ await client_1.notion.pages.update({
75
+ page_id: pageId,
76
+ properties: {
77
+ status: { select: { name: 'Done' } },
78
+ closed_at: {
79
+ date: { start: new Date().toISOString() },
80
+ },
81
+ },
82
+ });
83
+ console.log(`[Issue Handler] Notion task ${pageId} marked as Done for issue #${issue.number}`);
84
+ }
85
+ catch (err) {
86
+ const error = err;
87
+ throw new Error(`Failed to update Notion task for closed issue #${issue.number}: ${error.message}`);
88
+ }
89
+ }
90
+ /**
91
+ * When a GitHub issue is reopened: update the linked Notion task status back to Open.
92
+ */
93
+ async function handleIssueReopened(payload) {
94
+ const { issue } = payload;
95
+ try {
96
+ const pageId = await (0, client_1.findPageByExternalId)(config_1.config.NOTION_DATABASE_TASKS, String(issue.number), 'github_issue_number');
97
+ if (!pageId) {
98
+ console.warn(`[Issue Handler] No Notion task found for issue #${issue.number} — skipping update`);
99
+ return;
100
+ }
101
+ await client_1.notion.pages.update({
102
+ page_id: pageId,
103
+ properties: {
104
+ status: { select: { name: 'In Progress' } },
105
+ },
106
+ });
107
+ console.log(`[Issue Handler] Notion task ${pageId} marked as In Progress for issue #${issue.number}`);
108
+ }
109
+ catch (err) {
110
+ const error = err;
111
+ throw new Error(`Failed to update Notion task for reopened issue #${issue.number}: ${error.message}`);
112
+ }
113
+ }
114
+ //# sourceMappingURL=issue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/handlers/issue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PullRequestEvent } from '../types';
2
+ /**
3
+ * Handle pull_request events from GitHub.
4
+ */
5
+ export declare function handlePullRequestEvent(payload: PullRequestEvent): Promise<void>;
6
+ //# sourceMappingURL=pr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../src/handlers/pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAOjD;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAcrF"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlePullRequestEvent = handlePullRequestEvent;
4
+ const types_1 = require("../types");
5
+ const config_1 = require("../config");
6
+ const client_1 = require("../github/client");
7
+ const claude_1 = require("../processors/claude");
8
+ const client_2 = require("../notion/client");
9
+ /**
10
+ * Handle pull_request events from GitHub.
11
+ */
12
+ async function handlePullRequestEvent(payload) {
13
+ const { action, pull_request: pr, repository } = payload;
14
+ const owner = config_1.config.GITHUB_OWNER;
15
+ const repo = config_1.config.GITHUB_REPO;
16
+ console.log(`[PR Handler] action=${action} pr=#${pr.number} "${pr.title}"`);
17
+ if (action === 'closed' && pr.merged && pr.base.ref === repository.default_branch) {
18
+ await handleMergedPR(owner, repo, payload);
19
+ }
20
+ else if (action === 'opened' || action === 'ready_for_review') {
21
+ await handleOpenedPR(owner, repo, payload);
22
+ }
23
+ else {
24
+ console.log(`[PR Handler] Ignoring action: ${action}`);
25
+ }
26
+ }
27
+ /**
28
+ * When a PR is merged to the default branch:
29
+ * 1. Fetch the full diff
30
+ * 2. Ask Claude to analyze and determine what docs to generate
31
+ * 3. Write docs to appropriate Notion databases
32
+ */
33
+ async function handleMergedPR(owner, repo, payload) {
34
+ const { pull_request: pr } = payload;
35
+ console.log(`[PR Handler] PR #${pr.number} merged — fetching diff and generating docs`);
36
+ let diff;
37
+ try {
38
+ diff = await (0, client_1.getPRDiff)(owner, repo, pr.number);
39
+ }
40
+ catch (err) {
41
+ const error = err;
42
+ console.error(`[PR Handler] Could not fetch diff: ${error.message}`);
43
+ // Fall back to generating just a changelog without diff analysis
44
+ diff = '';
45
+ }
46
+ // Always generate a changelog entry for merged PRs
47
+ try {
48
+ const changelog = await (0, claude_1.generateChangelog)(payload);
49
+ const externalId = `pr-${pr.number}`;
50
+ await (0, client_2.createOrUpdatePage)(config_1.config.NOTION_DATABASE_CHANGELOG, externalId, `${pr.title} (#${pr.number})`, changelog, {
51
+ github_pr_number: String(pr.number),
52
+ github_pr_url: pr.html_url,
53
+ author: pr.user.login,
54
+ merged_at: new Date().toISOString(),
55
+ });
56
+ console.log(`[PR Handler] Changelog created for PR #${pr.number}`);
57
+ }
58
+ catch (err) {
59
+ const error = err;
60
+ console.error(`[PR Handler] Failed to create changelog: ${error.message}`);
61
+ }
62
+ // If we have a diff, do deeper AI analysis for ADRs / API Ref / Runbooks
63
+ if (diff) {
64
+ try {
65
+ const docs = await (0, claude_1.analyzeDiff)(diff, pr.title, pr.body ?? '');
66
+ for (const doc of docs) {
67
+ // Skip CHANGELOG — already handled above
68
+ if (doc.type === types_1.NotionDocType.CHANGELOG)
69
+ continue;
70
+ const databaseId = getDatabaseForDocType(doc.type);
71
+ if (!databaseId) {
72
+ console.warn(`[PR Handler] No database configured for doc type: ${doc.type}`);
73
+ continue;
74
+ }
75
+ const externalId = `pr-${pr.number}-${doc.type}`;
76
+ await (0, client_2.createOrUpdatePage)(databaseId, externalId, doc.title, doc.content, {
77
+ ...doc.metadata,
78
+ github_pr_number: String(pr.number),
79
+ github_pr_url: pr.html_url,
80
+ });
81
+ console.log(`[PR Handler] ${doc.type} doc created: "${doc.title}"`);
82
+ }
83
+ }
84
+ catch (err) {
85
+ const error = err;
86
+ console.error(`[PR Handler] Failed to analyze diff for additional docs: ${error.message}`);
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * When a PR is opened or marked ready for review:
92
+ * Generate a summary page for team context.
93
+ */
94
+ async function handleOpenedPR(_owner, _repo, payload) {
95
+ const { pull_request: pr } = payload;
96
+ console.log(`[PR Handler] PR #${pr.number} opened — generating review summary`);
97
+ try {
98
+ const summary = await (0, claude_1.summarizePR)(payload);
99
+ await (0, client_2.createPage)(config_1.config.NOTION_DATABASE_CHANGELOG, `[Review] ${pr.title} (#${pr.number})`, summary, {
100
+ github_pr_number: String(pr.number),
101
+ github_pr_url: pr.html_url,
102
+ author: pr.user.login,
103
+ status: 'open',
104
+ });
105
+ console.log(`[PR Handler] Review summary created for PR #${pr.number}`);
106
+ }
107
+ catch (err) {
108
+ const error = err;
109
+ console.error(`[PR Handler] Failed to create review summary: ${error.message}`);
110
+ }
111
+ }
112
+ function getDatabaseForDocType(type) {
113
+ switch (type) {
114
+ case types_1.NotionDocType.ADR:
115
+ return config_1.config.NOTION_DATABASE_ADR;
116
+ case types_1.NotionDocType.CHANGELOG:
117
+ return config_1.config.NOTION_DATABASE_CHANGELOG;
118
+ case types_1.NotionDocType.API_REF:
119
+ return config_1.config.NOTION_DATABASE_API_REF;
120
+ case types_1.NotionDocType.RUNBOOK:
121
+ return config_1.config.NOTION_DATABASE_RUNBOOKS;
122
+ default:
123
+ return null;
124
+ }
125
+ }
126
+ //# sourceMappingURL=pr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/handlers/pr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { PushEvent } from '../types';
2
+ /**
3
+ * Handle push events from GitHub.
4
+ * Only process pushes to the default branch.
5
+ */
6
+ export declare function handlePushEvent(payload: PushEvent): Promise<void>;
7
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/handlers/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAA+B,MAAM,UAAU,CAAC;AA+CvE;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DvE"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handlePushEvent = handlePushEvent;
4
+ const config_1 = require("../config");
5
+ const client_1 = require("../github/client");
6
+ const claude_1 = require("../processors/claude");
7
+ const client_2 = require("../notion/client");
8
+ // Patterns for different file categories
9
+ const API_PATTERNS = [
10
+ /routes?\//i,
11
+ /api\//i,
12
+ /controllers?\//i,
13
+ /endpoints?\//i,
14
+ /openapi/i,
15
+ /swagger/i,
16
+ /\.ya?ml$/i,
17
+ /graphql/i,
18
+ /schema\.(ts|js|json)$/i,
19
+ ];
20
+ const INFRA_PATTERNS = [
21
+ /Dockerfile/i,
22
+ /docker-compose/i,
23
+ /k8s\//i,
24
+ /kubernetes\//i,
25
+ /helm\//i,
26
+ /terraform\//i,
27
+ /\.tf$/i,
28
+ /\.tfvars$/i,
29
+ /\.github\/workflows/i,
30
+ /ansible\//i,
31
+ /nginx/i,
32
+ ];
33
+ const ARCH_PATTERNS = [
34
+ /package\.json$/i,
35
+ /tsconfig/i,
36
+ /webpack/i,
37
+ /vite\.config/i,
38
+ /babel\.config/i,
39
+ /jest\.config/i,
40
+ /src\/core\//i,
41
+ /src\/lib\//i,
42
+ /src\/shared\//i,
43
+ /middleware\//i,
44
+ /plugins?\//i,
45
+ ];
46
+ /**
47
+ * Handle push events from GitHub.
48
+ * Only process pushes to the default branch.
49
+ */
50
+ async function handlePushEvent(payload) {
51
+ const { ref, repository, commits } = payload;
52
+ const defaultBranch = `refs/heads/${repository.default_branch}`;
53
+ if (ref !== defaultBranch) {
54
+ console.log(`[Push Handler] Ignoring push to ${ref} (not default branch)`);
55
+ return;
56
+ }
57
+ if (!payload.after || payload.after === '0000000000000000000000000000000000000000') {
58
+ console.log('[Push Handler] Ignoring branch deletion event');
59
+ return;
60
+ }
61
+ console.log(`[Push Handler] Processing push to ${ref} with ${commits.length} commit(s)`);
62
+ const owner = config_1.config.GITHUB_OWNER;
63
+ const repo = config_1.config.GITHUB_REPO;
64
+ let changedFiles;
65
+ try {
66
+ changedFiles = await (0, client_1.getChangedFiles)(owner, repo, payload.after);
67
+ }
68
+ catch (err) {
69
+ const error = err;
70
+ console.error(`[Push Handler] Failed to fetch changed files: ${error.message}`);
71
+ return;
72
+ }
73
+ const commitMessages = commits.map((c) => c.message.split('\n')[0]);
74
+ // Check for API file changes
75
+ const apiFiles = changedFiles.filter((f) => API_PATTERNS.some((p) => p.test(f.filename)));
76
+ if (apiFiles.length > 0) {
77
+ await handleAPIChanges(apiFiles, payload.after, repository.name).catch((err) => {
78
+ console.error(`[Push Handler] API ref update failed: ${err.message}`);
79
+ });
80
+ }
81
+ // Check for infrastructure file changes
82
+ const infraFiles = changedFiles.filter((f) => INFRA_PATTERNS.some((p) => p.test(f.filename)));
83
+ if (infraFiles.length > 0) {
84
+ const runbookContext = {
85
+ changedFiles: infraFiles,
86
+ commitMessages,
87
+ ref,
88
+ repoName: repository.full_name,
89
+ repoUrl: repository.html_url,
90
+ };
91
+ await handleInfraChanges(runbookContext, payload.after).catch((err) => {
92
+ console.error(`[Push Handler] Runbook update failed: ${err.message}`);
93
+ });
94
+ }
95
+ // Check for architecture-level changes
96
+ const archFiles = changedFiles.filter((f) => ARCH_PATTERNS.some((p) => p.test(f.filename)));
97
+ if (archFiles.length >= 3) {
98
+ // Only trigger ADR for significant arch changes (3+ files)
99
+ await handleArchChanges(archFiles, payload, commitMessages).catch((err) => {
100
+ console.error(`[Push Handler] ADR generation failed: ${err.message}`);
101
+ });
102
+ }
103
+ }
104
+ async function handleAPIChanges(apiFiles, ref, repoName) {
105
+ console.log(`[Push Handler] ${apiFiles.length} API file(s) changed — updating API Reference`);
106
+ const content = await (0, claude_1.generateAPIRefUpdate)(apiFiles);
107
+ const externalId = `api-ref-${repoName}`;
108
+ await (0, client_2.createOrUpdatePage)(config_1.config.NOTION_DATABASE_API_REF, externalId, `API Reference — ${repoName}`, content, {
109
+ github_ref: ref,
110
+ last_updated: new Date().toISOString(),
111
+ changed_files: apiFiles.map((f) => f.filename).join(', '),
112
+ });
113
+ console.log('[Push Handler] API Reference updated in Notion');
114
+ }
115
+ async function handleInfraChanges(context, ref) {
116
+ console.log(`[Push Handler] ${context.changedFiles.length} infra file(s) changed — creating/updating Runbook`);
117
+ const content = await (0, claude_1.generateRunbook)(context);
118
+ const externalId = `runbook-${ref.slice(0, 12)}`;
119
+ const title = `Runbook: ${context.commitMessages[0] ?? 'Infrastructure Update'}`;
120
+ await (0, client_2.createOrUpdatePage)(config_1.config.NOTION_DATABASE_RUNBOOKS, externalId, title, content, {
121
+ github_ref: ref,
122
+ created_at: new Date().toISOString(),
123
+ changed_files: context.changedFiles.map((f) => f.filename).join(', '),
124
+ });
125
+ console.log('[Push Handler] Runbook created/updated in Notion');
126
+ }
127
+ async function handleArchChanges(archFiles, payload, commitMessages) {
128
+ console.log(`[Push Handler] ${archFiles.length} architecture file(s) changed — generating ADR`);
129
+ const adrContext = {
130
+ prTitle: commitMessages[0] ?? 'Architecture change via direct push',
131
+ prBody: commitMessages.join('\n'),
132
+ diff: archFiles
133
+ .filter((f) => f.patch)
134
+ .map((f) => `--- ${f.filename}\n${f.patch ?? ''}`)
135
+ .join('\n\n'),
136
+ changedFiles: archFiles,
137
+ prNumber: 0,
138
+ prUrl: payload.repository.html_url,
139
+ author: payload.pusher.name,
140
+ };
141
+ const content = await (0, claude_1.generateADR)(adrContext);
142
+ const externalId = `adr-push-${payload.after.slice(0, 12)}`;
143
+ const title = `ADR: ${commitMessages[0] ?? 'Architecture Decision'}`;
144
+ await (0, client_2.createOrUpdatePage)(config_1.config.NOTION_DATABASE_ADR, externalId, title, content, {
145
+ github_ref: payload.after,
146
+ author: payload.pusher.name,
147
+ created_at: new Date().toISOString(),
148
+ });
149
+ console.log('[Push Handler] ADR created in Notion');
150
+ }
151
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/handlers/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import 'dotenv/config';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("dotenv/config");
4
+ // config import triggers env validation at startup — fail fast before anything else
5
+ const config_1 = require("./config");
6
+ const server_1 = require("./server");
7
+ const notion_tasks_1 = require("./watcher/notion-tasks");
8
+ console.log('='.repeat(60));
9
+ console.log(' Autonomous Engineering Intelligence Hub');
10
+ console.log(' GitHub ↔ Notion Bidirectional Sync');
11
+ console.log('='.repeat(60));
12
+ console.log(`[Main] Environment: ${process.env.NODE_ENV ?? 'development'}`);
13
+ console.log(`[Main] GitHub: ${config_1.config.GITHUB_OWNER}/${config_1.config.GITHUB_REPO}`);
14
+ console.log(`[Main] Poll interval: ${config_1.config.POLL_INTERVAL_SECONDS}s`);
15
+ // Start the Express webhook server
16
+ (0, server_1.startServer)();
17
+ // Start the Notion task watcher cron job
18
+ (0, notion_tasks_1.startWatcher)();
19
+ // Graceful shutdown
20
+ process.on('SIGTERM', () => {
21
+ console.log('[Main] SIGTERM received — shutting down gracefully');
22
+ process.exit(0);
23
+ });
24
+ process.on('SIGINT', () => {
25
+ console.log('[Main] SIGINT received — shutting down gracefully');
26
+ process.exit(0);
27
+ });
28
+ process.on('uncaughtException', (err) => {
29
+ console.error('[Main] Uncaught exception:', err.message);
30
+ console.error(err.stack);
31
+ process.exit(1);
32
+ });
33
+ process.on('unhandledRejection', (reason) => {
34
+ console.error('[Main] Unhandled promise rejection:', reason);
35
+ process.exit(1);
36
+ });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yBAAuB;AACvB,oFAAoF;AACpF,qCAAkC;AAClC,qCAAuC;AACvC,yDAAsD;AAEtD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;AACxD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACnD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,EAAE,CAAC,CAAC;AAC5E,OAAO,CAAC,GAAG,CAAC,kBAAkB,eAAM,CAAC,YAAY,IAAI,eAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAC3E,OAAO,CAAC,GAAG,CAAC,yBAAyB,eAAM,CAAC,qBAAqB,GAAG,CAAC,CAAC;AAEtE,mCAAmC;AACnC,IAAA,oBAAW,GAAE,CAAC;AAEd,yCAAyC;AACzC,IAAA,2BAAY,GAAE,CAAC;AAEf,oBAAoB;AACpB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,MAAM,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Client } from '@notionhq/client';
2
+ import type { BlockObjectRequest } from '@notionhq/client/build/src/api-endpoints';
3
+ import type { NotionTask } from '../types';
4
+ declare const notion: Client;
5
+ /**
6
+ * Convert a markdown string to an array of Notion block objects.
7
+ * Handles headings, bullet lists, numbered lists, code blocks, and paragraphs.
8
+ */
9
+ export declare function markdownToNotionBlocks(markdown: string): BlockObjectRequest[];
10
+ /**
11
+ * Create a new page in a Notion database.
12
+ * Returns the created page ID.
13
+ */
14
+ export declare function createPage(databaseId: string, title: string, content: string, metadata: Record<string, string | number | boolean | null>): Promise<string>;
15
+ /**
16
+ * Update an existing Notion page's content by archiving old blocks and writing new ones.
17
+ */
18
+ export declare function updatePage(pageId: string, content: string): Promise<void>;
19
+ /**
20
+ * Find a Notion page in a database by a rich_text property matching an external ID.
21
+ * Returns the page ID if found, null otherwise.
22
+ */
23
+ export declare function findPageByExternalId(databaseId: string, externalId: string, propertyName?: string): Promise<string | null>;
24
+ /**
25
+ * Idempotent create-or-update: finds an existing page by externalId or creates a new one.
26
+ * Returns the page ID.
27
+ */
28
+ export declare function createOrUpdatePage(databaseId: string, externalId: string, title: string, content: string, metadata: Record<string, string | number | boolean | null>): Promise<string>;
29
+ /**
30
+ * Query the Tasks database for pages where github_sync checkbox is true
31
+ * and github_issue_number is not yet set.
32
+ */
33
+ export declare function getTasksToSync(): Promise<NotionTask[]>;
34
+ /**
35
+ * Mark a Notion task as synced by setting the github_issue_number and
36
+ * unchecking github_sync.
37
+ */
38
+ export declare function markTaskSynced(pageId: string, issueNumber: number, issueUrl: string): Promise<void>;
39
+ export { notion };
40
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/notion/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,QAAA,MAAM,MAAM,QAA4C,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA6E7E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GACzD,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAgBD;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,SAAqB,GAChC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GACzD,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CA4D5D;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}