@devflow-one/cli 0.1.7 → 0.1.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-one/cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
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/cli.js CHANGED
@@ -77,6 +77,15 @@ function printResult(result, json, stdout) {
77
77
  }
78
78
  }
79
79
 
80
+ /** Echo a result's `warnings` to stderr so they stay visible next to --json stdout. */
81
+ function printWarnings(result, stderr) {
82
+ const warnings = Array.isArray(result?.warnings) ? result.warnings : [];
83
+
84
+ for (const warning of warnings) {
85
+ stderr(`warning: ${warning}`);
86
+ }
87
+ }
88
+
80
89
  /** Print an error, honoring --json, to stderr. */
81
90
  function printError(err, json, stderr) {
82
91
  const code = err instanceof GatewayError ? err.code : err.name;
@@ -217,6 +226,7 @@ export async function run(argv, io = {}) {
217
226
  const result = await request(config, "POST", `/actions/${action}`, body);
218
227
 
219
228
  printResult(result, Boolean(flags.json), stdout);
229
+ printWarnings(result, stderr);
220
230
 
221
231
  return 0;
222
232
  } catch (err) {
package/src/commands.js CHANGED
@@ -143,7 +143,10 @@ const COMMANDS = {
143
143
  action: "commitByTemplate",
144
144
  usage:
145
145
  'commit template <worktreePath> [--values \'{"key":"val"}\'] [--no-push] [--issue KEY] [--project KEY]' +
146
- " (--values keys must match the {key} tokens of the project's configured commit template)",
146
+ " (--values keys fill the project's commit template, default" +
147
+ ' "{summary}\\n\\n{changesList}\\n\\n{issueSlug}": summary, changesList (string array,' +
148
+ " rendered as bullets), issueSlug, prNumber; missing keys are left empty and reported" +
149
+ " as warnings on stderr)",
147
150
  buildArgs: ([worktreePath], flags) => {
148
151
  if (!worktreePath) throw new UsageError("commit template requires <worktreePath>.");
149
152
 
package/src/context.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // The resolver itself (contextResolver.js) is generated from shared/ and must not
6
6
  // be edited here; everything CLI-specific lives in this file.
7
7
 
8
- import { resolveContext } from "./contextResolver.js";
8
+ import { issueKeyToProjectKey, resolveContext } from "./contextResolver.js";
9
9
  import { createGitRunner } from "./gitFacts.js";
10
10
  import { GatewayError } from "./client.js";
11
11
  import { UsageError } from "./commands.js";
@@ -84,13 +84,7 @@ export function resolveCliContext(
84
84
  export function projectKeyFrom(context) {
85
85
  if (context.projectKey) return context.projectKey.toUpperCase();
86
86
 
87
- if (context.issueKey) {
88
- const lastDash = context.issueKey.lastIndexOf("-");
89
-
90
- return (lastDash === -1 ? context.issueKey : context.issueKey.slice(0, lastDash)).toUpperCase();
91
- }
92
-
93
- return undefined;
87
+ return issueKeyToProjectKey(context.issueKey);
94
88
  }
95
89
 
96
90
  /** Describe one ambiguity candidate as `PROJECT/repo (profile)`. */
@@ -56,11 +56,11 @@ function clean(value) {
56
56
 
57
57
  /**
58
58
  * The project a key or issue key belongs to: split on the LAST `-` and uppercase
59
- * (`abc-123` → `ABC`). Mirrors `issueKeyToProjectKey` in the daemon's routing.js.
60
- * @param {string | undefined} value
61
- * @returns {string | undefined}
59
+ * (`abc-123` → `ABC`). A value with no `-` is already a project key.
60
+ * @param {unknown} value
61
+ * @returns {string | undefined} `undefined` for a non-string or blank value
62
62
  */
63
- function projectOf(value) {
63
+ export function issueKeyToProjectKey(value) {
64
64
  const trimmed = clean(value);
65
65
 
66
66
  if (!trimmed) return undefined;
@@ -227,16 +227,10 @@ export async function resolveContext({
227
227
  // so the reported precedence step reflects the real reason, not a guess.
228
228
  const origin = context.matchedBy === "remote" ? "gitRemote" : "localPath";
229
229
 
230
- // The daemon answered "this CHECKOUT belongs to project P". Its repo, profile,
231
- // liveness and issue key all describe P — they are only meaningful together.
232
- // If the caller already pinned a different project, adopting them field-by-field
233
- // would aim the action at P's repository under the caller's key: silent
234
- // mis-targeting, and worse than a failure because nothing looks wrong. So the
235
- // whole group is discarded on disagreement. Note this compares the KEYS, not
236
- // merely where they came from — a caller who names the project the checkout
237
- // already matches is agreeing, and must still get its repo/profile.
238
- const pinned = projectOf(resolved.projectKey) ?? projectOf(resolved.issueKey);
239
- const matched = projectOf(context.projectKey);
230
+ // A pinned project that disagrees with the match discards its repo/profile/issue together.
231
+ const pinned =
232
+ issueKeyToProjectKey(resolved.projectKey) ?? issueKeyToProjectKey(resolved.issueKey);
233
+ const matched = issueKeyToProjectKey(context.projectKey);
240
234
  const conflict = Boolean(pinned && matched && pinned !== matched);
241
235
 
242
236
  if (conflict) {
@@ -20,7 +20,7 @@ export const APP_DIR_NAME = "devflow";
20
20
  /** Filename the daemon writes the gateway token to, under the data dir. */
21
21
  export const TOKEN_FILE = "gateway-token";
22
22
 
23
- /** Default gateway port — must match desktop/src/gateway/server.js. */
23
+ /** Default gateway port, shared by the daemon and every client. */
24
24
  export const DEFAULT_PORT = 8787;
25
25
 
26
26
  /** Loopback host; the gateway only ever binds 127.0.0.1. */