claude-git-hooks 2.20.0 → 2.30.1

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.
@@ -0,0 +1,96 @@
1
+ /**
2
+ * File: setup-linear.js
3
+ * Purpose: Interactive Linear authentication setup command
4
+ *
5
+ * Handles:
6
+ * - Checking existing token
7
+ * - Prompting user for new token
8
+ * - Validating token via Linear API
9
+ * - Saving token to .claude/settings.local.json
10
+ */
11
+
12
+ import { testConnection, loadLinearToken } from '../utils/linear-connector.js';
13
+ import { saveToken } from '../utils/token-store.js';
14
+ import {
15
+ promptConfirmation,
16
+ promptEditField,
17
+ showSuccess,
18
+ showError,
19
+ showInfo,
20
+ showWarning
21
+ } from '../utils/interactive-ui.js';
22
+ import logger from '../utils/logger.js';
23
+
24
+ /**
25
+ * Run Linear authentication setup
26
+ * Why: Interactive flow to configure Linear token for PR analysis enrichment
27
+ *
28
+ * @returns {Promise<void>}
29
+ */
30
+ export async function runSetupLinear() {
31
+ showInfo('Linear Authentication Setup');
32
+
33
+ // Check existing token
34
+ const existingToken = loadLinearToken();
35
+ if (existingToken) {
36
+ showInfo('Existing Linear token found. Validating...');
37
+
38
+ const healthy = await testConnection(existingToken);
39
+ if (healthy) {
40
+ showSuccess('Linear token is valid and connected.');
41
+
42
+ const reconfigure = await promptConfirmation('Configure a different token?', false);
43
+ if (!reconfigure) {
44
+ return;
45
+ }
46
+ } else {
47
+ showWarning('Existing token is invalid or expired.');
48
+ }
49
+ }
50
+
51
+ // Show instructions
52
+ logger.info('Create a Linear API key:');
53
+ logger.info(' 1. Go to: https://linear.app/settings/api');
54
+ logger.info(' 2. Click "Create key"');
55
+ logger.info(' 3. Give it a label (e.g., "claude-hooks")');
56
+ logger.info(' 4. Copy the key (starts with lin_api_...)');
57
+
58
+ // Prompt for token
59
+ const token = await promptEditField('Paste your Linear API key (lin_api_...)', '');
60
+
61
+ if (!token || token.trim() === '') {
62
+ showWarning('No token provided. Setup cancelled.');
63
+ return;
64
+ }
65
+
66
+ const trimmedToken = token.trim();
67
+
68
+ // Basic format check
69
+ if (!trimmedToken.startsWith('lin_api_')) {
70
+ showWarning('Token format looks unusual (expected lin_api_...)');
71
+ const proceed = await promptConfirmation('Continue anyway?', false);
72
+ if (!proceed) {
73
+ return;
74
+ }
75
+ }
76
+
77
+ // Save token
78
+ const saveResult = saveToken('linearToken', trimmedToken);
79
+ if (!saveResult.success) {
80
+ showError(`Failed to save token: ${saveResult.error}`);
81
+ return;
82
+ }
83
+ showSuccess(`Token saved to ${saveResult.path}`);
84
+
85
+ // Validate with Linear API
86
+ showInfo('Validating token...');
87
+
88
+ const healthy = await testConnection(trimmedToken);
89
+ if (healthy) {
90
+ showSuccess('Linear connection verified.');
91
+ } else {
92
+ showWarning('Token validation failed - may not work correctly');
93
+ }
94
+
95
+ showSuccess('Setup complete! Linear ticket context will be used in: claude-hooks analyze-pr');
96
+ }