@devflow-one/cli 0.1.5 → 0.1.6

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 CHANGED
@@ -162,6 +162,10 @@ devflow branch create feat/x
162
162
  devflow branch create feat/x --project ABC
163
163
  devflow mr create "Title" feat/x --body "desc" --project ABC
164
164
 
165
+ # target branch: the repo's configured base branch by default (a {year}/{number}
166
+ # pattern is expanded to the newest matching remote branch), or pick one
167
+ devflow mr create "Title" feat/x --base release/2026.4 --project ABC
168
+
165
169
  # routed by issue key (project key = prefix before the last '-')
166
170
  devflow mr find ABC-123
167
171
  devflow pipeline status 42 deadbeef --issue ABC-9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-one/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Terminal CLI wrapping the local DevFlow gateway so shell scripts can trigger repo actions.",
5
5
  "keywords": [
6
6
  "devflow",
package/src/commands.js CHANGED
@@ -53,6 +53,19 @@ function toValues(flag, raw) {
53
53
  return parsed;
54
54
  }
55
55
 
56
+ /** Parse a value-taking flag as a non-blank string, or fail clearly. */
57
+ function toBranch(flag, raw) {
58
+ if (raw === undefined) return undefined;
59
+
60
+ const branch = String(raw).trim();
61
+
62
+ if (raw === true || branch === "") {
63
+ throw new UsageError(`"--${flag}" requires a branch name.`);
64
+ }
65
+
66
+ return branch;
67
+ }
68
+
56
69
  /** A bad-invocation error (wrong/missing args) — printed with the command usage. */
57
70
  export class UsageError extends Error {
58
71
  constructor(message) {
@@ -116,7 +129,8 @@ const COMMANDS = {
116
129
  method: "POST",
117
130
  action: "commitByTemplate",
118
131
  usage:
119
- 'commit template <worktreePath> [--values \'{"key":"val"}\'] [--no-push] [--issue KEY] [--project KEY]',
132
+ 'commit template <worktreePath> [--values \'{"key":"val"}\'] [--no-push] [--issue KEY] [--project KEY]' +
133
+ " (--values keys must match the {key} tokens of the project's configured commit template)",
120
134
  buildArgs: ([worktreePath], flags) => {
121
135
  if (!worktreePath) throw new UsageError("commit template requires <worktreePath>.");
122
136
 
@@ -130,13 +144,21 @@ const COMMANDS = {
130
144
  "mr create": {
131
145
  method: "POST",
132
146
  action: "createPullRequest",
133
- usage: "mr create <title> <headBranch> [--body <text>] [--issue KEY] [--project KEY]",
147
+ usage:
148
+ "mr create <title> <headBranch> [--body <text>] [--base <branch>] [--issue KEY] [--project KEY]" +
149
+ " (--base defaults to the repo's configured base branch, expanding a {year}/{number} pattern)",
134
150
  buildArgs: ([title, headBranch], flags) => {
135
151
  if (!title || !headBranch) {
136
152
  throw new UsageError("mr create requires <title> and <headBranch>.");
137
153
  }
138
154
 
139
- return [title, flags.body ?? "", headBranch];
155
+ const baseBranch = toBranch("base", flags.base);
156
+
157
+ // Omitted rather than trailing-undefined so the gateway resolves the repo's
158
+ // own configured base branch (and expands a pattern) instead of seeing null.
159
+ return baseBranch
160
+ ? [title, flags.body ?? "", headBranch, baseBranch]
161
+ : [title, flags.body ?? "", headBranch];
140
162
  },
141
163
  },
142
164
  "mr ready": {
@@ -162,8 +162,8 @@ function fill(resolved, source, origin) {
162
162
  * @param {(args: string[]) => string | null} [options.runGit]
163
163
  * @param {(q: { cwd?: string, remote?: string, branch?: string }) => Promise<object | null>} [options.queryContext]
164
164
  * @returns {Promise<{
165
- * projectKey?: string, issueKey?: string, repo?: string, profile?: string,
166
- * profileAlive?: boolean | null, matchedBy: Record<string, string>,
165
+ * projectKey?: string, issueKey?: string, repo?: string, baseBranch?: string,
166
+ * profile?: string, profileAlive?: boolean | null, matchedBy: Record<string, string>,
167
167
  * candidates?: object[], ambiguous?: boolean, warnings: string[]
168
168
  * }>}
169
169
  */
@@ -259,6 +259,9 @@ export async function resolveContext({
259
259
  clean(context.repo?.id) ??
260
260
  clean(context.repo?.name) ??
261
261
  clean(context.repo?.remoteUrl),
262
+ // The selector `repo` flattens the digest to one string; the configured
263
+ // base branch rides alongside it so a caller can target it explicitly.
264
+ baseBranch: clean(context.repo?.baseBranch),
262
265
  profile: clean(context.profileId),
263
266
  }),
264
267
  },