agent-relay 12.2.3 → 12.2.4
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/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +12 -5
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/commands/cloud-v1-deprecations.d.ts +44 -0
- package/dist/cli/commands/cloud-v1-deprecations.d.ts.map +1 -0
- package/dist/cli/commands/cloud-v1-deprecations.js +108 -0
- package/dist/cli/commands/cloud-v1-deprecations.js.map +1 -0
- package/dist/cli/commands/cloud.d.ts.map +1 -1
- package/dist/cli/commands/cloud.js +3 -0
- package/dist/cli/commands/cloud.js.map +1 -1
- package/dist/cli/commands/local-workflow.d.ts.map +1 -1
- package/dist/cli/commands/local-workflow.js +3 -0
- package/dist/cli/commands/local-workflow.js.map +1 -1
- package/dist/cli/commands/product-surfaces.d.ts +67 -0
- package/dist/cli/commands/product-surfaces.d.ts.map +1 -0
- package/dist/cli/commands/product-surfaces.js +165 -0
- package/dist/cli/commands/product-surfaces.js.map +1 -0
- package/dist/cli/commands/session.d.ts +17 -0
- package/dist/cli/commands/session.d.ts.map +1 -1
- package/dist/cli/commands/session.js +65 -1
- package/dist/cli/commands/session.js.map +1 -1
- package/dist/cli/lib/deprecate-command.d.ts +74 -0
- package/dist/cli/lib/deprecate-command.d.ts.map +1 -0
- package/dist/cli/lib/deprecate-command.js +107 -0
- package/dist/cli/lib/deprecate-command.js.map +1 -0
- package/dist/cli/lib/relay-cli-surface.d.ts +93 -0
- package/dist/cli/lib/relay-cli-surface.d.ts.map +1 -0
- package/dist/cli/lib/relay-cli-surface.js +237 -0
- package/dist/cli/lib/relay-cli-surface.js.map +1 -0
- package/package.json +13 -9
- package/dist/cli/commands/reflex.d.ts +0 -18
- package/dist/cli/commands/reflex.d.ts.map +0 -1
- package/dist/cli/commands/reflex.js +0 -181
- package/dist/cli/commands/reflex.js.map +0 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single generic mount point for Relay product CLIs.
|
|
3
|
+
*
|
|
4
|
+
* `agent-relay file`, `agent-relay flows`, and `agent-relay sessions` are all
|
|
5
|
+
* this module. Each product repo (relayfile, flows, relayhistory) ships a
|
|
6
|
+
* {@link RelayCliSurface} describing and dispatching its own commands; this
|
|
7
|
+
* host renders help from the declared tree and forwards everything else to the
|
|
8
|
+
* product verbatim. No product command is reimplemented here — if a command
|
|
9
|
+
* needs to change, it changes in the product repo.
|
|
10
|
+
*
|
|
11
|
+
* Two deliberate choices:
|
|
12
|
+
*
|
|
13
|
+
* - **Argv is forwarded untouched.** Commander parses only far enough to find
|
|
14
|
+
* the group, then hands the remaining tokens straight to `surface.run`. A
|
|
15
|
+
* re-serialized option list would silently drop product flags the host has
|
|
16
|
+
* never heard of.
|
|
17
|
+
* - **Help is rendered from the spec, not forwarded.** Asking the product to
|
|
18
|
+
* print its own help yields its own program name (`relayfile ls …`), which is
|
|
19
|
+
* wrong once mounted. Rendering from `commands` keeps `agent-relay file ls`
|
|
20
|
+
* in the usage line and makes every product's help look the same.
|
|
21
|
+
*/
|
|
22
|
+
import { type Command } from 'commander';
|
|
23
|
+
import type { RelayCliCommandSpec, RelayCliIo, RelayCliSurface } from '@agent-relay/cli-surface';
|
|
24
|
+
/** Injectable seams; the defaults are the real process. */
|
|
25
|
+
export interface RelayCliSurfaceDependencies {
|
|
26
|
+
io: RelayCliIo;
|
|
27
|
+
exit: (code: number) => never;
|
|
28
|
+
}
|
|
29
|
+
export interface MountSurfaceOptions {
|
|
30
|
+
/** Group name under `agent-relay`, e.g. `file`. */
|
|
31
|
+
as: string;
|
|
32
|
+
/** One-line description for `agent-relay --help`. */
|
|
33
|
+
description: string;
|
|
34
|
+
/**
|
|
35
|
+
* Import and construct the surface.
|
|
36
|
+
*
|
|
37
|
+
* Called only once the group is actually invoked. Product SDKs are heavy
|
|
38
|
+
* (the relayfile SDK resolves a Go binary, the flows SDK pulls a runtime),
|
|
39
|
+
* so importing them eagerly would tax every `agent-relay` invocation
|
|
40
|
+
* including `--help`.
|
|
41
|
+
*/
|
|
42
|
+
load: () => Promise<RelayCliSurface>;
|
|
43
|
+
/**
|
|
44
|
+
* Extra group names that reach the same surface, hidden from help.
|
|
45
|
+
*
|
|
46
|
+
* Used to keep `agent-relay session …` working after it was absorbed into
|
|
47
|
+
* `agent-relay sessions`.
|
|
48
|
+
*/
|
|
49
|
+
hiddenAliases?: readonly string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Walk `argv` down the spec tree as far as it matches.
|
|
53
|
+
*
|
|
54
|
+
* @returns The deepest matched command (undefined at the group root), the path
|
|
55
|
+
* taken, and the first token that did not match a subcommand.
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveSpecPath(commands: readonly RelayCliCommandSpec[], argv: readonly string[]): {
|
|
58
|
+
command: RelayCliCommandSpec | undefined;
|
|
59
|
+
path: readonly string[];
|
|
60
|
+
/** Tokens left once matching stopped, including the one that failed to match. */
|
|
61
|
+
rest: readonly string[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Render help for one node of a product command tree.
|
|
65
|
+
*
|
|
66
|
+
* @param groupPath - How the user reached here, e.g. `agent-relay file ls`.
|
|
67
|
+
* @param command - The resolved spec node, or undefined for the group root.
|
|
68
|
+
* @param roots - The surface's top-level commands, used at the group root.
|
|
69
|
+
* @returns The help text, newline-terminated.
|
|
70
|
+
*/
|
|
71
|
+
export declare function renderSurfaceHelp(groupPath: string, command: RelayCliCommandSpec | undefined, roots: readonly RelayCliCommandSpec[]): string;
|
|
72
|
+
/**
|
|
73
|
+
* Run one invocation against a loaded surface.
|
|
74
|
+
*
|
|
75
|
+
* Exported for tests and for the hidden-alias path; `mountRelayCliSurface` is
|
|
76
|
+
* the normal entry point.
|
|
77
|
+
*
|
|
78
|
+
* @param surface - The product surface.
|
|
79
|
+
* @param groupPath - Display path for help and notices, e.g. `agent-relay file`.
|
|
80
|
+
* @param argv - Tokens after the group name.
|
|
81
|
+
* @param deps - Output sink and exit function.
|
|
82
|
+
* @returns The exit code the host should use.
|
|
83
|
+
*/
|
|
84
|
+
export declare function runSurface(surface: RelayCliSurface, groupPath: string, argv: readonly string[], deps: RelayCliSurfaceDependencies): Promise<number>;
|
|
85
|
+
/**
|
|
86
|
+
* Mount a product CLI as a group on the `agent-relay` program.
|
|
87
|
+
*
|
|
88
|
+
* @param program - The root commander program.
|
|
89
|
+
* @param options - Group name, description, and the lazy surface loader.
|
|
90
|
+
* @param overrides - Test seams for io and exit.
|
|
91
|
+
*/
|
|
92
|
+
export declare function mountRelayCliSurface(program: Command, options: MountSurfaceOptions, overrides?: Partial<RelayCliSurfaceDependencies>): void;
|
|
93
|
+
//# sourceMappingURL=relay-cli-surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-cli-surface.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/relay-cli-surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQjG,2DAA2D;AAC3D,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACrC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAiBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,mBAAmB,EAAE,EACxC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB;IACD,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,iFAAiF;IACjF,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB,CAiBA;AAmBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,GAAG,SAAS,EACxC,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,MAAM,CAqDR;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,mBAAmB,EAC5B,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,IAAI,CAsCN"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single generic mount point for Relay product CLIs.
|
|
3
|
+
*
|
|
4
|
+
* `agent-relay file`, `agent-relay flows`, and `agent-relay sessions` are all
|
|
5
|
+
* this module. Each product repo (relayfile, flows, relayhistory) ships a
|
|
6
|
+
* {@link RelayCliSurface} describing and dispatching its own commands; this
|
|
7
|
+
* host renders help from the declared tree and forwards everything else to the
|
|
8
|
+
* product verbatim. No product command is reimplemented here — if a command
|
|
9
|
+
* needs to change, it changes in the product repo.
|
|
10
|
+
*
|
|
11
|
+
* Two deliberate choices:
|
|
12
|
+
*
|
|
13
|
+
* - **Argv is forwarded untouched.** Commander parses only far enough to find
|
|
14
|
+
* the group, then hands the remaining tokens straight to `surface.run`. A
|
|
15
|
+
* re-serialized option list would silently drop product flags the host has
|
|
16
|
+
* never heard of.
|
|
17
|
+
* - **Help is rendered from the spec, not forwarded.** Asking the product to
|
|
18
|
+
* print its own help yields its own program name (`relayfile ls …`), which is
|
|
19
|
+
* wrong once mounted. Rendering from `commands` keeps `agent-relay file ls`
|
|
20
|
+
* in the usage line and makes every product's help look the same.
|
|
21
|
+
*/
|
|
22
|
+
import { Help } from 'commander';
|
|
23
|
+
import { describeError } from './describe-error.js';
|
|
24
|
+
import { defaultExit } from './exit.js';
|
|
25
|
+
/** Exit code used when the argv names no command in the surface. */
|
|
26
|
+
const EXIT_UNKNOWN_COMMAND = 2;
|
|
27
|
+
function withDefaults(overrides) {
|
|
28
|
+
return {
|
|
29
|
+
io: overrides.io ?? {
|
|
30
|
+
stdout: (chunk) => process.stdout.write(chunk),
|
|
31
|
+
stderr: (chunk) => process.stderr.write(chunk),
|
|
32
|
+
},
|
|
33
|
+
exit: overrides.exit ?? defaultExit,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** True when the token asks for help rather than naming a command. */
|
|
37
|
+
function isHelpFlag(token) {
|
|
38
|
+
return token === '--help' || token === '-h' || token === 'help';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walk `argv` down the spec tree as far as it matches.
|
|
42
|
+
*
|
|
43
|
+
* @returns The deepest matched command (undefined at the group root), the path
|
|
44
|
+
* taken, and the first token that did not match a subcommand.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveSpecPath(commands, argv) {
|
|
47
|
+
let level = commands;
|
|
48
|
+
let command;
|
|
49
|
+
const path = [];
|
|
50
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
51
|
+
const token = argv[index];
|
|
52
|
+
// Stop at the first flag: everything after it belongs to the product.
|
|
53
|
+
if (token.startsWith('-'))
|
|
54
|
+
return { command, path, rest: argv.slice(index) };
|
|
55
|
+
const match = level.find((candidate) => candidate.name === token || candidate.aliases?.includes(token));
|
|
56
|
+
if (!match)
|
|
57
|
+
return { command, path, rest: argv.slice(index) };
|
|
58
|
+
command = match;
|
|
59
|
+
path.push(match.name);
|
|
60
|
+
level = match.subcommands ?? [];
|
|
61
|
+
}
|
|
62
|
+
return { command, path, rest: [] };
|
|
63
|
+
}
|
|
64
|
+
function renderUsage(groupPath, command) {
|
|
65
|
+
const parts = [groupPath];
|
|
66
|
+
if (command?.subcommands?.length)
|
|
67
|
+
parts.push('<command>');
|
|
68
|
+
for (const arg of command?.args ?? []) {
|
|
69
|
+
const name = arg.variadic ? `${arg.name}...` : arg.name;
|
|
70
|
+
parts.push(arg.required ? `<${name}>` : `[${name}]`);
|
|
71
|
+
}
|
|
72
|
+
if (command?.options?.length || !command)
|
|
73
|
+
parts.push('[options]');
|
|
74
|
+
return `Usage: ${parts.join(' ')}`;
|
|
75
|
+
}
|
|
76
|
+
function renderColumns(rows, indent = ' ') {
|
|
77
|
+
if (rows.length === 0)
|
|
78
|
+
return [];
|
|
79
|
+
const width = Math.max(...rows.map(([left]) => left.length));
|
|
80
|
+
return rows.map(([left, right]) => `${indent}${left.padEnd(width)} ${right}`);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Render help for one node of a product command tree.
|
|
84
|
+
*
|
|
85
|
+
* @param groupPath - How the user reached here, e.g. `agent-relay file ls`.
|
|
86
|
+
* @param command - The resolved spec node, or undefined for the group root.
|
|
87
|
+
* @param roots - The surface's top-level commands, used at the group root.
|
|
88
|
+
* @returns The help text, newline-terminated.
|
|
89
|
+
*/
|
|
90
|
+
export function renderSurfaceHelp(groupPath, command, roots) {
|
|
91
|
+
const lines = [renderUsage(groupPath, command), ''];
|
|
92
|
+
if (command?.description)
|
|
93
|
+
lines.push(command.description, '');
|
|
94
|
+
if (command?.deprecated) {
|
|
95
|
+
lines.push(`Deprecated. Use \`${command.deprecated.replacement}\` instead.`, '');
|
|
96
|
+
}
|
|
97
|
+
const args = command?.args ?? [];
|
|
98
|
+
if (args.length > 0) {
|
|
99
|
+
lines.push('Arguments:');
|
|
100
|
+
lines.push(...renderColumns(args.map((arg) => [arg.variadic ? `${arg.name}...` : arg.name, arg.description])));
|
|
101
|
+
lines.push('');
|
|
102
|
+
}
|
|
103
|
+
const options = command?.options ?? [];
|
|
104
|
+
if (options.length > 0) {
|
|
105
|
+
lines.push('Options:');
|
|
106
|
+
lines.push(...renderColumns(options.map((option) => [
|
|
107
|
+
option.flags,
|
|
108
|
+
option.defaultValue === undefined
|
|
109
|
+
? option.description
|
|
110
|
+
: `${option.description} (default: ${JSON.stringify(option.defaultValue)})`,
|
|
111
|
+
])));
|
|
112
|
+
lines.push('');
|
|
113
|
+
}
|
|
114
|
+
const children = (command?.subcommands ?? roots).filter((child) => !child.hidden);
|
|
115
|
+
if (children.length > 0) {
|
|
116
|
+
lines.push('Commands:');
|
|
117
|
+
lines.push(...renderColumns(children.map((child) => [child.name, child.deprecated ? `${child.description} (deprecated)` : child.description])));
|
|
118
|
+
lines.push('');
|
|
119
|
+
}
|
|
120
|
+
return `${lines.join('\n').trimEnd()}\n`;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Run one invocation against a loaded surface.
|
|
124
|
+
*
|
|
125
|
+
* Exported for tests and for the hidden-alias path; `mountRelayCliSurface` is
|
|
126
|
+
* the normal entry point.
|
|
127
|
+
*
|
|
128
|
+
* @param surface - The product surface.
|
|
129
|
+
* @param groupPath - Display path for help and notices, e.g. `agent-relay file`.
|
|
130
|
+
* @param argv - Tokens after the group name.
|
|
131
|
+
* @param deps - Output sink and exit function.
|
|
132
|
+
* @returns The exit code the host should use.
|
|
133
|
+
*/
|
|
134
|
+
export async function runSurface(surface, groupPath, argv, deps) {
|
|
135
|
+
const resolved = resolveSpecPath(surface.commands, argv);
|
|
136
|
+
const wantsHelp = argv.length === 0 || argv.some(isHelpFlag);
|
|
137
|
+
if (wantsHelp) {
|
|
138
|
+
// `--help` after a partially-matched path still documents the deepest node
|
|
139
|
+
// we recognised, which is what the user was asking about.
|
|
140
|
+
deps.io.stdout(renderSurfaceHelp([groupPath, ...resolved.path].join(' '), resolved.command, surface.commands));
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
if (!resolved.command) {
|
|
144
|
+
const unknown = resolved.rest[0] ?? argv[0] ?? '';
|
|
145
|
+
const available = surface.commands
|
|
146
|
+
.filter((command) => !command.hidden)
|
|
147
|
+
.map((command) => command.name)
|
|
148
|
+
.join(', ');
|
|
149
|
+
deps.io.stderr(`error: unknown command '${unknown}' for \`${groupPath}\`\n` +
|
|
150
|
+
`Available commands: ${available}\n` +
|
|
151
|
+
`Run \`${groupPath} --help\` for usage.\n`);
|
|
152
|
+
return EXIT_UNKNOWN_COMMAND;
|
|
153
|
+
}
|
|
154
|
+
if (resolved.command.deprecated) {
|
|
155
|
+
const { replacement, since } = resolved.command.deprecated;
|
|
156
|
+
deps.io.stderr(`warning: \`${[groupPath, ...resolved.path].join(' ')}\` is deprecated` +
|
|
157
|
+
`${since ? ` since ${since}` : ''}. Use \`${replacement}\` instead.\n`);
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
return await surface.run(argv, deps.io);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
// A product throwing instead of returning a code is a contract violation,
|
|
164
|
+
// but it must not surface as an unhandled rejection from the host.
|
|
165
|
+
deps.io.stderr(`${describeError(error)}\n`);
|
|
166
|
+
return 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Mount a product CLI as a group on the `agent-relay` program.
|
|
171
|
+
*
|
|
172
|
+
* @param program - The root commander program.
|
|
173
|
+
* @param options - Group name, description, and the lazy surface loader.
|
|
174
|
+
* @param overrides - Test seams for io and exit.
|
|
175
|
+
*/
|
|
176
|
+
export function mountRelayCliSurface(program, options, overrides = {}) {
|
|
177
|
+
const deps = withDefaults(overrides);
|
|
178
|
+
renderGroupTermsWithoutArgv(program);
|
|
179
|
+
const attach = (name, hidden) => {
|
|
180
|
+
program
|
|
181
|
+
.command(name, { hidden })
|
|
182
|
+
.description(options.description)
|
|
183
|
+
// The product owns its flags; commander must not reject or consume them.
|
|
184
|
+
.allowUnknownOption(true)
|
|
185
|
+
.allowExcessArguments(true)
|
|
186
|
+
// Without this, `agent-relay file --json` is parsed as a root-level flag.
|
|
187
|
+
.enablePositionalOptions()
|
|
188
|
+
.passThroughOptions()
|
|
189
|
+
// Help is rendered from the surface spec, so commander must not intercept.
|
|
190
|
+
.helpOption(false)
|
|
191
|
+
.argument('[args...]', `Arguments passed through to ${options.as}`)
|
|
192
|
+
.action(async (args) => {
|
|
193
|
+
let surface;
|
|
194
|
+
try {
|
|
195
|
+
surface = await options.load();
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// Loading fails when the product package is missing or too old. The
|
|
199
|
+
// loader's message names the fix, so it must reach stderr as a plain
|
|
200
|
+
// line rather than escaping the action as an unhandled rejection.
|
|
201
|
+
deps.io.stderr(`${describeError(error)}\n`);
|
|
202
|
+
deps.exit(1);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const code = await runSurface(surface, `agent-relay ${options.as}`, args, deps);
|
|
206
|
+
if (code !== 0)
|
|
207
|
+
deps.exit(code);
|
|
208
|
+
});
|
|
209
|
+
};
|
|
210
|
+
mountedGroups.get(program).add(options.as);
|
|
211
|
+
attach(options.as, false);
|
|
212
|
+
for (const alias of options.hiddenAliases ?? [])
|
|
213
|
+
attach(alias, true);
|
|
214
|
+
}
|
|
215
|
+
/** Group names mounted on each program, so help can render them bare. */
|
|
216
|
+
const mountedGroups = new WeakMap();
|
|
217
|
+
/**
|
|
218
|
+
* Render mounted groups in the parent's help as a bare name.
|
|
219
|
+
*
|
|
220
|
+
* Commander derives a subcommand's help term from its registered arguments, so
|
|
221
|
+
* the catch-all that carries product argv would surface to users as
|
|
222
|
+
* `file [args...]`. The placeholder is an implementation detail of the mount;
|
|
223
|
+
* what a reader needs is `file`, with the real commands one level down.
|
|
224
|
+
*
|
|
225
|
+
* Installed once per program and consulted per render, so several mounts share it.
|
|
226
|
+
*/
|
|
227
|
+
function renderGroupTermsWithoutArgv(program) {
|
|
228
|
+
if (mountedGroups.has(program))
|
|
229
|
+
return;
|
|
230
|
+
const groups = new Set();
|
|
231
|
+
mountedGroups.set(program, groups);
|
|
232
|
+
const base = new Help();
|
|
233
|
+
program.configureHelp({
|
|
234
|
+
subcommandTerm: (cmd) => (groups.has(cmd.name()) ? cmd.name() : base.subcommandTerm(cmd)),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=relay-cli-surface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-cli-surface.js","sourceRoot":"","sources":["../../../src/cli/lib/relay-cli-surface.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay",
|
|
3
|
-
"version": "12.2.
|
|
3
|
+
"version": "12.2.4",
|
|
4
4
|
"description": "Real-time agent-to-agent communication system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -43,18 +43,22 @@
|
|
|
43
43
|
"pack:validate": "npm pack --dry-run"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@agent-relay/
|
|
47
|
-
"@agent-relay/
|
|
48
|
-
"@agent-relay/
|
|
49
|
-
"@agent-relay/
|
|
50
|
-
"@agent-relay/
|
|
51
|
-
"@agent-relay/
|
|
52
|
-
"@agent-relay/
|
|
53
|
-
"@agent-relay/
|
|
46
|
+
"@agent-relay/cli-surface": "12.2.4",
|
|
47
|
+
"@agent-relay/cloud": "12.2.4",
|
|
48
|
+
"@agent-relay/config": "12.2.4",
|
|
49
|
+
"@agent-relay/fleet": "12.2.4",
|
|
50
|
+
"@agent-relay/harness-driver": "12.2.4",
|
|
51
|
+
"@agent-relay/harnesses": "12.2.4",
|
|
52
|
+
"@agent-relay/sdk": "12.2.4",
|
|
53
|
+
"@agent-relay/session": "12.2.4",
|
|
54
|
+
"@agent-relay/utils": "12.2.4",
|
|
54
55
|
"@modelcontextprotocol/sdk": "^1.23.0",
|
|
55
56
|
"@relayfile/client": "^0.10.27",
|
|
57
|
+
"@relayfile/sdk": "^0.10.63",
|
|
56
58
|
"@relayflows/cli": "1.0.1",
|
|
59
|
+
"@relayflows/sdk": "^2.0.16",
|
|
57
60
|
"@xterm/headless": "^6.0.0",
|
|
61
|
+
"ai-hist": "^0.18.0",
|
|
58
62
|
"commander": "^12.1.0",
|
|
59
63
|
"dotenv": "^17.2.3",
|
|
60
64
|
"jiti": "^2.6.1",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
export type LoginCloudResult = {
|
|
3
|
-
ok: true;
|
|
4
|
-
} | {
|
|
5
|
-
ok: false;
|
|
6
|
-
error: string;
|
|
7
|
-
};
|
|
8
|
-
export interface ReflexDependencies {
|
|
9
|
-
homedir: () => string;
|
|
10
|
-
readRelayAuth: () => Promise<{
|
|
11
|
-
accessToken: string;
|
|
12
|
-
} | null>;
|
|
13
|
-
loginToCloud: (relayAccessToken: string) => Promise<LoginCloudResult>;
|
|
14
|
-
prompt: (question: string) => Promise<boolean>;
|
|
15
|
-
log: (...args: unknown[]) => void;
|
|
16
|
-
}
|
|
17
|
-
export declare function registerReflexCommands(program: Command, overrides?: Partial<ReflexDependencies>): void;
|
|
18
|
-
//# sourceMappingURL=reflex.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reflex.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/reflex.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,YAAY,EAAE,CAAC,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACnC;AAyHD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAM,GAAG,IAAI,CA+E1G"}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { chmod, mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import readline from 'node:readline';
|
|
5
|
-
import { readReflexState, writeReflexState } from '@agent-relay/config';
|
|
6
|
-
const ALLOWED_RELAYHISTORY_HOSTS = new Set(['history.agentrelay.com']);
|
|
7
|
-
function validateRelayhistoryBaseUrl(raw) {
|
|
8
|
-
let parsed;
|
|
9
|
-
try {
|
|
10
|
-
parsed = new URL(raw);
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return { ok: false, error: `AI_HIST_BASE_URL is not a valid URL: ${raw}` };
|
|
14
|
-
}
|
|
15
|
-
const isLocalDev = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1' || parsed.hostname === '::1';
|
|
16
|
-
if (!isLocalDev && !ALLOWED_RELAYHISTORY_HOSTS.has(parsed.hostname)) {
|
|
17
|
-
return {
|
|
18
|
-
ok: false,
|
|
19
|
-
error: `AI_HIST_BASE_URL hostname "${parsed.hostname}" is not an allowed relayhistory host`,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
return { ok: true, url: parsed };
|
|
23
|
-
}
|
|
24
|
-
function promptYesNo(question) {
|
|
25
|
-
if (!process.stdin.isTTY) {
|
|
26
|
-
return Promise.resolve(false);
|
|
27
|
-
}
|
|
28
|
-
const rl = readline.createInterface({
|
|
29
|
-
input: process.stdin,
|
|
30
|
-
output: process.stdout,
|
|
31
|
-
});
|
|
32
|
-
return new Promise((resolve) => {
|
|
33
|
-
rl.question(question, (answer) => {
|
|
34
|
-
rl.close();
|
|
35
|
-
const normalized = answer.trim().toLowerCase();
|
|
36
|
-
resolve(normalized === 'y' || normalized === 'yes');
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
async function defaultReadRelayAuth() {
|
|
41
|
-
const { readStoredAuth } = await import('@agent-relay/cloud');
|
|
42
|
-
return readStoredAuth();
|
|
43
|
-
}
|
|
44
|
-
async function defaultLoginToCloud(relayAccessToken) {
|
|
45
|
-
const rawBase = process.env.AI_HIST_BASE_URL ?? 'https://history.agentrelay.com';
|
|
46
|
-
const validated = validateRelayhistoryBaseUrl(rawBase);
|
|
47
|
-
if (!validated.ok) {
|
|
48
|
-
return { ok: false, error: validated.error };
|
|
49
|
-
}
|
|
50
|
-
const url = `${rawBase.replace(/\/$/, '')}/v1/cli/login`;
|
|
51
|
-
let resp;
|
|
52
|
-
try {
|
|
53
|
-
resp = await fetch(url, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
headers: { 'Content-Type': 'application/json' },
|
|
56
|
-
body: JSON.stringify({ agentRelayToken: relayAccessToken }),
|
|
57
|
-
signal: AbortSignal.timeout(15_000),
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
return { ok: false, error: `Network error: ${err instanceof Error ? err.message : String(err)}` };
|
|
62
|
-
}
|
|
63
|
-
if (!resp.ok) {
|
|
64
|
-
const text = await resp.text().catch(() => '');
|
|
65
|
-
return { ok: false, error: `Login failed (HTTP ${resp.status}): ${text.slice(0, 200)}` };
|
|
66
|
-
}
|
|
67
|
-
let payload;
|
|
68
|
-
try {
|
|
69
|
-
const raw = await resp.json();
|
|
70
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
71
|
-
return { ok: false, error: 'Login response has unexpected shape' };
|
|
72
|
-
}
|
|
73
|
-
payload = raw;
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
return { ok: false, error: 'Login response was not valid JSON' };
|
|
77
|
-
}
|
|
78
|
-
if (typeof payload.accessToken !== 'string') {
|
|
79
|
-
return { ok: false, error: 'Login response missing accessToken' };
|
|
80
|
-
}
|
|
81
|
-
// Persist the rth_at_ session where the `ai-hist` Rust binary reads it, so the
|
|
82
|
-
// in-process cloud push (which drives `ai-hist push`) authenticates on later
|
|
83
|
-
// runs. The binary reads $RELAYHISTORY_HOME/auth.json (default
|
|
84
|
-
// ~/.agentworkforce/relayhistory/auth.json) in snake_case.
|
|
85
|
-
try {
|
|
86
|
-
const authDir = process.env.RELAYHISTORY_HOME ?? path.join(os.homedir(), '.agentworkforce', 'relayhistory');
|
|
87
|
-
const authPath = path.join(authDir, 'auth.json');
|
|
88
|
-
const auth = {
|
|
89
|
-
base_url: rawBase.replace(/\/$/, ''),
|
|
90
|
-
access_token: payload.accessToken,
|
|
91
|
-
...(typeof payload.refreshToken === 'string' ? { refresh_token: payload.refreshToken } : {}),
|
|
92
|
-
};
|
|
93
|
-
await mkdir(authDir, { recursive: true });
|
|
94
|
-
await writeFile(authPath, JSON.stringify(auth, null, 2));
|
|
95
|
-
// Explicitly tighten perms — writeFile mode only applies to newly created files.
|
|
96
|
-
await chmod(authPath, 0o600);
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// Non-fatal: local state is written; cloud sync may prompt again next run.
|
|
100
|
-
}
|
|
101
|
-
return { ok: true };
|
|
102
|
-
}
|
|
103
|
-
function withDefaults(overrides = {}) {
|
|
104
|
-
return {
|
|
105
|
-
homedir: os.homedir,
|
|
106
|
-
readRelayAuth: defaultReadRelayAuth,
|
|
107
|
-
loginToCloud: defaultLoginToCloud,
|
|
108
|
-
prompt: promptYesNo,
|
|
109
|
-
log: (...args) => console.log(...args),
|
|
110
|
-
...overrides,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
export function registerReflexCommands(program, overrides = {}) {
|
|
114
|
-
const deps = withDefaults(overrides);
|
|
115
|
-
const reflex = program.command('reflex').description('Manage Reflex history sync');
|
|
116
|
-
reflex
|
|
117
|
-
.command('on')
|
|
118
|
-
.description('Enable Reflex history sync')
|
|
119
|
-
.action(async () => {
|
|
120
|
-
deps.log('Reflex will capture your agent sessions and sync to history.agentrelay.com');
|
|
121
|
-
const accepted = await deps.prompt('Enable Reflex? (y/N) ');
|
|
122
|
-
if (!accepted) {
|
|
123
|
-
deps.log('Reflex was not enabled.');
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
writeReflexState({
|
|
127
|
-
enabled: true,
|
|
128
|
-
enabledAt: new Date().toISOString(),
|
|
129
|
-
}, deps.homedir());
|
|
130
|
-
const relayAuth = await deps.readRelayAuth();
|
|
131
|
-
let cloudSyncActive = false;
|
|
132
|
-
if (!relayAuth) {
|
|
133
|
-
deps.log('Not logged in to Agent Relay. Run `agent-relay login` first to sync Reflex history to the cloud.');
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
const result = await deps.loginToCloud(relayAuth.accessToken);
|
|
137
|
-
if (result.ok) {
|
|
138
|
-
cloudSyncActive = true;
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
deps.log(`Reflex is enabled locally, but cloud login did not complete: ${result.error}`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
deps.log('Reflex is on.');
|
|
145
|
-
// Only promise automatic cloud sync when cloud auth actually succeeded —
|
|
146
|
-
// otherwise the message would contradict the login warning above.
|
|
147
|
-
if (cloudSyncActive) {
|
|
148
|
-
deps.log('History syncs to relayhistory-cloud automatically while `agent-relay up` is running.');
|
|
149
|
-
}
|
|
150
|
-
deps.log('State file: ~/.agentworkforce/reflex.json');
|
|
151
|
-
});
|
|
152
|
-
reflex
|
|
153
|
-
.command('off')
|
|
154
|
-
.description('Disable Reflex history sync')
|
|
155
|
-
.action(() => {
|
|
156
|
-
writeReflexState({ enabled: false }, deps.homedir());
|
|
157
|
-
deps.log('Reflex is off.');
|
|
158
|
-
});
|
|
159
|
-
reflex
|
|
160
|
-
.command('status')
|
|
161
|
-
.description('Show Reflex status')
|
|
162
|
-
.action(() => {
|
|
163
|
-
const state = readReflexState(deps.homedir());
|
|
164
|
-
if (!state) {
|
|
165
|
-
deps.log('Reflex is off (never enabled).');
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (state.enabled) {
|
|
169
|
-
deps.log('Reflex is on.');
|
|
170
|
-
if (state.enabledAt) {
|
|
171
|
-
deps.log(`Enabled at: ${state.enabledAt}`);
|
|
172
|
-
}
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
deps.log('Reflex is off.');
|
|
176
|
-
if (state.enabledAt) {
|
|
177
|
-
deps.log(`Enabled at: ${state.enabledAt}`);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
//# sourceMappingURL=reflex.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reflex.js","sourceRoot":"","sources":["../../../src/cli/commands/reflex.ts"],"names":[],"mappings":"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"}
|