@phnx-labs/agents-cli 1.20.66 → 1.20.67

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
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.20.67
4
+
5
+ - **Interactive session browser — `agents sessions --active` and a bare `agents sessions`
6
+ now open a live, filterable picker on a TTY (RUSH-1802).** One canonical filter driven by
7
+ single keys, re-pulled across the fleet as you toggle: `s` search, `r` running-only, `c`
8
+ teams, `a` agent (cycles), `d` device (cycles), `p` this-repo↔all-dirs, `w` time window;
9
+ filters **stack** (AND together) and the active set shows in the header, with a live
10
+ preview of the highlighted row and `⏎` to resume/attach via the existing dispatch. Every
11
+ hotkey mirrors a flag, so the view is reproducible as a command — `y` copies (and
12
+ `--print-cmd` prints) the exact `ag sessions …` line the filters map to, bridging the
13
+ human picker and the agent/script flag surface. The interactive front-end is TTY-only:
14
+ `--json`, a pipe, or the new `--no-interactive` keep the existing static listing verbatim,
15
+ so scripts and headless agents are unchanged. Adds `-p` as the short form of `--project`,
16
+ `--print-cmd`, `--preview` (`agents sessions <id> --preview` prints the compact digest
17
+ without the pager), and `--no-interactive`. Built on a new async-refetch `dynamicPicker`
18
+ variant that reuses the existing render/pagination/preview machinery, the fleet SSH
19
+ fan-out, and the resume/focus path. Source: `apps/cli/src/lib/picker.ts` (`dynamicPicker`),
20
+ `apps/cli/src/commands/sessions-browser.ts` (+ `sessions-browser.test.ts`),
21
+ `apps/cli/src/commands/sessions.ts`.
22
+
23
+ - **kimi/grok headless `--mode plan` now auto-downgrades to `auto` instead of
24
+ crashing or stalling (RUSH-1810).** kimi's headless `-p` refuses to combine with
25
+ `--plan` (it hard-failed at spawn) and grok's `--permission-mode plan` silently
26
+ stalls a headless run at its ExitPlanMode gate. Both now model this honestly with
27
+ a `capabilities.headlessPlan: false` flag: a headless plan request degrades to
28
+ `auto` (kimi `-p` auto-runs; grok maps `auto`→`edit`) with a one-line stderr
29
+ warning, mirroring the graceful plan→edit degrade cursor/antigravity already get.
30
+ Interactive plan is unchanged, and claude/codex/droid/opencode keep read-only
31
+ plan headless. The same downgrade covers `agents run`, `agents teams add`
32
+ teammates, and routine jobs. Source: `apps/cli/src/lib/exec.ts`
33
+ (`resolveHeadlessMode`), `apps/cli/src/lib/runner.ts`, `apps/cli/src/lib/agents.ts`,
34
+ `apps/cli/src/lib/types.ts`.
35
+
3
36
  ## 1.20.66
4
37
 
5
38
  - **Fix (`agents monitors`, RUSH-1782 follow-up): `--watch-device` no longer silently watches the local machine on a bad name.** An unregistered or mistyped `--watch-device` name is now rejected at `add` time (same registry gate as `--device`/`--devices`), and the device source evaluator returns an explicit `device not registered` observation instead of falling back to local stats if a watched device is removed later — closing a "monitors the wrong box, silently" gap. The rate-limit firehose trip now also writes a fire record (`ok:false, error:'rate limited'`), so `agents monitors runs` reflects the auto-pause that `view`'s `last fired` already showed. Adds `sources/device.test.ts`. Source: `apps/cli/src/lib/monitors/sources/device.ts`, `apps/cli/src/commands/monitors.ts`, `apps/cli/src/lib/monitors/engine.ts`.
package/dist/bin/agents CHANGED
Binary file
@@ -328,6 +328,12 @@ export function registerRunCommand(program) {
328
328
  skip bypass every permission prompt (dangerously-skip-permissions)
329
329
  Legacy 'full' is silently rewritten to 'skip'.
330
330
 
331
+ Headless plan support (a prompt makes the run headless):
332
+ plan works headless on claude, codex, droid, opencode.
333
+ kimi, grok, cursor, antigravity have no headless plan mode — a headless
334
+ --mode plan auto-downgrades to --mode auto (with a stderr warning).
335
+ Interactive plan (omit the prompt) works everywhere it is listed.
336
+
331
337
  Run strategy (set via --strategy or run.<agent>.strategy in agents.yaml):
332
338
  pinned use the workspace/global pinned version
333
339
  available use pinned if it can run right now; otherwise switch to another signed-in version
@@ -1059,7 +1059,7 @@ export function registerTeamsCommands(program) {
1059
1059
  .alias('a')
1060
1060
  .description("Add a teammate to work on a task. Runs in background; returns immediately. Use 'status' to check in.")
1061
1061
  .option('-n, --name <name>', 'Friendly name for this teammate (e.g. alice). Required if using --after. Unique within team.')
1062
- .option('-m, --mode <mode>', `Permissions: plan (read-only) | edit (can write files) | auto (smart classifier auto-approves safe ops) | skip (bypass all permission prompts). 'full' accepted as alias for skip.`, 'edit')
1062
+ .option('-m, --mode <mode>', `Permissions: plan (read-only) | edit (can write files) | auto (smart classifier auto-approves safe ops) | skip (bypass all permission prompts). 'full' accepted as alias for skip. Teammates run headless: plan works headless on claude/codex/droid/opencode; kimi/grok/cursor/antigravity have no headless plan mode and auto-downgrade a plan request to auto.`, 'edit')
1063
1063
  .option('-e, --effort <effort>', `Reasoning intensity: ${VALID_EFFORTS.join('|')}`, 'medium')
1064
1064
  .option('--model <model>', 'Override the effort tier and use this specific model (e.g. claude-opus-4-6)')
1065
1065
  .option('--env <key=value>', 'Set an environment variable for this teammate (repeatable for multiple vars)', (val, prev) => [...prev, val], [])
@@ -505,6 +505,10 @@ export const AGENTS = {
505
505
  workflows: false,
506
506
  memory: true,
507
507
  modes: ['plan', 'edit', 'skip'],
508
+ // grok's `--permission-mode plan` silently stalls a headless `-p` run at
509
+ // its ExitPlanMode gate (no TTY to approve). Headless plan auto-downgrades
510
+ // to auto (→ edit via resolveMode). Interactive plan is unaffected.
511
+ headlessPlan: false,
508
512
  rulesImports: true,
509
513
  },
510
514
  },
@@ -544,6 +548,10 @@ export const AGENTS = {
544
548
  workflows: true,
545
549
  memory: false,
546
550
  modes: ['plan', 'edit', 'auto', 'skip'],
551
+ // kimi's headless `-p` refuses to combine with `--plan` (`Cannot combine
552
+ // --prompt with --plan`). Headless plan auto-downgrades to auto (kimi -p
553
+ // auto-runs). Interactive plan is unaffected.
554
+ headlessPlan: false,
547
555
  rulesImports: false,
548
556
  },
549
557
  },
@@ -52,6 +52,21 @@ export declare function headlessPlanStallCommand(args: {
52
52
  * explicitly asked to bypass permissions; pretending we did is unsafe.
53
53
  */
54
54
  export declare function resolveMode(agent: AgentId, requested: Mode): Mode;
55
+ /**
56
+ * Resolve a requested mode for a run, honoring whether the run is HEADLESS.
57
+ *
58
+ * Wraps resolveMode with one extra rule: an agent may list `plan` in its modes
59
+ * (so interactive plan works) yet declare `capabilities.headlessPlan === false`
60
+ * because plan is broken in a headless `--prompt`/`-p` run — kimi refuses
61
+ * `--prompt` + `--plan`, and grok's `--permission-mode plan` silently stalls at
62
+ * its ExitPlanMode gate. For those agents, a headless plan request degrades to
63
+ * `auto` (kimi -p auto-runs; grok maps auto→edit via resolveMode) with a visible
64
+ * one-line stderr warning, mirroring the graceful plan→edit degrade cursor and
65
+ * antigravity get for having no plan flag at all. Interactive runs are never
66
+ * downgraded. This is the single source of truth shared by buildExecCommand
67
+ * (agents run / teams) and the routine runner.
68
+ */
69
+ export declare function resolveHeadlessMode(agent: AgentId, requested: Mode, interactive: boolean): Mode;
55
70
  /**
56
71
  * The mode an agent should run in when the caller has no preference.
57
72
  *
package/dist/lib/exec.js CHANGED
@@ -104,6 +104,28 @@ export function resolveMode(agent, requested) {
104
104
  }
105
105
  throw new Error(`${agent} does not support '${requested}' mode. Supported modes: ${supported.join(', ')}.`);
106
106
  }
107
+ /**
108
+ * Resolve a requested mode for a run, honoring whether the run is HEADLESS.
109
+ *
110
+ * Wraps resolveMode with one extra rule: an agent may list `plan` in its modes
111
+ * (so interactive plan works) yet declare `capabilities.headlessPlan === false`
112
+ * because plan is broken in a headless `--prompt`/`-p` run — kimi refuses
113
+ * `--prompt` + `--plan`, and grok's `--permission-mode plan` silently stalls at
114
+ * its ExitPlanMode gate. For those agents, a headless plan request degrades to
115
+ * `auto` (kimi -p auto-runs; grok maps auto→edit via resolveMode) with a visible
116
+ * one-line stderr warning, mirroring the graceful plan→edit degrade cursor and
117
+ * antigravity get for having no plan flag at all. Interactive runs are never
118
+ * downgraded. This is the single source of truth shared by buildExecCommand
119
+ * (agents run / teams) and the routine runner.
120
+ */
121
+ export function resolveHeadlessMode(agent, requested, interactive) {
122
+ const mode = resolveMode(agent, requested);
123
+ if (!interactive && mode === 'plan' && AGENTS[agent].capabilities.headlessPlan === false) {
124
+ process.stderr.write(`warning: ${agent} has no headless plan mode; running --mode auto instead\n`);
125
+ return resolveMode(agent, 'auto');
126
+ }
127
+ return mode;
128
+ }
107
129
  /**
108
130
  * The mode an agent should run in when the caller has no preference.
109
131
  *
@@ -573,9 +595,11 @@ export function buildExecCommand(options) {
573
595
  // Resolve the requested mode against the agent's capability table.
574
596
  // - `auto` on an agent without auto support → silently degrades to `edit`
575
597
  // - `plan` on an agent without a read-only mode → degrades to modes[0]
598
+ // - headless `plan` on an agent with headlessPlan:false (kimi, grok) →
599
+ // degrades to `auto` with a stderr warning (see resolveHeadlessMode)
576
600
  // - `skip` on an unsupported agent → throws a clear error
577
- // After resolveMode, the chosen mode is guaranteed to be in template.modeFlags.
578
- const resolvedMode = resolveMode(options.agent, normalizeMode(options.mode));
601
+ // After resolution, the chosen mode is guaranteed to be in template.modeFlags.
602
+ const resolvedMode = resolveHeadlessMode(options.agent, normalizeMode(options.mode), interactive);
579
603
  const modeFlags = template.modeFlags[resolvedMode];
580
604
  if (!modeFlags) {
581
605
  // Defense in depth: would only fire if AGENTS.capabilities.modes and
@@ -609,11 +633,12 @@ export function buildExecCommand(options) {
609
633
  // all abort with "Cannot combine --prompt with --X" (verified against the live
610
634
  // kimi CLI). The write-capable modes (edit/auto/skip) all collapse to kimi's
611
635
  // default `-p` behavior, which already auto-approves tool calls, so we emit no
612
- // mode flag. Plan (read-only) has no headless equivalent, so fail closed rather
613
- // than silently letting a plan-mode run mutate the workspace.
636
+ // mode flag. Plan can't reach here headless resolveHeadlessMode already
637
+ // downgraded it to auto (kimi's headlessPlan:false); this asserts that
638
+ // invariant so a plan-mode run can never silently mutate the workspace.
614
639
  if (resolvedMode === 'plan') {
615
- throw new Error('kimi has no headless read-only mode: `--prompt` cannot be combined with `--plan`. ' +
616
- 'Run kimi in plan mode interactively (omit the prompt), or use --mode edit, auto, or skip.');
640
+ throw new Error(`Internal error: kimi reached headless command build with resolved mode 'plan'; ` +
641
+ `resolveHeadlessMode should have downgraded it to auto (capabilities.headlessPlan is false).`);
617
642
  }
618
643
  // edit/auto/skip: emit no mode flag — `kimi -p` auto-runs.
619
644
  }
@@ -22,7 +22,7 @@ import { getRunsDir } from './state.js';
22
22
  import { prepareJobHome, buildSpawnEnv } from './sandbox.js';
23
23
  import { resolveModel, buildReasoningFlags } from './models.js';
24
24
  import { createTimer, maybeRotate, redactPrompt } from './events.js';
25
- import { normalizeMode, buildExecEnv, detectRateLimit, } from './exec.js';
25
+ import { normalizeMode, resolveHeadlessMode, buildExecEnv, detectRateLimit, } from './exec.js';
26
26
  import { loadTask as loadHostTask } from './hosts/tasks.js';
27
27
  import { reconcileTask as reconcileHostTask } from './hosts/reconcile.js';
28
28
  import { backgroundSpawnOptions } from './platform/process.js';
@@ -129,12 +129,11 @@ export function buildJobCommand(config, resolvedPrompt) {
129
129
  // kimi daemon jobs always run headless via `--prompt`, which cannot be
130
130
  // combined with any startup-mode flag (--plan/--auto/--yolo all abort with
131
131
  // "Cannot combine --prompt with --X"). edit/auto/skip reduce to kimi's default
132
- // headless auto-run, so emit no flag; plan has no headless read-only
133
- // equivalent, so fail closed rather than silently allowing writes.
134
- if (mode === 'plan') {
135
- throw new Error('kimi has no headless read-only mode: routine jobs cannot run kimi with --mode plan ' +
136
- '(kimi rejects --prompt + --plan). Use --mode edit, auto, or skip.');
137
- }
132
+ // headless auto-run, so emit no flag. plan has no headless read-only
133
+ // equivalent, so resolveHeadlessMode downgrades a plan request to auto with a
134
+ // stderr warning (kimi's headlessPlan is false) — routines run headless, so
135
+ // interactive is always false here. The returned mode carries no flag either.
136
+ resolveHeadlessMode('kimi', mode, false);
138
137
  appendModelAndReasoning(cmd, config);
139
138
  }
140
139
  if (config.agent === 'droid') {
@@ -160,6 +160,16 @@ export interface AgentConfig {
160
160
  * `skip` errors with a clear message naming the supported modes.
161
161
  */
162
162
  modes: Mode[];
163
+ /**
164
+ * Whether `plan` mode works in a HEADLESS run (`--prompt`/`-p`). Some CLIs
165
+ * list a `plan` mode that only works interactively — kimi refuses `--prompt`
166
+ * combined with `--plan`, and grok's `--permission-mode plan` silently stalls
167
+ * a headless run at its ExitPlanMode gate. Absent (undefined) means true:
168
+ * headless plan is assumed to work unless a agent opts out with `false`, in
169
+ * which case a headless `--mode plan` request auto-downgrades to `auto`
170
+ * (see resolveHeadlessMode). Interactive plan is unaffected.
171
+ */
172
+ headlessPlan?: boolean;
163
173
  /**
164
174
  * Whether the agent natively resolves `@path/to/file` imports inside its
165
175
  * rules file at session start. If false, agents-cli must pre-compile the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phnx-labs/agents-cli",
3
- "version": "1.20.66",
3
+ "version": "1.20.67",
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",