@phnx-labs/agents-cli 1.20.4 → 1.20.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.
Files changed (207) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +49 -18
  3. package/dist/commands/browser.js +31 -4
  4. package/dist/commands/cli.js +1 -1
  5. package/dist/commands/cloud.js +1 -1
  6. package/dist/commands/commands.js +2 -0
  7. package/dist/commands/computer.js +10 -2
  8. package/dist/commands/defaults.d.ts +7 -0
  9. package/dist/commands/defaults.js +89 -0
  10. package/dist/commands/doctor.js +1 -1
  11. package/dist/commands/exec.js +73 -19
  12. package/dist/commands/hooks.js +6 -6
  13. package/dist/commands/inspect.d.ts +26 -0
  14. package/dist/commands/inspect.js +590 -0
  15. package/dist/commands/mcp.js +17 -16
  16. package/dist/commands/models.js +1 -1
  17. package/dist/commands/packages.js +6 -4
  18. package/dist/commands/permissions.js +13 -12
  19. package/dist/commands/plugins.d.ts +13 -0
  20. package/dist/commands/plugins.js +100 -11
  21. package/dist/commands/prune.js +3 -2
  22. package/dist/commands/pull.d.ts +12 -5
  23. package/dist/commands/pull.js +26 -422
  24. package/dist/commands/push.d.ts +14 -0
  25. package/dist/commands/push.js +30 -0
  26. package/dist/commands/repo.d.ts +1 -1
  27. package/dist/commands/repo.js +155 -112
  28. package/dist/commands/resource-view.d.ts +2 -0
  29. package/dist/commands/resource-view.js +12 -3
  30. package/dist/commands/routines.js +32 -7
  31. package/dist/commands/rules.js +4 -4
  32. package/dist/commands/secrets.js +46 -9
  33. package/dist/commands/sessions.js +1 -0
  34. package/dist/commands/setup.d.ts +3 -3
  35. package/dist/commands/setup.js +17 -17
  36. package/dist/commands/skills.js +6 -5
  37. package/dist/commands/subagents.js +5 -4
  38. package/dist/commands/sync.d.ts +18 -5
  39. package/dist/commands/sync.js +251 -65
  40. package/dist/commands/teams.js +109 -11
  41. package/dist/commands/tmux.d.ts +25 -0
  42. package/dist/commands/tmux.js +415 -0
  43. package/dist/commands/trash.d.ts +2 -2
  44. package/dist/commands/trash.js +1 -1
  45. package/dist/commands/versions.js +2 -2
  46. package/dist/commands/view.d.ts +12 -1
  47. package/dist/commands/view.js +128 -40
  48. package/dist/commands/workflows.js +4 -3
  49. package/dist/commands/worktree.d.ts +4 -5
  50. package/dist/commands/worktree.js +4 -4
  51. package/dist/index.js +106 -41
  52. package/dist/lib/agents.d.ts +23 -10
  53. package/dist/lib/agents.js +88 -25
  54. package/dist/lib/auto-pull-worker.d.ts +1 -1
  55. package/dist/lib/auto-pull-worker.js +2 -2
  56. package/dist/lib/auto-pull.d.ts +1 -1
  57. package/dist/lib/auto-pull.js +1 -1
  58. package/dist/lib/beta.d.ts +1 -1
  59. package/dist/lib/beta.js +1 -1
  60. package/dist/lib/browser/chrome.d.ts +10 -0
  61. package/dist/lib/browser/chrome.js +84 -3
  62. package/dist/lib/capabilities.js +2 -0
  63. package/dist/lib/commands.d.ts +28 -1
  64. package/dist/lib/commands.js +125 -20
  65. package/dist/lib/doctor-diff.js +2 -2
  66. package/dist/lib/exec.d.ts +14 -0
  67. package/dist/lib/exec.js +59 -5
  68. package/dist/lib/fuzzy.d.ts +12 -2
  69. package/dist/lib/fuzzy.js +29 -4
  70. package/dist/lib/git.js +8 -1
  71. package/dist/lib/hooks.d.ts +2 -2
  72. package/dist/lib/hooks.js +97 -10
  73. package/dist/lib/mcp.js +32 -2
  74. package/dist/lib/migrate.d.ts +51 -0
  75. package/dist/lib/migrate.js +233 -5
  76. package/dist/lib/models.js +62 -15
  77. package/dist/lib/permissions.d.ts +59 -2
  78. package/dist/lib/permissions.js +299 -7
  79. package/dist/lib/plugin-marketplace.d.ts +98 -40
  80. package/dist/lib/plugin-marketplace.js +196 -93
  81. package/dist/lib/plugins.d.ts +21 -4
  82. package/dist/lib/plugins.js +130 -49
  83. package/dist/lib/profiles-presets.js +12 -12
  84. package/dist/lib/project-launch.d.ts +70 -0
  85. package/dist/lib/project-launch.js +404 -0
  86. package/dist/lib/pty-client.js +1 -1
  87. package/dist/lib/pty-server.d.ts +1 -1
  88. package/dist/lib/pty-server.js +8 -5
  89. package/dist/lib/refresh.d.ts +26 -0
  90. package/dist/lib/refresh.js +315 -0
  91. package/dist/lib/resource-patterns.d.ts +1 -1
  92. package/dist/lib/resource-patterns.js +1 -1
  93. package/dist/lib/resources/commands.js +2 -2
  94. package/dist/lib/resources/hooks.d.ts +1 -1
  95. package/dist/lib/resources/hooks.js +1 -1
  96. package/dist/lib/resources/mcp.d.ts +1 -1
  97. package/dist/lib/resources/mcp.js +5 -6
  98. package/dist/lib/resources/permissions.js +5 -2
  99. package/dist/lib/resources/rules.js +3 -2
  100. package/dist/lib/resources/skills.js +3 -2
  101. package/dist/lib/resources/types.d.ts +1 -1
  102. package/dist/lib/resources.d.ts +2 -0
  103. package/dist/lib/resources.js +4 -3
  104. package/dist/lib/rotate.d.ts +1 -1
  105. package/dist/lib/rotate.js +7 -19
  106. package/dist/lib/routines.d.ts +16 -4
  107. package/dist/lib/routines.js +67 -17
  108. package/dist/lib/rules/compile.js +22 -10
  109. package/dist/lib/rules/rules.js +3 -3
  110. package/dist/lib/run-config.d.ts +9 -0
  111. package/dist/lib/run-config.js +35 -0
  112. package/dist/lib/run-defaults.d.ts +42 -0
  113. package/dist/lib/run-defaults.js +180 -0
  114. package/dist/lib/runner.js +16 -3
  115. package/dist/lib/scheduler.js +15 -1
  116. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  117. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  118. package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +9 -1
  119. package/dist/lib/secrets/Agents CLI.app/Contents/embedded.provisionprofile +0 -0
  120. package/dist/lib/secrets/install-helper.d.ts +11 -3
  121. package/dist/lib/secrets/install-helper.js +48 -6
  122. package/dist/lib/secrets/linux.d.ts +56 -9
  123. package/dist/lib/secrets/linux.js +327 -59
  124. package/dist/lib/session/db.js +15 -2
  125. package/dist/lib/session/discover.js +118 -3
  126. package/dist/lib/session/parse.js +3 -0
  127. package/dist/lib/session/types.d.ts +1 -1
  128. package/dist/lib/session/types.js +1 -1
  129. package/dist/lib/shims.d.ts +18 -9
  130. package/dist/lib/shims.js +133 -50
  131. package/dist/lib/skills.d.ts +1 -1
  132. package/dist/lib/skills.js +10 -9
  133. package/dist/lib/staleness/detectors/commands.d.ts +3 -0
  134. package/dist/lib/staleness/detectors/commands.js +46 -0
  135. package/dist/lib/staleness/detectors/hooks.d.ts +3 -0
  136. package/dist/lib/staleness/detectors/hooks.js +44 -0
  137. package/dist/lib/staleness/detectors/mcp.d.ts +3 -0
  138. package/dist/lib/staleness/detectors/mcp.js +31 -0
  139. package/dist/lib/staleness/detectors/permissions.d.ts +3 -0
  140. package/dist/lib/staleness/detectors/permissions.js +201 -0
  141. package/dist/lib/staleness/detectors/plugins.d.ts +8 -0
  142. package/dist/lib/staleness/detectors/plugins.js +23 -0
  143. package/dist/lib/staleness/detectors/rules.d.ts +3 -0
  144. package/dist/lib/staleness/detectors/rules.js +34 -0
  145. package/dist/lib/staleness/detectors/skills.d.ts +3 -0
  146. package/dist/lib/staleness/detectors/skills.js +71 -0
  147. package/dist/lib/staleness/detectors/subagents.d.ts +3 -0
  148. package/dist/lib/staleness/detectors/subagents.js +50 -0
  149. package/dist/lib/staleness/detectors/types.d.ts +22 -0
  150. package/dist/lib/staleness/detectors/types.js +1 -0
  151. package/dist/lib/staleness/detectors/workflows.d.ts +3 -0
  152. package/dist/lib/staleness/detectors/workflows.js +28 -0
  153. package/dist/lib/staleness/registry.d.ts +26 -0
  154. package/dist/lib/staleness/registry.js +123 -0
  155. package/dist/lib/staleness/writers/commands.d.ts +3 -0
  156. package/dist/lib/staleness/writers/commands.js +111 -0
  157. package/dist/lib/staleness/writers/hooks.d.ts +3 -0
  158. package/dist/lib/staleness/writers/hooks.js +47 -0
  159. package/dist/lib/staleness/writers/kinds.d.ts +10 -0
  160. package/dist/lib/staleness/writers/kinds.js +15 -0
  161. package/dist/lib/staleness/writers/lazy-map.d.ts +13 -0
  162. package/dist/lib/staleness/writers/lazy-map.js +19 -0
  163. package/dist/lib/staleness/writers/mcp.d.ts +10 -0
  164. package/dist/lib/staleness/writers/mcp.js +19 -0
  165. package/dist/lib/staleness/writers/permissions.d.ts +13 -0
  166. package/dist/lib/staleness/writers/permissions.js +26 -0
  167. package/dist/lib/staleness/writers/plugins.d.ts +7 -0
  168. package/dist/lib/staleness/writers/plugins.js +31 -0
  169. package/dist/lib/staleness/writers/rules.d.ts +7 -0
  170. package/dist/lib/staleness/writers/rules.js +55 -0
  171. package/dist/lib/staleness/writers/skills.d.ts +3 -0
  172. package/dist/lib/staleness/writers/skills.js +81 -0
  173. package/dist/lib/staleness/writers/sources.d.ts +16 -0
  174. package/dist/lib/staleness/writers/sources.js +72 -0
  175. package/dist/lib/staleness/writers/subagents.d.ts +3 -0
  176. package/dist/lib/staleness/writers/subagents.js +53 -0
  177. package/dist/lib/staleness/writers/types.d.ts +36 -0
  178. package/dist/lib/staleness/writers/types.js +1 -0
  179. package/dist/lib/staleness/writers/workflows.d.ts +7 -0
  180. package/dist/lib/staleness/writers/workflows.js +31 -0
  181. package/dist/lib/state.d.ts +34 -11
  182. package/dist/lib/state.js +58 -13
  183. package/dist/lib/subagents.d.ts +0 -2
  184. package/dist/lib/subagents.js +6 -6
  185. package/dist/lib/teams/agents.js +1 -1
  186. package/dist/lib/teams/api.d.ts +67 -0
  187. package/dist/lib/teams/api.js +78 -0
  188. package/dist/lib/teams/parsers.d.ts +1 -1
  189. package/dist/lib/tmux/binary.d.ts +67 -0
  190. package/dist/lib/tmux/binary.js +141 -0
  191. package/dist/lib/tmux/index.d.ts +8 -0
  192. package/dist/lib/tmux/index.js +8 -0
  193. package/dist/lib/tmux/paths.d.ts +17 -0
  194. package/dist/lib/tmux/paths.js +30 -0
  195. package/dist/lib/tmux/session.d.ts +122 -0
  196. package/dist/lib/tmux/session.js +305 -0
  197. package/dist/lib/types.d.ts +73 -13
  198. package/dist/lib/types.js +1 -1
  199. package/dist/lib/usage.js +1 -1
  200. package/dist/lib/versions.d.ts +4 -4
  201. package/dist/lib/versions.js +138 -496
  202. package/dist/lib/workflows.d.ts +2 -4
  203. package/dist/lib/workflows.js +3 -4
  204. package/package.json +6 -3
  205. package/scripts/postinstall.js +16 -63
  206. package/dist/commands/status.d.ts +0 -9
  207. package/dist/commands/status.js +0 -25
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Shared layer-source resolution for writers.
3
+ *
4
+ * Layer precedence matches getResourceBases() in versions.ts. Project layer
5
+ * is intentionally EXCLUDED for commands/skills/hooks/subagents/permissions
6
+ * — those bodies become agent context, and a cloned public repo could ship
7
+ * one that coerces the agent on the next launch. Trusted layers only:
8
+ * user → system → extras.
9
+ */
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { getUserAgentsDir, getAgentsDir, getEnabledExtraRepos, getCommandsDir, getSkillsDir, getHooksDir } from '../../state.js';
13
+ import { safeJoin } from '../../paths.js';
14
+ /** Trusted source bases for content-like kinds. Project layer excluded. */
15
+ export function trustedSourceBases() {
16
+ return [
17
+ { dir: getUserAgentsDir() },
18
+ { dir: getAgentsDir() },
19
+ ...getEnabledExtraRepos().map((e) => ({ dir: e.dir })),
20
+ ];
21
+ }
22
+ function isLiveFile(p) {
23
+ try {
24
+ return fs.existsSync(p) && !fs.lstatSync(p).isSymbolicLink();
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ function isLiveDir(p) {
31
+ try {
32
+ return fs.existsSync(p) && !fs.lstatSync(p).isSymbolicLink() && fs.lstatSync(p).isDirectory();
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ /** Find the trusted source for a command markdown by name. */
39
+ export function resolveCommandSource(name) {
40
+ const candidates = [
41
+ safeJoin(path.join(getUserAgentsDir(), 'commands'), `${name}.md`),
42
+ safeJoin(getCommandsDir(), `${name}.md`),
43
+ ...getEnabledExtraRepos().map((e) => safeJoin(path.join(e.dir, 'commands'), `${name}.md`)),
44
+ ];
45
+ return candidates.find(isLiveFile) ?? null;
46
+ }
47
+ /** Find the trusted source directory for a skill by name. */
48
+ export function resolveSkillSource(name) {
49
+ const candidates = [
50
+ safeJoin(path.join(getUserAgentsDir(), 'skills'), name),
51
+ safeJoin(getSkillsDir(), name),
52
+ ...getEnabledExtraRepos().map((e) => safeJoin(path.join(e.dir, 'skills'), name)),
53
+ ];
54
+ return candidates.find(isLiveDir) ?? null;
55
+ }
56
+ /** Find the trusted source file for a hook by name. */
57
+ export function resolveHookSource(name) {
58
+ const candidates = [
59
+ safeJoin(path.join(getUserAgentsDir(), 'hooks'), name),
60
+ safeJoin(getHooksDir(), name),
61
+ ...getEnabledExtraRepos().map((e) => safeJoin(path.join(e.dir, 'hooks'), name)),
62
+ ];
63
+ return candidates.find(isLiveFile) ?? null;
64
+ }
65
+ /** All trusted command-skill source roots, used to dedup name collisions for commands-as-skills writes. */
66
+ export function trustedSkillRoots() {
67
+ return [
68
+ path.join(getUserAgentsDir(), 'skills'),
69
+ getSkillsDir(),
70
+ ...getEnabledExtraRepos().map((e) => path.join(e.dir, 'skills')),
71
+ ];
72
+ }
@@ -0,0 +1,3 @@
1
+ import type { AgentId } from '../../types.js';
2
+ import type { ResourceWriter } from './types.js';
3
+ export declare const subagentsWriters: Partial<Record<AgentId, ResourceWriter<string[]>>>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Subagents writer. Claude flattens each subagent into a single .md file
3
+ * under `<agentDir>/agents/`. OpenClaw copies the full subagent directory
4
+ * (with AGENT.md renamed to AGENTS.md) into `<versionHome>/.openclaw/<name>/`.
5
+ *
6
+ * Source-side discovery is `listInstalledSubagents` from lib/subagents.ts —
7
+ * it reads user + system layers only (project layer excluded for the same
8
+ * defense as commands/skills/hooks).
9
+ */
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { capableAgents } from '../../capabilities.js';
13
+ import { listInstalledSubagents, transformSubagentForClaude, syncSubagentToOpenclaw } from '../../subagents.js';
14
+ import { safeJoin } from '../../paths.js';
15
+ import { lazyAgentMap } from './lazy-map.js';
16
+ function buildSubagentsWriter(agent) {
17
+ return {
18
+ kind: 'subagents',
19
+ agent,
20
+ write({ versionHome, selection }) {
21
+ const all = listInstalledSubagents();
22
+ const map = new Map(all.map(s => [s.name, s]));
23
+ const synced = [];
24
+ for (const name of selection) {
25
+ const sub = map.get(name);
26
+ if (!sub)
27
+ continue;
28
+ try {
29
+ if (agent === 'claude') {
30
+ const agentsDir = path.join(versionHome, '.claude', 'agents');
31
+ fs.mkdirSync(agentsDir, { recursive: true });
32
+ fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.md`), transformSubagentForClaude(sub.path));
33
+ synced.push(sub.name);
34
+ }
35
+ else if (agent === 'openclaw') {
36
+ const target = safeJoin(path.join(versionHome, '.openclaw'), sub.name);
37
+ const r = syncSubagentToOpenclaw(sub.path, target);
38
+ if (r.success)
39
+ synced.push(sub.name);
40
+ }
41
+ }
42
+ catch { /* per-item sync failure: skip */ }
43
+ }
44
+ return { synced };
45
+ },
46
+ };
47
+ }
48
+ export const subagentsWriters = lazyAgentMap(() => {
49
+ const m = {};
50
+ for (const agent of capableAgents('subagents'))
51
+ m[agent] = buildSubagentsWriter(agent);
52
+ return m;
53
+ });
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Per-(kind, agent) writer contract.
3
+ *
4
+ * The aggregator in `syncResourcesToVersion` (versions.ts) selects names per
5
+ * kind, then dispatches into a writer from `../registry.ts`. The writer owns
6
+ * everything kind-specific: the agent's storage format, the layered source
7
+ * search, the conversion/copy step. Writers MUST be reached only after a
8
+ * `supports(agent, kind, version).ok === true` precheck — they throw when
9
+ * called on a (kind, agent) pair that the capability matrix says is false.
10
+ *
11
+ * The shape is intentionally narrow. Writers don't accept ambient state; the
12
+ * caller passes the names already resolved against availability. Selection is
13
+ * a string[] for most kinds, a PermissionsSelection object for permissions,
14
+ * and a RulesSelection object for rules — see kind-specific writer modules.
15
+ */
16
+ import type { AgentId } from '../../types.js';
17
+ import type { ResourceKind } from './kinds.js';
18
+ export interface WriteArgs<Sel> {
19
+ /** Agent version (e.g. "1.2.3") — passed for version-gated capability checks and side files. */
20
+ version: string;
21
+ /** Absolute path to the version's home dir, i.e. `~/.agents/.history/versions/<agent>/<version>/home`. */
22
+ versionHome: string;
23
+ /** Kind-specific selection payload. */
24
+ selection: Sel;
25
+ /** Current working directory — used by writers that consult project-layer state. */
26
+ cwd: string;
27
+ }
28
+ export interface WriteResult {
29
+ /** Names actually written. Empty array = write produced nothing (not an error). */
30
+ synced: string[];
31
+ }
32
+ export interface ResourceWriter<Sel = string[]> {
33
+ readonly kind: ResourceKind;
34
+ readonly agent: AgentId;
35
+ write(args: WriteArgs<Sel>): WriteResult;
36
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Workflows writer — copies each workflow directory into
3
+ * `<versionHome>/workflows/<name>/` via `syncWorkflowToVersion`.
4
+ */
5
+ import type { AgentId } from '../../types.js';
6
+ import type { ResourceWriter } from './types.js';
7
+ export declare const workflowsWriters: Partial<Record<AgentId, ResourceWriter<string[]>>>;
@@ -0,0 +1,31 @@
1
+ import { capableAgents } from '../../capabilities.js';
2
+ import { listInstalledWorkflows, syncWorkflowToVersion } from '../../workflows.js';
3
+ import { lazyAgentMap } from './lazy-map.js';
4
+ function buildWorkflowsWriter(agent) {
5
+ return {
6
+ kind: 'workflows',
7
+ agent,
8
+ write({ versionHome, selection }) {
9
+ const all = listInstalledWorkflows();
10
+ const synced = [];
11
+ for (const name of selection) {
12
+ const wf = all.get(name);
13
+ if (!wf)
14
+ continue;
15
+ try {
16
+ const r = syncWorkflowToVersion(wf.path, name, agent, versionHome);
17
+ if (r.success)
18
+ synced.push(name);
19
+ }
20
+ catch { /* per-item failure: skip */ }
21
+ }
22
+ return { synced };
23
+ },
24
+ };
25
+ }
26
+ export const workflowsWriters = lazyAgentMap(() => {
27
+ const m = {};
28
+ for (const agent of capableAgents('workflows'))
29
+ m[agent] = buildWorkflowsWriter(agent);
30
+ return m;
31
+ });
@@ -1,28 +1,34 @@
1
1
  /**
2
2
  * Filesystem layout and persistent state for agents-cli.
3
3
  *
4
- * Two roots:
5
- * - ~/.agents-system/ — system repo (npm-shipped resources, read-only defaults)
6
- * - ~/.agents/ — user repo (resources + agents.yaml + operational state)
4
+ * Single root at ~/.agents/ with three internal buckets:
7
5
  *
8
- * Inside ~/.agents/, top-level paths hold ONLY resources + agents.yaml.
9
- * Operational state lives in two sibling buckets:
10
- *
11
- * - ~/.agents/.history/ durable runtime data (sessions, versions, runs,
6
+ * ~/.agents/ — user repo: user-authored resources + agents.yaml
7
+ * (git-tracked via `agents repo push`).
8
+ * ~/.agents/.system/ — system repo: npm-shipped resources, regenerable.
9
+ * Don't hand-edit; maintained by npm install /
10
+ * `agents repo pull system`.
11
+ * ~/.agents/.history/ — durable runtime data (sessions, versions, runs,
12
12
  * teams/agents, trash, backups). Backed up by
13
13
  * `agents repo push`.
14
- * - ~/.agents/.cache/ — regenerable runtime data (shims, packages, helpers
14
+ * ~/.agents/.cache/ — regenerable runtime data (shims, packages, helpers
15
15
  * for daemon/pty, terminals, cloud, drive, browser
16
16
  * chrome-data, logs, companion). Gitignored.
17
17
  *
18
18
  * Resolution precedence for resources: project > user > system.
19
19
  * Every module that needs a path or reads/writes agents.yaml goes through here.
20
+ *
21
+ * Legacy layout (pre-fold): system repo lived at ~/.agents-system/ as a peer
22
+ * of ~/.agents/. runMigration() folds it into ~/.agents/.system/ on first run
23
+ * and leaves a back-compat symlink at the old path.
20
24
  */
21
25
  import type { Meta } from './types.js';
22
- /** Root of the system data directory (~/.agents-system/). */
26
+ /** Root of the system data directory (~/.agents/.system/). */
23
27
  export declare function getAgentsDir(): string;
24
- /** Root of the system data directory (~/.agents-system/). */
28
+ /** Root of the system data directory (~/.agents/.system/). */
25
29
  export declare function getSystemAgentsDir(): string;
30
+ /** Legacy system-repo location (~/.agents-system/). Exported for migration only. */
31
+ export declare function getLegacySystemAgentsDir(): string;
26
32
  /** Root of the user repo (~/.agents/). Always present after ensureAgentsDir(). */
27
33
  export declare function getUserAgentsDir(): string;
28
34
  /**
@@ -55,7 +61,7 @@ export declare function getMcpDir(): string;
55
61
  export declare function getPermissionsDir(): string;
56
62
  /** Path to subagent definition directories — system repo. */
57
63
  export declare function getSubagentsDir(): string;
58
- /** Path to ~/.agents-system/hooks/promptcuts.yaml (system defaults). */
64
+ /** Path to ~/.agents/.system/hooks/promptcuts.yaml (system defaults). */
59
65
  export declare function getPromptcutsPath(): string;
60
66
  /**
61
67
  * Resolve the effective promptcuts file: user file if it exists, otherwise
@@ -101,6 +107,15 @@ export declare function getCacheDir(): string;
101
107
  export declare function getPackagesDir(): string;
102
108
  /** Path to routine YAML definitions (~/.agents/routines/). */
103
109
  export declare function getRoutinesDir(): string;
110
+ /**
111
+ * Path to a project-scoped routines directory (`<project>/.agents/routines/`),
112
+ * or null when no project `.agents/` is found by walking up from cwd.
113
+ *
114
+ * Project routines participate in `list`/`view`/`run` for inspection but are
115
+ * NOT fired by the daemon (which runs from $HOME and only loads user routines).
116
+ * Opt-in firing for project routines is tracked as a follow-up.
117
+ */
118
+ export declare function getProjectRoutinesDir(cwd?: string): string | null;
104
119
  /** Path to routine execution logs (~/.agents/.history/runs/). */
105
120
  export declare function getRunsDir(): string;
106
121
  /** Path to installed agent CLI binaries (~/.agents/.history/versions/). */
@@ -117,6 +132,12 @@ export declare function getBinDir(): string;
117
132
  export declare function getBackupsDir(): string;
118
133
  /** Path to plugin bundles (~/.agents/plugins/) — user-authored resource. */
119
134
  export declare function getPluginsDir(): string;
135
+ /** Path to system plugin bundles (~/.agents/.system/plugins/) — npm-shipped, read-only defaults. */
136
+ export declare function getSystemPluginsDir(): string;
137
+ /** Path to an extra repo's plugin bundles (~/.agents-<alias>/plugins/). */
138
+ export declare function getExtraPluginsDir(alias: string): string;
139
+ /** Path to a project-scoped plugins directory (<project>/.agents/plugins/), or null when none. */
140
+ export declare function getProjectPluginsDir(cwd?: string): string | null;
120
141
  /** Path to synced remote session data (~/.agents/.cache/drive/). */
121
142
  export declare function getDriveDir(): string;
122
143
  /** Path to soft-deleted resources (~/.agents/.history/trash/). */
@@ -149,6 +170,8 @@ export declare function getHelpersDir(): string;
149
170
  export declare function getDaemonDir(): string;
150
171
  /** Path to PTY server scratch (~/.agents/.cache/helpers/pty/). */
151
172
  export declare function getPtyDir(): string;
173
+ /** Path to tmux scratch (~/.agents/.cache/helpers/tmux/) — shared server socket + per-session meta JSONs. */
174
+ export declare function getTmuxDir(): string;
152
175
  /** Path to remote-resource auto-pull cache (~/.agents/.cache/.fetch/). */
153
176
  export declare function getFetchCacheDir(): string;
154
177
  /** Path to the CLI version cache file (~/.agents/.cache/.cli-version-cache.json). */
package/dist/lib/state.js CHANGED
@@ -1,22 +1,26 @@
1
1
  /**
2
2
  * Filesystem layout and persistent state for agents-cli.
3
3
  *
4
- * Two roots:
5
- * - ~/.agents-system/ — system repo (npm-shipped resources, read-only defaults)
6
- * - ~/.agents/ — user repo (resources + agents.yaml + operational state)
4
+ * Single root at ~/.agents/ with three internal buckets:
7
5
  *
8
- * Inside ~/.agents/, top-level paths hold ONLY resources + agents.yaml.
9
- * Operational state lives in two sibling buckets:
10
- *
11
- * - ~/.agents/.history/ durable runtime data (sessions, versions, runs,
6
+ * ~/.agents/ — user repo: user-authored resources + agents.yaml
7
+ * (git-tracked via `agents repo push`).
8
+ * ~/.agents/.system/ — system repo: npm-shipped resources, regenerable.
9
+ * Don't hand-edit; maintained by npm install /
10
+ * `agents repo pull system`.
11
+ * ~/.agents/.history/ — durable runtime data (sessions, versions, runs,
12
12
  * teams/agents, trash, backups). Backed up by
13
13
  * `agents repo push`.
14
- * - ~/.agents/.cache/ — regenerable runtime data (shims, packages, helpers
14
+ * ~/.agents/.cache/ — regenerable runtime data (shims, packages, helpers
15
15
  * for daemon/pty, terminals, cloud, drive, browser
16
16
  * chrome-data, logs, companion). Gitignored.
17
17
  *
18
18
  * Resolution precedence for resources: project > user > system.
19
19
  * Every module that needs a path or reads/writes agents.yaml goes through here.
20
+ *
21
+ * Legacy layout (pre-fold): system repo lived at ~/.agents-system/ as a peer
22
+ * of ~/.agents/. runMigration() folds it into ~/.agents/.system/ on first run
23
+ * and leaves a back-compat symlink at the old path.
20
24
  */
21
25
  import * as fs from 'fs';
22
26
  import * as path from 'path';
@@ -26,10 +30,16 @@ import { ensureLockTarget, atomicWriteFileSync, withFileLock } from './fs-atomic
26
30
  import { SEEDED_REGISTRIES } from './types.js';
27
31
  const HOME = process.env.HOME ?? os.homedir();
28
32
  // ─── Root directories ─────────────────────────────────────────────────────────
29
- /** System repo — npm-shipped, read-only from user commands. */
30
- const SYSTEM_AGENTS_DIR = path.join(HOME, '.agents-system');
31
33
  /** User repo — user-authored resources and agents.yaml. Always-on. */
32
34
  const USER_AGENTS_DIR = path.join(HOME, '.agents');
35
+ /** System repo — npm-shipped, read-only from user commands. Lives inside the user repo. */
36
+ const SYSTEM_AGENTS_DIR = path.join(USER_AGENTS_DIR, '.system');
37
+ /**
38
+ * Legacy system-repo location (pre-fold). Exported so the migrator can fold
39
+ * it into SYSTEM_AGENTS_DIR. No runtime code outside the migrator should
40
+ * reference this — use SYSTEM_AGENTS_DIR.
41
+ */
42
+ const LEGACY_SYSTEM_AGENTS_DIR = path.join(HOME, '.agents-system');
33
43
  // ─── Meta file (agents.yaml lives in the user repo) ──────────────────────────
34
44
  const META_FILE = path.join(USER_AGENTS_DIR, 'agents.yaml');
35
45
  /** Legacy location — used only for one-shot migration in readMeta(). */
@@ -43,6 +53,7 @@ const SYSTEM_MCP_DIR = path.join(SYSTEM_AGENTS_DIR, 'mcp');
43
53
  const SYSTEM_PERMISSIONS_DIR = path.join(SYSTEM_AGENTS_DIR, 'permissions');
44
54
  const SYSTEM_SUBAGENTS_DIR = path.join(SYSTEM_AGENTS_DIR, 'subagents');
45
55
  const SYSTEM_WORKFLOWS_DIR = path.join(SYSTEM_AGENTS_DIR, 'workflows');
56
+ const SYSTEM_PLUGINS_DIR = path.join(SYSTEM_AGENTS_DIR, 'plugins');
46
57
  const SYSTEM_PROMPTCUTS_FILE = path.join(SYSTEM_AGENTS_DIR, 'hooks', 'promptcuts.yaml');
47
58
  const SYSTEM_MCP_CONFIG_FILE = path.join(SYSTEM_AGENTS_DIR, 'mcp.json');
48
59
  const SYSTEM_INSTRUCTIONS_FILE = path.join(SYSTEM_AGENTS_DIR, 'instructions.md');
@@ -81,6 +92,7 @@ const BROWSER_RUNTIME_DIR = path.join(CACHE_DIR, 'browser');
81
92
  const HELPERS_DIR = path.join(CACHE_DIR, 'helpers');
82
93
  const DAEMON_DIR = path.join(HELPERS_DIR, 'daemon');
83
94
  const PTY_DIR = path.join(HELPERS_DIR, 'pty');
95
+ const TMUX_DIR = path.join(HELPERS_DIR, 'tmux');
84
96
  const FETCH_CACHE_DIR = path.join(CACHE_DIR, '.fetch');
85
97
  const CLI_VERSION_CACHE_FILE = path.join(CACHE_DIR, '.cli-version-cache.json');
86
98
  const MODELS_CACHE_FILE = path.join(CACHE_DIR, '.models-cache.json');
@@ -103,14 +115,18 @@ const META_HEADER = `# agents-cli metadata
103
115
 
104
116
  `;
105
117
  // ─── Root getters ─────────────────────────────────────────────────────────────
106
- /** Root of the system data directory (~/.agents-system/). */
118
+ /** Root of the system data directory (~/.agents/.system/). */
107
119
  export function getAgentsDir() {
108
120
  return SYSTEM_AGENTS_DIR;
109
121
  }
110
- /** Root of the system data directory (~/.agents-system/). */
122
+ /** Root of the system data directory (~/.agents/.system/). */
111
123
  export function getSystemAgentsDir() {
112
124
  return SYSTEM_AGENTS_DIR;
113
125
  }
126
+ /** Legacy system-repo location (~/.agents-system/). Exported for migration only. */
127
+ export function getLegacySystemAgentsDir() {
128
+ return LEGACY_SYSTEM_AGENTS_DIR;
129
+ }
114
130
  /** Root of the user repo (~/.agents/). Always present after ensureAgentsDir(). */
115
131
  export function getUserAgentsDir() {
116
132
  return USER_AGENTS_DIR;
@@ -187,7 +203,7 @@ export function getMcpDir() { return SYSTEM_MCP_DIR; }
187
203
  export function getPermissionsDir() { return SYSTEM_PERMISSIONS_DIR; }
188
204
  /** Path to subagent definition directories — system repo. */
189
205
  export function getSubagentsDir() { return SYSTEM_SUBAGENTS_DIR; }
190
- /** Path to ~/.agents-system/hooks/promptcuts.yaml (system defaults). */
206
+ /** Path to ~/.agents/.system/hooks/promptcuts.yaml (system defaults). */
191
207
  export function getPromptcutsPath() { return SYSTEM_PROMPTCUTS_FILE; }
192
208
  /**
193
209
  * Resolve the effective promptcuts file: user file if it exists, otherwise
@@ -261,6 +277,20 @@ export function getCacheDir() { return CACHE_DIR; }
261
277
  export function getPackagesDir() { return PACKAGES_DIR; }
262
278
  /** Path to routine YAML definitions (~/.agents/routines/). */
263
279
  export function getRoutinesDir() { return ROUTINES_DIR; }
280
+ /**
281
+ * Path to a project-scoped routines directory (`<project>/.agents/routines/`),
282
+ * or null when no project `.agents/` is found by walking up from cwd.
283
+ *
284
+ * Project routines participate in `list`/`view`/`run` for inspection but are
285
+ * NOT fired by the daemon (which runs from $HOME and only loads user routines).
286
+ * Opt-in firing for project routines is tracked as a follow-up.
287
+ */
288
+ export function getProjectRoutinesDir(cwd = process.cwd()) {
289
+ const projectAgentsDir = getProjectAgentsDir(cwd);
290
+ if (!projectAgentsDir)
291
+ return null;
292
+ return path.join(projectAgentsDir, 'routines');
293
+ }
264
294
  /** Path to routine execution logs (~/.agents/.history/runs/). */
265
295
  export function getRunsDir() { return RUNS_DIR; }
266
296
  /** Path to installed agent CLI binaries (~/.agents/.history/versions/). */
@@ -277,6 +307,19 @@ export function getBinDir() { return BIN_DIR; }
277
307
  export function getBackupsDir() { return BACKUPS_DIR; }
278
308
  /** Path to plugin bundles (~/.agents/plugins/) — user-authored resource. */
279
309
  export function getPluginsDir() { return PLUGINS_DIR; }
310
+ /** Path to system plugin bundles (~/.agents/.system/plugins/) — npm-shipped, read-only defaults. */
311
+ export function getSystemPluginsDir() { return SYSTEM_PLUGINS_DIR; }
312
+ /** Path to an extra repo's plugin bundles (~/.agents-<alias>/plugins/). */
313
+ export function getExtraPluginsDir(alias) {
314
+ return path.join(getExtraRepoDir(alias), 'plugins');
315
+ }
316
+ /** Path to a project-scoped plugins directory (<project>/.agents/plugins/), or null when none. */
317
+ export function getProjectPluginsDir(cwd = process.cwd()) {
318
+ const projectAgentsDir = getProjectAgentsDir(cwd);
319
+ if (!projectAgentsDir)
320
+ return null;
321
+ return path.join(projectAgentsDir, 'plugins');
322
+ }
280
323
  /** Path to synced remote session data (~/.agents/.cache/drive/). */
281
324
  export function getDriveDir() { return DRIVE_DIR; }
282
325
  /** Path to soft-deleted resources (~/.agents/.history/trash/). */
@@ -309,6 +352,8 @@ export function getHelpersDir() { return HELPERS_DIR; }
309
352
  export function getDaemonDir() { return DAEMON_DIR; }
310
353
  /** Path to PTY server scratch (~/.agents/.cache/helpers/pty/). */
311
354
  export function getPtyDir() { return PTY_DIR; }
355
+ /** Path to tmux scratch (~/.agents/.cache/helpers/tmux/) — shared server socket + per-session meta JSONs. */
356
+ export function getTmuxDir() { return TMUX_DIR; }
312
357
  /** Path to remote-resource auto-pull cache (~/.agents/.cache/.fetch/). */
313
358
  export function getFetchCacheDir() { return FETCH_CACHE_DIR; }
314
359
  /** Path to the CLI version cache file (~/.agents/.cache/.cli-version-cache.json). */
@@ -73,8 +73,6 @@ export declare function removeSubagentFromAgent(subagentName: string, agent: Age
73
73
  * Check if subagent content matches between source and installed
74
74
  */
75
75
  export declare function subagentContentMatches(installedDir: string, sourceDir: string): boolean;
76
- /** Agents that support the subagent system (Claude via flattened .md, OpenClaw via directory copy). */
77
- export declare const SUBAGENT_CAPABLE_AGENTS: AgentId[];
78
76
  /**
79
77
  * List subagents installed to a specific agent's home
80
78
  * Claude: scans ~/.claude/agents/{name}.md
@@ -9,6 +9,7 @@
9
9
  import * as fs from 'fs';
10
10
  import * as path from 'path';
11
11
  import * as yaml from 'yaml';
12
+ import { capableAgents } from './capabilities.js';
12
13
  import { getSubagentsDir, getUserSubagentsDir, getTrashSubagentsDir } from './state.js';
13
14
  import { listInstalledVersions, getVersionHomePath } from './versions.js';
14
15
  import { safeJoin } from './paths.js';
@@ -333,8 +334,9 @@ export function subagentContentMatches(installedDir, sourceDir) {
333
334
  }
334
335
  return true;
335
336
  }
336
- /** Agents that support the subagent system (Claude via flattened .md, OpenClaw via directory copy). */
337
- export const SUBAGENT_CAPABLE_AGENTS = ['claude', 'openclaw'];
337
+ // SUBAGENT_CAPABLE_AGENTS removed use `capableAgents('subagents')` from
338
+ // lib/capabilities.ts. The capability matrix on AgentConfig is the single
339
+ // source of truth.
338
340
  /**
339
341
  * List subagents installed to a specific agent's home
340
342
  * Claude: scans ~/.claude/agents/{name}.md
@@ -408,8 +410,6 @@ export function listSubagentsForAgent(agentId, home) {
408
410
  }
409
411
  return subagents;
410
412
  }
411
- // Agents that support subagents
412
- const SUBAGENTS_CAPABLE_AGENTS = ['claude', 'openclaw'];
413
413
  /**
414
414
  * Compare a version home's subagents against discovered subagents.
415
415
  * Returns orphan subagent names.
@@ -461,9 +461,9 @@ export function diffVersionSubagents(agent, version) {
461
461
  */
462
462
  export function iterSubagentsCapableVersions(filter) {
463
463
  const pairs = [];
464
- const agents = filter?.agent ? [filter.agent] : SUBAGENTS_CAPABLE_AGENTS;
464
+ const agents = filter?.agent ? [filter.agent] : capableAgents('subagents');
465
465
  for (const agent of agents) {
466
- if (!SUBAGENTS_CAPABLE_AGENTS.includes(agent))
466
+ if (!capableAgents('subagents').includes(agent))
467
467
  continue;
468
468
  const versions = listInstalledVersions(agent);
469
469
  for (const version of versions) {
@@ -172,7 +172,7 @@ export function captureProcessStartTime(pid) {
172
172
  }
173
173
  }
174
174
  /** Agent types the team runner supports. */
175
- const TEAM_AGENT_TYPES = ['codex', 'cursor', 'gemini', 'claude', 'opencode', 'grok', 'antigravity'];
175
+ const TEAM_AGENT_TYPES = ['codex', 'cursor', 'gemini', 'claude', 'opencode', 'grok', 'antigravity', 'kimi'];
176
176
  // Suffix appended to all prompts to ensure agents provide a summary
177
177
  const PROMPT_SUFFIX = `
178
178
 
@@ -64,6 +64,73 @@ export interface TaskStatusResult {
64
64
  };
65
65
  cursor: string;
66
66
  }
67
+ /**
68
+ * Compact per-teammate snapshot for the default `teams status` view.
69
+ *
70
+ * The detail shape (`AgentStatusDetail`) carries the full prompt (often many
71
+ * KB), every absolute path the agent has touched, and uncapped message
72
+ * bodies. That's the right shape for programmatic consumers, but it makes
73
+ * `teams status` unreadable for orchestrators who only need: what state are
74
+ * you in, what did you just do, what files have you touched.
75
+ *
76
+ * Use {@link toAgentStatusSummary} to derive this from a detail record.
77
+ */
78
+ export interface AgentStatusSummary {
79
+ agent_id: string;
80
+ name: string | null;
81
+ agent_type: string;
82
+ status: string;
83
+ duration: string | null;
84
+ tool_count: number;
85
+ has_errors: boolean;
86
+ pr_url: string | null;
87
+ files: {
88
+ /** Count of files modified since the cursor (delta), plus basenames. */
89
+ modified: {
90
+ count: number;
91
+ names: string[];
92
+ };
93
+ created: {
94
+ count: number;
95
+ names: string[];
96
+ };
97
+ deleted: {
98
+ count: number;
99
+ names: string[];
100
+ };
101
+ /** Read is noisy (per-Read events fire constantly); only emit a count. */
102
+ read: {
103
+ count: number;
104
+ };
105
+ };
106
+ /** Already capped at 15 × 120 chars by the detail builder. */
107
+ bash_commands: string[];
108
+ /** Last 3 messages, each body trimmed to ~400 chars. */
109
+ last_messages: string[];
110
+ /** ISO timestamp — feed back via --since for delta polling. */
111
+ cursor: string;
112
+ }
113
+ /** Compact aggregated result; mirrors {@link TaskStatusResult} but agents[] is the summary shape. */
114
+ export interface TaskStatusSummaryResult {
115
+ task_name: string;
116
+ agents: AgentStatusSummary[];
117
+ summary: {
118
+ pending: number;
119
+ running: number;
120
+ completed: number;
121
+ failed: number;
122
+ stopped: number;
123
+ };
124
+ cursor: string;
125
+ }
126
+ /**
127
+ * Project a full AgentStatusDetail down to a compact AgentStatusSummary.
128
+ * Drops `prompt` entirely (caller knows what they queued), folds file lists
129
+ * to basenames + counts, caps `last_messages` to 3 × {@link SUMMARY_MESSAGE_MAX_CHARS}.
130
+ */
131
+ export declare function toAgentStatusSummary(detail: AgentStatusDetail): AgentStatusSummary;
132
+ /** Project a full TaskStatusResult down to the compact summary shape. */
133
+ export declare function toTaskStatusSummary(result: TaskStatusResult): TaskStatusSummaryResult;
67
134
  /** Result of stopping one or more teammates. */
68
135
  export interface StopResult {
69
136
  task_name: string;