@phnx-labs/agents-cli 1.14.7 → 1.16.0
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 +78 -39
- package/README.md +74 -7
- package/dist/commands/alias.js +2 -2
- package/dist/commands/beta.js +6 -1
- package/dist/commands/browser-picker.d.ts +21 -0
- package/dist/commands/browser-picker.js +114 -0
- package/dist/commands/browser.js +546 -75
- package/dist/commands/commands.js +72 -22
- package/dist/commands/daemon.js +2 -2
- package/dist/commands/exec.js +9 -2
- package/dist/commands/fork.js +2 -2
- package/dist/commands/hooks.js +71 -26
- package/dist/commands/mcp.js +85 -43
- package/dist/commands/plugins.js +48 -15
- package/dist/commands/prune.d.ts +0 -20
- package/dist/commands/prune.js +291 -16
- package/dist/commands/pull.js +3 -3
- package/dist/commands/repo.js +1 -1
- package/dist/commands/routines.js +2 -2
- package/dist/commands/secrets.js +37 -1
- package/dist/commands/sessions.js +62 -19
- package/dist/commands/{init.d.ts → setup.d.ts} +7 -6
- package/dist/commands/{init.js → setup.js} +32 -21
- package/dist/commands/skills.js +60 -19
- package/dist/commands/subagents.js +41 -13
- package/dist/commands/teams.js +2 -3
- package/dist/commands/usage.js +6 -0
- package/dist/commands/utils.d.ts +16 -0
- package/dist/commands/utils.js +32 -0
- package/dist/commands/versions.js +8 -6
- package/dist/commands/view.js +61 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -20
- package/dist/lib/agents.js +2 -2
- package/dist/lib/auto-pull-worker.js +2 -3
- package/dist/lib/auto-pull.js +2 -2
- package/dist/lib/browser/cdp.d.ts +7 -1
- package/dist/lib/browser/cdp.js +29 -1
- package/dist/lib/browser/chrome.js +6 -3
- package/dist/lib/browser/devices.d.ts +4 -0
- package/dist/lib/browser/devices.js +27 -0
- package/dist/lib/browser/drivers/local.js +9 -4
- package/dist/lib/browser/drivers/ssh.d.ts +1 -0
- package/dist/lib/browser/drivers/ssh.js +32 -4
- package/dist/lib/browser/ipc.js +145 -23
- package/dist/lib/browser/profiles.d.ts +5 -2
- package/dist/lib/browser/profiles.js +77 -37
- package/dist/lib/browser/service.d.ts +84 -13
- package/dist/lib/browser/service.js +806 -122
- package/dist/lib/browser/types.d.ts +81 -3
- package/dist/lib/browser/types.js +16 -0
- package/dist/lib/cloud/rush.js +2 -2
- package/dist/lib/cloud/store.js +2 -2
- package/dist/lib/commands.d.ts +1 -0
- package/dist/lib/commands.js +6 -2
- package/dist/lib/daemon.js +6 -7
- package/dist/lib/doctor-diff.js +4 -4
- package/dist/lib/events.d.ts +94 -1
- package/dist/lib/events.js +264 -6
- package/dist/lib/exec.js +16 -10
- package/dist/lib/hooks.d.ts +11 -7
- package/dist/lib/hooks.js +125 -49
- package/dist/lib/migrate.d.ts +1 -1
- package/dist/lib/migrate.js +1178 -21
- package/dist/lib/models.js +2 -2
- package/dist/lib/permissions.d.ts +14 -11
- package/dist/lib/permissions.js +46 -42
- package/dist/lib/plugins.d.ts +30 -1
- package/dist/lib/plugins.js +75 -3
- package/dist/lib/pty-server.js +9 -10
- package/dist/lib/resources/hooks.d.ts +5 -1
- package/dist/lib/resources/hooks.js +21 -4
- package/dist/lib/rotate.js +3 -4
- package/dist/lib/routines.d.ts +15 -0
- package/dist/lib/routines.js +68 -0
- package/dist/lib/runner.js +9 -5
- package/dist/lib/secrets/index.d.ts +14 -11
- package/dist/lib/secrets/index.js +49 -21
- package/dist/lib/secrets/linux.d.ts +27 -0
- package/dist/lib/secrets/linux.js +161 -0
- package/dist/lib/session/active.d.ts +3 -0
- package/dist/lib/session/active.js +92 -6
- package/dist/lib/session/cloud.js +2 -2
- package/dist/lib/session/db.d.ts +4 -0
- package/dist/lib/session/db.js +34 -3
- package/dist/lib/session/discover.js +30 -15
- package/dist/lib/session/team-filter.js +2 -2
- package/dist/lib/shims.d.ts +2 -2
- package/dist/lib/shims.js +6 -6
- package/dist/lib/skills.js +6 -2
- package/dist/lib/state.d.ts +86 -14
- package/dist/lib/state.js +150 -23
- package/dist/lib/subagents.d.ts +28 -0
- package/dist/lib/subagents.js +98 -1
- package/dist/lib/sync-manifest.d.ts +1 -1
- package/dist/lib/sync-manifest.js +3 -3
- package/dist/lib/teams/persistence.js +15 -5
- package/dist/lib/teams/registry.js +2 -2
- package/dist/lib/types.d.ts +32 -3
- package/dist/lib/types.js +3 -3
- package/dist/lib/usage.d.ts +1 -1
- package/dist/lib/usage.js +15 -48
- package/dist/lib/versions.js +31 -21
- package/package.json +1 -1
- package/scripts/postinstall.js +37 -9
package/dist/lib/hooks.js
CHANGED
|
@@ -14,8 +14,42 @@ import * as TOML from 'smol-toml';
|
|
|
14
14
|
import { AGENTS, HOOKS_CAPABLE_AGENTS } from './agents.js';
|
|
15
15
|
import { supports, explainSkip } from './capabilities.js';
|
|
16
16
|
import { setGeminiAutoUpdateDisabled, updateGeminiSettings } from './gemini-settings.js';
|
|
17
|
-
import {
|
|
17
|
+
import { getHooksDir as getSystemHooksDir, getUserHooksDir, getUserAgentsDir, getSystemAgentsDir, getProjectAgentsDir, getTrashHooksDir } from './state.js';
|
|
18
18
|
function getCentralHooksDir() { return getUserHooksDir(); }
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a hook script's absolute path by checking the user dir first
|
|
21
|
+
* (where `installHooksCentrally` lands new files) and falling back to the
|
|
22
|
+
* system dir (where npm-shipped defaults live). Returns null if neither
|
|
23
|
+
* exists. Mirrors the precedence used by `listCentralHooks`.
|
|
24
|
+
*/
|
|
25
|
+
function resolveHookScriptPath(script) {
|
|
26
|
+
for (const root of [getUserAgentsDir(), getSystemAgentsDir()]) {
|
|
27
|
+
const candidate = path.join(root, 'hooks', script);
|
|
28
|
+
if (fs.existsSync(candidate))
|
|
29
|
+
return candidate;
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Prefixes used for stale-entry cleanup in agent settings files. A registered
|
|
35
|
+
* hook command is considered "managed by us" if it lives under either
|
|
36
|
+
* `~/.agents/hooks/` (user) or `~/.agents-system/hooks/` (system). Cleanup
|
|
37
|
+
* filters use this list so leftover entries from either dir get garbage
|
|
38
|
+
* collected on rewrite.
|
|
39
|
+
*/
|
|
40
|
+
function getManagedHookPrefixes() {
|
|
41
|
+
return [
|
|
42
|
+
path.join(getUserAgentsDir(), 'hooks') + path.sep,
|
|
43
|
+
path.join(getSystemAgentsDir(), 'hooks') + path.sep,
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
function isManagedHookCommand(command, prefixes) {
|
|
47
|
+
for (const prefix of prefixes) {
|
|
48
|
+
if (command.startsWith(prefix))
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
19
53
|
import { getEffectiveHome, getVersionHomePath, listInstalledVersions } from './versions.js';
|
|
20
54
|
const SCRIPT_EXTENSIONS = new Set([
|
|
21
55
|
'.sh',
|
|
@@ -366,10 +400,32 @@ export function installHookToVersion(agent, version, hookName) {
|
|
|
366
400
|
}
|
|
367
401
|
/**
|
|
368
402
|
* Remove a single hook (script + data file) from a specific version home.
|
|
403
|
+
* Soft-deletes to ~/.agents/.trash/hooks/.
|
|
369
404
|
*/
|
|
370
405
|
export function removeHookFromVersion(agent, version, hookName) {
|
|
371
406
|
try {
|
|
372
|
-
|
|
407
|
+
const hooksDir = getVersionHooksDir(agent, version);
|
|
408
|
+
if (!fs.existsSync(hooksDir))
|
|
409
|
+
return { success: true };
|
|
410
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
411
|
+
const trashDir = path.join(getTrashHooksDir(), agent, version, hookName, stamp);
|
|
412
|
+
let moved = false;
|
|
413
|
+
const files = fs.readdirSync(hooksDir);
|
|
414
|
+
for (const file of files) {
|
|
415
|
+
const ext = path.extname(file);
|
|
416
|
+
const base = path.basename(file, ext);
|
|
417
|
+
if (base === hookName) {
|
|
418
|
+
const fullPath = path.join(hooksDir, file);
|
|
419
|
+
const stat = fs.statSync(fullPath);
|
|
420
|
+
if (stat.isFile()) {
|
|
421
|
+
if (!moved) {
|
|
422
|
+
fs.mkdirSync(trashDir, { recursive: true, mode: 0o700 });
|
|
423
|
+
moved = true;
|
|
424
|
+
}
|
|
425
|
+
fs.renameSync(fullPath, path.join(trashDir, file));
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
373
429
|
}
|
|
374
430
|
catch (err) {
|
|
375
431
|
return { success: false, error: err.message };
|
|
@@ -502,32 +558,37 @@ export function listCentralHooks() {
|
|
|
502
558
|
return results;
|
|
503
559
|
}
|
|
504
560
|
/**
|
|
505
|
-
* Parse
|
|
506
|
-
* and user
|
|
507
|
-
*
|
|
508
|
-
*
|
|
561
|
+
* Parse hook manifests. Reads system hooks from ~/.agents-system/hooks.yaml
|
|
562
|
+
* (npm-shipped defaults) and user hooks from the `hooks:` section of
|
|
563
|
+
* ~/.agents/agents.yaml. Merges with user-wins-on-key-collision precedence.
|
|
564
|
+
* A user entry with `enabled: false` disables the system-shipped hook of
|
|
565
|
+
* the same name without forking the system file.
|
|
509
566
|
*
|
|
510
567
|
* Hooks marked `enabled: false` are dropped from the returned map.
|
|
511
568
|
*/
|
|
512
569
|
export function parseHookManifest() {
|
|
513
570
|
const merged = {};
|
|
514
|
-
// System
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
if (!fs.existsSync(manifestPath))
|
|
518
|
-
continue;
|
|
571
|
+
// System layer: hooks: section of agents.yaml (npm-shipped, separate repo).
|
|
572
|
+
const systemPath = path.join(getSystemAgentsDir(), 'agents.yaml');
|
|
573
|
+
if (fs.existsSync(systemPath)) {
|
|
519
574
|
try {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
for (const [name, def] of Object.entries(parsed)) {
|
|
525
|
-
merged[name] = def;
|
|
526
|
-
}
|
|
575
|
+
const meta = yaml.parse(fs.readFileSync(systemPath, 'utf-8'));
|
|
576
|
+
if (meta?.hooks)
|
|
577
|
+
for (const [name, def] of Object.entries(meta.hooks))
|
|
578
|
+
merged[name] = def;
|
|
527
579
|
}
|
|
528
|
-
catch {
|
|
529
|
-
|
|
580
|
+
catch { /* skip unreadable manifest */ }
|
|
581
|
+
}
|
|
582
|
+
// User layer: hooks: section of agents.yaml.
|
|
583
|
+
const userMetaPath = path.join(getUserAgentsDir(), 'agents.yaml');
|
|
584
|
+
if (fs.existsSync(userMetaPath)) {
|
|
585
|
+
try {
|
|
586
|
+
const meta = yaml.parse(fs.readFileSync(userMetaPath, 'utf-8'));
|
|
587
|
+
if (meta?.hooks)
|
|
588
|
+
for (const [name, def] of Object.entries(meta.hooks))
|
|
589
|
+
merged[name] = def;
|
|
530
590
|
}
|
|
591
|
+
catch { /* skip unreadable meta */ }
|
|
531
592
|
}
|
|
532
593
|
// Strip disabled hooks so they never reach the registrar.
|
|
533
594
|
for (const [name, def] of Object.entries(merged)) {
|
|
@@ -542,25 +603,37 @@ const CODEX_MATCHER_EVENTS = new Set(['PreToolUse', 'PostToolUse', 'SessionStart
|
|
|
542
603
|
/**
|
|
543
604
|
* Register hooks as lifecycle events in an agent's config.
|
|
544
605
|
* Reads hooks.yaml manifest, merges into the agent's config file(s).
|
|
545
|
-
* Only manages hooks whose command paths are under ~/.agents/hooks
|
|
546
|
-
* Does not remove user-added hooks.
|
|
606
|
+
* Only manages hooks whose command paths are under ~/.agents/hooks/ or
|
|
607
|
+
* ~/.agents-system/hooks/. Does not remove user-added hooks.
|
|
547
608
|
*
|
|
548
|
-
* @param agentsDirOverride -
|
|
609
|
+
* @param agentsDirOverride - When provided, treats this single dir as the
|
|
610
|
+
* only managed hook root. Used by tests to inject a temp path. In normal
|
|
611
|
+
* operation, both user and system roots are consulted with user precedence.
|
|
549
612
|
*/
|
|
550
613
|
export function registerHooksToSettings(agentId, versionHome, hookManifest, agentsDirOverride) {
|
|
551
614
|
const manifest = hookManifest || parseHookManifest();
|
|
552
615
|
if (Object.keys(manifest).length === 0) {
|
|
553
616
|
return { registered: [], errors: [] };
|
|
554
617
|
}
|
|
555
|
-
const
|
|
618
|
+
const overrideRoots = agentsDirOverride ? [agentsDirOverride] : null;
|
|
619
|
+
const resolveScript = (script) => {
|
|
620
|
+
if (overrideRoots) {
|
|
621
|
+
const candidate = path.join(overrideRoots[0], 'hooks', script);
|
|
622
|
+
return fs.existsSync(candidate) ? candidate : null;
|
|
623
|
+
}
|
|
624
|
+
return resolveHookScriptPath(script);
|
|
625
|
+
};
|
|
626
|
+
const managedPrefixes = overrideRoots
|
|
627
|
+
? [path.join(overrideRoots[0], 'hooks') + path.sep]
|
|
628
|
+
: getManagedHookPrefixes();
|
|
556
629
|
if (agentId === 'claude') {
|
|
557
|
-
return registerHooksForClaude(versionHome, manifest,
|
|
630
|
+
return registerHooksForClaude(versionHome, manifest, resolveScript, managedPrefixes);
|
|
558
631
|
}
|
|
559
632
|
if (agentId === 'codex') {
|
|
560
|
-
return registerHooksForCodex(versionHome, manifest,
|
|
633
|
+
return registerHooksForCodex(versionHome, manifest, resolveScript, managedPrefixes);
|
|
561
634
|
}
|
|
562
635
|
if (agentId === 'gemini') {
|
|
563
|
-
return registerHooksForGemini(versionHome, manifest,
|
|
636
|
+
return registerHooksForGemini(versionHome, manifest, resolveScript, managedPrefixes);
|
|
564
637
|
}
|
|
565
638
|
return { registered: [], errors: [] };
|
|
566
639
|
}
|
|
@@ -574,7 +647,7 @@ export function registerHooksToSettings(agentId, versionHome, hookManifest, agen
|
|
|
574
647
|
const GEMINI_EVENT_MAP = {
|
|
575
648
|
UserPromptSubmit: 'BeforeAgent',
|
|
576
649
|
};
|
|
577
|
-
function registerHooksForClaude(versionHome, manifest,
|
|
650
|
+
function registerHooksForClaude(versionHome, manifest, resolveScript, managedPrefixes) {
|
|
578
651
|
const registered = [];
|
|
579
652
|
const errors = [];
|
|
580
653
|
const configDir = path.join(versionHome, '.claude');
|
|
@@ -595,14 +668,15 @@ function registerHooksForClaude(versionHome, manifest, agentsDir) {
|
|
|
595
668
|
const hooks = config.hooks;
|
|
596
669
|
// Build set of all command paths the current manifest will register.
|
|
597
670
|
// Used to garbage-collect stale entries left behind after hook renames.
|
|
598
|
-
const managedHooksPrefix = path.join(agentsDir, 'hooks') + path.sep;
|
|
599
671
|
const currentManifestPaths = new Set();
|
|
600
672
|
for (const hookDef of Object.values(manifest)) {
|
|
601
673
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
602
674
|
continue;
|
|
603
|
-
|
|
675
|
+
const resolved = resolveScript(hookDef.script);
|
|
676
|
+
if (resolved)
|
|
677
|
+
currentManifestPaths.add(resolved);
|
|
604
678
|
}
|
|
605
|
-
// Remove stale entries: any hook command under
|
|
679
|
+
// Remove stale entries: any hook command under a managed root that isn't
|
|
606
680
|
// in the current manifest is a leftover from a renamed/deleted hook script.
|
|
607
681
|
for (const eventEntries of Object.values(hooks)) {
|
|
608
682
|
if (!Array.isArray(eventEntries))
|
|
@@ -610,7 +684,7 @@ function registerHooksForClaude(versionHome, manifest, agentsDir) {
|
|
|
610
684
|
for (const group of eventEntries) {
|
|
611
685
|
if (!group.hooks)
|
|
612
686
|
continue;
|
|
613
|
-
group.hooks = group.hooks.filter((h) => !h.command
|
|
687
|
+
group.hooks = group.hooks.filter((h) => !isManagedHookCommand(h.command, managedPrefixes) || currentManifestPaths.has(h.command));
|
|
614
688
|
}
|
|
615
689
|
}
|
|
616
690
|
// Remove empty matcher groups left after cleanup
|
|
@@ -622,9 +696,9 @@ function registerHooksForClaude(versionHome, manifest, agentsDir) {
|
|
|
622
696
|
for (const [name, hookDef] of Object.entries(manifest)) {
|
|
623
697
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
624
698
|
continue;
|
|
625
|
-
const commandPath =
|
|
626
|
-
if (!
|
|
627
|
-
errors.push(`${name}: script not found
|
|
699
|
+
const commandPath = resolveScript(hookDef.script);
|
|
700
|
+
if (!commandPath) {
|
|
701
|
+
errors.push(`${name}: script not found in user or system hooks dir`);
|
|
628
702
|
continue;
|
|
629
703
|
}
|
|
630
704
|
for (const event of hookDef.events) {
|
|
@@ -662,7 +736,7 @@ function registerHooksForClaude(versionHome, manifest, agentsDir) {
|
|
|
662
736
|
}
|
|
663
737
|
return { registered, errors };
|
|
664
738
|
}
|
|
665
|
-
function registerHooksForCodex(versionHome, manifest,
|
|
739
|
+
function registerHooksForCodex(versionHome, manifest, resolveScript, managedPrefixes) {
|
|
666
740
|
const registered = [];
|
|
667
741
|
const errors = [];
|
|
668
742
|
const configDir = path.join(versionHome, '.codex');
|
|
@@ -687,19 +761,20 @@ function registerHooksForCodex(versionHome, manifest, agentsDir) {
|
|
|
687
761
|
}
|
|
688
762
|
}
|
|
689
763
|
// Build set of current manifest command paths for codex to GC stale entries
|
|
690
|
-
const managedHooksPrefix = path.join(agentsDir, 'hooks') + path.sep;
|
|
691
764
|
const currentManifestPaths = new Set();
|
|
692
765
|
for (const hookDef of Object.values(manifest)) {
|
|
693
766
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
694
767
|
continue;
|
|
695
|
-
|
|
768
|
+
const resolved = resolveScript(hookDef.script);
|
|
769
|
+
if (resolved)
|
|
770
|
+
currentManifestPaths.add(resolved);
|
|
696
771
|
}
|
|
697
772
|
// Remove stale entries from all event groups
|
|
698
773
|
for (const eventGroups of Object.values(hooksFile.hooks)) {
|
|
699
774
|
for (const group of eventGroups) {
|
|
700
775
|
if (!group.hooks)
|
|
701
776
|
continue;
|
|
702
|
-
group.hooks = group.hooks.filter((h) => !h.command
|
|
777
|
+
group.hooks = group.hooks.filter((h) => !isManagedHookCommand(h.command, managedPrefixes) || currentManifestPaths.has(h.command));
|
|
703
778
|
}
|
|
704
779
|
}
|
|
705
780
|
for (const [event, eventGroups] of Object.entries(hooksFile.hooks)) {
|
|
@@ -708,9 +783,9 @@ function registerHooksForCodex(versionHome, manifest, agentsDir) {
|
|
|
708
783
|
for (const [name, hookDef] of Object.entries(manifest)) {
|
|
709
784
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
710
785
|
continue;
|
|
711
|
-
const commandPath =
|
|
712
|
-
if (!
|
|
713
|
-
errors.push(`${name}: script not found
|
|
786
|
+
const commandPath = resolveScript(hookDef.script);
|
|
787
|
+
if (!commandPath) {
|
|
788
|
+
errors.push(`${name}: script not found in user or system hooks dir`);
|
|
714
789
|
continue;
|
|
715
790
|
}
|
|
716
791
|
const timeout = hookDef.timeout || 600;
|
|
@@ -784,7 +859,7 @@ function registerHooksForCodex(versionHome, manifest, agentsDir) {
|
|
|
784
859
|
}
|
|
785
860
|
return { registered, errors };
|
|
786
861
|
}
|
|
787
|
-
function registerHooksForGemini(versionHome, manifest,
|
|
862
|
+
function registerHooksForGemini(versionHome, manifest, resolveScript, managedPrefixes) {
|
|
788
863
|
const registered = [];
|
|
789
864
|
const errors = [];
|
|
790
865
|
const settingsPath = path.join(versionHome, '.gemini', 'settings.json');
|
|
@@ -795,12 +870,13 @@ function registerHooksForGemini(versionHome, manifest, agentsDir) {
|
|
|
795
870
|
config.hooks = {};
|
|
796
871
|
}
|
|
797
872
|
const hooks = config.hooks;
|
|
798
|
-
const managedHooksPrefix = path.join(agentsDir, 'hooks') + path.sep;
|
|
799
873
|
const currentManifestPaths = new Set();
|
|
800
874
|
for (const hookDef of Object.values(manifest)) {
|
|
801
875
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
802
876
|
continue;
|
|
803
|
-
|
|
877
|
+
const resolved = resolveScript(hookDef.script);
|
|
878
|
+
if (resolved)
|
|
879
|
+
currentManifestPaths.add(resolved);
|
|
804
880
|
}
|
|
805
881
|
for (const eventEntries of Object.values(hooks)) {
|
|
806
882
|
if (!Array.isArray(eventEntries))
|
|
@@ -808,7 +884,7 @@ function registerHooksForGemini(versionHome, manifest, agentsDir) {
|
|
|
808
884
|
for (const group of eventEntries) {
|
|
809
885
|
if (!group.hooks)
|
|
810
886
|
continue;
|
|
811
|
-
group.hooks = group.hooks.filter((h) => !h.command
|
|
887
|
+
group.hooks = group.hooks.filter((h) => !isManagedHookCommand(h.command, managedPrefixes) || currentManifestPaths.has(h.command));
|
|
812
888
|
}
|
|
813
889
|
}
|
|
814
890
|
for (const [event, eventEntries] of Object.entries(hooks)) {
|
|
@@ -819,9 +895,9 @@ function registerHooksForGemini(versionHome, manifest, agentsDir) {
|
|
|
819
895
|
for (const [name, hookDef] of Object.entries(manifest)) {
|
|
820
896
|
if (!hookDef.events || hookDef.events.length === 0)
|
|
821
897
|
continue;
|
|
822
|
-
const commandPath =
|
|
823
|
-
if (!
|
|
824
|
-
errors.push(`${name}: script not found
|
|
898
|
+
const commandPath = resolveScript(hookDef.script);
|
|
899
|
+
if (!commandPath) {
|
|
900
|
+
errors.push(`${name}: script not found in user or system hooks dir`);
|
|
825
901
|
continue;
|
|
826
902
|
}
|
|
827
903
|
const timeoutMs = (hookDef.timeout || 600) * 1000;
|
package/dist/lib/migrate.d.ts
CHANGED