@swarmify/agents-cli 1.10.2 → 1.10.4
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/README.md +66 -28
- package/dist/commands/__tests__/sessions.test.d.ts +2 -0
- package/dist/commands/__tests__/sessions.test.d.ts.map +1 -0
- package/dist/commands/__tests__/sessions.test.js +170 -0
- package/dist/commands/__tests__/sessions.test.js.map +1 -0
- package/dist/commands/commands.d.ts.map +1 -1
- package/dist/commands/commands.js +74 -56
- package/dist/commands/commands.js.map +1 -1
- package/dist/commands/daemon.js +1 -1
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/exec.js +6 -6
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/hooks.d.ts.map +1 -1
- package/dist/commands/hooks.js +67 -49
- package/dist/commands/hooks.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +29 -18
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/packages.d.ts.map +1 -1
- package/dist/commands/packages.js +3 -3
- package/dist/commands/packages.js.map +1 -1
- package/dist/commands/permissions.d.ts.map +1 -1
- package/dist/commands/permissions.js +71 -48
- package/dist/commands/permissions.js.map +1 -1
- package/dist/commands/plugins.js +8 -8
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/pty.d.ts +20 -0
- package/dist/commands/pty.d.ts.map +1 -0
- package/dist/commands/pty.js +280 -0
- package/dist/commands/pty.js.map +1 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +15 -14
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +2 -2
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/routines.d.ts.map +1 -1
- package/dist/commands/routines.js +14 -10
- package/dist/commands/routines.js.map +1 -1
- package/dist/commands/rules.d.ts.map +1 -1
- package/dist/commands/rules.js +65 -50
- package/dist/commands/rules.js.map +1 -1
- package/dist/commands/sessions.d.ts.map +1 -1
- package/dist/commands/sessions.js +222 -21
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/sessions.test.d.ts +2 -0
- package/dist/commands/sessions.test.d.ts.map +1 -0
- package/dist/commands/sessions.test.js +53 -0
- package/dist/commands/sessions.test.js.map +1 -0
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +70 -46
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/subagents.d.ts.map +1 -1
- package/dist/commands/subagents.js +10 -4
- package/dist/commands/subagents.js.map +1 -1
- package/dist/commands/utils.d.ts +16 -0
- package/dist/commands/utils.d.ts.map +1 -1
- package/dist/commands/utils.js +48 -0
- package/dist/commands/utils.js.map +1 -1
- package/dist/commands/versions.d.ts.map +1 -1
- package/dist/commands/versions.js +144 -43
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.d.ts.map +1 -1
- package/dist/commands/view.js +137 -44
- package/dist/commands/view.js.map +1 -1
- package/dist/index.js +65 -42
- package/dist/index.js.map +1 -1
- package/dist/lib/agents.d.ts +5 -0
- package/dist/lib/agents.d.ts.map +1 -1
- package/dist/lib/agents.js +57 -7
- package/dist/lib/agents.js.map +1 -1
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/daemon.js +15 -7
- package/dist/lib/daemon.js.map +1 -1
- package/dist/lib/exec.d.ts.map +1 -1
- package/dist/lib/exec.js +8 -1
- package/dist/lib/exec.js.map +1 -1
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +11 -1
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/permissions.js +1 -1
- package/dist/lib/pty-client.d.ts +22 -0
- package/dist/lib/pty-client.d.ts.map +1 -0
- package/dist/lib/pty-client.js +181 -0
- package/dist/lib/pty-client.js.map +1 -0
- package/dist/lib/pty-server.d.ts +16 -0
- package/dist/lib/pty-server.d.ts.map +1 -0
- package/dist/lib/pty-server.js +422 -0
- package/dist/lib/pty-server.js.map +1 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +13 -9
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/sandbox.js +1 -1
- package/dist/lib/sandbox.js.map +1 -1
- package/dist/lib/session/discover.d.ts +18 -0
- package/dist/lib/session/discover.d.ts.map +1 -1
- package/dist/lib/session/discover.js +134 -32
- package/dist/lib/session/discover.js.map +1 -1
- package/dist/lib/session/parse.d.ts +9 -0
- package/dist/lib/session/parse.d.ts.map +1 -1
- package/dist/lib/session/parse.js +129 -0
- package/dist/lib/session/parse.js.map +1 -1
- package/dist/lib/session/types.d.ts +1 -1
- package/dist/lib/session/types.d.ts.map +1 -1
- package/dist/lib/session/types.js +1 -1
- package/dist/lib/session/types.js.map +1 -1
- package/dist/lib/shims.d.ts.map +1 -1
- package/dist/lib/shims.js +6 -1
- package/dist/lib/shims.js.map +1 -1
- package/dist/lib/state.d.ts +0 -1
- package/dist/lib/state.d.ts.map +1 -1
- package/dist/lib/state.js +3 -9
- package/dist/lib/state.js.map +1 -1
- package/dist/lib/types.d.ts +2 -5
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/usage.d.ts +29 -0
- package/dist/lib/usage.d.ts.map +1 -0
- package/dist/lib/usage.js +416 -0
- package/dist/lib/usage.js.map +1 -0
- package/dist/lib/versions.d.ts.map +1 -1
- package/dist/lib/versions.js +19 -8
- package/dist/lib/versions.js.map +1 -1
- package/package.json +3 -1
- package/dist/commands/cron.d.ts +0 -3
- package/dist/commands/cron.d.ts.map +0 -1
- package/dist/commands/cron.js +0 -457
- package/dist/commands/cron.js.map +0 -1
- package/dist/lib/cron.d.ts +0 -70
- package/dist/lib/cron.d.ts.map +0 -1
- package/dist/lib/cron.js +0 -325
- package/dist/lib/cron.js.map +0 -1
- package/dist/lib/drive-server.d.ts +0 -9
- package/dist/lib/drive-server.d.ts.map +0 -1
- package/dist/lib/drive-server.js +0 -217
- package/dist/lib/drive-server.js.map +0 -1
- package/dist/lib/drives.d.ts +0 -34
- package/dist/lib/drives.d.ts.map +0 -1
- package/dist/lib/drives.js +0 -267
- package/dist/lib/drives.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# agents
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**The package manager and runtime for AI coding agents.**
|
|
4
|
+
|
|
5
|
+
Install versions. Install skills. Run any agent through one interface. Build pipelines across Claude, Codex, Gemini, Cursor, OpenCode, and more.
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
npm install -g @swarmify/agents-cli
|
|
@@ -8,23 +10,75 @@ npm install -g @swarmify/agents-cli
|
|
|
8
10
|
|
|
9
11
|
Also available as `ag` -- all commands work with both `agents` and `ag`.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Run any agent. Same interface.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
agents exec claude "Find all auth vulnerabilities in src/"
|
|
19
|
+
agents exec codex "Fix the issues Claude found"
|
|
20
|
+
agents exec gemini "Write tests for the fixed code"
|
|
21
|
+
```
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
Each agent resolves to the project-pinned version, with the right skills, MCP servers, and permissions already synced. No setup between steps -- just run.
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
This makes agent pipelines possible. Chain agents by strength, swap one for another, script them in CI -- the interface stays the same:
|
|
16
26
|
|
|
17
27
|
```bash
|
|
18
|
-
|
|
28
|
+
# Friday night code review
|
|
29
|
+
agents exec claude "Review all PRs merged this week, summarize risks" \
|
|
30
|
+
| agents exec codex "Write regression tests for the top 3 risks"
|
|
31
|
+
|
|
32
|
+
# Same pipeline, different project -- different agent versions, same commands
|
|
33
|
+
cd ../other-project
|
|
34
|
+
agents exec claude "Review all PRs merged this week, summarize risks"
|
|
35
|
+
# ^ resolves to claude@2.0.0 here instead of claude@2.1.89
|
|
19
36
|
```
|
|
20
37
|
|
|
21
|
-
|
|
38
|
+
Supports plan (read-only) and edit modes, effort levels that map to the right model per agent, and JSON output for scripting.
|
|
22
39
|
|
|
23
40
|
---
|
|
24
41
|
|
|
25
|
-
##
|
|
42
|
+
## Non-interactive usage
|
|
43
|
+
|
|
44
|
+
Other coding agents usually run in non-TTY shells. `agents` now supports that mode directly:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
agents add codex@latest --yes
|
|
48
|
+
agents use claude@2.1.79 --yes
|
|
49
|
+
agents commands add --names review-pr,debug --agents codex
|
|
50
|
+
agents skills add --names agents-cli --agents claude
|
|
51
|
+
agents sessions view <session-id>
|
|
52
|
+
agents routines view <job-name>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Rules for automation:
|
|
56
|
+
|
|
57
|
+
- Pass explicit names or IDs instead of relying on pickers.
|
|
58
|
+
- Use `--yes` when a command would otherwise ask for default sync or confirmation choices.
|
|
59
|
+
- Use `--names` with `commands`, `skills`, `hooks`, `rules`, and `permissions` to install from central storage without a checkbox prompt.
|
|
60
|
+
- Long `view` commands print directly in non-interactive shells instead of opening `less`.
|
|
61
|
+
|
|
62
|
+
If a command still needs a human-only picker, it now exits with a plain-text hint that shows the matching non-interactive form.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Pin agent versions per project
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
agents add claude@2.0.0 # Install specific version
|
|
70
|
+
agents use claude@2.0.0 -p # Pin to this project
|
|
71
|
+
```
|
|
26
72
|
|
|
27
|
-
|
|
73
|
+
Like `.nvmrc` for Node -- different projects use different agent versions. A shim system reads `.agents-version` and routes to the right binary automatically. No other tool does this for AI agents.
|
|
74
|
+
|
|
75
|
+
When you switch versions, configs are backed up and resources are re-synced. Each version gets its own isolated home directory with the right skills, commands, and permissions already in place.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Install skills, MCP servers, and commands once -- every agent gets them
|
|
80
|
+
|
|
81
|
+
### Skills
|
|
28
82
|
|
|
29
83
|
Skills are reusable knowledge packs -- rules, patterns, and expertise that make your agents better at specific tasks. Install once, available everywhere.
|
|
30
84
|
|
|
@@ -68,16 +122,6 @@ agents commands view review-pr # View command content
|
|
|
68
122
|
|
|
69
123
|
Commands are markdown files with a description. The CLI handles format conversion automatically -- markdown for Claude/Gemini/Cursor, TOML for Codex.
|
|
70
124
|
|
|
71
|
-
### Version-lock agents per project
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
agents add claude@2.0.0 # Install specific version
|
|
75
|
-
agents use claude@2.0.0 -p # Pin to this project
|
|
76
|
-
agents list # Show installed versions
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Like `nvm` for Node -- different projects can use different agent versions. A shim system reads your project config and routes to the right version automatically.
|
|
80
|
-
|
|
81
125
|
### Sync your entire setup
|
|
82
126
|
|
|
83
127
|
```bash
|
|
@@ -107,16 +151,6 @@ agents routines logs daily-digest # Check execution logs
|
|
|
107
151
|
|
|
108
152
|
Jobs run sandboxed -- agents only see directories and tools you explicitly allow.
|
|
109
153
|
|
|
110
|
-
### Run any agent with a unified interface
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
agents exec claude "Find all TODO comments in src/"
|
|
114
|
-
agents exec codex -m edit "Add error handling to auth.ts"
|
|
115
|
-
agents exec gemini -e detailed "Analyze this architecture"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Same interface, every agent. Supports plan (read-only) and edit modes, effort levels that map to the right model per agent, and JSON output for scripting.
|
|
119
|
-
|
|
120
154
|
### Manage rules/instructions, hooks, and permissions
|
|
121
155
|
|
|
122
156
|
Each agent has its own instruction file format -- Claude uses `CLAUDE.md`, Codex uses `AGENTS.md`, Cursor uses `.cursorrules`. The CLI manages all of them under one command.
|
|
@@ -230,6 +264,10 @@ Add rule files in a `rules/` subdirectory -- each rule is a markdown file with s
|
|
|
230
264
|
| OpenCode | yes | yes | yes | yes | AGENTS.md | yes | yes | -- |
|
|
231
265
|
| OpenClaw | yes | yes | -- | yes | workspace/AGENTS.md | yes | -- | -- |
|
|
232
266
|
|
|
267
|
+
## How It Compares
|
|
268
|
+
|
|
269
|
+
See [docs/04-landscape.md](docs/04-landscape.md) for a detailed comparison with other tools in the ecosystem -- Rivet, Agentloom, mise, skills.sh, cass, Microsoft APM, and more.
|
|
270
|
+
|
|
233
271
|
## License
|
|
234
272
|
|
|
235
273
|
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/sessions.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { spawnSync } from 'child_process';
|
|
6
|
+
const repoRoot = process.cwd();
|
|
7
|
+
const cliEntry = path.join(repoRoot, 'src', 'index.ts');
|
|
8
|
+
const tsxBin = path.join(repoRoot, 'node_modules', '.bin', 'tsx');
|
|
9
|
+
function writeUpdateCache(tempHome) {
|
|
10
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf-8'));
|
|
11
|
+
fs.mkdirSync(path.join(tempHome, '.agents'), { recursive: true });
|
|
12
|
+
fs.writeFileSync(path.join(tempHome, '.agents', '.update-check'), JSON.stringify({ lastCheck: Date.now(), latestVersion: packageJson.version }), 'utf-8');
|
|
13
|
+
}
|
|
14
|
+
function writeClaudeSession(tempHome, projectKey, sessionId, cwd, content, timestamp) {
|
|
15
|
+
fs.mkdirSync(cwd, { recursive: true });
|
|
16
|
+
const sessionsDir = path.join(tempHome, '.claude', 'projects', projectKey);
|
|
17
|
+
fs.mkdirSync(sessionsDir, { recursive: true });
|
|
18
|
+
fs.writeFileSync(path.join(sessionsDir, `${sessionId}.jsonl`), JSON.stringify({
|
|
19
|
+
type: 'user',
|
|
20
|
+
timestamp,
|
|
21
|
+
cwd,
|
|
22
|
+
sessionId,
|
|
23
|
+
version: '2.1.110',
|
|
24
|
+
gitBranch: 'main',
|
|
25
|
+
message: { role: 'user', content },
|
|
26
|
+
}) + '\n', 'utf-8');
|
|
27
|
+
}
|
|
28
|
+
function runAgents(args, cwd, home) {
|
|
29
|
+
return spawnSync(tsxBin, [cliEntry, ...args], {
|
|
30
|
+
cwd,
|
|
31
|
+
env: { ...process.env, HOME: home },
|
|
32
|
+
encoding: 'utf-8',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function outputOf(result) {
|
|
36
|
+
return `${result.stdout}${result.stderr}`;
|
|
37
|
+
}
|
|
38
|
+
describe('agents sessions', () => {
|
|
39
|
+
it('lists only sessions from the current directory by default and shows all with --all', () => {
|
|
40
|
+
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'agents-sessions-list-'));
|
|
41
|
+
try {
|
|
42
|
+
writeUpdateCache(tempHome);
|
|
43
|
+
const swarmifyDir = path.join(tempHome, 'work', 'swarmify');
|
|
44
|
+
const agentsCliDir = path.join(tempHome, 'work', 'agents-cli');
|
|
45
|
+
const swarmifySessionId = '11111111-1111-4111-8111-111111111111';
|
|
46
|
+
const agentsCliSessionId = '22222222-2222-4222-8222-222222222222';
|
|
47
|
+
writeClaudeSession(tempHome, 'swarmify-test', swarmifySessionId, swarmifyDir, 'Inspect the swarmify session list', '2026-04-17T19:35:30.000Z');
|
|
48
|
+
writeClaudeSession(tempHome, 'agents-cli-test', agentsCliSessionId, agentsCliDir, 'Inspect the agents-cli session list', '2026-04-17T19:36:30.000Z');
|
|
49
|
+
const localResult = runAgents(['sessions'], swarmifyDir, tempHome);
|
|
50
|
+
expect(localResult.status).toBe(0);
|
|
51
|
+
const localOutput = outputOf(localResult);
|
|
52
|
+
expect(localOutput).toContain(swarmifySessionId.slice(0, 8));
|
|
53
|
+
expect(localOutput).not.toContain(agentsCliSessionId.slice(0, 8));
|
|
54
|
+
const allResult = runAgents(['sessions', '--all'], swarmifyDir, tempHome);
|
|
55
|
+
expect(allResult.status).toBe(0);
|
|
56
|
+
const allOutput = outputOf(allResult);
|
|
57
|
+
expect(allOutput).toContain(swarmifySessionId.slice(0, 8));
|
|
58
|
+
expect(allOutput).toContain(agentsCliSessionId.slice(0, 8));
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
fs.rmSync(tempHome, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('agents sessions view', () => {
|
|
66
|
+
it('resolves explicit IDs across directories even when the default listing is scoped to cwd', () => {
|
|
67
|
+
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'agents-sessions-view-global-'));
|
|
68
|
+
try {
|
|
69
|
+
writeUpdateCache(tempHome);
|
|
70
|
+
const swarmifyDir = path.join(tempHome, 'work', 'swarmify');
|
|
71
|
+
const agentsCliDir = path.join(tempHome, 'work', 'agents-cli');
|
|
72
|
+
const siblingSessionId = '33333333-3333-4333-8333-333333333333';
|
|
73
|
+
writeClaudeSession(tempHome, 'swarmify-test', '44444444-4444-4444-8444-444444444444', swarmifyDir, 'Inspect the swarmify session list', '2026-04-17T19:35:30.000Z');
|
|
74
|
+
writeClaudeSession(tempHome, 'agents-cli-test', siblingSessionId, agentsCliDir, 'Review sibling repo state', '2026-04-17T19:36:30.000Z');
|
|
75
|
+
const result = runAgents(['sessions', 'view', siblingSessionId, '--transcript'], swarmifyDir, tempHome);
|
|
76
|
+
expect(result.status).toBe(0);
|
|
77
|
+
const output = outputOf(result);
|
|
78
|
+
expect(output).toContain('Review sibling repo state');
|
|
79
|
+
expect(output).not.toContain(`No session found matching: ${siblingSessionId}`);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
fs.rmSync(tempHome, { recursive: true, force: true });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
it('resolves Claude /resume history IDs to the resumed transcript', () => {
|
|
86
|
+
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'agents-sessions-view-'));
|
|
87
|
+
try {
|
|
88
|
+
writeUpdateCache(tempHome);
|
|
89
|
+
const projectRoot = path.join(tempHome, 'work', 'swarmify');
|
|
90
|
+
const transcriptCwd = path.join(projectRoot, 'extension');
|
|
91
|
+
const transcriptId = '92267176-d991-45c2-a8e5-e851e30a203b';
|
|
92
|
+
const historyOnlyId = 'f6a6cd2d-2138-41c4-b653-d2881ce9cdd3';
|
|
93
|
+
fs.mkdirSync(path.join(tempHome, '.claude', 'projects', 'swarmify-test'), { recursive: true });
|
|
94
|
+
fs.writeFileSync(path.join(tempHome, '.claude', 'history.jsonl'), JSON.stringify({
|
|
95
|
+
display: '/resume',
|
|
96
|
+
timestamp: Date.parse('2026-04-17T19:30:00.000Z'),
|
|
97
|
+
project: projectRoot,
|
|
98
|
+
sessionId: historyOnlyId,
|
|
99
|
+
}) + '\n', 'utf-8');
|
|
100
|
+
fs.mkdirSync(transcriptCwd, { recursive: true });
|
|
101
|
+
fs.writeFileSync(path.join(tempHome, '.claude', 'projects', 'swarmify-test', `${transcriptId}.jsonl`), [
|
|
102
|
+
JSON.stringify({
|
|
103
|
+
type: 'user',
|
|
104
|
+
timestamp: '2026-04-17T19:00:00.000Z',
|
|
105
|
+
cwd: transcriptCwd,
|
|
106
|
+
sessionId: transcriptId,
|
|
107
|
+
version: '2.1.110',
|
|
108
|
+
gitBranch: 'main',
|
|
109
|
+
message: { role: 'user', content: 'Earlier context' },
|
|
110
|
+
}),
|
|
111
|
+
JSON.stringify({
|
|
112
|
+
type: 'assistant',
|
|
113
|
+
timestamp: '2026-04-17T19:00:05.000Z',
|
|
114
|
+
cwd: transcriptCwd,
|
|
115
|
+
sessionId: transcriptId,
|
|
116
|
+
version: '2.1.110',
|
|
117
|
+
gitBranch: 'main',
|
|
118
|
+
message: {
|
|
119
|
+
role: 'assistant',
|
|
120
|
+
content: [{ type: 'text', text: 'Earlier reply' }],
|
|
121
|
+
},
|
|
122
|
+
}),
|
|
123
|
+
JSON.stringify({
|
|
124
|
+
type: 'attachment',
|
|
125
|
+
timestamp: '2026-04-17T19:30:30.000Z',
|
|
126
|
+
cwd: transcriptCwd,
|
|
127
|
+
sessionId: transcriptId,
|
|
128
|
+
version: '2.1.110',
|
|
129
|
+
gitBranch: 'main',
|
|
130
|
+
attachment: {
|
|
131
|
+
type: 'hook_success',
|
|
132
|
+
hookName: 'SessionStart:resume',
|
|
133
|
+
hookEvent: 'SessionStart',
|
|
134
|
+
},
|
|
135
|
+
}),
|
|
136
|
+
JSON.stringify({
|
|
137
|
+
type: 'user',
|
|
138
|
+
timestamp: '2026-04-17T19:30:45.000Z',
|
|
139
|
+
cwd: transcriptCwd,
|
|
140
|
+
sessionId: transcriptId,
|
|
141
|
+
version: '2.1.110',
|
|
142
|
+
gitBranch: 'main',
|
|
143
|
+
message: { role: 'user', content: 'Continue from where we left off' },
|
|
144
|
+
}),
|
|
145
|
+
JSON.stringify({
|
|
146
|
+
type: 'assistant',
|
|
147
|
+
timestamp: '2026-04-17T19:31:00.000Z',
|
|
148
|
+
cwd: transcriptCwd,
|
|
149
|
+
sessionId: transcriptId,
|
|
150
|
+
version: '2.1.110',
|
|
151
|
+
gitBranch: 'main',
|
|
152
|
+
message: {
|
|
153
|
+
role: 'assistant',
|
|
154
|
+
content: [{ type: 'text', text: 'Loaded resumed transcript' }],
|
|
155
|
+
},
|
|
156
|
+
}),
|
|
157
|
+
].join('\n') + '\n', 'utf-8');
|
|
158
|
+
const result = runAgents(['sessions', 'view', historyOnlyId, '--transcript'], repoRoot, tempHome);
|
|
159
|
+
expect(result.status).toBe(0);
|
|
160
|
+
const output = outputOf(result);
|
|
161
|
+
expect(output).toContain(`Resolved Claude history entry ${historyOnlyId} to transcript ${transcriptId}.`);
|
|
162
|
+
expect(output).toContain('Loaded resumed transcript');
|
|
163
|
+
expect(output).not.toContain(`No transcript session found matching: ${historyOnlyId}`);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
fs.rmSync(tempHome, { recursive: true, force: true });
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=sessions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/sessions.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4CzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoe/D"}
|
|
@@ -4,12 +4,12 @@ import * as fs from 'fs';
|
|
|
4
4
|
import * as os from 'os';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
import { checkbox } from '@inquirer/prompts';
|
|
7
|
-
import { AGENTS, ALL_AGENT_IDS, resolveAgentName, formatAgentError, } from '../lib/agents.js';
|
|
7
|
+
import { AGENTS, ALL_AGENT_IDS, resolveAgentName, formatAgentError, agentLabel, } from '../lib/agents.js';
|
|
8
8
|
import { cloneRepo } from '../lib/git.js';
|
|
9
9
|
import { discoverCommands, resolveCommandSource, installCommandCentrally, uninstallCommand, listCentralCommands, listInstalledCommandsWithScope, getCommandInfo, } from '../lib/commands.js';
|
|
10
10
|
import { listInstalledVersions, getGlobalDefault, syncResourcesToVersion, promptAgentVersionSelection, getVersionHomePath, } from '../lib/versions.js';
|
|
11
11
|
import { recordVersionResources } from '../lib/state.js';
|
|
12
|
-
import { isPromptCancelled, formatPath } from './utils.js';
|
|
12
|
+
import { isPromptCancelled, formatPath, isInteractiveTerminal, parseCommaSeparatedList, printWithPager, requireInteractiveSelection, } from './utils.js';
|
|
13
13
|
export function registerCommandsCommands(program) {
|
|
14
14
|
const commandsCmd = program
|
|
15
15
|
.command('commands')
|
|
@@ -45,10 +45,10 @@ export function registerCommandsCommands(program) {
|
|
|
45
45
|
const defaultLabel = isDefault ? ' default' : '';
|
|
46
46
|
const versionStr = chalk.gray(` (${version}${defaultLabel})`);
|
|
47
47
|
if (commands.length === 0) {
|
|
48
|
-
console.log(` ${chalk.bold(agent.
|
|
48
|
+
console.log(` ${chalk.bold(agentLabel(agent.id))}${versionStr}: ${chalk.gray('none')}`);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
console.log(` ${chalk.bold(agent.
|
|
51
|
+
console.log(` ${chalk.bold(agentLabel(agent.id))}${versionStr}:`);
|
|
52
52
|
const userCommands = commands.filter((c) => c.scope === 'user');
|
|
53
53
|
const projectCommands = commands.filter((c) => c.scope === 'project');
|
|
54
54
|
if (userCommands.length > 0 && (options.scope === 'all' || options.scope === 'user')) {
|
|
@@ -74,13 +74,13 @@ export function registerCommandsCommands(program) {
|
|
|
74
74
|
const defaultVer = getGlobalDefault(agentId);
|
|
75
75
|
if (installedVersions.length === 0) {
|
|
76
76
|
// Not version-managed, show from effective home
|
|
77
|
-
console.log(chalk.bold(`Installed Commands for ${agent.
|
|
77
|
+
console.log(chalk.bold(`Installed Commands for ${agentLabel(agent.id)}\n`));
|
|
78
78
|
const commands = listInstalledCommandsWithScope(agentId, cwd).filter((c) => options.scope === 'all' || c.scope === options.scope);
|
|
79
79
|
if (commands.length === 0) {
|
|
80
|
-
console.log(` ${chalk.bold(agent.
|
|
80
|
+
console.log(` ${chalk.bold(agentLabel(agent.id))}: ${chalk.gray('none')}`);
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
83
|
-
console.log(` ${chalk.bold(agent.
|
|
83
|
+
console.log(` ${chalk.bold(agentLabel(agent.id))}:`);
|
|
84
84
|
const userCommands = commands.filter((c) => c.scope === 'user');
|
|
85
85
|
if (userCommands.length > 0) {
|
|
86
86
|
console.log(` ${chalk.gray('User:')}`);
|
|
@@ -91,18 +91,18 @@ export function registerCommandsCommands(program) {
|
|
|
91
91
|
}
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
-
console.log(chalk.bold(`Installed Commands for ${agent.
|
|
94
|
+
console.log(chalk.bold(`Installed Commands for ${agentLabel(agent.id)}\n`));
|
|
95
95
|
let versionsToShow;
|
|
96
96
|
if (requestedVersion === 'default') {
|
|
97
97
|
if (!defaultVer) {
|
|
98
|
-
console.log(chalk.yellow(` No default version set for ${agent.
|
|
98
|
+
console.log(chalk.yellow(` No default version set for ${agentLabel(agent.id)}. Run: agents use ${agentId}@<version>`));
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
101
|
versionsToShow = [defaultVer];
|
|
102
102
|
}
|
|
103
103
|
else if (requestedVersion) {
|
|
104
104
|
if (!installedVersions.includes(requestedVersion)) {
|
|
105
|
-
console.log(chalk.red(` Version ${requestedVersion} not installed for ${agent.
|
|
105
|
+
console.log(chalk.red(` Version ${requestedVersion} not installed for ${agentLabel(agent.id)}.`));
|
|
106
106
|
console.log(chalk.gray(` Installed versions: ${installedVersions.join(', ')}`));
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
@@ -137,10 +137,10 @@ export function registerCommandsCommands(program) {
|
|
|
137
137
|
// Version managed but no default
|
|
138
138
|
const commands = listInstalledCommandsWithScope(aid, cwd).filter((c) => options.scope === 'all' || c.scope === options.scope);
|
|
139
139
|
if (commands.length === 0) {
|
|
140
|
-
console.log(` ${chalk.bold(
|
|
140
|
+
console.log(` ${chalk.bold(agentLabel(aid))}: ${chalk.gray('none')}`);
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
143
|
-
console.log(` ${chalk.bold(
|
|
143
|
+
console.log(` ${chalk.bold(agentLabel(aid))}:`);
|
|
144
144
|
const userCommands = commands.filter((c) => c.scope === 'user');
|
|
145
145
|
if (userCommands.length > 0) {
|
|
146
146
|
console.log(` ${chalk.gray('User:')}`);
|
|
@@ -157,6 +157,7 @@ export function registerCommandsCommands(program) {
|
|
|
157
157
|
.command('add [source]')
|
|
158
158
|
.description('Install commands from a repo or local path')
|
|
159
159
|
.option('-a, --agents <list>', 'Comma-separated agents to install to')
|
|
160
|
+
.option('--names <list>', 'Comma-separated command names from ~/.agents/commands/')
|
|
160
161
|
.option('-y, --yes', 'Skip prompts and use defaults')
|
|
161
162
|
.action(async (source, options) => {
|
|
162
163
|
try {
|
|
@@ -171,35 +172,54 @@ export function registerCommandsCommands(program) {
|
|
|
171
172
|
console.log(chalk.cyan(' agents commands add gh:user/repo'));
|
|
172
173
|
return;
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
description = match[1].trim();
|
|
175
|
+
const requestedNames = parseCommaSeparatedList(options.names);
|
|
176
|
+
let selectedNames;
|
|
177
|
+
if (requestedNames.length > 0) {
|
|
178
|
+
const missing = requestedNames.filter((name) => !centralCommands.includes(name));
|
|
179
|
+
if (missing.length > 0) {
|
|
180
|
+
console.log(chalk.red(`Unknown command(s): ${missing.join(', ')}`));
|
|
181
|
+
console.log(chalk.gray(`Available: ${centralCommands.join(', ')}`));
|
|
182
|
+
process.exit(1);
|
|
183
183
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
184
|
+
selectedNames = requestedNames;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
if (!isInteractiveTerminal()) {
|
|
188
|
+
requireInteractiveSelection('Selecting commands from ~/.agents/commands/', [
|
|
189
|
+
'agents commands add --names README,debug --agents codex',
|
|
190
|
+
'agents commands add gh:user/repo --agents codex',
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
// Build choices with descriptions
|
|
194
|
+
const choices = centralCommands.map((name) => {
|
|
195
|
+
const cmdPath = path.join(os.homedir(), '.agents', 'commands', `${name}.md`);
|
|
196
|
+
let description = '';
|
|
197
|
+
if (fs.existsSync(cmdPath)) {
|
|
198
|
+
const content = fs.readFileSync(cmdPath, 'utf-8');
|
|
199
|
+
const match = content.match(/description:\s*(.+)/i) || content.match(/description\s*=\s*"([^"]+)"/);
|
|
200
|
+
if (match)
|
|
201
|
+
description = match[1].trim();
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
value: name,
|
|
205
|
+
name: description ? `${name} ${chalk.gray(description.slice(0, 50))}` : name,
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
const selected = await checkbox({
|
|
209
|
+
message: 'Select commands to install',
|
|
210
|
+
choices: [
|
|
211
|
+
{ value: '__all__', name: chalk.bold('Select All') },
|
|
212
|
+
...choices,
|
|
213
|
+
],
|
|
214
|
+
});
|
|
215
|
+
if (selected.length === 0) {
|
|
216
|
+
console.log(chalk.gray('No commands selected.'));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
selectedNames = selected.includes('__all__')
|
|
220
|
+
? centralCommands
|
|
221
|
+
: selected.filter((s) => s !== '__all__');
|
|
199
222
|
}
|
|
200
|
-
const selectedNames = selected.includes('__all__')
|
|
201
|
-
? centralCommands
|
|
202
|
-
: selected.filter((s) => s !== '__all__');
|
|
203
223
|
commands = selectedNames.map((name) => ({ name, description: '' }));
|
|
204
224
|
fromCentral = true;
|
|
205
225
|
}
|
|
@@ -269,7 +289,9 @@ export function registerCommandsCommands(program) {
|
|
|
269
289
|
}
|
|
270
290
|
}
|
|
271
291
|
else {
|
|
272
|
-
const result = await promptAgentVersionSelection(ALL_AGENT_IDS, {
|
|
292
|
+
const result = await promptAgentVersionSelection(ALL_AGENT_IDS, {
|
|
293
|
+
skipPrompts: options.yes || !isInteractiveTerminal(),
|
|
294
|
+
});
|
|
273
295
|
selectedAgents = result.selectedAgents;
|
|
274
296
|
versionSelections = result.versionSelections;
|
|
275
297
|
}
|
|
@@ -322,6 +344,11 @@ export function registerCommandsCommands(program) {
|
|
|
322
344
|
console.log(chalk.yellow('No commands installed.'));
|
|
323
345
|
return;
|
|
324
346
|
}
|
|
347
|
+
if (!isInteractiveTerminal()) {
|
|
348
|
+
requireInteractiveSelection('Selecting commands to remove', [
|
|
349
|
+
'agents commands remove README',
|
|
350
|
+
]);
|
|
351
|
+
}
|
|
325
352
|
try {
|
|
326
353
|
const selected = await checkbox({
|
|
327
354
|
message: 'Select commands to remove',
|
|
@@ -351,7 +378,7 @@ export function registerCommandsCommands(program) {
|
|
|
351
378
|
let removed = 0;
|
|
352
379
|
for (const agentId of agents) {
|
|
353
380
|
if (uninstallCommand(agentId, cmdName)) {
|
|
354
|
-
console.log(` ${chalk.red('-')} ${
|
|
381
|
+
console.log(` ${chalk.red('-')} ${agentLabel(agentId)}: ${cmdName}`);
|
|
355
382
|
removed++;
|
|
356
383
|
}
|
|
357
384
|
}
|
|
@@ -371,6 +398,11 @@ export function registerCommandsCommands(program) {
|
|
|
371
398
|
console.log(chalk.yellow('No commands installed'));
|
|
372
399
|
return;
|
|
373
400
|
}
|
|
401
|
+
if (!isInteractiveTerminal()) {
|
|
402
|
+
requireInteractiveSelection('Selecting a command to view', [
|
|
403
|
+
'agents commands view README',
|
|
404
|
+
]);
|
|
405
|
+
}
|
|
374
406
|
try {
|
|
375
407
|
const { select } = await import('@inquirer/prompts');
|
|
376
408
|
name = await select({
|
|
@@ -405,21 +437,7 @@ export function registerCommandsCommands(program) {
|
|
|
405
437
|
if (command.content) {
|
|
406
438
|
const rendered = renderMarkdown(command.content);
|
|
407
439
|
const contentLines = command.content.split('\n');
|
|
408
|
-
|
|
409
|
-
if (contentLines.length > 40) {
|
|
410
|
-
const { spawnSync } = await import('child_process');
|
|
411
|
-
const less = spawnSync('less', ['-R'], {
|
|
412
|
-
input: rendered,
|
|
413
|
-
stdio: ['pipe', 'inherit', 'inherit'],
|
|
414
|
-
});
|
|
415
|
-
// Fallback to direct output if less fails
|
|
416
|
-
if (less.status !== 0) {
|
|
417
|
-
console.log(rendered);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
console.log(rendered);
|
|
422
|
-
}
|
|
440
|
+
printWithPager(rendered, contentLines.length);
|
|
423
441
|
}
|
|
424
442
|
});
|
|
425
443
|
}
|