@phnx-labs/agents-cli 1.20.72 → 1.20.74
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 +395 -0
- package/README.md +40 -4
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +12 -0
- package/dist/commands/activity.js +68 -0
- package/dist/commands/apply.d.ts +13 -0
- package/dist/commands/apply.js +28 -3
- package/dist/commands/browser.js +1 -1
- package/dist/commands/cloud.js +21 -11
- package/dist/commands/doctor.js +21 -5
- package/dist/commands/events.d.ts +11 -10
- package/dist/commands/events.js +30 -21
- package/dist/commands/exec.d.ts +34 -0
- package/dist/commands/exec.js +337 -39
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.js +215 -0
- package/dist/commands/feed.d.ts +13 -0
- package/dist/commands/feed.js +130 -29
- package/dist/commands/hq.d.ts +2 -0
- package/dist/commands/hq.js +58 -0
- package/dist/commands/import.js +51 -3
- package/dist/commands/lease.d.ts +19 -0
- package/dist/commands/lease.js +138 -11
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/mine.d.ts +27 -0
- package/dist/commands/mine.js +207 -0
- package/dist/commands/monitors.js +79 -49
- package/dist/commands/plugins.js +1 -0
- package/dist/commands/profiles.js +158 -0
- package/dist/commands/repo.js +2 -60
- package/dist/commands/resources.d.ts +5 -0
- package/dist/commands/resources.js +95 -0
- package/dist/commands/routines.d.ts +2 -0
- package/dist/commands/routines.js +139 -37
- package/dist/commands/secrets.js +234 -47
- package/dist/commands/send.d.ts +15 -0
- package/dist/commands/send.js +62 -0
- package/dist/commands/sessions-tail.d.ts +1 -0
- package/dist/commands/sessions-tail.js +20 -9
- package/dist/commands/sessions.js +18 -3
- package/dist/commands/setup-mine.d.ts +18 -0
- package/dist/commands/setup-mine.js +106 -0
- package/dist/commands/setup-share.js +2 -2
- package/dist/commands/setup.js +9 -2
- package/dist/commands/share.d.ts +8 -1
- package/dist/commands/share.js +122 -37
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +196 -26
- package/dist/commands/sync.js +1 -1
- package/dist/commands/teams.js +11 -2
- package/dist/commands/versions.js +36 -5
- package/dist/commands/view.js +75 -27
- package/dist/index.js +80 -10
- package/dist/lib/activity.d.ts +124 -0
- package/dist/lib/activity.js +542 -0
- package/dist/lib/agents.d.ts +35 -0
- package/dist/lib/agents.js +79 -6
- package/dist/lib/artifact-actions.d.ts +1 -1
- package/dist/lib/artifact-actions.js +1 -1
- package/dist/lib/ask-classifier.d.ts +2 -1
- package/dist/lib/ask-classifier.js +3 -3
- package/dist/lib/auth-health.d.ts +32 -4
- package/dist/lib/auth-health.js +40 -1
- package/dist/lib/auto-pull.js +8 -1
- package/dist/lib/brand.d.ts +40 -0
- package/dist/lib/brand.js +122 -0
- package/dist/lib/browser/drivers/ssh.js +4 -7
- package/dist/lib/browser/service.js +6 -8
- package/dist/lib/channels/providers/index.d.ts +2 -0
- package/dist/lib/channels/providers/index.js +20 -0
- package/dist/lib/channels/providers/mailbox.d.ts +2 -0
- package/dist/lib/channels/providers/mailbox.js +26 -0
- package/dist/lib/channels/providers/openclaw-telegram.d.ts +2 -0
- package/dist/lib/channels/providers/openclaw-telegram.js +34 -0
- package/dist/lib/channels/providers/rush.d.ts +6 -0
- package/dist/lib/channels/providers/rush.js +55 -0
- package/dist/lib/channels/registry.d.ts +42 -0
- package/dist/lib/channels/registry.js +20 -0
- package/dist/lib/channels/resolve.d.ts +11 -0
- package/dist/lib/channels/resolve.js +12 -0
- package/dist/lib/cli-resources.d.ts +18 -0
- package/dist/lib/cli-resources.js +53 -4
- package/dist/lib/cloud/codex.js +6 -3
- package/dist/lib/cloud/factory.d.ts +1 -0
- package/dist/lib/cloud/factory.js +10 -4
- package/dist/lib/cloud/rush.d.ts +3 -1
- package/dist/lib/cloud/rush.js +6 -1
- package/dist/lib/cloud/types.d.ts +2 -0
- package/dist/lib/codex-home.d.ts +35 -0
- package/dist/lib/codex-home.js +136 -0
- package/dist/lib/config-transfer.d.ts +16 -0
- package/dist/lib/config-transfer.js +56 -0
- package/dist/lib/crabbox/cli.d.ts +44 -0
- package/dist/lib/crabbox/cli.js +120 -20
- package/dist/lib/crabbox/lease.d.ts +52 -1
- package/dist/lib/crabbox/lease.js +117 -16
- package/dist/lib/crabbox/progress.d.ts +31 -0
- package/dist/lib/crabbox/progress.js +76 -0
- package/dist/lib/crabbox/runtimes.d.ts +4 -0
- package/dist/lib/crabbox/runtimes.js +33 -8
- package/dist/lib/crabbox/setup-copy.d.ts +87 -0
- package/dist/lib/crabbox/setup-copy.js +127 -0
- package/dist/lib/daemon.d.ts +5 -5
- package/dist/lib/daemon.js +9 -9
- package/dist/lib/drive-sync.js +6 -3
- package/dist/lib/event-stream.d.ts +36 -0
- package/dist/lib/event-stream.js +68 -0
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/exec.d.ts +11 -0
- package/dist/lib/exec.js +23 -2
- package/dist/lib/export.d.ts +72 -0
- package/dist/lib/export.js +269 -0
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +14 -9
- package/dist/lib/feed-ranking.d.ts +32 -0
- package/dist/lib/feed-ranking.js +224 -0
- package/dist/lib/feed.d.ts +35 -2
- package/dist/lib/feed.js +66 -3
- package/dist/lib/fleet/auth-sync.d.ts +53 -0
- package/dist/lib/fleet/auth-sync.js +92 -0
- package/dist/lib/fleet/remote-login.d.ts +187 -0
- package/dist/lib/fleet/remote-login.js +556 -0
- package/dist/lib/format.d.ts +30 -3
- package/dist/lib/format.js +34 -5
- package/dist/lib/fs-atomic.d.ts +7 -2
- package/dist/lib/fs-atomic.js +8 -12
- package/dist/lib/git.d.ts +16 -0
- package/dist/lib/git.js +79 -2
- package/dist/lib/heal.js +11 -3
- package/dist/lib/hosts/progress.d.ts +28 -10
- package/dist/lib/hosts/progress.js +79 -22
- package/dist/lib/hosts/remote-cmd.js +4 -0
- package/dist/lib/hq/floor.d.ts +87 -0
- package/dist/lib/hq/floor.js +226 -0
- package/dist/lib/import.d.ts +23 -0
- package/dist/lib/import.js +74 -2
- package/dist/lib/isolation-boundary-report.d.ts +10 -0
- package/dist/lib/isolation-boundary-report.js +35 -0
- package/dist/lib/menubar/install-menubar.js +14 -20
- package/dist/lib/notify.d.ts +1 -0
- package/dist/lib/notify.js +3 -3
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.js +19 -0
- package/dist/lib/openclaw-keychain.d.ts +56 -0
- package/dist/lib/openclaw-keychain.js +236 -0
- package/dist/lib/overdue.js +10 -0
- package/dist/lib/permissions.d.ts +44 -1
- package/dist/lib/permissions.js +284 -7
- package/dist/lib/project-launch.d.ts +6 -12
- package/dist/lib/project-launch.js +13 -228
- package/dist/lib/project-resources.d.ts +7 -0
- package/dist/lib/project-resources.js +306 -0
- package/dist/lib/pty-client.d.ts +27 -0
- package/dist/lib/pty-client.js +136 -10
- package/dist/lib/refresh.js +14 -10
- package/dist/lib/resource-profiles.d.ts +26 -0
- package/dist/lib/resource-profiles.js +157 -0
- package/dist/lib/resources/permissions.js +7 -1
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +1 -1
- package/dist/lib/resources.js +32 -3
- package/dist/lib/routines.d.ts +11 -0
- package/dist/lib/routines.js +56 -15
- package/dist/lib/runner.d.ts +1 -0
- package/dist/lib/runner.js +66 -5
- package/dist/lib/secrets/bundles.d.ts +16 -3
- package/dist/lib/secrets/bundles.js +206 -37
- package/dist/lib/secrets/icloud-import.d.ts +2 -2
- package/dist/lib/secrets/icloud-import.js +9 -6
- package/dist/lib/secrets/mcp.js +1 -1
- package/dist/lib/secrets/vault-age-helper.d.ts +1 -0
- package/dist/lib/secrets/vault-age-helper.js +34 -0
- package/dist/lib/secrets/vault.d.ts +49 -0
- package/dist/lib/secrets/vault.js +397 -0
- package/dist/lib/self-heal/checks/path.js +3 -1
- package/dist/lib/self-heal/checks/shadowing.js +10 -2
- package/dist/lib/self-heal/checks/shims.js +19 -11
- package/dist/lib/session/cloud.d.ts +2 -2
- package/dist/lib/session/cloud.js +2 -2
- package/dist/lib/session/db.d.ts +4 -0
- package/dist/lib/session/db.js +44 -7
- package/dist/lib/session/discover.d.ts +2 -0
- package/dist/lib/session/discover.js +114 -3
- package/dist/lib/session/stream-render.d.ts +3 -0
- package/dist/lib/session/stream-render.js +130 -0
- package/dist/lib/session/types.d.ts +6 -0
- package/dist/lib/share/analytics.d.ts +13 -0
- package/dist/lib/share/analytics.js +45 -0
- package/dist/lib/share/config.d.ts +19 -5
- package/dist/lib/share/config.js +44 -8
- package/dist/lib/share/provision.d.ts +58 -6
- package/dist/lib/share/provision.js +97 -22
- package/dist/lib/share/publish.d.ts +36 -13
- package/dist/lib/share/publish.js +55 -8
- package/dist/lib/share/worker-template.js +83 -17
- package/dist/lib/shims.d.ts +35 -0
- package/dist/lib/shims.js +159 -13
- package/dist/lib/ssh-exec.d.ts +14 -0
- package/dist/lib/ssh-exec.js +57 -0
- package/dist/lib/staleness/detectors/hooks.js +25 -1
- package/dist/lib/staleness/detectors/permissions.js +66 -0
- package/dist/lib/staleness/detectors/workflows.js +20 -0
- package/dist/lib/staleness/writers/hooks.js +58 -4
- package/dist/lib/staleness/writers/permissions.js +2 -2
- package/dist/lib/staleness/writers/skills.js +1 -1
- package/dist/lib/staleness/writers/sources.d.ts +10 -1
- package/dist/lib/staleness/writers/sources.js +68 -1
- package/dist/lib/star-nudge.d.ts +45 -0
- package/dist/lib/star-nudge.js +91 -0
- package/dist/lib/startup/command-registry.d.ts +7 -1
- package/dist/lib/startup/command-registry.js +19 -3
- package/dist/lib/state.d.ts +2 -0
- package/dist/lib/state.js +17 -4
- package/dist/lib/subagents-registry.d.ts +2 -0
- package/dist/lib/subagents-registry.js +3 -0
- package/dist/lib/teams/parsers.js +214 -6
- package/dist/lib/teams/supervisor.d.ts +7 -0
- package/dist/lib/teams/supervisor.js +2 -1
- package/dist/lib/template.d.ts +1 -1
- package/dist/lib/template.js +1 -1
- package/dist/lib/triggers/webhook.js +36 -3
- package/dist/lib/types.d.ts +84 -0
- package/dist/lib/uninstall.js +1 -45
- package/dist/lib/version.d.ts +40 -0
- package/dist/lib/version.js +94 -16
- package/dist/lib/versions.d.ts +24 -0
- package/dist/lib/versions.js +269 -78
- package/dist/lib/workflows.d.ts +2 -0
- package/dist/lib/workflows.js +88 -0
- package/package.json +2 -1
- package/dist/commands/daemon.d.ts +0 -10
- package/dist/commands/daemon.js +0 -121
|
@@ -35,6 +35,50 @@ function isLiveDir(p) {
|
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
function readPluginManifest(pluginRoot) {
|
|
39
|
+
const manifestPath = path.join(pluginRoot, '.claude-plugin', 'plugin.json');
|
|
40
|
+
if (!isLiveFile(manifestPath))
|
|
41
|
+
return null;
|
|
42
|
+
try {
|
|
43
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
44
|
+
if (!manifest.name || !manifest.version)
|
|
45
|
+
return null;
|
|
46
|
+
return manifest;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function pluginSupportsAgent(manifest, agent) {
|
|
53
|
+
if (!agent)
|
|
54
|
+
return true;
|
|
55
|
+
return !manifest.agents || manifest.agents.length === 0 || manifest.agents.includes(agent);
|
|
56
|
+
}
|
|
57
|
+
function pluginSkillDirs(options = {}) {
|
|
58
|
+
const dirs = [];
|
|
59
|
+
for (const base of trustedSourceBases()) {
|
|
60
|
+
const pluginsDir = path.join(base.dir, 'plugins');
|
|
61
|
+
let entries;
|
|
62
|
+
try {
|
|
63
|
+
entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
if (!entry.isDirectory() || entry.name.startsWith('.'))
|
|
70
|
+
continue;
|
|
71
|
+
if (options.plugins && !options.plugins.has(entry.name))
|
|
72
|
+
continue;
|
|
73
|
+
const pluginRoot = path.join(pluginsDir, entry.name);
|
|
74
|
+
const manifest = readPluginManifest(pluginRoot);
|
|
75
|
+
if (!manifest || !pluginSupportsAgent(manifest, options.agent))
|
|
76
|
+
continue;
|
|
77
|
+
dirs.push(path.join(pluginRoot, 'skills'));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return dirs;
|
|
81
|
+
}
|
|
38
82
|
/** Find the trusted source for a command markdown by name. */
|
|
39
83
|
export function resolveCommandSource(name) {
|
|
40
84
|
const candidates = [
|
|
@@ -45,14 +89,36 @@ export function resolveCommandSource(name) {
|
|
|
45
89
|
return candidates.find(isLiveFile) ?? null;
|
|
46
90
|
}
|
|
47
91
|
/** Find the trusted source directory for a skill by name. */
|
|
48
|
-
export function resolveSkillSource(name) {
|
|
92
|
+
export function resolveSkillSource(name, options = {}) {
|
|
49
93
|
const candidates = [
|
|
50
94
|
safeJoin(path.join(getUserAgentsDir(), 'skills'), name),
|
|
51
95
|
safeJoin(getSkillsDir(), name),
|
|
52
96
|
...getEnabledExtraRepos().map((e) => safeJoin(path.join(e.dir, 'skills'), name)),
|
|
97
|
+
...pluginSkillDirs(options).map((skillsDir) => safeJoin(skillsDir, name)),
|
|
53
98
|
];
|
|
54
99
|
return candidates.find(isLiveDir) ?? null;
|
|
55
100
|
}
|
|
101
|
+
/** List trusted plugin-bundled skill names, filtered to an optional plugin/agent scope. */
|
|
102
|
+
export function listPluginSkillNames(options = {}) {
|
|
103
|
+
const names = new Set();
|
|
104
|
+
for (const skillsDir of pluginSkillDirs(options)) {
|
|
105
|
+
let entries;
|
|
106
|
+
try {
|
|
107
|
+
entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
if (!entry.isDirectory() || entry.name.startsWith('.'))
|
|
114
|
+
continue;
|
|
115
|
+
if (isLiveFile(path.join(skillsDir, entry.name, 'SKILL.md'))) {
|
|
116
|
+
names.add(entry.name);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Array.from(names);
|
|
121
|
+
}
|
|
56
122
|
/** Find the trusted source file for a hook by name. */
|
|
57
123
|
export function resolveHookSource(name) {
|
|
58
124
|
const candidates = [
|
|
@@ -68,5 +134,6 @@ export function trustedSkillRoots() {
|
|
|
68
134
|
path.join(getUserAgentsDir(), 'skills'),
|
|
69
135
|
getSkillsDir(),
|
|
70
136
|
...getEnabledExtraRepos().map((e) => path.join(e.dir, 'skills')),
|
|
137
|
+
...pluginSkillDirs(),
|
|
71
138
|
];
|
|
72
139
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-time "star us on GitHub" nudge.
|
|
3
|
+
*
|
|
4
|
+
* Printed a single time, ever, after a user's first *successful* headline run
|
|
5
|
+
* (`agents run` / `agents teams`). Modelled on the existing warn-once sentinel
|
|
6
|
+
* pattern (see maybeWarnMultiInstall in src/index.ts): a marker under the
|
|
7
|
+
* regenerable runtime-state dir records that the hint was shown so it never
|
|
8
|
+
* repeats. It is a plain inline line — not a toast, not a nag — and stays out
|
|
9
|
+
* of the way of non-interactive, CI, quiet, and JSON output.
|
|
10
|
+
*/
|
|
11
|
+
/** Canonical GitHub repo the nudge points at. */
|
|
12
|
+
export declare const REPO_URL = "https://github.com/phnx-labs/agents-cli";
|
|
13
|
+
/** Has the star nudge already been shown on this machine? */
|
|
14
|
+
export declare function hasShownStarNudge(): boolean;
|
|
15
|
+
/** Inputs to the pure show/skip decision (kept side-effect free for testing). */
|
|
16
|
+
export interface StarNudgeContext {
|
|
17
|
+
/** Caller asked for quiet / JSON output. */
|
|
18
|
+
quiet?: boolean;
|
|
19
|
+
/** stdout is attached to an interactive terminal. */
|
|
20
|
+
isTTY: boolean;
|
|
21
|
+
/** CI is set in the environment. */
|
|
22
|
+
ci: boolean;
|
|
23
|
+
/** User opted out via AGENTS_NO_NUDGE=1. */
|
|
24
|
+
optedOut: boolean;
|
|
25
|
+
/** The one-time sentinel already exists. */
|
|
26
|
+
alreadyShown: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Pure decision: should the one-time star nudge be shown? Skipped for
|
|
30
|
+
* quiet/JSON output, non-interactive terminals (pipes, redirects), CI, an
|
|
31
|
+
* explicit opt-out, or once it has already been shown.
|
|
32
|
+
*/
|
|
33
|
+
export declare function shouldShowStarNudge(ctx: StarNudgeContext): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Show the one-time star nudge if it hasn't been shown yet and the context is
|
|
36
|
+
* appropriate. Best-effort by contract: never throws, never blocks the run it
|
|
37
|
+
* follows.
|
|
38
|
+
*
|
|
39
|
+
* Skipped when: the caller asked for quiet/JSON output, stdout is not an
|
|
40
|
+
* interactive terminal (pipes, redirects), CI is set, or the user opted out
|
|
41
|
+
* with AGENTS_NO_NUDGE=1.
|
|
42
|
+
*/
|
|
43
|
+
export declare function maybeShowStarNudge(opts?: {
|
|
44
|
+
quiet?: boolean;
|
|
45
|
+
}): void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-time "star us on GitHub" nudge.
|
|
3
|
+
*
|
|
4
|
+
* Printed a single time, ever, after a user's first *successful* headline run
|
|
5
|
+
* (`agents run` / `agents teams`). Modelled on the existing warn-once sentinel
|
|
6
|
+
* pattern (see maybeWarnMultiInstall in src/index.ts): a marker under the
|
|
7
|
+
* regenerable runtime-state dir records that the hint was shown so it never
|
|
8
|
+
* repeats. It is a plain inline line — not a toast, not a nag — and stays out
|
|
9
|
+
* of the way of non-interactive, CI, quiet, and JSON output.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import chalk from 'chalk';
|
|
14
|
+
import { getRuntimeStateDir } from './state.js';
|
|
15
|
+
/** Canonical GitHub repo the nudge points at. */
|
|
16
|
+
export const REPO_URL = 'https://github.com/phnx-labs/agents-cli';
|
|
17
|
+
/** Sentinel written the first (and only) time the nudge is shown. */
|
|
18
|
+
function nudgeSentinelPath() {
|
|
19
|
+
return path.join(getRuntimeStateDir(), 'star-nudge-shown');
|
|
20
|
+
}
|
|
21
|
+
/** Has the star nudge already been shown on this machine? */
|
|
22
|
+
export function hasShownStarNudge() {
|
|
23
|
+
try {
|
|
24
|
+
return fs.existsSync(nudgeSentinelPath());
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Pure decision: should the one-time star nudge be shown? Skipped for
|
|
32
|
+
* quiet/JSON output, non-interactive terminals (pipes, redirects), CI, an
|
|
33
|
+
* explicit opt-out, or once it has already been shown.
|
|
34
|
+
*/
|
|
35
|
+
export function shouldShowStarNudge(ctx) {
|
|
36
|
+
if (ctx.quiet)
|
|
37
|
+
return false;
|
|
38
|
+
if (!ctx.isTTY)
|
|
39
|
+
return false;
|
|
40
|
+
if (ctx.ci)
|
|
41
|
+
return false;
|
|
42
|
+
if (ctx.optedOut)
|
|
43
|
+
return false;
|
|
44
|
+
if (ctx.alreadyShown)
|
|
45
|
+
return false;
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Show the one-time star nudge if it hasn't been shown yet and the context is
|
|
50
|
+
* appropriate. Best-effort by contract: never throws, never blocks the run it
|
|
51
|
+
* follows.
|
|
52
|
+
*
|
|
53
|
+
* Skipped when: the caller asked for quiet/JSON output, stdout is not an
|
|
54
|
+
* interactive terminal (pipes, redirects), CI is set, or the user opted out
|
|
55
|
+
* with AGENTS_NO_NUDGE=1.
|
|
56
|
+
*/
|
|
57
|
+
export function maybeShowStarNudge(opts = {}) {
|
|
58
|
+
try {
|
|
59
|
+
const show = shouldShowStarNudge({
|
|
60
|
+
quiet: opts.quiet,
|
|
61
|
+
isTTY: Boolean(process.stdout.isTTY),
|
|
62
|
+
ci: Boolean(process.env.CI),
|
|
63
|
+
optedOut: process.env.AGENTS_NO_NUDGE === '1',
|
|
64
|
+
alreadyShown: hasShownStarNudge(),
|
|
65
|
+
});
|
|
66
|
+
if (!show)
|
|
67
|
+
return;
|
|
68
|
+
// Claim the one-time slot with an ATOMIC exclusive create (O_EXCL). The
|
|
69
|
+
// hasShownStarNudge() check above is only a cheap fast-path; the existsSync
|
|
70
|
+
// + write pair is a TOCTOU race across processes, and `agents teams` spawns
|
|
71
|
+
// many at once. The `wx` flag makes the create itself the arbiter: exactly
|
|
72
|
+
// one process succeeds, every other gets EEXIST and stays silent — so the
|
|
73
|
+
// hint prints at most once even under concurrent completions.
|
|
74
|
+
const sentinel = nudgeSentinelPath();
|
|
75
|
+
fs.mkdirSync(path.dirname(sentinel), { recursive: true });
|
|
76
|
+
try {
|
|
77
|
+
fs.writeFileSync(sentinel, new Date().toISOString(), { flag: 'wx' });
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
if (e.code === 'EEXIST')
|
|
81
|
+
return; // another process won the race
|
|
82
|
+
throw e; // real write failure -> caught by the outer best-effort guard
|
|
83
|
+
}
|
|
84
|
+
console.log('\n' +
|
|
85
|
+
chalk.gray('Enjoying agents-cli? Give it a star to help others find it: ') +
|
|
86
|
+
chalk.cyan(REPO_URL));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* best-effort: a nudge must never break a successful run */
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -25,6 +25,7 @@ export type Registrar = (program: Command) => void;
|
|
|
25
25
|
export type ModuleLoader = () => Promise<Registrar>;
|
|
26
26
|
export declare const loadView: ModuleLoader;
|
|
27
27
|
export declare const loadInspect: ModuleLoader;
|
|
28
|
+
export declare const loadResources: ModuleLoader;
|
|
28
29
|
export declare const loadFeedback: ModuleLoader;
|
|
29
30
|
export declare const loadCommands: ModuleLoader;
|
|
30
31
|
export declare const loadHooks: ModuleLoader;
|
|
@@ -40,8 +41,8 @@ export declare const loadWorkflows: ModuleLoader;
|
|
|
40
41
|
export declare const loadWorktree: ModuleLoader;
|
|
41
42
|
export declare const loadVersions: ModuleLoader;
|
|
42
43
|
export declare const loadImport: ModuleLoader;
|
|
44
|
+
export declare const loadExport: ModuleLoader;
|
|
43
45
|
export declare const loadPackages: ModuleLoader;
|
|
44
|
-
export declare const loadDaemon: ModuleLoader;
|
|
45
46
|
export declare const loadRoutines: ModuleLoader;
|
|
46
47
|
export declare const loadMonitors: ModuleLoader;
|
|
47
48
|
export declare const loadRun: ModuleLoader;
|
|
@@ -57,6 +58,7 @@ export declare const loadCheck: ModuleLoader;
|
|
|
57
58
|
export declare const loadStatus: ModuleLoader;
|
|
58
59
|
export declare const loadProfiles: ModuleLoader;
|
|
59
60
|
export declare const loadSecrets: ModuleLoader;
|
|
61
|
+
export declare const loadLogin: ModuleLoader;
|
|
60
62
|
export declare const loadWallet: ModuleLoader;
|
|
61
63
|
export declare const loadHelper: ModuleLoader;
|
|
62
64
|
export declare const loadMenubar: ModuleLoader;
|
|
@@ -71,6 +73,7 @@ export declare const loadCost: ModuleLoader;
|
|
|
71
73
|
export declare const loadOutput: ModuleLoader;
|
|
72
74
|
export declare const loadBudget: ModuleLoader;
|
|
73
75
|
export declare const loadAlias: ModuleLoader;
|
|
76
|
+
export declare const loadMine: ModuleLoader;
|
|
74
77
|
export declare const loadPty: ModuleLoader;
|
|
75
78
|
export declare const loadTmux: ModuleLoader;
|
|
76
79
|
export declare const loadWatchdog: ModuleLoader;
|
|
@@ -90,7 +93,10 @@ export declare const loadSessions: ModuleLoader;
|
|
|
90
93
|
export declare const loadTeams: ModuleLoader;
|
|
91
94
|
export declare const loadCloud: ModuleLoader;
|
|
92
95
|
export declare const loadMessage: ModuleLoader;
|
|
96
|
+
export declare const loadSend: ModuleLoader;
|
|
97
|
+
export declare const loadHq: ModuleLoader;
|
|
93
98
|
export declare const loadFeed: ModuleLoader;
|
|
99
|
+
export declare const loadActivity: ModuleLoader;
|
|
94
100
|
export declare const loadMailboxes: ModuleLoader;
|
|
95
101
|
export declare const loadServe: ModuleLoader;
|
|
96
102
|
export declare const loadShare: ModuleLoader;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// them into the exact main-branch registration order for the slow path.
|
|
4
4
|
export const loadView = async () => (await import('../../commands/view.js')).registerViewCommand;
|
|
5
5
|
export const loadInspect = async () => (await import('../../commands/inspect.js')).registerInspectCommand;
|
|
6
|
+
export const loadResources = async () => (await import('../../commands/resources.js')).registerResourcesCommand;
|
|
6
7
|
export const loadFeedback = async () => (await import('../../commands/feedback.js')).registerFeedbackCommand;
|
|
7
8
|
export const loadCommands = async () => (await import('../../commands/commands.js')).registerCommandsCommands;
|
|
8
9
|
export const loadHooks = async () => (await import('../../commands/hooks.js')).registerHooksCommands;
|
|
@@ -18,8 +19,8 @@ export const loadWorkflows = async () => (await import('../../commands/workflows
|
|
|
18
19
|
export const loadWorktree = async () => (await import('../../commands/worktree.js')).registerWorktreeCommands;
|
|
19
20
|
export const loadVersions = async () => (await import('../../commands/versions.js')).registerVersionsCommands;
|
|
20
21
|
export const loadImport = async () => (await import('../../commands/import.js')).registerImportCommand;
|
|
22
|
+
export const loadExport = async () => (await import('../../commands/export.js')).registerExportCommand;
|
|
21
23
|
export const loadPackages = async () => (await import('../../commands/packages.js')).registerPackagesCommands;
|
|
22
|
-
export const loadDaemon = async () => (await import('../../commands/daemon.js')).registerDaemonCommands;
|
|
23
24
|
export const loadRoutines = async () => (await import('../../commands/routines.js')).registerRoutinesCommands;
|
|
24
25
|
export const loadMonitors = async () => (await import('../../commands/monitors.js')).registerMonitorsCommands;
|
|
25
26
|
export const loadRun = async () => (await import('../../commands/exec.js')).registerRunCommand;
|
|
@@ -35,6 +36,7 @@ export const loadCheck = async () => (await import('../../commands/check.js')).r
|
|
|
35
36
|
export const loadStatus = async () => (await import('../../commands/status.js')).registerStatusCommand;
|
|
36
37
|
export const loadProfiles = async () => (await import('../../commands/profiles.js')).registerProfilesCommands;
|
|
37
38
|
export const loadSecrets = async () => (await import('../../commands/secrets.js')).registerSecretsCommands;
|
|
39
|
+
export const loadLogin = async () => (await import('../../commands/login.js')).registerLoginCommands;
|
|
38
40
|
export const loadWallet = async () => (await import('../../commands/wallet.js')).registerWalletCommands;
|
|
39
41
|
export const loadHelper = async () => (await import('../../commands/helper.js')).registerHelperCommand;
|
|
40
42
|
export const loadMenubar = async () => (await import('../../commands/menubar.js')).registerMenubarCommands;
|
|
@@ -49,6 +51,7 @@ export const loadCost = async () => (await import('../../commands/cost.js')).reg
|
|
|
49
51
|
export const loadOutput = async () => (await import('../../commands/output.js')).registerOutputCommand;
|
|
50
52
|
export const loadBudget = async () => (await import('../../commands/budget.js')).registerBudgetCommand;
|
|
51
53
|
export const loadAlias = async () => (await import('../../commands/alias.js')).registerAliasCommand;
|
|
54
|
+
export const loadMine = async () => (await import('../../commands/mine.js')).registerMineCommand;
|
|
52
55
|
export const loadPty = async () => (await import('../../commands/pty.js')).registerPtyCommands;
|
|
53
56
|
export const loadTmux = async () => (await import('../../commands/tmux.js')).registerTmuxCommands;
|
|
54
57
|
export const loadWatchdog = async () => (await import('../../commands/watchdog.js')).registerWatchdogCommand;
|
|
@@ -68,7 +71,10 @@ export const loadSessions = async () => (await import('../../commands/sessions.j
|
|
|
68
71
|
export const loadTeams = async () => (await import('../../commands/teams.js')).registerTeamsCommands;
|
|
69
72
|
export const loadCloud = async () => (await import('../../commands/cloud.js')).registerCloudCommands;
|
|
70
73
|
export const loadMessage = async () => (await import('../../commands/message.js')).registerMessageCommand;
|
|
74
|
+
export const loadSend = async () => (await import('../../commands/send.js')).registerSendCommand;
|
|
75
|
+
export const loadHq = async () => (await import('../../commands/hq.js')).registerHqCommand;
|
|
71
76
|
export const loadFeed = async () => (await import('../../commands/feed.js')).registerFeedCommand;
|
|
77
|
+
export const loadActivity = async () => (await import('../../commands/activity.js')).registerActivityCommand;
|
|
72
78
|
export const loadMailboxes = async () => (await import('../../commands/mailboxes.js')).registerMailboxesCommand;
|
|
73
79
|
export const loadServe = async () => (await import('../../commands/serve.js')).registerServeCommand;
|
|
74
80
|
export const loadShare = async () => (await import('../../commands/share.js')).registerShareCommands;
|
|
@@ -82,7 +88,7 @@ export const loadFunnel = async () => (await import('../../commands/funnel.js'))
|
|
|
82
88
|
* inherit the root's custom help formatter rather than getting the per-command
|
|
83
89
|
* recursive pass. Keeping that ordering preserves their `--help` output exactly.
|
|
84
90
|
*/
|
|
85
|
-
export const LAZY_COMMAND_NAMES = new Set(['sessions', 'teams', 'cloud', 'message', 'serve']);
|
|
91
|
+
export const LAZY_COMMAND_NAMES = new Set(['sessions', 'teams', 'cloud', 'message', 'hq', 'serve']);
|
|
86
92
|
/**
|
|
87
93
|
* User-typed top-level command name -> ordered list of module loaders to run.
|
|
88
94
|
*
|
|
@@ -100,6 +106,7 @@ export const LAZY_COMMAND_NAMES = new Set(['sessions', 'teams', 'cloud', 'messag
|
|
|
100
106
|
export const COMMAND_LOADERS = {
|
|
101
107
|
view: [loadView],
|
|
102
108
|
inspect: [loadInspect],
|
|
109
|
+
resources: [loadResources],
|
|
103
110
|
feedback: [loadFeedback],
|
|
104
111
|
commands: [loadCommands],
|
|
105
112
|
hooks: [loadHooks],
|
|
@@ -121,10 +128,10 @@ export const COMMAND_LOADERS = {
|
|
|
121
128
|
purge: [loadVersions],
|
|
122
129
|
prune: [loadVersions, loadPrune],
|
|
123
130
|
import: [loadImport],
|
|
131
|
+
export: [loadExport],
|
|
124
132
|
registry: [loadPackages],
|
|
125
133
|
search: [loadPackages],
|
|
126
134
|
install: [loadPackages],
|
|
127
|
-
daemon: [loadDaemon],
|
|
128
135
|
routines: [loadRoutines],
|
|
129
136
|
monitors: [loadMonitors],
|
|
130
137
|
run: [loadRun],
|
|
@@ -137,8 +144,12 @@ export const COMMAND_LOADERS = {
|
|
|
137
144
|
apply: [loadApply],
|
|
138
145
|
check: [loadCheck],
|
|
139
146
|
status: [loadStatus],
|
|
147
|
+
profile: [loadProfiles],
|
|
140
148
|
profiles: [loadProfiles],
|
|
141
149
|
secrets: [loadSecrets],
|
|
150
|
+
login: [loadLogin],
|
|
151
|
+
logout: [loadLogin],
|
|
152
|
+
whoami: [loadLogin],
|
|
142
153
|
wallet: [loadWallet],
|
|
143
154
|
helper: [loadHelper],
|
|
144
155
|
menubar: [loadMenubar],
|
|
@@ -153,6 +164,7 @@ export const COMMAND_LOADERS = {
|
|
|
153
164
|
output: [loadOutput],
|
|
154
165
|
budget: [loadBudget],
|
|
155
166
|
alias: [loadAlias],
|
|
167
|
+
mine: [loadMine],
|
|
156
168
|
pty: [loadPty],
|
|
157
169
|
tmux: [loadTmux],
|
|
158
170
|
watchdog: [loadWatchdog],
|
|
@@ -180,7 +192,11 @@ export const COMMAND_LOADERS = {
|
|
|
180
192
|
teams: [loadTeams],
|
|
181
193
|
cloud: [loadCloud],
|
|
182
194
|
message: [loadMessage],
|
|
195
|
+
send: [loadSend],
|
|
196
|
+
notify: [loadSend],
|
|
197
|
+
hq: [loadHq],
|
|
183
198
|
feed: [loadFeed],
|
|
199
|
+
activity: [loadActivity],
|
|
184
200
|
mailboxes: [loadMailboxes],
|
|
185
201
|
mailbox: [loadMailboxes],
|
|
186
202
|
serve: [loadServe],
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -137,6 +137,8 @@ export declare function getMonitorsHistoryDir(): string;
|
|
|
137
137
|
export declare function getMailboxRootDir(): string;
|
|
138
138
|
/** Root for open-block feed records (~/.agents/.history/feed/). */
|
|
139
139
|
export declare function getFeedDir(): string;
|
|
140
|
+
/** Append-only per-session agent-activity event logs (~/.agents/.history/activity/). */
|
|
141
|
+
export declare function getActivityDir(): string;
|
|
140
142
|
/** Path to installed agent CLI binaries (~/.agents/.history/versions/). */
|
|
141
143
|
export declare function getVersionsDir(): string;
|
|
142
144
|
/** Path to version-switching shim scripts (~/.agents/.cache/shims/). */
|
package/dist/lib/state.js
CHANGED
|
@@ -101,6 +101,7 @@ const BACKUPS_DIR = path.join(HISTORY_DIR, 'backups');
|
|
|
101
101
|
const TRASH_DIR = path.join(HISTORY_DIR, 'trash');
|
|
102
102
|
const MAILBOX_DIR = path.join(HISTORY_DIR, 'mailbox');
|
|
103
103
|
const FEED_DIR = path.join(HISTORY_DIR, 'feed');
|
|
104
|
+
const ACTIVITY_DIR = path.join(HISTORY_DIR, 'activity');
|
|
104
105
|
// Cache bucket (regenerable).
|
|
105
106
|
const SHIMS_DIR = path.join(CACHE_DIR, 'shims');
|
|
106
107
|
const HOOK_SHIMS_DIR = path.join(SHIMS_DIR, 'hooks');
|
|
@@ -340,6 +341,8 @@ export function getMonitorsHistoryDir() { return MONITORS_HISTORY_DIR; }
|
|
|
340
341
|
export function getMailboxRootDir() { return MAILBOX_DIR; }
|
|
341
342
|
/** Root for open-block feed records (~/.agents/.history/feed/). */
|
|
342
343
|
export function getFeedDir() { return FEED_DIR; }
|
|
344
|
+
/** Append-only per-session agent-activity event logs (~/.agents/.history/activity/). */
|
|
345
|
+
export function getActivityDir() { return ACTIVITY_DIR; }
|
|
343
346
|
/** Path to installed agent CLI binaries (~/.agents/.history/versions/). */
|
|
344
347
|
export function getVersionsDir() { return VERSIONS_DIR; }
|
|
345
348
|
/** Path to version-switching shim scripts (~/.agents/.cache/shims/). */
|
|
@@ -603,18 +606,25 @@ function writeIfChanged(filePath, content) {
|
|
|
603
606
|
* `agents:` / `versions:` are not written (no empty committed files).
|
|
604
607
|
*/
|
|
605
608
|
function writeMetaUnlocked(meta) {
|
|
606
|
-
const { agents, versions, defaultBrowserProfile, ...central } = meta;
|
|
609
|
+
const { agents, isolatedAgents, versions, defaultBrowserProfile, ...central } = meta;
|
|
607
610
|
// Write the machine-local files FIRST, then strip central — so a crash mid-write
|
|
608
611
|
// never removes pins/versions from central before they're persisted elsewhere.
|
|
609
612
|
const devicePath = getDeviceMetaPath();
|
|
610
613
|
const hasAgents = !!agents && Object.keys(agents).length > 0;
|
|
614
|
+
// The isolated pointer names a version installed on THIS machine, exactly like a
|
|
615
|
+
// global pin, so it belongs beside `agents:` in the device file rather than in the
|
|
616
|
+
// central doc that syncs — otherwise another machine inherits a pointer to a copy
|
|
617
|
+
// it does not have.
|
|
618
|
+
const hasIsolatedAgents = !!isolatedAgents && Object.keys(isolatedAgents).length > 0;
|
|
611
619
|
const hasDefaultBrowser = !!defaultBrowserProfile;
|
|
612
|
-
if (hasAgents || hasDefaultBrowser) {
|
|
620
|
+
if (hasAgents || hasIsolatedAgents || hasDefaultBrowser) {
|
|
613
621
|
// Device-local doc carries `agents:` pins and `defaultBrowserProfile:` — both
|
|
614
622
|
// are per-machine and must never land in central agents.yaml (which syncs).
|
|
615
623
|
const deviceDoc = {};
|
|
616
624
|
if (hasAgents)
|
|
617
625
|
deviceDoc.agents = agents;
|
|
626
|
+
if (hasIsolatedAgents)
|
|
627
|
+
deviceDoc.isolatedAgents = isolatedAgents;
|
|
618
628
|
if (hasDefaultBrowser)
|
|
619
629
|
deviceDoc.defaultBrowserProfile = defaultBrowserProfile;
|
|
620
630
|
fs.mkdirSync(path.dirname(devicePath), { recursive: true });
|
|
@@ -637,8 +647,9 @@ function writeMetaUnlocked(meta) {
|
|
|
637
647
|
}
|
|
638
648
|
/**
|
|
639
649
|
* Overlay this machine's local state onto a central-portable Meta:
|
|
640
|
-
* - `agents:` from the device file (device wins; the union
|
|
641
|
-
* one-level merge and self-heals a pre-migration central that
|
|
650
|
+
* - `agents:` and `isolatedAgents:` from the device file (device wins; the union
|
|
651
|
+
* both preserves the one-level merge and self-heals a pre-migration central that
|
|
652
|
+
* still has pins)
|
|
642
653
|
* - `defaultBrowserProfile:` from the device file (device is the sole source;
|
|
643
654
|
* the field is stripped from central on write, so nothing to merge against)
|
|
644
655
|
* - `versions:` from the history JSON (wholesale replace; falls back to
|
|
@@ -651,6 +662,8 @@ function overlayMachineLocal(meta) {
|
|
|
651
662
|
const dm = yaml.parse(fs.readFileSync(devicePath, 'utf-8'));
|
|
652
663
|
if (dm?.agents)
|
|
653
664
|
meta.agents = { ...meta.agents, ...dm.agents };
|
|
665
|
+
if (dm?.isolatedAgents)
|
|
666
|
+
meta.isolatedAgents = { ...meta.isolatedAgents, ...dm.isolatedAgents };
|
|
654
667
|
if (dm?.defaultBrowserProfile)
|
|
655
668
|
meta.defaultBrowserProfile = dm.defaultBrowserProfile;
|
|
656
669
|
}
|
|
@@ -27,6 +27,8 @@ export interface SubagentTarget {
|
|
|
27
27
|
names(dir: string): string[];
|
|
28
28
|
/** On-disk paths subagent `name` occupies (for removal / soft-delete). */
|
|
29
29
|
occupied(dir: string, name: string): OccupiedEntry[];
|
|
30
|
+
/** Cross-item files this target owns outside any one subagent's occupied paths. */
|
|
31
|
+
finalizeOccupied?(dir: string): OccupiedEntry[];
|
|
30
32
|
/** Rich metadata for `name`; `null` skips it from the listing. */
|
|
31
33
|
read(dir: string, name: string): SubagentMeta | null;
|
|
32
34
|
/** Optional post-sync pass over the just-synced subagents (Kimi's parent index). */
|
|
@@ -213,6 +213,9 @@ const kimiTarget = {
|
|
|
213
213
|
{ path: safeJoin(dir, `${name}.system.md`), kind: 'file' },
|
|
214
214
|
];
|
|
215
215
|
},
|
|
216
|
+
finalizeOccupied(dir) {
|
|
217
|
+
return [{ path: safeJoin(dir, KIMI_SUBAGENTS_PARENT_FILE), kind: 'file' }];
|
|
218
|
+
},
|
|
216
219
|
read(dir, name) {
|
|
217
220
|
const yamlPath = path.join(dir, `${name}.yaml`);
|
|
218
221
|
if (!fs.existsSync(yamlPath) || !fs.statSync(yamlPath).isFile())
|