@phnx-labs/agents-cli 1.20.48 → 1.20.49

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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.20.49
6
+
7
+ - **`agents run --mode plan` no longer hard-fails on agents without a read-only mode (antigravity, cursor, kiro, …).** Those agents have no plan flag, so an explicit or default `--mode plan` used to abort with `does not support 'plan' mode` — breaking multi-agent scripts that pass a uniform plan flag, and diverging from `agents teams add` (default mode `edit`). `resolveMode` now degrades unsupported `plan` to the agent's safest native mode (`capabilities.modes[0]`, typically `edit`), matching the existing `auto` → `edit` degrade. The CLI prints a yellow warning when the user explicitly asked for plan (gray for the implicit default) so the elevation is never silent. `skip` still hard-fails when unsupported. Source: `apps/cli/src/lib/exec.ts`, `apps/cli/src/commands/exec.ts`.
8
+ - **`agents cloud cancel` now actually cancels paused runs.** `RushProvider.cancel()` issued `DELETE /api/v1/cloud-runs/{id}`, which the backend doesn't implement — it 404s — so `agents cloud cancel` (and the Factory Floor's cancel affordance) silently failed on any run that wasn't actively running: `queued`, `needs_review`, and `input_required` runs stayed stuck (e.g. a 14-day-old input-required run lingering in the Floor's "NEEDS YOU" bucket forever). Switched to the cancel action endpoint `POST /api/v1/cloud-runs/{id}/cancel`, which the backend implements and which cancels paused runs too. Verified live against `api.prix.dev` (the POST returned `{"ok":true,"status":"cancelled"}` and the stuck run transitioned `needs_review` → `cancelled`). Source: `apps/cli/src/lib/cloud/rush.ts`.
9
+
5
10
  ## 1.20.48
6
11
 
7
12
  - **Menu-bar helper: a RECENT TICKETS section shows the issues you filed via the quick-issue bar, each clickable to open in Linear.** The completion notification is transient, so the tickets the `Cmd-Shift-O` bar creates now also persist to a small local ledger (`~/.agents/.history/menubar/recent-tickets.json`, newest-first, deduped by id, capped at 10) that the menu-bar dropdown surfaces below RECENT sessions — click a row to open the ticket. The dispatch records the id + note + Linear URL on a successful create; the section renders nothing when the ledger is empty. Source: `apps/cli/menubar/Sources/MenubarHelper/{RecentTickets,StatusItemController,AgentsCLI,IssueSelfTest}.swift`.
@@ -570,7 +570,7 @@ export function registerRunCommand(program) {
570
570
  });
571
571
  process.exit(resumeExit);
572
572
  }
573
- const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, defaultModeFor, headlessPlanStallCommand, nativeResume, resolveInteractive }, { ALL_AGENT_IDS }, { profileExists, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports },] = await Promise.all([
573
+ const [{ buildExecCommand, parseExecEnv, execAgent, runWithFallback, normalizeMode, resolveMode, headlessPlanStallCommand, nativeResume, resolveInteractive }, { ALL_AGENT_IDS }, { profileExists, resolveProfileForRun }, { readAndResolveBundleEnv, describeBundle, assertRemoteBundleFlagsUnsupported }, { splitBundleRef, resolveSshTarget, remoteResolveEnv }, { getConfiguredRunStrategy, normalizeRunStrategy, resolveRunVersion, rotationFailoverChain, shouldArmRotationFailover, RUN_STRATEGIES }, { getGlobalDefault, getVersionHomePath, resolveVersion, resolveVersionAlias, ensureAgentRunnable }, { buildDiscoveredPlugin, loadPluginManifest, syncPluginToVersion }, { parseWorkflowFrontmatter, resolveWorkflowRef, resolveAllowedSubagents, pruneStaleWorkflowSubagents }, { resolveRunDefaults }, { getMcpServersByName, buildWorkflowMcpConfig }, { supports },] = await Promise.all([
574
574
  import('../lib/exec.js'),
575
575
  import('../lib/agents.js'),
576
576
  import('../lib/profiles.js'),
@@ -1017,28 +1017,38 @@ export function registerRunCommand(program) {
1017
1017
  console.error(chalk.red(`Invalid mode: ${mode}. Use plan, edit, auto, or skip ('full' accepted as alias for skip).`));
1018
1018
  process.exit(1);
1019
1019
  }
1020
- // When the user did not pass --mode explicitly, the default is the
1021
- // generic 'plan'. Some agents (antigravity: edit/skip only, grok in some
1022
- // configurations) do not support plan. For implicit defaults, degrade
1023
- // silently to the agent's first listed mode rather than throwing — the
1024
- // user did not ask for read-only, they asked for "just run it." An
1025
- // explicit --mode plan still throws (see resolveMode), because silently
1026
- // elevating an explicit read-only request to edit is unsafe.
1020
+ // Default CLI mode is the generic 'plan'. Agents without a read-only
1021
+ // mode (antigravity, cursor, kiro, …) degrade via resolveMode to their
1022
+ // safest native mode (modes[0], typically edit). That covers both the
1023
+ // implicit default and an explicit `--mode plan`, so multi-agent
1024
+ // scripts can pass a uniform plan flag without per-agent branching.
1025
+ // Elevation is never silent: we warn on stderr (yellow when the user
1026
+ // explicitly asked for plan; gray for the implicit default / auto).
1027
+ // `skip` still hard-fails when unsupported — pretending we bypassed
1028
+ // permissions would be unsafe.
1027
1029
  const modeIsDefault = modeSource === 'default';
1030
+ const requestedMode = normalizeMode(mode);
1031
+ let resolvedMode;
1028
1032
  try {
1029
- resolveMode(agent, normalizeMode(mode));
1033
+ resolvedMode = resolveMode(agent, requestedMode);
1030
1034
  }
1031
1035
  catch (err) {
1032
- if (modeIsDefault && !modeFromRunDefault) {
1033
- mode = defaultModeFor(agent);
1034
- if (!options.quiet) {
1035
- process.stderr.write(chalk.gray(`[agents] ${agent} has no '${options.mode}' mode; using '${mode}'\n`));
1036
+ console.error(chalk.red(err.message));
1037
+ process.exit(1);
1038
+ }
1039
+ if (resolvedMode !== requestedMode) {
1040
+ mode = resolvedMode;
1041
+ if (!options.quiet) {
1042
+ if (requestedMode === 'plan' && !modeIsDefault) {
1043
+ process.stderr.write(chalk.yellow(`[agents] ${agent} has no read-only 'plan' mode; using '${mode}' (writable) instead. Pass --mode ${mode} to silence this.\n`));
1044
+ }
1045
+ else {
1046
+ process.stderr.write(chalk.gray(`[agents] ${agent} has no '${requestedMode}' mode; using '${mode}'\n`));
1036
1047
  }
1037
1048
  }
1038
- else {
1039
- console.error(chalk.red(err.message));
1040
- process.exit(1);
1041
- }
1049
+ }
1050
+ else {
1051
+ mode = resolvedMode;
1042
1052
  }
1043
1053
  // Fail fast on the headless-plan stall footgun: a slash command run
1044
1054
  // headless under the implicit default 'plan' mode hangs forever at
@@ -525,7 +525,11 @@ export class RushCloudProvider {
525
525
  }
526
526
  async cancel(taskId) {
527
527
  const token = readToken();
528
- const res = await api('DELETE', `/api/v1/cloud-runs/${encodeURIComponent(taskId)}`, token);
528
+ // The cancel ACTION endpoint (POST .../cancel) is what the backend implements;
529
+ // it works on paused runs too (queued / needs_review / input_required). A bare
530
+ // DELETE on the run 404s, so `agents cloud cancel` silently failed on anything
531
+ // that wasn't actively running.
532
+ const res = await api('POST', `/api/v1/cloud-runs/${encodeURIComponent(taskId)}/cancel`, token);
529
533
  if (!res.ok) {
530
534
  throw new Error(`Failed to cancel task (${res.status}).`);
531
535
  }
@@ -40,10 +40,16 @@ export declare function headlessPlanStallCommand(args: {
40
40
  *
41
41
  * - `auto` on an agent without auto support silently degrades to `edit`
42
42
  * (every agent supports edit-like behavior as its default).
43
+ * - `plan` on an agent without a read-only mode degrades to the agent's
44
+ * safest native mode (`capabilities.modes[0]`, typically `edit`). Agents
45
+ * like antigravity/cursor/kiro have no plan flag; hard-failing made
46
+ * multi-agent scripts (`--mode plan` for everyone) unusable and diverged
47
+ * from `agents teams add`, which already defaults to `edit`. Callers that
48
+ * care (the `agents run` CLI) must surface a warning when requested ≠
49
+ * resolved so the elevation is not silent.
43
50
  * - `skip` on an agent without skip support throws with a clear message
44
51
  * naming the agent's supported modes. No silent fallback — the user
45
52
  * explicitly asked to bypass permissions; pretending we did is unsafe.
46
- * - `plan` on an agent without plan support throws the same way.
47
53
  */
48
54
  export declare function resolveMode(agent: AgentId, requested: Mode): Mode;
49
55
  /**
@@ -54,10 +60,8 @@ export declare function resolveMode(agent: AgentId, requested: Mode): Mode;
54
60
  * supports." Agents that include `plan` list it first; agents like
55
61
  * antigravity that have no read-only mode list `edit` first.
56
62
  *
57
- * Use this when the user did not pass `--mode` explicitly. When the user
58
- * *did* pass `--mode plan` and the agent doesn't support it, call
59
- * `resolveMode` instead so the user sees a loud error rather than a silent
60
- * elevation from read-only to writable.
63
+ * Prefer this over a hard-coded `'plan'` when the agent is known. `resolveMode`
64
+ * also maps an unsupported `'plan'` request onto this same value.
61
65
  */
62
66
  export declare function defaultModeFor(agent: AgentId): Mode;
63
67
  /** Reasoning effort levels passed to agents that support them. 'auto' defers to the agent's default. */
package/dist/lib/exec.js CHANGED
@@ -75,10 +75,16 @@ export function headlessPlanStallCommand(args) {
75
75
  *
76
76
  * - `auto` on an agent without auto support silently degrades to `edit`
77
77
  * (every agent supports edit-like behavior as its default).
78
+ * - `plan` on an agent without a read-only mode degrades to the agent's
79
+ * safest native mode (`capabilities.modes[0]`, typically `edit`). Agents
80
+ * like antigravity/cursor/kiro have no plan flag; hard-failing made
81
+ * multi-agent scripts (`--mode plan` for everyone) unusable and diverged
82
+ * from `agents teams add`, which already defaults to `edit`. Callers that
83
+ * care (the `agents run` CLI) must surface a warning when requested ≠
84
+ * resolved so the elevation is not silent.
78
85
  * - `skip` on an agent without skip support throws with a clear message
79
86
  * naming the agent's supported modes. No silent fallback — the user
80
87
  * explicitly asked to bypass permissions; pretending we did is unsafe.
81
- * - `plan` on an agent without plan support throws the same way.
82
88
  */
83
89
  export function resolveMode(agent, requested) {
84
90
  const supported = AGENTS[agent].capabilities.modes;
@@ -89,6 +95,12 @@ export function resolveMode(agent, requested) {
89
95
  // at least 'edit' in its modes table, since that's the default behavior).
90
96
  return 'edit';
91
97
  }
98
+ if (requested === 'plan') {
99
+ // No read-only mode on this agent. modes[0] is the declared safest mode
100
+ // (edit for antigravity/cursor/kiro/…). Prefer that over hard-fail so
101
+ // uniform multi-agent `--mode plan` dispatches still run.
102
+ return supported[0];
103
+ }
92
104
  throw new Error(`${agent} does not support '${requested}' mode. Supported modes: ${supported.join(', ')}.`);
93
105
  }
94
106
  /**
@@ -99,10 +111,8 @@ export function resolveMode(agent, requested) {
99
111
  * supports." Agents that include `plan` list it first; agents like
100
112
  * antigravity that have no read-only mode list `edit` first.
101
113
  *
102
- * Use this when the user did not pass `--mode` explicitly. When the user
103
- * *did* pass `--mode plan` and the agent doesn't support it, call
104
- * `resolveMode` instead so the user sees a loud error rather than a silent
105
- * elevation from read-only to writable.
114
+ * Prefer this over a hard-coded `'plan'` when the agent is known. `resolveMode`
115
+ * also maps an unsupported `'plan'` request onto this same value.
106
116
  */
107
117
  export function defaultModeFor(agent) {
108
118
  return AGENTS[agent].capabilities.modes[0];
@@ -541,7 +551,8 @@ export function buildExecCommand(options) {
541
551
  }
542
552
  // Resolve the requested mode against the agent's capability table.
543
553
  // - `auto` on an agent without auto support → silently degrades to `edit`
544
- // - `skip`/`plan` on an unsupported agent → throws a clear error
554
+ // - `plan` on an agent without a read-only mode degrades to modes[0]
555
+ // - `skip` on an unsupported agent → throws a clear error
545
556
  // After resolveMode, the chosen mode is guaranteed to be in template.modeFlags.
546
557
  const resolvedMode = resolveMode(options.agent, normalizeMode(options.mode));
547
558
  const modeFlags = template.modeFlags[resolvedMode];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phnx-labs/agents-cli",
3
- "version": "1.20.48",
3
+ "version": "1.20.49",
4
4
  "description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",