Skip to content

Commit 473f651

Browse files
committed
docs: document gateway helper comments
1 parent 4912342 commit 473f651

7 files changed

Lines changed: 31 additions & 0 deletions

File tree

src/commands/gateway-health-auth-diagnostic.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Gateway health auth diagnostic helpers for reachable-but-unauthenticated probes. */
12
import type { DaemonStatus } from "../cli/daemon-cli/status.gather.js";
23

34
type GatewayProbeReachabilityEvidence = NonNullable<DaemonStatus["rpc"]>;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
/** Runtime persistence seam for gateway install token config writes. */
12
export { readConfigFileSnapshotForWrite } from "../config/io.js";
23
export { replaceConfigFile } from "../config/mutate.js";

src/commands/gateway-install-token.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Resolves the gateway token used when installing or updating the managed service. */
12
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
23
import { formatCliCommand } from "../cli/command-format.js";
34
import type { ConfigWriteOptions } from "../config/io.js";
@@ -67,6 +68,7 @@ async function maybePersistAutoGeneratedGatewayInstallToken(params: {
6768
existingTokenRef || typeof baseConfig.gateway?.auth?.token !== "string"
6869
? undefined
6970
: normalizeOptionalString(baseConfig.gateway.auth.token);
71+
// Only persist a generated plaintext token when config has no token or SecretRef.
7072
if (!existingTokenRef && !baseConfigToken) {
7173
await replaceConfigFile({
7274
nextConfig: {
@@ -111,6 +113,7 @@ function formatAmbiguousGatewayAuthModeReason(): string {
111113
].join(" ");
112114
}
113115

116+
/** Resolves, validates, optionally generates, and optionally persists a gateway install token. */
114117
export async function resolveGatewayInstallToken(
115118
options: GatewayInstallTokenOptions,
116119
): Promise<GatewayInstallTokenResolution> {

src/commands/gateway-presence.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Extracts the gateway's self presence entry from status/presence payloads. */
12
import { readStringValue } from "@openclaw/normalization-core/string-coerce";
23

34
type GatewaySelfPresence = {
@@ -7,6 +8,7 @@ type GatewaySelfPresence = {
78
platform?: string;
89
};
910

11+
/** Picks host, ip, version, and platform from the gateway self presence record. */
1012
export function pickGatewaySelfPresence(presence: unknown): GatewaySelfPresence | null {
1113
if (!Array.isArray(presence)) {
1214
return null;

src/commands/gateway-readiness.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Ensures the managed gateway is available before commands that need it run. */
12
import type { DaemonStatus } from "../cli/daemon-cli/status.gather.js";
23
import { promptYesNo } from "../cli/prompt.js";
34
import type { RuntimeEnv } from "../runtime.js";
@@ -14,6 +15,7 @@ const daemonLifecycleModuleLoader = createLazyImportLoader(
1415
() => import("../cli/daemon-cli/lifecycle.js"),
1516
);
1617

18+
/** Result returned after checking, optionally installing, and optionally starting the gateway. */
1719
export type GatewayReadinessResult =
1820
| {
1921
ready: true;
@@ -34,6 +36,7 @@ type GatewayReadinessDeps = {
3436
startGateway?: () => Promise<void>;
3537
};
3638

39+
/** Inputs controlling readiness checks, recovery prompts, and injectable test seams. */
3740
export type GatewayReadinessOptions = {
3841
runtime: RuntimeEnv;
3942
operation: string;
@@ -92,6 +95,8 @@ function gatewayLooksReachable(status: DaemonStatus): boolean {
9295
if (port?.status !== "busy") {
9396
return false;
9497
}
98+
// A busy port alone is not enough: pair it with probe evidence so another
99+
// local service on the same port cannot satisfy gateway readiness.
95100
return gatewayProbeSawGateway(status);
96101
}
97102

@@ -176,6 +181,7 @@ async function waitForGatewayReady(params: {
176181
return latest;
177182
}
178183

184+
/** Checks readiness and, when approved, recovers by installing or starting the gateway. */
179185
export async function ensureGatewayReadyForOperation(
180186
options: GatewayReadinessOptions,
181187
): Promise<GatewayReadinessResult> {

src/commands/gateway-status/discovery.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
/** Discovery helpers for turning gateway remote URLs and Bonjour beacons into SSH targets. */
12
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
23
import type { GatewayBonjourBeacon } from "../../infra/bonjour-discovery.js";
34
import {
45
buildGatewayDiscoveryTarget,
56
serializeGatewayDiscoveryBeacon,
67
} from "../../infra/gateway-discovery-targets.js";
78

9+
/** Infers a user@host SSH target from a configured remote websocket URL. */
810
export function inferSshTargetFromRemoteUrl(rawUrl?: string | null): string | null {
911
if (typeof rawUrl !== "string") {
1012
return null;
@@ -40,6 +42,7 @@ function buildSshTarget(input: { user?: string; host?: string; port?: number }):
4042
return base;
4143
}
4244

45+
/** Resolves an SSH target through ssh-config while preserving explicit identity choices. */
4346
export async function resolveSshTarget(params: {
4447
rawTarget: string;
4548
identity: string | null;
@@ -77,6 +80,7 @@ export async function resolveSshTarget(params: {
7780
return { target, identity: identityFile };
7881
}
7982

83+
/** Picks the first Bonjour-derived SSH target that parses as a valid tunnel target. */
8084
export function pickAutoSshTargetFromDiscovery(params: {
8185
discovery: GatewayBonjourBeacon[];
8286
parseSshTarget: (target: string) => unknown;

src/commands/gateway-status/helpers.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Shared helpers for gateway status target selection, auth, summaries, and probe rendering. */
12
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
23
import { colorize, theme } from "../../../packages/terminal-core/src/theme.js";
34
import { parseTimeoutMsWithFallback } from "../../cli/parse-timeout.js";
@@ -15,6 +16,7 @@ const MISSING_SCOPE_PATTERN = /\bmissing scope:\s*[a-z0-9._-]+/i;
1516

1617
type TargetKind = "explicit" | "configRemote" | "localLoopback" | "sshTunnel";
1718

19+
/** Concrete websocket endpoint that gateway status should probe. */
1820
export type GatewayStatusTarget = {
1921
id: string;
2022
kind: TargetKind;
@@ -29,6 +31,7 @@ export type GatewayStatusTarget = {
2931
};
3032
};
3133

34+
/** Sanitized config subset rendered by the deep gateway status view. */
3235
export type GatewayConfigSummary = {
3336
path: string | null;
3437
exists: boolean;
@@ -67,6 +70,7 @@ function parseIntOrNull(value: unknown): number | null {
6770
return parseStrictInteger(s) ?? null;
6871
}
6972

73+
/** Parses CLI timeout input with the gateway-status fallback rules. */
7074
export function parseTimeoutMs(raw: unknown, fallbackMs: number): number {
7175
return parseTimeoutMsWithFallback(raw, fallbackMs);
7276
}
@@ -82,6 +86,7 @@ function normalizeWsUrl(value: string): string | null {
8286
return trimmed;
8387
}
8488

89+
/** Builds the deduplicated ordered gateway probe targets from CLI input and config. */
8590
export function resolveTargets(cfg: OpenClawConfig, explicitUrl?: string): GatewayStatusTarget[] {
8691
const targets: GatewayStatusTarget[] = [];
8792
const add = (t: GatewayStatusTarget) => {
@@ -148,6 +153,7 @@ export function resolveProbeBudgetMs(
148153
return overallMs;
149154
}
150155

156+
/** Normalizes user-entered SSH targets, accepting both raw targets and `ssh host` input. */
151157
export function sanitizeSshTarget(value: unknown): string | null {
152158
if (typeof value !== "string") {
153159
return null;
@@ -159,6 +165,7 @@ export function sanitizeSshTarget(value: unknown): string | null {
159165
return trimmed.replace(/^ssh\s+/, "");
160166
}
161167

168+
/** Resolves auth for the probe surface represented by the selected status target. */
162169
export async function resolveAuthForTarget(
163170
cfg: OpenClawConfig,
164171
target: GatewayStatusTarget,
@@ -178,6 +185,7 @@ export async function resolveAuthForTarget(
178185

179186
export { pickGatewaySelfPresence };
180187

188+
/** Extracts the config fields displayed by `openclaw gateway status --deep`. */
181189
export function extractConfigSummary(snapshotUnknown: unknown): GatewayConfigSummary {
182190
const snap = snapshotUnknown as Partial<ConfigFileSnapshot> | null;
183191
const path = typeof snap?.path === "string" ? snap.path : null;
@@ -244,6 +252,7 @@ export function extractConfigSummary(snapshotUnknown: unknown): GatewayConfigSum
244252
};
245253
}
246254

255+
/** Builds local and tailnet gateway URL hints for the configured gateway port. */
247256
export function buildNetworkHints(cfg: OpenClawConfig) {
248257
const { tailnetIPv4 } = inspectBestEffortPrimaryTailnetIPv4();
249258
const port = resolveGatewayPort(cfg);
@@ -255,6 +264,7 @@ export function buildNetworkHints(cfg: OpenClawConfig) {
255264
};
256265
}
257266

267+
/** Renders the status heading for a single gateway probe target. */
258268
export function renderTargetHeader(target: GatewayStatusTarget, rich: boolean) {
259269
const kindLabel =
260270
target.kind === "localLoopback"
@@ -269,17 +279,20 @@ export function renderTargetHeader(target: GatewayStatusTarget, rich: boolean) {
269279
return `${colorize(rich, theme.heading, kindLabel)} ${colorize(rich, theme.muted, target.url)}`;
270280
}
271281

282+
/** Returns true when auth succeeded enough to connect but lacks the read scope. */
272283
export function isScopeLimitedProbeFailure(probe: GatewayProbeResult): boolean {
273284
if (probe.ok || probe.connectLatencyMs == null) {
274285
return false;
275286
}
276287
return MISSING_SCOPE_PATTERN.test(probe.error ?? "");
277288
}
278289

290+
/** Returns true when the gateway connection was established but a later probe failed. */
279291
export function isPostConnectProbeFailure(probe: GatewayProbeResult): boolean {
280292
return !probe.ok && probe.connectLatencyMs != null;
281293
}
282294

295+
/** Returns true when the probe established any gateway connection. */
283296
export function isProbeReachable(probe: GatewayProbeResult): boolean {
284297
return probe.ok || probe.connectLatencyMs != null;
285298
}
@@ -291,6 +304,7 @@ function getGatewayProbeCapability(probe: GatewayProbeResult): GatewayProbeCapab
291304
export function summarizeGatewayProbeCapability(
292305
probes: GatewayProbeResult[],
293306
): GatewayProbeCapability {
307+
// Show the strongest observed capability across all attempted targets.
294308
const priority: GatewayProbeCapability[] = [
295309
"admin_capable",
296310
"write_capable",

0 commit comments

Comments
 (0)