@phnx-labs/agents-cli 1.20.72 → 1.20.74
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 +395 -0
- package/README.md +40 -4
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +12 -0
- package/dist/commands/activity.js +68 -0
- package/dist/commands/apply.d.ts +13 -0
- package/dist/commands/apply.js +28 -3
- package/dist/commands/browser.js +1 -1
- package/dist/commands/cloud.js +21 -11
- package/dist/commands/doctor.js +21 -5
- package/dist/commands/events.d.ts +11 -10
- package/dist/commands/events.js +30 -21
- package/dist/commands/exec.d.ts +34 -0
- package/dist/commands/exec.js +337 -39
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.js +215 -0
- package/dist/commands/feed.d.ts +13 -0
- package/dist/commands/feed.js +130 -29
- package/dist/commands/hq.d.ts +2 -0
- package/dist/commands/hq.js +58 -0
- package/dist/commands/import.js +51 -3
- package/dist/commands/lease.d.ts +19 -0
- package/dist/commands/lease.js +138 -11
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/mine.d.ts +27 -0
- package/dist/commands/mine.js +207 -0
- package/dist/commands/monitors.js +79 -49
- package/dist/commands/plugins.js +1 -0
- package/dist/commands/profiles.js +158 -0
- package/dist/commands/repo.js +2 -60
- package/dist/commands/resources.d.ts +5 -0
- package/dist/commands/resources.js +95 -0
- package/dist/commands/routines.d.ts +2 -0
- package/dist/commands/routines.js +139 -37
- package/dist/commands/secrets.js +234 -47
- package/dist/commands/send.d.ts +15 -0
- package/dist/commands/send.js +62 -0
- package/dist/commands/sessions-tail.d.ts +1 -0
- package/dist/commands/sessions-tail.js +20 -9
- package/dist/commands/sessions.js +18 -3
- package/dist/commands/setup-mine.d.ts +18 -0
- package/dist/commands/setup-mine.js +106 -0
- package/dist/commands/setup-share.js +2 -2
- package/dist/commands/setup.js +9 -2
- package/dist/commands/share.d.ts +8 -1
- package/dist/commands/share.js +122 -37
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +196 -26
- package/dist/commands/sync.js +1 -1
- package/dist/commands/teams.js +11 -2
- package/dist/commands/versions.js +36 -5
- package/dist/commands/view.js +75 -27
- package/dist/index.js +80 -10
- package/dist/lib/activity.d.ts +124 -0
- package/dist/lib/activity.js +542 -0
- package/dist/lib/agents.d.ts +35 -0
- package/dist/lib/agents.js +79 -6
- package/dist/lib/artifact-actions.d.ts +1 -1
- package/dist/lib/artifact-actions.js +1 -1
- package/dist/lib/ask-classifier.d.ts +2 -1
- package/dist/lib/ask-classifier.js +3 -3
- package/dist/lib/auth-health.d.ts +32 -4
- package/dist/lib/auth-health.js +40 -1
- package/dist/lib/auto-pull.js +8 -1
- package/dist/lib/brand.d.ts +40 -0
- package/dist/lib/brand.js +122 -0
- package/dist/lib/browser/drivers/ssh.js +4 -7
- package/dist/lib/browser/service.js +6 -8
- package/dist/lib/channels/providers/index.d.ts +2 -0
- package/dist/lib/channels/providers/index.js +20 -0
- package/dist/lib/channels/providers/mailbox.d.ts +2 -0
- package/dist/lib/channels/providers/mailbox.js +26 -0
- package/dist/lib/channels/providers/openclaw-telegram.d.ts +2 -0
- package/dist/lib/channels/providers/openclaw-telegram.js +34 -0
- package/dist/lib/channels/providers/rush.d.ts +6 -0
- package/dist/lib/channels/providers/rush.js +55 -0
- package/dist/lib/channels/registry.d.ts +42 -0
- package/dist/lib/channels/registry.js +20 -0
- package/dist/lib/channels/resolve.d.ts +11 -0
- package/dist/lib/channels/resolve.js +12 -0
- package/dist/lib/cli-resources.d.ts +18 -0
- package/dist/lib/cli-resources.js +53 -4
- package/dist/lib/cloud/codex.js +6 -3
- package/dist/lib/cloud/factory.d.ts +1 -0
- package/dist/lib/cloud/factory.js +10 -4
- package/dist/lib/cloud/rush.d.ts +3 -1
- package/dist/lib/cloud/rush.js +6 -1
- package/dist/lib/cloud/types.d.ts +2 -0
- package/dist/lib/codex-home.d.ts +35 -0
- package/dist/lib/codex-home.js +136 -0
- package/dist/lib/config-transfer.d.ts +16 -0
- package/dist/lib/config-transfer.js +56 -0
- package/dist/lib/crabbox/cli.d.ts +44 -0
- package/dist/lib/crabbox/cli.js +120 -20
- package/dist/lib/crabbox/lease.d.ts +52 -1
- package/dist/lib/crabbox/lease.js +117 -16
- package/dist/lib/crabbox/progress.d.ts +31 -0
- package/dist/lib/crabbox/progress.js +76 -0
- package/dist/lib/crabbox/runtimes.d.ts +4 -0
- package/dist/lib/crabbox/runtimes.js +33 -8
- package/dist/lib/crabbox/setup-copy.d.ts +87 -0
- package/dist/lib/crabbox/setup-copy.js +127 -0
- package/dist/lib/daemon.d.ts +5 -5
- package/dist/lib/daemon.js +9 -9
- package/dist/lib/drive-sync.js +6 -3
- package/dist/lib/event-stream.d.ts +36 -0
- package/dist/lib/event-stream.js +68 -0
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/exec.d.ts +11 -0
- package/dist/lib/exec.js +23 -2
- package/dist/lib/export.d.ts +72 -0
- package/dist/lib/export.js +269 -0
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +14 -9
- package/dist/lib/feed-ranking.d.ts +32 -0
- package/dist/lib/feed-ranking.js +224 -0
- package/dist/lib/feed.d.ts +35 -2
- package/dist/lib/feed.js +66 -3
- package/dist/lib/fleet/auth-sync.d.ts +53 -0
- package/dist/lib/fleet/auth-sync.js +92 -0
- package/dist/lib/fleet/remote-login.d.ts +187 -0
- package/dist/lib/fleet/remote-login.js +556 -0
- package/dist/lib/format.d.ts +30 -3
- package/dist/lib/format.js +34 -5
- package/dist/lib/fs-atomic.d.ts +7 -2
- package/dist/lib/fs-atomic.js +8 -12
- package/dist/lib/git.d.ts +16 -0
- package/dist/lib/git.js +79 -2
- package/dist/lib/heal.js +11 -3
- package/dist/lib/hosts/progress.d.ts +28 -10
- package/dist/lib/hosts/progress.js +79 -22
- package/dist/lib/hosts/remote-cmd.js +4 -0
- package/dist/lib/hq/floor.d.ts +87 -0
- package/dist/lib/hq/floor.js +226 -0
- package/dist/lib/import.d.ts +23 -0
- package/dist/lib/import.js +74 -2
- package/dist/lib/isolation-boundary-report.d.ts +10 -0
- package/dist/lib/isolation-boundary-report.js +35 -0
- package/dist/lib/menubar/install-menubar.js +14 -20
- package/dist/lib/notify.d.ts +1 -0
- package/dist/lib/notify.js +3 -3
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.js +19 -0
- package/dist/lib/openclaw-keychain.d.ts +56 -0
- package/dist/lib/openclaw-keychain.js +236 -0
- package/dist/lib/overdue.js +10 -0
- package/dist/lib/permissions.d.ts +44 -1
- package/dist/lib/permissions.js +284 -7
- package/dist/lib/project-launch.d.ts +6 -12
- package/dist/lib/project-launch.js +13 -228
- package/dist/lib/project-resources.d.ts +7 -0
- package/dist/lib/project-resources.js +306 -0
- package/dist/lib/pty-client.d.ts +27 -0
- package/dist/lib/pty-client.js +136 -10
- package/dist/lib/refresh.js +14 -10
- package/dist/lib/resource-profiles.d.ts +26 -0
- package/dist/lib/resource-profiles.js +157 -0
- package/dist/lib/resources/permissions.js +7 -1
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +1 -1
- package/dist/lib/resources.js +32 -3
- package/dist/lib/routines.d.ts +11 -0
- package/dist/lib/routines.js +56 -15
- package/dist/lib/runner.d.ts +1 -0
- package/dist/lib/runner.js +66 -5
- package/dist/lib/secrets/bundles.d.ts +16 -3
- package/dist/lib/secrets/bundles.js +206 -37
- package/dist/lib/secrets/icloud-import.d.ts +2 -2
- package/dist/lib/secrets/icloud-import.js +9 -6
- package/dist/lib/secrets/mcp.js +1 -1
- package/dist/lib/secrets/vault-age-helper.d.ts +1 -0
- package/dist/lib/secrets/vault-age-helper.js +34 -0
- package/dist/lib/secrets/vault.d.ts +49 -0
- package/dist/lib/secrets/vault.js +397 -0
- package/dist/lib/self-heal/checks/path.js +3 -1
- package/dist/lib/self-heal/checks/shadowing.js +10 -2
- package/dist/lib/self-heal/checks/shims.js +19 -11
- package/dist/lib/session/cloud.d.ts +2 -2
- package/dist/lib/session/cloud.js +2 -2
- package/dist/lib/session/db.d.ts +4 -0
- package/dist/lib/session/db.js +44 -7
- package/dist/lib/session/discover.d.ts +2 -0
- package/dist/lib/session/discover.js +114 -3
- package/dist/lib/session/stream-render.d.ts +3 -0
- package/dist/lib/session/stream-render.js +130 -0
- package/dist/lib/session/types.d.ts +6 -0
- package/dist/lib/share/analytics.d.ts +13 -0
- package/dist/lib/share/analytics.js +45 -0
- package/dist/lib/share/config.d.ts +19 -5
- package/dist/lib/share/config.js +44 -8
- package/dist/lib/share/provision.d.ts +58 -6
- package/dist/lib/share/provision.js +97 -22
- package/dist/lib/share/publish.d.ts +36 -13
- package/dist/lib/share/publish.js +55 -8
- package/dist/lib/share/worker-template.js +83 -17
- package/dist/lib/shims.d.ts +35 -0
- package/dist/lib/shims.js +159 -13
- package/dist/lib/ssh-exec.d.ts +14 -0
- package/dist/lib/ssh-exec.js +57 -0
- package/dist/lib/staleness/detectors/hooks.js +25 -1
- package/dist/lib/staleness/detectors/permissions.js +66 -0
- package/dist/lib/staleness/detectors/workflows.js +20 -0
- package/dist/lib/staleness/writers/hooks.js +58 -4
- package/dist/lib/staleness/writers/permissions.js +2 -2
- package/dist/lib/staleness/writers/skills.js +1 -1
- package/dist/lib/staleness/writers/sources.d.ts +10 -1
- package/dist/lib/staleness/writers/sources.js +68 -1
- package/dist/lib/star-nudge.d.ts +45 -0
- package/dist/lib/star-nudge.js +91 -0
- package/dist/lib/startup/command-registry.d.ts +7 -1
- package/dist/lib/startup/command-registry.js +19 -3
- package/dist/lib/state.d.ts +2 -0
- package/dist/lib/state.js +17 -4
- package/dist/lib/subagents-registry.d.ts +2 -0
- package/dist/lib/subagents-registry.js +3 -0
- package/dist/lib/teams/parsers.js +214 -6
- package/dist/lib/teams/supervisor.d.ts +7 -0
- package/dist/lib/teams/supervisor.js +2 -1
- package/dist/lib/template.d.ts +1 -1
- package/dist/lib/template.js +1 -1
- package/dist/lib/triggers/webhook.js +36 -3
- package/dist/lib/types.d.ts +84 -0
- package/dist/lib/uninstall.js +1 -45
- package/dist/lib/version.d.ts +40 -0
- package/dist/lib/version.js +94 -16
- package/dist/lib/versions.d.ts +24 -0
- package/dist/lib/versions.js +269 -78
- package/dist/lib/workflows.d.ts +2 -0
- package/dist/lib/workflows.js +88 -0
- package/package.json +2 -1
- package/dist/commands/daemon.d.ts +0 -10
- package/dist/commands/daemon.js +0 -121
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { extractFileOpsFromBash } from './file_ops.js';
|
|
10
10
|
const claudeToolUseMap = new Map();
|
|
11
|
+
const droidToolUseMap = new Map();
|
|
11
12
|
/** Normalize a raw JSON event from any agent type into an array of unified event objects. */
|
|
12
13
|
export function normalizeEvents(agentType, raw) {
|
|
13
14
|
if (agentType === 'codex') {
|
|
@@ -34,12 +35,9 @@ export function normalizeEvents(agentType, raw) {
|
|
|
34
35
|
else if (agentType === 'kimi') {
|
|
35
36
|
return normalizeKimi(raw);
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// still stream and render; structured tool/file categorization will be added
|
|
41
|
-
// once a real `droid exec -o stream-json` sample is captured. Do NOT guess the
|
|
42
|
-
// schema here — a wrong discriminator silently mislabels every event.
|
|
38
|
+
else if (agentType === 'droid') {
|
|
39
|
+
return normalizeDroid(raw);
|
|
40
|
+
}
|
|
43
41
|
const timestamp = new Date().toISOString();
|
|
44
42
|
return [{
|
|
45
43
|
type: raw.type || 'unknown',
|
|
@@ -1078,6 +1076,216 @@ function normalizeKimi(raw) {
|
|
|
1078
1076
|
timestamp: timestamp,
|
|
1079
1077
|
}];
|
|
1080
1078
|
}
|
|
1079
|
+
// --- Droid parsing ---
|
|
1080
|
+
// Droid's `droid exec -o stream-json` stream mirrors the Factory session JSONL
|
|
1081
|
+
// envelope: session_start records plus Anthropic-shaped message content blocks.
|
|
1082
|
+
// Tool blocks carry the actionable file path / command in `input`; result blocks
|
|
1083
|
+
// only carry `tool_use_id`, so keep a small id map just like normalizeClaude.
|
|
1084
|
+
function normalizeDroid(raw) {
|
|
1085
|
+
const timestamp = typeof raw?.timestamp === 'string' ? raw.timestamp : new Date().toISOString();
|
|
1086
|
+
if (!raw || typeof raw !== 'object') {
|
|
1087
|
+
return [{
|
|
1088
|
+
type: 'unknown',
|
|
1089
|
+
agent: 'droid',
|
|
1090
|
+
raw: raw,
|
|
1091
|
+
timestamp: timestamp,
|
|
1092
|
+
}];
|
|
1093
|
+
}
|
|
1094
|
+
const eventType = typeof raw.type === 'string' ? raw.type : 'unknown';
|
|
1095
|
+
if (eventType === 'session_start') {
|
|
1096
|
+
return [{
|
|
1097
|
+
type: 'init',
|
|
1098
|
+
agent: 'droid',
|
|
1099
|
+
session_id: typeof raw.id === 'string' ? raw.id : null,
|
|
1100
|
+
timestamp: timestamp,
|
|
1101
|
+
}];
|
|
1102
|
+
}
|
|
1103
|
+
if (eventType === 'result') {
|
|
1104
|
+
return [{
|
|
1105
|
+
type: 'result',
|
|
1106
|
+
agent: 'droid',
|
|
1107
|
+
status: raw.is_error === true ? 'error' : 'success',
|
|
1108
|
+
message: typeof raw.result === 'string' ? raw.result : undefined,
|
|
1109
|
+
timestamp: timestamp,
|
|
1110
|
+
}];
|
|
1111
|
+
}
|
|
1112
|
+
if (eventType !== 'message') {
|
|
1113
|
+
return [{
|
|
1114
|
+
type: eventType,
|
|
1115
|
+
agent: 'droid',
|
|
1116
|
+
raw: raw,
|
|
1117
|
+
timestamp: timestamp,
|
|
1118
|
+
}];
|
|
1119
|
+
}
|
|
1120
|
+
const message = raw.message || {};
|
|
1121
|
+
const role = message.role === 'user' ? 'user' : 'assistant';
|
|
1122
|
+
const blocks = message.content;
|
|
1123
|
+
if (typeof blocks === 'string') {
|
|
1124
|
+
const content = blocks.trim();
|
|
1125
|
+
if (!content)
|
|
1126
|
+
return [];
|
|
1127
|
+
return role === 'assistant'
|
|
1128
|
+
? [{ type: 'message', agent: 'droid', content, complete: true, timestamp }]
|
|
1129
|
+
: [{ type: 'user_message', agent: 'droid', content, timestamp }];
|
|
1130
|
+
}
|
|
1131
|
+
if (!Array.isArray(blocks))
|
|
1132
|
+
return [];
|
|
1133
|
+
const events = [];
|
|
1134
|
+
for (const block of blocks) {
|
|
1135
|
+
if (!block || typeof block !== 'object')
|
|
1136
|
+
continue;
|
|
1137
|
+
if (block.type === 'text') {
|
|
1138
|
+
const text = typeof block.text === 'string' ? block.text.trim() : '';
|
|
1139
|
+
if (!text)
|
|
1140
|
+
continue;
|
|
1141
|
+
if (role === 'assistant') {
|
|
1142
|
+
events.push({
|
|
1143
|
+
type: 'message',
|
|
1144
|
+
agent: 'droid',
|
|
1145
|
+
content: text,
|
|
1146
|
+
complete: true,
|
|
1147
|
+
timestamp: timestamp,
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
else if (!text.startsWith('<system-reminder>') && !text.startsWith('Hook execution:')) {
|
|
1151
|
+
events.push({
|
|
1152
|
+
type: 'user_message',
|
|
1153
|
+
agent: 'droid',
|
|
1154
|
+
content: text,
|
|
1155
|
+
timestamp: timestamp,
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
if (block.type === 'thinking') {
|
|
1161
|
+
const thinking = typeof block.thinking === 'string' ? block.thinking.trim() : '';
|
|
1162
|
+
if (thinking) {
|
|
1163
|
+
events.push({
|
|
1164
|
+
type: 'thinking',
|
|
1165
|
+
agent: 'droid',
|
|
1166
|
+
content: thinking,
|
|
1167
|
+
timestamp: timestamp,
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
continue;
|
|
1171
|
+
}
|
|
1172
|
+
if (block.type === 'tool_use') {
|
|
1173
|
+
events.push(...normalizeDroidToolUse(block, timestamp));
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
if (block.type === 'tool_result') {
|
|
1177
|
+
const toolUseId = typeof block.tool_use_id === 'string' ? block.tool_use_id : null;
|
|
1178
|
+
const toolInfo = toolUseId ? droidToolUseMap.get(toolUseId) : undefined;
|
|
1179
|
+
if (toolUseId)
|
|
1180
|
+
droidToolUseMap.delete(toolUseId);
|
|
1181
|
+
const content = extractDroidToolResultContent(block.content);
|
|
1182
|
+
if (block.is_error === true) {
|
|
1183
|
+
events.push({
|
|
1184
|
+
type: 'error',
|
|
1185
|
+
agent: 'droid',
|
|
1186
|
+
tool: toolInfo?.tool,
|
|
1187
|
+
content: content || 'Tool execution failed',
|
|
1188
|
+
timestamp: timestamp,
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
else {
|
|
1192
|
+
events.push({
|
|
1193
|
+
type: 'tool_result',
|
|
1194
|
+
agent: 'droid',
|
|
1195
|
+
tool: toolInfo?.tool,
|
|
1196
|
+
tool_call_id: toolUseId,
|
|
1197
|
+
success: true,
|
|
1198
|
+
content: content.length > 500 ? content.slice(0, 497) + '...' : content,
|
|
1199
|
+
timestamp: timestamp,
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return events;
|
|
1205
|
+
}
|
|
1206
|
+
function normalizeDroidToolUse(block, timestamp) {
|
|
1207
|
+
const toolName = typeof block.name === 'string' ? block.name : 'unknown';
|
|
1208
|
+
const toolInput = block.input && typeof block.input === 'object' ? block.input : {};
|
|
1209
|
+
if (typeof block.id === 'string') {
|
|
1210
|
+
droidToolUseMap.set(block.id, { tool: toolName, args: toolInput });
|
|
1211
|
+
}
|
|
1212
|
+
const filePath = toolInput.file_path || toolInput.path || '';
|
|
1213
|
+
const command = toolInput.command || '';
|
|
1214
|
+
if ((toolName === 'Execute' || toolName === 'Bash') && command) {
|
|
1215
|
+
const events = [{
|
|
1216
|
+
type: 'bash',
|
|
1217
|
+
agent: 'droid',
|
|
1218
|
+
tool: toolName,
|
|
1219
|
+
command: command,
|
|
1220
|
+
timestamp: timestamp,
|
|
1221
|
+
}];
|
|
1222
|
+
const [filesRead, filesWritten, filesDeleted] = extractFileOpsFromBash(command);
|
|
1223
|
+
for (const path of filesRead) {
|
|
1224
|
+
events.push({ type: 'file_read', agent: 'droid', tool: 'bash', path, command, timestamp });
|
|
1225
|
+
}
|
|
1226
|
+
for (const path of filesWritten) {
|
|
1227
|
+
events.push({ type: 'file_write', agent: 'droid', tool: 'bash', path, command, timestamp });
|
|
1228
|
+
}
|
|
1229
|
+
for (const path of filesDeleted) {
|
|
1230
|
+
events.push({ type: 'file_delete', agent: 'droid', tool: 'bash', path, command, timestamp });
|
|
1231
|
+
}
|
|
1232
|
+
return events;
|
|
1233
|
+
}
|
|
1234
|
+
if (toolName === 'Read' && filePath) {
|
|
1235
|
+
return [{
|
|
1236
|
+
type: 'file_read',
|
|
1237
|
+
agent: 'droid',
|
|
1238
|
+
tool: toolName,
|
|
1239
|
+
path: filePath,
|
|
1240
|
+
timestamp: timestamp,
|
|
1241
|
+
}];
|
|
1242
|
+
}
|
|
1243
|
+
if ((toolName === 'Create' || toolName === 'Write') && filePath) {
|
|
1244
|
+
return [{
|
|
1245
|
+
type: 'file_create',
|
|
1246
|
+
agent: 'droid',
|
|
1247
|
+
tool: toolName,
|
|
1248
|
+
path: filePath,
|
|
1249
|
+
timestamp: timestamp,
|
|
1250
|
+
}];
|
|
1251
|
+
}
|
|
1252
|
+
if ((toolName === 'Edit' || toolName === 'MultiEdit') && filePath) {
|
|
1253
|
+
return [{
|
|
1254
|
+
type: 'file_write',
|
|
1255
|
+
agent: 'droid',
|
|
1256
|
+
tool: toolName,
|
|
1257
|
+
path: filePath,
|
|
1258
|
+
timestamp: timestamp,
|
|
1259
|
+
}];
|
|
1260
|
+
}
|
|
1261
|
+
if ((toolName === 'Delete' || toolName === 'Remove') && filePath) {
|
|
1262
|
+
return [{
|
|
1263
|
+
type: 'file_delete',
|
|
1264
|
+
agent: 'droid',
|
|
1265
|
+
tool: toolName,
|
|
1266
|
+
path: filePath,
|
|
1267
|
+
timestamp: timestamp,
|
|
1268
|
+
}];
|
|
1269
|
+
}
|
|
1270
|
+
return [{
|
|
1271
|
+
type: 'tool_use',
|
|
1272
|
+
agent: 'droid',
|
|
1273
|
+
tool: toolName,
|
|
1274
|
+
args: toolInput,
|
|
1275
|
+
timestamp: timestamp,
|
|
1276
|
+
}];
|
|
1277
|
+
}
|
|
1278
|
+
function extractDroidToolResultContent(content) {
|
|
1279
|
+
if (typeof content === 'string')
|
|
1280
|
+
return content;
|
|
1281
|
+
if (Array.isArray(content)) {
|
|
1282
|
+
return content
|
|
1283
|
+
.filter((part) => part && typeof part === 'object' && part.type === 'text')
|
|
1284
|
+
.map((part) => typeof part.text === 'string' ? part.text : '')
|
|
1285
|
+
.join('\n');
|
|
1286
|
+
}
|
|
1287
|
+
return '';
|
|
1288
|
+
}
|
|
1081
1289
|
// --- Antigravity parsing ---
|
|
1082
1290
|
// Intentionally conservative. Antigravity's `agy` binary advertises an
|
|
1083
1291
|
// `--output-format json` flag in its docs, but the released binary errors with
|
|
@@ -51,6 +51,13 @@ export interface SupervisorResult {
|
|
|
51
51
|
waves: number;
|
|
52
52
|
stoppedBy: 'drained' | 'max-waves' | 'signal' | 'callback' | 'budget';
|
|
53
53
|
elapsed_ms: number;
|
|
54
|
+
/**
|
|
55
|
+
* Number of teammates in the `failed` state when the team drained. Only set
|
|
56
|
+
* for `stoppedBy === 'drained'`. A drained DAG means nothing is pending or
|
|
57
|
+
* running — NOT that everything succeeded — so callers that treat "drained"
|
|
58
|
+
* as success (e.g. a completion nudge) must check `failed === 0` first.
|
|
59
|
+
*/
|
|
60
|
+
failed?: number;
|
|
54
61
|
/** Set when `stoppedBy === 'budget'` — the breach that terminated the team. */
|
|
55
62
|
budgetBreach?: BreachInfo;
|
|
56
63
|
}
|
|
@@ -80,7 +80,8 @@ export async function runSupervisor(mgr, opts) {
|
|
|
80
80
|
const afterCallback = await mgr.listByTask(team);
|
|
81
81
|
const stillLive = afterCallback.some((a) => a.status === 'pending' || a.status === 'running');
|
|
82
82
|
if (!stillLive) {
|
|
83
|
-
|
|
83
|
+
const failed = afterCallback.filter((a) => a.status === 'failed').length;
|
|
84
|
+
return { waves: wave, stoppedBy: 'drained', failed, elapsed_ms: Date.now() - startedAt };
|
|
84
85
|
}
|
|
85
86
|
if (stopSignal) {
|
|
86
87
|
return { waves: wave, stoppedBy: 'signal', elapsed_ms: Date.now() - startedAt };
|
package/dist/lib/template.d.ts
CHANGED
package/dist/lib/template.js
CHANGED
|
@@ -77,18 +77,46 @@ function linearTeamKey(payload) {
|
|
|
77
77
|
return typeof team?.key === 'string' ? team.key : null;
|
|
78
78
|
}
|
|
79
79
|
function linearLabels(payload) {
|
|
80
|
+
// Linear webhook bodies flatten list relations: an Issue event carries
|
|
81
|
+
// `data.labels` as a flat array of label objects (`[{ id, name, color }]`),
|
|
82
|
+
// NOT the `{ nodes: [...] }` connection shape returned by the GraphQL API.
|
|
83
|
+
// Reading `.nodes` here made every `--label` filter match nothing.
|
|
80
84
|
const data = payload.data;
|
|
81
|
-
const labels = data?.labels;
|
|
82
|
-
|
|
83
|
-
return nodes
|
|
85
|
+
const labels = Array.isArray(data?.labels) ? data?.labels : [];
|
|
86
|
+
return labels
|
|
84
87
|
.map((n) => n.name)
|
|
85
88
|
.filter((n) => typeof n === 'string' && n.length > 0);
|
|
86
89
|
}
|
|
90
|
+
function githubAction(payload) {
|
|
91
|
+
return typeof payload.action === 'string' ? payload.action : null;
|
|
92
|
+
}
|
|
93
|
+
function githubLabels(payload) {
|
|
94
|
+
const names = new Set();
|
|
95
|
+
const add = (value) => {
|
|
96
|
+
if (typeof value === 'string' && value.length > 0)
|
|
97
|
+
names.add(value);
|
|
98
|
+
};
|
|
99
|
+
const deliveryLabel = payload.label;
|
|
100
|
+
add(deliveryLabel?.name);
|
|
101
|
+
const pr = payload.pull_request;
|
|
102
|
+
const prLabels = Array.isArray(pr?.labels) ? pr.labels : [];
|
|
103
|
+
for (const label of prLabels) {
|
|
104
|
+
add(label.name);
|
|
105
|
+
}
|
|
106
|
+
const issue = payload.issue;
|
|
107
|
+
const issueLabels = Array.isArray(issue?.labels) ? issue.labels : [];
|
|
108
|
+
for (const label of issueLabels) {
|
|
109
|
+
add(label.name);
|
|
110
|
+
}
|
|
111
|
+
return [...names];
|
|
112
|
+
}
|
|
87
113
|
function githubTriggerMatches(trigger, webhook) {
|
|
88
114
|
if (webhook.source !== 'github')
|
|
89
115
|
return false;
|
|
90
116
|
if (trigger.event !== webhook.event)
|
|
91
117
|
return false;
|
|
118
|
+
if (trigger.action && githubAction(webhook.payload) !== trigger.action)
|
|
119
|
+
return false;
|
|
92
120
|
if (trigger.repo) {
|
|
93
121
|
const repo = webhookRepo(webhook.payload);
|
|
94
122
|
if (!repo || repo.toLowerCase() !== trigger.repo.toLowerCase())
|
|
@@ -99,6 +127,11 @@ function githubTriggerMatches(trigger, webhook) {
|
|
|
99
127
|
if (!branches.some((b) => b === trigger.branch))
|
|
100
128
|
return false;
|
|
101
129
|
}
|
|
130
|
+
if (trigger.label) {
|
|
131
|
+
const expected = trigger.label.toLowerCase();
|
|
132
|
+
if (!githubLabels(webhook.payload).some((name) => name.toLowerCase() === expected))
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
102
135
|
return true;
|
|
103
136
|
}
|
|
104
137
|
function linearTriggerMatches(trigger, webhook) {
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -508,6 +508,29 @@ export interface VersionResources {
|
|
|
508
508
|
permissions?: ResourcePattern[];
|
|
509
509
|
mcp?: ResourcePattern[];
|
|
510
510
|
}
|
|
511
|
+
/** Resource-kind selectors controlled by top-level resource profiles. */
|
|
512
|
+
export interface ResourceProfilePreset {
|
|
513
|
+
description?: string;
|
|
514
|
+
commands?: ResourcePattern[];
|
|
515
|
+
skills?: ResourcePattern[];
|
|
516
|
+
hooks?: ResourcePattern[];
|
|
517
|
+
subagents?: ResourcePattern[];
|
|
518
|
+
plugins?: ResourcePattern[];
|
|
519
|
+
workflows?: ResourcePattern[];
|
|
520
|
+
permissions?: ResourcePattern[];
|
|
521
|
+
mcp?: ResourcePattern[];
|
|
522
|
+
/** Rule preset name to compose while this profile is active. */
|
|
523
|
+
rules?: string;
|
|
524
|
+
/** Alias for rules, accepted so YAML can mirror VersionResources naming. */
|
|
525
|
+
rulesPreset?: string;
|
|
526
|
+
/** Secrets bundle names, or "*" for every bundle. */
|
|
527
|
+
secrets?: string[];
|
|
528
|
+
}
|
|
529
|
+
/** Top-level profiles/presets that switch the resolved resource view. */
|
|
530
|
+
export interface ResourceProfilesConfig {
|
|
531
|
+
active?: string;
|
|
532
|
+
presets?: Record<string, ResourceProfilePreset>;
|
|
533
|
+
}
|
|
511
534
|
/** A userConfig field declared in a plugin manifest. */
|
|
512
535
|
export interface PluginUserConfigField {
|
|
513
536
|
key: string;
|
|
@@ -644,9 +667,42 @@ export interface ExtraRepoConfig {
|
|
|
644
667
|
path?: string;
|
|
645
668
|
enabled: boolean;
|
|
646
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* A white-label brand — a personally-named CLI (e.g. `jack`) that IS agents-cli,
|
|
672
|
+
* minted by `agents setup mine` / `agents mine`. The brand's shim exports
|
|
673
|
+
* `AGENTS_BRAND=<name>`; the entrypoint reads it to present under this name and
|
|
674
|
+
* apply the customization below. Portable user config — rides `agents repo
|
|
675
|
+
* push/pull`. See lib/brand.ts.
|
|
676
|
+
*/
|
|
677
|
+
export interface BrandConfig {
|
|
678
|
+
/** The brand name; also the binary name on PATH. */
|
|
679
|
+
name: string;
|
|
680
|
+
/** Built-in top-level commands this brand hides/disables (e.g. `["teams"]`). */
|
|
681
|
+
disabledCommands?: string[];
|
|
682
|
+
/**
|
|
683
|
+
* Resource-profile preset this brand pins (a key in `profiles.presets`). When
|
|
684
|
+
* the CLI runs under this brand, that preset becomes the active profile, so
|
|
685
|
+
* skills/plugins/mcp/hooks/etc. filter to the brand's curated set. Defaults to
|
|
686
|
+
* `mine-<name>`.
|
|
687
|
+
*/
|
|
688
|
+
profile?: string;
|
|
689
|
+
/** False to keep the config but stop minting/using the brand. */
|
|
690
|
+
enabled: boolean;
|
|
691
|
+
}
|
|
647
692
|
/** Top-level structure of ~/.agents/.system/agents.yaml -- the CLI's persistent state. */
|
|
648
693
|
export interface Meta {
|
|
649
694
|
agents?: Partial<Record<AgentId, string>>;
|
|
695
|
+
/**
|
|
696
|
+
* Per-agent preferred ISOLATED version — which copy a bare `agents run <agent>`
|
|
697
|
+
* resolves to when the agent has no global default.
|
|
698
|
+
*
|
|
699
|
+
* Kept separate from `agents` on purpose. An entry there is the global default,
|
|
700
|
+
* which owns the launcher, the bare shim and the real `~/.<agent>` config
|
|
701
|
+
* symlink, and arms the self-heal `shadowing` check. An isolated copy must never
|
|
702
|
+
* acquire any of that, so it cannot be recorded in the same place — the
|
|
703
|
+
* separation is what keeps `getGlobalDefault` incapable of returning one.
|
|
704
|
+
*/
|
|
705
|
+
isolatedAgents?: Partial<Record<AgentId, string>>;
|
|
650
706
|
run?: RunConfig;
|
|
651
707
|
/**
|
|
652
708
|
* `agents run --lease` config. `secretsBundle` names the keychain secrets bundle
|
|
@@ -682,6 +738,12 @@ export interface Meta {
|
|
|
682
738
|
enabled?: BetaFeatureName[];
|
|
683
739
|
};
|
|
684
740
|
registries?: Record<RegistryType, Record<string, RegistryConfig>>;
|
|
741
|
+
/**
|
|
742
|
+
* Top-level resource profiles. Activating one filters the resolved resource
|
|
743
|
+
* set across commands, skills, hooks, rules, MCP, permissions, and secrets.
|
|
744
|
+
* Model-provider run profiles are separate YAML files under profiles/.
|
|
745
|
+
*/
|
|
746
|
+
profiles?: ResourceProfilesConfig;
|
|
685
747
|
versions?: Partial<Record<AgentId, Record<string, VersionResources>>>;
|
|
686
748
|
source?: string;
|
|
687
749
|
/**
|
|
@@ -696,6 +758,12 @@ export interface Meta {
|
|
|
696
758
|
* via the `path` field.
|
|
697
759
|
*/
|
|
698
760
|
extraRepos?: Record<string, ExtraRepoConfig>;
|
|
761
|
+
/**
|
|
762
|
+
* White-label brands keyed by name. Each mints a personally-named binary
|
|
763
|
+
* (e.g. `jack`) that runs agents-cli under that name with its own disabled
|
|
764
|
+
* commands + curated resource profile. See lib/brand.ts.
|
|
765
|
+
*/
|
|
766
|
+
brands?: Record<string, BrandConfig>;
|
|
699
767
|
/**
|
|
700
768
|
* Keys like `skill.hermes` — registries seeded from SEEDED_REGISTRIES exactly
|
|
701
769
|
* once. Tracked so a user `registry remove` won't silently re-seed.
|
|
@@ -746,6 +814,22 @@ export interface Meta {
|
|
|
746
814
|
workerName?: string;
|
|
747
815
|
bucketName?: string;
|
|
748
816
|
domain?: string;
|
|
817
|
+
/** Cloudflare Web Analytics token injected into published HTML pages. */
|
|
818
|
+
analyticsToken?: string;
|
|
819
|
+
};
|
|
820
|
+
/**
|
|
821
|
+
* Owner/channel notification config for `agents send` / `agents notify`.
|
|
822
|
+
* `owner` is the default recipient for `agents notify` (channel + target).
|
|
823
|
+
* `transports` maps a user-facing channel name to the provider that actually
|
|
824
|
+
* delivers it — explicit, one provider per channel, no fallback. Omitted keys
|
|
825
|
+
* default to name-identity (channel `slack` -> provider `slack`).
|
|
826
|
+
*/
|
|
827
|
+
notify?: {
|
|
828
|
+
owner?: {
|
|
829
|
+
channel: string;
|
|
830
|
+
to: string;
|
|
831
|
+
};
|
|
832
|
+
transports?: Record<string, string>;
|
|
749
833
|
};
|
|
750
834
|
}
|
|
751
835
|
/** Persisted agent-host entry in agents.yaml (overlay or inline). */
|
package/dist/lib/uninstall.js
CHANGED
|
@@ -20,6 +20,7 @@ import * as os from 'os';
|
|
|
20
20
|
import * as path from 'path';
|
|
21
21
|
import { AGENTS, ALL_AGENT_IDS } from './agents.js';
|
|
22
22
|
import { getAgentConfigPath, getConfigSymlinkVersion, stripShimPathLines, releaseAdoptedLauncher, } from './shims.js';
|
|
23
|
+
import { moveDirCrossDevice, copyDirStrippingAgentsSymlinks } from './config-transfer.js';
|
|
23
24
|
import { getUserAgentsDir, getBackupsDir, getHistoryDir, getShimsDir, getLegacySystemAgentsDir, } from './state.js';
|
|
24
25
|
/** Home dir honoring the AGENTS_REAL_HOME test/override, mirroring shims.ts. */
|
|
25
26
|
function realHome() {
|
|
@@ -60,51 +61,6 @@ function symlinkTarget(p) {
|
|
|
60
61
|
function removeLink(p) {
|
|
61
62
|
fs.unlinkSync(p);
|
|
62
63
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Move `source` onto `dest` across possibly-different volumes. `renameSync` is
|
|
65
|
-
* atomic but throws EXDEV when `~/.agents` lives on a different filesystem than
|
|
66
|
-
* `$HOME`; fall back to copy-then-remove so the restore still completes. The
|
|
67
|
-
* source (a backup inside `~/.agents`) is removed only after the copy succeeds,
|
|
68
|
-
* so a mid-copy failure never destroys the sole surviving copy.
|
|
69
|
-
*/
|
|
70
|
-
function moveDirCrossDevice(source, dest) {
|
|
71
|
-
try {
|
|
72
|
-
fs.renameSync(source, dest);
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
if (err.code !== 'EXDEV')
|
|
76
|
-
throw err;
|
|
77
|
-
fs.cpSync(source, dest, { recursive: true });
|
|
78
|
-
fs.rmSync(source, { recursive: true, force: true });
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Copy `source` to `dest`, dropping any symlink whose target resolves back into
|
|
83
|
-
* `~/.agents`. Adoption syncs managed resources (skills/commands) into the
|
|
84
|
-
* version home as symlinks into `~/.agents`; copying them verbatim would leave
|
|
85
|
-
* the restored config full of links that dangle the moment `~/.agents` is
|
|
86
|
-
* disposed. Stripping them yields a clean, self-contained restore.
|
|
87
|
-
*/
|
|
88
|
-
function copyDirStrippingAgentsSymlinks(source, dest, agentsDir) {
|
|
89
|
-
const inside = agentsDir + path.sep;
|
|
90
|
-
fs.cpSync(source, dest, {
|
|
91
|
-
recursive: true,
|
|
92
|
-
filter: (src) => {
|
|
93
|
-
try {
|
|
94
|
-
const st = fs.lstatSync(src);
|
|
95
|
-
if (st.isSymbolicLink()) {
|
|
96
|
-
const tgt = path.resolve(path.dirname(src), fs.readlinkSync(src));
|
|
97
|
-
if (tgt === agentsDir || tgt.startsWith(inside))
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
/* unreadable entry — let cpSync surface it on the real copy */
|
|
103
|
-
}
|
|
104
|
-
return true;
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
64
|
/** Classify one agent's config dir without mutating anything. */
|
|
109
65
|
function planConfig(agent) {
|
|
110
66
|
const realPath = getAgentConfigPath(agent);
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,8 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Well-known locations of the `agents` launcher for PATH-less GUI/launchd
|
|
3
|
+
* processes (the menu-bar helper inherits no login PATH). Also the anchor for
|
|
4
|
+
* recovering the on-disk install layout when the CLI runs as a Bun single-file
|
|
5
|
+
* binary — see {@link resolveInstalledLayout}.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveAgentsBin(): string | null;
|
|
8
|
+
export interface InstallLayout {
|
|
9
|
+
/** The install's `dist/` directory (holds `index.js` + `lib/`). */
|
|
10
|
+
distDir: string;
|
|
11
|
+
/** The compiled CLI entry, `dist/index.js`. */
|
|
12
|
+
entryPath: string;
|
|
13
|
+
/** The shipping `package.json`, `dist/../package.json`. */
|
|
14
|
+
pkgJsonPath: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Pure derivation (no I/O) of an install's on-disk layout from the realpath of
|
|
18
|
+
* its `agents` launcher. A launcher lives at `<pkg>/dist/bin/agents`, so two
|
|
19
|
+
* levels up is `<pkg>/dist`. Exported for unit testing so the dirname chain the
|
|
20
|
+
* Bun-binary fallback depends on stays locked.
|
|
21
|
+
*/
|
|
22
|
+
export declare function installLayoutFromBin(realBin: string): InstallLayout;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the on-disk install layout of the running CLI by following the
|
|
25
|
+
* `agents` launcher symlink.
|
|
26
|
+
*
|
|
27
|
+
* When the CLI runs as a Bun single-file executable, `import.meta.url` points
|
|
28
|
+
* inside the virtual bundle (`/$bunfs/…`), so sibling-relative resolution can't
|
|
29
|
+
* see the shipped `package.json`, `dist/index.js`, or `MenubarHelper.app` on
|
|
30
|
+
* disk. The launcher symlink points at the real files; walk up from it. Returns
|
|
31
|
+
* null when no launcher is found (dev/tsx runs, or a box without the helper) —
|
|
32
|
+
* callers keep their in-bundle resolution as the primary path and use this only
|
|
33
|
+
* as the fallback.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveInstalledLayout(): InstallLayout | null;
|
|
1
36
|
/**
|
|
2
37
|
* Resolve the CLI version from the shipping package.json. Used by the daemon
|
|
3
38
|
* to answer `IPCAction: 'version'` and by the client to detect daemon drift —
|
|
4
39
|
* a dev-build CLI talking to a launchd-managed registry daemon would silently
|
|
5
40
|
* get stale behavior without this check.
|
|
41
|
+
*
|
|
42
|
+
* Primary read is relative to this module; when that fails (the Bun single-file
|
|
43
|
+
* binary can't read its own bundled package.json), fall back to the on-disk
|
|
44
|
+
* install found via the launcher symlink so callers like the menu bar don't see
|
|
45
|
+
* a bogus `unknown`.
|
|
6
46
|
*/
|
|
7
47
|
export declare function getCliVersion(): string;
|
|
8
48
|
/**
|