From 1f52854c0d38cee5a687e24dab752aae211133ec Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 16:56:05 -0400 Subject: [PATCH] docs: document command analysis infra --- src/infra/command-analysis/explain.lazy.test.ts | 2 ++ src/infra/command-analysis/explain.test.ts | 2 ++ src/infra/command-analysis/explain.ts | 2 ++ src/infra/command-analysis/inline-eval.test.ts | 2 ++ src/infra/command-analysis/inline-eval.ts | 2 ++ src/infra/command-analysis/policy.ts | 2 ++ src/infra/command-analysis/risks.test.ts | 2 ++ src/infra/command-analysis/risks.ts | 4 ++++ src/infra/command-explainer/extract.test.ts | 2 ++ src/infra/command-explainer/extract.ts | 2 ++ src/infra/command-explainer/format.test.ts | 2 ++ src/infra/command-explainer/format.ts | 2 ++ src/infra/command-explainer/tree-sitter-runtime.ts | 4 ++++ src/infra/tls/fingerprint.test.ts | 2 ++ src/infra/tls/fingerprint.ts | 2 ++ src/infra/tls/gateway.test.ts | 2 ++ src/infra/tls/gateway.ts | 2 ++ 17 files changed, 38 insertions(+) diff --git a/src/infra/command-analysis/explain.lazy.test.ts b/src/infra/command-analysis/explain.lazy.test.ts index 9a035fe00362..0e7b5889fd3e 100644 --- a/src/infra/command-analysis/explain.lazy.test.ts +++ b/src/infra/command-analysis/explain.lazy.test.ts @@ -1,3 +1,5 @@ +// Verifies lightweight command summaries stay independent from tree-sitter and +// the rich command explainer dependency graph. import { describe, expect, it, vi } from "vitest"; vi.mock("../command-explainer/extract.js", () => { diff --git a/src/infra/command-analysis/explain.test.ts b/src/infra/command-analysis/explain.test.ts index 2e57edea2665..8f1697f8fd0f 100644 --- a/src/infra/command-analysis/explain.test.ts +++ b/src/infra/command-analysis/explain.test.ts @@ -1,3 +1,5 @@ +// Covers command-analysis summary formatting for parsed shell explanations and +// policy-only argv/shell segment analysis. import { describe, expect, it } from "vitest"; import { explainShellCommand } from "../command-explainer/index.js"; import { diff --git a/src/infra/command-analysis/explain.ts b/src/infra/command-analysis/explain.ts index 863d1df1bc8c..d229381aa9f9 100644 --- a/src/infra/command-analysis/explain.ts +++ b/src/infra/command-analysis/explain.ts @@ -1,3 +1,5 @@ +// Command-analysis display helpers turn parsed command policy data into small +// warning summaries for approval surfaces without loading the rich parser path. import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import type { CommandExplanation, CommandRisk } from "../command-explainer/types.js"; import type { ExecCommandSegment } from "../exec-approvals-analysis.js"; diff --git a/src/infra/command-analysis/inline-eval.test.ts b/src/infra/command-analysis/inline-eval.test.ts index c552202e894f..8aef4b15ea70 100644 --- a/src/infra/command-analysis/inline-eval.test.ts +++ b/src/infra/command-analysis/inline-eval.test.ts @@ -1,3 +1,5 @@ +// Covers interpreter inline-eval flag detection, positional program forms, and +// allowlist pattern matching for approval policy. import { describe, expect, it } from "vitest"; import type { InterpreterInlineEvalHit } from "./inline-eval.js"; import { diff --git a/src/infra/command-analysis/inline-eval.ts b/src/infra/command-analysis/inline-eval.ts index 44e73b009084..e8093660fae5 100644 --- a/src/infra/command-analysis/inline-eval.ts +++ b/src/infra/command-analysis/inline-eval.ts @@ -1,3 +1,5 @@ +// Interpreter inline-eval detection recognizes flags and positional program +// forms that execute command text without reading a script file. import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { normalizeExecutableToken } from "../exec-wrapper-resolution.js"; diff --git a/src/infra/command-analysis/policy.ts b/src/infra/command-analysis/policy.ts index 8537a3391d3a..753d038e4312 100644 --- a/src/infra/command-analysis/policy.ts +++ b/src/infra/command-analysis/policy.ts @@ -1,3 +1,5 @@ +// Approval-policy command analysis normalizes shell and argv inputs into the +// shared exec segment shape consumed by risk checks. import { analyzeArgvCommand, analyzeShellCommand, diff --git a/src/infra/command-analysis/risks.test.ts b/src/infra/command-analysis/risks.test.ts index defcae38c569..1220ad28d2e1 100644 --- a/src/infra/command-analysis/risks.test.ts +++ b/src/infra/command-analysis/risks.test.ts @@ -1,3 +1,5 @@ +// Exercises recursive command-risk detection through interpreters, carriers, +// shell wrappers, env split-string, eval, and source invocations. import { describe, expect, it } from "vitest"; import { buildCommandPayloadCandidates, diff --git a/src/infra/command-analysis/risks.ts b/src/infra/command-analysis/risks.ts index 217955f09f29..39114f3e49a7 100644 --- a/src/infra/command-analysis/risks.ts +++ b/src/infra/command-analysis/risks.ts @@ -1,3 +1,5 @@ +// Command risk detection follows nested carriers, shell wrappers, and inline +// interpreter eval paths used by approval policy and command explanations. import { uniqueStrings } from "@openclaw/normalization-core/string-normalization"; import { splitShellArgs } from "../../utils/shell-argv.js"; import { @@ -250,6 +252,8 @@ function detectInlineEvalArgvInternal( if (!Array.isArray(argv)) { return null; } + // Try direct interpreters first, then shell positional trampoline patterns, + // then transparent carriers such as sudo/env/exec. return ( detectInterpreterInlineEvalArgv(argv) ?? detectShellPositionalCarrierInlineEvalArgvInternal(argv, seenArgv) ?? diff --git a/src/infra/command-explainer/extract.test.ts b/src/infra/command-explainer/extract.test.ts index 1fdb4d846a8c..105671576cff 100644 --- a/src/infra/command-explainer/extract.test.ts +++ b/src/infra/command-explainer/extract.test.ts @@ -1,3 +1,5 @@ +// Covers rich shell-command extraction, fake parser shapes, source span mapping, +// nested wrapper parsing, and parser error handling. import { afterEach, describe, expect, it, vi } from "vitest"; import type { Node as TreeSitterNode, Parser, Tree } from "web-tree-sitter"; import { explainShellCommand } from "./extract.js"; diff --git a/src/infra/command-explainer/extract.ts b/src/infra/command-explainer/extract.ts index 7ec960142d27..a55c9af00eb6 100644 --- a/src/infra/command-explainer/extract.ts +++ b/src/infra/command-explainer/extract.ts @@ -1,3 +1,5 @@ +// Rich shell command explainer walks tree-sitter-bash nodes into command steps, +// nested wrapper payloads, source spans, and risk annotations. import type { Node as TreeSitterNode } from "web-tree-sitter"; import type { InterpreterInlineEvalHit } from "../command-analysis/inline-eval.js"; import { diff --git a/src/infra/command-explainer/format.test.ts b/src/infra/command-explainer/format.test.ts index 9f136f2f366b..b18b542f02d3 100644 --- a/src/infra/command-explainer/format.test.ts +++ b/src/infra/command-explainer/format.test.ts @@ -1,3 +1,5 @@ +// Verifies command explanation spans are reduced to executable highlights and +// suppressed for unsupported shell-wrapper grammars. import { describe, expect, it } from "vitest"; import { explainShellCommand } from "./extract.js"; import { formatCommandSpans } from "./format.js"; diff --git a/src/infra/command-explainer/format.ts b/src/infra/command-explainer/format.ts index b866b027a3f0..af63d12b56d5 100644 --- a/src/infra/command-explainer/format.ts +++ b/src/infra/command-explainer/format.ts @@ -1,3 +1,5 @@ +// Command-explainer formatting converts parsed executable spans into approval +// UI highlight ranges, omitting shells whose parsing semantics differ. import type { ExecApprovalCommandSpan } from "../exec-approvals.js"; import { normalizeExecutableToken } from "../exec-wrapper-tokens.js"; import { diff --git a/src/infra/command-explainer/tree-sitter-runtime.ts b/src/infra/command-explainer/tree-sitter-runtime.ts index 08792a7851a9..b6d8e7dca117 100644 --- a/src/infra/command-explainer/tree-sitter-runtime.ts +++ b/src/infra/command-explainer/tree-sitter-runtime.ts @@ -1,3 +1,5 @@ +// Lazy tree-sitter runtime resolves WASM assets, caches the bash parser, and +// enforces source-size/time limits for command explanation. import fs from "node:fs"; import { createRequire } from "node:module"; import path from "node:path"; @@ -62,6 +64,8 @@ async function loadParser(): Promise { } export function getBashParserForCommandExplanation(): Promise { + // Reset the cache on load failure so transient filesystem or WASM init errors + // do not poison all later command explanations in the process. parserPromise ??= parserLoader().catch((error: unknown) => { parserPromise = null; throw error; diff --git a/src/infra/tls/fingerprint.test.ts b/src/infra/tls/fingerprint.test.ts index 658eaecd78e8..157f6646fdef 100644 --- a/src/infra/tls/fingerprint.test.ts +++ b/src/infra/tls/fingerprint.test.ts @@ -1,3 +1,5 @@ +// Covers gateway TLS fingerprint normalization across prefixes, separators, +// blank values, and malformed text. import { describe, expect, it } from "vitest"; import { normalizeFingerprint } from "./fingerprint.js"; diff --git a/src/infra/tls/fingerprint.ts b/src/infra/tls/fingerprint.ts index ca13ea0f61d5..413bb1962da3 100644 --- a/src/infra/tls/fingerprint.ts +++ b/src/infra/tls/fingerprint.ts @@ -1,3 +1,5 @@ +// TLS fingerprint normalization accepts common SHA-256 display formats and +// stores lowercase hex for config comparisons. import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; // Gateway TLS fingerprints are stored as lowercase hex without labels or diff --git a/src/infra/tls/gateway.test.ts b/src/infra/tls/gateway.test.ts index 1400ddfd025d..f8326e88534c 100644 --- a/src/infra/tls/gateway.test.ts +++ b/src/infra/tls/gateway.test.ts @@ -1,3 +1,5 @@ +// Covers gateway TLS loading, fingerprint reporting, generated certificate +// paths, and error handling for missing or invalid material. import { X509Certificate } from "node:crypto"; import { writeFile } from "node:fs/promises"; import path from "node:path"; diff --git a/src/infra/tls/gateway.ts b/src/infra/tls/gateway.ts index bbcda126c259..6c0a3b8cdf19 100644 --- a/src/infra/tls/gateway.ts +++ b/src/infra/tls/gateway.ts @@ -1,3 +1,5 @@ +// Gateway TLS runtime loads configured certificates or generates a local +// self-signed pair, returning server-ready options plus client fingerprint. import { execFile } from "node:child_process"; import { X509Certificate } from "node:crypto"; import fs from "node:fs/promises";