@phnx-labs/agents-cli 1.20.7 → 1.20.9
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 +6 -0
- package/README.md +1 -1
- package/dist/commands/computer-actions.d.ts +19 -0
- package/dist/commands/computer-actions.js +159 -1
- package/dist/commands/computer.js +2 -2
- package/dist/commands/daemon.js +6 -6
- package/dist/commands/import.js +3 -6
- package/dist/commands/inspect.js +17 -8
- package/dist/commands/models.js +2 -1
- package/dist/commands/plugins.js +3 -2
- package/dist/commands/refresh-rules.js +4 -4
- package/dist/commands/routines.js +8 -7
- package/dist/commands/sessions.js +17 -2
- package/dist/commands/setup.js +2 -2
- package/dist/commands/subagents.js +2 -1
- package/dist/commands/usage.js +11 -3
- package/dist/commands/versions.js +2 -2
- package/dist/index.js +69 -47
- package/dist/lib/agents.d.ts +18 -1
- package/dist/lib/agents.js +89 -23
- package/dist/lib/browser/chrome.d.ts +4 -3
- package/dist/lib/browser/chrome.js +87 -12
- package/dist/lib/browser/ipc.js +59 -13
- package/dist/lib/computer-rpc.d.ts +2 -0
- package/dist/lib/computer-rpc.js +21 -1
- package/dist/lib/daemon.js +20 -8
- package/dist/lib/fs-walk.d.ts +7 -1
- package/dist/lib/fs-walk.js +45 -11
- package/dist/lib/git.js +5 -2
- package/dist/lib/log-follow.d.ts +7 -0
- package/dist/lib/log-follow.js +65 -0
- package/dist/lib/platform/index.d.ts +1 -0
- package/dist/lib/platform/index.js +1 -0
- package/dist/lib/platform/ipc.d.ts +11 -0
- package/dist/lib/platform/ipc.js +21 -0
- package/dist/lib/platform/paths.d.ts +7 -0
- package/dist/lib/platform/paths.js +9 -0
- package/dist/lib/platform/process.d.ts +9 -1
- package/dist/lib/platform/process.js +27 -0
- package/dist/lib/plugins.js +5 -3
- package/dist/lib/refresh.js +2 -2
- package/dist/lib/self-update.d.ts +86 -0
- package/dist/lib/self-update.js +178 -0
- package/dist/lib/shims.d.ts +13 -8
- package/dist/lib/shims.js +46 -11
- package/dist/lib/versions.js +3 -3
- package/package.json +1 -1
- package/scripts/postinstall.js +36 -26
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-update install plumbing.
|
|
3
|
+
*
|
|
4
|
+
* The hard requirement: an upgrade must replace the copy that is currently
|
|
5
|
+
* running. A bare `npm install -g` writes into the global prefix of whatever
|
|
6
|
+
* `npm` PATH happens to resolve — on machines with more than one node
|
|
7
|
+
* installation (nvm + Homebrew + vendored runtimes) that prefix can belong to
|
|
8
|
+
* a different node than the one this copy lives under. The install then
|
|
9
|
+
* "succeeds" while the running copy stays stale and re-prompts forever.
|
|
10
|
+
*
|
|
11
|
+
* So every step here is anchored to the running package root on disk, never
|
|
12
|
+
* to PATH resolution.
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'fs';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
import { spawnSync } from 'child_process';
|
|
17
|
+
import { compareVersions } from './versions.js';
|
|
18
|
+
export const NPM_PACKAGE_NAME = '@phnx-labs/agents-cli';
|
|
19
|
+
/** Read the cached update-check state from disk. Returns null if the file is missing or corrupt. */
|
|
20
|
+
export function readUpdateCache(file) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* cache file missing or corrupt */
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Persist the latest known version and current timestamp. Preserves an
|
|
31
|
+
* existing `dismissed` marker — the background refresh must not erase a
|
|
32
|
+
* user's "Skip this version" choice, or they get re-prompted for the exact
|
|
33
|
+
* version they dismissed.
|
|
34
|
+
*/
|
|
35
|
+
export function saveUpdateCheck(file, latestVersion) {
|
|
36
|
+
try {
|
|
37
|
+
const dir = path.dirname(file);
|
|
38
|
+
if (!fs.existsSync(dir))
|
|
39
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
40
|
+
const dismissed = readUpdateCache(file)?.dismissed;
|
|
41
|
+
fs.writeFileSync(file, JSON.stringify({ lastCheck: Date.now(), latestVersion, ...(dismissed ? { dismissed } : {}) }));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
/* best-effort cache update */
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Record that the user chose to skip `version`; suppresses prompts until a newer version appears. */
|
|
48
|
+
export function dismissUpdateVersion(file, version) {
|
|
49
|
+
try {
|
|
50
|
+
const dir = path.dirname(file);
|
|
51
|
+
if (!fs.existsSync(dir))
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
53
|
+
const existing = readUpdateCache(file);
|
|
54
|
+
fs.writeFileSync(file, JSON.stringify({
|
|
55
|
+
lastCheck: existing?.lastCheck ?? Date.now(),
|
|
56
|
+
latestVersion: version,
|
|
57
|
+
dismissed: version,
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* best-effort */
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Whether the cached state warrants an upgrade prompt for a copy running `currentVersion`. */
|
|
65
|
+
export function shouldPromptUpgrade(cache, currentVersion) {
|
|
66
|
+
if (!cache?.latestVersion)
|
|
67
|
+
return false;
|
|
68
|
+
return (cache.latestVersion !== currentVersion &&
|
|
69
|
+
compareVersions(cache.latestVersion, currentVersion) > 0 &&
|
|
70
|
+
cache.latestVersion !== cache.dismissed);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Derive the npm global prefix that owns the install at `packageRoot`.
|
|
74
|
+
*
|
|
75
|
+
* npm's global layout for a scoped package:
|
|
76
|
+
* POSIX: <prefix>/lib/node_modules/@phnx-labs/agents-cli
|
|
77
|
+
* Windows: <prefix>/node_modules/@phnx-labs/agents-cli
|
|
78
|
+
*
|
|
79
|
+
* Throws when `packageRoot` is not inside a node_modules tree (e.g. running
|
|
80
|
+
* from a source checkout) — there is no prefix to install into, and guessing
|
|
81
|
+
* one is exactly the bug this module exists to prevent.
|
|
82
|
+
*/
|
|
83
|
+
export function deriveGlobalPrefix(packageRoot) {
|
|
84
|
+
const resolved = path.resolve(packageRoot);
|
|
85
|
+
// Two levels up from the package root: the scope dir, then node_modules.
|
|
86
|
+
const nodeModulesDir = path.dirname(path.dirname(resolved));
|
|
87
|
+
if (path.basename(nodeModulesDir) !== 'node_modules') {
|
|
88
|
+
throw new Error(`${resolved} is not an npm-managed install; reinstall with: npm install -g ${NPM_PACKAGE_NAME}`);
|
|
89
|
+
}
|
|
90
|
+
const parent = path.dirname(nodeModulesDir);
|
|
91
|
+
return path.basename(parent) === 'lib' ? path.dirname(parent) : parent;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Install `spec` into an explicit global prefix. `--prefix` pins the
|
|
95
|
+
* destination no matter which npm binary PATH resolves. `--ignore-scripts`
|
|
96
|
+
* skips lifecycle scripts; the caller refreshes alias shims afterwards via
|
|
97
|
+
* refreshAliasShims().
|
|
98
|
+
*/
|
|
99
|
+
export async function installPackageIntoPrefix(spec, prefix) {
|
|
100
|
+
const { execFile } = await import('child_process');
|
|
101
|
+
const { promisify } = await import('util');
|
|
102
|
+
const execFileAsync = promisify(execFile);
|
|
103
|
+
await execFileAsync('npm', ['install', '-g', '--prefix', prefix, spec, '--ignore-scripts']);
|
|
104
|
+
}
|
|
105
|
+
/** Read the version field of the package.json at `packageRoot`, fresh from disk. */
|
|
106
|
+
export function readInstalledVersion(packageRoot) {
|
|
107
|
+
return JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8')).version;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Assert that the install at `packageRoot` now carries `expectedVersion`.
|
|
111
|
+
* npm exiting 0 only proves it wrote *somewhere*; this proves it wrote *here*.
|
|
112
|
+
*/
|
|
113
|
+
export function verifyInstalledVersion(packageRoot, expectedVersion) {
|
|
114
|
+
const actual = readInstalledVersion(packageRoot);
|
|
115
|
+
if (actual !== expectedVersion) {
|
|
116
|
+
throw new Error(`npm reported success but ${packageRoot} is still ${actual} (expected ${expectedVersion}). ` +
|
|
117
|
+
`Run manually: npm install -g --prefix ${deriveGlobalPrefix(packageRoot)} ${NPM_PACKAGE_NAME}@${expectedVersion}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Re-run the freshly installed copy's postinstall in shims-only mode so the
|
|
122
|
+
* bare-command aliases (secrets, sessions, ...) pick up the new entrypoint
|
|
123
|
+
* and any aliases added in the new version. Best-effort: a failure here
|
|
124
|
+
* leaves the previous shims in place, which still point at the (now
|
|
125
|
+
* upgraded) package root.
|
|
126
|
+
*/
|
|
127
|
+
export function refreshAliasShims(packageRoot) {
|
|
128
|
+
spawnSync(process.execPath, [path.join(packageRoot, 'scripts', 'postinstall.js')], {
|
|
129
|
+
env: { ...process.env, AGENTS_POSTINSTALL_SHIMS_ONLY: '1' },
|
|
130
|
+
stdio: 'ignore',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Scan PATH for `agents` entrypoints and resolve each to the agents-cli
|
|
135
|
+
* package root it executes. More than one distinct root means upgrades,
|
|
136
|
+
* shims, and the command the user types can act on different copies — the
|
|
137
|
+
* divergence behind silently-failing self-updates.
|
|
138
|
+
*
|
|
139
|
+
* npm bin entries are symlinks that resolve to `<packageRoot>/dist/index.js`
|
|
140
|
+
* (the dev install's `~/.local/bin/agents` chains through the dev prefix to
|
|
141
|
+
* the same shape). Anything that doesn't resolve to a dist/index.js inside a
|
|
142
|
+
* package named @phnx-labs/agents-cli is some other tool and is skipped.
|
|
143
|
+
* POSIX-only: Windows npm bins are .cmd wrappers, not symlinks.
|
|
144
|
+
*/
|
|
145
|
+
export function findAgentsCliInstalls(pathEnv) {
|
|
146
|
+
if (process.platform === 'win32')
|
|
147
|
+
return [];
|
|
148
|
+
const installs = [];
|
|
149
|
+
const seenRoots = new Set();
|
|
150
|
+
for (const dir of pathEnv.split(path.delimiter).filter(Boolean)) {
|
|
151
|
+
const candidate = path.join(dir, 'agents');
|
|
152
|
+
let real;
|
|
153
|
+
try {
|
|
154
|
+
real = fs.realpathSync(candidate);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
continue; // missing or dangling symlink
|
|
158
|
+
}
|
|
159
|
+
if (path.basename(real) !== 'index.js' || path.basename(path.dirname(real)) !== 'dist') {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const packageRoot = path.dirname(path.dirname(real));
|
|
163
|
+
if (seenRoots.has(packageRoot))
|
|
164
|
+
continue;
|
|
165
|
+
let pkg;
|
|
166
|
+
try {
|
|
167
|
+
pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8'));
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (pkg.name !== NPM_PACKAGE_NAME || typeof pkg.version !== 'string')
|
|
173
|
+
continue;
|
|
174
|
+
seenRoots.add(packageRoot);
|
|
175
|
+
installs.push({ binPath: candidate, packageRoot, version: pkg.version });
|
|
176
|
+
}
|
|
177
|
+
return installs;
|
|
178
|
+
}
|
package/dist/lib/shims.d.ts
CHANGED
|
@@ -248,20 +248,25 @@ export declare function isShimsInPath(): boolean;
|
|
|
248
248
|
* Get shell configuration instructions for adding shims to PATH.
|
|
249
249
|
*/
|
|
250
250
|
export declare function getPathSetupInstructions(): string;
|
|
251
|
+
interface ShimPathResult {
|
|
252
|
+
success: boolean;
|
|
253
|
+
alreadyPresent?: boolean;
|
|
254
|
+
rcFile?: string;
|
|
255
|
+
/** Human label of where the entry landed, e.g. `~/.zshrc` or `your user PATH`. */
|
|
256
|
+
location?: string;
|
|
257
|
+
/** Per-platform "how to pick it up" hint, e.g. `source ~/.zshrc` / open a new terminal. */
|
|
258
|
+
reloadHint?: string;
|
|
259
|
+
error?: string;
|
|
260
|
+
}
|
|
251
261
|
/**
|
|
252
|
-
* Add shims directory to shell
|
|
253
|
-
*
|
|
262
|
+
* Add the shims directory to PATH: edits the shell rc file on POSIX, or registers
|
|
263
|
+
* it on the Windows User PATH (registry + WM_SETTINGCHANGE). Idempotent.
|
|
254
264
|
*/
|
|
255
265
|
export declare function addShimsToPath(overrides?: {
|
|
256
266
|
homeDir?: string;
|
|
257
267
|
shell?: string;
|
|
258
268
|
shimsDir?: string;
|
|
259
|
-
}):
|
|
260
|
-
success: boolean;
|
|
261
|
-
alreadyPresent?: boolean;
|
|
262
|
-
rcFile?: string;
|
|
263
|
-
error?: string;
|
|
264
|
-
};
|
|
269
|
+
}): ShimPathResult;
|
|
265
270
|
export declare function listAgentsWithInstalledVersions(): AgentId[];
|
|
266
271
|
/**
|
|
267
272
|
* Resource diff between two versions. Each field lists resources present in
|
package/dist/lib/shims.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import * as fs from 'fs';
|
|
12
12
|
import * as path from 'path';
|
|
13
13
|
import * as os from 'os';
|
|
14
|
+
import { execFileSync } from 'child_process';
|
|
14
15
|
import { fileURLToPath } from 'url';
|
|
15
16
|
import { confirm, select } from '@inquirer/prompts';
|
|
16
17
|
import { IS_WINDOWS } from './platform/index.js';
|
|
@@ -1520,18 +1521,15 @@ Then restart your shell or run:
|
|
|
1520
1521
|
source ~/${rcFile}`;
|
|
1521
1522
|
}
|
|
1522
1523
|
/**
|
|
1523
|
-
* Add shims directory to shell
|
|
1524
|
-
*
|
|
1524
|
+
* Add the shims directory to PATH: edits the shell rc file on POSIX, or registers
|
|
1525
|
+
* it on the Windows User PATH (registry + WM_SETTINGCHANGE). Idempotent.
|
|
1525
1526
|
*/
|
|
1526
1527
|
export function addShimsToPath(overrides) {
|
|
1527
|
-
// Windows has no shell rc file to edit
|
|
1528
|
-
//
|
|
1529
|
-
//
|
|
1530
|
-
// Report "already present" so callers don't emit a misleading "added to
|
|
1531
|
-
// ~/.bashrc / source ~/.bashrc" message. (The `shell` override is the test hook
|
|
1532
|
-
// for exercising the POSIX path, so it bypasses this short-circuit.)
|
|
1528
|
+
// Windows has no shell rc file to edit. Register the shims dir on the User PATH
|
|
1529
|
+
// via the platform-native mechanism instead. (The `shell` override is the test
|
|
1530
|
+
// hook for exercising the POSIX path, so it bypasses this branch.)
|
|
1533
1531
|
if (IS_WINDOWS && !overrides?.shell) {
|
|
1534
|
-
return
|
|
1532
|
+
return addShimsToWindowsUserPath(overrides?.shimsDir || getShimsDir());
|
|
1535
1533
|
}
|
|
1536
1534
|
const shimsDir = overrides?.shimsDir || getShimsDir();
|
|
1537
1535
|
const { rcFile, rcPath, shell } = getShellRcFile(overrides);
|
|
@@ -1565,16 +1563,53 @@ export function addShimsToPath(overrides) {
|
|
|
1565
1563
|
const separator = contentWithoutShimLines.length > 0 && !contentWithoutShimLines.endsWith('\n') ? '\n' : '';
|
|
1566
1564
|
let newContent = contentWithoutShimLines + separator + exportBlock;
|
|
1567
1565
|
newContent = newContent.replace(/\n{2,}$/g, '\n');
|
|
1566
|
+
const location = `~/${rcFile}`;
|
|
1567
|
+
const reloadHint = `Restart your shell or run: source ~/${rcFile}`;
|
|
1568
1568
|
if (newContent === content) {
|
|
1569
|
-
return { success: true, alreadyPresent: true, rcFile };
|
|
1569
|
+
return { success: true, alreadyPresent: true, rcFile, location, reloadHint };
|
|
1570
1570
|
}
|
|
1571
1571
|
fs.writeFileSync(rcPath, newContent, 'utf-8');
|
|
1572
|
-
return { success: true, rcFile };
|
|
1572
|
+
return { success: true, rcFile, location, reloadHint };
|
|
1573
1573
|
}
|
|
1574
1574
|
catch (err) {
|
|
1575
1575
|
return { success: false, error: `Could not write ${rcFile}: ${err.message}` };
|
|
1576
1576
|
}
|
|
1577
1577
|
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Register the shims dir on the Windows User PATH via the .NET environment API,
|
|
1580
|
+
* which writes the registry AND broadcasts WM_SETTINGCHANGE — the correct analog
|
|
1581
|
+
* of editing a shell rc file (no `setx` truncation, no manual step). Idempotent:
|
|
1582
|
+
* a no-op when the dir is already present. The shims dir is passed via an env var
|
|
1583
|
+
* so it is never interpolated into the PowerShell script text.
|
|
1584
|
+
*/
|
|
1585
|
+
function addShimsToWindowsUserPath(shimsDir) {
|
|
1586
|
+
const script = [
|
|
1587
|
+
'$d = $env:AGENTS_SHIMS_DIR',
|
|
1588
|
+
"$u = [Environment]::GetEnvironmentVariable('Path','User')",
|
|
1589
|
+
"if ($null -eq $u) { $u = '' }",
|
|
1590
|
+
"$parts = @($u -split ';' | Where-Object { $_ -ne '' })",
|
|
1591
|
+
"if ($parts -contains $d) { 'present' } else {",
|
|
1592
|
+
" [Environment]::SetEnvironmentVariable('Path', (($parts + $d) -join ';'), 'User')",
|
|
1593
|
+
" 'added'",
|
|
1594
|
+
'}',
|
|
1595
|
+
].join('\n');
|
|
1596
|
+
try {
|
|
1597
|
+
const out = execFileSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', script], {
|
|
1598
|
+
encoding: 'utf-8',
|
|
1599
|
+
env: { ...process.env, AGENTS_SHIMS_DIR: shimsDir },
|
|
1600
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
1601
|
+
}).trim();
|
|
1602
|
+
return {
|
|
1603
|
+
success: true,
|
|
1604
|
+
alreadyPresent: out.includes('present'),
|
|
1605
|
+
location: 'your user PATH',
|
|
1606
|
+
reloadHint: 'Open a new terminal for the change to take effect.',
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
catch (err) {
|
|
1610
|
+
return { success: false, error: `Could not update the Windows user PATH: ${err.message}` };
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1578
1613
|
export function listAgentsWithInstalledVersions() {
|
|
1579
1614
|
const versionsDir = getVersionsDir();
|
|
1580
1615
|
if (!fs.existsSync(versionsDir)) {
|
package/dist/lib/versions.js
CHANGED
|
@@ -777,9 +777,9 @@ export function parseAgentSpec(spec) {
|
|
|
777
777
|
if (parts.length > 2) {
|
|
778
778
|
return null;
|
|
779
779
|
}
|
|
780
|
-
const agentName = parts[0].toLowerCase();
|
|
781
780
|
const version = parts[1] || 'latest';
|
|
782
|
-
|
|
781
|
+
const agent = resolveAgentName(parts[0]);
|
|
782
|
+
if (!agent) {
|
|
783
783
|
return null;
|
|
784
784
|
}
|
|
785
785
|
// Reject any version string that could escape an exec context or a
|
|
@@ -788,7 +788,7 @@ export function parseAgentSpec(spec) {
|
|
|
788
788
|
return null;
|
|
789
789
|
}
|
|
790
790
|
return {
|
|
791
|
-
agent
|
|
791
|
+
agent,
|
|
792
792
|
version,
|
|
793
793
|
};
|
|
794
794
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.9",
|
|
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",
|
package/scripts/postinstall.js
CHANGED
|
@@ -32,6 +32,35 @@ function shellQuote(value) {
|
|
|
32
32
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// Shorthands that delegate to the installed agents-cli entrypoint.
|
|
36
|
+
const ALIASES = ['sessions', 'secrets', 'browser', 'pty', 'teams'];
|
|
37
|
+
|
|
38
|
+
function writeAliasShims() {
|
|
39
|
+
const written = [];
|
|
40
|
+
for (const name of ALIASES) {
|
|
41
|
+
const target = path.join(SHIMS_DIR, name);
|
|
42
|
+
const script = `#!/bin/sh\nAGENTS_BIN=${shellQuote(AGENTS_BIN)}\nif [ -z "$AGENTS_BIN" ] || [ ! -x "$AGENTS_BIN" ]; then\n echo "agents: agents-cli entrypoint missing or not executable: $AGENTS_BIN" >&2\n exit 127\nfi\nexec "$AGENTS_BIN" ${name} "$@"\n`;
|
|
43
|
+
fs.writeFileSync(target, script, { mode: 0o755 });
|
|
44
|
+
// Windows can't run the POSIX shim; drop a `.cmd` companion that invokes the
|
|
45
|
+
// entrypoint via node so the bare shorthand works in a Windows shell.
|
|
46
|
+
if (process.platform === 'win32') {
|
|
47
|
+
fs.writeFileSync(target + '.cmd', `@echo off\r\nnode "${AGENTS_BIN}" ${name} %*\r\n`);
|
|
48
|
+
}
|
|
49
|
+
written.push(name);
|
|
50
|
+
}
|
|
51
|
+
return written;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Self-updater entry: the upgrade installs with --ignore-scripts (skipping
|
|
55
|
+
// this script as an npm lifecycle hook), then re-invokes it with this env var
|
|
56
|
+
// so the alias shims are refreshed from the newly installed copy. Shims only —
|
|
57
|
+
// no prompts, no rc-file edits, no output.
|
|
58
|
+
if (process.env.AGENTS_POSTINSTALL_SHIMS_ONLY === '1') {
|
|
59
|
+
fs.mkdirSync(SHIMS_DIR, { recursive: true });
|
|
60
|
+
writeAliasShims();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
35
64
|
// For local installs, create directories and show a message
|
|
36
65
|
const isGlobalInstall = process.env.npm_config_global || process.argv.includes('-g');
|
|
37
66
|
if (!isGlobalInstall) {
|
|
@@ -86,25 +115,6 @@ const exportLine = shellName === 'fish'
|
|
|
86
115
|
? `fish_add_path ${SHIMS_DIR}`
|
|
87
116
|
: `export PATH="${SHIMS_DIR}:$PATH"`;
|
|
88
117
|
|
|
89
|
-
// Shorthands that delegate to the installed agents-cli entrypoint.
|
|
90
|
-
const ALIASES = ['sessions', 'secrets', 'browser', 'pty', 'teams'];
|
|
91
|
-
|
|
92
|
-
function writeAliasShims() {
|
|
93
|
-
const written = [];
|
|
94
|
-
for (const name of ALIASES) {
|
|
95
|
-
const target = path.join(SHIMS_DIR, name);
|
|
96
|
-
const script = `#!/bin/sh\nAGENTS_BIN=${shellQuote(AGENTS_BIN)}\nif [ -z "$AGENTS_BIN" ] || [ ! -x "$AGENTS_BIN" ]; then\n echo "agents: agents-cli entrypoint missing or not executable: $AGENTS_BIN" >&2\n exit 127\nfi\nexec "$AGENTS_BIN" ${name} "$@"\n`;
|
|
97
|
-
fs.writeFileSync(target, script, { mode: 0o755 });
|
|
98
|
-
// Windows can't run the POSIX shim; drop a `.cmd` companion that invokes the
|
|
99
|
-
// entrypoint via node so the bare shorthand works in a Windows shell.
|
|
100
|
-
if (process.platform === 'win32') {
|
|
101
|
-
fs.writeFileSync(target + '.cmd', `@echo off\r\nnode "${AGENTS_BIN}" ${name} %*\r\n`);
|
|
102
|
-
}
|
|
103
|
-
written.push(name);
|
|
104
|
-
}
|
|
105
|
-
return written;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
118
|
function getVersion() {
|
|
109
119
|
const pkgPath = new URL('../package.json', import.meta.url).pathname;
|
|
110
120
|
try {
|
|
@@ -144,17 +154,17 @@ function isAlreadyConfigured(rcFile) {
|
|
|
144
154
|
}
|
|
145
155
|
|
|
146
156
|
async function main() {
|
|
147
|
-
// Windows has no shell rc files to edit. Write the `.cmd` shorthands
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
157
|
+
// Windows has no shell rc files to edit. Write the `.cmd` shorthands here; the
|
|
158
|
+
// shims dir gets registered on the User PATH by `agents setup` (via the native
|
|
159
|
+
// registry API), so we point the user there instead of mutating PATH from an
|
|
160
|
+
// npm lifecycle script. The primary `agents` command is already on PATH via
|
|
161
|
+
// npm's global bin and works immediately.
|
|
151
162
|
if (process.platform === 'win32') {
|
|
152
163
|
console.log(`\nagents-cli installed.`);
|
|
153
164
|
const written = writeAliasShims();
|
|
154
165
|
console.log(` Installed shorthands: ${written.join(', ')}`);
|
|
155
|
-
console.log(`\
|
|
156
|
-
console.log(`
|
|
157
|
-
console.log(` PowerShell: setx PATH "$env:PATH;${SHIMS_DIR}" (then open a new terminal)`);
|
|
166
|
+
console.log(`\nNext: run agents setup — it finishes setup and adds the shims dir to your PATH`);
|
|
167
|
+
console.log(`(so the bare shorthands ${ALIASES.join(', ')} and versioned aliases work in a new terminal).`);
|
|
158
168
|
}
|
|
159
169
|
// Opt-in: AGENTS_INIT_SHELL=1 npm install -g @phnx-labs/agents-cli
|
|
160
170
|
else if (process.env.AGENTS_INIT_SHELL === '1') {
|