@phnx-labs/agents-cli 1.20.62 → 1.20.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +19 -0
- package/dist/bin/agents +0 -0
- package/dist/commands/browser.js +13 -3
- package/dist/commands/exec.js +96 -28
- package/dist/commands/feed.d.ts +4 -0
- package/dist/commands/feed.js +27 -8
- package/dist/commands/funnel.d.ts +5 -0
- package/dist/commands/funnel.js +62 -0
- package/dist/commands/hosts.js +42 -0
- package/dist/commands/lease.d.ts +23 -0
- package/dist/commands/lease.js +201 -0
- package/dist/commands/mailboxes.d.ts +20 -0
- package/dist/commands/mailboxes.js +390 -0
- package/dist/commands/repo.d.ts +4 -4
- package/dist/commands/repo.js +30 -19
- package/dist/commands/routines.js +92 -29
- package/dist/commands/sessions-export.d.ts +2 -0
- package/dist/commands/sessions-export.js +279 -0
- package/dist/commands/sessions-import.d.ts +2 -0
- package/dist/commands/sessions-import.js +230 -0
- package/dist/commands/sessions-sync.d.ts +1 -0
- package/dist/commands/sessions-sync.js +16 -2
- package/dist/commands/sessions.js +12 -1
- package/dist/commands/setup.js +9 -0
- package/dist/commands/ssh.js +170 -5
- package/dist/commands/sync-provision.d.ts +23 -0
- package/dist/commands/sync-provision.js +107 -0
- package/dist/commands/usage.d.ts +2 -0
- package/dist/commands/usage.js +7 -2
- package/dist/commands/view.d.ts +1 -1
- package/dist/commands/webhook.d.ts +9 -0
- package/dist/commands/webhook.js +93 -0
- package/dist/index.js +7 -2
- package/dist/lib/agents.d.ts +44 -0
- package/dist/lib/agents.js +85 -35
- package/dist/lib/browser/drivers/ssh.js +19 -2
- package/dist/lib/browser/ipc.js +5 -4
- package/dist/lib/browser/profiles.d.ts +13 -0
- package/dist/lib/browser/profiles.js +17 -0
- package/dist/lib/browser/service.d.ts +12 -1
- package/dist/lib/browser/service.js +48 -13
- package/dist/lib/browser/sessions-list.d.ts +40 -0
- package/dist/lib/browser/sessions-list.js +190 -0
- package/dist/lib/comms-render.d.ts +37 -0
- package/dist/lib/comms-render.js +89 -0
- package/dist/lib/crabbox/cli.d.ts +72 -0
- package/dist/lib/crabbox/cli.js +158 -9
- package/dist/lib/crabbox/runtimes.d.ts +13 -0
- package/dist/lib/crabbox/runtimes.js +24 -0
- package/dist/lib/daemon.js +8 -1
- package/dist/lib/devices/fleet.d.ts +62 -0
- package/dist/lib/devices/fleet.js +128 -0
- package/dist/lib/devices/health.d.ts +77 -0
- package/dist/lib/devices/health.js +186 -0
- package/dist/lib/funnel.d.ts +5 -0
- package/dist/lib/funnel.js +23 -0
- package/dist/lib/git.d.ts +21 -5
- package/dist/lib/git.js +64 -14
- package/dist/lib/hosts/credentials.d.ts +28 -0
- package/dist/lib/hosts/credentials.js +48 -0
- package/dist/lib/hosts/dispatch.d.ts +25 -0
- package/dist/lib/hosts/dispatch.js +68 -2
- package/dist/lib/hosts/passthrough.d.ts +13 -10
- package/dist/lib/hosts/passthrough.js +119 -29
- package/dist/lib/mailbox-gc.js +4 -16
- package/dist/lib/mailbox.d.ts +39 -0
- package/dist/lib/mailbox.js +112 -0
- package/dist/lib/migrate.d.ts +12 -0
- package/dist/lib/migrate.js +55 -1
- package/dist/lib/paths.d.ts +13 -0
- package/dist/lib/paths.js +26 -4
- package/dist/lib/routines.d.ts +50 -12
- package/dist/lib/routines.js +82 -27
- package/dist/lib/runner.js +255 -13
- package/dist/lib/sandbox.d.ts +9 -1
- package/dist/lib/sandbox.js +11 -2
- package/dist/lib/session/bundle.d.ts +150 -0
- package/dist/lib/session/bundle.js +189 -0
- package/dist/lib/session/remote-bundle.d.ts +12 -0
- package/dist/lib/session/remote-bundle.js +61 -0
- package/dist/lib/session/sync/agents.d.ts +56 -6
- package/dist/lib/session/sync/agents.js +0 -0
- package/dist/lib/session/sync/config.d.ts +8 -0
- package/dist/lib/session/sync/config.js +6 -1
- package/dist/lib/session/sync/manifest.d.ts +14 -3
- package/dist/lib/session/sync/manifest.js +4 -0
- package/dist/lib/session/sync/provision.d.ts +49 -0
- package/dist/lib/session/sync/provision.js +91 -0
- package/dist/lib/session/sync/sync.d.ts +26 -2
- package/dist/lib/session/sync/sync.js +192 -69
- package/dist/lib/session/sync/transcript-crypto.d.ts +77 -0
- package/dist/lib/session/sync/transcript-crypto.js +147 -0
- package/dist/lib/ssh-tunnel.js +13 -1
- package/dist/lib/staleness/detectors/subagents.d.ts +5 -0
- package/dist/lib/staleness/detectors/subagents.js +5 -192
- package/dist/lib/staleness/writers/subagents.d.ts +10 -0
- package/dist/lib/staleness/writers/subagents.js +11 -102
- package/dist/lib/startup/command-registry.d.ts +4 -0
- package/dist/lib/startup/command-registry.js +16 -0
- package/dist/lib/state.d.ts +10 -2
- package/dist/lib/state.js +14 -2
- package/dist/lib/subagents-registry.d.ts +85 -0
- package/dist/lib/subagents-registry.js +393 -0
- package/dist/lib/subagents.d.ts +8 -8
- package/dist/lib/subagents.js +32 -663
- package/dist/lib/sync-umbrella.d.ts +1 -0
- package/dist/lib/sync-umbrella.js +14 -3
- package/dist/lib/triggers/webhook.d.ts +70 -27
- package/dist/lib/triggers/webhook.js +264 -43
- package/dist/lib/types.d.ts +9 -0
- package/dist/lib/usage.d.ts +42 -3
- package/dist/lib/usage.js +162 -22
- package/package.json +1 -1
|
@@ -1,205 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subagents detector. Claude/Gemini/Grok: flat .md files under `<agentDir>/agents/`.
|
|
3
|
-
* Codex: flat .toml files under `<versionHome>/.codex/agents/`.
|
|
4
|
-
* Droid: flat .md files under `<versionHome>/.factory/droids/`.
|
|
5
|
-
* Cursor: flat .md files under `<versionHome>/.cursor/agents/`.
|
|
6
|
-
* ForgeCode: flat .md files under `<versionHome>/.forge/agents/`.
|
|
7
|
-
* OpenClaw: subdirectories containing AGENTS.md under `<versionHome>/.openclaw/`.
|
|
8
|
-
* Mirrors versions.ts:521-539.
|
|
9
|
-
*/
|
|
10
|
-
import * as fs from 'fs';
|
|
11
|
-
import * as path from 'path';
|
|
12
1
|
import { capableAgents } from '../../capabilities.js';
|
|
2
|
+
import { listInstalledSubagentNames } from '../../subagents-registry.js';
|
|
13
3
|
import { lazyAgentMap } from '../writers/lazy-map.js';
|
|
14
|
-
function
|
|
4
|
+
function buildSubagentsDetector(agent) {
|
|
15
5
|
return {
|
|
16
6
|
kind: 'subagents',
|
|
17
7
|
agent,
|
|
18
8
|
list({ versionHome }) {
|
|
19
|
-
|
|
20
|
-
if (!fs.existsSync(agentsDir))
|
|
21
|
-
return [];
|
|
22
|
-
return fs.readdirSync(agentsDir)
|
|
23
|
-
.filter(f => f.endsWith('.md'))
|
|
24
|
-
.map(f => f.replace('.md', ''));
|
|
9
|
+
return listInstalledSubagentNames(agent, versionHome);
|
|
25
10
|
},
|
|
26
11
|
};
|
|
27
12
|
}
|
|
28
|
-
function buildClaudeDetector() {
|
|
29
|
-
return buildFlatMdAgentsDetector('claude', '.claude');
|
|
30
|
-
}
|
|
31
|
-
function buildGrokDetector() {
|
|
32
|
-
return buildFlatMdAgentsDetector('grok', '.grok');
|
|
33
|
-
}
|
|
34
|
-
function buildGeminiDetector() {
|
|
35
|
-
return buildFlatMdAgentsDetector('gemini', '.gemini');
|
|
36
|
-
}
|
|
37
|
-
function buildCodexDetector() {
|
|
38
|
-
return {
|
|
39
|
-
kind: 'subagents',
|
|
40
|
-
agent: 'codex',
|
|
41
|
-
list({ versionHome }) {
|
|
42
|
-
const agentsDir = path.join(versionHome, '.codex', 'agents');
|
|
43
|
-
if (!fs.existsSync(agentsDir))
|
|
44
|
-
return [];
|
|
45
|
-
return fs.readdirSync(agentsDir)
|
|
46
|
-
.filter(f => f.endsWith('.toml'))
|
|
47
|
-
.map(f => f.replace(/\.toml$/, ''));
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function buildDroidDetector() {
|
|
52
|
-
return {
|
|
53
|
-
kind: 'subagents',
|
|
54
|
-
agent: 'droid',
|
|
55
|
-
list({ versionHome }) {
|
|
56
|
-
const droidsDir = path.join(versionHome, '.factory', 'droids');
|
|
57
|
-
if (!fs.existsSync(droidsDir))
|
|
58
|
-
return [];
|
|
59
|
-
return fs.readdirSync(droidsDir)
|
|
60
|
-
.filter(f => f.endsWith('.md'))
|
|
61
|
-
.map(f => f.replace('.md', ''));
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function buildCopilotDetector() {
|
|
66
|
-
return {
|
|
67
|
-
kind: 'subagents',
|
|
68
|
-
agent: 'copilot',
|
|
69
|
-
list({ versionHome }) {
|
|
70
|
-
const agentsDir = path.join(versionHome, '.copilot', 'agents');
|
|
71
|
-
if (!fs.existsSync(agentsDir))
|
|
72
|
-
return [];
|
|
73
|
-
return fs.readdirSync(agentsDir)
|
|
74
|
-
.filter(f => f.endsWith('.agent.md'))
|
|
75
|
-
.map(f => f.replace('.agent.md', ''));
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function buildCursorDetector() {
|
|
80
|
-
return {
|
|
81
|
-
kind: 'subagents',
|
|
82
|
-
agent: 'cursor',
|
|
83
|
-
list({ versionHome }) {
|
|
84
|
-
const agentsDir = path.join(versionHome, '.cursor', 'agents');
|
|
85
|
-
if (!fs.existsSync(agentsDir))
|
|
86
|
-
return [];
|
|
87
|
-
return fs.readdirSync(agentsDir)
|
|
88
|
-
.filter(f => f.endsWith('.md'))
|
|
89
|
-
.map(f => f.replace(/\.md$/, ''));
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function buildOpenclawDetector() {
|
|
94
|
-
return {
|
|
95
|
-
kind: 'subagents',
|
|
96
|
-
agent: 'openclaw',
|
|
97
|
-
list({ versionHome }) {
|
|
98
|
-
const openclawDir = path.join(versionHome, '.openclaw');
|
|
99
|
-
if (!fs.existsSync(openclawDir))
|
|
100
|
-
return [];
|
|
101
|
-
return fs.readdirSync(openclawDir, { withFileTypes: true })
|
|
102
|
-
.filter(d => d.isDirectory() && fs.existsSync(path.join(openclawDir, d.name, 'AGENTS.md')))
|
|
103
|
-
.map(d => d.name);
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function buildKimiDetector() {
|
|
108
|
-
return {
|
|
109
|
-
kind: 'subagents',
|
|
110
|
-
agent: 'kimi',
|
|
111
|
-
list({ versionHome }) {
|
|
112
|
-
const agentsDir = path.join(versionHome, '.kimi-code', 'agents');
|
|
113
|
-
if (!fs.existsSync(agentsDir))
|
|
114
|
-
return [];
|
|
115
|
-
// Parent is `_agents-cli.yaml` (underscore-prefixed reserved name).
|
|
116
|
-
return fs.readdirSync(agentsDir)
|
|
117
|
-
.filter(f => f.endsWith('.yaml') && !f.startsWith('_'))
|
|
118
|
-
.map(f => f.replace(/\.yaml$/, ''));
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
function buildKiroDetector() {
|
|
123
|
-
return {
|
|
124
|
-
kind: 'subagents',
|
|
125
|
-
agent: 'kiro',
|
|
126
|
-
list({ versionHome }) {
|
|
127
|
-
const agentsDir = path.join(versionHome, '.kiro', 'agents');
|
|
128
|
-
if (!fs.existsSync(agentsDir))
|
|
129
|
-
return [];
|
|
130
|
-
return fs.readdirSync(agentsDir)
|
|
131
|
-
.filter(f => f.endsWith('.json'))
|
|
132
|
-
.map(f => f.replace(/\.json$/, ''));
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function buildForgeDetector() {
|
|
137
|
-
return buildFlatMdAgentsDetector('forge', '.forge');
|
|
138
|
-
}
|
|
139
|
-
function buildGooseDetector() {
|
|
140
|
-
return {
|
|
141
|
-
kind: 'subagents',
|
|
142
|
-
agent: 'goose',
|
|
143
|
-
list({ versionHome }) {
|
|
144
|
-
const agentsDir = path.join(versionHome, '.config', 'goose', 'agents');
|
|
145
|
-
if (!fs.existsSync(agentsDir))
|
|
146
|
-
return [];
|
|
147
|
-
return fs.readdirSync(agentsDir)
|
|
148
|
-
.filter(f => f.endsWith('.yaml'))
|
|
149
|
-
.map(f => f.replace(/\.yaml$/, ''));
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
function buildOpenCodeDetector() {
|
|
154
|
-
return {
|
|
155
|
-
kind: 'subagents',
|
|
156
|
-
agent: 'opencode',
|
|
157
|
-
list({ versionHome }) {
|
|
158
|
-
const agentsDir = path.join(versionHome, '.config', 'opencode', 'agents');
|
|
159
|
-
if (!fs.existsSync(agentsDir))
|
|
160
|
-
return [];
|
|
161
|
-
return fs.readdirSync(agentsDir)
|
|
162
|
-
.filter(f => f.endsWith('.md'))
|
|
163
|
-
.map(f => f.replace(/\.md$/, ''));
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
function buildAntigravityDetector() {
|
|
168
|
-
return {
|
|
169
|
-
kind: 'subagents',
|
|
170
|
-
agent: 'antigravity',
|
|
171
|
-
list({ versionHome }) {
|
|
172
|
-
const agentsDir = path.join(versionHome, '.gemini', 'config', 'agents');
|
|
173
|
-
if (!fs.existsSync(agentsDir))
|
|
174
|
-
return [];
|
|
175
|
-
return fs.readdirSync(agentsDir, { withFileTypes: true })
|
|
176
|
-
.filter(d => d.isDirectory() && fs.existsSync(path.join(agentsDir, d.name, 'agent.md')))
|
|
177
|
-
.map(d => d.name);
|
|
178
|
-
},
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
const handlers = {
|
|
182
|
-
claude: buildClaudeDetector,
|
|
183
|
-
copilot: buildCopilotDetector,
|
|
184
|
-
gemini: buildGeminiDetector,
|
|
185
|
-
grok: buildGrokDetector,
|
|
186
|
-
codex: buildCodexDetector,
|
|
187
|
-
kimi: buildKimiDetector,
|
|
188
|
-
opencode: buildOpenCodeDetector,
|
|
189
|
-
antigravity: buildAntigravityDetector,
|
|
190
|
-
droid: buildDroidDetector,
|
|
191
|
-
openclaw: buildOpenclawDetector,
|
|
192
|
-
kiro: buildKiroDetector,
|
|
193
|
-
cursor: buildCursorDetector,
|
|
194
|
-
forge: buildForgeDetector,
|
|
195
|
-
goose: buildGooseDetector,
|
|
196
|
-
};
|
|
197
13
|
export const subagentsDetectors = lazyAgentMap(() => {
|
|
198
14
|
const m = {};
|
|
199
|
-
for (const agent of capableAgents('subagents'))
|
|
200
|
-
|
|
201
|
-
if (f)
|
|
202
|
-
m[agent] = f();
|
|
203
|
-
}
|
|
15
|
+
for (const agent of capableAgents('subagents'))
|
|
16
|
+
m[agent] = buildSubagentsDetector(agent);
|
|
204
17
|
return m;
|
|
205
18
|
});
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagents writer. Every agent's on-disk layout (target dir, file/dir shape,
|
|
3
|
+
* transform, and any post-sync finalize such as Kimi's parent index) is
|
|
4
|
+
* declared once in the subagent registry; this writer is generic and iterates
|
|
5
|
+
* the registry instead of a per-agent `else if` chain.
|
|
6
|
+
*
|
|
7
|
+
* Source-side discovery is `listInstalledSubagents` from lib/subagents.ts —
|
|
8
|
+
* it reads user + system layers only (project layer excluded for the same
|
|
9
|
+
* defense as commands/skills/hooks).
|
|
10
|
+
*/
|
|
1
11
|
import type { AgentId } from '../../types.js';
|
|
2
12
|
import type { ResourceWriter } from './types.js';
|
|
3
13
|
export declare const subagentsWriters: Partial<Record<AgentId, ResourceWriter<string[]>>>;
|
|
@@ -1,123 +1,32 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subagents writer. Claude/Gemini/Grok flatten each subagent into a single
|
|
3
|
-
* .md file under their native agents directory. Codex writes TOML under
|
|
4
|
-
* `.codex/agents/`.
|
|
5
|
-
* Droid (Factory AI) flattens each into a custom droid .md under
|
|
6
|
-
* `<versionHome>/.factory/droids/`. Cursor flattens each into a custom
|
|
7
|
-
* subagent .md under `<versionHome>/.cursor/agents/`. OpenClaw copies the
|
|
8
|
-
* full subagent directory (with AGENT.md renamed to AGENTS.md) into
|
|
9
|
-
* `<versionHome>/.openclaw/<name>/`.
|
|
10
|
-
*
|
|
11
|
-
* Source-side discovery is `listInstalledSubagents` from lib/subagents.ts —
|
|
12
|
-
* it reads user + system layers only (project layer excluded for the same
|
|
13
|
-
* defense as commands/skills/hooks).
|
|
14
|
-
*/
|
|
15
|
-
import * as fs from 'fs';
|
|
16
|
-
import * as path from 'path';
|
|
17
1
|
import { capableAgents } from '../../capabilities.js';
|
|
18
|
-
import { listInstalledSubagents
|
|
19
|
-
import {
|
|
2
|
+
import { listInstalledSubagents } from '../../subagents.js';
|
|
3
|
+
import { subagentTarget } from '../../subagents-registry.js';
|
|
20
4
|
import { lazyAgentMap } from './lazy-map.js';
|
|
21
5
|
function buildSubagentsWriter(agent) {
|
|
22
6
|
return {
|
|
23
7
|
kind: 'subagents',
|
|
24
8
|
agent,
|
|
25
9
|
write({ versionHome, selection }) {
|
|
10
|
+
const target = subagentTarget(agent);
|
|
11
|
+
if (!target)
|
|
12
|
+
return { synced: [] };
|
|
26
13
|
const all = listInstalledSubagents();
|
|
27
14
|
const map = new Map(all.map(s => [s.name, s]));
|
|
15
|
+
const dir = target.dir(versionHome);
|
|
28
16
|
const synced = [];
|
|
29
17
|
for (const name of selection) {
|
|
30
18
|
const sub = map.get(name);
|
|
31
19
|
if (!sub)
|
|
32
20
|
continue;
|
|
33
21
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const agentsDir = path.join(versionHome, agentsRoot, 'agents');
|
|
37
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
38
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.md`), transformSubagentForClaude(sub.path));
|
|
39
|
-
synced.push(sub.name);
|
|
40
|
-
}
|
|
41
|
-
else if (agent === 'codex') {
|
|
42
|
-
const agentsDir = path.join(versionHome, '.codex', 'agents');
|
|
43
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
44
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.toml`), transformSubagentForCodex(sub.path));
|
|
45
|
-
synced.push(sub.name);
|
|
46
|
-
}
|
|
47
|
-
else if (agent === 'kimi') {
|
|
48
|
-
writeKimiSubagentFiles(path.join(versionHome, '.kimi-code', 'agents'), sub.path, sub.name);
|
|
49
|
-
synced.push(sub.name);
|
|
50
|
-
}
|
|
51
|
-
else if (agent === 'opencode') {
|
|
52
|
-
const agentsDir = path.join(versionHome, '.config', 'opencode', 'agents');
|
|
53
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
54
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.md`), transformSubagentForOpenCode(sub.path));
|
|
55
|
-
synced.push(sub.name);
|
|
56
|
-
}
|
|
57
|
-
else if (agent === 'antigravity') {
|
|
58
|
-
const agentDir = safeJoin(path.join(versionHome, '.gemini', 'config', 'agents'), sub.name);
|
|
59
|
-
fs.mkdirSync(agentDir, { recursive: true });
|
|
60
|
-
fs.writeFileSync(safeJoin(agentDir, 'agent.md'), transformSubagentForAntigravity(sub.path));
|
|
61
|
-
synced.push(sub.name);
|
|
62
|
-
}
|
|
63
|
-
else if (agent === 'droid') {
|
|
64
|
-
const droidsDir = path.join(versionHome, '.factory', 'droids');
|
|
65
|
-
fs.mkdirSync(droidsDir, { recursive: true });
|
|
66
|
-
fs.writeFileSync(safeJoin(droidsDir, `${sub.name}.md`), transformSubagentForDroid(sub.path));
|
|
67
|
-
synced.push(sub.name);
|
|
68
|
-
}
|
|
69
|
-
else if (agent === 'copilot') {
|
|
70
|
-
const agentsDir = path.join(versionHome, '.copilot', 'agents');
|
|
71
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
72
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.agent.md`), transformSubagentForCopilot(sub.path));
|
|
73
|
-
synced.push(sub.name);
|
|
74
|
-
}
|
|
75
|
-
else if (agent === 'openclaw') {
|
|
76
|
-
const target = safeJoin(path.join(versionHome, '.openclaw'), sub.name);
|
|
77
|
-
const r = syncSubagentToOpenclaw(sub.path, target);
|
|
78
|
-
if (r.success)
|
|
79
|
-
synced.push(sub.name);
|
|
80
|
-
}
|
|
81
|
-
else if (agent === 'kiro') {
|
|
82
|
-
const agentsDir = path.join(versionHome, '.kiro', 'agents');
|
|
83
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
84
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.json`), transformSubagentForKiro(sub.path));
|
|
85
|
-
synced.push(sub.name);
|
|
86
|
-
}
|
|
87
|
-
else if (agent === 'cursor') {
|
|
88
|
-
const agentsDir = path.join(versionHome, '.cursor', 'agents');
|
|
89
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
90
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.md`), transformSubagentForCursor(sub.path));
|
|
91
|
-
synced.push(sub.name);
|
|
92
|
-
}
|
|
93
|
-
else if (agent === 'forge') {
|
|
94
|
-
const agentsDir = path.join(versionHome, '.forge', 'agents');
|
|
95
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
96
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.md`), transformSubagentForForge(sub.path));
|
|
97
|
-
synced.push(sub.name);
|
|
98
|
-
}
|
|
99
|
-
else if (agent === 'goose') {
|
|
100
|
-
const agentsDir = path.join(versionHome, '.config', 'goose', 'agents');
|
|
101
|
-
fs.mkdirSync(agentsDir, { recursive: true });
|
|
102
|
-
fs.writeFileSync(safeJoin(agentsDir, `${sub.name}.yaml`), transformSubagentForGoose(sub.path));
|
|
103
|
-
synced.push(sub.name);
|
|
104
|
-
}
|
|
22
|
+
target.write(dir, sub);
|
|
23
|
+
synced.push(sub.name);
|
|
105
24
|
}
|
|
106
25
|
catch { /* per-item sync failure: skip */ }
|
|
107
26
|
}
|
|
108
|
-
//
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
const entries = synced.map((name) => {
|
|
112
|
-
const sub = map.get(name);
|
|
113
|
-
const fm = parseSubagentFrontmatter(path.join(sub.path, 'AGENT.md'));
|
|
114
|
-
return {
|
|
115
|
-
name,
|
|
116
|
-
description: fm?.description ?? name,
|
|
117
|
-
relativePath: `./${name}.yaml`,
|
|
118
|
-
};
|
|
119
|
-
});
|
|
120
|
-
fs.writeFileSync(safeJoin(agentsDir, KIMI_SUBAGENTS_PARENT_FILE), buildKimiSubagentsParentYaml(entries));
|
|
27
|
+
// Optional cross-item pass (e.g. Kimi's `_agents-cli.yaml` parent index).
|
|
28
|
+
if (target.finalize && synced.length > 0) {
|
|
29
|
+
target.finalize(dir, synced.map((name) => map.get(name)));
|
|
121
30
|
}
|
|
122
31
|
return { synced };
|
|
123
32
|
},
|
|
@@ -74,6 +74,7 @@ export declare const loadWatchdog: ModuleLoader;
|
|
|
74
74
|
export declare const loadBrowser: ModuleLoader;
|
|
75
75
|
export declare const loadComputer: ModuleLoader;
|
|
76
76
|
export declare const loadHosts: ModuleLoader;
|
|
77
|
+
export declare const loadLease: ModuleLoader;
|
|
77
78
|
export declare const loadLogs: ModuleLoader;
|
|
78
79
|
export declare const loadEvents: ModuleLoader;
|
|
79
80
|
export declare const loadSsh: ModuleLoader;
|
|
@@ -86,8 +87,11 @@ export declare const loadTeams: ModuleLoader;
|
|
|
86
87
|
export declare const loadCloud: ModuleLoader;
|
|
87
88
|
export declare const loadMessage: ModuleLoader;
|
|
88
89
|
export declare const loadFeed: ModuleLoader;
|
|
90
|
+
export declare const loadMailboxes: ModuleLoader;
|
|
89
91
|
export declare const loadServe: ModuleLoader;
|
|
90
92
|
export declare const loadAudit: ModuleLoader;
|
|
93
|
+
export declare const loadWebhook: ModuleLoader;
|
|
94
|
+
export declare const loadFunnel: ModuleLoader;
|
|
91
95
|
/**
|
|
92
96
|
* Commands whose modules pull in the SQLite-backed session/cloud stack. They are
|
|
93
97
|
* registered AFTER `applyGlobalHelpConventions` (mirroring main's order: help
|
|
@@ -52,6 +52,7 @@ export const loadWatchdog = async () => (await import('../../commands/watchdog.j
|
|
|
52
52
|
export const loadBrowser = async () => (await import('../../commands/browser.js')).registerBrowserCommand;
|
|
53
53
|
export const loadComputer = async () => (await import('../../commands/computer.js')).registerComputerCommand;
|
|
54
54
|
export const loadHosts = async () => (await import('../../commands/hosts.js')).registerHostsCommand;
|
|
55
|
+
export const loadLease = async () => (await import('../../commands/lease.js')).registerLeaseCommand;
|
|
55
56
|
export const loadLogs = async () => (await import('../../commands/logs.js')).registerLogsCommand;
|
|
56
57
|
export const loadEvents = async () => (await import('../../commands/events.js')).registerEventsCommand;
|
|
57
58
|
export const loadSsh = async () => (await import('../../commands/ssh.js')).registerSshCommands;
|
|
@@ -64,8 +65,11 @@ export const loadTeams = async () => (await import('../../commands/teams.js')).r
|
|
|
64
65
|
export const loadCloud = async () => (await import('../../commands/cloud.js')).registerCloudCommands;
|
|
65
66
|
export const loadMessage = async () => (await import('../../commands/message.js')).registerMessageCommand;
|
|
66
67
|
export const loadFeed = async () => (await import('../../commands/feed.js')).registerFeedCommand;
|
|
68
|
+
export const loadMailboxes = async () => (await import('../../commands/mailboxes.js')).registerMailboxesCommand;
|
|
67
69
|
export const loadServe = async () => (await import('../../commands/serve.js')).registerServeCommand;
|
|
68
70
|
export const loadAudit = async () => (await import('../../commands/audit.js')).registerAuditCommands;
|
|
71
|
+
export const loadWebhook = async () => (await import('../../commands/webhook.js')).registerWebhookCommand;
|
|
72
|
+
export const loadFunnel = async () => (await import('../../commands/funnel.js')).registerFunnelCommand;
|
|
69
73
|
/**
|
|
70
74
|
* Commands whose modules pull in the SQLite-backed session/cloud stack. They are
|
|
71
75
|
* registered AFTER `applyGlobalHelpConventions` (mirroring main's order: help
|
|
@@ -147,12 +151,20 @@ export const COMMAND_LOADERS = {
|
|
|
147
151
|
browser: [loadBrowser],
|
|
148
152
|
computer: [loadComputer],
|
|
149
153
|
hosts: [loadHosts],
|
|
154
|
+
lease: [loadLease],
|
|
150
155
|
logs: [loadLogs],
|
|
151
156
|
events: [loadEvents],
|
|
152
157
|
ssh: [loadSsh],
|
|
153
158
|
devices: [loadSsh],
|
|
159
|
+
// `fleet` is a commander alias of `devices` (see commands/ssh.ts); list it so
|
|
160
|
+
// lazy registration loads the devices tree when the user types `agents fleet`.
|
|
161
|
+
fleet: [loadSsh],
|
|
154
162
|
pull: [loadPull],
|
|
155
163
|
push: [loadPush],
|
|
164
|
+
// `repos` is the canonical command name; `repo` remains a convenience alias
|
|
165
|
+
// (see commands/repo.ts). List both so lazy registration loads the tree
|
|
166
|
+
// whichever the user types.
|
|
167
|
+
repos: [loadRepo],
|
|
156
168
|
repo: [loadRepo],
|
|
157
169
|
setup: [loadSetup],
|
|
158
170
|
sessions: [loadSessions],
|
|
@@ -160,6 +172,10 @@ export const COMMAND_LOADERS = {
|
|
|
160
172
|
cloud: [loadCloud],
|
|
161
173
|
message: [loadMessage],
|
|
162
174
|
feed: [loadFeed],
|
|
175
|
+
mailboxes: [loadMailboxes],
|
|
176
|
+
mailbox: [loadMailboxes],
|
|
163
177
|
serve: [loadServe],
|
|
164
178
|
audit: [loadAudit],
|
|
179
|
+
webhook: [loadWebhook],
|
|
180
|
+
funnel: [loadFunnel],
|
|
165
181
|
};
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -109,13 +109,21 @@ export declare function getCacheDir(): string;
|
|
|
109
109
|
export declare function getPackagesDir(): string;
|
|
110
110
|
/** Path to routine YAML definitions (~/.agents/routines/). */
|
|
111
111
|
export declare function getRoutinesDir(): string;
|
|
112
|
+
/**
|
|
113
|
+
* Path to built-in routine definitions shipped in the system repo
|
|
114
|
+
* (`~/.agents/.system/routines/`). Unioned under the user routines dir by
|
|
115
|
+
* listJobs()/readJob(): a routine shipped here fires for every install, and a
|
|
116
|
+
* user routine of the same name overrides it (a user copy with `enabled: false`
|
|
117
|
+
* disables the built-in). The daemon fires these; the directory need not exist.
|
|
118
|
+
*/
|
|
119
|
+
export declare function getSystemRoutinesDir(): string;
|
|
112
120
|
/**
|
|
113
121
|
* Path to a project-scoped routines directory (`<project>/.agents/routines/`),
|
|
114
122
|
* or null when no project `.agents/` is found by walking up from cwd.
|
|
115
123
|
*
|
|
116
124
|
* Project routines participate in `list`/`view`/`run` for inspection but are
|
|
117
|
-
* NOT fired by the daemon (which runs from $HOME and only
|
|
118
|
-
* Opt-in firing for project routines is tracked as a follow-up.
|
|
125
|
+
* NOT fired by the daemon (which runs from $HOME and loads only user + system
|
|
126
|
+
* routines). Opt-in firing for project routines is tracked as a follow-up.
|
|
119
127
|
*/
|
|
120
128
|
export declare function getProjectRoutinesDir(cwd?: string): string | null;
|
|
121
129
|
/** Path to routine execution logs (~/.agents/.history/runs/). */
|
package/dist/lib/state.js
CHANGED
|
@@ -69,6 +69,10 @@ const SYSTEM_PERMISSIONS_DIR = path.join(SYSTEM_AGENTS_DIR, 'permissions');
|
|
|
69
69
|
const SYSTEM_SUBAGENTS_DIR = path.join(SYSTEM_AGENTS_DIR, 'subagents');
|
|
70
70
|
const SYSTEM_WORKFLOWS_DIR = path.join(SYSTEM_AGENTS_DIR, 'workflows');
|
|
71
71
|
const SYSTEM_PLUGINS_DIR = path.join(SYSTEM_AGENTS_DIR, 'plugins');
|
|
72
|
+
// Built-in routines shipped in the system repo (gh:phnx-labs/.agents-system).
|
|
73
|
+
// Unioned under user routines by listJobs()/readJob() so a routine shipped here
|
|
74
|
+
// fires for every install, while a user routine of the same name overrides it.
|
|
75
|
+
const SYSTEM_ROUTINES_DIR = path.join(SYSTEM_AGENTS_DIR, 'routines');
|
|
72
76
|
const SYSTEM_PROMPTCUTS_FILE = path.join(SYSTEM_AGENTS_DIR, 'hooks', 'promptcuts.yaml');
|
|
73
77
|
const SYSTEM_MCP_CONFIG_FILE = path.join(SYSTEM_AGENTS_DIR, 'mcp.json');
|
|
74
78
|
const SYSTEM_INSTRUCTIONS_FILE = path.join(SYSTEM_AGENTS_DIR, 'instructions.md');
|
|
@@ -296,13 +300,21 @@ export function getCacheDir() { return CACHE_DIR; }
|
|
|
296
300
|
export function getPackagesDir() { return PACKAGES_DIR; }
|
|
297
301
|
/** Path to routine YAML definitions (~/.agents/routines/). */
|
|
298
302
|
export function getRoutinesDir() { return ROUTINES_DIR; }
|
|
303
|
+
/**
|
|
304
|
+
* Path to built-in routine definitions shipped in the system repo
|
|
305
|
+
* (`~/.agents/.system/routines/`). Unioned under the user routines dir by
|
|
306
|
+
* listJobs()/readJob(): a routine shipped here fires for every install, and a
|
|
307
|
+
* user routine of the same name overrides it (a user copy with `enabled: false`
|
|
308
|
+
* disables the built-in). The daemon fires these; the directory need not exist.
|
|
309
|
+
*/
|
|
310
|
+
export function getSystemRoutinesDir() { return SYSTEM_ROUTINES_DIR; }
|
|
299
311
|
/**
|
|
300
312
|
* Path to a project-scoped routines directory (`<project>/.agents/routines/`),
|
|
301
313
|
* or null when no project `.agents/` is found by walking up from cwd.
|
|
302
314
|
*
|
|
303
315
|
* Project routines participate in `list`/`view`/`run` for inspection but are
|
|
304
|
-
* NOT fired by the daemon (which runs from $HOME and only
|
|
305
|
-
* Opt-in firing for project routines is tracked as a follow-up.
|
|
316
|
+
* NOT fired by the daemon (which runs from $HOME and loads only user + system
|
|
317
|
+
* routines). Opt-in firing for project routines is tracked as a follow-up.
|
|
306
318
|
*/
|
|
307
319
|
export function getProjectRoutinesDir(cwd = process.cwd()) {
|
|
308
320
|
const projectAgentsDir = getProjectAgentsDir(cwd);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { AgentId, InstalledSubagent, SubagentFrontmatter } from './types.js';
|
|
2
|
+
/** A path an installed subagent occupies, tagged for removal/trash handling. */
|
|
3
|
+
export interface OccupiedEntry {
|
|
4
|
+
path: string;
|
|
5
|
+
kind: 'file' | 'dir';
|
|
6
|
+
}
|
|
7
|
+
/** Parsed metadata for one installed subagent (drives the rich listing). */
|
|
8
|
+
export interface SubagentMeta {
|
|
9
|
+
frontmatter: SubagentFrontmatter;
|
|
10
|
+
files: string[];
|
|
11
|
+
/** Primary on-disk path for the listing's `path` field (a file or a dir, per layout). */
|
|
12
|
+
path: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The complete on-disk contract for one agent's subagents. Every operation is
|
|
16
|
+
* expressed here so the engine below never branches on the agent id.
|
|
17
|
+
*/
|
|
18
|
+
export interface SubagentTarget {
|
|
19
|
+
/** Absolute container dir under a home root (a version home or an agent home). */
|
|
20
|
+
dir(home: string): string;
|
|
21
|
+
/** Materialize central subagent `sub` into container `dir`. Throws on fs error. */
|
|
22
|
+
write(dir: string, sub: {
|
|
23
|
+
name: string;
|
|
24
|
+
path: string;
|
|
25
|
+
}): void;
|
|
26
|
+
/** Installed subagent names in `dir` (detector + orphan diff). */
|
|
27
|
+
names(dir: string): string[];
|
|
28
|
+
/** On-disk paths subagent `name` occupies (for removal / soft-delete). */
|
|
29
|
+
occupied(dir: string, name: string): OccupiedEntry[];
|
|
30
|
+
/** Rich metadata for `name`; `null` skips it from the listing. */
|
|
31
|
+
read(dir: string, name: string): SubagentMeta | null;
|
|
32
|
+
/** Optional post-sync pass over the just-synced subagents (Kimi's parent index). */
|
|
33
|
+
finalize?(dir: string, synced: Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
path: string;
|
|
36
|
+
}>): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Copy every file in `src` into `dest` (created if missing), applying
|
|
40
|
+
* `rename` (source filename -> target filename) on the way. Directories in
|
|
41
|
+
* `src` are skipped -- subagents are flat file sets. Throws on fs error.
|
|
42
|
+
*/
|
|
43
|
+
export declare function copyDirWithRename(src: string, dest: string, rename?: Record<string, string>): void;
|
|
44
|
+
/**
|
|
45
|
+
* Single source of truth for how each subagents-capable agent stores subagents.
|
|
46
|
+
* The keys MUST match `capableAgents('subagents')` (the `subagents` flag in
|
|
47
|
+
* `agents.ts`): the capability flag is the version gate, this table is the shape.
|
|
48
|
+
*/
|
|
49
|
+
export declare const SUBAGENT_TARGETS: Partial<Record<AgentId, SubagentTarget>>;
|
|
50
|
+
/** The registry entry for `agent`, or undefined if it stores no subagents. */
|
|
51
|
+
export declare function subagentTarget(agent: AgentId): SubagentTarget | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Materialize central subagent `sub` into `home` for `agent`. Returns whether a
|
|
54
|
+
* write happened (false when the agent has no registry entry). Throws only on
|
|
55
|
+
* unexpected fs errors -- bulk callers wrap per-item.
|
|
56
|
+
*/
|
|
57
|
+
export declare function writeSubagentToHome(agent: AgentId, home: string, sub: {
|
|
58
|
+
name: string;
|
|
59
|
+
path: string;
|
|
60
|
+
}): boolean;
|
|
61
|
+
/** Installed subagent names for `agent` under `home` (detector + orphan diff). */
|
|
62
|
+
export declare function listInstalledSubagentNames(agent: AgentId, home: string): string[];
|
|
63
|
+
/**
|
|
64
|
+
* Rich listing of subagents installed for `agent` under `home`, with parsed
|
|
65
|
+
* metadata. Enumerates names, then reads each -- entries whose metadata is
|
|
66
|
+
* unreadable (per the target's reader) are dropped.
|
|
67
|
+
*/
|
|
68
|
+
export declare function listInstalledSubagentsRich(agent: AgentId, home: string): InstalledSubagent[];
|
|
69
|
+
/**
|
|
70
|
+
* Remove subagent `name` for `agent` from `home` (hard delete). No-op success
|
|
71
|
+
* when the agent has no registry entry or nothing is installed.
|
|
72
|
+
*/
|
|
73
|
+
export declare function removeSubagentFromHome(agent: AgentId, home: string, name: string): {
|
|
74
|
+
success: boolean;
|
|
75
|
+
error?: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Soft-delete subagent `name` for `agent` from `home` into `trashDir`, stamping
|
|
79
|
+
* each moved entry. Files land as `<basename>.<stamp>`, directories as
|
|
80
|
+
* `<stamp>/`. No-op success when nothing is installed.
|
|
81
|
+
*/
|
|
82
|
+
export declare function trashSubagentFromHome(agent: AgentId, home: string, name: string, trashDir: string, stamp: string): {
|
|
83
|
+
success: boolean;
|
|
84
|
+
error?: string;
|
|
85
|
+
};
|