planflow-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/bin/cli.js +169 -0
- package/bin/postinstall.js +87 -0
- package/commands/pfActivity/SKILL.md +725 -0
- package/commands/pfAssign/SKILL.md +623 -0
- package/commands/pfCloudLink/SKILL.md +192 -0
- package/commands/pfCloudList/SKILL.md +222 -0
- package/commands/pfCloudNew/SKILL.md +187 -0
- package/commands/pfCloudUnlink/SKILL.md +152 -0
- package/commands/pfComment/SKILL.md +227 -0
- package/commands/pfComments/SKILL.md +159 -0
- package/commands/pfConnectionStatus/SKILL.md +433 -0
- package/commands/pfDiscord/SKILL.md +740 -0
- package/commands/pfGithubBranch/SKILL.md +672 -0
- package/commands/pfGithubIssue/SKILL.md +963 -0
- package/commands/pfGithubLink/SKILL.md +859 -0
- package/commands/pfGithubPr/SKILL.md +1335 -0
- package/commands/pfGithubUnlink/SKILL.md +401 -0
- package/commands/pfLive/SKILL.md +185 -0
- package/commands/pfLogin/SKILL.md +249 -0
- package/commands/pfLogout/SKILL.md +155 -0
- package/commands/pfMyTasks/SKILL.md +198 -0
- package/commands/pfNotificationSettings/SKILL.md +619 -0
- package/commands/pfNotifications/SKILL.md +420 -0
- package/commands/pfNotificationsClear/SKILL.md +421 -0
- package/commands/pfReact/SKILL.md +232 -0
- package/commands/pfSlack/SKILL.md +659 -0
- package/commands/pfSyncPull/SKILL.md +210 -0
- package/commands/pfSyncPush/SKILL.md +299 -0
- package/commands/pfSyncStatus/SKILL.md +212 -0
- package/commands/pfTeamInvite/SKILL.md +161 -0
- package/commands/pfTeamList/SKILL.md +253 -0
- package/commands/pfTeamRemove/SKILL.md +115 -0
- package/commands/pfTeamRole/SKILL.md +160 -0
- package/commands/pfTestWebhooks/SKILL.md +722 -0
- package/commands/pfUnassign/SKILL.md +134 -0
- package/commands/pfWhoami/SKILL.md +258 -0
- package/commands/pfWorkload/SKILL.md +219 -0
- package/commands/planExportCsv/SKILL.md +106 -0
- package/commands/planExportGithub/SKILL.md +222 -0
- package/commands/planExportJson/SKILL.md +159 -0
- package/commands/planExportSummary/SKILL.md +158 -0
- package/commands/planNew/SKILL.md +641 -0
- package/commands/planNext/SKILL.md +1200 -0
- package/commands/planSettingsAutoSync/SKILL.md +199 -0
- package/commands/planSettingsLanguage/SKILL.md +201 -0
- package/commands/planSettingsReset/SKILL.md +237 -0
- package/commands/planSettingsShow/SKILL.md +482 -0
- package/commands/planSpec/SKILL.md +929 -0
- package/commands/planUpdate/SKILL.md +2518 -0
- package/commands/team/SKILL.md +740 -0
- package/locales/en.json +1499 -0
- package/locales/ka.json +1499 -0
- package/package.json +48 -0
- package/templates/PROJECT_PLAN.template.md +157 -0
- package/templates/backend-api.template.md +562 -0
- package/templates/frontend-spa.template.md +610 -0
- package/templates/fullstack.template.md +397 -0
- package/templates/ka/backend-api.template.md +562 -0
- package/templates/ka/frontend-spa.template.md +610 -0
- package/templates/ka/fullstack.template.md +397 -0
- package/templates/sections/architecture.md +21 -0
- package/templates/sections/overview.md +15 -0
- package/templates/sections/tasks.md +22 -0
- package/templates/sections/tech-stack.md +19 -0
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pfGithubLink
|
|
3
|
+
description: Link a GitHub repository to the current PlanFlow project
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PlanFlow GitHub Link
|
|
7
|
+
|
|
8
|
+
Link a GitHub repository to the current PlanFlow cloud project for issue tracking, branch creation, and PR integration.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
/pfGithubLink owner/repo # Link to GitHub repository
|
|
14
|
+
/pfGithubLink # Show current link status
|
|
15
|
+
/pfGithubLink autocomplete on # Enable auto-complete tasks on PR merge
|
|
16
|
+
/pfGithubLink autocomplete off # Disable auto-complete tasks on PR merge
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Step 0: Load Configuration
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
function getMergedConfig() {
|
|
23
|
+
let globalConfig = {}
|
|
24
|
+
let localConfig = {}
|
|
25
|
+
|
|
26
|
+
const globalPath = expandPath("~/.config/claude/plan-plugin-config.json")
|
|
27
|
+
if (fileExists(globalPath)) {
|
|
28
|
+
try { globalConfig = JSON.parse(readFile(globalPath)) } catch (e) {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (fileExists("./.plan-config.json")) {
|
|
32
|
+
try { localConfig = JSON.parse(readFile("./.plan-config.json")) } catch (e) {}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
...globalConfig,
|
|
37
|
+
...localConfig,
|
|
38
|
+
cloud: {
|
|
39
|
+
...(globalConfig.cloud || {}),
|
|
40
|
+
...(localConfig.cloud || {})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const config = getMergedConfig()
|
|
46
|
+
const language = config.language || "en"
|
|
47
|
+
const cloudConfig = config.cloud || {}
|
|
48
|
+
const isAuthenticated = !!cloudConfig.apiToken
|
|
49
|
+
const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
|
|
50
|
+
const projectId = cloudConfig.projectId || null
|
|
51
|
+
|
|
52
|
+
const t = JSON.parse(readFile(`locales/${language}.json`))
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Step 0.5: Show Notification Badge
|
|
56
|
+
|
|
57
|
+
Only if authenticated AND linked to a project:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
if [ -n "$TOKEN" ] && [ -n "$PROJECT_ID" ]; then
|
|
61
|
+
RESPONSE=$(curl -s --connect-timeout 3 --max-time 5 \
|
|
62
|
+
-X GET \
|
|
63
|
+
-H "Accept: application/json" \
|
|
64
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
65
|
+
"${API_URL}/projects/${PROJECT_ID}/notifications?limit=1&unread=true" 2>/dev/null)
|
|
66
|
+
|
|
67
|
+
if [ $? -eq 0 ]; then
|
|
68
|
+
UNREAD_COUNT=$(echo "$RESPONSE" | grep -o '"unreadCount":[0-9]*' | grep -o '[0-9]*')
|
|
69
|
+
if [ -n "$UNREAD_COUNT" ] && [ "$UNREAD_COUNT" -gt 0 ]; then
|
|
70
|
+
echo "🔔 $UNREAD_COUNT unread notification(s) — /pfNotifications to view"
|
|
71
|
+
echo ""
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Step 1: Parse Arguments
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
const args = commandArgs.trim()
|
|
81
|
+
const repoPattern = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/
|
|
82
|
+
const autocompletePattern = /^autocomplete\s+(on|off)$/i
|
|
83
|
+
|
|
84
|
+
if (args === "") {
|
|
85
|
+
// Show current status
|
|
86
|
+
showGitHubStatus()
|
|
87
|
+
} else if (autocompletePattern.test(args)) {
|
|
88
|
+
// Toggle auto-complete setting
|
|
89
|
+
const match = args.match(autocompletePattern)
|
|
90
|
+
const enabled = match[1].toLowerCase() === "on"
|
|
91
|
+
toggleAutoComplete(enabled)
|
|
92
|
+
} else if (repoPattern.test(args)) {
|
|
93
|
+
// Link to repo
|
|
94
|
+
const [owner, repo] = args.split("/")
|
|
95
|
+
linkGitHubRepo(owner, repo)
|
|
96
|
+
} else {
|
|
97
|
+
showUsageError()
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Step 2: Validate Prerequisites
|
|
102
|
+
|
|
103
|
+
### 2a: Check Authentication
|
|
104
|
+
|
|
105
|
+
If not authenticated:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
109
|
+
│ ❌ ERROR │
|
|
110
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
111
|
+
│ │
|
|
112
|
+
│ {t.commands.sync.notAuthenticated} │
|
|
113
|
+
│ │
|
|
114
|
+
│ You must be logged in to link GitHub repositories. │
|
|
115
|
+
│ │
|
|
116
|
+
│ 💡 Next Steps: │
|
|
117
|
+
│ • /pfLogin Sign in to PlanFlow │
|
|
118
|
+
│ │
|
|
119
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 2b: Check Project Link
|
|
123
|
+
|
|
124
|
+
If not linked to a cloud project:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
128
|
+
│ ❌ ERROR │
|
|
129
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
130
|
+
│ │
|
|
131
|
+
│ {t.commands.sync.notLinked} │
|
|
132
|
+
│ │
|
|
133
|
+
│ You must link to a cloud project first. │
|
|
134
|
+
│ │
|
|
135
|
+
│ 💡 Next Steps: │
|
|
136
|
+
│ • /pfCloudLink Link to existing project │
|
|
137
|
+
│ • /pfCloudNew Create new cloud project │
|
|
138
|
+
│ │
|
|
139
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2c: Check GitHub CLI (Optional Enhancement)
|
|
143
|
+
|
|
144
|
+
Optionally check if `gh` CLI is available for enhanced features:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
if command -v gh &> /dev/null; then
|
|
148
|
+
GH_AVAILABLE=true
|
|
149
|
+
# Check if gh is authenticated
|
|
150
|
+
if gh auth status &> /dev/null; then
|
|
151
|
+
GH_AUTHENTICATED=true
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Step 3: Show Current Status (No Arguments)
|
|
157
|
+
|
|
158
|
+
If no arguments provided, show current GitHub link status:
|
|
159
|
+
|
|
160
|
+
### 3a: Fetch Current Integration Status
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
164
|
+
--connect-timeout 5 \
|
|
165
|
+
--max-time 10 \
|
|
166
|
+
-X GET \
|
|
167
|
+
-H "Accept: application/json" \
|
|
168
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
169
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
170
|
+
|
|
171
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
172
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 3b: Show Status Card
|
|
176
|
+
|
|
177
|
+
**If linked:**
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
181
|
+
│ 🐙 GitHub Integration │
|
|
182
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
183
|
+
│ │
|
|
184
|
+
│ ── Repository ──────────────────────────────────────────────────────────── │
|
|
185
|
+
│ │
|
|
186
|
+
│ 📦 Repository: owner/repo-name │
|
|
187
|
+
│ 🔗 URL: https://github.com/owner/repo-name │
|
|
188
|
+
│ 📅 Linked: 2026-02-15 │
|
|
189
|
+
│ │
|
|
190
|
+
│ ╭────────────────╮ │
|
|
191
|
+
│ │ ✓ Connected │ │
|
|
192
|
+
│ ╰────────────────╯ │
|
|
193
|
+
│ │
|
|
194
|
+
│ ── Features ────────────────────────────────────────────────────────────── │
|
|
195
|
+
│ │
|
|
196
|
+
│ ✅ Create branches from tasks │
|
|
197
|
+
│ ✅ Create issues from tasks │
|
|
198
|
+
│ ✅ Link PRs to tasks │
|
|
199
|
+
│ │
|
|
200
|
+
│ ── Auto-Complete Settings ──────────────────────────────────────────────── │
|
|
201
|
+
│ │
|
|
202
|
+
│ ✅ Auto-complete on PR merge: Enabled │
|
|
203
|
+
│ When a PR with "Closes TX.X" is merged, the task is marked DONE │
|
|
204
|
+
│ │
|
|
205
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
206
|
+
│ │
|
|
207
|
+
│ 💡 Commands: │
|
|
208
|
+
│ • /pfGithubBranch T1.1 Create branch for task │
|
|
209
|
+
│ • /pfGithubIssue T1.1 Create GitHub issue │
|
|
210
|
+
│ • /pfGithubLink autocomplete Toggle auto-complete (on|off) │
|
|
211
|
+
│ • /pfGithubUnlink Disconnect repository │
|
|
212
|
+
│ │
|
|
213
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**If not linked:**
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
220
|
+
│ 🐙 GitHub Integration │
|
|
221
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
222
|
+
│ │
|
|
223
|
+
│ {t.commands.github.notLinked} │
|
|
224
|
+
│ │
|
|
225
|
+
│ No GitHub repository is linked to this project. │
|
|
226
|
+
│ │
|
|
227
|
+
│ ╭────────────────╮ │
|
|
228
|
+
│ │ ○ Not Connected│ │
|
|
229
|
+
│ ╰────────────────╯ │
|
|
230
|
+
│ │
|
|
231
|
+
│ ── Benefits of Linking ─────────────────────────────────────────────────── │
|
|
232
|
+
│ │
|
|
233
|
+
│ • Create feature branches directly from tasks │
|
|
234
|
+
│ • Sync tasks to GitHub Issues │
|
|
235
|
+
│ • Link Pull Requests to tasks │
|
|
236
|
+
│ • Auto-complete tasks when PRs are merged │
|
|
237
|
+
│ │
|
|
238
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
239
|
+
│ │
|
|
240
|
+
│ 💡 To link a repository: │
|
|
241
|
+
│ • /pfGithubLink owner/repo │
|
|
242
|
+
│ │
|
|
243
|
+
│ Example: │
|
|
244
|
+
│ • /pfGithubLink acme/my-project │
|
|
245
|
+
│ │
|
|
246
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Step 4: Link GitHub Repository
|
|
250
|
+
|
|
251
|
+
### 4a: Validate Repository Format
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
const repoRegex = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/
|
|
255
|
+
if (!repoRegex.test(repoArg)) {
|
|
256
|
+
// Show error
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Invalid format error:**
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
264
|
+
│ ❌ ERROR │
|
|
265
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
266
|
+
│ │
|
|
267
|
+
│ {t.commands.github.invalidFormat} │
|
|
268
|
+
│ │
|
|
269
|
+
│ Invalid repository format: {input} │
|
|
270
|
+
│ │
|
|
271
|
+
│ Expected format: owner/repo │
|
|
272
|
+
│ │
|
|
273
|
+
│ Examples: │
|
|
274
|
+
│ • /pfGithubLink microsoft/vscode │
|
|
275
|
+
│ • /pfGithubLink facebook/react │
|
|
276
|
+
│ • /pfGithubLink my-org/my-project │
|
|
277
|
+
│ │
|
|
278
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 4b: Check if Already Linked
|
|
282
|
+
|
|
283
|
+
If project already has a GitHub repo linked:
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
287
|
+
│ ⚠️ WARNING │
|
|
288
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
289
|
+
│ │
|
|
290
|
+
│ {t.commands.github.alreadyLinked} │
|
|
291
|
+
│ │
|
|
292
|
+
│ This project is already linked to: {currentRepo} │
|
|
293
|
+
│ │
|
|
294
|
+
│ To switch repositories: │
|
|
295
|
+
│ 1. /pfGithubUnlink Remove current link │
|
|
296
|
+
│ 2. /pfGithubLink {newRepo} Link new repository │
|
|
297
|
+
│ │
|
|
298
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### 4c: Verify Repository Exists (Optional)
|
|
302
|
+
|
|
303
|
+
If `gh` CLI is available, verify the repository exists:
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
if [ "$GH_AVAILABLE" = true ] && [ "$GH_AUTHENTICATED" = true ]; then
|
|
307
|
+
if ! gh repo view "$OWNER/$REPO" &> /dev/null; then
|
|
308
|
+
echo "Repository not found or inaccessible: $OWNER/$REPO"
|
|
309
|
+
exit 1
|
|
310
|
+
fi
|
|
311
|
+
fi
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 4d: Link Repository via API
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
318
|
+
--connect-timeout 5 \
|
|
319
|
+
--max-time 15 \
|
|
320
|
+
-X POST \
|
|
321
|
+
-H "Content-Type: application/json" \
|
|
322
|
+
-H "Accept: application/json" \
|
|
323
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
324
|
+
-d "{\"owner\": \"$OWNER\", \"repo\": \"$REPO\"}" \
|
|
325
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
326
|
+
|
|
327
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
328
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### 4e: Handle Response
|
|
332
|
+
|
|
333
|
+
**Success (200/201):**
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
337
|
+
│ ✅ SUCCESS │
|
|
338
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
339
|
+
│ │
|
|
340
|
+
│ {t.commands.github.linkSuccess} │
|
|
341
|
+
│ │
|
|
342
|
+
│ ── Repository Linked ───────────────────────────────────────────────────── │
|
|
343
|
+
│ │
|
|
344
|
+
│ 📦 Repository: owner/repo-name │
|
|
345
|
+
│ 🔗 URL: https://github.com/owner/repo-name │
|
|
346
|
+
│ 📁 Project: {projectName} │
|
|
347
|
+
│ │
|
|
348
|
+
│ ╭────────────────╮ │
|
|
349
|
+
│ │ ✓ Connected │ │
|
|
350
|
+
│ ╰────────────────╯ │
|
|
351
|
+
│ │
|
|
352
|
+
│ ── What's Next? ────────────────────────────────────────────────────────── │
|
|
353
|
+
│ │
|
|
354
|
+
│ You can now: │
|
|
355
|
+
│ • Create branches: /pfGithubBranch T1.1 │
|
|
356
|
+
│ • Create issues: /pfGithubIssue T1.1 │
|
|
357
|
+
│ • View status: /pfGithubLink │
|
|
358
|
+
│ │
|
|
359
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
360
|
+
│ │
|
|
361
|
+
│ 💡 Tip: When you merge a PR with "Closes T1.1" in the description, │
|
|
362
|
+
│ the task will automatically be marked as complete! │
|
|
363
|
+
│ │
|
|
364
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
365
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Repository Not Found (404):**
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
372
|
+
│ ❌ ERROR │
|
|
373
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
374
|
+
│ │
|
|
375
|
+
│ {t.commands.github.repoNotFound} │
|
|
376
|
+
│ │
|
|
377
|
+
│ Repository not found: owner/repo │
|
|
378
|
+
│ │
|
|
379
|
+
│ Possible reasons: │
|
|
380
|
+
│ • Repository doesn't exist │
|
|
381
|
+
│ • Repository is private and you don't have access │
|
|
382
|
+
│ • Typo in owner or repository name │
|
|
383
|
+
│ │
|
|
384
|
+
│ 💡 Tip: Check the repository URL in your browser first. │
|
|
385
|
+
│ │
|
|
386
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Permission Denied (403):**
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
393
|
+
│ ❌ ERROR │
|
|
394
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
395
|
+
│ │
|
|
396
|
+
│ {t.commands.github.noPermission} │
|
|
397
|
+
│ │
|
|
398
|
+
│ You don't have permission to link this repository. │
|
|
399
|
+
│ │
|
|
400
|
+
│ To link a GitHub repository, you need: │
|
|
401
|
+
│ • Admin or Editor role in the PlanFlow project │
|
|
402
|
+
│ • Read access to the GitHub repository │
|
|
403
|
+
│ │
|
|
404
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Already Linked to Different Project (409):**
|
|
408
|
+
|
|
409
|
+
```
|
|
410
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
411
|
+
│ ❌ ERROR │
|
|
412
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
413
|
+
│ │
|
|
414
|
+
│ {t.commands.github.repoAlreadyLinked} │
|
|
415
|
+
│ │
|
|
416
|
+
│ This repository is already linked to another project. │
|
|
417
|
+
│ │
|
|
418
|
+
│ Repository: owner/repo │
|
|
419
|
+
│ Linked to: Other Project Name │
|
|
420
|
+
│ │
|
|
421
|
+
│ 💡 A repository can only be linked to one project at a time. │
|
|
422
|
+
│ │
|
|
423
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## Step 5: Toggle Auto-Complete Setting
|
|
427
|
+
|
|
428
|
+
When the user runs `/pfGithubLink autocomplete on` or `/pfGithubLink autocomplete off`:
|
|
429
|
+
|
|
430
|
+
### 5a: Validate Auto-Complete Toggle Value
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
if [[ ! "$ACTION" =~ ^(on|off)$ ]]; then
|
|
434
|
+
echo "❌ {t.github.autoComplete.invalidAction}"
|
|
435
|
+
echo ""
|
|
436
|
+
echo "Usage: /pfGithubLink autocomplete on|off"
|
|
437
|
+
exit 1
|
|
438
|
+
fi
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### 5b: Send PATCH Request to Update Setting
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
toggle_autocomplete() {
|
|
445
|
+
local ENABLED="$1"
|
|
446
|
+
local AUTO_COMPLETE_VALUE="false"
|
|
447
|
+
[ "$ENABLED" = "on" ] && AUTO_COMPLETE_VALUE="true"
|
|
448
|
+
|
|
449
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
450
|
+
--connect-timeout 5 \
|
|
451
|
+
--max-time 15 \
|
|
452
|
+
-X PATCH \
|
|
453
|
+
-H "Content-Type: application/json" \
|
|
454
|
+
-H "Accept: application/json" \
|
|
455
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
456
|
+
-d "{\"autoComplete\": $AUTO_COMPLETE_VALUE}" \
|
|
457
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
458
|
+
|
|
459
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
460
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
461
|
+
|
|
462
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
463
|
+
if [ "$ENABLED" = "on" ]; then
|
|
464
|
+
echo "✅ {t.github.autoComplete.enabled}"
|
|
465
|
+
echo ""
|
|
466
|
+
echo "💡 {t.github.autoComplete.tip}"
|
|
467
|
+
else
|
|
468
|
+
echo "{t.github.autoComplete.disabled}"
|
|
469
|
+
fi
|
|
470
|
+
elif [ "$HTTP_CODE" -eq 401 ]; then
|
|
471
|
+
echo "❌ Authentication failed. Run /pfLogin to refresh."
|
|
472
|
+
elif [ "$HTTP_CODE" -eq 403 ]; then
|
|
473
|
+
echo "❌ Permission denied. You need Editor role or higher."
|
|
474
|
+
elif [ "$HTTP_CODE" -eq 404 ]; then
|
|
475
|
+
echo "❌ GitHub integration not found. Link a repository first with /pfGithubLink owner/repo"
|
|
476
|
+
else
|
|
477
|
+
echo "❌ Failed to update auto-complete setting (HTTP $HTTP_CODE)"
|
|
478
|
+
fi
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### 5c: Display Success Cards
|
|
483
|
+
|
|
484
|
+
**Auto-complete enabled:**
|
|
485
|
+
|
|
486
|
+
```
|
|
487
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
488
|
+
│ ✅ {t.github.autoComplete.enabled} │
|
|
489
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
490
|
+
│ │
|
|
491
|
+
│ {t.github.autoComplete.description} │
|
|
492
|
+
│ │
|
|
493
|
+
│ ╭────────────────╮ │
|
|
494
|
+
│ │ ✓ Enabled │ │
|
|
495
|
+
│ ╰────────────────╯ │
|
|
496
|
+
│ │
|
|
497
|
+
│ 💡 {t.github.autoComplete.tip} │
|
|
498
|
+
│ │
|
|
499
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Auto-complete disabled:**
|
|
503
|
+
|
|
504
|
+
```
|
|
505
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
506
|
+
│ {t.github.autoComplete.disabled} │
|
|
507
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
508
|
+
│ │
|
|
509
|
+
│ Auto-complete on PR merge is now disabled. │
|
|
510
|
+
│ │
|
|
511
|
+
│ ╭────────────────╮ │
|
|
512
|
+
│ │ ○ Disabled │ │
|
|
513
|
+
│ ╰────────────────╯ │
|
|
514
|
+
│ │
|
|
515
|
+
│ 💡 To re-enable: │
|
|
516
|
+
│ • /pfGithubLink autocomplete on │
|
|
517
|
+
│ │
|
|
518
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
## Step 6: Update Local Config (Optional)
|
|
522
|
+
|
|
523
|
+
Store GitHub link info locally for offline reference:
|
|
524
|
+
|
|
525
|
+
```javascript
|
|
526
|
+
// Read current local config
|
|
527
|
+
let localConfig = {}
|
|
528
|
+
try {
|
|
529
|
+
localConfig = JSON.parse(readFile("./.plan-config.json"))
|
|
530
|
+
} catch {}
|
|
531
|
+
|
|
532
|
+
// Add GitHub info
|
|
533
|
+
localConfig.github = {
|
|
534
|
+
owner: owner,
|
|
535
|
+
repo: repo,
|
|
536
|
+
linkedAt: new Date().toISOString()
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Save
|
|
540
|
+
writeFile("./.plan-config.json", JSON.stringify(localConfig, null, 2))
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
## Error Handling
|
|
544
|
+
|
|
545
|
+
### Network Error
|
|
546
|
+
|
|
547
|
+
```
|
|
548
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
549
|
+
│ ❌ ERROR │
|
|
550
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
551
|
+
│ │
|
|
552
|
+
│ Network error. Could not connect to PlanFlow API. │
|
|
553
|
+
│ │
|
|
554
|
+
│ Please check your internet connection and try again. │
|
|
555
|
+
│ │
|
|
556
|
+
│ 💡 To retry: │
|
|
557
|
+
│ • /pfGithubLink owner/repo │
|
|
558
|
+
│ │
|
|
559
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Token Expired (401)
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
566
|
+
│ ❌ ERROR │
|
|
567
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
568
|
+
│ │
|
|
569
|
+
│ Authentication failed. Your session may have expired. │
|
|
570
|
+
│ │
|
|
571
|
+
│ 💡 To re-authenticate: │
|
|
572
|
+
│ • /pfLogin │
|
|
573
|
+
│ │
|
|
574
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
## Translation Keys
|
|
578
|
+
|
|
579
|
+
Add to `locales/en.json` and `locales/ka.json`:
|
|
580
|
+
|
|
581
|
+
```json
|
|
582
|
+
{
|
|
583
|
+
"commands": {
|
|
584
|
+
"github": {
|
|
585
|
+
"title": "GitHub Integration",
|
|
586
|
+
"linkSuccess": "GitHub repository linked successfully!",
|
|
587
|
+
"unlinkSuccess": "GitHub repository unlinked.",
|
|
588
|
+
"notLinked": "No GitHub repository linked.",
|
|
589
|
+
"alreadyLinked": "A GitHub repository is already linked.",
|
|
590
|
+
"invalidFormat": "Invalid repository format.",
|
|
591
|
+
"formatHint": "Use format: owner/repo",
|
|
592
|
+
"repoNotFound": "Repository not found.",
|
|
593
|
+
"noPermission": "You don't have permission to link repositories.",
|
|
594
|
+
"repoAlreadyLinked": "This repository is linked to another project.",
|
|
595
|
+
"repository": "Repository:",
|
|
596
|
+
"url": "URL:",
|
|
597
|
+
"linkedAt": "Linked:",
|
|
598
|
+
"connected": "Connected",
|
|
599
|
+
"notConnected": "Not Connected",
|
|
600
|
+
"features": "Features",
|
|
601
|
+
"featureBranch": "Create branches from tasks",
|
|
602
|
+
"featureIssue": "Create issues from tasks",
|
|
603
|
+
"featurePR": "Link PRs to tasks",
|
|
604
|
+
"featureAutoComplete": "Auto-complete tasks on PR merge",
|
|
605
|
+
"benefits": "Benefits of Linking",
|
|
606
|
+
"benefitBranch": "Create feature branches directly from tasks",
|
|
607
|
+
"benefitIssue": "Sync tasks to GitHub Issues",
|
|
608
|
+
"benefitPR": "Link Pull Requests to tasks",
|
|
609
|
+
"benefitAuto": "Auto-complete tasks when PRs are merged",
|
|
610
|
+
"toLink": "To link a repository:",
|
|
611
|
+
"example": "Example:",
|
|
612
|
+
"tip": "Tip:",
|
|
613
|
+
"autoCompleteTip": "When you merge a PR with \"Closes TX.X\" in the description, the task will automatically be marked as complete!",
|
|
614
|
+
"commands": "Commands:",
|
|
615
|
+
"branchCommand": "Create branch for task",
|
|
616
|
+
"issueCommand": "Create GitHub issue",
|
|
617
|
+
"unlinkCommand": "Disconnect repository",
|
|
618
|
+
"statusCommand": "View integration status"
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Full Bash Implementation
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
#!/bin/bash
|
|
628
|
+
|
|
629
|
+
# Step 0: Load config
|
|
630
|
+
GLOBAL_CONFIG_PATH="$HOME/.config/claude/plan-plugin-config.json"
|
|
631
|
+
LOCAL_CONFIG_PATH="./.plan-config.json"
|
|
632
|
+
|
|
633
|
+
# Read configs and merge
|
|
634
|
+
if [ -f "$GLOBAL_CONFIG_PATH" ]; then
|
|
635
|
+
API_TOKEN=$(jq -r '.cloud.apiToken // empty' "$GLOBAL_CONFIG_PATH")
|
|
636
|
+
API_URL=$(jq -r '.cloud.apiUrl // "https://api.planflow.tools"' "$GLOBAL_CONFIG_PATH")
|
|
637
|
+
fi
|
|
638
|
+
|
|
639
|
+
if [ -f "$LOCAL_CONFIG_PATH" ]; then
|
|
640
|
+
PROJECT_ID=$(jq -r '.cloud.projectId // empty' "$LOCAL_CONFIG_PATH")
|
|
641
|
+
# Local can override global
|
|
642
|
+
LOCAL_TOKEN=$(jq -r '.cloud.apiToken // empty' "$LOCAL_CONFIG_PATH")
|
|
643
|
+
[ -n "$LOCAL_TOKEN" ] && API_TOKEN="$LOCAL_TOKEN"
|
|
644
|
+
fi
|
|
645
|
+
|
|
646
|
+
# Parse arguments
|
|
647
|
+
ARGS="$*"
|
|
648
|
+
|
|
649
|
+
# Validate prerequisites
|
|
650
|
+
if [ -z "$API_TOKEN" ]; then
|
|
651
|
+
echo "❌ Not authenticated. Run /pfLogin first."
|
|
652
|
+
exit 1
|
|
653
|
+
fi
|
|
654
|
+
|
|
655
|
+
if [ -z "$PROJECT_ID" ]; then
|
|
656
|
+
echo "❌ No project linked. Run /pfCloudLink first."
|
|
657
|
+
exit 1
|
|
658
|
+
fi
|
|
659
|
+
|
|
660
|
+
# Check for autocomplete toggle command
|
|
661
|
+
if echo "$ARGS" | grep -qiE '^autocomplete[[:space:]]+(on|off)$'; then
|
|
662
|
+
ACTION=$(echo "$ARGS" | sed -E 's/^autocomplete[[:space:]]+//i' | tr '[:upper:]' '[:lower:]')
|
|
663
|
+
AUTO_COMPLETE_VALUE="false"
|
|
664
|
+
[ "$ACTION" = "on" ] && AUTO_COMPLETE_VALUE="true"
|
|
665
|
+
|
|
666
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
667
|
+
--connect-timeout 5 \
|
|
668
|
+
--max-time 15 \
|
|
669
|
+
-X PATCH \
|
|
670
|
+
-H "Content-Type: application/json" \
|
|
671
|
+
-H "Accept: application/json" \
|
|
672
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
673
|
+
-d "{\"autoComplete\": $AUTO_COMPLETE_VALUE}" \
|
|
674
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
675
|
+
|
|
676
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
677
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
678
|
+
|
|
679
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
680
|
+
if [ "$ACTION" = "on" ]; then
|
|
681
|
+
echo "✅ Auto-complete is now enabled!"
|
|
682
|
+
echo ""
|
|
683
|
+
echo "💡 When a PR with \"Closes T1.1\" is merged, T1.1 will be marked DONE automatically!"
|
|
684
|
+
else
|
|
685
|
+
echo "Auto-complete is now disabled."
|
|
686
|
+
fi
|
|
687
|
+
elif [ "$HTTP_CODE" -eq 401 ]; then
|
|
688
|
+
echo "❌ Authentication failed. Run /pfLogin to refresh."
|
|
689
|
+
elif [ "$HTTP_CODE" -eq 403 ]; then
|
|
690
|
+
echo "❌ Permission denied. You need Editor role or higher."
|
|
691
|
+
elif [ "$HTTP_CODE" -eq 404 ]; then
|
|
692
|
+
echo "❌ GitHub integration not found. Link a repository first."
|
|
693
|
+
else
|
|
694
|
+
echo "❌ Failed to update auto-complete setting (HTTP $HTTP_CODE)"
|
|
695
|
+
fi
|
|
696
|
+
exit 0
|
|
697
|
+
fi
|
|
698
|
+
|
|
699
|
+
REPO_ARG="$1"
|
|
700
|
+
|
|
701
|
+
# If no argument, show status
|
|
702
|
+
if [ -z "$REPO_ARG" ]; then
|
|
703
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
704
|
+
--connect-timeout 5 \
|
|
705
|
+
--max-time 10 \
|
|
706
|
+
-X GET \
|
|
707
|
+
-H "Accept: application/json" \
|
|
708
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
709
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
710
|
+
|
|
711
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
712
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
713
|
+
|
|
714
|
+
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
715
|
+
OWNER=$(echo "$BODY" | jq -r '.data.owner // empty')
|
|
716
|
+
REPO=$(echo "$BODY" | jq -r '.data.repo // empty')
|
|
717
|
+
|
|
718
|
+
if [ -n "$OWNER" ] && [ -n "$REPO" ]; then
|
|
719
|
+
AUTO_COMPLETE=$(echo "$BODY" | jq -r '.data.autoComplete // false')
|
|
720
|
+
echo "🐙 GitHub Integration"
|
|
721
|
+
echo ""
|
|
722
|
+
echo " Repository: $OWNER/$REPO"
|
|
723
|
+
echo " URL: https://github.com/$OWNER/$REPO"
|
|
724
|
+
echo " Status: ✓ Connected"
|
|
725
|
+
echo ""
|
|
726
|
+
if [ "$AUTO_COMPLETE" = "true" ]; then
|
|
727
|
+
echo " ✅ Auto-complete on PR merge: Enabled"
|
|
728
|
+
else
|
|
729
|
+
echo " ○ Auto-complete on PR merge: Disabled"
|
|
730
|
+
fi
|
|
731
|
+
else
|
|
732
|
+
echo "🐙 GitHub Integration"
|
|
733
|
+
echo ""
|
|
734
|
+
echo " Status: ○ Not Connected"
|
|
735
|
+
echo ""
|
|
736
|
+
echo " To link: /pfGithubLink owner/repo"
|
|
737
|
+
fi
|
|
738
|
+
else
|
|
739
|
+
echo "🐙 GitHub Integration"
|
|
740
|
+
echo ""
|
|
741
|
+
echo " Status: ○ Not Connected"
|
|
742
|
+
echo ""
|
|
743
|
+
echo " To link: /pfGithubLink owner/repo"
|
|
744
|
+
fi
|
|
745
|
+
exit 0
|
|
746
|
+
fi
|
|
747
|
+
|
|
748
|
+
# Validate repo format
|
|
749
|
+
if ! echo "$REPO_ARG" | grep -qE '^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$'; then
|
|
750
|
+
echo "❌ Invalid format: $REPO_ARG"
|
|
751
|
+
echo ""
|
|
752
|
+
echo "Expected: owner/repo"
|
|
753
|
+
echo "Example: /pfGithubLink microsoft/vscode"
|
|
754
|
+
exit 1
|
|
755
|
+
fi
|
|
756
|
+
|
|
757
|
+
# Extract owner and repo
|
|
758
|
+
OWNER=$(echo "$REPO_ARG" | cut -d'/' -f1)
|
|
759
|
+
REPO=$(echo "$REPO_ARG" | cut -d'/' -f2)
|
|
760
|
+
|
|
761
|
+
# Link repository
|
|
762
|
+
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
763
|
+
--connect-timeout 5 \
|
|
764
|
+
--max-time 15 \
|
|
765
|
+
-X POST \
|
|
766
|
+
-H "Content-Type: application/json" \
|
|
767
|
+
-H "Accept: application/json" \
|
|
768
|
+
-H "Authorization: Bearer $API_TOKEN" \
|
|
769
|
+
-d "{\"owner\": \"$OWNER\", \"repo\": \"$REPO\"}" \
|
|
770
|
+
"${API_URL}/projects/${PROJECT_ID}/integrations/github")
|
|
771
|
+
|
|
772
|
+
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
|
773
|
+
BODY=$(echo "$RESPONSE" | sed '$d')
|
|
774
|
+
|
|
775
|
+
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
|
776
|
+
echo "✅ GitHub repository linked!"
|
|
777
|
+
echo ""
|
|
778
|
+
echo " Repository: $OWNER/$REPO"
|
|
779
|
+
echo " URL: https://github.com/$OWNER/$REPO"
|
|
780
|
+
echo ""
|
|
781
|
+
echo " You can now:"
|
|
782
|
+
echo " • /pfGithubBranch T1.1 - Create branch"
|
|
783
|
+
echo " • /pfGithubIssue T1.1 - Create issue"
|
|
784
|
+
elif [ "$HTTP_CODE" -eq 404 ]; then
|
|
785
|
+
echo "❌ Repository not found: $OWNER/$REPO"
|
|
786
|
+
elif [ "$HTTP_CODE" -eq 401 ]; then
|
|
787
|
+
echo "❌ Authentication failed. Run /pfLogin to refresh."
|
|
788
|
+
elif [ "$HTTP_CODE" -eq 403 ]; then
|
|
789
|
+
echo "❌ Permission denied. You need Editor role or higher."
|
|
790
|
+
elif [ "$HTTP_CODE" -eq 409 ]; then
|
|
791
|
+
echo "❌ This repository is already linked to another project."
|
|
792
|
+
else
|
|
793
|
+
echo "❌ Failed to link repository (HTTP $HTTP_CODE)"
|
|
794
|
+
echo "$BODY"
|
|
795
|
+
fi
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
## Testing
|
|
799
|
+
|
|
800
|
+
```bash
|
|
801
|
+
# Test 1: Show status (not linked)
|
|
802
|
+
/pfGithubLink
|
|
803
|
+
# Expected: Shows "Not Connected" status
|
|
804
|
+
|
|
805
|
+
# Test 2: Link repository
|
|
806
|
+
/pfGithubLink microsoft/vscode
|
|
807
|
+
# Expected: Success message with repo details
|
|
808
|
+
|
|
809
|
+
# Test 3: Show status (linked)
|
|
810
|
+
/pfGithubLink
|
|
811
|
+
# Expected: Shows connected repository details with auto-complete status
|
|
812
|
+
|
|
813
|
+
# Test 4: Invalid format
|
|
814
|
+
/pfGithubLink invalid-format
|
|
815
|
+
# Expected: Error with format hint
|
|
816
|
+
|
|
817
|
+
# Test 5: Repo not found
|
|
818
|
+
/pfGithubLink nonexistent/nonexistent-repo-12345
|
|
819
|
+
# Expected: Error "Repository not found"
|
|
820
|
+
|
|
821
|
+
# Test 6: Not authenticated
|
|
822
|
+
# (Clear token first)
|
|
823
|
+
/pfGithubLink owner/repo
|
|
824
|
+
# Expected: Error "Not authenticated"
|
|
825
|
+
|
|
826
|
+
# Test 7: No project linked
|
|
827
|
+
# (Clear projectId first)
|
|
828
|
+
/pfGithubLink owner/repo
|
|
829
|
+
# Expected: Error "No project linked"
|
|
830
|
+
|
|
831
|
+
# Test 8: Enable auto-complete
|
|
832
|
+
/pfGithubLink autocomplete on
|
|
833
|
+
# Expected: "✅ Auto-complete is now enabled!"
|
|
834
|
+
|
|
835
|
+
# Test 9: Disable auto-complete
|
|
836
|
+
/pfGithubLink autocomplete off
|
|
837
|
+
# Expected: "Auto-complete is now disabled."
|
|
838
|
+
|
|
839
|
+
# Test 10: Show status (verify auto-complete setting)
|
|
840
|
+
/pfGithubLink
|
|
841
|
+
# Expected: Shows "✅ Auto-complete on PR merge: Enabled" or "○ Auto-complete on PR merge: Disabled"
|
|
842
|
+
|
|
843
|
+
# Test 11: Invalid autocomplete argument
|
|
844
|
+
/pfGithubLink autocomplete maybe
|
|
845
|
+
# Expected: Error with usage hint
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
## Success Criteria
|
|
849
|
+
|
|
850
|
+
- [ ] Shows current GitHub link status when no arguments
|
|
851
|
+
- [ ] Links GitHub repository with owner/repo format
|
|
852
|
+
- [ ] Validates repository format before API call
|
|
853
|
+
- [ ] Handles all error cases gracefully
|
|
854
|
+
- [ ] Updates local config with GitHub info
|
|
855
|
+
- [ ] Shows helpful next steps after linking
|
|
856
|
+
- [ ] Works in both English and Georgian
|
|
857
|
+
- [ ] `/pfGithubLink autocomplete on` enables auto-complete
|
|
858
|
+
- [ ] `/pfGithubLink autocomplete off` disables auto-complete
|
|
859
|
+
- [ ] Status display shows auto-complete setting
|