@phnx-labs/agents-cli 1.20.50 → 1.20.51
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 +24 -0
- package/dist/commands/browser-picker.js +1 -18
- package/dist/commands/cloud.js +1 -25
- package/dist/commands/computer.d.ts +1 -0
- package/dist/commands/computer.js +129 -8
- package/dist/commands/exec.js +49 -6
- package/dist/commands/factory.js +1 -4
- package/dist/commands/inspect.js +1 -11
- package/dist/commands/mcp.js +2 -6
- package/dist/commands/message.js +1 -4
- package/dist/commands/profiles.js +1 -18
- package/dist/commands/repo.js +33 -14
- package/dist/commands/resource-view.d.ts +1 -0
- package/dist/commands/resource-view.js +5 -17
- package/dist/commands/secrets.d.ts +1 -0
- package/dist/commands/secrets.js +1 -28
- package/dist/commands/sessions-picker.js +1 -18
- package/dist/commands/sessions.js +6 -8
- package/dist/commands/teams-picker.js +1 -32
- package/dist/commands/teams.js +1 -27
- package/dist/commands/tmux.js +1 -3
- package/dist/commands/view.js +1 -9
- package/dist/commands/worktree.js +1 -4
- package/dist/lib/agents.d.ts +0 -4
- package/dist/lib/agents.js +20 -33
- package/dist/lib/auto-dispatch-linear.d.ts +18 -0
- package/dist/lib/auto-dispatch-linear.js +107 -0
- package/dist/lib/auto-dispatch-provider.d.ts +10 -0
- package/dist/lib/auto-dispatch-provider.js +25 -0
- package/dist/lib/auto-dispatch.d.ts +87 -0
- package/dist/lib/auto-dispatch.js +142 -0
- package/dist/lib/browser/cdp.js +11 -2
- package/dist/lib/browser/drivers/ssh.d.ts +28 -10
- package/dist/lib/browser/drivers/ssh.js +57 -18
- package/dist/lib/browser/refs.js +1 -5
- package/dist/lib/cli-resources.d.ts +0 -2
- package/dist/lib/cli-resources.js +30 -13
- package/dist/lib/cloud/rush.d.ts +0 -24
- package/dist/lib/cloud/rush.js +0 -31
- package/dist/lib/crabbox/cli.js +4 -1
- package/dist/lib/crabbox/lease.js +29 -1
- package/dist/lib/daemon.js +41 -0
- package/dist/lib/exec.js +31 -14
- package/dist/lib/format.d.ts +38 -0
- package/dist/lib/format.js +108 -0
- package/dist/lib/git.d.ts +21 -0
- package/dist/lib/git.js +92 -0
- package/dist/lib/hooks/cache.d.ts +9 -2
- package/dist/lib/hooks/cache.js +220 -8
- package/dist/lib/hooks.js +17 -8
- package/dist/lib/platform/exec.d.ts +4 -1
- package/dist/lib/platform/exec.js +8 -2
- package/dist/lib/resources.d.ts +0 -8
- package/dist/lib/resources.js +0 -10
- package/dist/lib/runner.js +10 -2
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/session/active.d.ts +11 -1
- package/dist/lib/session/active.js +3 -0
- package/dist/lib/session/db.d.ts +1 -4
- package/dist/lib/session/db.js +20 -25
- package/dist/lib/session/discover.d.ts +2 -2
- package/dist/lib/session/discover.js +61 -48
- package/dist/lib/session/parse.js +35 -34
- package/dist/lib/session/render.d.ts +7 -3
- package/dist/lib/session/render.js +15 -9
- package/dist/lib/session/state.d.ts +55 -0
- package/dist/lib/session/state.js +87 -10
- package/dist/lib/session/types.d.ts +9 -0
- package/dist/lib/shims.d.ts +9 -3
- package/dist/lib/shims.js +44 -8
- package/dist/lib/ssh-tunnel.d.ts +33 -2
- package/dist/lib/ssh-tunnel.js +94 -7
- package/dist/lib/staleness/types.d.ts +0 -1
- package/dist/lib/types.d.ts +14 -1
- package/dist/lib/versions.d.ts +0 -26
- package/dist/lib/versions.js +2 -145
- package/dist/lib/warn-unpushed.d.ts +40 -0
- package/dist/lib/warn-unpushed.js +128 -0
- package/package.json +3 -1
- package/dist/lib/resources/index.d.ts +0 -53
- package/dist/lib/resources/index.js +0 -76
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-run guard against silently stranded work.
|
|
3
|
+
*
|
|
4
|
+
* A headless `agents run` in a writable mode can end with the agent having
|
|
5
|
+
* committed on a branch but never pushed it — the CLI's exit path does no git
|
|
6
|
+
* work, so those commits sit invisible in a worktree until someone audits the
|
|
7
|
+
* box. This module detects that state and prints a loud stderr warning with the
|
|
8
|
+
* exact push / PR commands. It is advisory only: it never pushes, never mutates
|
|
9
|
+
* the repo, and never throws (a non-repo cwd or any git error yields an inert
|
|
10
|
+
* result), so it can sit on the run's exit path without ever breaking it.
|
|
11
|
+
*/
|
|
12
|
+
import { execFile } from 'child_process';
|
|
13
|
+
import { promisify } from 'util';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
const execFileAsync = promisify(execFile);
|
|
16
|
+
// Unit-separator byte (0x1f) as the git-log field delimiter: it cannot occur in
|
|
17
|
+
// a commit subject, so splitting on it never truncates a subject with spaces.
|
|
18
|
+
const SEP = '\x1f';
|
|
19
|
+
/**
|
|
20
|
+
* Whether a just-finished run should be checked for stranded work: only
|
|
21
|
+
* writable modes can leave commits (plan is read-only), and only non-interactive
|
|
22
|
+
* runs need the warning (an interactive user sees their own shell). Centralizes
|
|
23
|
+
* the gate so every exit path in the run command applies it identically.
|
|
24
|
+
*/
|
|
25
|
+
export function shouldWarnUnpushed(mode, interactive) {
|
|
26
|
+
return mode !== 'plan' && !interactive;
|
|
27
|
+
}
|
|
28
|
+
const INERT = { isRepo: false, branch: null, hasUpstream: false, unpushed: [] };
|
|
29
|
+
async function git(args, cwd) {
|
|
30
|
+
// These are all local, non-prompting reads, but the call sits on a run's exit
|
|
31
|
+
// path — a hard timeout guarantees a wedged git can never delay exit unbounded.
|
|
32
|
+
const { stdout } = await execFileAsync('git', args, { cwd, timeout: 5000 });
|
|
33
|
+
return stdout.trim();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Inspect `cwd` for commits on the current branch that have not reached any
|
|
37
|
+
* remote. Uses `git log --not --remotes` so it is correct even when the branch
|
|
38
|
+
* has no upstream set: commits already present on some `origin/*` ref are NOT
|
|
39
|
+
* reported (no false positive), and a never-pushed branch reports all its
|
|
40
|
+
* commits. Returns an inert result — never throws — for a non-repo cwd, a
|
|
41
|
+
* detached HEAD, or a repo with no remotes (nothing to push to).
|
|
42
|
+
*/
|
|
43
|
+
export async function getUnpushedState(cwd) {
|
|
44
|
+
let branch;
|
|
45
|
+
try {
|
|
46
|
+
branch = await git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return INERT; // not a git repo
|
|
50
|
+
}
|
|
51
|
+
// Detached HEAD: agents commit on branches; nothing nameable to push.
|
|
52
|
+
if (!branch || branch === 'HEAD') {
|
|
53
|
+
return { isRepo: true, branch: null, hasUpstream: false, unpushed: [] };
|
|
54
|
+
}
|
|
55
|
+
// No remote configured -> `--remotes` matches nothing and would report the
|
|
56
|
+
// entire history as "unpushed". There's nowhere to push, so stay silent.
|
|
57
|
+
let hasRemote = false;
|
|
58
|
+
try {
|
|
59
|
+
hasRemote = (await git(['remote'], cwd)).length > 0;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
hasRemote = false;
|
|
63
|
+
}
|
|
64
|
+
if (!hasRemote) {
|
|
65
|
+
return { isRepo: true, branch, hasUpstream: false, unpushed: [] };
|
|
66
|
+
}
|
|
67
|
+
let unpushed = [];
|
|
68
|
+
try {
|
|
69
|
+
// HEAD must precede `--not`: everything after `--not` is negated, so
|
|
70
|
+
// `--not --remotes HEAD` would negate HEAD too and always return empty.
|
|
71
|
+
const out = await git(['log', 'HEAD', '--not', '--remotes', `--pretty=format:%h${SEP}%s`], cwd);
|
|
72
|
+
unpushed = out
|
|
73
|
+
? out.split('\n').map((line) => {
|
|
74
|
+
const idx = line.indexOf(SEP);
|
|
75
|
+
return idx === -1
|
|
76
|
+
? { sha: line, subject: '' }
|
|
77
|
+
: { sha: line.slice(0, idx), subject: line.slice(idx + 1) };
|
|
78
|
+
})
|
|
79
|
+
: [];
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { isRepo: true, branch, hasUpstream: false, unpushed: [] };
|
|
83
|
+
}
|
|
84
|
+
let hasUpstream = false;
|
|
85
|
+
try {
|
|
86
|
+
await git(['rev-parse', '--abbrev-ref', '@{u}'], cwd);
|
|
87
|
+
hasUpstream = true;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
hasUpstream = false;
|
|
91
|
+
}
|
|
92
|
+
return { isRepo: true, branch, hasUpstream, unpushed };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Render the warning for an unpushed state, or null when there is nothing to
|
|
96
|
+
* warn about. Split out from the printer so it is directly testable.
|
|
97
|
+
*/
|
|
98
|
+
export function formatUnpushedWarning(state, cwd) {
|
|
99
|
+
if (!state.isRepo || !state.branch || state.unpushed.length === 0)
|
|
100
|
+
return null;
|
|
101
|
+
const n = state.unpushed.length;
|
|
102
|
+
const lines = [`\n⚠ agent left ${n} commit${n === 1 ? '' : 's'} on '${state.branch}' not pushed to any remote:`];
|
|
103
|
+
for (const c of state.unpushed.slice(0, 5))
|
|
104
|
+
lines.push(` ${c.sha} ${c.subject}`);
|
|
105
|
+
if (n > 5)
|
|
106
|
+
lines.push(` … and ${n - 5} more`);
|
|
107
|
+
const pushCmd = state.hasUpstream
|
|
108
|
+
? `git -C "${cwd}" push`
|
|
109
|
+
: `git -C "${cwd}" push -u origin ${state.branch}`;
|
|
110
|
+
lines.push(` push them: ${pushCmd}`);
|
|
111
|
+
lines.push(` open a PR: gh pr create --head ${state.branch}`);
|
|
112
|
+
return lines.join('\n');
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* If the just-finished run left committed-but-unpushed work in `cwd`, print a
|
|
116
|
+
* loud stderr warning with the exact push / PR commands. Non-fatal by contract:
|
|
117
|
+
* any failure is swallowed so it can never break a run's exit path.
|
|
118
|
+
*/
|
|
119
|
+
export async function warnUnpushedWork(cwd) {
|
|
120
|
+
try {
|
|
121
|
+
const warning = formatUnpushedWarning(await getUnpushedState(cwd), cwd);
|
|
122
|
+
if (warning)
|
|
123
|
+
process.stderr.write(chalk.yellow(warning) + '\n');
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Advisory only — never break the run over a warning.
|
|
127
|
+
}
|
|
128
|
+
}
|
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.51",
|
|
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",
|
|
@@ -98,12 +98,14 @@
|
|
|
98
98
|
"proper-lockfile": "4.1.2",
|
|
99
99
|
"simple-git": "3.36.0",
|
|
100
100
|
"smol-toml": "1.7.0",
|
|
101
|
+
"ws": "^8.21.0",
|
|
101
102
|
"yaml": "2.9.0"
|
|
102
103
|
},
|
|
103
104
|
"devDependencies": {
|
|
104
105
|
"@types/diff": "8.0.0",
|
|
105
106
|
"@types/marked-terminal": "6.1.1",
|
|
106
107
|
"@types/node": "26.1.0",
|
|
108
|
+
"@types/ws": "^8.18.1",
|
|
107
109
|
"tsx": "4.23.0",
|
|
108
110
|
"typescript": "6.0.3",
|
|
109
111
|
"vitest": "4.1.9"
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified resource system - exports all handlers and provides a registry.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* import { handlers, getHandler } from './resources/index.js';
|
|
6
|
-
* const cmds = handlers.commands.listAll('claude');
|
|
7
|
-
*/
|
|
8
|
-
export * from './types.js';
|
|
9
|
-
export { CommandsHandler, commandsHandler, type CommandItem } from './commands.js';
|
|
10
|
-
export { HooksHandler, type HookItem } from './hooks.js';
|
|
11
|
-
export { SkillsHandler, type SkillItem } from './skills.js';
|
|
12
|
-
export { RulesHandler, type RuleItem } from './rules.js';
|
|
13
|
-
export { McpHandler, getMcpConfigPath, type McpItem } from './mcp.js';
|
|
14
|
-
export { PermissionsHandler, type PermissionItem } from './permissions.js';
|
|
15
|
-
export { SubagentsHandler, subagentsHandler, type SubagentItem } from './subagents.js';
|
|
16
|
-
export { WorkflowsHandler, type WorkflowItem } from './workflows.js';
|
|
17
|
-
import type { ResourceKind, ResourceHandler } from './types.js';
|
|
18
|
-
/** All resource handlers keyed by kind. */
|
|
19
|
-
export declare const handlers: {
|
|
20
|
-
readonly command: import("./commands.js").CommandsHandler;
|
|
21
|
-
readonly commands: import("./commands.js").CommandsHandler;
|
|
22
|
-
readonly hook: ResourceHandler<import("../types.js").ManifestHook>;
|
|
23
|
-
readonly hooks: ResourceHandler<import("../types.js").ManifestHook>;
|
|
24
|
-
readonly skill: ResourceHandler<import("./skills.js").SkillItem>;
|
|
25
|
-
readonly skills: ResourceHandler<import("./skills.js").SkillItem>;
|
|
26
|
-
readonly rule: ResourceHandler<import("./rules.js").RuleItem>;
|
|
27
|
-
readonly rules: ResourceHandler<import("./rules.js").RuleItem>;
|
|
28
|
-
readonly mcp: ResourceHandler<import("./mcp.js").McpItem>;
|
|
29
|
-
readonly permission: ResourceHandler<import("../types.js").PermissionSet>;
|
|
30
|
-
readonly permissions: ResourceHandler<import("../types.js").PermissionSet>;
|
|
31
|
-
readonly subagent: import("./subagents.js").SubagentsHandler;
|
|
32
|
-
readonly subagents: import("./subagents.js").SubagentsHandler;
|
|
33
|
-
readonly workflow: {
|
|
34
|
-
readonly kind: "workflow";
|
|
35
|
-
listAll(_agent: import("./types.js").AgentId, cwd?: string): import("./types.js").ResolvedItem<import("./workflows.js").WorkflowItem>[];
|
|
36
|
-
resolve(_agent: import("./types.js").AgentId, name: string, cwd?: string): import("./types.js").ResolvedItem<import("./workflows.js").WorkflowItem> | null;
|
|
37
|
-
sync(_agent: import("./types.js").AgentId, _versionHome: string, _cwd?: string): void;
|
|
38
|
-
format(_agent: import("./types.js").AgentId): "md";
|
|
39
|
-
targetDir(_agent: import("./types.js").AgentId): string;
|
|
40
|
-
};
|
|
41
|
-
readonly workflows: {
|
|
42
|
-
readonly kind: "workflow";
|
|
43
|
-
listAll(_agent: import("./types.js").AgentId, cwd?: string): import("./types.js").ResolvedItem<import("./workflows.js").WorkflowItem>[];
|
|
44
|
-
resolve(_agent: import("./types.js").AgentId, name: string, cwd?: string): import("./types.js").ResolvedItem<import("./workflows.js").WorkflowItem> | null;
|
|
45
|
-
sync(_agent: import("./types.js").AgentId, _versionHome: string, _cwd?: string): void;
|
|
46
|
-
format(_agent: import("./types.js").AgentId): "md";
|
|
47
|
-
targetDir(_agent: import("./types.js").AgentId): string;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
/** Get a handler by resource kind. */
|
|
51
|
-
export declare function getHandler(kind: ResourceKind): ResourceHandler<unknown> | null;
|
|
52
|
-
/** All resource kinds. */
|
|
53
|
-
export declare const RESOURCE_KINDS: ResourceKind[];
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified resource system - exports all handlers and provides a registry.
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* import { handlers, getHandler } from './resources/index.js';
|
|
6
|
-
* const cmds = handlers.commands.listAll('claude');
|
|
7
|
-
*/
|
|
8
|
-
export * from './types.js';
|
|
9
|
-
export { CommandsHandler, commandsHandler } from './commands.js';
|
|
10
|
-
export { HooksHandler } from './hooks.js';
|
|
11
|
-
export { SkillsHandler } from './skills.js';
|
|
12
|
-
export { RulesHandler } from './rules.js';
|
|
13
|
-
export { McpHandler, getMcpConfigPath } from './mcp.js';
|
|
14
|
-
export { PermissionsHandler } from './permissions.js';
|
|
15
|
-
export { SubagentsHandler, subagentsHandler } from './subagents.js';
|
|
16
|
-
export { WorkflowsHandler } from './workflows.js';
|
|
17
|
-
import { commandsHandler } from './commands.js';
|
|
18
|
-
import { HooksHandler } from './hooks.js';
|
|
19
|
-
import { SkillsHandler } from './skills.js';
|
|
20
|
-
import { RulesHandler } from './rules.js';
|
|
21
|
-
import { McpHandler } from './mcp.js';
|
|
22
|
-
import { PermissionsHandler } from './permissions.js';
|
|
23
|
-
import { subagentsHandler } from './subagents.js';
|
|
24
|
-
import { WorkflowsHandler } from './workflows.js';
|
|
25
|
-
/** All resource handlers keyed by kind. */
|
|
26
|
-
export const handlers = {
|
|
27
|
-
command: commandsHandler,
|
|
28
|
-
commands: commandsHandler,
|
|
29
|
-
hook: HooksHandler,
|
|
30
|
-
hooks: HooksHandler,
|
|
31
|
-
skill: SkillsHandler,
|
|
32
|
-
skills: SkillsHandler,
|
|
33
|
-
rule: RulesHandler,
|
|
34
|
-
rules: RulesHandler,
|
|
35
|
-
mcp: McpHandler,
|
|
36
|
-
permission: PermissionsHandler,
|
|
37
|
-
permissions: PermissionsHandler,
|
|
38
|
-
subagent: subagentsHandler,
|
|
39
|
-
subagents: subagentsHandler,
|
|
40
|
-
workflow: WorkflowsHandler,
|
|
41
|
-
workflows: WorkflowsHandler,
|
|
42
|
-
};
|
|
43
|
-
/** Get a handler by resource kind. */
|
|
44
|
-
export function getHandler(kind) {
|
|
45
|
-
switch (kind) {
|
|
46
|
-
case 'command':
|
|
47
|
-
return commandsHandler;
|
|
48
|
-
case 'hook':
|
|
49
|
-
return HooksHandler;
|
|
50
|
-
case 'skill':
|
|
51
|
-
return SkillsHandler;
|
|
52
|
-
case 'rule':
|
|
53
|
-
return RulesHandler;
|
|
54
|
-
case 'mcp':
|
|
55
|
-
return McpHandler;
|
|
56
|
-
case 'permission':
|
|
57
|
-
return PermissionsHandler;
|
|
58
|
-
case 'subagent':
|
|
59
|
-
return subagentsHandler;
|
|
60
|
-
case 'workflow':
|
|
61
|
-
return WorkflowsHandler;
|
|
62
|
-
default:
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/** All resource kinds. */
|
|
67
|
-
export const RESOURCE_KINDS = [
|
|
68
|
-
'command',
|
|
69
|
-
'hook',
|
|
70
|
-
'skill',
|
|
71
|
-
'rule',
|
|
72
|
-
'mcp',
|
|
73
|
-
'permission',
|
|
74
|
-
'subagent',
|
|
75
|
-
'workflow',
|
|
76
|
-
];
|