@phnx-labs/agents-cli 1.22.24 → 1.22.26
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 +350 -1
- package/README.md +31 -6
- package/dist/bin/agents +0 -0
- package/dist/browser.js +14 -4
- package/dist/commands/apply.js +52 -8
- package/dist/commands/browser.js +35 -0
- package/dist/commands/cloud.js +9 -5
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +108 -9
- package/dist/commands/exec.js +19 -16
- package/dist/commands/feed.d.ts +5 -0
- package/dist/commands/feed.js +21 -1
- package/dist/commands/focus.js +2 -2
- package/dist/commands/insights.d.ts +25 -19
- package/dist/commands/insights.js +107 -33
- package/dist/commands/menubar.js +8 -0
- package/dist/commands/reconnect.d.ts +46 -0
- package/dist/commands/reconnect.js +109 -0
- package/dist/commands/routines.d.ts +3 -0
- package/dist/commands/routines.js +72 -49
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets.d.ts +2 -8
- package/dist/commands/secrets.js +29 -105
- package/dist/commands/sessions-browser.d.ts +1 -1
- package/dist/commands/sessions-browser.js +27 -7
- package/dist/commands/sessions-resume.js +3 -2
- package/dist/commands/sessions.d.ts +13 -1
- package/dist/commands/sessions.js +28 -2
- package/dist/commands/setup-secrets.d.ts +1 -0
- package/dist/commands/setup-secrets.js +1 -1
- package/dist/commands/setup-watchdog.js +5 -10
- package/dist/commands/setup.d.ts +26 -3
- package/dist/commands/setup.js +106 -47
- package/dist/commands/teams.d.ts +6 -0
- package/dist/commands/teams.js +46 -2
- package/dist/commands/trends.d.ts +8 -0
- package/dist/commands/trends.js +10 -156
- package/dist/commands/watchdog.d.ts +3 -4
- package/dist/commands/watchdog.js +26 -66
- package/dist/index.js +37 -2
- package/dist/lib/agents.d.ts +11 -0
- package/dist/lib/agents.js +155 -23
- package/dist/lib/analytics/dashboard.d.ts +10 -6
- package/dist/lib/analytics/dashboard.js +6 -4
- package/dist/lib/analytics/mix-commands.d.ts +53 -0
- package/dist/lib/analytics/mix-commands.js +229 -0
- package/dist/lib/analytics/recipes.d.ts +19 -14
- package/dist/lib/analytics/recipes.js +4 -2
- package/dist/lib/browser/ipc.d.ts +26 -0
- package/dist/lib/browser/ipc.js +139 -24
- package/dist/lib/browser/profiles.d.ts +11 -0
- package/dist/lib/browser/profiles.js +1 -1
- package/dist/lib/browser/stream.d.ts +14 -0
- package/dist/lib/browser/stream.js +71 -0
- package/dist/lib/channels/owner-sink.d.ts +27 -0
- package/dist/lib/channels/owner-sink.js +93 -0
- package/dist/lib/cloud/cursor.d.ts +79 -0
- package/dist/lib/cloud/cursor.js +228 -0
- package/dist/lib/cloud/registry.js +2 -0
- package/dist/lib/cloud/types.d.ts +7 -2
- package/dist/lib/cloud/types.js +14 -0
- package/dist/lib/crabbox/cli.d.ts +2 -2
- package/dist/lib/crabbox/config.d.ts +7 -8
- package/dist/lib/crabbox/config.js +14 -14
- package/dist/lib/crabbox/lease.d.ts +11 -4
- package/dist/lib/crabbox/lease.js +40 -8
- package/dist/lib/crabbox/setup-copy.d.ts +5 -0
- package/dist/lib/crabbox/setup-copy.js +17 -1
- package/dist/lib/daemon.js +27 -1
- package/dist/lib/device-config.js +7 -0
- package/dist/lib/devices/doctor-findings.d.ts +13 -1
- package/dist/lib/devices/doctor-findings.js +73 -2
- package/dist/lib/events.d.ts +9 -0
- package/dist/lib/events.js +58 -0
- package/dist/lib/exec.d.ts +3 -3
- package/dist/lib/exec.js +24 -10
- package/dist/lib/feed-outcome.d.ts +3 -0
- package/dist/lib/feed-outcome.js +18 -10
- package/dist/lib/feed.d.ts +4 -0
- package/dist/lib/fleet/apply.d.ts +59 -3
- package/dist/lib/fleet/apply.js +183 -6
- package/dist/lib/fleet/types.d.ts +21 -2
- package/dist/lib/hooks/cache.js +15 -0
- package/dist/lib/hosts/passthrough.d.ts +44 -0
- package/dist/lib/hosts/passthrough.js +84 -12
- package/dist/lib/hosts/ready.d.ts +2 -0
- package/dist/lib/hosts/ready.js +10 -1
- package/dist/lib/hosts/reconnect.d.ts +14 -12
- package/dist/lib/hosts/reconnect.js +41 -40
- package/dist/lib/mcp.js +5 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/snapshot.d.ts +15 -0
- package/dist/lib/menubar/snapshot.js +40 -0
- package/dist/lib/plugins.js +13 -1
- package/dist/lib/resources/mcp.js +3 -0
- package/dist/lib/routine-process-cleanup.d.ts +9 -0
- package/dist/lib/routine-process-cleanup.js +73 -0
- package/dist/lib/routines.js +14 -2
- package/dist/lib/runner.d.ts +0 -3
- package/dist/lib/runner.js +6 -19
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/bundles.js +1 -20
- package/dist/lib/secrets/filestore.d.ts +2 -0
- package/dist/lib/secrets/filestore.js +13 -0
- package/dist/lib/secrets/push.d.ts +94 -0
- package/dist/lib/secrets/push.js +145 -0
- package/dist/lib/secrets/rc-hygiene.d.ts +14 -0
- package/dist/lib/secrets/rc-hygiene.js +14 -1
- package/dist/lib/secrets/reaper.d.ts +15 -1
- package/dist/lib/secrets/reaper.js +30 -3
- package/dist/lib/session/active.d.ts +4 -0
- package/dist/lib/session/db.d.ts +21 -3
- package/dist/lib/session/db.js +229 -15
- package/dist/lib/session/discover.d.ts +1 -0
- package/dist/lib/session/discover.js +115 -19
- package/dist/lib/session/insights.d.ts +18 -0
- package/dist/lib/session/insights.js +143 -1
- package/dist/lib/session/remote-list.d.ts +2 -0
- package/dist/lib/session/remote-list.js +1 -0
- package/dist/lib/session/session-cache.d.ts +4 -4
- package/dist/lib/session/session-cache.js +4 -4
- package/dist/lib/session/tool-index.js +133 -22
- package/dist/lib/session/tool-store.d.ts +26 -2
- package/dist/lib/session/tool-store.js +36 -17
- package/dist/lib/shims.js +21 -1
- package/dist/lib/signin-badge.js +2 -0
- package/dist/lib/ssh-exec.js +8 -2
- package/dist/lib/startup/command-registry.d.ts +16 -0
- package/dist/lib/startup/command-registry.js +46 -0
- package/dist/lib/teams/agents.d.ts +13 -0
- package/dist/lib/teams/agents.js +76 -8
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/teams/placement-probe.d.ts +21 -0
- package/dist/lib/teams/placement-probe.js +135 -0
- package/dist/lib/teams/scheduler.d.ts +74 -1
- package/dist/lib/teams/scheduler.js +187 -10
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/versions.js +16 -1
- package/dist/lib/watchdog/service.d.ts +17 -0
- package/dist/lib/watchdog/service.js +39 -0
- package/package.json +1 -1
|
@@ -10,27 +10,21 @@
|
|
|
10
10
|
* agents watchdog --nudge one tick, actually injects (explicit opt-in)
|
|
11
11
|
* agents watchdog --watch manual poll loop (dry unless --nudge)
|
|
12
12
|
* agents watchdog --json machine-readable tick output (for the menu-bar)
|
|
13
|
-
* agents watchdog on|off turn the
|
|
13
|
+
* agents watchdog on|off turn the device-local daemon pass on/off
|
|
14
14
|
* agents watchdog policy <id> <p> per-session policy: off | keep | handsoff
|
|
15
15
|
*
|
|
16
|
-
* The
|
|
17
|
-
*
|
|
18
|
-
* repo; on/off only changes this device's routine membership.
|
|
16
|
+
* The agents daemon is the sole automatic watchdog scheduler. The menu bar reads
|
|
17
|
+
* persisted state; it never runs a tick.
|
|
19
18
|
*/
|
|
20
19
|
import chalk from 'chalk';
|
|
21
20
|
import * as path from 'path';
|
|
22
21
|
import { setHelpSections } from '../lib/help.js';
|
|
23
22
|
import { parseDuration } from '../lib/hooks/cache.js';
|
|
24
23
|
import { getRuntimeStateDir } from '../lib/state.js';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { loadLocalActiveSessions } from '../lib/session/session-cache.js';
|
|
28
|
-
import { mailboxIdForActiveSession } from '../lib/mailbox-target.js';
|
|
29
|
-
import { gcMailbox } from '../lib/mailbox-gc.js';
|
|
30
|
-
import { devicesWithRoutineEnabled, routineEnabledOnThisDevice } from '../lib/routine-activation.js';
|
|
31
|
-
import { runWatchdogTick, writePolicySentinel, DEFAULT_THRESHOLDS, } from '../lib/watchdog/runner.js';
|
|
24
|
+
import { getConfigValue, setConfigValue } from '../lib/device-config.js';
|
|
25
|
+
import { writePolicySentinel, DEFAULT_THRESHOLDS, } from '../lib/watchdog/runner.js';
|
|
32
26
|
import { isWatchdogRotateEnabled, listRotateStates, setWatchdogRotateEnabled } from '../lib/watchdog/rotate.js';
|
|
33
|
-
|
|
27
|
+
import { loadWatchdogSessions, runWatchdogPass } from '../lib/watchdog/service.js';
|
|
34
28
|
/** Default state dir the runner and these subcommands share. */
|
|
35
29
|
function stateDir() {
|
|
36
30
|
return path.join(getRuntimeStateDir(), 'watchdog');
|
|
@@ -63,21 +57,6 @@ function humanMs(ms) {
|
|
|
63
57
|
return `${Math.round(ms / 60_000)}m`;
|
|
64
58
|
return `${Math.round(ms / 1000)}s`;
|
|
65
59
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Run the mailbox liveness sweep against the same session set the tick just used.
|
|
68
|
-
* Idempotent and cheap: archiving a message twice is a no-op, and GC only scans
|
|
69
|
-
* directories. Failures are swallowed so a mailbox-root problem cannot break the
|
|
70
|
-
* watchdog tick.
|
|
71
|
-
*/
|
|
72
|
-
async function runMailboxGc(sessions) {
|
|
73
|
-
const activeBoxIds = new Set(sessions.map(mailboxIdForActiveSession).filter((id) => !!id));
|
|
74
|
-
try {
|
|
75
|
-
gcMailbox(activeBoxIds);
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
// GC is best-effort housekeeping; the next tick will retry.
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
60
|
function colorForOutcome(o) {
|
|
82
61
|
if (o.injected)
|
|
83
62
|
return chalk.green;
|
|
@@ -139,45 +118,35 @@ export function registerWatchdogCommand(program) {
|
|
|
139
118
|
};
|
|
140
119
|
// Injection gate: --nudge is the explicit opt-in to actually inject. Bare
|
|
141
120
|
// `agents watchdog` (and `--watch` without `--nudge`) is dry. The always-on
|
|
142
|
-
// path is the daemon
|
|
143
|
-
//
|
|
121
|
+
// path is the daemon-owned pass. Device config is its on/off switch; this
|
|
122
|
+
// explicit command still requires --nudge before it can inject.
|
|
144
123
|
const computeWillInject = () => opts.nudge === true;
|
|
145
|
-
const tickOnce = async (willInject, sessions) =>
|
|
124
|
+
const tickOnce = async (willInject, sessions) => runWatchdogPass({
|
|
146
125
|
nudge: willInject,
|
|
147
126
|
nudgeText: opts.text,
|
|
148
127
|
smart: opts.smart === true,
|
|
149
128
|
smartAgent: opts.smartAgent,
|
|
150
129
|
thresholds,
|
|
151
130
|
allowGhosttyFocus: opts.allowGhosttyFocus === true,
|
|
152
|
-
stateDir: stateDir(),
|
|
153
131
|
sessions,
|
|
154
132
|
});
|
|
155
133
|
// RUSH-2062: share the daemon-warmed local active-session snapshot with
|
|
156
134
|
// menubar/CLI/Factory instead of re-running a full gather every tick.
|
|
157
|
-
const loadWatchdogSessions = async () => {
|
|
158
|
-
const loaded = await loadLocalActiveSessions({
|
|
159
|
-
// Force a live gather only when the warm path is unavailable; the
|
|
160
|
-
// cache layer already re-gathers past DEFAULT_ACTIVE_CACHE_MAX_AGE_MS.
|
|
161
|
-
gather: () => getActiveSessions({ localOnly: true }),
|
|
162
|
-
});
|
|
163
|
-
return loaded.sessions;
|
|
164
|
-
};
|
|
165
135
|
if (!opts.watch) {
|
|
166
136
|
const willInject = computeWillInject();
|
|
167
137
|
const sessions = await loadWatchdogSessions();
|
|
168
138
|
const result = await tickOnce(willInject, sessions);
|
|
169
|
-
await runMailboxGc(sessions);
|
|
170
139
|
if (opts.json)
|
|
171
140
|
console.log(JSON.stringify(result, null, 2));
|
|
172
141
|
else
|
|
173
142
|
printTick(result, willInject);
|
|
174
143
|
return;
|
|
175
144
|
}
|
|
176
|
-
// Manual poll loop
|
|
145
|
+
// Manual poll loop for ad-hoc use; the daemon owns the automatic cadence.
|
|
177
146
|
const intervalMs = durationMsOr(opts.interval, 30_000);
|
|
178
147
|
if (!computeWillInject() && !opts.json) {
|
|
179
148
|
console.log(chalk.yellow(`watchdog --watch is DETECT-ONLY. Pass --nudge to inject, ` +
|
|
180
|
-
`or run 'agents watchdog on' for the
|
|
149
|
+
`or run 'agents watchdog on' for the daemon-owned pass.`));
|
|
181
150
|
}
|
|
182
151
|
// eslint-disable-next-line no-constant-condition
|
|
183
152
|
while (true) {
|
|
@@ -185,7 +154,6 @@ export function registerWatchdogCommand(program) {
|
|
|
185
154
|
const willInject = computeWillInject();
|
|
186
155
|
const sessions = await loadWatchdogSessions();
|
|
187
156
|
const result = await tickOnce(willInject, sessions);
|
|
188
|
-
await runMailboxGc(sessions);
|
|
189
157
|
if (opts.json)
|
|
190
158
|
console.log(JSON.stringify(result));
|
|
191
159
|
else
|
|
@@ -207,10 +175,10 @@ export function registerWatchdogCommand(program) {
|
|
|
207
175
|
# Machine-readable for the menu-bar
|
|
208
176
|
agents watchdog --json
|
|
209
177
|
|
|
210
|
-
# Turn on the
|
|
178
|
+
# Turn on the daemon-owned watchdog pass (every three minutes)
|
|
211
179
|
agents watchdog on
|
|
212
180
|
|
|
213
|
-
# Show
|
|
181
|
+
# Show device enablement, rotate config, and in-flight rotates
|
|
214
182
|
agents watchdog status
|
|
215
183
|
|
|
216
184
|
# Leave one session detected-but-untouched
|
|
@@ -253,37 +221,32 @@ export function registerWatchdogCommand(program) {
|
|
|
253
221
|
'watchdog.rotate: off' to ~/.agents/agents.yaml; nudging stays on).
|
|
254
222
|
State machine: ~/.agents/.cache/state/watchdog/rotate/<sessionId>.json.
|
|
255
223
|
|
|
256
|
-
Always-on: 'agents watchdog on' enables
|
|
257
|
-
on this device and reloads the daemon; 'off' disables it here.
|
|
258
|
-
|
|
259
|
-
|
|
224
|
+
Always-on: 'agents watchdog on' enables one daemon-owned pass every three
|
|
225
|
+
minutes on this device and reloads the daemon; 'off' disables it here.
|
|
226
|
+
Defaults OFF. Per-session policy: off (ignore), keep (default), handsoff
|
|
227
|
+
(detect + flag).
|
|
260
228
|
|
|
261
229
|
State (tray-readable): ${path.join('~/.agents/.cache/state/watchdog', '{nudges,flags,last-tick}.json')}
|
|
262
230
|
`,
|
|
263
231
|
});
|
|
264
232
|
// --- always-on enable/disable/status (backed by the daemon routine) --------
|
|
265
233
|
const turnOn = async () => {
|
|
266
|
-
|
|
267
|
-
if (!routine)
|
|
268
|
-
throw new Error("Built-in routine 'watchdog' is missing. Run: agents repo pull system");
|
|
269
|
-
setJobEnabled(WATCHDOG_ROUTINE_NAME, true);
|
|
234
|
+
setConfigValue('watchdog.enabled', true);
|
|
270
235
|
await reloadDaemonForRoutine(true);
|
|
271
|
-
console.log(chalk.green(
|
|
236
|
+
console.log(chalk.green('watchdog: ON on this device (every 3 minutes)'));
|
|
272
237
|
};
|
|
273
238
|
const turnOff = async () => {
|
|
274
|
-
|
|
275
|
-
throw new Error("Built-in routine 'watchdog' is missing. Run: agents repo pull system");
|
|
276
|
-
setJobEnabled(WATCHDOG_ROUTINE_NAME, false);
|
|
239
|
+
setConfigValue('watchdog.enabled', false);
|
|
277
240
|
await reloadDaemonForRoutine(false);
|
|
278
241
|
console.log(chalk.yellow('watchdog: OFF on this device'));
|
|
279
242
|
};
|
|
280
243
|
cmd.command('on')
|
|
281
|
-
.description('Enable the
|
|
244
|
+
.description('Enable the daemon watchdog pass on this device.')
|
|
282
245
|
.action(async () => {
|
|
283
246
|
await turnOn();
|
|
284
247
|
});
|
|
285
248
|
cmd.command('off')
|
|
286
|
-
.description('Disable the
|
|
249
|
+
.description('Disable the daemon watchdog pass on this device.')
|
|
287
250
|
.action(async () => {
|
|
288
251
|
await turnOff();
|
|
289
252
|
});
|
|
@@ -304,7 +267,7 @@ export function registerWatchdogCommand(program) {
|
|
|
304
267
|
chalk.dim(`(watchdog.rotate: ${s} in agents.yaml)`));
|
|
305
268
|
});
|
|
306
269
|
cmd.command('status')
|
|
307
|
-
.description('Show whether the
|
|
270
|
+
.description('Show whether the daemon watchdog pass is enabled and where state is written.')
|
|
308
271
|
.option('--json', 'Emit status as JSON (for the menu-bar / scripts)')
|
|
309
272
|
.action((_opts, command) => {
|
|
310
273
|
// The parent `watchdog` command also declares --json and greedily parses it
|
|
@@ -312,16 +275,14 @@ export function registerWatchdogCommand(program) {
|
|
|
312
275
|
// parent, not this subcommand. optsWithGlobals() merges both levels, so we
|
|
313
276
|
// read it correctly regardless of which command commander bound it to.
|
|
314
277
|
const json = command.optsWithGlobals().json === true;
|
|
315
|
-
const on =
|
|
316
|
-
const enabledDevices = devicesWithRoutineEnabled(WATCHDOG_ROUTINE_NAME);
|
|
278
|
+
const on = getConfigValue('watchdog.enabled').value === true;
|
|
317
279
|
const rotate = isWatchdogRotateEnabled() ? 'on' : 'off';
|
|
318
280
|
const rotates = listRotateStates(stateDir());
|
|
319
281
|
const inflight = rotates.filter((r) => r.phase !== 'done' && r.phase !== 'failed');
|
|
320
282
|
if (json) {
|
|
321
283
|
console.log(JSON.stringify({
|
|
322
284
|
enabled: on,
|
|
323
|
-
|
|
324
|
-
routine: WATCHDOG_ROUTINE_NAME,
|
|
285
|
+
cadenceMs: 180_000,
|
|
325
286
|
stateDir: stateDir(),
|
|
326
287
|
rotate,
|
|
327
288
|
rotates: rotates.map((r) => ({
|
|
@@ -335,8 +296,7 @@ export function registerWatchdogCommand(program) {
|
|
|
335
296
|
}));
|
|
336
297
|
return;
|
|
337
298
|
}
|
|
338
|
-
console.log(`always-on watchdog: ${on ? chalk.green('ON') : chalk.dim('off')} (
|
|
339
|
-
console.log(`enabled devices: ${enabledDevices.length > 0 ? enabledDevices.join(', ') : chalk.dim('none')}`);
|
|
299
|
+
console.log(`always-on watchdog: ${on ? chalk.green('ON') : chalk.dim('off')} (every 3 minutes on this device)`);
|
|
340
300
|
console.log(`rotate: ${rotate === 'on' ? chalk.green('on') : chalk.yellow('off')} (watchdog.rotate in agents.yaml) · ${inflight.length} in-flight`);
|
|
341
301
|
for (const r of inflight) {
|
|
342
302
|
console.log(` ${chalk.magenta(r.phase.padEnd(12))} ${chalk.bold(r.sessionId.slice(0, 8))} → ${r.newSessionId.slice(0, 8)}${r.error ? chalk.red(` ${r.error}`) : ''}`);
|
package/dist/index.js
CHANGED
|
@@ -327,7 +327,7 @@ Credentials and profiles:
|
|
|
327
327
|
Diagnostics:
|
|
328
328
|
doctor [agent[@version]] Diagnose CLI availability, sync status, and resource divergence; --check for the CI drift gate
|
|
329
329
|
usage [agent] Show rate-limit and quota usage per agent
|
|
330
|
-
insights How
|
|
330
|
+
insights How work looks — behaviour (default) or counter mix (insights mix)
|
|
331
331
|
perf Latency rollups (hooks, commands, runs) from the disposable perf warehouse
|
|
332
332
|
|
|
333
333
|
Config sync:
|
|
@@ -1035,7 +1035,23 @@ program.on('command:*', (operands) => {
|
|
|
1035
1035
|
if (minDist === 1 && closest) {
|
|
1036
1036
|
const args = process.argv.slice(2);
|
|
1037
1037
|
args[0] = closest;
|
|
1038
|
-
|
|
1038
|
+
// The typo'd name was unknown, so the top-level --host router (which ran
|
|
1039
|
+
// before commander parsing, against the ORIGINAL name) could not have
|
|
1040
|
+
// routed it - it correctly fell through to reach this handler at all
|
|
1041
|
+
// (that fallthrough is this ticket's own fix). But falling through to a
|
|
1042
|
+
// plain local re-parse means a routing flag on a corrected REAL
|
|
1043
|
+
// host-routable command (e.g. `docto --host box`, corrected to `doctor`)
|
|
1044
|
+
// silently ran LOCALLY instead of remotely, with no error - worse than
|
|
1045
|
+
// the loud "does not support --host" this ticket replaced. Re-run the
|
|
1046
|
+
// router with the CORRECTED name before falling through to local parse;
|
|
1047
|
+
// it already no-ops when no routing flag is present. RUSH-2022 review r2.
|
|
1048
|
+
void (async () => {
|
|
1049
|
+
const { maybeRunOnHost } = await import('./lib/hosts/passthrough.js');
|
|
1050
|
+
if (await maybeRunOnHost(closest, args)) {
|
|
1051
|
+
process.exit(process.exitCode ?? 0);
|
|
1052
|
+
}
|
|
1053
|
+
program.parse(['node', 'agents', ...args]);
|
|
1054
|
+
})();
|
|
1039
1055
|
return;
|
|
1040
1056
|
}
|
|
1041
1057
|
console.error(`error: unknown command '${unknown}'`);
|
|
@@ -1074,6 +1090,9 @@ if (requestedCommand !== undefined && !helpOrVersionRequested && !requestedIsDis
|
|
|
1074
1090
|
// Register only the command(s) this invocation actually uses. Lazy commands
|
|
1075
1091
|
// (sessions/teams/cloud) are handled after applyGlobalHelpConventions below.
|
|
1076
1092
|
const isLazyRequest = requestedCommand !== undefined && LAZY_COMMAND_NAMES.has(requestedCommand);
|
|
1093
|
+
// Set when the requested name maps to no command: the lazy tree is then also
|
|
1094
|
+
// registered below so the spellcheck can suggest `sessions`/`teams`/`cloud`.
|
|
1095
|
+
let requestedIsUnknown = false;
|
|
1077
1096
|
if (requestedIsDisabled) {
|
|
1078
1097
|
// The brand turned this command off: register the full tree so the "did you
|
|
1079
1098
|
// mean" picker still works, then strip the disabled commands below so the
|
|
@@ -1087,6 +1106,7 @@ else if (requestedCommand !== undefined && !isLazyRequest) {
|
|
|
1087
1106
|
// spellcheck and edit-distance-1 auto-correct (the command:* handler above)
|
|
1088
1107
|
// see the same candidate set — and ordering — as main.
|
|
1089
1108
|
await registerAllEagerCommands();
|
|
1109
|
+
requestedIsUnknown = true;
|
|
1090
1110
|
}
|
|
1091
1111
|
}
|
|
1092
1112
|
// When requestedCommand is undefined (bare invocation, --version, --help, -h) no
|
|
@@ -1102,6 +1122,21 @@ if (isLazyRequest && !requestedIsDisabled) {
|
|
|
1102
1122
|
for (const loader of COMMAND_LOADERS[requestedCommand])
|
|
1103
1123
|
await reg(loader);
|
|
1104
1124
|
}
|
|
1125
|
+
else if (requestedIsUnknown) {
|
|
1126
|
+
// Unknown command: the lazy names must be candidates too, or `agents session`
|
|
1127
|
+
// (a typo for the very much lazy `sessions`) gets no "did you mean" at all —
|
|
1128
|
+
// the miss the RUSH-2022 report walked into. Registration order still mirrors
|
|
1129
|
+
// main: lazy commands come after applyGlobalHelpConventions.
|
|
1130
|
+
const seen = new Set();
|
|
1131
|
+
for (const name of LAZY_COMMAND_NAMES) {
|
|
1132
|
+
for (const loader of COMMAND_LOADERS[name] ?? []) {
|
|
1133
|
+
if (seen.has(loader))
|
|
1134
|
+
continue;
|
|
1135
|
+
seen.add(loader);
|
|
1136
|
+
await reg(loader);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1105
1140
|
// White-label: remove any commands this brand disabled so they resolve as
|
|
1106
1141
|
// unknown (the command:* handler then reports "unknown command"). Unbranded or
|
|
1107
1142
|
// nothing-disabled → no-op. Done after all registration paths above.
|
package/dist/lib/agents.d.ts
CHANGED
|
@@ -34,6 +34,17 @@ export declare function findInPath(command: string): string | null;
|
|
|
34
34
|
export declare const AGENTS: Record<AgentId, AgentConfig>;
|
|
35
35
|
/** All current and legacy agent IDs derived from the AGENTS registry. */
|
|
36
36
|
export declare const ALL_AGENT_IDS: AgentId[];
|
|
37
|
+
/**
|
|
38
|
+
* CLI command templates per agent for daemon-fired routine jobs, with
|
|
39
|
+
* {prompt} as a placeholder. Lives here (not runner.ts) so routines.ts can
|
|
40
|
+
* import ROUTINE_AGENT_IDS for schedule-time validation without a circular
|
|
41
|
+
* import (runner.ts already imports from routines.ts).
|
|
42
|
+
*/
|
|
43
|
+
export declare const ROUTINE_AGENT_COMMANDS: Record<string, string[]>;
|
|
44
|
+
/** Agents the routine daemon can actually run when firing locally, derived
|
|
45
|
+
* from the command table above so the `--agent` help and validateJob's
|
|
46
|
+
* schedule-time check can never drift from it. */
|
|
47
|
+
export declare const ROUTINE_AGENT_IDS: readonly string[];
|
|
37
48
|
/** Agents retained only for legacy reads, not install/import/sync targets. */
|
|
38
49
|
export declare const HARD_DEPRECATED_AGENT_IDS: AgentId[];
|
|
39
50
|
/** Agents that can receive managed installs, imports, and resource sync writes. */
|
package/dist/lib/agents.js
CHANGED
|
@@ -279,6 +279,7 @@ export const AGENTS = {
|
|
|
279
279
|
color: 'cyan',
|
|
280
280
|
cliCommand: 'cursor-agent',
|
|
281
281
|
npmPackage: '',
|
|
282
|
+
cloudProvider: 'cursor',
|
|
282
283
|
installScript: 'curl https://cursor.com/install -fsS | bash && mv ~/.local/bin/agent ~/.local/bin/cursor-agent && grep -q "/.local/bin" ~/.zshrc || echo \'export PATH="$HOME/.local/bin:$PATH"\' >> ~/.zshrc',
|
|
283
284
|
configDir: path.join(HOME, '.cursor'),
|
|
284
285
|
commandsDir: path.join(HOME, '.cursor', 'commands'),
|
|
@@ -306,7 +307,7 @@ export const AGENTS = {
|
|
|
306
307
|
// See transformSubagentForCursor / https://cursor.com/docs/subagents.
|
|
307
308
|
// interactiveRepl: false — cursor-agent exits immediately with no argv. It requires a
|
|
308
309
|
// prompt to do anything useful; a bare invocation is not a REPL (RUSH-2185, EXEC-23a).
|
|
309
|
-
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '2026.1.22' }, rules: { file: '.cursorrules' }, workflows: false, memory: false, modes: ['edit', 'skip'], interactiveRepl: false }, // allowlist: ~/.cursor/cli-config.json
|
|
310
|
+
capabilities: { hooks: true, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: true, plugins: true, subagents: { since: '2026.1.22' }, rules: { file: '.cursorrules' }, workflows: false, memory: false, modes: ['plan', 'edit', 'skip'], interactiveRepl: false }, // allowlist: ~/.cursor/cli-config.json
|
|
310
311
|
},
|
|
311
312
|
opencode: {
|
|
312
313
|
id: 'opencode',
|
|
@@ -383,14 +384,22 @@ export const AGENTS = {
|
|
|
383
384
|
instructionsFile: 'workspace/AGENTS.md', // Primary memory file (also has SOUL.md, IDENTITY.md, etc.)
|
|
384
385
|
format: 'markdown',
|
|
385
386
|
variableSyntax: '{{ARGUMENTS}}',
|
|
386
|
-
|
|
387
|
+
// hooks: NOT supported. OpenClaw only exposes a fixed set of internal,
|
|
388
|
+
// named hooks (e.g. `boot-md`, which runs BOOT.md on gateway restart) —
|
|
389
|
+
// there is no general event->shell-command registration surface (no
|
|
390
|
+
// PreToolUse/PostToolUse/UserPromptSubmit equivalent an agents-cli
|
|
391
|
+
// hooks.yaml manifest could target). registerHooksToSettings has no
|
|
392
|
+
// `openclaw` case and silently no-ops (RUSH-2122: capability claimed
|
|
393
|
+
// hooks:true with zero hooks ever installed). Flip back to `true` only
|
|
394
|
+
// alongside a real registerHooksForOpenClaw implementation.
|
|
395
|
+
supportsHooks: false,
|
|
387
396
|
// allowlist: maps blanket (whole-tool) rules to ~/.openclaw/openclaw.json
|
|
388
397
|
// tools.alsoAllow (allow) / tools.deny (deny). OpenClaw gates at tool
|
|
389
398
|
// granularity only, so sub-command/path/domain patterns are skipped.
|
|
390
399
|
// OpenClaw is self-updating (no pinned since), so `true` is correct.
|
|
391
400
|
// Workflows sync as Lobster `.lobster` files under `.openclaw/workflows/`;
|
|
392
401
|
// the Lobster tool runs them by receiving the file path as `pipeline`.
|
|
393
|
-
capabilities: { hooks:
|
|
402
|
+
capabilities: { hooks: false, mcp: true, mcpHttp: false, mcpHeaders: false, allowlist: true, skills: true, commands: false, plugins: true, subagents: true, rules: { file: 'workspace/AGENTS.md' }, workflows: true, memory: true, modes: ['plan', 'edit', 'skip'], interactiveRepl: true },
|
|
394
403
|
},
|
|
395
404
|
copilot: {
|
|
396
405
|
id: 'copilot',
|
|
@@ -811,9 +820,97 @@ export const AGENTS = {
|
|
|
811
820
|
interactiveRepl: true,
|
|
812
821
|
},
|
|
813
822
|
},
|
|
823
|
+
// Warp Agent CLI (`oz`) — the standalone coding-agent CLI on Warp's "Oz"
|
|
824
|
+
// platform (the same shared Warp binary invoked via the `oz` symlink). Native
|
|
825
|
+
// binary via `brew install --cask oz` (macOS) / `oz-stable` apt|yum|pacman
|
|
826
|
+
// package (Linux); self-updating, no npm package. Config lives under `~/.warp/`
|
|
827
|
+
// (`.mcp.json`, `skills/`, `tab_configs/`, `worktrees/`, `remote-server`).
|
|
828
|
+
// Headless: `oz agent run --prompt "<task>" [--model <id>]` (local) /
|
|
829
|
+
// `oz agent run-cloud` (cloud). Auth: `oz login` (browser OAuth) or a
|
|
830
|
+
// `WARP_API_KEY` env token for headless/CI (`oz api-key create`). Rules/context
|
|
831
|
+
// file is `AGENTS.md` (also reads WARP.md / CLAUDE.md). Autonomy is governed by
|
|
832
|
+
// the selected agent profile (`--profile`), not a per-run permission flag.
|
|
833
|
+
// Sessions/conversations are stored SERVER-SIDE (retrieved with auth via
|
|
834
|
+
// `oz run conversation get <id>`), so there is no local transcript for
|
|
835
|
+
// `agents sessions` to index — warp is intentionally absent from SESSION_AGENTS.
|
|
836
|
+
// Docs: https://docs.warp.dev/reference/cli
|
|
837
|
+
warp: {
|
|
838
|
+
id: 'warp',
|
|
839
|
+
name: 'Warp',
|
|
840
|
+
color: 'blueBright',
|
|
841
|
+
cliCommand: 'oz',
|
|
842
|
+
npmPackage: '',
|
|
843
|
+
installScript: 'brew install --cask oz',
|
|
844
|
+
configDir: path.join(HOME, '.warp'),
|
|
845
|
+
commandsDir: '',
|
|
846
|
+
commandsSubdir: '',
|
|
847
|
+
skillsDir: path.join(HOME, '.warp', 'skills'),
|
|
848
|
+
hooksDir: 'hooks',
|
|
849
|
+
instructionsFile: 'AGENTS.md',
|
|
850
|
+
format: 'markdown',
|
|
851
|
+
variableSyntax: '$ARGUMENTS',
|
|
852
|
+
// Oz has no event->shell-command hook registration surface (its documented
|
|
853
|
+
// capabilities are agent-profiles-permissions, codebase-context,
|
|
854
|
+
// full-terminal-use, mcp, planning, rules, slash-commands — no hooks).
|
|
855
|
+
supportsHooks: false,
|
|
856
|
+
capabilities: {
|
|
857
|
+
hooks: false,
|
|
858
|
+
// MCP: Oz reads the Claude `{ "mcpServers": {...} }` schema from
|
|
859
|
+
// `.warp/.mcp.json` (user `~/.warp/.mcp.json`, project `<root>/.warp/.mcp.json`)
|
|
860
|
+
// and accepts `--mcp <path|json>` at run time; `oz mcp list` reads them
|
|
861
|
+
// back. stdio + http with headers, same schema as Claude's .mcp.json.
|
|
862
|
+
mcp: true,
|
|
863
|
+
mcpHttp: true,
|
|
864
|
+
mcpHeaders: true,
|
|
865
|
+
// Autonomy is governed by the selected agent profile
|
|
866
|
+
// (agent-profiles-permissions), not a Claude-style tool-name allow/deny
|
|
867
|
+
// list agents-cli can write — so no allowlist writer (mirrors muse).
|
|
868
|
+
allowlist: false,
|
|
869
|
+
// Skills: `--skill <spec>` + `oz agent skills`; searched in
|
|
870
|
+
// `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, `.codex/skills/`.
|
|
871
|
+
skills: true,
|
|
872
|
+
// Slash-commands are native/server-managed (no droppable markdown
|
|
873
|
+
// command-file directory for agents-cli to sync into).
|
|
874
|
+
commands: false,
|
|
875
|
+
// No Claude marketplace / plugin manifest support.
|
|
876
|
+
plugins: false,
|
|
877
|
+
// Cloud agents + agent profiles are server-side; no installable
|
|
878
|
+
// subagent-definition directory to sync into (keeps the table truthful).
|
|
879
|
+
subagents: false,
|
|
880
|
+
rules: { file: 'AGENTS.md' },
|
|
881
|
+
workflows: false,
|
|
882
|
+
memory: false,
|
|
883
|
+
// Oz has no per-run permission flag; a single autonomous mode maps to no
|
|
884
|
+
// flags (the `--profile` selection governs autonomy). Mirrors hermes.
|
|
885
|
+
modes: ['edit'],
|
|
886
|
+
rulesImports: false,
|
|
887
|
+
// `oz agent run` requires a prompt (--prompt/--saved-prompt/--task-id/
|
|
888
|
+
// --skill), so a bare invocation opens no REPL.
|
|
889
|
+
interactiveRepl: false,
|
|
890
|
+
},
|
|
891
|
+
},
|
|
814
892
|
};
|
|
815
893
|
/** All current and legacy agent IDs derived from the AGENTS registry. */
|
|
816
894
|
export const ALL_AGENT_IDS = Object.keys(AGENTS);
|
|
895
|
+
/**
|
|
896
|
+
* CLI command templates per agent for daemon-fired routine jobs, with
|
|
897
|
+
* {prompt} as a placeholder. Lives here (not runner.ts) so routines.ts can
|
|
898
|
+
* import ROUTINE_AGENT_IDS for schedule-time validation without a circular
|
|
899
|
+
* import (runner.ts already imports from routines.ts).
|
|
900
|
+
*/
|
|
901
|
+
export const ROUTINE_AGENT_COMMANDS = {
|
|
902
|
+
claude: ['claude', '-p', '--verbose', '{prompt}', '--output-format', 'stream-json', '--permission-mode', 'plan'],
|
|
903
|
+
codex: ['codex', 'exec', '{prompt}', '--json'],
|
|
904
|
+
gemini: ['gemini', '{prompt}', '--output-format', 'stream-json'],
|
|
905
|
+
cursor: ['cursor-agent', '-p', '{prompt}', '--output-format', 'stream-json'],
|
|
906
|
+
kimi: ['kimi', '--prompt', '{prompt}', '--output-format', 'stream-json'],
|
|
907
|
+
droid: ['droid', 'exec', '{prompt}', '-o', 'stream-json'],
|
|
908
|
+
muse: ['muse', 'exec', '{prompt}', '--json'],
|
|
909
|
+
};
|
|
910
|
+
/** Agents the routine daemon can actually run when firing locally, derived
|
|
911
|
+
* from the command table above so the `--agent` help and validateJob's
|
|
912
|
+
* schedule-time check can never drift from it. */
|
|
913
|
+
export const ROUTINE_AGENT_IDS = Object.freeze(Object.keys(ROUTINE_AGENT_COMMANDS));
|
|
817
914
|
/** Agents retained only for legacy reads, not install/import/sync targets. */
|
|
818
915
|
export const HARD_DEPRECATED_AGENT_IDS = ALL_AGENT_IDS.filter((id) => AGENTS[id].deprecated?.hard);
|
|
819
916
|
/** Agents that can receive managed installs, imports, and resource sync writes. */
|
|
@@ -1507,11 +1604,16 @@ function isValidOpenCodeCredential(value) {
|
|
|
1507
1604
|
}
|
|
1508
1605
|
/**
|
|
1509
1606
|
* Whether a Muse Code `~/.config/muse/auth.json` document holds any usable
|
|
1510
|
-
* access token.
|
|
1511
|
-
*
|
|
1512
|
-
*
|
|
1607
|
+
* access token. Live shape from `muse login` (device OAuth, Muse Code 0.1.0):
|
|
1608
|
+
* { schema_version: 1, providers: { meta: { access_token, api_key, user_email, … } } }
|
|
1609
|
+
* Also accept top-level or one-level-nested tokens for older/alternate writers.
|
|
1610
|
+
* Recurses into objects so `providers.meta.access_token` is found — a flat
|
|
1611
|
+
* one-level walk only saw `providers` and reported signed-out after a successful
|
|
1612
|
+
* login (balanced then excluded the account). Never returns the secret itself.
|
|
1513
1613
|
*/
|
|
1514
|
-
function museAuthHasToken(value) {
|
|
1614
|
+
function museAuthHasToken(value, depth = 0) {
|
|
1615
|
+
if (depth > 4)
|
|
1616
|
+
return false;
|
|
1515
1617
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
1516
1618
|
return false;
|
|
1517
1619
|
const root = value;
|
|
@@ -1520,16 +1622,31 @@ function museAuthHasToken(value) {
|
|
|
1520
1622
|
if (typeof root.api_key === 'string' && root.api_key.length > 0)
|
|
1521
1623
|
return true;
|
|
1522
1624
|
for (const slot of Object.values(root)) {
|
|
1523
|
-
if (
|
|
1524
|
-
continue;
|
|
1525
|
-
const entry = slot;
|
|
1526
|
-
if (typeof entry.access_token === 'string' && entry.access_token.length > 0)
|
|
1527
|
-
return true;
|
|
1528
|
-
if (typeof entry.api_key === 'string' && entry.api_key.length > 0)
|
|
1625
|
+
if (museAuthHasToken(slot, depth + 1))
|
|
1529
1626
|
return true;
|
|
1530
1627
|
}
|
|
1531
1628
|
return false;
|
|
1532
1629
|
}
|
|
1630
|
+
/** Best-effort email from a Muse auth.json (providers.meta.user_email, etc.). */
|
|
1631
|
+
function museAuthEmail(value, depth = 0) {
|
|
1632
|
+
if (depth > 4)
|
|
1633
|
+
return null;
|
|
1634
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
1635
|
+
return null;
|
|
1636
|
+
const root = value;
|
|
1637
|
+
if (typeof root.user_email === 'string' && root.user_email.includes('@')) {
|
|
1638
|
+
return root.user_email;
|
|
1639
|
+
}
|
|
1640
|
+
if (typeof root.email === 'string' && root.email.includes('@')) {
|
|
1641
|
+
return root.email;
|
|
1642
|
+
}
|
|
1643
|
+
for (const slot of Object.values(root)) {
|
|
1644
|
+
const found = museAuthEmail(slot, depth + 1);
|
|
1645
|
+
if (found)
|
|
1646
|
+
return found;
|
|
1647
|
+
}
|
|
1648
|
+
return null;
|
|
1649
|
+
}
|
|
1533
1650
|
/**
|
|
1534
1651
|
* Whether a Claude version home's credential file is present but carries no
|
|
1535
1652
|
* token — the "must have a real credential" floor (see
|
|
@@ -1924,10 +2041,8 @@ export async function getAccountInfo(agentId, home) {
|
|
|
1924
2041
|
}
|
|
1925
2042
|
case 'muse': {
|
|
1926
2043
|
// Muse Code authenticates with META_API_KEY (env, highest priority) or
|
|
1927
|
-
// a stored OAuth/API credential at ~/.config/muse/auth.json.
|
|
1928
|
-
//
|
|
1929
|
-
// access_token; there is no email claim, so we report signed-in + a
|
|
1930
|
-
// stable identity key (env-key vs provider slots) like kimi/opencode.
|
|
2044
|
+
// a stored OAuth/API credential at ~/.config/muse/auth.json. Live file
|
|
2045
|
+
// shape nests under providers.meta (access_token + optional user_email).
|
|
1931
2046
|
if (process.env.META_API_KEY?.trim() || process.env.MODEL_API_KEY?.trim()) {
|
|
1932
2047
|
const accountKey = buildIdentityKey(agentId, [['auth', 'env']]);
|
|
1933
2048
|
return { ...empty, signedIn: true, accountId: 'env', accountKey, lastActive };
|
|
@@ -1938,13 +2053,18 @@ export async function getAccountInfo(agentId, home) {
|
|
|
1938
2053
|
const data = JSON.parse(await fs.promises.readFile(authPath, 'utf-8'));
|
|
1939
2054
|
if (!data || typeof data !== 'object')
|
|
1940
2055
|
return { ...empty, lastActive };
|
|
1941
|
-
|
|
1942
|
-
// Any object with a nested access_token (or a top-level one) counts.
|
|
1943
|
-
const hasToken = museAuthHasToken(data);
|
|
1944
|
-
if (!hasToken)
|
|
2056
|
+
if (!museAuthHasToken(data))
|
|
1945
2057
|
return { ...empty, lastActive };
|
|
1946
|
-
const
|
|
1947
|
-
|
|
2058
|
+
const email = museAuthEmail(data);
|
|
2059
|
+
const accountKey = buildIdentityKey(agentId, email ? [['email', email]] : [['auth', 'file']]);
|
|
2060
|
+
return {
|
|
2061
|
+
...empty,
|
|
2062
|
+
signedIn: true,
|
|
2063
|
+
email,
|
|
2064
|
+
accountId: email ?? 'file',
|
|
2065
|
+
accountKey,
|
|
2066
|
+
lastActive,
|
|
2067
|
+
};
|
|
1948
2068
|
}
|
|
1949
2069
|
default:
|
|
1950
2070
|
return { ...empty, lastActive };
|
|
@@ -2563,6 +2683,9 @@ export function getUserMcpConfigPath(agentId) {
|
|
|
2563
2683
|
case 'muse':
|
|
2564
2684
|
// Muse Code: MCP lives in ~/.config/muse/settings.json under mcp_servers.
|
|
2565
2685
|
return path.join(agent.configDir, 'settings.json');
|
|
2686
|
+
case 'warp':
|
|
2687
|
+
// Oz reads user-scope MCP from ~/.warp/.mcp.json (Claude schema).
|
|
2688
|
+
return path.join(agent.configDir, '.mcp.json');
|
|
2566
2689
|
default:
|
|
2567
2690
|
// Gemini and others use settings.json
|
|
2568
2691
|
return path.join(agent.configDir, 'settings.json');
|
|
@@ -2603,6 +2726,8 @@ export function getMcpConfigPathForHome(agentId, home) {
|
|
|
2603
2726
|
return path.join(home, '.omp', 'agent', '.mcp.json');
|
|
2604
2727
|
case 'muse':
|
|
2605
2728
|
return path.join(home, '.config', 'muse', 'settings.json');
|
|
2729
|
+
case 'warp':
|
|
2730
|
+
return path.join(home, '.warp', '.mcp.json');
|
|
2606
2731
|
default:
|
|
2607
2732
|
return path.join(home, agentConfigDirName(agentId), 'settings.json');
|
|
2608
2733
|
}
|
|
@@ -2649,6 +2774,9 @@ export function getProjectMcpConfigPath(agentId, cwd = process.cwd()) {
|
|
|
2649
2774
|
// Muse project MCP rides the same settings schema under .muse/settings.json
|
|
2650
2775
|
// when present; otherwise fall back to the user settings path.
|
|
2651
2776
|
return path.join(cwd, '.muse', 'settings.json');
|
|
2777
|
+
case 'warp':
|
|
2778
|
+
// Oz reads project MCP from <root>/.warp/.mcp.json (Claude schema).
|
|
2779
|
+
return path.join(cwd, '.warp', '.mcp.json');
|
|
2652
2780
|
default:
|
|
2653
2781
|
return path.join(cwd, `.${agentId}`, 'settings.json');
|
|
2654
2782
|
}
|
|
@@ -2796,6 +2924,10 @@ export const AGENT_NAME_ALIASES = {
|
|
|
2796
2924
|
'muse-code': 'muse',
|
|
2797
2925
|
'muse-spark': 'muse',
|
|
2798
2926
|
'meta-muse': 'muse',
|
|
2927
|
+
warp: 'warp',
|
|
2928
|
+
oz: 'warp',
|
|
2929
|
+
'warp-agent': 'warp',
|
|
2930
|
+
'warp-cli': 'warp',
|
|
2799
2931
|
};
|
|
2800
2932
|
/**
|
|
2801
2933
|
* Resolve a user-provided agent name (alias, shorthand, or canonical) to its AgentId.
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { RECIPE_IDS, runRecipe,
|
|
2
|
-
export interface
|
|
3
|
-
window:
|
|
1
|
+
import { RECIPE_IDS, runRecipe, analyticsWindow, type RecipeId, type RecipeSection, type AnalyticsWindow } from './recipes.js';
|
|
2
|
+
export interface MixDashboard {
|
|
3
|
+
window: AnalyticsWindow;
|
|
4
4
|
durationMs: number;
|
|
5
5
|
sections: RecipeSection[];
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
/** @deprecated Use MixDashboard. */
|
|
8
|
+
export type TrendsDashboard = MixDashboard;
|
|
9
|
+
export declare function buildMixDashboard(opts?: {
|
|
8
10
|
days?: number;
|
|
9
11
|
ids?: RecipeId[];
|
|
10
|
-
}):
|
|
11
|
-
|
|
12
|
+
}): MixDashboard;
|
|
13
|
+
/** @deprecated Use buildMixDashboard. */
|
|
14
|
+
export declare const buildTrendsDashboard: typeof buildMixDashboard;
|
|
15
|
+
export { analyticsWindow, analyticsWindow as trendsWindow, runRecipe, RECIPE_IDS, type RecipeId, type RecipeSection, type AnalyticsWindow, };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RECIPE_IDS, runRecipe,
|
|
1
|
+
import { RECIPE_IDS, runRecipe, analyticsWindow, } from './recipes.js';
|
|
2
2
|
const DEFAULT_ORDER = [
|
|
3
3
|
'harness-mix',
|
|
4
4
|
'model-mix',
|
|
@@ -9,9 +9,9 @@ const DEFAULT_ORDER = [
|
|
|
9
9
|
'browser-activity',
|
|
10
10
|
'resource-mix',
|
|
11
11
|
];
|
|
12
|
-
export function
|
|
12
|
+
export function buildMixDashboard(opts = {}) {
|
|
13
13
|
const t0 = Date.now();
|
|
14
|
-
const win =
|
|
14
|
+
const win = analyticsWindow(opts.days ?? 7);
|
|
15
15
|
const ids = opts.ids ?? DEFAULT_ORDER;
|
|
16
16
|
const sections = [];
|
|
17
17
|
for (const id of ids) {
|
|
@@ -28,4 +28,6 @@ export function buildTrendsDashboard(opts = {}) {
|
|
|
28
28
|
sections,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
/** @deprecated Use buildMixDashboard. */
|
|
32
|
+
export const buildTrendsDashboard = buildMixDashboard;
|
|
33
|
+
export { analyticsWindow, analyticsWindow as trendsWindow, runRecipe, RECIPE_IDS, };
|