@devflow-one/cli 0.1.14 → 0.1.16
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 +30 -2
- package/package.json +1 -1
- package/src/commands.js +85 -4
package/README.md
CHANGED
|
@@ -182,6 +182,8 @@ devflow mr create "Title" feat/x --base release/2026.4 --project ABC
|
|
|
182
182
|
# stamped with. Omitted or unrecognized, it is auto-selected by matching configured
|
|
183
183
|
# type names against the title's conventional prefix, branch prefix, Jira issue type
|
|
184
184
|
# and title keywords, falling back to the first type. Pass its id or label to pick one.
|
|
185
|
+
# The template (its own {prMedia} uploads media) writes the description; --body is the
|
|
186
|
+
# fallback, where {prMedia} is filled or removed.
|
|
185
187
|
devflow mr create "Title" feat/x --type Bugfix --project ABC
|
|
186
188
|
devflow mr types --project ABC # configured types: id, label, default flag
|
|
187
189
|
|
|
@@ -204,17 +206,42 @@ devflow commit template /wt/ABC-123 --no-push --project ABC # commit locally,
|
|
|
204
206
|
|
|
205
207
|
# read a PR/MR's title + description, then edit it: --title/--description replace,
|
|
206
208
|
# --append-description adds text after a `---` rule (skipped if already at the end);
|
|
207
|
-
# --base retargets the PR/MR to an existing remote branch
|
|
209
|
+
# --base retargets the PR/MR to an existing remote branch; `{prMedia}` in the description
|
|
210
|
+
# uploads .devflow/media/<ISSUE-KEY>[-n].{mp4,png,jpg,jpeg} and is replaced with the links
|
|
211
|
+
# (removed when the upload fails or the head branch names no issue; media.error says why)
|
|
208
212
|
devflow mr get 42 --project ABC
|
|
209
213
|
devflow mr update 42 --append-description "## Test plan" --project ABC
|
|
210
214
|
devflow mr update 42 --title "Fix login redirect" --project ABC
|
|
211
215
|
devflow mr update 42 --base release/2026.4 --project ABC
|
|
216
|
+
devflow mr update 42 --description "$(cat body.md)" --project ABC # body.md has {prMedia}
|
|
212
217
|
|
|
213
218
|
# assembled fix-review-comments prompt (read-only; runs no AI, makes no writes)
|
|
214
219
|
devflow mr fix-prompt 42 # issue key inferred from the branch
|
|
215
220
|
|
|
221
|
+
# issue status and the repo card's branches and PRs/MRs (read-only; the issue key is
|
|
222
|
+
# inferred from the branch). Status needs the Jira API token set in Settings.
|
|
223
|
+
devflow issue status # the issue's and its parent's status
|
|
224
|
+
devflow issue branches ABC-123 --project ABC
|
|
225
|
+
devflow issue prs # every state, merged and closed included
|
|
226
|
+
|
|
227
|
+
# review comments: counts, then "Reply as Fixed" or an AI "Fix Comments" run, which
|
|
228
|
+
# commits and pushes (so it needs --force). It returns at once: `started`, `prNumber` and
|
|
229
|
+
# `queued` (true when an automation run is busy, so the fix starts on its next tick), or
|
|
230
|
+
# `started: false` with a `reason` — e.g. while the panel or the timer is fixing that PR
|
|
231
|
+
devflow mr comments 42 # unfixed / fixed / resolved / prComments
|
|
232
|
+
devflow mr reply-fixed 42 # success / failed / resolved counts
|
|
233
|
+
devflow mr fix-comments 42 --force # then re-check the counts
|
|
234
|
+
|
|
216
235
|
# notify the project's configured Slack channel(s)
|
|
217
236
|
devflow slack notify "Review fixes ready on {pr}" --values '{"pr":"#42"}' --project ABC
|
|
237
|
+
devflow slack channels --project ABC # configured channels (read-only, no credentials)
|
|
238
|
+
|
|
239
|
+
# reviewer notify: per channel, were reviewers already notified, and is the next step a
|
|
240
|
+
# send or a ping? `source` says who posted: manual (panel), auto (auto-send), gateway
|
|
241
|
+
# (`slack notify --pr`) or slack (found only in Slack history). `--pr` records the post
|
|
242
|
+
# and threads a ping under the earlier message
|
|
243
|
+
devflow mr notify-status 42
|
|
244
|
+
devflow slack notify "Please review #42" --channel C123 --pr 42
|
|
218
245
|
|
|
219
246
|
# force a specific profile when a key is ambiguous
|
|
220
247
|
devflow mr ready 12 --profile prof-1
|
|
@@ -222,7 +249,8 @@ devflow mr ready 12 --profile prof-1
|
|
|
222
249
|
|
|
223
250
|
### Destructive actions
|
|
224
251
|
|
|
225
|
-
`branch delete`, `mr close`
|
|
252
|
+
`branch delete`, `mr close`, `mr merge`, `mr fix-comments` (its AI run commits and
|
|
253
|
+
pushes) and `commit template` (unless `--no-push`) are destructive. They are **refused
|
|
226
254
|
unless you confirm** with `--force` (or `--yes`); the gateway enforces the same
|
|
227
255
|
gate server-side, so the confirmation can't be bypassed:
|
|
228
256
|
|
package/package.json
CHANGED
package/src/commands.js
CHANGED
|
@@ -218,6 +218,32 @@ const COMMANDS = {
|
|
|
218
218
|
},
|
|
219
219
|
},
|
|
220
220
|
|
|
221
|
+
"issue status": {
|
|
222
|
+
method: "POST",
|
|
223
|
+
action: "getIssueStatus",
|
|
224
|
+
usage:
|
|
225
|
+
"issue status [issueKey] [--issue KEY] [--project KEY]" +
|
|
226
|
+
" (the issue's and its parent's Jira status; needs the Jira API token source; read-only)",
|
|
227
|
+
buildArgs: issueKeyArgs("issue status"),
|
|
228
|
+
},
|
|
229
|
+
"issue branches": {
|
|
230
|
+
method: "POST",
|
|
231
|
+
action: "listIssueBranches",
|
|
232
|
+
usage:
|
|
233
|
+
"issue branches [issueKey] [--issue KEY] [--project KEY]" +
|
|
234
|
+
" (each repo's remote branches for the issue and its parent, as the repo card lists them; read-only)",
|
|
235
|
+
buildArgs: issueKeyArgs("issue branches"),
|
|
236
|
+
},
|
|
237
|
+
"issue prs": {
|
|
238
|
+
method: "POST",
|
|
239
|
+
action: "listIssuePullRequests",
|
|
240
|
+
usage:
|
|
241
|
+
"issue prs [issueKey] [--issue KEY] [--project KEY]" +
|
|
242
|
+
" (each repo's PRs/MRs for the issue in every state, merged and closed included, with" +
|
|
243
|
+
" approvers on open ones; read-only)",
|
|
244
|
+
buildArgs: issueKeyArgs("issue prs"),
|
|
245
|
+
},
|
|
246
|
+
|
|
221
247
|
"mr create": {
|
|
222
248
|
method: "POST",
|
|
223
249
|
retryUnsafe: true,
|
|
@@ -228,7 +254,8 @@ const COMMANDS = {
|
|
|
228
254
|
" (a headBranch that exists on the remote is used as is; otherwise the repo's branch" +
|
|
229
255
|
" template picks the head branch from the issue; --base defaults to the repo's configured base branch, expanding a {year}/{number} pattern;" +
|
|
230
256
|
" --type is auto-selected by matching PR type names against the title prefix, branch prefix," +
|
|
231
|
-
" Jira issue type and title keywords, falling back to the first configured type
|
|
257
|
+
" Jira issue type and title keywords, falling back to the first configured type;" +
|
|
258
|
+
" the description comes from the PR type template, --body is the fallback where {prMedia} is filled or removed)",
|
|
232
259
|
buildArgs: ([title, headBranch], flags, context = {}) => {
|
|
233
260
|
const issueKey = templateIssueKey(headBranch, flags, context);
|
|
234
261
|
|
|
@@ -341,7 +368,10 @@ const COMMANDS = {
|
|
|
341
368
|
" [--base <branch>] [--issue KEY] [--project KEY]" +
|
|
342
369
|
" (--title/--description replace; --append-description adds text after a `---` rule" +
|
|
343
370
|
" and is skipped if it already ends the description after that rule; --base retargets" +
|
|
344
|
-
" the PR/MR to an existing remote branch
|
|
371
|
+
" the PR/MR to an existing remote branch; `{prMedia}` in --description or" +
|
|
372
|
+
" --append-description uploads .devflow/media/<ISSUE-KEY>[-n].{mp4,png,jpg,jpeg} and is" +
|
|
373
|
+
" replaced with the links, so swap old media links for `{prMedia}` to refresh them." +
|
|
374
|
+
" It is removed if the upload fails or the head branch names no issue; media.error says why)",
|
|
345
375
|
buildArgs: ([prId], flags) => {
|
|
346
376
|
const title = toText("title", flags.title);
|
|
347
377
|
const body = toRawText("description", flags.description);
|
|
@@ -377,6 +407,46 @@ const COMMANDS = {
|
|
|
377
407
|
return [parsedPrId, context.issueKey];
|
|
378
408
|
},
|
|
379
409
|
},
|
|
410
|
+
"mr comments": {
|
|
411
|
+
method: "POST",
|
|
412
|
+
action: "getPrReviewCommentCounts",
|
|
413
|
+
usage:
|
|
414
|
+
"mr comments <prId> [--issue KEY] [--project KEY]" +
|
|
415
|
+
" (unfixed / fixed / resolved review-thread and PR-level comment counts; read-only)",
|
|
416
|
+
buildArgs: ([prId]) => [toInt("prId", prId)],
|
|
417
|
+
},
|
|
418
|
+
"mr notify-status": {
|
|
419
|
+
method: "POST",
|
|
420
|
+
action: "getReviewerNotifyStatus",
|
|
421
|
+
usage:
|
|
422
|
+
"mr notify-status <prId> [--issue KEY] [--project KEY]" +
|
|
423
|
+
" (per reviewer channel: whether reviewers were already notified on Slack and whether the" +
|
|
424
|
+
" next step is a send or a ping, and who posted; follow up with `slack notify` for that" +
|
|
425
|
+
" PR; read-only)",
|
|
426
|
+
buildArgs: ([prId]) => [toInt("prId", prId)],
|
|
427
|
+
},
|
|
428
|
+
"mr fix-comments": {
|
|
429
|
+
method: "POST",
|
|
430
|
+
retryUnsafe: true,
|
|
431
|
+
action: "fixPrComments",
|
|
432
|
+
destructive: true,
|
|
433
|
+
usage:
|
|
434
|
+
"mr fix-comments <prId> [--issue KEY] [--project KEY] --force" +
|
|
435
|
+
" (starts an AI fix of the PR's unresolved review comments, which commits and pushes;" +
|
|
436
|
+
" returns at once: started / prNumber / queued, or a reason it was refused, e.g. that PR" +
|
|
437
|
+
" is already being fixed; re-check with `mr comments`)",
|
|
438
|
+
buildArgs: ([prId]) => [toInt("prId", prId)],
|
|
439
|
+
},
|
|
440
|
+
"mr reply-fixed": {
|
|
441
|
+
method: "POST",
|
|
442
|
+
retryUnsafe: true,
|
|
443
|
+
action: "replyPrCommentsFixed",
|
|
444
|
+
usage:
|
|
445
|
+
"mr reply-fixed <prId> [--issue KEY] [--project KEY]" +
|
|
446
|
+
' (replies "Fixed" to every unanswered review thread, resolving it when the repo is set to;' +
|
|
447
|
+
" prints success / failed counts)",
|
|
448
|
+
buildArgs: ([prId]) => [toInt("prId", prId)],
|
|
449
|
+
},
|
|
380
450
|
"pipeline status": {
|
|
381
451
|
method: "POST",
|
|
382
452
|
action: "getPipelineStatus",
|
|
@@ -423,16 +493,27 @@ const COMMANDS = {
|
|
|
423
493
|
retryUnsafe: true,
|
|
424
494
|
action: "notifySlack",
|
|
425
495
|
usage:
|
|
426
|
-
'slack notify <message> [--channel ID] [--values \'{"key":"val"}\'] [--
|
|
496
|
+
'slack notify <message> [--channel ID] [--values \'{"key":"val"}\'] [--pr <prId>]' +
|
|
497
|
+
" [--issue KEY] [--project KEY]" +
|
|
498
|
+
" (--pr records the post as that PR's reviewer notify; a channel already notified for it" +
|
|
499
|
+
" gets a ping threaded under the earlier message)",
|
|
427
500
|
buildArgs: ([message], flags) => {
|
|
428
501
|
if (!message) throw new UsageError("slack notify requires <message>.");
|
|
429
502
|
|
|
430
503
|
const channel = flags.channel ? String(flags.channel) : undefined;
|
|
431
504
|
const values = toValues("values", flags.values);
|
|
432
505
|
|
|
433
|
-
return [message, channel, values];
|
|
506
|
+
if (flags.pr === undefined) return [message, channel, values];
|
|
507
|
+
|
|
508
|
+
return [message, channel, values, { prNumber: toInt("pr", String(flags.pr)) }];
|
|
434
509
|
},
|
|
435
510
|
},
|
|
511
|
+
"slack channels": {
|
|
512
|
+
method: "POST",
|
|
513
|
+
action: "listSlackChannels",
|
|
514
|
+
usage: "slack channels [--issue KEY] [--project KEY] (configured channels; read-only)",
|
|
515
|
+
buildArgs: () => [],
|
|
516
|
+
},
|
|
436
517
|
};
|
|
437
518
|
|
|
438
519
|
/**
|