@phnx-labs/agents-cli 1.20.78 → 1.20.83

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.
Files changed (183) hide show
  1. package/CHANGELOG.md +595 -0
  2. package/README.md +26 -26
  3. package/dist/bin/agents +0 -0
  4. package/dist/commands/activity.d.ts +9 -0
  5. package/dist/commands/activity.js +153 -24
  6. package/dist/commands/apply.js +11 -4
  7. package/dist/commands/cli.js +1 -1
  8. package/dist/commands/commands.d.ts +1 -1
  9. package/dist/commands/commands.js +7 -6
  10. package/dist/commands/defaults.js +3 -11
  11. package/dist/commands/doctor.d.ts +66 -0
  12. package/dist/commands/doctor.js +596 -33
  13. package/dist/commands/events.js +1 -1
  14. package/dist/commands/exec.js +24 -5
  15. package/dist/commands/feed.d.ts +4 -0
  16. package/dist/commands/feed.js +87 -11
  17. package/dist/commands/harness.js +2 -2
  18. package/dist/commands/hooks.js +1 -1
  19. package/dist/commands/import.js +8 -4
  20. package/dist/commands/logs.js +6 -0
  21. package/dist/commands/menubar.js +12 -0
  22. package/dist/commands/models.js +1 -1
  23. package/dist/commands/packages.js +6 -6
  24. package/dist/commands/permissions.js +1 -1
  25. package/dist/commands/profiles.js +1 -1
  26. package/dist/commands/pull.d.ts +1 -1
  27. package/dist/commands/pull.js +4 -4
  28. package/dist/commands/repo.d.ts +78 -0
  29. package/dist/commands/repo.js +187 -11
  30. package/dist/commands/routines.d.ts +8 -1
  31. package/dist/commands/routines.js +241 -77
  32. package/dist/commands/rules.js +13 -12
  33. package/dist/commands/secrets.d.ts +3 -1
  34. package/dist/commands/secrets.js +100 -32
  35. package/dist/commands/sessions-inject.d.ts +7 -4
  36. package/dist/commands/sessions-inject.js +18 -18
  37. package/dist/commands/sessions-picker.js +32 -3
  38. package/dist/commands/sessions-resume.d.ts +16 -0
  39. package/dist/commands/sessions-resume.js +14 -13
  40. package/dist/commands/sessions.d.ts +115 -0
  41. package/dist/commands/sessions.js +189 -35
  42. package/dist/commands/set.d.ts +15 -0
  43. package/dist/commands/set.js +79 -0
  44. package/dist/commands/setup-fleet.d.ts +21 -0
  45. package/dist/commands/setup-fleet.js +201 -0
  46. package/dist/commands/setup-secrets.d.ts +20 -0
  47. package/dist/commands/setup-secrets.js +223 -0
  48. package/dist/commands/setup.js +17 -3
  49. package/dist/commands/skills.js +1 -1
  50. package/dist/commands/sync.js +7 -2
  51. package/dist/commands/teams-picker.js +0 -1
  52. package/dist/commands/teams.d.ts +33 -1
  53. package/dist/commands/teams.js +208 -44
  54. package/dist/commands/versions.js +10 -5
  55. package/dist/commands/view.d.ts +1 -0
  56. package/dist/commands/view.js +11 -0
  57. package/dist/index.js +52 -8
  58. package/dist/lib/acp/harnesses.js +0 -7
  59. package/dist/lib/activity.d.ts +156 -0
  60. package/dist/lib/activity.js +282 -0
  61. package/dist/lib/agents.d.ts +9 -2
  62. package/dist/lib/agents.js +72 -63
  63. package/dist/lib/browser/service.js +3 -0
  64. package/dist/lib/browser/types.d.ts +7 -0
  65. package/dist/lib/capabilities.js +6 -2
  66. package/dist/lib/crabbox/lease.js +2 -2
  67. package/dist/lib/crabbox/setup-copy.d.ts +4 -4
  68. package/dist/lib/crabbox/setup-copy.js +4 -4
  69. package/dist/lib/daemon.d.ts +18 -0
  70. package/dist/lib/daemon.js +47 -6
  71. package/dist/lib/devices/fleet.d.ts +1 -1
  72. package/dist/lib/devices/fleet.js +1 -1
  73. package/dist/lib/doctor-diff.d.ts +20 -0
  74. package/dist/lib/doctor-diff.js +6 -1
  75. package/dist/lib/drift.d.ts +31 -11
  76. package/dist/lib/drift.js +58 -7
  77. package/dist/lib/events.d.ts +8 -1
  78. package/dist/lib/events.js +10 -1
  79. package/dist/lib/exec.d.ts +7 -0
  80. package/dist/lib/exec.js +69 -11
  81. package/dist/lib/feed-post.d.ts +28 -1
  82. package/dist/lib/feed-post.js +110 -2
  83. package/dist/lib/fleet/apply.js +8 -1
  84. package/dist/lib/fleet/auth-sync.d.ts +18 -1
  85. package/dist/lib/fleet/auth-sync.js +25 -11
  86. package/dist/lib/fleet/remote-login.js +5 -0
  87. package/dist/lib/git.d.ts +14 -14
  88. package/dist/lib/git.js +41 -44
  89. package/dist/lib/hooks.d.ts +71 -0
  90. package/dist/lib/hooks.js +245 -95
  91. package/dist/lib/hosts/dispatch.d.ts +28 -1
  92. package/dist/lib/hosts/dispatch.js +33 -5
  93. package/dist/lib/hosts/option.js +2 -2
  94. package/dist/lib/hosts/passthrough.d.ts +22 -1
  95. package/dist/lib/hosts/passthrough.js +238 -13
  96. package/dist/lib/hosts/run-target.d.ts +2 -0
  97. package/dist/lib/hosts/run-target.js +1 -0
  98. package/dist/lib/hq/floor.d.ts +1 -1
  99. package/dist/lib/hq/floor.js +6 -1
  100. package/dist/lib/mcp.js +3 -71
  101. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  102. package/dist/lib/menubar/install-menubar.d.ts +24 -0
  103. package/dist/lib/menubar/install-menubar.js +52 -2
  104. package/dist/lib/menubar/notify-desktop.d.ts +15 -0
  105. package/dist/lib/menubar/notify-desktop.js +41 -5
  106. package/dist/lib/merged-resources.d.ts +11 -0
  107. package/dist/{commands/resources.js → lib/merged-resources.js} +11 -19
  108. package/dist/lib/permissions.d.ts +0 -32
  109. package/dist/lib/permissions.js +4 -157
  110. package/dist/lib/picker.js +1 -1
  111. package/dist/lib/platform/process.d.ts +16 -5
  112. package/dist/lib/platform/process.js +54 -0
  113. package/dist/lib/plugins.d.ts +0 -8
  114. package/dist/lib/plugins.js +4 -110
  115. package/dist/lib/project-resources.js +4 -1
  116. package/dist/lib/refresh.d.ts +5 -3
  117. package/dist/lib/refresh.js +7 -5
  118. package/dist/lib/resources/commands.js +4 -1
  119. package/dist/lib/resources/mcp.js +0 -4
  120. package/dist/lib/resources/permissions.d.ts +1 -1
  121. package/dist/lib/resources/permissions.js +1 -5
  122. package/dist/lib/resources/rules.js +4 -1
  123. package/dist/lib/resources/skills.js +4 -1
  124. package/dist/lib/resources/subagents.js +4 -0
  125. package/dist/lib/resources/types.d.ts +1 -1
  126. package/dist/lib/routines.d.ts +33 -0
  127. package/dist/lib/routines.js +122 -0
  128. package/dist/lib/run-defaults.d.ts +1 -0
  129. package/dist/lib/run-defaults.js +9 -0
  130. package/dist/lib/runner.d.ts +0 -12
  131. package/dist/lib/runner.js +49 -10
  132. package/dist/lib/scheduler.js +16 -4
  133. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  134. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  135. package/dist/lib/secrets/agent.d.ts +16 -0
  136. package/dist/lib/secrets/agent.js +105 -3
  137. package/dist/lib/secrets/audit.d.ts +46 -0
  138. package/dist/lib/secrets/audit.js +56 -0
  139. package/dist/lib/secrets/bundles.d.ts +11 -8
  140. package/dist/lib/secrets/bundles.js +31 -23
  141. package/dist/lib/secrets/index.d.ts +2 -1
  142. package/dist/lib/secrets/index.js +8 -2
  143. package/dist/lib/secrets/remote.d.ts +75 -2
  144. package/dist/lib/secrets/remote.js +139 -5
  145. package/dist/lib/secrets/sync.js +3 -3
  146. package/dist/lib/session/active.d.ts +128 -26
  147. package/dist/lib/session/active.js +192 -53
  148. package/dist/lib/session/actor-sidecar.d.ts +23 -0
  149. package/dist/lib/session/actor-sidecar.js +101 -0
  150. package/dist/lib/session/db.d.ts +4 -1
  151. package/dist/lib/session/db.js +65 -8
  152. package/dist/lib/session/discover.d.ts +4 -0
  153. package/dist/lib/session/discover.js +13 -0
  154. package/dist/lib/session/hook-sessions.d.ts +9 -0
  155. package/dist/lib/session/hook-sessions.js +57 -8
  156. package/dist/lib/session/pid-registry.d.ts +13 -0
  157. package/dist/lib/session/render.d.ts +2 -0
  158. package/dist/lib/session/render.js +1 -1
  159. package/dist/lib/session/types.d.ts +16 -0
  160. package/dist/lib/staleness/detectors/commands.js +2 -2
  161. package/dist/lib/staleness/detectors/permissions.js +1 -45
  162. package/dist/lib/staleness/writers/commands.js +4 -5
  163. package/dist/lib/staleness/writers/hooks.js +1 -1
  164. package/dist/lib/startup/command-registry.d.ts +1 -2
  165. package/dist/lib/startup/command-registry.js +2 -4
  166. package/dist/lib/state.js +57 -1
  167. package/dist/lib/subagents-registry.js +5 -12
  168. package/dist/lib/subagents.d.ts +0 -10
  169. package/dist/lib/subagents.js +0 -12
  170. package/dist/lib/teams/agents.d.ts +0 -2
  171. package/dist/lib/teams/agents.js +10 -27
  172. package/dist/lib/teams/index.d.ts +1 -1
  173. package/dist/lib/teams/index.js +1 -1
  174. package/dist/lib/types.d.ts +17 -9
  175. package/dist/lib/usage.d.ts +28 -5
  176. package/dist/lib/usage.js +271 -8
  177. package/dist/lib/versions.js +7 -1
  178. package/dist/lib/watchdog/watchdog.d.ts +1 -1
  179. package/dist/lib/watchdog/watchdog.js +25 -13
  180. package/package.json +1 -2
  181. package/dist/commands/check.d.ts +0 -15
  182. package/dist/commands/check.js +0 -180
  183. package/dist/commands/resources.d.ts +0 -5
@@ -3,7 +3,6 @@
3
3
  // them into the exact main-branch registration order for the slow path.
4
4
  export const loadView = async () => (await import('../../commands/view.js')).registerViewCommand;
5
5
  export const loadInspect = async () => (await import('../../commands/inspect.js')).registerInspectCommand;
6
- export const loadResources = async () => (await import('../../commands/resources.js')).registerResourcesCommand;
7
6
  export const loadFeedback = async () => (await import('../../commands/feedback.js')).registerFeedbackCommand;
8
7
  export const loadCommands = async () => (await import('../../commands/commands.js')).registerCommandsCommands;
9
8
  export const loadHooks = async () => (await import('../../commands/hooks.js')).registerHooksCommands;
@@ -26,13 +25,13 @@ export const loadMonitors = async () => (await import('../../commands/monitors.j
26
25
  export const loadRun = async () => (await import('../../commands/exec.js')).registerRunCommand;
27
26
  export const loadFork = async () => (await import('../../commands/fork.js')).registerForkCommand;
28
27
  export const loadDefaults = async () => (await import('../../commands/defaults.js')).registerDefaultsCommands;
28
+ export const loadSet = async () => (await import('../../commands/set.js')).registerSetCommand;
29
29
  export const loadModels = async () => (await import('../../commands/models.js')).registerModelsCommand;
30
30
  export const loadPrune = async () => (await import('../../commands/prune.js')).registerPruneCommand;
31
31
  export const loadTrash = async () => (await import('../../commands/trash.js')).registerTrashCommands;
32
32
  export const loadRestore = async () => (await import('../../commands/trash.js')).registerRestoreCommand;
33
33
  export const loadDoctor = async () => (await import('../../commands/doctor.js')).registerDoctorCommand;
34
34
  export const loadApply = async () => (await import('../../commands/apply.js')).registerApplyCommand;
35
- export const loadCheck = async () => (await import('../../commands/check.js')).registerCheckCommand;
36
35
  export const loadStatus = async () => (await import('../../commands/status.js')).registerStatusCommand;
37
36
  export const loadProfiles = async () => (await import('../../commands/profiles.js')).registerProfilesCommands;
38
37
  export const loadHarness = async () => (await import('../../commands/harness.js')).registerHarnessCommands;
@@ -107,7 +106,6 @@ export const LAZY_COMMAND_NAMES = new Set(['sessions', 'teams', 'cloud', 'messag
107
106
  export const COMMAND_LOADERS = {
108
107
  view: [loadView],
109
108
  inspect: [loadInspect],
110
- resources: [loadResources],
111
109
  feedback: [loadFeedback],
112
110
  commands: [loadCommands],
113
111
  hooks: [loadHooks],
@@ -138,12 +136,12 @@ export const COMMAND_LOADERS = {
138
136
  run: [loadRun],
139
137
  fork: [loadFork],
140
138
  defaults: [loadDefaults],
139
+ set: [loadSet],
141
140
  models: [loadModels],
142
141
  trash: [loadTrash],
143
142
  restore: [loadRestore],
144
143
  doctor: [loadDoctor],
145
144
  apply: [loadApply],
146
- check: [loadCheck],
147
145
  status: [loadStatus],
148
146
  profile: [loadProfiles],
149
147
  profiles: [loadProfiles],
package/dist/lib/state.js CHANGED
@@ -619,6 +619,62 @@ function writeIfChanged(filePath, content) {
619
619
  * All callers funnel through writeMeta → here, so nothing else changes. Empty
620
620
  * `agents:` / `versions:` are not written (no empty committed files).
621
621
  */
622
+ /**
623
+ * Serialize the central (synced) meta to `agents.yaml` WITHOUT destroying the
624
+ * hand-written comments in the committed file.
625
+ *
626
+ * `yaml.stringify(central)` drops every comment, so the freshly-written bytes
627
+ * never equal the comment-annotated file on disk — `writeIfChanged`'s byte
628
+ * compare then rewrites on EVERY meta write, leaving `agents.yaml` perpetually
629
+ * dirty and wedging `agents sync` ("Blocked by local changes"). Instead we parse
630
+ * the existing file into a `yaml.Document` (which preserves comments + ordering)
631
+ * and edit only the keys that actually changed — untouched keys, and all their
632
+ * comments, are left byte-stable. If nothing central changed we return the exact
633
+ * existing bytes, so a device-field-only write no longer touches `agents.yaml` at
634
+ * all. Falls back to plain stringify only when the file doesn't exist yet.
635
+ */
636
+ function serializeCentral(central) {
637
+ const isEmpty = Object.keys(central).length === 0;
638
+ let existing = null;
639
+ try {
640
+ existing = fs.readFileSync(META_FILE, 'utf-8');
641
+ }
642
+ catch {
643
+ /* first write — no file yet */
644
+ }
645
+ if (existing == null) {
646
+ // Empty central → header only. `yaml.stringify({})` emits `{}` (a FLOW empty
647
+ // map); once that lands on disk, a later parseDocument sees a flow root and
648
+ // doc.set() below would inherit flow, flow-ifying the whole file. Writing just
649
+ // the header avoids seeding that poison.
650
+ return isEmpty ? META_HEADER : META_HEADER + yaml.stringify(central);
651
+ }
652
+ const doc = yaml.parseDocument(existing);
653
+ const current = doc.toJSON() ?? {};
654
+ let changed = false;
655
+ for (const [k, v] of Object.entries(central)) {
656
+ if (JSON.stringify(current[k]) !== JSON.stringify(v)) {
657
+ doc.set(k, v);
658
+ changed = true;
659
+ }
660
+ }
661
+ for (const k of Object.keys(current)) {
662
+ if (!(k in central)) {
663
+ doc.delete(k);
664
+ changed = true;
665
+ }
666
+ }
667
+ // No central field changed → keep the file byte-identical (comments intact), so
668
+ // writeIfChanged skips it and the churn loop never starts.
669
+ if (!changed)
670
+ return existing;
671
+ // Everything cleared → header only (never leave a flow `{}` behind).
672
+ // Otherwise force BLOCK style: an existing flow root (e.g. a legacy `{}`) would
673
+ // otherwise make the edited nodes render flow (`disabledCommands: [ teams ]`
674
+ // instead of a `- teams` block list). collectionStyle pins the whole doc block
675
+ // while parseDocument still preserves comments + key ordering.
676
+ return isEmpty ? META_HEADER : doc.toString({ collectionStyle: 'block' });
677
+ }
622
678
  function writeMetaUnlocked(meta) {
623
679
  const { agents, isolatedAgents, versions, defaultBrowserProfile, ...central } = meta;
624
680
  // Write the machine-local files FIRST, then strip central — so a crash mid-write
@@ -656,7 +712,7 @@ function writeMetaUnlocked(meta) {
656
712
  fs.mkdirSync(path.dirname(vrPath), { recursive: true });
657
713
  writeIfChanged(vrPath, JSON.stringify(versions, null, 2) + '\n');
658
714
  }
659
- writeIfChanged(META_FILE, META_HEADER + yaml.stringify(central));
715
+ writeIfChanged(META_FILE, serializeCentral(central));
660
716
  metaCache = null;
661
717
  }
662
718
  /**
@@ -14,8 +14,8 @@
14
14
  * every current agent, so most entries are a single call:
15
15
  *
16
16
  * - `flatFile` one `<name><ext>` file, body from a `transform` fn.
17
- * (claude, gemini, grok, droid, codex, opencode, copilot,
18
- * cursor, forge, kiro, goose)
17
+ * (claude, grok, droid, codex, opencode, copilot,
18
+ * cursor, kiro, goose)
19
19
  * - `dirFile` a `<name>/` directory holding one generated `<file>`.
20
20
  * (antigravity: `<name>/agent.md`)
21
21
  * - `dirCopy` copy the whole source directory to `<name>/`, applying
@@ -33,13 +33,13 @@ import * as fs from 'fs';
33
33
  import * as path from 'path';
34
34
  import * as yaml from 'yaml';
35
35
  import { safeJoin } from './paths.js';
36
- import { parseSubagentFrontmatter, transformSubagentForClaude, transformSubagentForCodex, transformSubagentForCopilot, transformSubagentForCursor, transformSubagentForDroid, transformSubagentForForge, transformSubagentForGoose, transformSubagentForKiro, transformSubagentForOpenCode, transformSubagentForAntigravity, writeKimiSubagentFiles, buildKimiSubagentsParentYaml, KIMI_SUBAGENTS_PARENT_FILE, } from './subagents.js';
36
+ import { parseSubagentFrontmatter, transformSubagentForClaude, transformSubagentForCodex, transformSubagentForCopilot, transformSubagentForCursor, transformSubagentForDroid, transformSubagentForGoose, transformSubagentForKiro, transformSubagentForOpenCode, transformSubagentForAntigravity, writeKimiSubagentFiles, buildKimiSubagentsParentYaml, KIMI_SUBAGENTS_PARENT_FILE, } from './subagents.js';
37
37
  // ── metadata readers (the per-format escape hatch) ───────────────────────────
38
- /** Frontmatter, skipping files that lack a valid block (claude/gemini/grok/droid/codex). */
38
+ /** Frontmatter, skipping files that lack a valid block (claude/grok/droid/codex). */
39
39
  function metaFrontmatterSkip(filePath) {
40
40
  return parseSubagentFrontmatter(filePath);
41
41
  }
42
- /** Frontmatter, falling back to an empty description (opencode/copilot/cursor/forge). */
42
+ /** Frontmatter, falling back to an empty description (opencode/copilot/cursor). */
43
43
  function metaFrontmatterFallback(filePath, name) {
44
44
  return parseSubagentFrontmatter(filePath) ?? { name, description: '' };
45
45
  }
@@ -251,7 +251,6 @@ const kimiTarget = {
251
251
  export const SUBAGENT_TARGETS = {
252
252
  // Tier 1 -- flat markdown, Claude-compatible flatten.
253
253
  claude: flatFile({ subdir: ['.claude', 'agents'], ext: '.md', transform: transformSubagentForClaude }),
254
- gemini: flatFile({ subdir: ['.gemini', 'agents'], ext: '.md', transform: transformSubagentForClaude }),
255
254
  grok: flatFile({ subdir: ['.grok', 'agents'], ext: '.md', transform: transformSubagentForClaude }),
256
255
  droid: flatFile({ subdir: ['.factory', 'droids'], ext: '.md', transform: transformSubagentForDroid }),
257
256
  // Bespoke frontmatter/format, still one flat file.
@@ -274,12 +273,6 @@ export const SUBAGENT_TARGETS = {
274
273
  transform: transformSubagentForCursor,
275
274
  readMeta: metaFrontmatterFallback,
276
275
  }),
277
- forge: flatFile({
278
- subdir: ['.forge', 'agents'],
279
- ext: '.md',
280
- transform: transformSubagentForForge,
281
- readMeta: metaFrontmatterFallback,
282
- }),
283
276
  kiro: flatFile({
284
277
  subdir: ['.kiro', 'agents'],
285
278
  ext: '.json',
@@ -79,16 +79,6 @@ export declare function transformSubagentForCopilot(subagentDir: string): string
79
79
  * See https://cursor.com/docs/subagents.
80
80
  */
81
81
  export declare function transformSubagentForCursor(subagentDir: string): string;
82
- /**
83
- * Transform a subagent into a ForgeCode custom subagent `.md` file.
84
- *
85
- * ForgeCode loads named agents from `.forge/agents/*.md` (project) or
86
- * `~/.forge/agents/*.md` (user) — Markdown with YAML frontmatter (id, title,
87
- * description, tools, model, temperature) + a system-prompt body. ForgeCode has
88
- * no `color` field, so this is an alias of transformSubagentForDroid, same as
89
- * Copilot/Cursor. See https://forgecode.dev/docs/agent-definition-guide/.
90
- */
91
- export declare function transformSubagentForForge(subagentDir: string): string;
92
82
  /**
93
83
  * Transform a subagent into Antigravity's custom-agent markdown shape.
94
84
  *
@@ -290,18 +290,6 @@ export function transformSubagentForCopilot(subagentDir) {
290
290
  export function transformSubagentForCursor(subagentDir) {
291
291
  return transformSubagentForDroid(subagentDir);
292
292
  }
293
- /**
294
- * Transform a subagent into a ForgeCode custom subagent `.md` file.
295
- *
296
- * ForgeCode loads named agents from `.forge/agents/*.md` (project) or
297
- * `~/.forge/agents/*.md` (user) — Markdown with YAML frontmatter (id, title,
298
- * description, tools, model, temperature) + a system-prompt body. ForgeCode has
299
- * no `color` field, so this is an alias of transformSubagentForDroid, same as
300
- * Copilot/Cursor. See https://forgecode.dev/docs/agent-definition-guide/.
301
- */
302
- export function transformSubagentForForge(subagentDir) {
303
- return transformSubagentForDroid(subagentDir);
304
- }
305
293
  /**
306
294
  * Transform a subagent into Antigravity's custom-agent markdown shape.
307
295
  *
@@ -56,8 +56,6 @@ export declare const VALID_MODES: readonly ["plan", "edit", "auto", "skip", "ful
56
56
  type Mode = 'plan' | 'edit' | 'auto' | 'skip';
57
57
  /** Resolve a mode string to a validated Mode, falling back to the given default. */
58
58
  export declare function resolveMode(requestedMode: string | null | undefined, defaultMode?: Mode): Mode;
59
- /** Ensure Gemini's settings.json has experimental.plan enabled for headless plan mode. */
60
- export declare function ensureGeminiPlanMode(): Promise<void>;
61
59
  /**
62
60
  * Check whether the CLI binary for a given agent type is installed.
63
61
  * Returns [available, pathOrError].
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Defines the AgentProcess and AgentManager classes that handle spawning,
5
5
  * monitoring, stopping, and persisting teammate processes across all supported
6
- * agent CLIs (Claude, Codex, Gemini, Cursor, OpenCode). Supports DAG-based
6
+ * agent CLIs (Claude, Codex, Cursor, OpenCode). Supports DAG-based
7
7
  * dependency scheduling via --after, per-teammate model/effort overrides, and
8
8
  * multiple permission modes (plan, edit, full).
9
9
  */
@@ -18,7 +18,6 @@ import { resolveAgentsDir } from './persistence.js';
18
18
  import { findExecutable, captureProcessStartTime } from '../platform/index.js';
19
19
  import { normalizeEvents } from './parsers.js';
20
20
  import { debug } from './debug.js';
21
- import { setGeminiAutoUpdateDisabled, updateGeminiSettings } from '../gemini-settings.js';
22
21
  import { getAgentsDir as getSystemAgentsDir, getShimsDir } from '../state.js';
23
22
  import { AGENTS, getAccountInfo } from '../agents.js';
24
23
  import { resolveVersion, isVersionInstalled, verifyInstalledBinaryLaunches } from '../versions.js';
@@ -196,7 +195,7 @@ export function buildTeammateSpawnEnv(envOverrides) {
196
195
  */
197
196
  export { captureProcessStartTime };
198
197
  /** Agent types the team runner supports. */
199
- const TEAM_AGENT_TYPES = ['codex', 'cursor', 'gemini', 'claude', 'opencode', 'grok', 'antigravity', 'kimi', 'droid'];
198
+ const TEAM_AGENT_TYPES = ['codex', 'cursor', 'claude', 'opencode', 'grok', 'antigravity', 'kimi', 'droid'];
200
199
  // Suffix appended to all prompts to ensure agents provide a summary
201
200
  const PROMPT_SUFFIX = `
202
201
 
@@ -294,30 +293,6 @@ export function resolveMode(requestedMode, defaultMode = 'plan') {
294
293
  }
295
294
  return normalizedDefault;
296
295
  }
297
- /** Ensure Gemini's settings.json has experimental.plan enabled for headless plan mode. */
298
- export async function ensureGeminiPlanMode() {
299
- const settingsPath = path.join(os.homedir(), '.gemini', 'settings.json');
300
- try {
301
- let changed = false;
302
- const settings = updateGeminiSettings(settingsPath, (nextSettings) => {
303
- setGeminiAutoUpdateDisabled(nextSettings);
304
- const experimental = typeof nextSettings.experimental === 'object' && nextSettings.experimental !== null
305
- ? nextSettings.experimental
306
- : {};
307
- if (experimental.plan === true) {
308
- return;
309
- }
310
- nextSettings.experimental = { ...experimental, plan: true };
311
- changed = true;
312
- });
313
- if (changed && settings.experimental && typeof settings.experimental === 'object' && settings.experimental.plan === true) {
314
- console.error('[Swarm] Enabled Gemini experimental.plan in', settingsPath);
315
- }
316
- }
317
- catch (err) {
318
- console.warn('[Swarm] Could not enable Gemini plan mode:', err);
319
- }
320
- }
321
296
  /**
322
297
  * Check whether the CLI binary for a given agent type is installed.
323
298
  * Returns [available, pathOrError].
@@ -1312,6 +1287,14 @@ export class AgentManager {
1312
1287
  async spawn(taskName, agentType, prompt, cwd = null, mode = null, effort = 'medium', parentSessionId = null, workspaceDir = null, version = null, name = null, after = [], model = null, envOverrides = null, taskType = null, cloudProvider = null, cloudSessionId = null, cloudRepo = null, cloudBranch = null, worktreeName = null, worktreePath = null, profileName = null, hostName = null, hostTarget = null, repoPath = null) {
1313
1288
  await this.initialize();
1314
1289
  const resolvedMode = resolveMode(mode, this.defaultMode);
1290
+ // Lineage (RUSH-2019): when the caller didn't name a parent, inherit the
1291
+ // orchestrator's own session id from its env (exec.ts stamps AGENTS_SESSION_ID
1292
+ // onto every agent process). A team spawned from inside a running agent then
1293
+ // records which session created it, so the spawn chain traces back to a parent
1294
+ // session; a team started outside any agent simply carries none.
1295
+ if (!parentSessionId) {
1296
+ parentSessionId = process.env.AGENTS_SESSION_ID ?? null;
1297
+ }
1315
1298
  // Enforce: teammate names are unique within a team.
1316
1299
  const siblings = await this.listByTask(taskName);
1317
1300
  if (name && siblings.some((a) => a.name === name)) {
@@ -5,7 +5,7 @@
5
5
  * to reuse the same agent lifecycle, parsing, summarization, and persistence
6
6
  * layer that powers the `agents teams` CLI.
7
7
  */
8
- export { AgentManager, AgentProcess, AgentStatus, VALID_TASK_TYPES, computePathLCA, checkAllClis, checkCliAvailable, ensureGeminiPlanMode, getAgentsDir, resolveMode, type TaskType, type CloudDispatchFn, } from './agents.js';
8
+ export { AgentManager, AgentProcess, AgentStatus, VALID_TASK_TYPES, computePathLCA, checkAllClis, checkCliAvailable, getAgentsDir, resolveMode, type TaskType, type CloudDispatchFn, } from './agents.js';
9
9
  export { type AgentType } from './parsers.js';
10
10
  export { normalizeEvents, normalizeEvent, parseEvent } from './parsers.js';
11
11
  export { handleSpawn, handleStatus, handleStop, handleTasks, type SpawnResult, type AgentStatusDetail, type TaskStatusResult, type StopResult, type TaskInfo, type TasksResult, } from './api.js';
@@ -5,7 +5,7 @@
5
5
  * to reuse the same agent lifecycle, parsing, summarization, and persistence
6
6
  * layer that powers the `agents teams` CLI.
7
7
  */
8
- export { AgentManager, AgentProcess, AgentStatus, VALID_TASK_TYPES, computePathLCA, checkAllClis, checkCliAvailable, ensureGeminiPlanMode, getAgentsDir, resolveMode, } from './agents.js';
8
+ export { AgentManager, AgentProcess, AgentStatus, VALID_TASK_TYPES, computePathLCA, checkAllClis, checkCliAvailable, getAgentsDir, resolveMode, } from './agents.js';
9
9
  export { normalizeEvents, normalizeEvent, parseEvent } from './parsers.js';
10
10
  export { handleSpawn, handleStatus, handleStop, handleTasks, } from './api.js';
11
11
  export { resolveAgentsDir, resolveBaseDir, } from './persistence.js';
@@ -6,8 +6,8 @@
6
6
  * formats for each supported agent.
7
7
  */
8
8
  import type { CloudProviderId } from './cloud/types.js';
9
- /** Unique identifier for a supported AI coding agent. */
10
- export type AgentId = 'claude' | 'codex' | 'gemini' | 'cursor' | 'opencode' | 'openclaw' | 'copilot' | 'amp' | 'kiro' | 'goose' | 'antigravity' | 'grok' | 'kimi' | 'droid' | 'hermes' | 'forge';
9
+ /** Unique identifier for a current or legacy AI coding agent. */
10
+ export type AgentId = 'claude' | 'codex' | 'gemini' | 'cursor' | 'opencode' | 'openclaw' | 'copilot' | 'amp' | 'kiro' | 'goose' | 'antigravity' | 'grok' | 'kimi' | 'droid' | 'hermes';
11
11
  /** How `agents run <agent>` chooses an installed version when none is pinned. */
12
12
  export type RunStrategy = 'pinned' | 'available' | 'balanced';
13
13
  /** Per-agent run strategy config. */
@@ -107,11 +107,11 @@ export interface AgentConfig {
107
107
  */
108
108
  cloudProvider?: CloudProviderId;
109
109
  /**
110
- * Set when the upstream vendor has retired this agent's CLI. Presence marks
111
- * the agent deprecated (it is never blocked from use); `warnAgentDeprecated`
112
- * surfaces this in yellow whenever a user installs the agent or adds it to a
113
- * team. Point `replacement` at the successor agent so the warning can suggest
114
- * a migration path.
110
+ * Set when the upstream vendor has retired this agent's CLI. A warning-only
111
+ * deprecation leaves the agent manageable; a hard deprecation keeps the id
112
+ * parseable for legacy state but excludes it from install/import/sync targets.
113
+ * Point `replacement` at the successor agent so messages can suggest a
114
+ * migration path.
115
115
  */
116
116
  deprecated?: {
117
117
  /** Vendor that retired it, e.g. "Google". */
@@ -124,6 +124,8 @@ export interface AgentConfig {
124
124
  replacement?: AgentId;
125
125
  /** Announcement URL for the deprecation. */
126
126
  url?: string;
127
+ /** Hard-deprecated agents are retained only for legacy reads. */
128
+ hard?: boolean;
127
129
  };
128
130
  capabilities: {
129
131
  hooks: Capability;
@@ -745,7 +747,13 @@ export interface Meta {
745
747
  * passing `--durable` per unlock; off means the secure split default (survive
746
748
  * upgrade/restart, re-lock on sleep). */
747
749
  secrets?: {
748
- policy?: 'always' | 'daily';
750
+ /** Default storage backend used when `agents secrets create/import` create a
751
+ * new bundle without `--backend` or `--synced`. */
752
+ backend?: 'keychain' | 'file' | 'vault';
753
+ /** Default prompt policy. `hold` (the default) holds a bundle for
754
+ * `agent.holdMs`; `daily`/`session` are accepted aliases kept so an existing
755
+ * agents.yaml keeps working. See SecretsPolicy in lib/secrets/bundles.ts. */
756
+ policy?: 'always' | 'hold' | 'daily';
749
757
  agent?: {
750
758
  auto?: boolean;
751
759
  holdMs?: number;
@@ -933,7 +941,7 @@ export interface BrowserProfileConfig {
933
941
  /** Optional SSH host where logDir lives, e.g. "user@remote-host". */
934
942
  logHost?: string;
935
943
  }
936
- /** Options controlling which agents and resources are synced during `agents repo refresh` / `agents use`. */
944
+ /** Options controlling which agents and resources are synced during `agents sync` / `agents use`. */
937
945
  export interface SyncOptions {
938
946
  agents?: AgentId[];
939
947
  yes?: boolean;
@@ -79,11 +79,11 @@ export declare function buildCanonicalUsageContext(inputs: UsageIdentityInput[])
79
79
  usageFetchInputs: Map<string, UsageFetchInput>;
80
80
  };
81
81
  /**
82
- * Whether an agent exposes usage/limit data we can render — Claude/Kimi/Droid via
83
- * a live API, Codex via local session logs. Everything else has no usage concept,
84
- * so callers use this to decide whether a missing snapshot is worth flagging as
85
- * "usage unavailable" (a signed-in Claude account with no data) versus simply not
86
- * applicable (Antigravity, Grok, OpenCode).
82
+ * Whether an agent exposes usage/limit data we can render — Claude/Kimi/Droid/Cursor
83
+ * via a live API, Codex/Grok via local session logs. Everything else has no usage
84
+ * concept, so callers use this to decide whether a missing snapshot is worth
85
+ * flagging as "usage unavailable" (a signed-in Claude account with no data)
86
+ * versus simply not applicable (Antigravity, OpenCode).
87
87
  */
88
88
  export declare function agentReportsUsage(agentId: AgentId): boolean;
89
89
  /** Fetch usage info for all unique accounts in parallel, keyed by usage key. */
@@ -296,4 +296,27 @@ export declare function writeClaudeUsageCache(usageKey: string, snapshot: UsageS
296
296
  * Returns true only when a valid access token can be obtained.
297
297
  */
298
298
  export declare function isClaudeAuthValid(home?: string): Promise<boolean>;
299
+ /** Per-model bucket in Cursor's /api/usage response. */
300
+ interface CursorUsageModel {
301
+ numRequests?: number | null;
302
+ maxRequestUsage?: number | null;
303
+ }
304
+ /** Response shape from Cursor's dashboard usage endpoint. */
305
+ export interface CursorUsageResponse {
306
+ /** The premium ("fast request") bucket the plan meters. */
307
+ 'gpt-4'?: CursorUsageModel | null;
308
+ /** ISO timestamp the monthly request window resets from. */
309
+ startOfMonth?: string | null;
310
+ [model: string]: CursorUsageModel | string | null | undefined;
311
+ }
312
+ /**
313
+ * Normalize Cursor's /api/usage payload into the common UsageWindow shape.
314
+ *
315
+ * Only free / legacy request-capped plans carry a `maxRequestUsage` on the
316
+ * premium ("gpt-4") bucket — that's the fast-request cap the plan meters, and it
317
+ * maps cleanly to a monthly window. Usage-based plans report `maxRequestUsage:
318
+ * null` (no request cap — spend is metered in dollars instead), so they have no
319
+ * bar to draw here and return no windows rather than a misleading empty gauge.
320
+ */
321
+ export declare function normalizeCursorUsage(data: CursorUsageResponse): UsageWindow[];
299
322
  export {};