@phnx-labs/agents-cli 1.20.14 → 1.20.15
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/dist/commands/repo.js +22 -1
- package/dist/lib/browser/service.js +28 -18
- package/dist/lib/shims.js +12 -2
- package/dist/lib/state.d.ts +18 -0
- package/dist/lib/state.js +73 -0
- package/package.json +1 -1
package/dist/commands/repo.js
CHANGED
|
@@ -23,7 +23,7 @@ function resolveRepoPath(target) {
|
|
|
23
23
|
}
|
|
24
24
|
return path.join(HOME, `.agents-${trimmed}`);
|
|
25
25
|
}
|
|
26
|
-
import { ensureAgentsDir, getExtraRepoDir, getSystemAgentsDir, getUserAgentsDir, readMeta, resolveExtraRepoDir, updateMeta, } from '../lib/state.js';
|
|
26
|
+
import { applyExtraAliasToVersions, ensureAgentsDir, getExtraRepoDir, getSystemAgentsDir, getUserAgentsDir, readMeta, resolveExtraRepoDir, updateMeta, } from '../lib/state.js';
|
|
27
27
|
import { parseSource, pullRepo, commitAndPush, isGitRepo, isSystemRepoOrigin } from '../lib/git.js';
|
|
28
28
|
import { DEFAULT_SYSTEM_REPO } from '../lib/types.js';
|
|
29
29
|
import { ALL_AGENT_IDS, isAgentName, resolveAgentName } from '../lib/agents.js';
|
|
@@ -259,6 +259,7 @@ export function registerRepoCommands(program) {
|
|
|
259
259
|
const commit = log.latest?.hash.slice(0, 8) || 'unknown';
|
|
260
260
|
extras[alias] = { url: targetDir, path: targetDir, enabled: true };
|
|
261
261
|
updateMeta({ extraRepos: extras });
|
|
262
|
+
syncExtraAliasAcrossVersions(alias, true);
|
|
262
263
|
spinner.succeed(`Created ${targetDir} (${commit})`);
|
|
263
264
|
console.log(chalk.gray(`\nRegistered as "${alias}". Edit files there, then add your own git remote when ready.`));
|
|
264
265
|
}
|
|
@@ -306,6 +307,7 @@ export function registerRepoCommands(program) {
|
|
|
306
307
|
if (parsed.type === 'local') {
|
|
307
308
|
extras[alias] = { url: parsed.url, path: parsed.url, enabled: true };
|
|
308
309
|
updateMeta({ extraRepos: extras });
|
|
310
|
+
syncExtraAliasAcrossVersions(alias, true);
|
|
309
311
|
syncMarketplacesForDefaults();
|
|
310
312
|
console.log(chalk.green(`Registered local repo "${alias}" -> ${parsed.url}`));
|
|
311
313
|
return;
|
|
@@ -342,6 +344,7 @@ export function registerRepoCommands(program) {
|
|
|
342
344
|
}
|
|
343
345
|
extras[alias] = { url: parsed.url, path: targetDir, enabled: true };
|
|
344
346
|
updateMeta({ extraRepos: extras });
|
|
347
|
+
syncExtraAliasAcrossVersions(alias, true);
|
|
345
348
|
syncMarketplacesForDefaults();
|
|
346
349
|
console.log(chalk.gray(`\nRegistered as "${alias}". Skills and commands from this repo will be`));
|
|
347
350
|
console.log(chalk.gray(`picked up automatically the next time you launch any agent.`));
|
|
@@ -379,6 +382,7 @@ export function registerRepoCommands(program) {
|
|
|
379
382
|
}
|
|
380
383
|
delete extras[alias];
|
|
381
384
|
updateMeta({ extraRepos: extras });
|
|
385
|
+
syncExtraAliasAcrossVersions(alias, false);
|
|
382
386
|
syncMarketplacesForDefaults();
|
|
383
387
|
console.log(chalk.green(`Removed "${alias}"`));
|
|
384
388
|
});
|
|
@@ -592,6 +596,19 @@ function collectRepoTargets(alias) {
|
|
|
592
596
|
}
|
|
593
597
|
return [found];
|
|
594
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* Keep already-installed versions' selectors in sync with an extra-repo change:
|
|
601
|
+
* add `<alias>:*` when the repo is registered/enabled, strip it when removed.
|
|
602
|
+
* Newly-installed versions inherit it from `defaultPatterns()` at scaffold time,
|
|
603
|
+
* so without this a repo added after install is invisible to existing versions.
|
|
604
|
+
*/
|
|
605
|
+
function syncExtraAliasAcrossVersions(alias, add) {
|
|
606
|
+
const n = applyExtraAliasToVersions(alias, add);
|
|
607
|
+
if (n > 0) {
|
|
608
|
+
const verb = add ? 'Added to' : 'Removed from';
|
|
609
|
+
console.log(chalk.gray(`${verb} ${n} existing version selector${n === 1 ? '' : 's'}.`));
|
|
610
|
+
}
|
|
611
|
+
}
|
|
595
612
|
async function toggle(alias, enabled) {
|
|
596
613
|
const meta = readMeta();
|
|
597
614
|
const extras = { ...(meta.extraRepos || {}) };
|
|
@@ -606,6 +623,10 @@ async function toggle(alias, enabled) {
|
|
|
606
623
|
}
|
|
607
624
|
extras[alias] = { ...extras[alias], enabled };
|
|
608
625
|
updateMeta({ extraRepos: extras });
|
|
626
|
+
// Re-enabling backfills the alias into existing versions; disabling leaves the
|
|
627
|
+
// selectors (resolution skips disabled extras) so a later enable is a no-op.
|
|
628
|
+
if (enabled)
|
|
629
|
+
syncExtraAliasAcrossVersions(alias, true);
|
|
609
630
|
syncMarketplacesForDefaults();
|
|
610
631
|
console.log(chalk.green(`${enabled ? 'Enabled' : 'Disabled'} "${alias}"`));
|
|
611
632
|
}
|
|
@@ -1701,24 +1701,34 @@ export class BrowserService {
|
|
|
1701
1701
|
targetId: tabId,
|
|
1702
1702
|
flatten: true,
|
|
1703
1703
|
}));
|
|
1704
|
-
// Inject a
|
|
1705
|
-
//
|
|
1706
|
-
//
|
|
1707
|
-
//
|
|
1708
|
-
//
|
|
1709
|
-
//
|
|
1710
|
-
//
|
|
1711
|
-
//
|
|
1712
|
-
//
|
|
1713
|
-
//
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1704
|
+
// Inject a stealth shim before any page script runs. Chromium exposes
|
|
1705
|
+
// navigator.webdriver = true whenever a remote-debug transport is attached;
|
|
1706
|
+
// Cloudflare Turnstile, hCaptcha, and similar bot checks read it first.
|
|
1707
|
+
//
|
|
1708
|
+
// Only attach-to-running profiles (conn.pid === 0 — Comet / Arc / Brave the
|
|
1709
|
+
// user launched themselves) need this. Browsers agents-cli spawns already
|
|
1710
|
+
// carry the --disable-blink-features=AutomationControlled launch flag, which
|
|
1711
|
+
// makes navigator.webdriver a native Navigator.prototype getter returning
|
|
1712
|
+
// false — indistinguishable from an untouched browser. Injecting on top of
|
|
1713
|
+
// that is actively harmful: it defines an OWN getter on the instance, and an
|
|
1714
|
+
// own `webdriver` descriptor (native lives on the prototype) returning
|
|
1715
|
+
// `undefined` (native returns `false`) is itself a tampering signal that
|
|
1716
|
+
// bot.sannysoft.com and similar tests flag as "WebDriver present".
|
|
1717
|
+
//
|
|
1718
|
+
// When we do inject (attach mode), mirror native semantics exactly: define
|
|
1719
|
+
// on Navigator.prototype and return false, so no own descriptor leaks and
|
|
1720
|
+
// the value matches a real browser. Non-page targets (workers, service
|
|
1721
|
+
// workers) reject these calls; swallow the error and keep going.
|
|
1722
|
+
if (conn.pid === 0) {
|
|
1723
|
+
try {
|
|
1724
|
+
await conn.cdp.send('Page.enable', {}, sessionId);
|
|
1725
|
+
await conn.cdp.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
1726
|
+
source: "Object.defineProperty(Navigator.prototype,'webdriver',{get:()=>false,configurable:true});",
|
|
1727
|
+
}, sessionId);
|
|
1728
|
+
}
|
|
1729
|
+
catch {
|
|
1730
|
+
// Target doesn't support Page domain — nothing to inject.
|
|
1731
|
+
}
|
|
1722
1732
|
}
|
|
1723
1733
|
conn.sessionCache.set(tabId, sessionId);
|
|
1724
1734
|
return sessionId;
|
package/dist/lib/shims.js
CHANGED
|
@@ -685,7 +685,10 @@ export function ensureVersionedAliasCurrent(agent, version) {
|
|
|
685
685
|
createVersionedAlias(agent, version);
|
|
686
686
|
return 'created';
|
|
687
687
|
}
|
|
688
|
-
|
|
688
|
+
// Upgrade-only (newest-wins), same rationale as ensureShimCurrent: never
|
|
689
|
+
// downgrade an alias stamped by a newer install sharing the shims dir.
|
|
690
|
+
const onDisk = readVersionedAliasSchemaVersion(agent, version);
|
|
691
|
+
if (onDisk === null || onDisk < VERSIONED_ALIAS_SCHEMA_VERSION) {
|
|
689
692
|
createVersionedAlias(agent, version);
|
|
690
693
|
return 'updated';
|
|
691
694
|
}
|
|
@@ -1278,7 +1281,14 @@ export function ensureShimCurrent(agent) {
|
|
|
1278
1281
|
createShim(agent);
|
|
1279
1282
|
return 'created';
|
|
1280
1283
|
}
|
|
1281
|
-
|
|
1284
|
+
// Upgrade-only (newest-wins): regenerate only when the on-disk shim is
|
|
1285
|
+
// unversioned/unreadable (null) or OLDER than this binary. Never downgrade a
|
|
1286
|
+
// shim stamped by a NEWER agents-cli install. Two installs at different
|
|
1287
|
+
// SHIM_SCHEMA_VERSION sharing ~/.agents/.cache/shims/ (e.g. a dev build on
|
|
1288
|
+
// PATH alongside a Hermes-bundled published copy) otherwise ping-pong —
|
|
1289
|
+
// rewriting every shim on each alternating launch and adding boot latency.
|
|
1290
|
+
const onDisk = readShimSchemaVersion(agent);
|
|
1291
|
+
if (onDisk === null || onDisk < SHIM_SCHEMA_VERSION) {
|
|
1282
1292
|
createShim(agent);
|
|
1283
1293
|
return 'updated';
|
|
1284
1294
|
}
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -247,6 +247,24 @@ export declare function recordVersionResources(_agent: AgentId, _version: string
|
|
|
247
247
|
* Pass all resource types you want to initialize in one call to batch the write.
|
|
248
248
|
*/
|
|
249
249
|
export declare function ensureVersionResourcePatterns(agent: AgentId, version: string, updates: Partial<Record<Exclude<keyof VersionResources, 'rulesPreset'>, ResourcePattern[]>>): void;
|
|
250
|
+
/**
|
|
251
|
+
* Insert `<alias>:*` at the canonical position (after the system/user/other-extra
|
|
252
|
+
* includes, before `project:*`), unless the alias is already referenced — as an
|
|
253
|
+
* include (`alias:...`) or an exclude (`!alias:...`). Returns a new array when it
|
|
254
|
+
* changes, otherwise the same reference (so callers can detect no-ops cheaply).
|
|
255
|
+
*/
|
|
256
|
+
export declare function withAlias(list: ResourcePattern[], alias: string): ResourcePattern[];
|
|
257
|
+
/** Strip every reference to `<alias>:...` / `!<alias>:...` from a selector list. */
|
|
258
|
+
export declare function withoutAlias(list: ResourcePattern[], alias: string): ResourcePattern[];
|
|
259
|
+
/**
|
|
260
|
+
* Backfill (add=true) or strip (add=false) an extra-repo alias across every
|
|
261
|
+
* already-installed version's selectors. New versions get the alias via
|
|
262
|
+
* `defaultPatterns()` at scaffold time; this keeps existing versions in sync
|
|
263
|
+
* when an extra repo is registered/enabled or removed. Only touches selector
|
|
264
|
+
* lists that are already set — an unset list is left for `defaultPatterns()`.
|
|
265
|
+
* Returns the number of (agent, version) pairs changed.
|
|
266
|
+
*/
|
|
267
|
+
export declare function applyExtraAliasToVersions(alias: string, add: boolean): number;
|
|
250
268
|
export declare function getVersionResources(agent: AgentId, version: string): VersionResources | null;
|
|
251
269
|
/** Active rules preset for an agent@version. Defaults to "default" when unset. */
|
|
252
270
|
export declare function getActiveRulesPreset(agent: AgentId, version: string): string;
|
package/dist/lib/state.js
CHANGED
|
@@ -711,6 +711,79 @@ export function ensureVersionResourcePatterns(agent, version, updates) {
|
|
|
711
711
|
if (changed)
|
|
712
712
|
writeMeta(meta);
|
|
713
713
|
}
|
|
714
|
+
/**
|
|
715
|
+
* Resource types that resolve across the extra-repo layer. Mirrors
|
|
716
|
+
* `defaultPatterns()`: extras feed commands/skills/hooks/subagents/plugins/
|
|
717
|
+
* workflows, but never permissions (`system:*`) or mcp (`user:*`).
|
|
718
|
+
*/
|
|
719
|
+
const EXTRA_ELIGIBLE_TYPES = [
|
|
720
|
+
'commands', 'skills', 'hooks', 'subagents', 'plugins', 'workflows',
|
|
721
|
+
];
|
|
722
|
+
/**
|
|
723
|
+
* Insert `<alias>:*` at the canonical position (after the system/user/other-extra
|
|
724
|
+
* includes, before `project:*`), unless the alias is already referenced — as an
|
|
725
|
+
* include (`alias:...`) or an exclude (`!alias:...`). Returns a new array when it
|
|
726
|
+
* changes, otherwise the same reference (so callers can detect no-ops cheaply).
|
|
727
|
+
*/
|
|
728
|
+
export function withAlias(list, alias) {
|
|
729
|
+
const prefix = `${alias}:`;
|
|
730
|
+
if (list.some(p => p === `${alias}:*` || p.startsWith(prefix) || p.startsWith(`!${prefix}`))) {
|
|
731
|
+
return list;
|
|
732
|
+
}
|
|
733
|
+
const next = [...list];
|
|
734
|
+
const projIdx = next.findIndex(p => p === 'project:*' || p.startsWith('project:'));
|
|
735
|
+
if (projIdx >= 0)
|
|
736
|
+
next.splice(projIdx, 0, `${alias}:*`);
|
|
737
|
+
else
|
|
738
|
+
next.push(`${alias}:*`);
|
|
739
|
+
return next;
|
|
740
|
+
}
|
|
741
|
+
/** Strip every reference to `<alias>:...` / `!<alias>:...` from a selector list. */
|
|
742
|
+
export function withoutAlias(list, alias) {
|
|
743
|
+
const prefix = `${alias}:`;
|
|
744
|
+
const next = list.filter(p => !(p.startsWith(prefix) || p.startsWith(`!${prefix}`)));
|
|
745
|
+
return next.length === list.length ? list : next;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Backfill (add=true) or strip (add=false) an extra-repo alias across every
|
|
749
|
+
* already-installed version's selectors. New versions get the alias via
|
|
750
|
+
* `defaultPatterns()` at scaffold time; this keeps existing versions in sync
|
|
751
|
+
* when an extra repo is registered/enabled or removed. Only touches selector
|
|
752
|
+
* lists that are already set — an unset list is left for `defaultPatterns()`.
|
|
753
|
+
* Returns the number of (agent, version) pairs changed.
|
|
754
|
+
*/
|
|
755
|
+
export function applyExtraAliasToVersions(alias, add) {
|
|
756
|
+
const meta = readMeta();
|
|
757
|
+
if (!meta.versions)
|
|
758
|
+
return 0;
|
|
759
|
+
let changed = false;
|
|
760
|
+
let count = 0;
|
|
761
|
+
for (const versions of Object.values(meta.versions)) {
|
|
762
|
+
if (!versions)
|
|
763
|
+
continue;
|
|
764
|
+
for (const vr of Object.values(versions)) {
|
|
765
|
+
if (!vr)
|
|
766
|
+
continue;
|
|
767
|
+
let touched = false;
|
|
768
|
+
for (const type of EXTRA_ELIGIBLE_TYPES) {
|
|
769
|
+
const cur = vr[type];
|
|
770
|
+
if (!Array.isArray(cur) || cur.length === 0)
|
|
771
|
+
continue;
|
|
772
|
+
const next = add ? withAlias(cur, alias) : withoutAlias(cur, alias);
|
|
773
|
+
if (next !== cur) {
|
|
774
|
+
vr[type] = next;
|
|
775
|
+
touched = true;
|
|
776
|
+
changed = true;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (touched)
|
|
780
|
+
count++;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
if (changed)
|
|
784
|
+
writeMeta(meta);
|
|
785
|
+
return count;
|
|
786
|
+
}
|
|
714
787
|
export function getVersionResources(agent, version) {
|
|
715
788
|
const meta = readMeta();
|
|
716
789
|
return meta.versions?.[agent]?.[version] || null;
|
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.15",
|
|
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",
|