chief-clancy 0.5.3 → 0.5.5
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 +3 -3
- package/dist/bundle/clancy-afk.js +2 -2
- package/dist/bundle/clancy-once.js +54 -28
- package/dist/schemas/bitbucket-pr.d.ts +122 -0
- package/dist/schemas/bitbucket-pr.d.ts.map +1 -0
- package/dist/schemas/bitbucket-pr.js +69 -0
- package/dist/schemas/bitbucket-pr.js.map +1 -0
- package/dist/schemas/env.d.ts +31 -0
- package/dist/schemas/env.d.ts.map +1 -1
- package/dist/schemas/env.js +10 -0
- package/dist/schemas/env.js.map +1 -1
- package/dist/schemas/github.d.ts +60 -0
- package/dist/schemas/github.d.ts.map +1 -1
- package/dist/schemas/github.js +32 -0
- package/dist/schemas/github.js.map +1 -1
- package/dist/schemas/gitlab-mr.d.ts +62 -0
- package/dist/schemas/gitlab-mr.d.ts.map +1 -0
- package/dist/schemas/gitlab-mr.js +31 -0
- package/dist/schemas/gitlab-mr.js.map +1 -0
- package/dist/scripts/afk/afk.d.ts.map +1 -1
- package/dist/scripts/afk/afk.js +1 -8
- package/dist/scripts/afk/afk.js.map +1 -1
- package/dist/scripts/board/github/github.d.ts.map +1 -1
- package/dist/scripts/board/github/github.js +1 -2
- package/dist/scripts/board/github/github.js.map +1 -1
- package/dist/scripts/board/linear/linear.d.ts.map +1 -1
- package/dist/scripts/board/linear/linear.js +35 -4
- package/dist/scripts/board/linear/linear.js.map +1 -1
- package/dist/scripts/once/once.d.ts.map +1 -1
- package/dist/scripts/once/once.js +381 -53
- package/dist/scripts/once/once.js.map +1 -1
- package/dist/scripts/shared/env-schema/env-schema.d.ts.map +1 -1
- package/dist/scripts/shared/env-schema/env-schema.js +3 -2
- package/dist/scripts/shared/env-schema/env-schema.js.map +1 -1
- package/dist/scripts/shared/format/format.d.ts +11 -0
- package/dist/scripts/shared/format/format.d.ts.map +1 -0
- package/dist/scripts/shared/format/format.js +18 -0
- package/dist/scripts/shared/format/format.js.map +1 -0
- package/dist/scripts/shared/git-ops/git-ops.d.ts +18 -0
- package/dist/scripts/shared/git-ops/git-ops.d.ts.map +1 -1
- package/dist/scripts/shared/git-ops/git-ops.js +40 -0
- package/dist/scripts/shared/git-ops/git-ops.js.map +1 -1
- package/dist/scripts/shared/http/http.d.ts +2 -0
- package/dist/scripts/shared/http/http.d.ts.map +1 -1
- package/dist/scripts/shared/http/http.js +2 -0
- package/dist/scripts/shared/http/http.js.map +1 -1
- package/dist/scripts/shared/progress/progress.d.ts +44 -2
- package/dist/scripts/shared/progress/progress.d.ts.map +1 -1
- package/dist/scripts/shared/progress/progress.js +97 -2
- package/dist/scripts/shared/progress/progress.js.map +1 -1
- package/dist/scripts/shared/prompt/prompt.d.ts +27 -0
- package/dist/scripts/shared/prompt/prompt.d.ts.map +1 -1
- package/dist/scripts/shared/prompt/prompt.js +32 -7
- package/dist/scripts/shared/prompt/prompt.js.map +1 -1
- package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts +70 -0
- package/dist/scripts/shared/pull-request/bitbucket/bitbucket.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js +251 -0
- package/dist/scripts/shared/pull-request/bitbucket/bitbucket.js.map +1 -0
- package/dist/scripts/shared/pull-request/github/github.d.ts +48 -0
- package/dist/scripts/shared/pull-request/github/github.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/github/github.js +133 -0
- package/dist/scripts/shared/pull-request/github/github.js.map +1 -0
- package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts +46 -0
- package/dist/scripts/shared/pull-request/gitlab/gitlab.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/gitlab/gitlab.js +154 -0
- package/dist/scripts/shared/pull-request/gitlab/gitlab.js.map +1 -0
- package/dist/scripts/shared/pull-request/post-pr/post-pr.d.ts +31 -0
- package/dist/scripts/shared/pull-request/post-pr/post-pr.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/post-pr/post-pr.js +61 -0
- package/dist/scripts/shared/pull-request/post-pr/post-pr.js.map +1 -0
- package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts +19 -0
- package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/pr-body/pr-body.js +42 -0
- package/dist/scripts/shared/pull-request/pr-body/pr-body.js.map +1 -0
- package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts +23 -0
- package/dist/scripts/shared/pull-request/rework-comment/rework-comment.d.ts.map +1 -0
- package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js +30 -0
- package/dist/scripts/shared/pull-request/rework-comment/rework-comment.js.map +1 -0
- package/dist/scripts/shared/remote/remote.d.ts +41 -0
- package/dist/scripts/shared/remote/remote.d.ts.map +1 -0
- package/dist/scripts/shared/remote/remote.js +227 -0
- package/dist/scripts/shared/remote/remote.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/remote.d.ts +53 -0
- package/dist/types/remote.d.ts.map +1 -0
- package/dist/types/remote.js +5 -0
- package/dist/types/remote.js.map +1 -0
- package/package.json +1 -1
- package/src/roles/setup/workflows/init.md +106 -0
- package/src/roles/setup/workflows/scaffold.md +45 -0
- package/src/roles/setup/workflows/settings.md +81 -4
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote git host detection.
|
|
3
|
+
*
|
|
4
|
+
* Parses `git remote get-url origin` to detect the hosting platform
|
|
5
|
+
* (GitHub, GitLab, Bitbucket, etc.) and extract owner/repo/project info.
|
|
6
|
+
*/
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
/**
|
|
9
|
+
* Extract hostname and path from a raw git remote URL.
|
|
10
|
+
*
|
|
11
|
+
* Strips `.git` suffix, then tries SSH (`git@host:path`) and
|
|
12
|
+
* HTTPS/SSH-URL (`https://host/path`, `ssh://git@host/path`) formats.
|
|
13
|
+
*
|
|
14
|
+
* @param rawUrl - The raw git remote URL.
|
|
15
|
+
* @returns The extracted hostname and path, or `undefined` if unparseable.
|
|
16
|
+
*/
|
|
17
|
+
function extractHostAndPath(rawUrl) {
|
|
18
|
+
const url = rawUrl.trim().replace(/\.git$/, '');
|
|
19
|
+
// SSH format: git@<host>:<path>
|
|
20
|
+
const sshMatch = url.match(/^git@([^:]+):(.+)$/);
|
|
21
|
+
// HTTPS or SSH-URL format: https://<host>/<path> or ssh://git@<host>/<path>
|
|
22
|
+
const httpsMatch = url.match(/^(?:https?|ssh):\/\/(?:[^@]+@)?([^/:]+)(?::\d+)?\/(.+)$/);
|
|
23
|
+
const hostname = sshMatch?.[1] ?? httpsMatch?.[1];
|
|
24
|
+
const path = sshMatch?.[2] ?? httpsMatch?.[2];
|
|
25
|
+
if (!hostname || !path)
|
|
26
|
+
return undefined;
|
|
27
|
+
return { hostname, path };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse a git remote URL into platform-specific info.
|
|
31
|
+
*
|
|
32
|
+
* Supports HTTPS, SSH, and SSH-URL formats for GitHub, GitLab, Bitbucket
|
|
33
|
+
* (Cloud and Server), Azure DevOps, and self-hosted instances.
|
|
34
|
+
*
|
|
35
|
+
* @param rawUrl - The raw git remote URL.
|
|
36
|
+
* @returns Parsed remote info with platform and path details.
|
|
37
|
+
*/
|
|
38
|
+
export function parseRemote(rawUrl) {
|
|
39
|
+
const extracted = extractHostAndPath(rawUrl);
|
|
40
|
+
if (!extracted) {
|
|
41
|
+
return { host: 'unknown', url: rawUrl };
|
|
42
|
+
}
|
|
43
|
+
const { hostname, path } = extracted;
|
|
44
|
+
const platform = detectPlatformFromHostname(hostname);
|
|
45
|
+
switch (platform) {
|
|
46
|
+
case 'github': {
|
|
47
|
+
const parts = path.split('/');
|
|
48
|
+
if (parts.length >= 2) {
|
|
49
|
+
return {
|
|
50
|
+
host: 'github',
|
|
51
|
+
owner: parts[0],
|
|
52
|
+
repo: parts[1],
|
|
53
|
+
hostname,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return { host: 'unknown', url: rawUrl };
|
|
57
|
+
}
|
|
58
|
+
case 'gitlab': {
|
|
59
|
+
return {
|
|
60
|
+
host: 'gitlab',
|
|
61
|
+
projectPath: path,
|
|
62
|
+
hostname,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
case 'bitbucket': {
|
|
66
|
+
// Bitbucket Server uses /scm/<projectKey>/<repo> format
|
|
67
|
+
const scmMatch = path.match(/^scm\/([^/]+)\/(.+)$/);
|
|
68
|
+
if (scmMatch) {
|
|
69
|
+
return {
|
|
70
|
+
host: 'bitbucket-server',
|
|
71
|
+
projectKey: scmMatch[1],
|
|
72
|
+
repoSlug: scmMatch[2],
|
|
73
|
+
hostname,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Bitbucket Cloud: <workspace>/<repo>
|
|
77
|
+
const parts = path.split('/');
|
|
78
|
+
if (parts.length >= 2) {
|
|
79
|
+
return {
|
|
80
|
+
host: 'bitbucket',
|
|
81
|
+
workspace: parts[0],
|
|
82
|
+
repoSlug: parts[1],
|
|
83
|
+
hostname,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return { host: 'unknown', url: rawUrl };
|
|
87
|
+
}
|
|
88
|
+
case 'azure':
|
|
89
|
+
return { host: 'azure', url: rawUrl };
|
|
90
|
+
default:
|
|
91
|
+
return { host: 'unknown', url: rawUrl };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Detect the git hosting platform from a hostname.
|
|
96
|
+
*
|
|
97
|
+
* Uses known domain patterns. Self-hosted instances with custom domains
|
|
98
|
+
* (e.g. `git.acme.com`) fall through to 'unknown' — use `CLANCY_GIT_PLATFORM`
|
|
99
|
+
* env var to override.
|
|
100
|
+
*
|
|
101
|
+
* @param hostname - The hostname from the remote URL.
|
|
102
|
+
* @returns The detected platform.
|
|
103
|
+
*/
|
|
104
|
+
export function detectPlatformFromHostname(hostname) {
|
|
105
|
+
const lower = hostname.toLowerCase();
|
|
106
|
+
if (lower === 'github.com' || lower.includes('github'))
|
|
107
|
+
return 'github';
|
|
108
|
+
if (lower === 'gitlab.com' || lower.includes('gitlab'))
|
|
109
|
+
return 'gitlab';
|
|
110
|
+
if (lower === 'bitbucket.org' || lower.includes('bitbucket'))
|
|
111
|
+
return 'bitbucket';
|
|
112
|
+
if (lower.includes('dev.azure') || lower.includes('visualstudio'))
|
|
113
|
+
return 'azure';
|
|
114
|
+
return 'unknown';
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Detect the remote origin info from the current git repository.
|
|
118
|
+
*
|
|
119
|
+
* Falls back to `{ host: 'none' }` if no remote is configured or
|
|
120
|
+
* if the command fails.
|
|
121
|
+
*
|
|
122
|
+
* @param platformOverride - Override platform detection (from `CLANCY_GIT_PLATFORM` env var).
|
|
123
|
+
* @returns Parsed remote info.
|
|
124
|
+
*/
|
|
125
|
+
export function detectRemote(platformOverride) {
|
|
126
|
+
let rawUrl;
|
|
127
|
+
try {
|
|
128
|
+
rawUrl = execFileSync('git', ['remote', 'get-url', 'origin'], {
|
|
129
|
+
encoding: 'utf8',
|
|
130
|
+
}).trim();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return { host: 'none' };
|
|
134
|
+
}
|
|
135
|
+
if (!rawUrl)
|
|
136
|
+
return { host: 'none' };
|
|
137
|
+
// If user explicitly overrides the platform, always use it — they know better
|
|
138
|
+
if (platformOverride) {
|
|
139
|
+
return overrideRemotePlatform(rawUrl, platformOverride);
|
|
140
|
+
}
|
|
141
|
+
return parseRemote(rawUrl);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Re-parse a remote URL with a known platform override.
|
|
145
|
+
*
|
|
146
|
+
* Used when auto-detection fails (self-hosted with custom domain)
|
|
147
|
+
* and the user sets `CLANCY_GIT_PLATFORM`.
|
|
148
|
+
*/
|
|
149
|
+
function overrideRemotePlatform(rawUrl, platform) {
|
|
150
|
+
const extracted = extractHostAndPath(rawUrl);
|
|
151
|
+
if (!extracted)
|
|
152
|
+
return { host: 'unknown', url: rawUrl };
|
|
153
|
+
const { hostname, path } = extracted;
|
|
154
|
+
switch (platform.toLowerCase()) {
|
|
155
|
+
case 'github': {
|
|
156
|
+
const parts = path.split('/');
|
|
157
|
+
if (parts.length >= 2) {
|
|
158
|
+
return { host: 'github', owner: parts[0], repo: parts[1], hostname };
|
|
159
|
+
}
|
|
160
|
+
return { host: 'unknown', url: rawUrl };
|
|
161
|
+
}
|
|
162
|
+
case 'gitlab':
|
|
163
|
+
return { host: 'gitlab', projectPath: path, hostname };
|
|
164
|
+
case 'bitbucket': {
|
|
165
|
+
const parts = path.split('/');
|
|
166
|
+
if (parts.length >= 2) {
|
|
167
|
+
return {
|
|
168
|
+
host: 'bitbucket',
|
|
169
|
+
workspace: parts[0],
|
|
170
|
+
repoSlug: parts[1],
|
|
171
|
+
hostname,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { host: 'unknown', url: rawUrl };
|
|
175
|
+
}
|
|
176
|
+
case 'bitbucket-server': {
|
|
177
|
+
// Strip leading scm/ prefix used in Bitbucket Server URLs
|
|
178
|
+
const scmMatch = path.match(/^scm\/([^/]+)\/(.+)$/);
|
|
179
|
+
if (scmMatch) {
|
|
180
|
+
return {
|
|
181
|
+
host: 'bitbucket-server',
|
|
182
|
+
projectKey: scmMatch[1],
|
|
183
|
+
repoSlug: scmMatch[2],
|
|
184
|
+
hostname,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const parts = path.split('/');
|
|
188
|
+
if (parts.length >= 2) {
|
|
189
|
+
return {
|
|
190
|
+
host: 'bitbucket-server',
|
|
191
|
+
projectKey: parts[0],
|
|
192
|
+
repoSlug: parts[1],
|
|
193
|
+
hostname,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return { host: 'unknown', url: rawUrl };
|
|
197
|
+
}
|
|
198
|
+
default:
|
|
199
|
+
return { host: 'unknown', url: rawUrl };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Build the API base URL for a given remote.
|
|
204
|
+
*
|
|
205
|
+
* @param remote - The parsed remote info.
|
|
206
|
+
* @param apiUrlOverride - Override from `CLANCY_GIT_API_URL` env var.
|
|
207
|
+
* @returns The API base URL, or undefined if not applicable.
|
|
208
|
+
*/
|
|
209
|
+
export function buildApiBaseUrl(remote, apiUrlOverride) {
|
|
210
|
+
if (apiUrlOverride)
|
|
211
|
+
return apiUrlOverride.replace(/\/$/, '');
|
|
212
|
+
switch (remote.host) {
|
|
213
|
+
case 'github':
|
|
214
|
+
return remote.hostname === 'github.com'
|
|
215
|
+
? 'https://api.github.com'
|
|
216
|
+
: `https://${remote.hostname}/api/v3`;
|
|
217
|
+
case 'gitlab':
|
|
218
|
+
return `https://${remote.hostname}/api/v4`;
|
|
219
|
+
case 'bitbucket':
|
|
220
|
+
return 'https://api.bitbucket.org/2.0';
|
|
221
|
+
case 'bitbucket-server':
|
|
222
|
+
return `https://${remote.hostname}/rest/api/1.0`;
|
|
223
|
+
default:
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../../../src/scripts/shared/remote/remote.ts"],"names":[],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type { BoardProvider, Ticket } from './board.js';
|
|
2
|
+
export type { GitPlatform, PrCreationResult, PrReviewState, ProgressStatus, RemoteInfo, } from './remote.js';
|
|
2
3
|
export type { BoardConfig, GitHubEnv, JiraEnv, LinearEnv, SharedEnv, } from '../schemas/env.js';
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,SAAS,GACV,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,SAAS,EACT,SAAS,GACV,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote git hosting types shared across remote detection and PR creation.
|
|
3
|
+
*/
|
|
4
|
+
/** Supported git hosting platforms. */
|
|
5
|
+
export type GitPlatform = 'github' | 'gitlab' | 'bitbucket' | 'bitbucket-server' | 'azure' | 'unknown';
|
|
6
|
+
/** Parsed remote URL with platform and path info. */
|
|
7
|
+
export type RemoteInfo = {
|
|
8
|
+
host: 'github';
|
|
9
|
+
owner: string;
|
|
10
|
+
repo: string;
|
|
11
|
+
hostname: string;
|
|
12
|
+
} | {
|
|
13
|
+
host: 'gitlab';
|
|
14
|
+
projectPath: string;
|
|
15
|
+
hostname: string;
|
|
16
|
+
} | {
|
|
17
|
+
host: 'bitbucket';
|
|
18
|
+
workspace: string;
|
|
19
|
+
repoSlug: string;
|
|
20
|
+
hostname: string;
|
|
21
|
+
} | {
|
|
22
|
+
host: 'bitbucket-server';
|
|
23
|
+
projectKey: string;
|
|
24
|
+
repoSlug: string;
|
|
25
|
+
hostname: string;
|
|
26
|
+
} | {
|
|
27
|
+
host: 'azure' | 'unknown';
|
|
28
|
+
url: string;
|
|
29
|
+
} | {
|
|
30
|
+
host: 'none';
|
|
31
|
+
};
|
|
32
|
+
/** Result of a PR/MR creation attempt. */
|
|
33
|
+
export type PrCreationResult = {
|
|
34
|
+
ok: true;
|
|
35
|
+
url: string;
|
|
36
|
+
number: number;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
error: string;
|
|
40
|
+
alreadyExists?: boolean;
|
|
41
|
+
};
|
|
42
|
+
/** Result of checking PR/MR review state. */
|
|
43
|
+
export type PrReviewState = {
|
|
44
|
+
/** Whether changes have been requested by a reviewer. */
|
|
45
|
+
changesRequested: boolean;
|
|
46
|
+
/** The PR/MR number/ID (needed to fetch comments). */
|
|
47
|
+
prNumber: number;
|
|
48
|
+
/** The PR/MR URL (for logging). */
|
|
49
|
+
prUrl: string;
|
|
50
|
+
};
|
|
51
|
+
/** Progress log status values. */
|
|
52
|
+
export type ProgressStatus = 'DONE' | 'SKIPPED' | 'PR_CREATED' | 'PUSHED' | 'PUSH_FAILED' | 'LOCAL' | 'PLAN' | 'APPROVE' | 'REWORK';
|
|
53
|
+
//# sourceMappingURL=remote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/types/remote.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,kBAAkB,GAClB,OAAO,GACP,SAAS,CAAC;AAEd,qDAAqD;AACrD,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb,GACD;IACE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN,0CAA0C;AAC1C,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1D,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,kCAAkC;AAClC,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,aAAa,GACb,OAAO,GACP,MAAM,GACN,SAAS,GACT,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/types/remote.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
CHANGED
|
@@ -207,6 +207,56 @@ Never silently continue with unverified credentials — the user must explicitly
|
|
|
207
207
|
|
|
208
208
|
---
|
|
209
209
|
|
|
210
|
+
### Q2c (Jira and Linear only): Git host token
|
|
211
|
+
|
|
212
|
+
When the board is **Jira** or **Linear**, Clancy needs a git host token to create pull requests after implementation. Skip this step entirely for **GitHub Issues** — the `GITHUB_TOKEN` collected in Q2 already covers PR creation.
|
|
213
|
+
|
|
214
|
+
Output:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
Clancy can push your feature branch and create a pull request automatically.
|
|
218
|
+
Which git host does this project use?
|
|
219
|
+
|
|
220
|
+
[1] GitHub
|
|
221
|
+
[2] GitLab
|
|
222
|
+
[3] Bitbucket
|
|
223
|
+
[4] Skip — I'll push and create PRs manually
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**If [1] GitHub:**
|
|
227
|
+
|
|
228
|
+
`Paste your GitHub personal access token: (needs repo scope — create at github.com/settings/tokens)`
|
|
229
|
+
|
|
230
|
+
Store as `GITHUB_TOKEN` in `.clancy/.env`.
|
|
231
|
+
|
|
232
|
+
Verify by calling `GET https://api.github.com/user` with `Authorization: Bearer {token}` and `X-GitHub-Api-Version: 2022-11-28`.
|
|
233
|
+
|
|
234
|
+
On success: `✅ GitHub connected — {login}`
|
|
235
|
+
On failure: offer re-enter or skip (same pattern as Q2b).
|
|
236
|
+
|
|
237
|
+
**If [2] GitLab:**
|
|
238
|
+
|
|
239
|
+
`Paste your GitLab personal access token: (needs api scope — create at gitlab.com/-/user_settings/personal_access_tokens)`
|
|
240
|
+
|
|
241
|
+
Store as `GITLAB_TOKEN` in `.clancy/.env`.
|
|
242
|
+
|
|
243
|
+
If the user is using a self-hosted GitLab instance, also ask:
|
|
244
|
+
`What's your GitLab API base URL? (e.g. https://gitlab.example.com/api/v4 — press Enter for gitlab.com)`
|
|
245
|
+
|
|
246
|
+
If a URL is entered, store as `CLANCY_GIT_API_URL` in `.clancy/.env` and `CLANCY_GIT_PLATFORM="gitlab"`.
|
|
247
|
+
If the user enters just a hostname or instance URL without `/api/v4`, append `/api/v4` automatically.
|
|
248
|
+
|
|
249
|
+
**If [3] Bitbucket:**
|
|
250
|
+
|
|
251
|
+
1. `What's your Bitbucket username? (your Atlassian account username)`
|
|
252
|
+
2. `Paste your Bitbucket app password: (needs repository:write scope — create at bitbucket.org/account/settings/app-passwords)`
|
|
253
|
+
|
|
254
|
+
Store as `BITBUCKET_USER` and `BITBUCKET_TOKEN` in `.clancy/.env`.
|
|
255
|
+
|
|
256
|
+
**If [4] Skip:** no git host token is written. Clancy will still implement tickets but leave the feature branch for the user to push and create PRs manually.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
210
260
|
### Q3 (Jira only): Status name
|
|
211
261
|
|
|
212
262
|
Output:
|
|
@@ -315,6 +365,62 @@ You can always configure these later via `/clancy:settings`.
|
|
|
315
365
|
|
|
316
366
|
---
|
|
317
367
|
|
|
368
|
+
### Q3d-2 (Jira and Linear only): Review status
|
|
369
|
+
|
|
370
|
+
Only ask this if a git host token was configured in Q2c (i.e. the user didn't skip PR creation).
|
|
371
|
+
|
|
372
|
+
**GitHub:** Skip entirely — not applicable (GitHub Issues don't have workflow states).
|
|
373
|
+
|
|
374
|
+
**Jira:** Output:
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
When Clancy creates a pull request, it can transition the ticket to a review status.
|
|
378
|
+
|
|
379
|
+
What transition should Clancy use after creating a PR?
|
|
380
|
+
|
|
381
|
+
[1] In Review
|
|
382
|
+
[2] Ready for Review
|
|
383
|
+
[3] Enter a different value
|
|
384
|
+
[4] Skip — use the same status as completion (CLANCY_STATUS_DONE)
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
If [1]: store `CLANCY_STATUS_REVIEW="In Review"` in `.clancy/.env`.
|
|
388
|
+
If [2]: store `CLANCY_STATUS_REVIEW="Ready for Review"` in `.clancy/.env`.
|
|
389
|
+
If [3]: prompt for the value, store as `CLANCY_STATUS_REVIEW` in `.clancy/.env`. Wrap in double quotes.
|
|
390
|
+
If [4] or the user says "skip"/"none": skip — no `CLANCY_STATUS_REVIEW` line written (falls back to `CLANCY_STATUS_DONE`).
|
|
391
|
+
|
|
392
|
+
**Linear:** Output:
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
When Clancy creates a pull request, it can move the issue to a review state.
|
|
396
|
+
|
|
397
|
+
What state should Clancy move an issue to after creating a PR?
|
|
398
|
+
|
|
399
|
+
[1] In Review
|
|
400
|
+
[2] Ready for Review
|
|
401
|
+
[3] Enter a different value
|
|
402
|
+
[4] Skip — use the same state as completion (CLANCY_STATUS_DONE)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Same storage logic as Jira above.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### Q3e (all boards): Max rework cycles
|
|
410
|
+
|
|
411
|
+
PR-based rework detection is automatic — no configuration needed. This setting controls the safety limit.
|
|
412
|
+
|
|
413
|
+
Output:
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
Max rework cycles before flagging for human intervention? [3]
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
If a number is entered: store as `CLANCY_MAX_REWORK` in `.clancy/.env`.
|
|
420
|
+
If enter is pressed with no value: use default 3 — store `CLANCY_MAX_REWORK=3` in `.clancy/.env`.
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
318
424
|
### Q4: Base branch (auto-detect)
|
|
319
425
|
|
|
320
426
|
Silently detect the base branch — do not ask unless detection fails:
|
|
@@ -383,6 +383,24 @@ MAX_ITERATIONS=5
|
|
|
383
383
|
# "Done" can be any transition to a post-implementation status.
|
|
384
384
|
# CLANCY_STATUS_IN_PROGRESS="In Progress"
|
|
385
385
|
# CLANCY_STATUS_DONE="Done"
|
|
386
|
+
# CLANCY_STATUS_REVIEW="In Review" # used when creating a PR instead of merging locally
|
|
387
|
+
|
|
388
|
+
# ─── Optional: Git host (PR creation) ───────────────────────────────────────
|
|
389
|
+
# When a ticket has no parent epic, Clancy pushes the feature branch and creates
|
|
390
|
+
# a pull request instead of squash-merging locally. Requires a git host token.
|
|
391
|
+
# GitHub Issues users already have GITHUB_TOKEN above — no extra config needed.
|
|
392
|
+
# GITHUB_TOKEN=ghp_your-token # if your git host is GitHub
|
|
393
|
+
# GITLAB_TOKEN=glpat-your-token # if your git host is GitLab
|
|
394
|
+
# BITBUCKET_USER=your-username # if your git host is Bitbucket
|
|
395
|
+
# BITBUCKET_TOKEN=your-app-password # if your git host is Bitbucket
|
|
396
|
+
# CLANCY_GIT_PLATFORM=gitlab # override auto-detection (github/gitlab/bitbucket)
|
|
397
|
+
# CLANCY_GIT_API_URL=https://gitlab.example.com/api/v4 # self-hosted git API base URL
|
|
398
|
+
|
|
399
|
+
# ─── Optional: Rework loop ──────────────────────────────────────────────────
|
|
400
|
+
# PR-based rework is automatic — when a reviewer leaves inline comments or
|
|
401
|
+
# a conversation comment prefixed with "Rework:", Clancy picks it up on the
|
|
402
|
+
# next run. No configuration needed.
|
|
403
|
+
# CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
|
|
386
404
|
|
|
387
405
|
# ─── Optional: Planner queue ─────────────────────────────────────────────────
|
|
388
406
|
# Status for backlog tickets that /clancy:plan fetches from (default: Backlog)
|
|
@@ -419,6 +437,10 @@ GITHUB_REPO=owner/repo-name
|
|
|
419
437
|
# When an issue has a milestone, Clancy auto-creates milestone/{slug} from this branch.
|
|
420
438
|
CLANCY_BASE_BRANCH=main
|
|
421
439
|
|
|
440
|
+
# ─── PR creation ─────────────────────────────────────────────────────────────
|
|
441
|
+
# When an issue has no milestone, Clancy pushes the feature branch and creates a
|
|
442
|
+
# PR using your GITHUB_TOKEN above. No extra config needed for GitHub Issues users.
|
|
443
|
+
|
|
422
444
|
# ─── Loop ─────────────────────────────────────────────────────────────────────
|
|
423
445
|
# Max tickets to process per /clancy:run session (default: 20)
|
|
424
446
|
MAX_ITERATIONS=20
|
|
@@ -441,6 +463,12 @@ MAX_ITERATIONS=20
|
|
|
441
463
|
# PLAYWRIGHT_STORYBOOK_PORT=6006
|
|
442
464
|
# PLAYWRIGHT_STARTUP_WAIT=15
|
|
443
465
|
|
|
466
|
+
# ─── Optional: Rework loop ──────────────────────────────────────────────────
|
|
467
|
+
# PR-based rework is automatic — when a reviewer leaves inline comments or
|
|
468
|
+
# a conversation comment prefixed with "Rework:", Clancy picks it up on the
|
|
469
|
+
# next run. No configuration needed.
|
|
470
|
+
# CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
|
|
471
|
+
|
|
444
472
|
# ─── Optional: Notifications ──────────────────────────────────────────────────
|
|
445
473
|
# Webhook URL for Slack or Teams notifications on ticket completion
|
|
446
474
|
# CLANCY_NOTIFY_WEBHOOK=https://hooks.slack.com/services/your/webhook/url
|
|
@@ -495,6 +523,23 @@ MAX_ITERATIONS=20
|
|
|
495
523
|
# "Done" can be any post-implementation state (e.g. "Ready for Review", "In Review").
|
|
496
524
|
# CLANCY_STATUS_IN_PROGRESS="In Progress"
|
|
497
525
|
# CLANCY_STATUS_DONE="Done"
|
|
526
|
+
# CLANCY_STATUS_REVIEW="In Review" # used when creating a PR instead of merging locally
|
|
527
|
+
|
|
528
|
+
# ─── Optional: Rework loop ──────────────────────────────────────────────────
|
|
529
|
+
# PR-based rework is automatic — when a reviewer leaves inline comments or
|
|
530
|
+
# a conversation comment prefixed with "Rework:", Clancy picks it up on the
|
|
531
|
+
# next run. No configuration needed.
|
|
532
|
+
# CLANCY_MAX_REWORK=3 # Max rework cycles before human intervention (default: 3)
|
|
533
|
+
|
|
534
|
+
# ─── Optional: Git host (PR creation) ───────────────────────────────────────
|
|
535
|
+
# When an issue has no parent, Clancy pushes the feature branch and creates a
|
|
536
|
+
# pull request instead of squash-merging locally. Requires a git host token.
|
|
537
|
+
# GITHUB_TOKEN=ghp_your-token # if your git host is GitHub
|
|
538
|
+
# GITLAB_TOKEN=glpat-your-token # if your git host is GitLab
|
|
539
|
+
# BITBUCKET_USER=your-username # if your git host is Bitbucket
|
|
540
|
+
# BITBUCKET_TOKEN=your-app-password # if your git host is Bitbucket
|
|
541
|
+
# CLANCY_GIT_PLATFORM=gitlab # override auto-detection (github/gitlab/bitbucket)
|
|
542
|
+
# CLANCY_GIT_API_URL=https://gitlab.example.com/api/v4 # self-hosted git API base URL
|
|
498
543
|
|
|
499
544
|
# ─── Optional: Notifications ──────────────────────────────────────────────────
|
|
500
545
|
# Webhook URL for Slack or Teams notifications on ticket completion
|
|
@@ -51,6 +51,7 @@ General
|
|
|
51
51
|
[G1] Max iterations {MAX_ITERATIONS:-5} tickets per /clancy:run session
|
|
52
52
|
[G2] Claude model {CLANCY_MODEL:-default} model used for each ticket session
|
|
53
53
|
[G3] Base branch {CLANCY_BASE_BRANCH:-main}
|
|
54
|
+
[G4] Max rework {CLANCY_MAX_REWORK:-3}
|
|
54
55
|
|
|
55
56
|
{If Jira:}
|
|
56
57
|
Jira
|
|
@@ -59,16 +60,14 @@ Jira
|
|
|
59
60
|
[B3] Label filter {CLANCY_LABEL if set, else off}
|
|
60
61
|
[B4] Pickup status {CLANCY_STATUS_IN_PROGRESS if set, else off}
|
|
61
62
|
[B5] Done status {CLANCY_STATUS_DONE if set, else off}
|
|
62
|
-
|
|
63
|
-
{If GitHub:}
|
|
64
|
-
GitHub
|
|
65
|
-
(No board-specific settings — labels are managed in GitHub directly)
|
|
63
|
+
[B6] Review status {CLANCY_STATUS_REVIEW if set, else "uses Done status"}
|
|
66
64
|
|
|
67
65
|
{If Linear:}
|
|
68
66
|
Linear
|
|
69
67
|
[B1] Label filter {CLANCY_LABEL if set, else off}
|
|
70
68
|
[B2] Pickup status {CLANCY_STATUS_IN_PROGRESS if set, else off}
|
|
71
69
|
[B3] Done status {CLANCY_STATUS_DONE if set, else off}
|
|
70
|
+
[B4] Review status {CLANCY_STATUS_REVIEW if set, else "uses Done state"}
|
|
72
71
|
|
|
73
72
|
Roles
|
|
74
73
|
[R1] Planner {✅ enabled / ─ disabled}
|
|
@@ -82,6 +81,9 @@ Planner
|
|
|
82
81
|
{If Linear:}
|
|
83
82
|
[P1] Plan state type {CLANCY_PLAN_STATE_TYPE:-backlog}
|
|
84
83
|
|
|
84
|
+
Git Host (PR creation)
|
|
85
|
+
[H1] Git host token {platform: GitHub/GitLab/Bitbucket or "not set"}
|
|
86
|
+
|
|
85
87
|
Integrations
|
|
86
88
|
[I1] Figma MCP {enabled if FIGMA_API_KEY set, else not set}
|
|
87
89
|
[I2] Playwright {enabled if PLAYWRIGHT_ENABLED=true, else off}
|
|
@@ -151,6 +153,24 @@ Write `CLANCY_BASE_BRANCH=<value>` to `.clancy/.env`.
|
|
|
151
153
|
|
|
152
154
|
---
|
|
153
155
|
|
|
156
|
+
### [G4] Max rework cycles
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
Max rework cycles — current: {value or 3}
|
|
160
|
+
After this many rework cycles on a single ticket, Clancy flags it for human intervention.
|
|
161
|
+
|
|
162
|
+
[1] 3 (default)
|
|
163
|
+
[2] Enter a different number
|
|
164
|
+
[3] Cancel
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Validate the input is a positive integer between 1 and 20. If invalid, re-prompt.
|
|
168
|
+
|
|
169
|
+
If [1]: remove `CLANCY_MAX_REWORK` from `.clancy/.env` (uses default).
|
|
170
|
+
If [2]: prompt `How many rework cycles before human intervention?` then write `CLANCY_MAX_REWORK=<value>` to `.clancy/.env`.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
154
174
|
### [B1] Jira status filter (Jira only)
|
|
155
175
|
|
|
156
176
|
```
|
|
@@ -232,6 +252,23 @@ If [2]: remove `CLANCY_STATUS_DONE` from `.clancy/.env`.
|
|
|
232
252
|
|
|
233
253
|
---
|
|
234
254
|
|
|
255
|
+
### [B6] Jira Review status (Jira only)
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
Jira Review status — current: {value or "uses Done status"}
|
|
259
|
+
When Clancy creates a pull request (instead of merging locally), it transitions
|
|
260
|
+
the ticket to this status. Falls back to CLANCY_STATUS_DONE if not set.
|
|
261
|
+
|
|
262
|
+
[1] Set status name
|
|
263
|
+
[2] Off (use Done status for PR flow too)
|
|
264
|
+
[3] Cancel
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
If [1]: prompt `What status name should Clancy use for In Review? (e.g. In Review, Ready for Review, Code Review)` then write `CLANCY_STATUS_REVIEW=<value>` to `.clancy/.env`.
|
|
268
|
+
If [2]: remove `CLANCY_STATUS_REVIEW` from `.clancy/.env`.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
235
272
|
### [B1] Linear label filter (Linear only)
|
|
236
273
|
|
|
237
274
|
```
|
|
@@ -283,6 +320,23 @@ If [2]: remove `CLANCY_STATUS_DONE` from `.clancy/.env`.
|
|
|
283
320
|
|
|
284
321
|
---
|
|
285
322
|
|
|
323
|
+
### [B4] Linear Review status (Linear only)
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
Linear Review status — current: {value or "uses Done state"}
|
|
327
|
+
When Clancy creates a pull request (instead of merging locally), it moves
|
|
328
|
+
the issue to this state. Falls back to CLANCY_STATUS_DONE if not set.
|
|
329
|
+
|
|
330
|
+
[1] Set state name
|
|
331
|
+
[2] Off (use Done state for PR flow too)
|
|
332
|
+
[3] Cancel
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
If [1]: prompt `What workflow state name should Clancy use for In Review? (e.g. In Review, Ready for Review, Code Review)` then write `CLANCY_STATUS_REVIEW=<value>` to `.clancy/.env`.
|
|
336
|
+
If [2]: remove `CLANCY_STATUS_REVIEW` from `.clancy/.env`.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
286
340
|
### [R1] Planner role
|
|
287
341
|
|
|
288
342
|
```
|
|
@@ -355,6 +409,28 @@ If [3]: prompt `What state type should /clancy:plan fetch from?` then write `CLA
|
|
|
355
409
|
|
|
356
410
|
---
|
|
357
411
|
|
|
412
|
+
### [H1] Git host token
|
|
413
|
+
|
|
414
|
+
Only shown for Jira and Linear boards. GitHub Issues users already have `GITHUB_TOKEN` for PR creation.
|
|
415
|
+
|
|
416
|
+
```
|
|
417
|
+
Git host — current: {GitHub / GitLab / Bitbucket / not set}
|
|
418
|
+
Clancy pushes feature branches and creates PRs on your git host.
|
|
419
|
+
|
|
420
|
+
[1] GitHub
|
|
421
|
+
[2] GitLab
|
|
422
|
+
[3] Bitbucket
|
|
423
|
+
[4] Remove (push and create PRs manually)
|
|
424
|
+
[5] Cancel
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
If [1]: prompt `Paste your GitHub personal access token:` then write `GITHUB_TOKEN=<value>` to `.clancy/.env`. Remove any existing `GITLAB_TOKEN`, `BITBUCKET_USER`, `BITBUCKET_TOKEN`.
|
|
428
|
+
If [2]: prompt `Paste your GitLab personal access token:` then write `GITLAB_TOKEN=<value>` to `.clancy/.env`. Optionally ask for a self-hosted API base URL (e.g. `https://gitlab.example.com/api/v4`) and write `CLANCY_GIT_API_URL` and `CLANCY_GIT_PLATFORM="gitlab"`. If the user enters just a hostname or instance URL without `/api/v4`, append `/api/v4` automatically. Remove any existing `GITHUB_TOKEN` (only if board is not GitHub), `BITBUCKET_USER`, `BITBUCKET_TOKEN`.
|
|
429
|
+
If [3]: prompt for `Bitbucket username` and `Bitbucket app password`, write `BITBUCKET_USER` and `BITBUCKET_TOKEN` to `.clancy/.env`. Remove any existing `GITHUB_TOKEN` (only if board is not GitHub), `GITLAB_TOKEN`.
|
|
430
|
+
If [4]: remove all git host token vars (`GITLAB_TOKEN`, `BITBUCKET_USER`, `BITBUCKET_TOKEN`, `CLANCY_GIT_PLATFORM`, `CLANCY_GIT_API_URL`). Keep `GITHUB_TOKEN` only if board is GitHub Issues.
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
358
434
|
### [I1] Figma MCP
|
|
359
435
|
|
|
360
436
|
```
|
|
@@ -479,6 +555,7 @@ If no: print `Cancelled. No changes made.` and loop back to the menu.
|
|
|
479
555
|
- Jira: `JIRA_BASE_URL`, `JIRA_USER`, `JIRA_API_TOKEN`, `JIRA_PROJECT_KEY`, `CLANCY_JQL_STATUS`, `CLANCY_JQL_SPRINT`
|
|
480
556
|
- GitHub: `GITHUB_TOKEN`, `GITHUB_REPO`
|
|
481
557
|
- Linear: `LINEAR_API_KEY`, `LINEAR_TEAM_ID`
|
|
558
|
+
- Git host (all boards): `GITLAB_TOKEN`, `BITBUCKET_USER`, `BITBUCKET_TOKEN`, `CLANCY_GIT_PLATFORM`, `CLANCY_GIT_API_URL`, `CLANCY_STATUS_REVIEW`
|
|
482
559
|
2. Write the new board credentials to `.clancy/.env`
|
|
483
560
|
3. If switching to Jira: also ask the status filter question (same as init Q3) and write `CLANCY_JQL_STATUS` to `.clancy/.env`
|
|
484
561
|
4. No script replacement needed — the bundled runtime scripts are board-agnostic (board detection happens at runtime from `.clancy/.env`)
|