@relaymessenger/cli 0.4.4 → 0.5.0-staging.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/README.md +108 -118
- package/dist/cli.js +2 -172
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +13 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +206 -0
- package/dist/config.js.map +1 -0
- package/dist/doctor.d.ts +20 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +73 -112
- package/dist/doctor.js.map +1 -1
- package/dist/event-listen.d.ts +11 -0
- package/dist/event-listen.d.ts.map +1 -0
- package/dist/event-listen.js +37 -0
- package/dist/event-listen.js.map +1 -0
- package/dist/output.d.ts +4 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +26 -0
- package/dist/output.js.map +1 -0
- package/dist/program.d.ts +14 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +655 -0
- package/dist/program.js.map +1 -0
- package/package.json +31 -37
- package/claude-plugin/marketplace/.claude-plugin/marketplace.json +0 -14
- package/claude-plugin/marketplace/plugins/relay/.claude-plugin/plugin.json +0 -27
- package/claude-plugin/marketplace/plugins/relay/LICENSE +0 -21
- package/claude-plugin/marketplace/plugins/relay/README.md +0 -173
- package/claude-plugin/marketplace/plugins/relay/commands/configure.md +0 -71
- package/claude-plugin/marketplace/plugins/relay/runtime/server.mjs +0 -26197
- package/dist/api.d.ts +0 -114
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -162
- package/dist/api.js.map +0 -1
- package/dist/claude-settings.d.ts +0 -14
- package/dist/claude-settings.d.ts.map +0 -1
- package/dist/claude-settings.js +0 -47
- package/dist/claude-settings.js.map +0 -1
- package/dist/codex.d.ts +0 -25
- package/dist/codex.d.ts.map +0 -1
- package/dist/codex.js +0 -237
- package/dist/codex.js.map +0 -1
- package/dist/engine/acp.d.ts +0 -74
- package/dist/engine/acp.d.ts.map +0 -1
- package/dist/engine/acp.js +0 -413
- package/dist/engine/acp.js.map +0 -1
- package/dist/engine/catalog.d.ts +0 -26
- package/dist/engine/catalog.d.ts.map +0 -1
- package/dist/engine/catalog.js +0 -41
- package/dist/engine/catalog.js.map +0 -1
- package/dist/engine/process.d.ts +0 -12
- package/dist/engine/process.d.ts.map +0 -1
- package/dist/engine/process.js +0 -54
- package/dist/engine/process.js.map +0 -1
- package/dist/engine/types.d.ts +0 -57
- package/dist/engine/types.d.ts.map +0 -1
- package/dist/engine/types.js +0 -8
- package/dist/engine/types.js.map +0 -1
- package/dist/flags.d.ts +0 -9
- package/dist/flags.d.ts.map +0 -1
- package/dist/flags.js +0 -34
- package/dist/flags.js.map +0 -1
- package/dist/install.d.ts +0 -69
- package/dist/install.d.ts.map +0 -1
- package/dist/install.js +0 -513
- package/dist/install.js.map +0 -1
- package/dist/mcp.d.ts +0 -16
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js +0 -127
- package/dist/mcp.js.map +0 -1
- package/dist/pair.d.ts +0 -20
- package/dist/pair.d.ts.map +0 -1
- package/dist/pair.js +0 -135
- package/dist/pair.js.map +0 -1
- package/dist/permissions.d.ts +0 -90
- package/dist/permissions.d.ts.map +0 -1
- package/dist/permissions.js +0 -361
- package/dist/permissions.js.map +0 -1
- package/dist/receive.d.ts +0 -113
- package/dist/receive.d.ts.map +0 -1
- package/dist/receive.js +0 -596
- package/dist/receive.js.map +0 -1
- package/dist/store.d.ts +0 -301
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -551
- package/dist/store.js.map +0 -1
- package/openclaw-plugin/relaymessenger-openclaw-plugin-0.3.3.tgz +0 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { chmod, mkdir, open, readFile, rename, stat, } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
export const DEFAULT_API_URL = "https://api.relayapp.im";
|
|
5
|
+
export const DEFAULT_PROFILE = "default";
|
|
6
|
+
const contextEnv = (context) => context.env ?? process.env;
|
|
7
|
+
export const configPath = (context = {}) => {
|
|
8
|
+
const env = contextEnv(context);
|
|
9
|
+
if (env.RELAY_CONFIG_PATH) {
|
|
10
|
+
if (!isAbsolute(env.RELAY_CONFIG_PATH)) {
|
|
11
|
+
throw new Error("RELAY_CONFIG_PATH must be absolute.");
|
|
12
|
+
}
|
|
13
|
+
return env.RELAY_CONFIG_PATH;
|
|
14
|
+
}
|
|
15
|
+
const root = env.RELAY_CONFIG_DIR
|
|
16
|
+
?? env.XDG_CONFIG_HOME
|
|
17
|
+
?? join(context.home ?? homedir(), ".config");
|
|
18
|
+
return resolve(root, "relay", "config.json");
|
|
19
|
+
};
|
|
20
|
+
export const emptyConfig = () => ({
|
|
21
|
+
version: 1,
|
|
22
|
+
current_profile: DEFAULT_PROFILE,
|
|
23
|
+
profiles: {
|
|
24
|
+
[DEFAULT_PROFILE]: { api_url: DEFAULT_API_URL },
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
28
|
+
const parseConfig = (value) => {
|
|
29
|
+
if (!isRecord(value) || value.version !== 1) {
|
|
30
|
+
throw new Error("Relay config has an unsupported format.");
|
|
31
|
+
}
|
|
32
|
+
if (typeof value.current_profile !== "string"
|
|
33
|
+
|| !isRecord(value.profiles)) {
|
|
34
|
+
throw new Error("Relay config is invalid.");
|
|
35
|
+
}
|
|
36
|
+
const profiles = {};
|
|
37
|
+
for (const [name, profile] of Object.entries(value.profiles)) {
|
|
38
|
+
validateProfileName(name);
|
|
39
|
+
if (!isRecord(profile))
|
|
40
|
+
throw new Error(`Relay profile ${name} is invalid.`);
|
|
41
|
+
const apiURL = profile.api_url;
|
|
42
|
+
const token = profile.agent_token;
|
|
43
|
+
if (apiURL !== undefined && typeof apiURL !== "string") {
|
|
44
|
+
throw new Error(`Relay profile ${name} has an invalid API URL.`);
|
|
45
|
+
}
|
|
46
|
+
if (token !== undefined && typeof token !== "string") {
|
|
47
|
+
throw new Error(`Relay profile ${name} has an invalid Agent Token.`);
|
|
48
|
+
}
|
|
49
|
+
profiles[name] = {
|
|
50
|
+
...(apiURL === undefined ? {} : { api_url: validateApiURL(apiURL) }),
|
|
51
|
+
...(token === undefined ? {} : { agent_token: validateToken(token) }),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (!profiles[value.current_profile]) {
|
|
55
|
+
throw new Error("Relay config selects a missing profile.");
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
version: 1,
|
|
59
|
+
current_profile: value.current_profile,
|
|
60
|
+
profiles,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export const readConfig = async (context = {}) => {
|
|
64
|
+
try {
|
|
65
|
+
const raw = await readFile(configPath(context), "utf8");
|
|
66
|
+
return parseConfig(JSON.parse(raw));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof Error
|
|
70
|
+
&& "code" in error
|
|
71
|
+
&& error.code === "ENOENT") {
|
|
72
|
+
return emptyConfig();
|
|
73
|
+
}
|
|
74
|
+
if (error instanceof SyntaxError) {
|
|
75
|
+
throw new Error("Relay config is not valid JSON.", { cause: error });
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const writeConfig = async (config, context = {}) => {
|
|
81
|
+
const path = configPath(context);
|
|
82
|
+
const directory = dirname(path);
|
|
83
|
+
const normalized = parseConfig(config);
|
|
84
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
85
|
+
if ((context.platform ?? process.platform) !== "win32") {
|
|
86
|
+
await chmod(directory, 0o700);
|
|
87
|
+
}
|
|
88
|
+
const temporary = join(directory, `.config.${process.pid}.${Date.now()}.tmp`);
|
|
89
|
+
const handle = await open(temporary, "wx", 0o600);
|
|
90
|
+
try {
|
|
91
|
+
await handle.writeFile(`${JSON.stringify(normalized, null, 2)}\n`, "utf8");
|
|
92
|
+
await handle.sync();
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await handle.close();
|
|
96
|
+
}
|
|
97
|
+
await rename(temporary, path);
|
|
98
|
+
if ((context.platform ?? process.platform) !== "win32") {
|
|
99
|
+
await chmod(path, 0o600);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
export const validateProfileName = (name) => {
|
|
103
|
+
if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(name)) {
|
|
104
|
+
throw new Error("Profile names must be 1-64 letters, numbers, underscores, or hyphens.");
|
|
105
|
+
}
|
|
106
|
+
return name;
|
|
107
|
+
};
|
|
108
|
+
const isLoopback = (hostname) => hostname === "localhost"
|
|
109
|
+
|| hostname === "127.0.0.1"
|
|
110
|
+
|| hostname === "::1"
|
|
111
|
+
|| hostname === "[::1]";
|
|
112
|
+
export const validateApiURL = (input) => {
|
|
113
|
+
let url;
|
|
114
|
+
try {
|
|
115
|
+
url = new URL(input);
|
|
116
|
+
}
|
|
117
|
+
catch (cause) {
|
|
118
|
+
throw new Error("Relay API URL must be an absolute URL.", { cause });
|
|
119
|
+
}
|
|
120
|
+
if (url.username || url.password || url.search || url.hash) {
|
|
121
|
+
throw new Error("Relay API URL cannot contain credentials, query, or hash.");
|
|
122
|
+
}
|
|
123
|
+
if (url.pathname !== "/" && url.pathname !== "") {
|
|
124
|
+
throw new Error("Relay API URL must be an origin without a path.");
|
|
125
|
+
}
|
|
126
|
+
if (url.protocol !== "https:"
|
|
127
|
+
&& !(url.protocol === "http:" && isLoopback(url.hostname))) {
|
|
128
|
+
throw new Error("Relay API URL must use HTTPS (HTTP is loopback-only).");
|
|
129
|
+
}
|
|
130
|
+
return url.origin;
|
|
131
|
+
};
|
|
132
|
+
export const validateForwardURL = (input) => {
|
|
133
|
+
let url;
|
|
134
|
+
try {
|
|
135
|
+
url = new URL(input);
|
|
136
|
+
}
|
|
137
|
+
catch (cause) {
|
|
138
|
+
throw new Error("Forward URL must be absolute.", { cause });
|
|
139
|
+
}
|
|
140
|
+
if (!isLoopback(url.hostname)
|
|
141
|
+
|| (url.protocol !== "http:" && url.protocol !== "https:")
|
|
142
|
+
|| url.username
|
|
143
|
+
|| url.password) {
|
|
144
|
+
throw new Error("Forward URL must be loopback HTTP(S) without credentials.");
|
|
145
|
+
}
|
|
146
|
+
return url.toString();
|
|
147
|
+
};
|
|
148
|
+
export const validateToken = (value) => {
|
|
149
|
+
const token = value.trim();
|
|
150
|
+
if (!token || /[\r\n\0]/.test(token)) {
|
|
151
|
+
throw new Error("Agent Token is empty or malformed.");
|
|
152
|
+
}
|
|
153
|
+
return token;
|
|
154
|
+
};
|
|
155
|
+
export const resolveAuth = async (requestedProfile, context = {}) => {
|
|
156
|
+
const env = contextEnv(context);
|
|
157
|
+
const config = await readConfig(context);
|
|
158
|
+
const profile = validateProfileName(requestedProfile ?? env.RELAY_PROFILE ?? config.current_profile);
|
|
159
|
+
const selected = config.profiles[profile];
|
|
160
|
+
if (!selected)
|
|
161
|
+
throw new Error(`Relay profile ${profile} does not exist.`);
|
|
162
|
+
const apiURL = validateApiURL(env.RELAY_API_URL ?? selected.api_url ?? DEFAULT_API_URL);
|
|
163
|
+
const envToken = env.RELAY_AGENT_TOKEN;
|
|
164
|
+
const token = envToken === undefined
|
|
165
|
+
? selected.agent_token
|
|
166
|
+
: validateToken(envToken);
|
|
167
|
+
if (!token) {
|
|
168
|
+
throw new Error(`No Agent Token for profile ${profile}. Run relay auth login --token-stdin.`);
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
profile,
|
|
172
|
+
apiURL,
|
|
173
|
+
token: validateToken(token),
|
|
174
|
+
tokenSource: envToken === undefined ? "profile" : "environment",
|
|
175
|
+
configPath: configPath(context),
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
export const inspectConfigPermissions = async (context = {}) => {
|
|
179
|
+
try {
|
|
180
|
+
const info = await stat(configPath(context));
|
|
181
|
+
const mode = info.mode & 0o777;
|
|
182
|
+
if ((context.platform ?? process.platform) === "win32") {
|
|
183
|
+
return { exists: true, secure: true, mode };
|
|
184
|
+
}
|
|
185
|
+
return { exists: true, secure: (mode & 0o077) === 0, mode };
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
if (error instanceof Error
|
|
189
|
+
&& "code" in error
|
|
190
|
+
&& error.code === "ENOENT") {
|
|
191
|
+
return { exists: false, secure: true };
|
|
192
|
+
}
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
export const collectConfiguredTokens = async (context = {}) => {
|
|
197
|
+
const config = await readConfig(context);
|
|
198
|
+
const tokens = Object.values(config.profiles)
|
|
199
|
+
.map((profile) => profile.agent_token)
|
|
200
|
+
.filter((token) => Boolean(token));
|
|
201
|
+
const envToken = contextEnv(context).RELAY_AGENT_TOKEN;
|
|
202
|
+
if (envToken)
|
|
203
|
+
tokens.push(envToken);
|
|
204
|
+
return [...new Set(tokens)];
|
|
205
|
+
};
|
|
206
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,2 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import type Relay from "@relaymessenger/sdk";
|
|
2
|
+
import type { ConfigContext } from "./config.js";
|
|
3
|
+
import { resolveAuth } from "./config.js";
|
|
4
|
+
export interface DoctorCheck {
|
|
5
|
+
name: string;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
detail: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DoctorReport {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
checks: DoctorCheck[];
|
|
12
|
+
}
|
|
13
|
+
export declare const runDoctor: (options: {
|
|
14
|
+
profile?: string;
|
|
15
|
+
offline?: boolean;
|
|
16
|
+
nodeVersion?: string;
|
|
17
|
+
}, dependencies: {
|
|
18
|
+
configContext?: ConfigContext;
|
|
19
|
+
createClient(auth: Awaited<ReturnType<typeof resolveAuth>>): Relay;
|
|
20
|
+
}) => Promise<DoctorReport>;
|
|
2
21
|
//# sourceMappingURL=doctor.d.ts.map
|
package/dist/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAEL,WAAW,EAEZ,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAWD,eAAO,MAAM,SAAS,GACpB,SAAS;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,cAAc;IACZ,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC;CACpE,KACA,OAAO,CAAC,YAAY,CAyEtB,CAAC"}
|
package/dist/doctor.js
CHANGED
|
@@ -1,122 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export async
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const client = new RelayClient(origin, loaded.agent_token);
|
|
41
|
-
const me = (await client.getMe());
|
|
42
|
-
const handle = me?.agent?.handle ?? me?.handle;
|
|
43
|
-
check(true, `API reachable (${origin})`, handle ? `@${handle}` : undefined);
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
check(false, `API reachable (${origin})`, String(error?.message ?? error));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
out(" run `relaymessenger pair` to connect this machine to a Relay agent");
|
|
51
|
-
}
|
|
52
|
-
if (loaded?.agent_token) {
|
|
53
|
-
// Match `start`: durable state is scoped to the effective origin.
|
|
54
|
-
let effectiveOrigin = loaded.api_origin;
|
|
55
|
-
try {
|
|
56
|
-
effectiveOrigin = resolveApiOrigin(loaded.api_origin);
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
// Invalid override already reported above; fall back to the paired origin.
|
|
60
|
-
}
|
|
61
|
-
const runtimeHome = runtimeHomeForConfig({ ...loaded, api_origin: effectiveOrigin }, dirname(config.path));
|
|
62
|
-
try {
|
|
63
|
-
const state = readStateSnapshot(runtimeHome);
|
|
64
|
-
const pendingEvents = Object.values(state.pending_events).reduce((sum, queue) => sum + queue.length, 0);
|
|
65
|
-
const pendingApprovals = new ApprovalStore(runtimeHome).list().length;
|
|
66
|
-
out(`info state: cursor=${state.cursor}, pending_events=${pendingEvents}, ` +
|
|
67
|
-
`pending_approvals=${pendingApprovals}, owner_conversation=${state.owner_conversation_id ?? "unset"} ` +
|
|
68
|
-
`(${join(runtimeHome, "state.json")})`);
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
check(false, "runtime state readable", String(error));
|
|
72
|
-
}
|
|
1
|
+
import { RELAY_V1_OPERATIONS } from "@relaymessenger/sdk";
|
|
2
|
+
import { inspectConfigPermissions, resolveAuth, validateApiURL, } from "./config.js";
|
|
3
|
+
const nodeIsSupported = (version) => {
|
|
4
|
+
const [major = 0, minor = 0, patch = 0] = version
|
|
5
|
+
.replace(/^v/, "")
|
|
6
|
+
.split(".")
|
|
7
|
+
.map(Number);
|
|
8
|
+
return major > 22
|
|
9
|
+
|| (major === 22 && (minor > 22 || (minor === 22 && patch >= 3)));
|
|
10
|
+
};
|
|
11
|
+
export const runDoctor = async (options, dependencies) => {
|
|
12
|
+
const checks = [];
|
|
13
|
+
const nodeVersion = options.nodeVersion ?? process.version;
|
|
14
|
+
checks.push({
|
|
15
|
+
name: "node",
|
|
16
|
+
ok: nodeIsSupported(nodeVersion),
|
|
17
|
+
detail: nodeVersion,
|
|
18
|
+
});
|
|
19
|
+
const permissions = await inspectConfigPermissions(dependencies.configContext);
|
|
20
|
+
checks.push({
|
|
21
|
+
name: "config_permissions",
|
|
22
|
+
ok: permissions.secure,
|
|
23
|
+
detail: permissions.exists
|
|
24
|
+
? `mode ${(permissions.mode ?? 0).toString(8).padStart(3, "0")}`
|
|
25
|
+
: "no local config (environment-only is allowed)",
|
|
26
|
+
});
|
|
27
|
+
let auth;
|
|
28
|
+
try {
|
|
29
|
+
auth = await resolveAuth(options.profile, dependencies.configContext);
|
|
30
|
+
checks.push({
|
|
31
|
+
name: "agent_token",
|
|
32
|
+
ok: true,
|
|
33
|
+
detail: `resolved from ${auth.tokenSource}`,
|
|
34
|
+
});
|
|
35
|
+
checks.push({
|
|
36
|
+
name: "api_url",
|
|
37
|
+
ok: true,
|
|
38
|
+
detail: validateApiURL(auth.apiURL),
|
|
39
|
+
});
|
|
73
40
|
}
|
|
74
|
-
|
|
75
|
-
|
|
41
|
+
catch (error) {
|
|
42
|
+
checks.push({
|
|
43
|
+
name: "agent_token",
|
|
44
|
+
ok: false,
|
|
45
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
46
|
+
});
|
|
76
47
|
}
|
|
77
|
-
|
|
48
|
+
checks.push({
|
|
49
|
+
name: "sdk_contract",
|
|
50
|
+
ok: RELAY_V1_OPERATIONS.length === 34,
|
|
51
|
+
detail: `${RELAY_V1_OPERATIONS.length} v1 operations`,
|
|
52
|
+
});
|
|
53
|
+
if (!options.offline && auth) {
|
|
78
54
|
try {
|
|
79
|
-
const
|
|
80
|
-
|
|
55
|
+
const client = dependencies.createClient(auth);
|
|
56
|
+
await client.webhookEvents.list();
|
|
57
|
+
checks.push({
|
|
58
|
+
name: "api_reachability",
|
|
59
|
+
ok: true,
|
|
60
|
+
detail: "read-only webhook event list succeeded",
|
|
61
|
+
});
|
|
81
62
|
}
|
|
82
63
|
catch (error) {
|
|
83
|
-
|
|
64
|
+
checks.push({
|
|
65
|
+
name: "api_reachability",
|
|
66
|
+
ok: false,
|
|
67
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
68
|
+
});
|
|
84
69
|
}
|
|
85
70
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (lookup.status !== 0) {
|
|
92
|
-
out(`info ${engine}: not installed; ${spec.docsUrl}`);
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
const version = crossSpawn.sync(spec.command, spec.versionArgs, {
|
|
96
|
-
encoding: "utf8",
|
|
97
|
-
timeout: 20_000,
|
|
98
|
-
windowsHide: true,
|
|
71
|
+
else if (options.offline) {
|
|
72
|
+
checks.push({
|
|
73
|
+
name: "api_reachability",
|
|
74
|
+
ok: true,
|
|
75
|
+
detail: "skipped (--offline)",
|
|
99
76
|
});
|
|
100
|
-
check(version.status === 0, `${engine} binary present`, version.stdout?.trim() || version.stderr?.trim());
|
|
101
|
-
if (spec.checkArgs) {
|
|
102
|
-
const readiness = crossSpawn.sync(spec.command, spec.checkArgs, {
|
|
103
|
-
encoding: "utf8",
|
|
104
|
-
timeout: 30_000,
|
|
105
|
-
windowsHide: true,
|
|
106
|
-
});
|
|
107
|
-
check(readiness.status === 0, `${engine} ACP readiness`, readiness.stdout?.trim() || readiness.stderr?.trim());
|
|
108
|
-
}
|
|
109
77
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
out(existsSync(codexConfig)
|
|
116
|
-
? `info codex config present (${codexConfig}); run \`relaymessenger install-codex\` to wire notify + approvals`
|
|
117
|
-
: "info no ~/.codex/config.toml; install Codex or skip install-codex");
|
|
118
|
-
out("");
|
|
119
|
-
out(healthy ? "All checks passed." : "Some checks failed. See above.");
|
|
120
|
-
return healthy;
|
|
121
|
-
}
|
|
78
|
+
return {
|
|
79
|
+
ok: checks.every((check) => check.ok),
|
|
80
|
+
checks,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
122
83
|
//# sourceMappingURL=doctor.js.map
|
package/dist/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type Relay from "@relaymessenger/sdk";
|
|
2
|
+
export interface ListenIO {
|
|
3
|
+
stdout(value: string): void;
|
|
4
|
+
stderr(value: string): void;
|
|
5
|
+
}
|
|
6
|
+
export declare const listenForAgentEvents: (client: Relay, options: {
|
|
7
|
+
forwardTo?: string;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
fetch?: typeof fetch;
|
|
10
|
+
}, io: ListenIO) => Promise<void>;
|
|
11
|
+
//# sourceMappingURL=event-listen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-listen.d.ts","sourceRoot":"","sources":["../src/event-listen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAI7C,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,KAAK,EACb,SAAS;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,EACD,IAAI,QAAQ,KACX,OAAO,CAAC,IAAI,CAuCd,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { validateForwardURL } from "./config.js";
|
|
2
|
+
export const listenForAgentEvents = async (client, options, io) => {
|
|
3
|
+
const target = options.forwardTo
|
|
4
|
+
? validateForwardURL(options.forwardTo)
|
|
5
|
+
: undefined;
|
|
6
|
+
const fetchImplementation = options.fetch ?? globalThis.fetch;
|
|
7
|
+
await client.websocket.run({
|
|
8
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
9
|
+
async onEvent(event) {
|
|
10
|
+
const body = JSON.stringify(event);
|
|
11
|
+
if (!target) {
|
|
12
|
+
io.stdout(`${body}\n`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const response = await fetchImplementation(target, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: {
|
|
18
|
+
"content-type": "application/json",
|
|
19
|
+
"x-relay-dev-forwarded": "1",
|
|
20
|
+
"x-relay-event-id": event.event_id,
|
|
21
|
+
"x-relay-event-type": event.event_type,
|
|
22
|
+
},
|
|
23
|
+
body,
|
|
24
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
25
|
+
});
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
throw new Error(`Local forward target returned HTTP ${response.status}; event was not acknowledged.`);
|
|
28
|
+
}
|
|
29
|
+
io.stderr(`forwarded ${event.event_type} ${event.event_id}\n`);
|
|
30
|
+
},
|
|
31
|
+
async onFullSync(context) {
|
|
32
|
+
throw new Error(`Relay requested FULL sync through sequence ${context.throughSequence}; `
|
|
33
|
+
+ "the stateless development listener cannot rebuild durable state.");
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=event-listen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-listen.js","sourceRoot":"","sources":["../src/event-listen.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAOjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,MAAa,EACb,OAIC,EACD,EAAY,EACG,EAAE;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS;QAC9B,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC;QACvC,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAE9D,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;QACzB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,KAAK,CAAC,OAAO,CAAC,KAAwB;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;gBACvB,OAAO;YACT,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE;gBACjD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,uBAAuB,EAAE,GAAG;oBAC5B,kBAAkB,EAAE,KAAK,CAAC,QAAQ;oBAClC,oBAAoB,EAAE,KAAK,CAAC,UAAU;iBACvC;gBACD,IAAI;gBACJ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,sCAAsC,QAAQ,CAAC,MAAM,+BAA+B,CACrF,CAAC;YACJ,CAAC;YACD,EAAE,CAAC,MAAM,CAAC,aAAa,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,OAAO;YACtB,MAAM,IAAI,KAAK,CACb,8CAA8C,OAAO,CAAC,eAAe,IAAI;kBACvE,kEAAkE,CACrE,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const redactText: (value: string, secrets: readonly string[]) => string;
|
|
2
|
+
export declare const errorText: (error: unknown, secrets?: readonly string[]) => string;
|
|
3
|
+
export declare const jsonText: (value: unknown) => string;
|
|
4
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,UAAU,GACrB,OAAO,MAAM,EACb,SAAS,SAAS,MAAM,EAAE,KACzB,MAkBF,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,OAAO,OAAO,EACd,UAAS,SAAS,MAAM,EAAO,KAC9B,MAGF,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,MACH,CAAC"}
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const REDACTED = "[REDACTED]";
|
|
2
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3
|
+
export const redactText = (value, secrets) => {
|
|
4
|
+
let output = value;
|
|
5
|
+
for (const secret of secrets) {
|
|
6
|
+
if (secret.length < 4)
|
|
7
|
+
continue;
|
|
8
|
+
output = output.replace(new RegExp(escapeRegExp(secret), "g"), REDACTED);
|
|
9
|
+
try {
|
|
10
|
+
const encoded = encodeURIComponent(secret);
|
|
11
|
+
if (encoded !== secret) {
|
|
12
|
+
output = output.replace(new RegExp(escapeRegExp(encoded), "g"), REDACTED);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// Invalid URL encoding input is still redacted in its raw form.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return output;
|
|
20
|
+
};
|
|
21
|
+
export const errorText = (error, secrets = []) => {
|
|
22
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
23
|
+
return redactText(raw, secrets);
|
|
24
|
+
};
|
|
25
|
+
export const jsonText = (value) => `${JSON.stringify(value, null, 2)}\n`;
|
|
26
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7C,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,KAAa,EACb,OAA0B,EAClB,EAAE;IACV,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAChC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,EACtC,QAAQ,CACT,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,KAAc,EACd,UAA6B,EAAE,EACvB,EAAE;IACV,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAU,EAAE,CACjD,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { ClientContext } from "./client.js";
|
|
3
|
+
import type { ConfigContext } from "./config.js";
|
|
4
|
+
export interface ProgramDependencies {
|
|
5
|
+
configContext?: ConfigContext;
|
|
6
|
+
resolveClient?: (profile?: string) => Promise<ClientContext>;
|
|
7
|
+
readStdin?: () => Promise<string>;
|
|
8
|
+
stdout?: (value: string) => void;
|
|
9
|
+
stderr?: (value: string) => void;
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
}
|
|
12
|
+
export declare const createProgram: (dependencies?: ProgramDependencies) => Command;
|
|
13
|
+
export declare const runCLI: (argv: string[], dependencies?: ProgramDependencies) => Promise<number>;
|
|
14
|
+
//# sourceMappingURL=program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,OAAO,EAGR,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAgB/D,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IAC7D,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AA4DD,eAAO,MAAM,aAAa,GACxB,eAAc,mBAAwB,KACrC,OAqvBF,CAAC;AAEF,eAAO,MAAM,MAAM,GACjB,MAAM,MAAM,EAAE,EACd,eAAc,mBAAwB,KACrC,OAAO,CAAC,MAAM,CAyBhB,CAAC"}
|