# @compforge/harness-toolbox 中文文档

规范地址：https://npmcn.com/package/%40compforge/harness-toolbox/

版本：0\.5\.6
npm 元数据更新时间：2026-11-06T09:04:17.584Z
中文译文更新时间：2026-11-10T13:39:44.081Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40compforge/harness-toolbox
原文对照：https://npmcn.com/package/%40compforge/harness-toolbox/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：349 kB，193 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：11 个
- 首次发布：2026-09-10T06:36:33.812Z
- 最新版本发布：2026-11-06T09:04:17.342Z
- 近 30 天下载量：3447（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：28（近 12 个月 28 个）

## 中文简介

共享基础设施客户、运输和有限数据采集

## 安装

```sh
npm install @compforge/harness-toolbox
```

也可以使用：`pnpm add @compforge/harness-toolbox`、`yarn add @compforge/harness-toolbox`、`bun add @compforge/harness-toolbox`

## README

# 调理工具箱

客户端、 客户端提供者、 数据源、 环境连接和客户端管理器为兄弟端类型Script包所有 `@compforge/harness-common`. 工具箱提供协议执行和运输; 它的生命周期入境点再出口相同的共同符号.

共享诊断工具、试验跑道和商业适配器的基础设施。 用同样的 客户端访问 HTTP( S), Kubernetes, MySQL, Redis, OpenSearch 和 S3 兼容对象存储而不取决于特定对象 命令、插件协议、测试模型或判断.

该软件包支持Node.js 22+和 Bun. 安装方式 `npm install @compforge/harness-toolbox`。 。 。 . 使用 `@compforge/harness-toolbox/duration` 以分析正时长, 如 `30m` 或者说 `2d` 变成毫秒. `searchAfterPages` 从 `@compforge/harness-toolbox/opensearch/search-after` 生成原始 OpenSearch 提供查询和稳定排序。 它在不拥有客户端的情况下流出页面或 声称快照一致性; 呼叫者提供取消,并决定如何坚持或核实结果. 协议适配器设有单独的切入点;进口生命周期或运输合同确实如此 不装入数据库或 Kubernetes 驱动程序.

## HTTP 请求

`HttpClient` 借同样的 `Transport` 作为其他协议客户端,保留逻辑主机和 TLS 身份, 即使套接字通过端口前行 。 限制包括反应机构; 状态和重定向在返回时不重复或重定向.

```ts
import { ClientManager } from "@compforge/harness-common";
import { HttpClient } from "@compforge/harness-toolbox/http";
import { DirectTransport } from "@compforge/harness-toolbox/transport";

const clients = new ClientManager();
try {
  const route = await clients.get({ clientKey: "direct", createClient: () => new DirectTransport() });
  const http = await clients.create({ createClient: (_clients, signal) => new HttpClient(
    { endpoint: "https://service.example" }, route,
    { concurrency: 4, connectTimeoutMs: 5000, requestTimeoutMs: 10000, maxResponseBytes: 1024 * 1024 },
    { signal },
  ) });
  const response = await http.request("/health");
  console.log(response.status, new TextDecoder().decode(response.body));
  await http.dispose(); // The shared route remains available until root disposal.
} finally { await clients.dispose(); }
```

## 文件来源

一个FileData Source是一个呼叫者宣布的收购集团. 使用 `LocalFileDataSource` 本地路径 或者说 `PodFileDataSource` 用于一个明确名称空间/Pod/容器中的路径。 两个扩展的普通 `FileDataSource`;不需要额外的id/kind包装.

```ts
import { ClientManager } from "@compforge/harness-common";
import { LocalFileDataSource, PodFileDataSource } from "@compforge/harness-toolbox/file";

const source = new LocalFileDataSource(["./config.yaml", "./secret/config.yaml"], { concurrency: 2 });
const clients = new ClientManager();
try {
  const file = await clients.get(source);
  const results = await file.read({ maxBytes: 1024 * 1024, maxTotalBytes: 2 * 1024 * 1024, timeoutMs: 15_000 });
  for (const result of results) {
    if (result.status === "error") console.error(result.path, result.error.message);
    else console.log(result.path, new TextDecoder("utf-8", { fatal: true }).decode(result.bytes));
  }
} finally { await clients.dispose(); }

// Resolve Workloads first. This entire group is fetched through one exec session.
const podSource = new PodFileDataSource(environment,
  { namespace: "app", pod: "worker-abc", container: "worker" },
  ["/etc/app/config.yaml", "/etc/app/secret/config.yaml"], { concurrency: 2 });
```

每个读取重开所有已声明的路径并返回每个路径一个命令的结果 。 空文件成功; 缺少、否定、非常规和超大小的文件返回单个错误,没有部分字节. 一个文件中的错误不会丢弃兄弟间的结果 。 每一路径的每个文件限制重设; 总计 预算约束保留了解码字节,包括不完整的文件. 排队和整组 共享一个最后期限。 取消、总预算用完、最后期限和运输/议定书失效 拒绝手术 源代码共享客户端, 从没有之前的文件内容 .

Pod 组使用一个执行器并需要 `sh`, (中文(简体) ), `head -c`, (中文(简体) ), `base64` 财务报告和审定财务报表 `tr`。 路径仍然定位 参数,即使包含 shell 语法或新行。 已索引的 Base64 记录带有原始二进制 字节加每个文件的退出状态;不重放便被截断或错误的记录拒绝. 无远程 临时文件被写入 。 本地读取允许将符号链接到正则文件并拒绝非正则文件. 将路径和Pod目标保持在证据上; 分组保证既不保证原子文件系统快照 或应用程序配置优先。 Pod 名称不是 UID 栅栏; 需要化身的呼叫者 保证必须检查收集周围的发现。 文件客户端借用 root Kubernetes 访问和 永远不要关闭它自己.

0.4.2版本要求通用0.5.4. 将单一路径参数替换为数组, 供应 `maxTotalBytes`, (中文(简体) ), 并处理每个文件的结果。 在 Toolbox 之前发布 Common; 此更改没有单文件的遗留适配器 .

## Redis 来源

`RedisClient` 拥有已解析的配置和可再使用的节点连接。 使用 `clusterType` 改为 选择 `single`, (中文(简体) ), `cluster` 或者说 `sentinel`· ; `endpoints` 包含该模式的种子地址。 哨兵队 配置额外提供 `sentinelMasterName` 和可选的哨兵证书, 与数据节点证书分开。 集群连接需要数据库零.

供应一 `Transport`,在需要的地方有命令的 TCP 路径。 只有映射或握手网络 失败推进到下个传输;认证和TLS验证失败立即停止. `connectTimeoutMs` 绑定每个路由( 映射和握手); 它默认为命令 `timeoutMs`。 。 。 . `acquireTimeoutMs` 将所有候选人合并在一起,并缺省到每个路线的预算 乘以路线数。 已经花费的总预算不会开始另一条路线. `onRoute` 报告选中的路由和之前的失败代码,没有证书.

`client.topology()` 使用与 `client.access.connection(endpoint, database)`。根信号取消连接准备 活动命令。 命令和管道发送一次,没有下线排队或自动回放; 之后的购买取代了不健康的连接。 打电话者拥有 `dispose()` 运输 清理,诊断者拥有取样政策和收集观测结果.

## 库伯涅斯资源

借用根 `KubernetesClient` 结束 `KubernetesEnvironment` 财务报告和审定财务报表 `ClientManager`启用 `get(ref)` 财务报告和审定财务报表 `list(query)` 资源读取; `inNamespace(namespace)` 绑定所借视图 不创建第二个客户端或集合的命名空间 :

```ts
const kube = await clients.get(environment);
const ns = kube.inNamespace("app");
const service = await ns.get({ apiVersion: "v1", resource: "services", name: "api" });
const pods = await ns.list({ apiVersion: "v1", resource: "pods", labelSelector: "app=api" },
  { timeoutMs: 15_000, signal });
```

`resource` 是复数 REST 资源名称,而不是 Kind 或 kubectl 化名。 明确的 API 版本 支持内置资源和自定义资源,无需发现请求或本地许可列表. 根使用它所配置的命名空间, 除非查询超过它; 命名空间视图强制 他们的边框命名空间。 资源对象和列表元数据完整地返回. 名单请求 接受标签/字段选择并明确 `limit`编号 :`continue` 页面;它们不默读所有页面. 错误是 `KubernetesError` 带有稳定类型和HTTP状态的物体. 呼叫者以其证据保留了查询;资源操作不会产生 shell 命令结果.

Root 拥有一个 HTTP 传输, 拥有在命名空间和资源之间共享的恒活连接 类型。 每次请求都会刷新认证 。 TLS/ 代理身份更改 选择新池并 上一个在读完后退休。 请求有字节和最后期限 包括队列、认证和身体消耗. `dispose()` 取消工作, 等待跟踪 操作,并关闭连接。 视图和注入所借资源阅读器没有所有权 这生命周期。 没有查询结果被缓存,失败永远不会通过另一个传输重放.

本地资源访问使用 kubeconfig 认证、 TLS 和 明文 `proxy-url`它不会 基于 shell 代理环境变量选择传输. `exec` 财务报告和审定财务报表 `forward` 分开 流式操作;其执行不截取读取资源. `KubernetesClient` 没有 `run(argv)` 方法。 货币仍由调用人组成,而不是从池大小推断.

## 工作量的发现

通过 Kubernetes Environment 和 共享客户端管理器生命周期借取 Kubernetes 客户端 `client.resolveWorkload(workload, environmentId)`。ID是一个稳定的目标身份 从您 环境注册,而不是显示名称或 kubeconfig 路径。 Workload的命名空间可以覆盖客户端的默认值. 资源、 服务选择器和标签位置返回所有匹配的 Pod 化身而不包含 准备过滤; 成功的空发现返回空阵列。 缺少资源, 无选择服务, 访问失败 .

资源路径使用客户端-node kubeconfig认证/TLS,并被捆绑的本地JSON读取:, 不是 kubectl 错误文本 。 使用 客户端的资源Limits构建器参数。 Exec 使用相同的根能/字节政策 拥有一个单独的槽池;其每次呼叫的超时都会默认该策略并覆盖排队, 认证、升级和执行。 明确的呼叫暂停支持更长的命令.

只输出的Exec直接连接到波德Exec WebSocket的端点而无需初步 Pod 获取和需要 `get pods/exec`。带有明确 stdin(包括空输入)使用的命令 `kubectl exec -i`,它通过 SPDY/v5 处理关于更古老和更新的集群的输入 EOF。 这个 路径需要 Host 上兼容的 kubectl, Pod 读取权限和 `create pods/exec` sPDY (英语:`get pods/exec` 用于 WebSocket 。 执行前选择频道; 失败 从未被工具箱重试或重放。 结果 `command` 记录实际频道. Kubeconfig控制认证,TLS和代理访问. 两个路径共享根执行槽 池、 截止日期、 保留输出字节限制和取消 。 stdout/stder 仍然分开; 本地 exec 使用远程状态, kubectl 使用进程退出状态, 保留原始 CLI stderr 不猜测结构化的 HTTP 错误类型 。 串流呼叫器可能设置 `collectStdout: false` 并且执行自己的总字节预算; 单个产出块仍然有限制。 根处理 取消活动会话和队列会话,等待本地的kubectl进程退出. 只输出会话接受v4/v5. Bun没有显示 HTTP 升级拒绝状态,所以 失败保留了未知的连接错误 。 有 kubeconfig 代理的本地执行需要节点 : Bun 无法可靠地释放代理套接字或保存 TLS 名称覆盖 。 这个限制是 不适用于 kubectl stdin 路径 。 路径都无法绕过代理或 TLS 检查 . 前港也使用克贝克特克. 见 [共享工作量模型](https://npmcn.com/docs/workload.md)。 。 。 .

```ts
import { ClientManager, EnvironmentContext } from "@compforge/harness-toolbox";
import { KubernetesEnvironment } from "@compforge/harness-toolbox/kubernetes/environment";

const clients = new ClientManager();
try {
  const ctx = new EnvironmentContext(
    new KubernetesEnvironment("dev",
      { kubeconfig: "/config/cluster", context: "dev", namespace: "app" },
      { timeoutMs: 10_000, concurrency: 4, maxBytes: 8 * 1024 * 1024 }),
    clients, performance.now() + 30_000,
  );
  const kube = await ctx.clients.get(ctx.environment);
  const pods = await kube.resolveWorkload({
    name: "api", platform: "kubernetes",
    location: { kind: "resource", resource_kind: "Deployment", name: "api" },
  }, "cluster-a/runtime");
} finally {
  await clients.dispose();
}
```

上下文不会自动取消工作 。 其预算尚存。 老师; root拥有注销权,在处置客户前必须加入童工.

从根项抓取工具框错误或 `@compforge/harness-toolbox/errors`; 使用 `kind` 财务报告和审定财务报表 `code` 用于决定。 土著 `cause` 可能包含敏感细节,并且只调试. 连接获取截止日期和 Redis 握手/ 命令截止日期 `TimeoutError` 从 `@compforge/harness-toolbox/errors`它延伸 `ToolboxError`,保留 `kind: "timeout"` 财务报告和审定财务报表 `code: "ETIMEDOUT"`; OpenSearch 保存不变.

为协调的通用/工具箱开发,在安装工具箱前安装和构建通用工具箱:

```sh
# From sdks/typescript/toolbox
(cd ../common && bun install --frozen-lockfile && make build)
bun install --frozen-lockfile
make lint
make test
```

工具箱根覆盖从 `../common` 仅供地方发展之用; 已公布的依赖关系仍然是登记版本。 在工具箱前公布常见信息 . Makefile 在排入或构建工具箱之前建立常见文件 .

A 类 `ClientProvider` 识别可重复使用的客户端并构建它; `DataSource` 添加数据访问语义. 无障碍环境在不成为数据源的情况下直接执行客户端提供. 这个 `Client` 拥有初始化 (a) 处置 `ClientManager` 加入同一密钥同时初始化,并 呼叫者完成后关闭自有客户端 。 协议客户端接受配置( 或自动解析器) 和一个 `Transport`; 运输选择和准备访问路径. `clients.create(factory)` 创建 其打电话者可能提前关闭的新客户端 `get` 留活口,直到根处理.

共享端口,登记 a `ServicePortForwardTransport` 每组/名称空间一次,然后通过 借给每个协议客户端的运输。 关闭 OpenSearch 客户端将可用的前端留给下一个 OpenSearch, MySQL, Redis 或 S3 客户端; root 处理在停止前关闭客户端. 借款人的取消只停止了借款人的等待。 退出前置在下一次获取时重新创建 . 运算映射改变拨号地址,而协议客户端保留了原始主机,TLS和签名身份. 在0.5中,替换 `new Client({ resolve, transports }, options)` 与 `new Client(resolve, transport, options)` (S3保留其明确的限制理由).

```ts
import { ClientManager, clientKey, type DataSource } from "@compforge/harness-toolbox";
import { MysqlClient } from "@compforge/harness-toolbox/mysql";
import { DirectTransport } from "@compforge/harness-toolbox/transport";

const target = { host: "localhost", port: 3306, database: "app", user: "reader", password: "..." };
const source: DataSource<MysqlClient> = {
  clientKey: clientKey("mysql", target),
  createClient: (_clients, signal) => new MysqlClient(target, new DirectTransport(),
    { signal, connectTimeoutMs: 5_000, queryTimeoutMs: 10_000 }),
};
const clients = new ClientManager();
try {
  const db = await clients.get(source);
  const rows = await db.database.query(db.target, "SELECT 1 AS value", []);
} finally {
  await clients.dispose();
}
```

呼叫者拥有证书,授权,查询语义,容量和超时. MySQL 可以使用 TCP或Python-capable Pod;后者需要PyMySQL. 运输回落只发生在 建立连接,绝不通过重放失败的 SQL 操作。 Pod 输入使用 stdin .

Pod 日志抓取共享一个相同的 Pod/ 容器实例和一次绝对时间窗口 客户端,而消费者独立过滤并保留自己的原始副本。 提供明确的 抓取策略、 共享货币池和字节预算; 软件包不选择产品 限制。 临时抓取文件直播直到客户端处理.

见 [工具箱合同](https://npmcn.com/docs/toolbox.md) 为所有权和跨语言语义.

## 读取 S3 对象

S3使用官方的AWS SDK在同一个被管理的生命周期后. 供应解决连接 设置和明确的限制; 软件包没有发现业务配置或证书.

```ts
import { ClientManager } from "@compforge/harness-toolbox";
import { S3DataSource } from "@compforge/harness-toolbox/s3";

const clients = new ClientManager();
try {
  const s3 = await clients.get(new S3DataSource({
    endpoint: "https://s3.example.com", region: "us-east-1",
    credentials: { accessKeyId: "...", secretAccessKey: "..." },
  }, { concurrency: 4, connectTimeoutMs: 5_000, requestTimeoutMs: 15_000 }));
  const object = await s3.headObject("artifacts", "runs/example.json");
  const prefix = await s3.readObject("artifacts", "runs/example.json", { maxBytes: 65_536 });
  // prefix.truncated distinguishes a bounded prefix from the complete object.
} finally {
  await clients.dispose();
}
```

`listObjects` 财务报告和审定财务报表 `listBuckets` 返回带有继续符号的有明确界限的页面; 呼叫者拥有整个扫描预算 Bucket Head和版本也可用. 错误保存 SDK 状态/ 代码: 失败的头部没有转换为 `exists=false`。阅读停止于 字节盖并关闭正文; 请求截止日期包括排队和体能消耗. 没有写入操作,自动重试或隐含的区域重定向被曝光.

对于绘制的TCP运输,通过 `{ key: "cluster/context identity", transport }` 作为第三个 数据来源论证. 来电者拥有运输的一生. 需要路径式地址 用于绘制路径; 直接端点也支持虚拟托管桶。 已签名的主机和 TLS 身份仍然是逻辑终点,而不是转发地址。 可提供私人CA 明确使用 `ca`; 证书验证仍然启用。 初始化准备客户端 和路线,不列出桶或声称证书已经验证.

## 边界 MySQL 读取

`MysqlClient.database.queryReadonly(target, sql, values, { timeoutMs, maxRows, maxBytes })` 用途 共享查询位置和可支配本地会话 `NO_BACKSLASH_ESCAPES`一个SELECT的最后期限, 和只读交易。 准备执行会绑定值并逐步保留行, 返回时 `rows`, (中文(简体) ), `columns`, (中文(简体) ), `bytes`, (中文(简体) ), `truncated`,以及 `truncation`。额外一行证明行切换; a 不保留超过所余字节预算的行.

呼叫者拥有 SQL 分类、功能政策和最低特权身份:只读 EAD 不是任意的 SQL 沙盒。 这个API需要 MySQL 5.7.8+ `max_execution_time` 没有 倒倒倒波德活佛. 完成、缩短、超时和取消销毁一次性 会话没有重放或更改普通借用会话。 断接不能证明是即时的 服务器取消。 字节预算限制保留了JSON行,而不是单个线包或字段.

## 可重用绑定的查询并读取缓存

对于可信,呼叫者拥有的SELECT声明, `queryLimited(database, target, statement, maxRows)` 附加整数 `LIMIT maxRows + 1` 返回时 `{ rows, truncated }`. SQL 绝不能已经拥有 LIMIT或后继终止;帮助者不解析或重写任意的 SQL. 商业价值 保留约束参数. `limitedStatement` 财务报告和审定财务报表 `limitedRows` 披露相同的准备/预测 页:1 `Database.queryBatch`。 。 。 . `maxRows` 必须是低于2147483647的正整数。 这些帮手 只绑定行数:使用 `queryReadonly` 当一次性只读会话和字节/时间预算 需要这样做.

`DataLoader` 在一个明确解读的范围内分享结果、失败和飞行中的工作,类似于 瓜娃的"加载卡切"但范围为一发一发. 消费者不得改变共同的成果. 使用 `withReadScope` (b) 不使用它写作或投票.

```ts
import { DataLoader } from '@compforge/harness-toolbox/data-loader';
import { withReadScope, queryLimited } from '@compforge/harness-toolbox/mysql';

const scope = new DataLoader({
  maxEntries: 256, maxBytes: 4 * 1024 * 1024, signal: client.signal,
});
const reads = withReadScope(client.database, scope);
try {
  const page = await queryLimited(reads, client.target, {
    sql: 'SELECT id FROM items WHERE owner = ? ORDER BY id', values: [owner],
  }, 100);
} finally {
  await scope.close(); // Root still owns client.dispose().
}
```

密钥包括完整的数据库身份,SQL和打入的参数作为不透明摘要. 不连续 参数绕行缓存。 批次读取再利用缓存条目并按本地命令发送错失 批号,或无法批号时的顺序查询。 失败不重放而共享; 使用新的观测范围。 这不是一个一致的数据库快照.

入站容量包括失败和待读;新密钥在满时会绕行缓存. 序列化 结果字节绑定保留结果,不包括密钥/errors和活操作内存. 超规模 或非顺序结果返回但不保留。 范围 关闭信号取消并加入 操作,包括未标记的读取。 行动必须尊重迅速取消的信号; MySQL读取保留其基本的客户端超时/取消政策. 适配器关闭时也不拥有 范围或数据库。 服务员的可选信号 `scope.read` 只取消那个服务员.

## 共享 Pod中继运输

`PodRelayTransport` 通过现有的 Running/Ready Pod 打开 TCP 路由。 它发现一个 选定命名空间中符合条件的容器(可选择由标签选择器限制) 当前执行使用 Python 3.8+ 标准图书馆 Ayncio. 呼叫者提供终点, 不是一个Pod名或口译员。 它不创建 Pods 并安装任何软件包 。 选中的 Pod 必须能够解决并到达每个目的地.

在 root 执行的客户端管理器中创建一个传送器, 并将其借给 Service/ protocol 客户。 它的密钥描述了集群访问和中继政策,从来不是服务或数据库身份. 同时代的呼叫者共享Pod发现,每个主机/端口一个接力过程和一个前置过程. 数据库 证书和连接仍然归其协议客户所有.

```ts
import { ClientManager } from '@compforge/harness-toolbox';
import { PodRelayTransport } from '@compforge/harness-toolbox/transport';

const clients = new ClientManager();
try {
  const relay = await clients.get({
    clientKey: 'transport:customer-cluster:app',
    createClient: (_clients, signal) => new PodRelayTransport({
      kubeconfig: '/config/cluster', context: 'customer', namespace: 'app',
      selector: 'diagnostic-relay=eligible',
      startupTimeoutMs: 5000, connectTimeoutMs: 5000,
      maxConnections: 16, maxTargets: 8, maxCandidatePods: 8, signal,
    }),
  });
  // Pass this same transport instance to each protocol client; clients never dispose it.
  const address = await relay.connect({host: 'database.internal', port: 3306});
  // Connect the native protocol client to address; do not dispose relay in a Service.
} finally {
  await clients.dispose();
}
```

主办方必须授权 `list pods`, (中文(简体) ), `create pods/exec` 财务报告和审定财务报表 `create pods/portforward`,包括: 在选定的容器中运行一个临时进程。 清单/发现和每次准备行动 使用启动TimeoutMs; 候选的Pod计数、目标计数和集合的活继电器连接为 分别相接. 列表 socks 是命名空间范围 。 中继收听器只绑入波德回路和 本地转发仅用于主机回回转 。 控制信件包含目的地, 绝不是 DB 证书 .

处理关闭前置和执行流; EOF关闭远程收听器/连接. 如果执行官 无 EOF 连接已丢失, 一个30秒的心跳租赁会限制远程进程寿命 . 死继电器会使其路由无效并失效的呼叫者;没有重放SQL或其他协议操作. 根应在处置运输之前完成或取消协议工作.

### OpenSearch 连接准备

`openOpenSearch` 在返回前对已解决的终点进行探测。 它尝试了提供的TCP运输 仅用于连接失败; HTTP 授权/服务器出错停止准备, 而失败 读取不再在其它路线上重放. `onRoute` 报告选定的运输和安全后退 理由,你觉得呢? 呼叫者拥有共享的运输工具,例如 `PodRelayTransport` 和他们的清理.

Routed HTTPS保留了原来的TLS服务器名. Bun 禁用 HTTP 保留活性,因为它被再利用 套接字恢复可在驱动程序下方重放失败的请求; 节点保留连接集合 .

## 计算证据

`kubernetes/compute` 出口 `collectClusterCompute` 财务报告和审定财务报表 `collectWorkloadCompute`他们借钱 获取资源,使用明确的截止日期/项目/页数预算,并独立保留阅读范围. 使用 `client.clusterResources()` 用于节点和全名空间 Pods; 普通客户端方法保留其 已配置命名空间 。 禁用集群读取记录 `permission_denied`; 它不阻断一个 单独命名空间范围的工作负荷读取。 见 [计算收藏](https://npmcn.com/docs/toolbox.md#kubernetes-compute-evidence)。 。 。 .

### 连接获取截止日期

MySQL,OpenSearch和Redis使用相同的收购生命周期. `connectTimeoutMs` 包括路线绘图 和握手/检测;可选 `acquireTimeoutMs` 将所有路由绑定在一起( 默认: 每个路由预算 × 路由计数) . 取消会保留呼叫者的理由并阻止后期映射开始握手. 查询和命令 超时仍然单独进行,失败的操作从不在另一运输上重放.

数据记录器接受可选选项 `logger.debug(message)` 和不敏感 `label`。 。 。 . 诊断方法区分误差、等值、被击中、绕行、不保留和使用范围/读取的相近 标识符,从不按键,数值或出错。 记录不会改变保留或重试政策.

### 网络连接

`@compforge/harness-toolbox/network` 出口 `probeConnectivity(endpoint, execute, {timeoutMs, signal?})`。 。 。 . 它会消耗 `Endpoint` 从 `@compforge/harness-common`· ; `ConnectivityTarget` 删除.

```typescript
import type { Endpoint } from "@compforge/harness-common";
import { endpointFromUrl, validateEndpoint } from "@compforge/harness-toolbox/endpoint";

const endpoint: Endpoint = endpointFromUrl("https://storage.example:9443/object?signature=private");
// { scheme: "https", host: "storage.example", port: 9443, secure: true }
validateEndpoint(endpoint); // Pure validation; no DNS or I/O.
```

URL投影会降低资质,路径,查询和片段,并解压IPv6主机. HTTP(S),WS(S)和FTP都有默认的端口. 这个 `tls` 方案需要端口和设置 `secure: true`。 。 。 . 其他计划需要明确的港口和出港条件 `secure` 未说明; 调用者从协议配置中提供任何加密要求 . 出错不会暴露原始的 URL 。 将完整的 URL 单独保存用于资源访问 .

`secure` 替换 `tls` 在探测输入和结果目标。 HTTPS/WSS/TLS要求 `secure: true`· ; HTTP/WS拒绝. 与 `secure: true`,该探测器支持直接 TLS 用于 `https`, (中文(简体) ), `wss`,以及 明确 `tls` 计划。 其他计划或缺失的计划 `ProtocolError` 联合国 `ToolboxError` 与 `kind: "protocol"`, (中文(简体) ), `code: "Unsupported"`(中文(简体) ) 执行前: 协议谈判的加密, 如 MySQL 或 SSTATLS 未执行 . 没有加密要求,成功的TCP检查不能证明应用程序-protocol 可用性或加密。 TLS仍然是被观测到的握手阶段的名称.

呼叫者在消费环境(主机、Pod或沙盒)提供执行器, 运行 Python 3 与 供给的 argv 和 stdin 并强制超时/取消. DNS,TCP和可选验证的TLS有分别的结果和时间. 域名,( 域名), IP 字元和库伯内特 `service.namespace` 名称使用相同的API。 没有 在呼叫器主机或ICMP要求上隐含执行. 网络失败返回 ; 缺少 Python 、 执行失败和不完全输出抛出 。 TLS 成功 不建立 HTTP 授权、 对象访问或应用程序下载政策.

## 常见问题

### @compforge/harness-toolbox 是什么？

共享基础设施客户、运输和有限数据采集

### 如何安装 @compforge/harness-toolbox？

在项目目录运行 npm install @compforge/harness-toolbox，或使用 pnpm add / yarn add / bun add。

### @compforge/harness-toolbox 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @compforge/harness-toolbox 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @compforge/harness-toolbox 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @compforge/harness-toolbox 可以商用吗？

@compforge/harness-toolbox 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @compforge/harness-toolbox 的下载量有多少？

根据 npm 官方下载统计，@compforge/harness-toolbox 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,447 次，日均约 115 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @compforge/harness-toolbox 还在维护吗？

最新版本 0\.5\.6 发布于 2026/11/06（4 天前）；至今共发布 28 个版本，其中过去 12 个月发布了 28 个；首次发布于 2026/09/10。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

