@phnx-labs/agents-cli 1.22.31 → 1.22.32
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 +66 -0
- package/README.md +8 -2
- package/dist/bin/agents +0 -0
- package/dist/commands/daemon.js +52 -12
- package/dist/commands/doctor.d.ts +19 -0
- package/dist/commands/doctor.js +119 -17
- package/dist/commands/routines.js +164 -36
- package/dist/commands/sessions.d.ts +1 -1
- package/dist/commands/sessions.js +44 -10
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +148 -0
- package/dist/index.js +3 -1
- package/dist/lib/catchup.js +4 -1
- package/dist/lib/daemon.d.ts +17 -0
- package/dist/lib/daemon.js +69 -3
- package/dist/lib/devices/doctor-findings.d.ts +7 -2
- package/dist/lib/devices/doctor-findings.js +53 -2
- package/dist/lib/devices/doctor-overview-cache.d.ts +7 -0
- package/dist/lib/devices/doctor-overview-cache.js +15 -0
- package/dist/lib/devices/fleet-divergence.d.ts +11 -0
- package/dist/lib/devices/fleet-divergence.js +6 -0
- package/dist/lib/devices/fleet-inventory.js +16 -2
- package/dist/lib/drift.d.ts +6 -1
- package/dist/lib/drift.js +9 -0
- package/dist/lib/hooks/cache.js +20 -1
- package/dist/lib/hooks.d.ts +91 -1
- package/dist/lib/hooks.js +289 -3
- package/dist/lib/hosts/passthrough.js +3 -0
- package/dist/lib/installations/index.d.ts +14 -0
- package/dist/lib/installations/index.js +14 -0
- package/dist/lib/installations/resolve.d.ts +43 -0
- package/dist/lib/installations/resolve.js +93 -0
- package/dist/lib/installations/store.d.ts +56 -0
- package/dist/lib/installations/store.js +196 -0
- package/dist/lib/installations/strategies.d.ts +73 -0
- package/dist/lib/installations/strategies.js +293 -0
- package/dist/lib/installations/types.d.ts +78 -0
- package/dist/lib/installations/types.js +8 -0
- package/dist/lib/installations/update.d.ts +40 -0
- package/dist/lib/installations/update.js +131 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/migrate.d.ts +27 -0
- package/dist/lib/migrate.js +112 -2
- package/dist/lib/routine-context.d.ts +144 -0
- package/dist/lib/routine-context.js +268 -0
- package/dist/lib/routine-readiness.d.ts +47 -0
- package/dist/lib/routine-readiness.js +239 -0
- package/dist/lib/routines.d.ts +97 -1
- package/dist/lib/routines.js +107 -1
- package/dist/lib/runner.d.ts +18 -4
- package/dist/lib/runner.js +291 -98
- package/dist/lib/scheduler.d.ts +7 -1
- package/dist/lib/scheduler.js +5 -2
- 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/self-heal/checks/hook-runtime.d.ts +2 -0
- package/dist/lib/self-heal/checks/hook-runtime.js +16 -0
- package/dist/lib/self-heal/registry.js +5 -2
- package/dist/lib/self-heal/types.d.ts +1 -1
- package/dist/lib/session/state.js +4 -1
- package/dist/lib/startup/command-registry.d.ts +1 -0
- package/dist/lib/startup/command-registry.js +2 -0
- package/dist/lib/versions.d.ts +24 -0
- package/dist/lib/versions.js +49 -16
- package/package.json +2 -2
|
@@ -5,15 +5,18 @@
|
|
|
5
5
|
// SelfHealReport. Both front doors — the daemon (by cadence) and `agents doctor`
|
|
6
6
|
// (all, or by id) — call runSelfHeal.
|
|
7
7
|
import { resourcesCheck } from './checks/resources.js';
|
|
8
|
+
import { hookRuntimeCheck } from './checks/hook-runtime.js';
|
|
8
9
|
import { shimsCheck } from './checks/shims.js';
|
|
9
10
|
import { shadowingCheck } from './checks/shadowing.js';
|
|
10
11
|
import { pathCheck } from './checks/path.js';
|
|
11
|
-
// Order matters: cheap structural fixes (shims, shadow adoption, PATH
|
|
12
|
-
// heavier resource reconciliation, so a freshly-
|
|
12
|
+
// Order matters: cheap structural fixes (shims, shadow adoption, PATH, generated
|
|
13
|
+
// hook wrappers) before the heavier resource reconciliation, so a freshly-
|
|
14
|
+
// repaired shim is in place first.
|
|
13
15
|
export const HEAL_CHECKS = [
|
|
14
16
|
shimsCheck,
|
|
15
17
|
shadowingCheck,
|
|
16
18
|
pathCheck,
|
|
19
|
+
hookRuntimeCheck,
|
|
17
20
|
resourcesCheck,
|
|
18
21
|
];
|
|
19
22
|
/** Run the selected checks, isolating per-check failures. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type HealCheckId = 'resources' | 'shims' | 'shadowing' | 'path';
|
|
1
|
+
export type HealCheckId = 'resources' | 'hook-runtime' | 'shims' | 'shadowing' | 'path';
|
|
2
2
|
/** When the daemon schedules a check. */
|
|
3
3
|
export type HealCadence = 'startup' | 'frequent' | 'periodic';
|
|
4
4
|
export interface HealCtx {
|
|
@@ -194,7 +194,10 @@ const TICKET_BRANCH_RE = /(?:^|[/_-])([a-z]{2,6})-(\d{2,6})(?=[/_-]|$)/;
|
|
|
194
194
|
/** Keys that look like tickets but aren't — avoid false positives from branches. */
|
|
195
195
|
const TICKET_DENYLIST = new Set(['UTF', 'SHA', 'ISO', 'RFC', 'IPV', 'X86', 'ARM', 'MP', 'H']);
|
|
196
196
|
const PR_URL_RE = /https:\/\/github\.com\/[^\s"'()<>]+\/pull\/(\d+)/;
|
|
197
|
-
|
|
197
|
+
// Either separator: a Windows session cwd is `…\.agents\worktrees\<slug>`, and a
|
|
198
|
+
// forward-slash-only pattern silently derived no slug there (the RUSH-2358
|
|
199
|
+
// worktree_slug parity test is red on the Windows CI leg for exactly this).
|
|
200
|
+
export const WORKTREE_RE = /[\\/]\.agents[\\/]worktrees[\\/]([^\\/]+)/;
|
|
198
201
|
/** gh invocations that create/open a PR. */
|
|
199
202
|
const GH_PR_CREATE_RE = /\bgh\s+pr\s+(?:create|new)\b/;
|
|
200
203
|
/** gh invocation that opens an issue — the created number is read from its result. */
|
|
@@ -39,6 +39,7 @@ export declare const loadPlugins: ModuleLoader;
|
|
|
39
39
|
export declare const loadWorkflows: ModuleLoader;
|
|
40
40
|
export declare const loadWorktree: ModuleLoader;
|
|
41
41
|
export declare const loadVersions: ModuleLoader;
|
|
42
|
+
export declare const loadUpdate: ModuleLoader;
|
|
42
43
|
export declare const loadImport: ModuleLoader;
|
|
43
44
|
export declare const loadExport: ModuleLoader;
|
|
44
45
|
export declare const loadPackages: ModuleLoader;
|
|
@@ -38,6 +38,7 @@ export const loadPlugins = async () => (await import('../../commands/plugins.js'
|
|
|
38
38
|
export const loadWorkflows = async () => (await import('../../commands/workflows.js')).registerWorkflowsCommands;
|
|
39
39
|
export const loadWorktree = async () => (await import('../../commands/worktree.js')).registerWorktreeCommands;
|
|
40
40
|
export const loadVersions = async () => (await import('../../commands/versions.js')).registerVersionsCommands;
|
|
41
|
+
export const loadUpdate = async () => (await import('../../commands/update.js')).registerUpdateCommand;
|
|
41
42
|
export const loadImport = async () => (await import('../../commands/import.js')).registerImportCommand;
|
|
42
43
|
export const loadExport = async () => (await import('../../commands/export.js')).registerExportCommand;
|
|
43
44
|
export const loadPackages = async () => (await import('../../commands/packages.js')).registerPackagesCommands;
|
|
@@ -168,6 +169,7 @@ export const COMMAND_LOADERS = {
|
|
|
168
169
|
remove: [loadVersions],
|
|
169
170
|
rm: [loadVersions],
|
|
170
171
|
purge: [loadVersions],
|
|
172
|
+
update: [loadUpdate],
|
|
171
173
|
prune: [loadVersions, loadPrune],
|
|
172
174
|
import: [loadImport],
|
|
173
175
|
export: [loadExport],
|
package/dist/lib/versions.d.ts
CHANGED
|
@@ -414,6 +414,30 @@ export declare function verifyInstalledBinaryLaunches(agent: AgentId, version: s
|
|
|
414
414
|
ok: boolean;
|
|
415
415
|
detail?: string;
|
|
416
416
|
}>;
|
|
417
|
+
/**
|
|
418
|
+
* The launch probe itself, addressed by PATH rather than by installed version.
|
|
419
|
+
*
|
|
420
|
+
* `verifyInstalledBinaryLaunches` is this function applied to a version dir that
|
|
421
|
+
* is already live. `agents update` needs the identical check applied to a release
|
|
422
|
+
* that is still STAGED — probing it before the swap is what makes the update
|
|
423
|
+
* transactional, since a staged release that cannot launch is discarded instead
|
|
424
|
+
* of replacing a working one. Both callers must agree byte-for-byte on what
|
|
425
|
+
* "launches" means, hence one implementation.
|
|
426
|
+
*
|
|
427
|
+
* `posixBinary` is the extensionless launch target. The real launch target
|
|
428
|
+
* differs by platform, so we probe whatever `agents run` actually execs: on
|
|
429
|
+
* Windows that is the npm `.cmd` wrapper beside it (exec.ts uses
|
|
430
|
+
* `absPath + '.cmd'`), which chains to the native `.exe`; a gutted install
|
|
431
|
+
* (renamed/missing `.exe`) makes that wrapper emit "is not recognized" — the
|
|
432
|
+
* exact win-mini failure a vendor auto-update leaves behind. Probing the
|
|
433
|
+
* extensionless `.bin/<cli>` instead would ENOENT even on a HEALTHY Windows
|
|
434
|
+
* install, so we DON'T. On POSIX the `.bin/<cli>` binary is the launch target
|
|
435
|
+
* and is probed directly.
|
|
436
|
+
*/
|
|
437
|
+
export declare function verifyBinaryLaunches(posixBinary: string, home: string): Promise<{
|
|
438
|
+
ok: boolean;
|
|
439
|
+
detail?: string;
|
|
440
|
+
}>;
|
|
417
441
|
/**
|
|
418
442
|
* Launch-path self-heal. Given the concrete version `agents run` is about to
|
|
419
443
|
* spawn, make sure it will actually run — and if not, repair it instead of
|
package/dist/lib/versions.js
CHANGED
|
@@ -34,6 +34,8 @@ import { discoverPermissionGroups, getActivePermissionPresetName, readPermission
|
|
|
34
34
|
import { parseMcpServerConfig, isProjectMcpTrusted } from './mcp.js';
|
|
35
35
|
import { createVersionedAlias, removeVersionedAlias, getConfigSymlinkVersion, ensureClaudeInsideSymlink, assertIsolationBoundary, } from './shims.js';
|
|
36
36
|
import { importInstallScriptBinary } from './import.js';
|
|
37
|
+
import { createInstallation } from './installations/store.js';
|
|
38
|
+
import { INSTALLATION_RECORD_FILE } from './installations/types.js';
|
|
37
39
|
import { IS_WINDOWS, composeWin32CommandLine } from './platform/index.js';
|
|
38
40
|
import { listInstalledSubagents } from './subagents.js';
|
|
39
41
|
import { listInstalledWorkflows } from './workflows.js';
|
|
@@ -1579,6 +1581,10 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1579
1581
|
correctly reports it uninstalled. */
|
|
1580
1582
|
}
|
|
1581
1583
|
createVersionedAlias(agent, installedVersion);
|
|
1584
|
+
// Freeze this installation's identity. The dir name is its stable label from
|
|
1585
|
+
// here on; the release it carries is recorded separately so `agents update`
|
|
1586
|
+
// can move the release without invalidating any reference to the label.
|
|
1587
|
+
createInstallation(agent, installedVersion, installedVersion);
|
|
1582
1588
|
// The self-updating binary just changed on disk — drop the cached
|
|
1583
1589
|
// `--version` so `agents view` reflects the freshly-installed release.
|
|
1584
1590
|
invalidateLiveVersionCache(agent);
|
|
@@ -1633,6 +1639,9 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1633
1639
|
// load-bearing: it ensures `version` (which VERSION_RE permits to start with
|
|
1634
1640
|
// `-`) is never passed as a standalone npm CLI flag.
|
|
1635
1641
|
const packageSpec = `${agentConfig.npmPackage}@${version}`;
|
|
1642
|
+
// Set once the install has passed its integrity gate; read after the try so
|
|
1643
|
+
// the success path's bookkeeping sits outside the catch's cleanup.
|
|
1644
|
+
let healthyVersion;
|
|
1636
1645
|
try {
|
|
1637
1646
|
// Check npm is available
|
|
1638
1647
|
const winShell = process.platform === 'win32';
|
|
@@ -1719,8 +1728,10 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1719
1728
|
+ `The install is incomplete — the platform binary is missing. Re-run: agents add ${agent}@${installedVersion}`,
|
|
1720
1729
|
};
|
|
1721
1730
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1731
|
+
// The install is healthy from here. Identity is frozen AFTER the try (see
|
|
1732
|
+
// below) so a bookkeeping write failure cannot fall into the catch and wipe
|
|
1733
|
+
// a working install.
|
|
1734
|
+
healthyVersion = installedVersion;
|
|
1724
1735
|
}
|
|
1725
1736
|
catch (err) {
|
|
1726
1737
|
// Clean up on failure — preserve `home/` in case a prior install left
|
|
@@ -1731,13 +1742,20 @@ export async function installVersion(agent, version, onProgress, opts) {
|
|
|
1731
1742
|
emit('version.install', { agent, version, error: err.message });
|
|
1732
1743
|
return { success: false, installedVersion: version, error: err.message };
|
|
1733
1744
|
}
|
|
1745
|
+
// Freeze this installation's identity (see the installScript branch above).
|
|
1746
|
+
createInstallation(agent, healthyVersion, healthyVersion);
|
|
1747
|
+
emit('version.install', { agent, version: healthyVersion });
|
|
1748
|
+
return { success: true, installedVersion: healthyVersion };
|
|
1734
1749
|
}
|
|
1735
1750
|
// Version-dir entries that are STATE, not install output, and so must survive a
|
|
1736
|
-
// clean reinstall: `home/`,
|
|
1737
|
-
// of truth for "this copy is walled off"
|
|
1751
|
+
// clean reinstall: `home/`, the `.isolated` marker that is the single source
|
|
1752
|
+
// of truth for "this copy is walled off", and `installation.json`, which carries
|
|
1753
|
+
// this installation's frozen identity. Losing the marker would silently demote
|
|
1738
1754
|
// an isolated copy to a normal one on its first repair — after which shim
|
|
1739
|
-
// self-heal would hand it a bare `<agent>` shim and a PATH entry.
|
|
1740
|
-
|
|
1755
|
+
// self-heal would hand it a bare `<agent>` shim and a PATH entry. Losing the
|
|
1756
|
+
// installation record would mint a NEW id for the same install on its first
|
|
1757
|
+
// repair, discarding its release history.
|
|
1758
|
+
const PRESERVED_ON_CLEAN_REINSTALL = new Set(['home', '.isolated', INSTALLATION_RECORD_FILE]);
|
|
1741
1759
|
/**
|
|
1742
1760
|
* Remove install artifacts from a version directory, preserving `home/` which
|
|
1743
1761
|
* contains the user's conversation history, sessions, history.jsonl, tasks,
|
|
@@ -2233,16 +2251,31 @@ export function probeSpawnSpec(binary, isWin) {
|
|
|
2233
2251
|
return { command: binary, args: ['--version'], shell: false };
|
|
2234
2252
|
}
|
|
2235
2253
|
export async function verifyInstalledBinaryLaunches(agent, version) {
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2254
|
+
return verifyBinaryLaunches(getBinaryPath(agent, version), getVersionHomePath(agent, version));
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* The launch probe itself, addressed by PATH rather than by installed version.
|
|
2258
|
+
*
|
|
2259
|
+
* `verifyInstalledBinaryLaunches` is this function applied to a version dir that
|
|
2260
|
+
* is already live. `agents update` needs the identical check applied to a release
|
|
2261
|
+
* that is still STAGED — probing it before the swap is what makes the update
|
|
2262
|
+
* transactional, since a staged release that cannot launch is discarded instead
|
|
2263
|
+
* of replacing a working one. Both callers must agree byte-for-byte on what
|
|
2264
|
+
* "launches" means, hence one implementation.
|
|
2265
|
+
*
|
|
2266
|
+
* `posixBinary` is the extensionless launch target. The real launch target
|
|
2267
|
+
* differs by platform, so we probe whatever `agents run` actually execs: on
|
|
2268
|
+
* Windows that is the npm `.cmd` wrapper beside it (exec.ts uses
|
|
2269
|
+
* `absPath + '.cmd'`), which chains to the native `.exe`; a gutted install
|
|
2270
|
+
* (renamed/missing `.exe`) makes that wrapper emit "is not recognized" — the
|
|
2271
|
+
* exact win-mini failure a vendor auto-update leaves behind. Probing the
|
|
2272
|
+
* extensionless `.bin/<cli>` instead would ENOENT even on a HEALTHY Windows
|
|
2273
|
+
* install, so we DON'T. On POSIX the `.bin/<cli>` binary is the launch target
|
|
2274
|
+
* and is probed directly.
|
|
2275
|
+
*/
|
|
2276
|
+
export async function verifyBinaryLaunches(posixBinary, home) {
|
|
2244
2277
|
const isWin = process.platform === 'win32';
|
|
2245
|
-
const binary = isWin ?
|
|
2278
|
+
const binary = isWin ? posixBinary + '.cmd' : posixBinary;
|
|
2246
2279
|
if (!fs.existsSync(binary)) {
|
|
2247
2280
|
// Windows: a missing `.cmd` means a non-npm/global agent (droid.exe) we can't
|
|
2248
2281
|
// safely probe — treat as healthy (isVersionInstalled validates presence).
|
|
@@ -2259,7 +2292,7 @@ export async function verifyInstalledBinaryLaunches(agent, version) {
|
|
|
2259
2292
|
await execFileAsync(spec.command, spec.args, {
|
|
2260
2293
|
timeout: 15000,
|
|
2261
2294
|
shell: spec.shell,
|
|
2262
|
-
env: { ...process.env, HOME:
|
|
2295
|
+
env: { ...process.env, HOME: home },
|
|
2263
2296
|
});
|
|
2264
2297
|
return { ok: true };
|
|
2265
2298
|
}
|
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.32",
|
|
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",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"test": "node ./node_modules/vitest/vitest.mjs run",
|
|
59
59
|
"bench": "node ./node_modules/vitest/vitest.mjs bench --run",
|
|
60
60
|
"typecheck:bench": "tsc --noEmit --ignoreConfig --skipLibCheck --module esnext --moduleResolution bundler --target es2022 --strict --esModuleInterop --lib es2022 --types node src/lib/*.bench.ts src/lib/**/*.bench.ts",
|
|
61
|
-
"test:remote": "scripts/sandbox.sh 'bun install && bun run build && bun run test'",
|
|
61
|
+
"test:remote": "scripts/sandbox.sh 'cd apps/cli && bun install && bun run build && bun run test'",
|
|
62
62
|
"verify-docs": "scripts/verify-docs.sh",
|
|
63
63
|
"test:watch": "node ./node_modules/vitest/vitest.mjs"
|
|
64
64
|
},
|