taip-connect 0.5.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/README.md +11 -0
- package/bin/connect.js +8994 -0
- package/package.json +19 -0
- package/packs/process/skills/taip-workflow-acceptance-testing/SKILL.md +159 -0
- package/packs/process/skills/taip-workflow-git-init/SKILL.md +131 -0
- package/packs/process/skills/taip-workflow-git-pr/SKILL.md +113 -0
- package/packs/process/skills/taip-workflow-plane-init/SKILL.md +188 -0
- package/packs/process/skills/taip-workflow-plane-task/SKILL.md +356 -0
- package/packs/process/skills/taip-workflow-planning/SKILL.md +159 -0
- package/packs/process/skills/taip-workflow-release/SKILL.md +134 -0
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "taip-connect",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "taip-connect — wire the hosted taip brain + context + taip-tools MCP servers into Claude Code (VS Code).",
|
|
5
|
+
"bin": {
|
|
6
|
+
"taip-connect": "bin/connect.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"packs/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
},
|
|
17
|
+
"license": "UNLICENSED",
|
|
18
|
+
"repository": "github:taip-ai/taip-agent"
|
|
19
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/skills/taip-workflow-acceptance-testing
|
|
3
|
+
version: 1.0.1
|
|
4
|
+
trigger: "acceptance testing|run AT|acceptance test|sign off|ready for done|hotfix AT"
|
|
5
|
+
description: >
|
|
6
|
+
Runs acceptance testing against a plan's acceptance criteria or a PM tool's ticket list.
|
|
7
|
+
Walks each Given-When-Then AC, records Pass/Fail/Blocked, generates an AT report,
|
|
8
|
+
writes it to docs/tests/, updates the traceability matrix, and gates completion on sign-off.
|
|
9
|
+
If a PM tool binding (Plane/Jira) is active, also posts the report as a ticket comment
|
|
10
|
+
and gates the tool's "Done" transition. Works offline with no PM tool.
|
|
11
|
+
user-invocable: true
|
|
12
|
+
tags: [acceptance-testing, qa, verification, process]
|
|
13
|
+
attribution:
|
|
14
|
+
source: original
|
|
15
|
+
license: brain-official
|
|
16
|
+
author: brain Official
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# taip-workflow-acceptance-testing
|
|
20
|
+
|
|
21
|
+
Acceptance testing gate: load ACs → walk each → record results → write report → update traceability → gate sign-off.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step 1 — Determine scope
|
|
26
|
+
|
|
27
|
+
Ask in one message if not already provided:
|
|
28
|
+
|
|
29
|
+
1. **Scope:** Plan file path (e.g. `docs/plans/2026-06-12-slug.md`) OR ticket key(s) if a PM tool is active
|
|
30
|
+
2. **Hotfix?** Yes / No — if yes, all ACs must pass before going live
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 2 — Load acceptance criteria
|
|
35
|
+
|
|
36
|
+
**Path A — from plan file (default, no tool needed):**
|
|
37
|
+
|
|
38
|
+
1. Read the plan file's `## Acceptance Tests` table
|
|
39
|
+
2. If the table is empty or has no rows with `Given/When/Then`: stop and tell the user:
|
|
40
|
+
> "No acceptance criteria found in `## Acceptance Tests`. Please add Given/When/Then rows before running AT."
|
|
41
|
+
3. Also load any linked `docs/tests/<slug>-acceptance.md` for full test case scenarios
|
|
42
|
+
|
|
43
|
+
**Path B — from PM tool (if active):**
|
|
44
|
+
|
|
45
|
+
1. Fetch tickets in `Acceptance Testing` or `System Testing` state for the scope
|
|
46
|
+
2. Parse each ticket's `## Acceptance Criteria` section for Given/When/Then lines
|
|
47
|
+
3. If a ticket has no `## Acceptance Criteria`: skip it and warn the user
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Step 3 — Walk each AC and record result
|
|
52
|
+
|
|
53
|
+
For each AC, display:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
───────────────────────────────────
|
|
57
|
+
AC{N}: Given {precondition}, when {action}, then {expected outcome}.
|
|
58
|
+
───────────────────────────────────
|
|
59
|
+
Result? [Pass / Fail / Blocked] Notes (optional):
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
WAIT for the user's result before moving to the next AC.
|
|
63
|
+
|
|
64
|
+
Build a results table:
|
|
65
|
+
|
|
66
|
+
| AC | Criterion (short) | Result | Notes |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| AC1 | Given … then … | ✅ Pass | — |
|
|
69
|
+
| AC2 | Given … then … | ❌ Fail | {notes} |
|
|
70
|
+
|
|
71
|
+
**Overall verdict:**
|
|
72
|
+
- **PASS** — all ACs pass
|
|
73
|
+
- **FAIL** — one or more ACs fail or are blocked
|
|
74
|
+
|
|
75
|
+
MUST NOT skip or estimate AC results — every AC must be explicitly recorded.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Step 4 — Generate AT report
|
|
80
|
+
|
|
81
|
+
**Report filename:** `docs/tests/AT-<DDMMYYYY>-<scope-slug>.md`
|
|
82
|
+
|
|
83
|
+
Get today's date: `date +%d%m%Y`
|
|
84
|
+
|
|
85
|
+
**Report template:**
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
# Acceptance Test Report — {scope}
|
|
89
|
+
|
|
90
|
+
**Date:** {DD Month YYYY}
|
|
91
|
+
**Tester:** {user name}
|
|
92
|
+
**Type:** {Regular / Hotfix}
|
|
93
|
+
**Scope:** {plan file or ticket keys}
|
|
94
|
+
|
|
95
|
+
## Summary
|
|
96
|
+
|
|
97
|
+
| Metric | Value |
|
|
98
|
+
|---|---|
|
|
99
|
+
| ACs tested | {N} |
|
|
100
|
+
| PASS | {N} |
|
|
101
|
+
| FAIL | {N} |
|
|
102
|
+
| Overall verdict | ✅ ALL PASS / ❌ FAILURES PRESENT |
|
|
103
|
+
|
|
104
|
+
{If hotfix:}
|
|
105
|
+
> ⚠ **Hotfix** — all ACs MUST pass. Live release: {BLOCKED / APPROVED}.
|
|
106
|
+
|
|
107
|
+
## Results
|
|
108
|
+
|
|
109
|
+
| AC | Criterion | Result | Notes |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| AC1 | Given … then … | ✅ Pass | — |
|
|
112
|
+
|
|
113
|
+
## Sign-off
|
|
114
|
+
|
|
115
|
+
- [ ] Sign-off: _____________________ Date: ___________
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Write the report to `docs/tests/AT-<DDMMYYYY>-<scope-slug>.md`.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Step 5 — Update traceability matrix
|
|
123
|
+
|
|
124
|
+
Update `docs/traceability-matrix.md`:
|
|
125
|
+
- Add or update the row(s) linking the plan → this AT report
|
|
126
|
+
- Format: `[AT-DDMMYYYY-scope](tests/AT-DDMMYYYY-scope.md)`
|
|
127
|
+
|
|
128
|
+
If `docs/traceability-matrix.md` does not exist: create it from the traceability matrix template.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Step 6 — PM tool sync (only if a tool binding is active)
|
|
133
|
+
|
|
134
|
+
**If Plane or Jira is configured:**
|
|
135
|
+
|
|
136
|
+
For each ticket in scope:
|
|
137
|
+
1. Post the AT report as a comment on the ticket
|
|
138
|
+
2. Comment MUST include: report link, overall verdict, AC table, next step
|
|
139
|
+
|
|
140
|
+
**If PASS:** ask "Has the tester/QM signed off on {ticket}? (Y/N)"
|
|
141
|
+
- Yes → transition ticket to **Done**
|
|
142
|
+
- No → print "Waiting for sign-off. Transition manually when approved."
|
|
143
|
+
|
|
144
|
+
**If FAIL:** do NOT transition. Print:
|
|
145
|
+
> "❌ {ticket} — FAIL. Return to developer. Ticket stays in Acceptance Testing."
|
|
146
|
+
|
|
147
|
+
**If no PM tool:** skip this step. Sign-off is recorded in the report file and traceability matrix.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Hard fails
|
|
152
|
+
|
|
153
|
+
- MUST NOT mark a task complete without writing the AT report to `docs/tests/`
|
|
154
|
+
- MUST NOT mark a task complete without updating `docs/traceability-matrix.md`
|
|
155
|
+
- MUST NOT skip or estimate any AC — record every one as Pass / Fail / Blocked
|
|
156
|
+
- MUST NOT transition a PM ticket to Done if any AC is Fail or Blocked
|
|
157
|
+
- MUST NOT transition a PM ticket to Done without explicit sign-off confirmation from user
|
|
158
|
+
- MUST NOT transition a PM ticket to Done without posting a comment first (if tool active)
|
|
159
|
+
- For hotfix: MUST print live release BLOCKED message if any AC failed
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/git/git-init
|
|
3
|
+
version: 1.1.0
|
|
4
|
+
trigger: "init git|setup git|initialize repo|git setup|setup branches|init branches"
|
|
5
|
+
description: >
|
|
6
|
+
Bootstraps a repo with the main/develop branch model. Checks pre-conditions,
|
|
7
|
+
creates develop from main if missing, pushes both branches to the remote,
|
|
8
|
+
emits a CLAUDE.md snippet, and optionally sets GitHub branch protection.
|
|
9
|
+
user-invocable: true
|
|
10
|
+
tags: [git, branching, workflow, init]
|
|
11
|
+
attribution:
|
|
12
|
+
source: original
|
|
13
|
+
license: brain-official
|
|
14
|
+
author: brain Official
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# taip-workflow-git-init
|
|
18
|
+
|
|
19
|
+
Set up the main/develop branch model in a repo. Run once on a new repo or to
|
|
20
|
+
align an existing repo to the strategy defined in `process/git/branch-strategy`.
|
|
21
|
+
|
|
22
|
+
## Pre-conditions
|
|
23
|
+
|
|
24
|
+
**Check 1 — Git repo:**
|
|
25
|
+
```bash
|
|
26
|
+
git rev-parse --git-dir
|
|
27
|
+
```
|
|
28
|
+
If not a git repo: stop and tell the user to run `git init` first.
|
|
29
|
+
|
|
30
|
+
**Check 2 — At least one commit:**
|
|
31
|
+
```bash
|
|
32
|
+
git log --oneline -1
|
|
33
|
+
```
|
|
34
|
+
If empty repo: stop and tell the user to make an initial commit first.
|
|
35
|
+
|
|
36
|
+
**Check 3 — Remote configured (info only):**
|
|
37
|
+
```bash
|
|
38
|
+
git remote -v
|
|
39
|
+
```
|
|
40
|
+
If no remote: warn that branches will be created locally only. Continue.
|
|
41
|
+
|
|
42
|
+
**Check 4 — Current branch:**
|
|
43
|
+
Note the current branch name. If it is `master`, ask: "This repo uses `master`. Rename
|
|
44
|
+
to `main`? (Y / keep master)" — proceed based on answer. If it is already `main`, continue.
|
|
45
|
+
|
|
46
|
+
## Step 1 — Ensure main exists
|
|
47
|
+
|
|
48
|
+
If current branch is `master` and user confirmed rename:
|
|
49
|
+
```bash
|
|
50
|
+
git branch -m master main
|
|
51
|
+
git push origin main --force-with-lease # only if a remote is configured
|
|
52
|
+
git push origin --delete master # only if remote master exists
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If current branch is already `main` or another name: skip.
|
|
56
|
+
|
|
57
|
+
## Step 2 — Create develop
|
|
58
|
+
|
|
59
|
+
Check if `develop` already exists:
|
|
60
|
+
```bash
|
|
61
|
+
git branch --list develop
|
|
62
|
+
git branch -r --list origin/develop
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If `develop` does not exist locally:
|
|
66
|
+
```bash
|
|
67
|
+
git checkout -b develop
|
|
68
|
+
git checkout - # return to previous branch
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If `develop` already exists locally: skip creation, report "develop already exists".
|
|
72
|
+
|
|
73
|
+
## Step 3 — Push both branches to remote
|
|
74
|
+
|
|
75
|
+
Only if a remote is configured:
|
|
76
|
+
```bash
|
|
77
|
+
git push -u origin main
|
|
78
|
+
git push -u origin develop
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If push fails due to no remote: skip silently (already warned in pre-conditions).
|
|
82
|
+
|
|
83
|
+
## Step 4 — Emit CLAUDE.md snippet
|
|
84
|
+
|
|
85
|
+
Output this block to stdout so the user can paste it into their project's CLAUDE.md:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
## Branch model
|
|
89
|
+
|
|
90
|
+
| Branch | Role |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `main` | Production-stable — receives merges from `develop` at release time |
|
|
93
|
+
| `develop` | Integration branch — all feature and fix PRs target this |
|
|
94
|
+
| `feature/{slug}-{sequence_id}` | Task branches (from Plane issues) |
|
|
95
|
+
| `fix/{slug}` | Hotfix branches |
|
|
96
|
+
|
|
97
|
+
PRs: feature/* and fix/* → develop. develop → main at release only.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Step 5 — Optional GitHub branch protection (if GitHub remote detected)
|
|
101
|
+
|
|
102
|
+
Check for GitHub remote:
|
|
103
|
+
```bash
|
|
104
|
+
git remote get-url origin | grep github.com
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
If GitHub remote found, ask: "Configure branch protection for main and develop via gh CLI? (Y / n)"
|
|
108
|
+
|
|
109
|
+
On Y:
|
|
110
|
+
```bash
|
|
111
|
+
gh api repos/{owner}/{repo}/branches/main/protection \
|
|
112
|
+
--method PUT \
|
|
113
|
+
--input - <<'EOF'
|
|
114
|
+
{"required_status_checks":null,"enforce_admins":false,"required_pull_request_reviews":{"required_approving_review_count":0},"restrictions":null}
|
|
115
|
+
EOF
|
|
116
|
+
|
|
117
|
+
gh api repos/{owner}/{repo}/branches/develop/protection \
|
|
118
|
+
--method PUT \
|
|
119
|
+
--input - <<'EOF'
|
|
120
|
+
{"required_status_checks":null,"enforce_admins":false,"required_pull_request_reviews":{"required_approving_review_count":0},"restrictions":null}
|
|
121
|
+
EOF
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Report success or any error from the API.
|
|
125
|
+
|
|
126
|
+
## Rules
|
|
127
|
+
|
|
128
|
+
- MUST NOT force-push `main` unless the user explicitly confirmed the `master` → `main` rename
|
|
129
|
+
- MUST NOT delete any remote branch without explicit user confirmation
|
|
130
|
+
- MUST report clearly what was created vs what already existed (idempotent output)
|
|
131
|
+
- If `develop` already exists: skip creation silently and confirm it's on the remote
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/git/pr-creation
|
|
3
|
+
version: 1.1.0
|
|
4
|
+
trigger: "create pr|make pr|open pull request|submit pr|raise pr"
|
|
5
|
+
description: >
|
|
6
|
+
Creates a pull request with pre-flight checks. Verifies branch state, generates
|
|
7
|
+
a conventional PR title and description, references the plan file if one exists,
|
|
8
|
+
and outputs the PR link. Use when user says "create a PR", "open a pull request",
|
|
9
|
+
or "submit my changes".
|
|
10
|
+
user-invocable: true
|
|
11
|
+
tags: [git, pr, workflow]
|
|
12
|
+
attribution:
|
|
13
|
+
source: original
|
|
14
|
+
license: brain-official
|
|
15
|
+
author: brain Official
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# taip-workflow-git-pr
|
|
19
|
+
|
|
20
|
+
PR creation: pre-flight → draft PR → confirm → create.
|
|
21
|
+
|
|
22
|
+
## Pre-conditions
|
|
23
|
+
|
|
24
|
+
**Check 1 — Not on main/master/develop:**
|
|
25
|
+
Verify current branch is NOT `main`, `master`, or `develop`. If it is: stop and ask the user to switch to a feature or fix branch.
|
|
26
|
+
|
|
27
|
+
**Check 2 — Uncommitted changes:**
|
|
28
|
+
If `git status` shows uncommitted changes: stop and ask the user to commit or stash first.
|
|
29
|
+
|
|
30
|
+
**Check 3 — CI status:**
|
|
31
|
+
Check if CI is passing on the current branch. Warn if CI status cannot be determined.
|
|
32
|
+
|
|
33
|
+
## Step 1 — Gather info
|
|
34
|
+
|
|
35
|
+
Detect the base branch (default `develop`, fallback to `main` or `master` if `develop` does not exist):
|
|
36
|
+
```bash
|
|
37
|
+
BASE=$(git branch -r | grep -E 'origin/(develop|main|master)' | sed 's|.*origin/||' | head -1)
|
|
38
|
+
BASE=${BASE:-main}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Run:
|
|
42
|
+
```bash
|
|
43
|
+
git log --oneline $(git merge-base HEAD $BASE)..HEAD
|
|
44
|
+
git diff $(git merge-base HEAD $BASE)..HEAD --stat
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Check for a plan file: `ls docs/plans/*.md` sorted by date — use the most recent one if it exists.
|
|
48
|
+
|
|
49
|
+
## Step 2 — Draft PR
|
|
50
|
+
|
|
51
|
+
Generate:
|
|
52
|
+
- **Title**: conventional, ≤ 70 chars, derived from commits or task description
|
|
53
|
+
- **Body**: summary of what changed + why, plan reference if found, verification checklist
|
|
54
|
+
|
|
55
|
+
Template:
|
|
56
|
+
```markdown
|
|
57
|
+
## Summary
|
|
58
|
+
<2-4 bullet points of what changed>
|
|
59
|
+
|
|
60
|
+
## Plan
|
|
61
|
+
<link to docs/plans/YYYY-MM-DD-slug.md if found>
|
|
62
|
+
|
|
63
|
+
## Verification
|
|
64
|
+
- [ ] Tests pass
|
|
65
|
+
- [ ] Smoke check
|
|
66
|
+
- [ ] No secrets committed (git log --all --full-history -- "**/secrets/**")
|
|
67
|
+
|
|
68
|
+
🤖 Generated with [brain taip-workflow-git-pr](https://taip.is)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Show the draft and ask: "Create PR with this title and description? (Y / edit)"
|
|
72
|
+
|
|
73
|
+
## Step 3 — Create PR (via the GitHub MCP tool)
|
|
74
|
+
|
|
75
|
+
On confirmation, open the PR through the **`github` MCP tool** — do **NOT** shell out to `gh`
|
|
76
|
+
(it is absent from the hosted/agent images and fails on SSH-only remotes).
|
|
77
|
+
|
|
78
|
+
**a. Derive the PR coordinates:**
|
|
79
|
+
```bash
|
|
80
|
+
ORIGIN=$(git remote get-url origin)
|
|
81
|
+
# Strip the git@host: / https://host/ prefix and any trailing .git → owner/repo
|
|
82
|
+
SLUG=$(printf '%s' "$ORIGIN" | sed -E 's#^(git@[^:]+:|https?://[^/]+/)##; s#\.git$##')
|
|
83
|
+
OWNER=${SLUG%%/*}; REPO=${SLUG##*/}
|
|
84
|
+
OWNER=${OWNER:-taip-ai} # default org
|
|
85
|
+
HEAD=$(git rev-parse --abbrev-ref HEAD) # current feature branch
|
|
86
|
+
# BASE resolved in Step 1 (default develop)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**b. Ensure HEAD is pushed** (GitHub needs the branch to exist on the remote):
|
|
90
|
+
```bash
|
|
91
|
+
git push -u origin "$HEAD"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**c. Call `create_pull_request`** — tool id `mcp__github__create_pull_request` in Claude Code
|
|
95
|
+
(`github__create_pull_request` behind the taip-tools proxy) with:
|
|
96
|
+
```json
|
|
97
|
+
{ "owner": "$OWNER", "repo": "$REPO", "base": "$BASE", "head": "$HEAD",
|
|
98
|
+
"title": "<title>", "body": "<body>" }
|
|
99
|
+
```
|
|
100
|
+
Print the returned `html_url`.
|
|
101
|
+
|
|
102
|
+
**d. Fallback** — if the `github` tool is unavailable or `create_pull_request` errors, print the
|
|
103
|
+
compare link so the user can open the PR manually, plus the drafted title and body:
|
|
104
|
+
```
|
|
105
|
+
https://github.com/$OWNER/$REPO/compare/$BASE...$HEAD?expand=1
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Rules
|
|
109
|
+
|
|
110
|
+
- MUST NOT create PR while on main/master
|
|
111
|
+
- MUST NOT create PR with uncommitted changes
|
|
112
|
+
- MUST NOT shell out to `gh` — open PRs via the `github` MCP tool (`create_pull_request`)
|
|
113
|
+
- PR description MUST include verification checklist
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/skills/taip-workflow-plane-init
|
|
3
|
+
version: 2.0.1
|
|
4
|
+
trigger: "plane init|plane setup|init plane|setup plane|setup plane projects|create plane projects|deploy sprint runner|sprint runner setup"
|
|
5
|
+
description: >
|
|
6
|
+
Full bootstrap for the Plane + n8n sprint runner stack. Covers: deploy n8n and sprint
|
|
7
|
+
scripts to fridholmi, verify Plane API, create missing projects (with sprint label +
|
|
8
|
+
initial cycle), write SPRINT_PROJECTS into n8n config, restart n8n. Runs end-to-end
|
|
9
|
+
without manual steps. Requires: SSH access to fridholmi, plane_api_token in secrets.
|
|
10
|
+
user-invocable: true
|
|
11
|
+
tags: [plane, project-management, setup, sprint, n8n, init, deploy]
|
|
12
|
+
attribution:
|
|
13
|
+
source: original
|
|
14
|
+
license: brain-official
|
|
15
|
+
author: brain Official
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# taip-workflow-plane-init
|
|
19
|
+
|
|
20
|
+
Full Plane + sprint runner bootstrap. Zero manual steps.
|
|
21
|
+
|
|
22
|
+
Reference files (all in `fh-smarthome-docker`):
|
|
23
|
+
- `openclaw/sprint/projects.json` — repo ↔ Plane project mapping
|
|
24
|
+
- `openclaw/sprint/setup-plane-projects.sh` — project creation script
|
|
25
|
+
- `ansible/deploy-n8n-sprint.sh` — n8n + sprint deploy script
|
|
26
|
+
- `n8n/docker-compose.yml` — n8n service config
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 1 — Read current config
|
|
31
|
+
|
|
32
|
+
Read `openclaw/sprint/projects.json`. Confirm:
|
|
33
|
+
- `plane_api_url` is set
|
|
34
|
+
- At least one project entry exists with `workspace_slug`, `name`, `identifier`, `repo`
|
|
35
|
+
|
|
36
|
+
If `default_workspace_slug` is missing, ask for the primary Plane workspace slug.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Step 2 — Check Plane API token
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ls -la openclaw/secrets/local/plane_api_token 2>/dev/null && wc -c openclaw/secrets/local/plane_api_token
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If missing or empty:
|
|
47
|
+
- Ask: "Paste your Plane API token (Profile → API Tokens in the Plane UI):"
|
|
48
|
+
- Write it: `echo "<token>" > openclaw/secrets/local/plane_api_token && chmod 0600 openclaw/secrets/local/plane_api_token`
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Step 3 — Check if n8n is deployed on the server
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
ssh fridholmi "docker ps --filter name=fridholmit_n8n --format '{{.Names}}\t{{.Status}}' 2>/dev/null || echo 'not running'"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**If n8n is already running:** skip to Step 5.
|
|
59
|
+
|
|
60
|
+
**If n8n is not running:** check if the deploy directory exists:
|
|
61
|
+
```bash
|
|
62
|
+
ssh fridholmi "ls ~/fh-sprint/n8n/docker-compose.yml 2>/dev/null && echo 'deployed' || echo 'not deployed'"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Step 4 — Deploy n8n + sprint runner (if needed)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
bash openclaw/sprint/deploy-n8n-sprint.sh --host fridholmi --start
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Wait for confirmation that n8n started:
|
|
74
|
+
```bash
|
|
75
|
+
ssh fridholmi "docker ps --filter name=fridholmit_n8n --format '{{.Names}}\t{{.Status}}'"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If n8n fails to start, check logs:
|
|
79
|
+
```bash
|
|
80
|
+
ssh fridholmi "docker logs fridholmit_n8n --tail=30"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Step 5 — Verify Plane API connectivity
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
TOKEN=$(cat openclaw/secrets/local/plane_api_token)
|
|
89
|
+
PLANE_URL=$(python3 -c "import json; d=json.load(open('openclaw/sprint/projects.json')); print(d['plane_api_url'])")
|
|
90
|
+
curl -sf "${PLANE_URL}/api/v1/users/me/" -H "X-Api-Key: ${TOKEN}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Authenticated as:', d.get('email'))"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Note: Plane 1.3.x `/api/v1/workspaces/` returns 404 — use `/api/v1/users/me/` to verify.
|
|
94
|
+
|
|
95
|
+
If this fails:
|
|
96
|
+
- 401: wrong token → go back to Step 2
|
|
97
|
+
- Connection refused: Plane is down → `ssh fridholmi "docker ps --filter name=plane"`
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Step 6 — Create missing Plane projects (dry-run first)
|
|
102
|
+
|
|
103
|
+
Copy the setup script to fridholmi if not already there:
|
|
104
|
+
```bash
|
|
105
|
+
rsync -av openclaw/sprint/setup-plane-projects.sh openclaw/sprint/projects.json \
|
|
106
|
+
fridholmi:~/fh-sprint/openclaw/sprint/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run dry-run on the server:
|
|
110
|
+
```bash
|
|
111
|
+
ssh fridholmi "cd ~/fh-sprint && bash openclaw/sprint/setup-plane-projects.sh --dry-run"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Show output to user. Ask: "Create these projects? (Y/N)"
|
|
115
|
+
|
|
116
|
+
WAIT for confirmation.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Step 7 — Create projects + update n8n config
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
ssh fridholmi "cd ~/fh-sprint && bash openclaw/sprint/setup-plane-projects.sh --update-compose"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This:
|
|
127
|
+
1. Creates missing Plane projects via REST API
|
|
128
|
+
2. Creates the `ai-task` sprint label in each new project
|
|
129
|
+
3. Creates "Sprint 1" cycle (today → +14 days)
|
|
130
|
+
4. Writes `SPRINT_PROJECTS` into `~/fh-sprint/n8n/docker-compose.yml`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Step 8 — Restart n8n to pick up SPRINT_PROJECTS
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ssh fridholmi "cd ~/fh-sprint && docker compose --project-directory . -f n8n/docker-compose.yml --env-file .env up -d"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Verify:
|
|
141
|
+
```bash
|
|
142
|
+
ssh fridholmi "docker ps --filter name=fridholmit_n8n --format '{{.Names}}\t{{.Status}}'"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Step 9 — Set TELEGRAM_CHAT_ID (if not set)
|
|
148
|
+
|
|
149
|
+
Check if it's configured:
|
|
150
|
+
```bash
|
|
151
|
+
ssh fridholmi "grep TELEGRAM_CHAT_ID ~/fh-sprint/.env"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
If empty, ask: "What's your Telegram Chat ID? (from @userinfobot)" and update:
|
|
155
|
+
```bash
|
|
156
|
+
ssh fridholmi "sed -i 's/TELEGRAM_CHAT_ID=/TELEGRAM_CHAT_ID=<id>/' ~/fh-sprint/.env"
|
|
157
|
+
ssh fridholmi "cd ~/fh-sprint && docker compose -f n8n/docker-compose.yml up -d"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Step 10 — Summary
|
|
163
|
+
|
|
164
|
+
Print:
|
|
165
|
+
```
|
|
166
|
+
✅ Plane sprint runner is ready.
|
|
167
|
+
|
|
168
|
+
Projects configured:
|
|
169
|
+
<list from SPRINT_PROJECTS>
|
|
170
|
+
|
|
171
|
+
n8n UI: http://localhost:5678 (SSH tunnel: ssh -L 5678:127.0.0.1:5678 fridholmi -N)
|
|
172
|
+
|
|
173
|
+
Remaining manual step:
|
|
174
|
+
Add SSH credential 'Host SSH' in n8n UI → Settings → Credentials
|
|
175
|
+
(sshPrivateKey pointing to the server's SSH key)
|
|
176
|
+
|
|
177
|
+
To run a sprint: open n8n → 'Plane Sprint Runner' → Execute workflow
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Hard fails
|
|
183
|
+
|
|
184
|
+
- MUST NOT create projects without running dry-run and getting user confirmation first
|
|
185
|
+
- MUST NOT write API tokens to any file other than `openclaw/secrets/local/plane_api_token`
|
|
186
|
+
- MUST NOT modify `n8n/docker-compose.yml` directly — the `--update-compose` flag on `setup-plane-projects.sh` handles this safely
|
|
187
|
+
- Plane 1.3.x quirks: hyphens in project names are rejected (script auto-converts to spaces); cycle creation requires `project_id` in body AND `cycle_view: true` on the project; `/api/v1/workspaces/` returns 404 (use `/api/v1/users/me/` for connectivity check)
|
|
188
|
+
- If n8n fails to start after 3 attempts: stop and show logs — do not retry silently
|