@phnx-labs/agents-cli 1.22.23 → 1.22.25
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 +359 -0
- package/README.md +19 -8
- package/dist/bin/agents +0 -0
- package/dist/commands/attach.d.ts +2 -0
- package/dist/commands/attach.js +32 -7
- package/dist/commands/cloud.js +9 -5
- package/dist/commands/defaults.js +2 -0
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +105 -9
- package/dist/commands/exec.js +99 -44
- package/dist/commands/feed.d.ts +23 -0
- package/dist/commands/feed.js +65 -2
- package/dist/commands/focus.d.ts +34 -3
- package/dist/commands/focus.js +301 -57
- package/dist/commands/go.d.ts +14 -1
- package/dist/commands/go.js +49 -5
- package/dist/commands/insights.js +6 -2
- package/dist/commands/inspect.js +39 -5
- package/dist/commands/menubar.js +14 -1
- package/dist/commands/models.js +1 -0
- package/dist/commands/modes.d.ts +12 -0
- package/dist/commands/modes.js +147 -0
- package/dist/commands/routines.d.ts +3 -0
- package/dist/commands/routines.js +70 -47
- package/dist/commands/run-cloud.js +1 -1
- package/dist/commands/secrets-sync.js +11 -13
- package/dist/commands/secrets.d.ts +2 -0
- package/dist/commands/secrets.js +54 -17
- package/dist/commands/sessions-browser.d.ts +36 -1
- package/dist/commands/sessions-browser.js +165 -19
- package/dist/commands/sessions-resume.d.ts +2 -0
- package/dist/commands/sessions-resume.js +28 -12
- package/dist/commands/sessions.d.ts +23 -1
- package/dist/commands/sessions.js +58 -61
- package/dist/commands/setup-secrets.js +1 -1
- package/dist/commands/setup-watchdog.js +5 -10
- package/dist/commands/setup.js +1 -1
- package/dist/commands/sync.js +246 -42
- package/dist/commands/teams.js +3 -2
- package/dist/commands/view.js +2 -0
- package/dist/commands/watchdog.d.ts +3 -4
- package/dist/commands/watchdog.js +26 -66
- package/dist/index.js +38 -2
- package/dist/lib/agent-modes.d.ts +49 -0
- package/dist/lib/agent-modes.js +70 -0
- package/dist/lib/agents.js +126 -21
- 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 +7 -1
- package/dist/lib/devices/doctor-findings.js +40 -1
- package/dist/lib/doctor-diff.d.ts +3 -0
- package/dist/lib/doctor-diff.js +15 -13
- package/dist/lib/event-stream.d.ts +3 -1
- package/dist/lib/event-stream.js +14 -1
- package/dist/lib/events.d.ts +9 -0
- package/dist/lib/events.js +58 -0
- package/dist/lib/exec.d.ts +15 -3
- package/dist/lib/exec.js +112 -19
- 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/hooks/cache.js +36 -3
- package/dist/lib/hooks.d.ts +19 -7
- package/dist/lib/hooks.js +88 -38
- package/dist/lib/hosts/passthrough.d.ts +21 -0
- package/dist/lib/hosts/passthrough.js +39 -12
- package/dist/lib/hosts/session-index.d.ts +4 -0
- package/dist/lib/hosts/session-index.js +7 -0
- package/dist/lib/manifest.d.ts +12 -2
- package/dist/lib/manifest.js +60 -5
- package/dist/lib/mcp.js +5 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +5 -1
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/Resources/AppIcon.icns +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/_CodeSignature/CodeResources +15 -2
- package/dist/lib/menubar/install-menubar.d.ts +52 -2
- package/dist/lib/menubar/install-menubar.js +128 -6
- 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/refresh.d.ts +5 -0
- package/dist/lib/refresh.js +37 -33
- package/dist/lib/resource-inventory.d.ts +79 -0
- package/dist/lib/resource-inventory.js +122 -0
- package/dist/lib/resources/mcp.js +3 -0
- package/dist/lib/resources.js +8 -5
- package/dist/lib/routine-process-cleanup.d.ts +9 -0
- package/dist/lib/routine-process-cleanup.js +73 -0
- package/dist/lib/run-defaults.d.ts +2 -0
- package/dist/lib/run-defaults.js +23 -2
- package/dist/lib/runner.js +27 -22
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +2 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/Resources/AppIcon.icns +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +13 -1
- package/dist/lib/secrets/bundles.js +158 -85
- package/dist/lib/secrets/filestore.d.ts +7 -3
- package/dist/lib/secrets/filestore.js +25 -8
- package/dist/lib/secrets/index.js +34 -8
- 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 +10 -0
- package/dist/lib/secrets/reaper.js +50 -15
- package/dist/lib/secrets/sync-passphrase.d.ts +27 -0
- package/dist/lib/secrets/sync-passphrase.js +78 -0
- package/dist/lib/session/active.d.ts +4 -0
- package/dist/lib/session/db.js +8 -2
- package/dist/lib/session/recovery.d.ts +37 -0
- package/dist/lib/session/recovery.js +95 -0
- 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/shims.d.ts +2 -2
- package/dist/lib/shims.js +45 -6
- package/dist/lib/signin-badge.js +2 -0
- package/dist/lib/startup/command-registry.d.ts +16 -0
- package/dist/lib/startup/command-registry.js +44 -0
- package/dist/lib/sync-umbrella.d.ts +5 -0
- package/dist/lib/sync-umbrella.js +5 -4
- package/dist/lib/teams/agents.js +1 -1
- package/dist/lib/teams/parsers.d.ts +1 -1
- package/dist/lib/tmux/session.d.ts +4 -2
- package/dist/lib/tmux/session.js +5 -5
- package/dist/lib/types.d.ts +3 -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
|
@@ -29,6 +29,7 @@ export const loadFork = async () => (await import('../../commands/fork.js')).reg
|
|
|
29
29
|
export const loadDefaults = async () => (await import('../../commands/defaults.js')).registerDefaultsCommands;
|
|
30
30
|
export const loadSet = async () => (await import('../../commands/set.js')).registerSetCommand;
|
|
31
31
|
export const loadModels = async () => (await import('../../commands/models.js')).registerModelsCommand;
|
|
32
|
+
export const loadModes = async () => (await import('../../commands/modes.js')).registerModesCommand;
|
|
32
33
|
export const loadPrune = async () => (await import('../../commands/prune.js')).registerPruneCommand;
|
|
33
34
|
export const loadTrash = async () => (await import('../../commands/trash.js')).registerTrashCommands;
|
|
34
35
|
export const loadRestore = async () => (await import('../../commands/trash.js')).registerRestoreCommand;
|
|
@@ -145,6 +146,11 @@ export const COMMAND_LOADERS = {
|
|
|
145
146
|
registry: [loadPackages],
|
|
146
147
|
search: [loadPackages],
|
|
147
148
|
install: [loadPackages],
|
|
149
|
+
// packages.ts also registers `publish` at top level (commands/packages.ts:435).
|
|
150
|
+
// It was missing here, so `agents publish` only worked via the unknown-command
|
|
151
|
+
// fallback that registers the whole tree — and the --host router could not see
|
|
152
|
+
// it as a real command at all (RUSH-2022).
|
|
153
|
+
publish: [loadPackages],
|
|
148
154
|
routines: [loadRoutines],
|
|
149
155
|
monitors: [loadMonitors],
|
|
150
156
|
projects: [loadProjects],
|
|
@@ -154,6 +160,7 @@ export const COMMAND_LOADERS = {
|
|
|
154
160
|
defaults: [loadDefaults],
|
|
155
161
|
set: [loadSet],
|
|
156
162
|
models: [loadModels],
|
|
163
|
+
modes: [loadModes],
|
|
157
164
|
trash: [loadTrash],
|
|
158
165
|
restore: [loadRestore],
|
|
159
166
|
doctor: [loadDoctor],
|
|
@@ -229,3 +236,40 @@ export const COMMAND_LOADERS = {
|
|
|
229
236
|
funnel: [loadFunnel],
|
|
230
237
|
humans: [loadHumans],
|
|
231
238
|
};
|
|
239
|
+
/**
|
|
240
|
+
* Top-level names that {@link COMMAND_LOADERS} does not carry because they are
|
|
241
|
+
* registered inline in src/index.ts — closures over entry-point state (the
|
|
242
|
+
* deprecated aliases and tombstones) plus the internal/upgrade commands. They are
|
|
243
|
+
* real commands, so anything that asks "does this command exist?" must count them.
|
|
244
|
+
*/
|
|
245
|
+
const INLINE_COMMAND_NAMES = [
|
|
246
|
+
'perms', // deprecated alias -> permissions
|
|
247
|
+
'exec', // deprecated alias -> run
|
|
248
|
+
'jobs', // deprecated alias -> routines
|
|
249
|
+
'cron', // deprecated alias -> routines
|
|
250
|
+
'check', // tombstone -> doctor --check
|
|
251
|
+
'resources', // tombstone -> view --merged
|
|
252
|
+
'hq', // tombstone
|
|
253
|
+
'_internal',
|
|
254
|
+
'upgrade',
|
|
255
|
+
];
|
|
256
|
+
/**
|
|
257
|
+
* Every top-level command name the CLI answers to — the loader table plus the
|
|
258
|
+
* inline aliases/tombstones above. This is the "does this command exist?"
|
|
259
|
+
* predicate for code that runs BEFORE commander parses, most importantly the
|
|
260
|
+
* `--host`/`--device` router (lib/hosts/passthrough.ts): without it a typo'd
|
|
261
|
+
* command carrying `--host` reported a flag-support error instead of
|
|
262
|
+
* `unknown command` (RUSH-2022).
|
|
263
|
+
*
|
|
264
|
+
* Commander sub-aliases (`sessions ls`, `teams rm`, …) are deliberately absent —
|
|
265
|
+
* this set is top-level only. `command-registry.test.ts` pins it against the real
|
|
266
|
+
* registered command tree so a new command can never drift out of it.
|
|
267
|
+
*/
|
|
268
|
+
export const KNOWN_TOP_LEVEL_COMMANDS = new Set([
|
|
269
|
+
...Object.keys(COMMAND_LOADERS),
|
|
270
|
+
...INLINE_COMMAND_NAMES,
|
|
271
|
+
]);
|
|
272
|
+
/** Whether `name` is a top-level command this CLI registers. See {@link KNOWN_TOP_LEVEL_COMMANDS}. */
|
|
273
|
+
export function isKnownTopLevelCommand(name) {
|
|
274
|
+
return KNOWN_TOP_LEVEL_COMMANDS.has(name);
|
|
275
|
+
}
|
|
@@ -68,6 +68,11 @@ export interface RunUmbrellaArgs {
|
|
|
68
68
|
yes: boolean;
|
|
69
69
|
/** Secrets passphrase, if available (env var or prompt). Undefined => skip secrets. */
|
|
70
70
|
passphrase?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Suppress human progress from the reconcile stage (`refresh`). Required so
|
|
73
|
+
* `agents sync --json` / fleet fan-out leave stdout as a single JSON object.
|
|
74
|
+
*/
|
|
75
|
+
quiet?: boolean;
|
|
71
76
|
}
|
|
72
77
|
/**
|
|
73
78
|
* Execute the planned stages in order: repos -> secrets -> reconcile.
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { pullRepo } from './git.js';
|
|
19
19
|
import { getUserAgentsDir, getEnabledExtraRepos } from './state.js';
|
|
20
20
|
import { listRemoteBundles, pullBundle } from './secrets/sync.js';
|
|
21
|
+
import { SYNC_PASSPHRASE_ENV } from './secrets/sync-passphrase.js';
|
|
21
22
|
/**
|
|
22
23
|
* Decide which stages run. Pure — no I/O. Semantics:
|
|
23
24
|
* bare (no flags) fetch repos, then reconcile
|
|
@@ -52,7 +53,7 @@ export function planUmbrellaStages(f) {
|
|
|
52
53
|
* reconcile — `agents sync` should make as much current as it can in one pass.
|
|
53
54
|
*/
|
|
54
55
|
export async function runUmbrellaSync(args) {
|
|
55
|
-
const { flags, log, yes, passphrase } = args;
|
|
56
|
+
const { flags, log, yes, passphrase, quiet = false } = args;
|
|
56
57
|
const plan = planUmbrellaStages(flags);
|
|
57
58
|
const result = { plan, reconciled: false };
|
|
58
59
|
if (plan.fetchRepos) {
|
|
@@ -79,10 +80,10 @@ export async function runUmbrellaSync(args) {
|
|
|
79
80
|
result.secrets = {
|
|
80
81
|
pulled: 0,
|
|
81
82
|
skipped: true,
|
|
82
|
-
reason:
|
|
83
|
+
reason: `no passphrase — set ${SYNC_PASSPHRASE_ENV} or run \`agents login\` (#366)`,
|
|
83
84
|
errors: [],
|
|
84
85
|
};
|
|
85
|
-
log(
|
|
86
|
+
log(`secrets: skipped (no passphrase — set ${SYNC_PASSPHRASE_ENV})`);
|
|
86
87
|
}
|
|
87
88
|
else {
|
|
88
89
|
let pulled = 0;
|
|
@@ -108,7 +109,7 @@ export async function runUmbrellaSync(args) {
|
|
|
108
109
|
}
|
|
109
110
|
if (plan.reconcile) {
|
|
110
111
|
const { refresh } = await import('./refresh.js');
|
|
111
|
-
await refresh({ skipPrompts: yes });
|
|
112
|
+
await refresh({ skipPrompts: yes, quiet });
|
|
112
113
|
result.reconciled = true;
|
|
113
114
|
// Keep already-registered devices' reachability current, and surface newly
|
|
114
115
|
// appeared tailnet nodes as "pending" for the menu-bar Register/Ignore gate
|
package/dist/lib/teams/agents.js
CHANGED
|
@@ -197,7 +197,7 @@ export function buildTeammateSpawnEnv(envOverrides) {
|
|
|
197
197
|
*/
|
|
198
198
|
export { captureProcessStartTime };
|
|
199
199
|
/** Agent types the team runner supports. */
|
|
200
|
-
const TEAM_AGENT_TYPES = ['codex', 'cursor', 'claude', 'opencode', 'grok', 'antigravity', 'kimi', 'droid'];
|
|
200
|
+
const TEAM_AGENT_TYPES = ['codex', 'cursor', 'claude', 'opencode', 'grok', 'antigravity', 'kimi', 'droid', 'warp'];
|
|
201
201
|
// Suffix appended to all prompts to ensure agents provide a summary
|
|
202
202
|
const PROMPT_SUFFIX = `
|
|
203
203
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Supported agent CLI types for team spawning. */
|
|
2
|
-
export type AgentType = 'codex' | 'gemini' | 'cursor' | 'claude' | 'opencode' | 'grok' | 'antigravity' | 'kimi' | 'droid';
|
|
2
|
+
export type AgentType = 'codex' | 'gemini' | 'cursor' | 'claude' | 'opencode' | 'grok' | 'antigravity' | 'kimi' | 'droid' | 'warp';
|
|
3
3
|
/** Normalize a raw JSON event from any agent type into an array of unified event objects. */
|
|
4
4
|
export declare function normalizeEvents(agentType: AgentType, raw: any): any[];
|
|
5
5
|
/** Normalize a raw JSON event, returning only the first unified event (convenience wrapper). */
|
|
@@ -114,6 +114,8 @@ export interface TmuxClient {
|
|
|
114
114
|
export declare function listClients(socket?: string): Promise<TmuxClient[]>;
|
|
115
115
|
/** A dead pane's exit status, read from tmux while the pane lingers under remain-on-exit. */
|
|
116
116
|
export interface PaneExit {
|
|
117
|
+
/** False when the pane/socket no longer exists or tmux could not query it. */
|
|
118
|
+
found: boolean;
|
|
117
119
|
/** True once the process that ran in the pane has exited (pane is dead). */
|
|
118
120
|
dead: boolean;
|
|
119
121
|
/** Exit status of the dead pane's process, when tmux reports it. */
|
|
@@ -122,8 +124,8 @@ export interface PaneExit {
|
|
|
122
124
|
/**
|
|
123
125
|
* Read whether a pane's process has exited and, if so, its exit status. Used by
|
|
124
126
|
* the spawn-wrap path to recover the wrapped agent's exit code after the attach
|
|
125
|
-
* client returns.
|
|
126
|
-
*
|
|
127
|
+
* client returns. `found: false` distinguishes a missing pane from a living one;
|
|
128
|
+
* focus must recover the former instead of attaching a retained/stale target.
|
|
127
129
|
*/
|
|
128
130
|
export declare function paneExitStatus(pane: string, socket?: string): Promise<PaneExit>;
|
|
129
131
|
/**
|
package/dist/lib/tmux/session.js
CHANGED
|
@@ -248,8 +248,8 @@ export async function listClients(socket) {
|
|
|
248
248
|
/**
|
|
249
249
|
* Read whether a pane's process has exited and, if so, its exit status. Used by
|
|
250
250
|
* the spawn-wrap path to recover the wrapped agent's exit code after the attach
|
|
251
|
-
* client returns.
|
|
252
|
-
*
|
|
251
|
+
* client returns. `found: false` distinguishes a missing pane from a living one;
|
|
252
|
+
* focus must recover the former instead of attaching a retained/stale target.
|
|
253
253
|
*/
|
|
254
254
|
export async function paneExitStatus(pane, socket) {
|
|
255
255
|
let res;
|
|
@@ -261,13 +261,13 @@ export async function paneExitStatus(pane, socket) {
|
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
catch {
|
|
264
|
-
return { dead: false };
|
|
264
|
+
return { found: false, dead: false };
|
|
265
265
|
}
|
|
266
266
|
if (res.code !== 0)
|
|
267
|
-
return { dead: false };
|
|
267
|
+
return { found: false, dead: false };
|
|
268
268
|
const [deadRaw, statusRaw] = res.stdout.trim().split(/\s+/);
|
|
269
269
|
const status = statusRaw !== undefined && statusRaw !== '' ? parseInt(statusRaw, 10) : undefined;
|
|
270
|
-
return { dead: deadRaw === '1', status: Number.isFinite(status) ? status : undefined };
|
|
270
|
+
return { found: true, dead: deadRaw === '1', status: Number.isFinite(status) ? status : undefined };
|
|
271
271
|
}
|
|
272
272
|
/**
|
|
273
273
|
* Bind a per-session hook. Used by the spawn-wrap path to install a `pane-died`
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
import type { CloudProviderId } from './cloud/types.js';
|
|
9
9
|
import type { FeedBroadcastConfig } from './feed-broadcast.js';
|
|
10
10
|
/** Unique identifier for a current or legacy AI coding agent. */
|
|
11
|
-
export type AgentId = 'claude' | 'codex' | 'gemini' | 'cursor' | 'opencode' | 'openclaw' | 'copilot' | 'amp' | 'kiro' | 'goose' | 'antigravity' | 'grok' | 'kimi' | 'droid' | 'hermes' | 'pi' | 'muse';
|
|
11
|
+
export type AgentId = 'claude' | 'codex' | 'gemini' | 'cursor' | 'opencode' | 'openclaw' | 'copilot' | 'amp' | 'kiro' | 'goose' | 'antigravity' | 'grok' | 'kimi' | 'droid' | 'hermes' | 'pi' | 'muse' | 'warp';
|
|
12
12
|
/** How `agents run <agent>` chooses an installed version when none is pinned. */
|
|
13
13
|
export type RunStrategy = 'pinned' | 'available' | 'balanced';
|
|
14
|
+
export type RunEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'auto';
|
|
14
15
|
/**
|
|
15
16
|
* Reserved `<agent>` keyword for `agents run auto` — full-auto dispatch:
|
|
16
17
|
* host (14d launch affinity) → harness (best-account headroom, weighted) →
|
|
@@ -36,6 +37,7 @@ export interface AgentRunConfig {
|
|
|
36
37
|
export interface RunDefaults {
|
|
37
38
|
mode?: Mode;
|
|
38
39
|
model?: string;
|
|
40
|
+
effort?: RunEffort;
|
|
39
41
|
}
|
|
40
42
|
/** `run:` section in agents.yaml. Agent keys keep strategy; `defaults` stores selector rules. */
|
|
41
43
|
export type RunConfig = Partial<Record<AgentId, AgentRunConfig>> & {
|
package/dist/lib/versions.js
CHANGED
|
@@ -928,6 +928,21 @@ export function getBinaryPath(agent, version) {
|
|
|
928
928
|
? path.join(getHomeDir(), 'bin', 'muse.exe')
|
|
929
929
|
: path.join(getHomeDir(), '.local', 'bin', 'muse');
|
|
930
930
|
}
|
|
931
|
+
if (agent === 'warp') {
|
|
932
|
+
// Warp Agent CLI installs a single global, self-updating `oz` binary — brew
|
|
933
|
+
// cask on macOS, the `oz-stable` apt|yum|pacman package on Linux — so, unlike
|
|
934
|
+
// droid/muse (which land at ~/.local/bin), its install location is
|
|
935
|
+
// platform/package specific. Resolve the real binary on PATH (findInPath
|
|
936
|
+
// skips our own shims dir) so isVersionInstalled / agents view agree with
|
|
937
|
+
// what executes. When oz is not installed, fall back to a deterministic path
|
|
938
|
+
// that won't exist, so isVersionInstalled reports uninstalled honestly.
|
|
939
|
+
const onPath = findInPath('oz');
|
|
940
|
+
if (onPath)
|
|
941
|
+
return onPath;
|
|
942
|
+
return IS_WINDOWS
|
|
943
|
+
? path.join(getHomeDir(), 'bin', 'oz.exe')
|
|
944
|
+
: '/opt/warpdotdev/oz-stable/oz';
|
|
945
|
+
}
|
|
931
946
|
const versionDir = getVersionDir(agent, version);
|
|
932
947
|
return path.join(versionDir, 'node_modules', '.bin', agentConfig.cliCommand);
|
|
933
948
|
}
|
|
@@ -1539,7 +1554,7 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1539
1554
|
// exec itself forever. So we skip the resolver-backed agents here AND, for
|
|
1540
1555
|
// everyone else, filter the shims dir out of the `which` candidates so the
|
|
1541
1556
|
// same race can't bite a non-special-cased installScript agent.
|
|
1542
|
-
if (agent !== 'grok' && agent !== 'droid' && agent !== 'muse') {
|
|
1557
|
+
if (agent !== 'grok' && agent !== 'droid' && agent !== 'muse' && agent !== 'warp') {
|
|
1543
1558
|
// findInPath is a pure-Node PATH scan that already skips our own shims
|
|
1544
1559
|
// dir — so it returns the genuine install, never our dispatcher shim
|
|
1545
1560
|
// (which sits ahead of ~/.local/bin on PATH and would otherwise be
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ActiveSession } from '../session/active.js';
|
|
2
|
+
import { type WatchdogThresholds, type WatchdogTickResult } from './runner.js';
|
|
3
|
+
export interface WatchdogPassOptions {
|
|
4
|
+
nudge: boolean;
|
|
5
|
+
nudgeText?: string;
|
|
6
|
+
smart?: boolean;
|
|
7
|
+
smartAgent?: string;
|
|
8
|
+
thresholds?: WatchdogThresholds;
|
|
9
|
+
allowGhosttyFocus?: boolean;
|
|
10
|
+
sessions?: ActiveSession[];
|
|
11
|
+
stateDir?: string;
|
|
12
|
+
mailboxGc?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function loadWatchdogSessions(): Promise<ActiveSession[]>;
|
|
15
|
+
export declare function runWatchdogMailboxGc(sessions: ActiveSession[]): void;
|
|
16
|
+
/** Execute one watchdog pass from the daemon or the explicit CLI command. */
|
|
17
|
+
export declare function runWatchdogPass(opts: WatchdogPassOptions): Promise<WatchdogTickResult>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { gcMailbox } from '../mailbox-gc.js';
|
|
3
|
+
import { mailboxIdForActiveSession } from '../mailbox-target.js';
|
|
4
|
+
import { getActiveSessions } from '../session/active.js';
|
|
5
|
+
import { loadLocalActiveSessions } from '../session/session-cache.js';
|
|
6
|
+
import { getRuntimeStateDir } from '../state.js';
|
|
7
|
+
import { runWatchdogTick } from './runner.js';
|
|
8
|
+
export async function loadWatchdogSessions() {
|
|
9
|
+
const loaded = await loadLocalActiveSessions({
|
|
10
|
+
gather: () => getActiveSessions({ localOnly: true }),
|
|
11
|
+
});
|
|
12
|
+
return loaded.sessions;
|
|
13
|
+
}
|
|
14
|
+
export function runWatchdogMailboxGc(sessions) {
|
|
15
|
+
const activeBoxIds = new Set(sessions.map(mailboxIdForActiveSession).filter((id) => Boolean(id)));
|
|
16
|
+
try {
|
|
17
|
+
gcMailbox(activeBoxIds);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Housekeeping is retried by the next daemon tick.
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Execute one watchdog pass from the daemon or the explicit CLI command. */
|
|
24
|
+
export async function runWatchdogPass(opts) {
|
|
25
|
+
const sessions = opts.sessions ?? await loadWatchdogSessions();
|
|
26
|
+
const result = await runWatchdogTick({
|
|
27
|
+
nudge: opts.nudge,
|
|
28
|
+
nudgeText: opts.nudgeText,
|
|
29
|
+
smart: opts.smart,
|
|
30
|
+
smartAgent: opts.smartAgent,
|
|
31
|
+
thresholds: opts.thresholds,
|
|
32
|
+
allowGhosttyFocus: opts.allowGhosttyFocus,
|
|
33
|
+
stateDir: opts.stateDir ?? path.join(getRuntimeStateDir(), 'watchdog'),
|
|
34
|
+
sessions,
|
|
35
|
+
});
|
|
36
|
+
if (opts.mailboxGc !== false)
|
|
37
|
+
runWatchdogMailboxGc(sessions);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.25",
|
|
4
4
|
"description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|