docs: document command analysis infra

This commit is contained in:
Peter Steinberger
2026-06-04 16:56:05 -04:00
parent 170df6612e
commit 1f52854c0d
17 changed files with 38 additions and 0 deletions

View File

@@ -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", () => {

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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,

View File

@@ -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,

View File

@@ -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) ??

View File

@@ -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";

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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 {

View File

@@ -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<TreeSitter.Parser> {
}
export function getBashParserForCommandExplanation(): Promise<TreeSitter.Parser> {
// 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;

View File

@@ -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";

View File

@@ -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

View File

@@ -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";

View File

@@ -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";