@compforge/harness-toolbox 0.4.8 → 0.5.1

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.
Files changed (70) hide show
  1. package/README.md +41 -9
  2. package/dist/{chunk-1ts7pswj.js → chunk-0d8vs5q8.js} +33 -2
  3. package/dist/{chunk-h8fwx0k7.js → chunk-18gcp0ck.js} +32 -7
  4. package/dist/{chunk-35cjec9z.js → chunk-3b877a0y.js} +6 -6
  5. package/dist/{chunk-gm4swndx.js → chunk-43mcyrh4.js} +14 -24
  6. package/dist/chunk-56fev9np.js +142 -0
  7. package/dist/{chunk-zp1s833x.js → chunk-7m95c7pn.js} +26 -13
  8. package/dist/{chunk-f3vq900j.js → chunk-92aacbwh.js} +1 -1
  9. package/dist/{chunk-x4ntb898.js → chunk-c2b2jwm4.js} +18 -18
  10. package/dist/chunk-ehmx0yhp.js +52 -0
  11. package/dist/{chunk-t4hrnaj0.js → chunk-ex429qjt.js} +22 -20
  12. package/dist/{chunk-m391jmpw.js → chunk-hbhbragw.js} +9 -9
  13. package/dist/{chunk-fqrknvr8.js → chunk-kap6ka3n.js} +27 -12
  14. package/dist/{chunk-vymm4g9h.js → chunk-kxpecgy7.js} +106 -37
  15. package/dist/{chunk-nftzckdy.js → chunk-mvkxs8d0.js} +17 -2
  16. package/dist/{chunk-f98qrpx1.js → chunk-njs48b51.js} +28 -27
  17. package/dist/chunk-sb5qzv37.js +62 -0
  18. package/dist/{chunk-dx6yvj81.js → chunk-xhfbark7.js} +1 -1
  19. package/dist/chunk-z8e1ckkq.js +16 -0
  20. package/dist/connection/acquire.d.ts +3 -4
  21. package/dist/connection/acquire.js +2 -4
  22. package/dist/datasource.d.ts +0 -6
  23. package/dist/file/client.js +2 -2
  24. package/dist/file/index.js +4 -4
  25. package/dist/file/local.js +3 -3
  26. package/dist/file/pod.js +3 -3
  27. package/dist/http/client.d.ts +15 -0
  28. package/dist/http/client.js +21 -0
  29. package/dist/http/handler.d.ts +10 -0
  30. package/dist/http/handler.js +6 -0
  31. package/dist/http/index.d.ts +2 -0
  32. package/dist/http/index.js +21 -0
  33. package/dist/http/types.d.ts +34 -0
  34. package/dist/http/types.js +0 -0
  35. package/dist/kubernetes/client.js +9 -9
  36. package/dist/kubernetes/environment.js +9 -9
  37. package/dist/kubernetes/exec-transport.js +2 -2
  38. package/dist/kubernetes/pod-log-datasource.js +1 -1
  39. package/dist/kubernetes/port-forward.d.ts +4 -0
  40. package/dist/kubernetes/port-forward.js +1 -1
  41. package/dist/kubernetes/resource-transport.js +2 -2
  42. package/dist/kubernetes/service-port-forward.d.ts +3 -2
  43. package/dist/kubernetes/service-port-forward.js +2 -2
  44. package/dist/mysql/client.d.ts +7 -7
  45. package/dist/mysql/client.js +12 -7
  46. package/dist/mysql/index.js +16 -11
  47. package/dist/opensearch/client.d.ts +14 -4
  48. package/dist/opensearch/client.js +15 -8
  49. package/dist/opensearch/index.js +15 -8
  50. package/dist/redis/client.d.ts +7 -6
  51. package/dist/redis/client.js +12 -7
  52. package/dist/redis/index.js +16 -11
  53. package/dist/s3/client.d.ts +5 -3
  54. package/dist/s3/client.js +16 -2
  55. package/dist/s3/datasource.js +15 -8
  56. package/dist/s3/handler.d.ts +2 -3
  57. package/dist/s3/handler.js +2 -1
  58. package/dist/s3/index.js +15 -8
  59. package/dist/transport/index.d.ts +18 -8
  60. package/dist/transport/index.js +17 -4
  61. package/dist/transport/lifecycle.d.ts +22 -0
  62. package/dist/transport/lifecycle.js +8 -0
  63. package/dist/transport/pod-relay.d.ts +7 -4
  64. package/dist/transport/pod-relay.js +6 -3
  65. package/dist/transport/service-port-forward.d.ts +30 -0
  66. package/dist/transport/service-port-forward.js +15 -0
  67. package/package.json +9 -3
  68. package/dist/{chunk-x0yhfg29.js → chunk-5w85c7cs.js} +3 -3
  69. package/dist/{chunk-ww11q58v.js → chunk-rncagjbc.js} +3 -3
  70. package/dist/{chunk-r3rnsvwv.js → chunk-xeft7af0.js} +3 -3
@@ -1,18 +1,18 @@
1
- import {
2
- acquireConnection,
3
- awaitWithSignal
4
- } from "./chunk-gm4swndx.js";
5
1
  import {
6
2
  discoverRedisTopology
7
3
  } from "./chunk-5tbzf9wd.js";
4
+ import {
5
+ isConnectionNetworkError
6
+ } from "./chunk-18gcp0ck.js";
7
+ import {
8
+ Transport
9
+ } from "./chunk-sb5qzv37.js";
8
10
  import {
9
11
  TimeoutError
10
12
  } from "./chunk-rkt41za2.js";
11
- import {
12
- isConnectionNetworkError
13
- } from "./chunk-h8fwx0k7.js";
14
13
 
15
14
  // src/redis/client.ts
15
+ import { raceSignal } from "race-signal";
16
16
  import { createClient, SocketClosedUnexpectedlyError, ConnectionTimeoutError } from "@redis/client";
17
17
  function stringValue(value) {
18
18
  if (Buffer.isBuffer(value))
@@ -96,7 +96,7 @@ class RedisConnection {
96
96
  client.destroy();
97
97
  };
98
98
  try {
99
- await awaitWithSignal(client.connect(), signal, close);
99
+ await raceSignal(client.connect(), signal);
100
100
  signal.throwIfAborted();
101
101
  return new RedisConnection(endpoint, client, config.timeoutMs, () => lastError, config.signal);
102
102
  } catch (error) {
@@ -119,12 +119,14 @@ class RedisConnection {
119
119
  const timer = setTimeout(() => timeout.abort(new TimeoutError(`Redis ${operationName} timed out after ${this.timeoutMs}ms (${this.endpoint.host}:${this.endpoint.port})`)), this.timeoutMs);
120
120
  const signal = this.signal ? AbortSignal.any([this.signal, timeout.signal]) : timeout.signal;
121
121
  try {
122
- return await awaitWithSignal(Promise.resolve().then(() => {
122
+ return await raceSignal(Promise.resolve().then(() => {
123
123
  signal.throwIfAborted();
124
124
  return operation();
125
- }), signal, () => this.close());
125
+ }), signal);
126
126
  } finally {
127
127
  clearTimeout(timer);
128
+ if (signal.aborted)
129
+ this.close();
128
130
  }
129
131
  }
130
132
  ping() {
@@ -171,19 +173,17 @@ class RedisAccess {
171
173
  #connections = new Map;
172
174
  #controller = new AbortController;
173
175
  #signal;
174
- #transports;
176
+ #transport;
175
177
  #closing;
176
178
  constructor(transports, baseConfig, connectionFactory = RedisConnection.connect, lifecycle = {}) {
177
179
  this.baseConfig = baseConfig;
178
180
  this.connectionFactory = connectionFactory;
179
181
  this.lifecycle = lifecycle;
180
- this.#transports = Array.isArray(transports) ? transports : [transports];
181
- if (!this.#transports.length)
182
- throw new Error("Redis requires a TCP transport");
182
+ this.#transport = transports instanceof Transport ? transports : new Transport(Array.isArray(transports) ? transports : [transports]);
183
183
  for (const value of [
184
184
  baseConfig.timeoutMs,
185
185
  baseConfig.connectTimeoutMs ?? baseConfig.timeoutMs,
186
- baseConfig.acquireTimeoutMs ?? (baseConfig.connectTimeoutMs ?? baseConfig.timeoutMs) * this.#transports.length
186
+ baseConfig.acquireTimeoutMs ?? (baseConfig.connectTimeoutMs ?? baseConfig.timeoutMs)
187
187
  ]) {
188
188
  if (!Number.isFinite(value) || value <= 0)
189
189
  throw new Error("Redis timeouts must be positive milliseconds");
@@ -214,14 +214,16 @@ class RedisAccess {
214
214
  return pending;
215
215
  }
216
216
  #open(endpoint, database, credentials) {
217
- return acquireConnection(this.#transports, {
217
+ return this.#transport.acquire({
218
218
  name: "Redis connection",
219
219
  signal: this.#signal,
220
220
  connectTimeoutMs: this.baseConfig.connectTimeoutMs ?? this.baseConfig.timeoutMs,
221
221
  acquireTimeoutMs: this.baseConfig.acquireTimeoutMs,
222
222
  onRoute: this.lifecycle.onRoute,
223
223
  open: async (transport, attempt) => {
224
- const mapped = await transport.connect(endpoint);
224
+ if (transport.kind !== "tcp")
225
+ throw new Error("Redis requires a TCP transport");
226
+ const mapped = await transport.connect(endpoint, attempt);
225
227
  const connection = await this.connectionFactory(endpoint, mapped, {
226
228
  ...this.baseConfig,
227
229
  ...credentials,
@@ -263,7 +265,8 @@ class RedisAccess {
263
265
  }
264
266
 
265
267
  class RedisClient {
266
- source;
268
+ configuration;
269
+ transport;
267
270
  lifecycle;
268
271
  #controller = new AbortController;
269
272
  signal;
@@ -271,22 +274,20 @@ class RedisClient {
271
274
  #disposal;
272
275
  #access;
273
276
  #target;
274
- constructor(source, lifecycle = {}) {
275
- this.source = source;
277
+ constructor(configuration, transport, lifecycle = {}) {
278
+ this.configuration = configuration;
279
+ this.transport = transport;
276
280
  this.lifecycle = lifecycle;
277
281
  this.signal = lifecycle.signal ? AbortSignal.any([lifecycle.signal, this.#controller.signal]) : this.#controller.signal;
278
282
  }
279
283
  initialize() {
280
284
  this.signal.throwIfAborted();
281
285
  return this.#initialization ??= (async () => {
282
- this.#target = await awaitWithSignal(this.source.resolve(), this.signal);
286
+ this.#target = await raceSignal(typeof this.configuration === "function" ? this.configuration() : Promise.resolve(this.configuration), this.signal);
283
287
  this.signal.throwIfAborted();
284
- if (!this.source.transports.length || this.source.transports.some((transport) => transport.kind !== "tcp")) {
285
- throw new Error("Redis requires TCP transports");
286
- }
287
288
  if (this.#target.clusterType === "cluster" && this.#target.database !== 0)
288
289
  throw new Error("Redis Cluster requires database 0");
289
- this.#access = new RedisAccess(this.source.transports, this.#target, undefined, { ...this.lifecycle, signal: this.signal });
290
+ this.#access = new RedisAccess(this.transport, this.#target, undefined, { ...this.lifecycle, signal: this.signal });
290
291
  })();
291
292
  }
292
293
  get access() {
@@ -311,8 +312,8 @@ class RedisClient {
311
312
  })();
312
313
  }
313
314
  }
314
- async function openRedis(source, lifecycle = {}) {
315
- const client = new RedisClient(source, lifecycle);
315
+ async function openRedis(configuration, transport, lifecycle = {}) {
316
+ const client = new RedisClient(configuration, transport, lifecycle);
316
317
  try {
317
318
  await client.initialize();
318
319
  } catch (error) {
@@ -0,0 +1,62 @@
1
+ import {
2
+ acquireConnection
3
+ } from "./chunk-43mcyrh4.js";
4
+
5
+ // src/transport/lifecycle.ts
6
+ class Transport {
7
+ candidates;
8
+ #controller = new AbortController;
9
+ resourceSignal = this.#controller.signal;
10
+ signal;
11
+ #pending = new Set;
12
+ #cleanupErrors = [];
13
+ #disposal;
14
+ constructor(candidates = [], signal) {
15
+ this.candidates = candidates;
16
+ this.signal = signal ? AbortSignal.any([signal, this.#controller.signal]) : this.#controller.signal;
17
+ }
18
+ paths() {
19
+ return this.candidates;
20
+ }
21
+ async initialize() {
22
+ this.signal.throwIfAborted();
23
+ }
24
+ acquire(options) {
25
+ this.signal.throwIfAborted();
26
+ const signal = options.signal ? AbortSignal.any([options.signal, this.signal]) : this.signal;
27
+ return acquireConnection(this.paths(), {
28
+ ...options,
29
+ signal,
30
+ onPending: (pending) => {
31
+ this.#pending.add(pending);
32
+ pending.then(() => this.#pending.delete(pending), () => this.#pending.delete(pending));
33
+ },
34
+ close: async (connection) => {
35
+ try {
36
+ await options.close(connection);
37
+ } catch (error) {
38
+ this.#cleanupErrors.push(error);
39
+ throw error;
40
+ }
41
+ }
42
+ });
43
+ }
44
+ async close() {}
45
+ dispose() {
46
+ return this.#disposal ??= (async () => {
47
+ this.#controller.abort(new Error("Transport disposed"));
48
+ const errors = [];
49
+ try {
50
+ await this.close();
51
+ } catch (error) {
52
+ errors.push(error);
53
+ }
54
+ await Promise.allSettled([...this.#pending]);
55
+ errors.push(...this.#cleanupErrors);
56
+ if (errors.length)
57
+ throw new AggregateError(errors, "Transport cleanup failed");
58
+ })();
59
+ }
60
+ }
61
+
62
+ export { Transport };
@@ -2,7 +2,7 @@ import {
2
2
  BoundedFileClient,
3
3
  fileClientOptions,
4
4
  filePaths
5
- } from "./chunk-ww11q58v.js";
5
+ } from "./chunk-rncagjbc.js";
6
6
  import {
7
7
  FileError
8
8
  } from "./chunk-rkt41za2.js";
@@ -0,0 +1,16 @@
1
+ import {
2
+ httpHandler
3
+ } from "./chunk-c2b2jwm4.js";
4
+
5
+ // src/s3/handler.ts
6
+ function s3Handler(target, route, limits) {
7
+ const endpoint = new URL(target.endpoint);
8
+ const mapped = route.host !== endpoint.hostname || route.port !== Number(endpoint.port || (endpoint.protocol === "https:" ? 443 : 80));
9
+ if (mapped && target.forcePathStyle === false) {
10
+ throw new Error("S3 mapped transports require path-style addressing to preserve bucket and TLS identity");
11
+ }
12
+ const handler = httpHandler(target, route, limits);
13
+ return { handler, destroy: () => handler.destroy() };
14
+ }
15
+
16
+ export { s3Handler };
@@ -1,12 +1,10 @@
1
1
  import type { ClientLifecycle } from "../datasource";
2
- /** Stop waiting without leaving rejected preparation promises unobserved. */
3
- export declare function awaitWithSignal<T>(pending: Promise<T>, signal: AbortSignal, cancel?: () => void): Promise<T>;
4
2
  export interface ConnectionAttempt {
5
3
  readonly signal: AbortSignal;
6
4
  /** Remaining mapping + handshake budget, not a fresh timeout for each phase. */
7
5
  remainingMs(): number;
8
6
  }
9
- interface Acquisition<R, C> {
7
+ export interface Acquisition<R, C> {
10
8
  name: string;
11
9
  connectTimeoutMs: number;
12
10
  acquireTimeoutMs?: number;
@@ -19,6 +17,8 @@ interface Acquisition<R, C> {
19
17
  /** Undefined means terminal; authentication and protocol errors must not change route. */
20
18
  retryReason(error: unknown): string | undefined;
21
19
  onRoute?: ClientLifecycle["onRoute"];
20
+ /** Owner tracks late completion through its rollback, not only the initial open promise. */
21
+ onPending?: (pending: Promise<unknown>) => void;
22
22
  }
23
23
  /**
24
24
  * @spec One acquisition owns ordered attempts and a deadline covering mapping and handshake.
@@ -31,4 +31,3 @@ interface Acquisition<R, C> {
31
31
  export declare function acquireConnection<R extends {
32
32
  readonly name: string;
33
33
  }, C>(routes: readonly R[], options: Acquisition<R, C>): Promise<C>;
34
- export {};
@@ -1,9 +1,7 @@
1
1
  import {
2
- acquireConnection,
3
- awaitWithSignal
4
- } from "../chunk-gm4swndx.js";
2
+ acquireConnection
3
+ } from "../chunk-43mcyrh4.js";
5
4
  import"../chunk-rkt41za2.js";
6
5
  export {
7
- awaitWithSignal,
8
6
  acquireConnection
9
7
  };
@@ -1,11 +1,5 @@
1
1
  export { clientKey, ClientManager, EnvironmentContext, type Client, type ClientProvider, type DataSource, type ServiceDataSource } from "@compforge/harness-common";
2
- import type { Transport } from "./transport";
3
2
  export { ToolboxError, KubernetesError, type ErrorKind } from "./errors";
4
- /** Resolution owns configuration semantics; transports preserve the resolved target and identity. */
5
- export interface ConnectionSource<Target> {
6
- resolve(): Promise<Target>;
7
- readonly transports: readonly Transport[];
8
- }
9
3
  export interface ClientLifecycle {
10
4
  signal?: AbortSignal;
11
5
  onDispose?: (dispose: () => Promise<void>) => void;
@@ -2,9 +2,9 @@ import {
2
2
  BoundedFileClient,
3
3
  fileClientOptions,
4
4
  filePaths
5
- } from "../chunk-ww11q58v.js";
6
- import"../chunk-rkt41za2.js";
5
+ } from "../chunk-rncagjbc.js";
7
6
  import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-rkt41za2.js";
8
8
  export {
9
9
  filePaths,
10
10
  fileClientOptions,
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  PodFileClient,
3
3
  PodFileDataSource
4
- } from "../chunk-dx6yvj81.js";
4
+ } from "../chunk-xhfbark7.js";
5
5
  import {
6
6
  LocalFileClient,
7
7
  LocalFileDataSource
8
- } from "../chunk-f3vq900j.js";
9
- import"../chunk-ww11q58v.js";
8
+ } from "../chunk-92aacbwh.js";
9
+ import"../chunk-rncagjbc.js";
10
+ import"../chunk-v3hxvnrc.js";
10
11
  import {
11
12
  FileError
12
13
  } from "../chunk-rkt41za2.js";
13
- import"../chunk-v3hxvnrc.js";
14
14
 
15
15
  // src/file/index.ts
16
16
  import { FileDataSource } from "@compforge/harness-common";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  LocalFileClient,
3
3
  LocalFileDataSource
4
- } from "../chunk-f3vq900j.js";
5
- import"../chunk-ww11q58v.js";
6
- import"../chunk-rkt41za2.js";
4
+ } from "../chunk-92aacbwh.js";
5
+ import"../chunk-rncagjbc.js";
7
6
  import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-rkt41za2.js";
8
8
  export {
9
9
  LocalFileDataSource,
10
10
  LocalFileClient
package/dist/file/pod.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  PodFileClient,
3
3
  PodFileDataSource
4
- } from "../chunk-dx6yvj81.js";
5
- import"../chunk-ww11q58v.js";
6
- import"../chunk-rkt41za2.js";
4
+ } from "../chunk-xhfbark7.js";
5
+ import"../chunk-rncagjbc.js";
7
6
  import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-rkt41za2.js";
8
8
  export {
9
9
  PodFileDataSource,
10
10
  PodFileClient
@@ -0,0 +1,15 @@
1
+ import type { Client } from "../client";
2
+ import type { ClientLifecycle } from "../datasource";
3
+ import { Transport } from "../transport";
4
+ import type { HttpTarget, HttpLimits, HttpRequestOptions, HttpResponse, HttpApi } from "./types";
5
+ /** HTTP clients borrow a Transport; their pools and response bodies belong to the client. */
6
+ export declare class HttpClient implements Client, HttpApi {
7
+ #private;
8
+ private readonly transport;
9
+ private readonly lifecycle;
10
+ readonly signal: AbortSignal;
11
+ constructor(target: HttpTarget, transport: Transport, limits: HttpLimits, lifecycle?: ClientLifecycle);
12
+ initialize(): Promise<void>;
13
+ request(path: string, options?: HttpRequestOptions): Promise<HttpResponse>;
14
+ dispose(): Promise<void>;
15
+ }
@@ -0,0 +1,21 @@
1
+ import {
2
+ HttpClient
3
+ } from "../chunk-56fev9np.js";
4
+ import"../chunk-18gcp0ck.js";
5
+ import"../chunk-kap6ka3n.js";
6
+ import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-c2b2jwm4.js";
8
+ import"../chunk-ssj93brx.js";
9
+ import"../chunk-ehmx0yhp.js";
10
+ import"../chunk-0d8vs5q8.js";
11
+ import"../chunk-xgnz10sr.js";
12
+ import"../chunk-6fnhzhdb.js";
13
+ import"../chunk-mvkxs8d0.js";
14
+ import"../chunk-rq5fc007.js";
15
+ import"../chunk-9shz0bw1.js";
16
+ import"../chunk-sb5qzv37.js";
17
+ import"../chunk-43mcyrh4.js";
18
+ import"../chunk-rkt41za2.js";
19
+ export {
20
+ HttpClient
21
+ };
@@ -0,0 +1,10 @@
1
+ import { NodeHttpHandler } from "@smithy/node-http-handler";
2
+ import type { Endpoint } from "../transport";
3
+ import type { HttpTarget, HttpLimits } from "./types";
4
+ /** @rule Routing changes the dial address, never the HTTP Host or certificate identity. */
5
+ export declare function httpHandler(target: HttpTarget, route: Endpoint, limits: Omit<HttpLimits, "maxResponseBytes">): {
6
+ handle(request: Parameters<NodeHttpHandler["handle"]>[0], options: Parameters<NodeHttpHandler["handle"]>[1]): Promise<{
7
+ response: import("@smithy/core/transport").HttpResponse;
8
+ }>;
9
+ destroy(): void;
10
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ httpHandler
3
+ } from "../chunk-c2b2jwm4.js";
4
+ export {
5
+ httpHandler
6
+ };
@@ -0,0 +1,2 @@
1
+ export { HttpClient } from "./client";
2
+ export type { HttpTarget, HttpLimits, HttpRequestOptions, HttpResponse, HttpApi } from "./types";
@@ -0,0 +1,21 @@
1
+ import {
2
+ HttpClient
3
+ } from "../chunk-56fev9np.js";
4
+ import"../chunk-18gcp0ck.js";
5
+ import"../chunk-kap6ka3n.js";
6
+ import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-c2b2jwm4.js";
8
+ import"../chunk-ssj93brx.js";
9
+ import"../chunk-ehmx0yhp.js";
10
+ import"../chunk-0d8vs5q8.js";
11
+ import"../chunk-xgnz10sr.js";
12
+ import"../chunk-6fnhzhdb.js";
13
+ import"../chunk-mvkxs8d0.js";
14
+ import"../chunk-rq5fc007.js";
15
+ import"../chunk-9shz0bw1.js";
16
+ import"../chunk-sb5qzv37.js";
17
+ import"../chunk-43mcyrh4.js";
18
+ import"../chunk-rkt41za2.js";
19
+ export {
20
+ HttpClient
21
+ };
@@ -0,0 +1,34 @@
1
+ export interface HttpTarget {
2
+ /** Logical endpoint; forwarding never changes HTTP Host or TLS identity. */
3
+ endpoint: string;
4
+ ca?: string;
5
+ }
6
+ /** Request time includes queueing, route preparation and response consumption. */
7
+ export interface HttpLimits {
8
+ concurrency: number;
9
+ connectTimeoutMs: number;
10
+ requestTimeoutMs: number;
11
+ maxResponseBytes: number;
12
+ }
13
+ export interface HttpRequestOptions {
14
+ method?: string;
15
+ headers?: Record<string, string>;
16
+ body?: string | Uint8Array;
17
+ signal?: AbortSignal;
18
+ }
19
+ /** The wire body is consumed or destroyed before return; callers own no socket. */
20
+ export interface HttpResponse {
21
+ status: number;
22
+ headers: Readonly<Record<string, string>>;
23
+ body: Uint8Array;
24
+ }
25
+ /**
26
+ * @spec Responses are bounded and consumed before returning; cancellation releases the request's resources.
27
+ * @rule HTTP statuses and redirects are returned without automatic replay or redirect following.
28
+ * @case id=http_forwarded_identity,desc=`HTTP through a mapped route`,expect=`original Host and TLS identity`
29
+ * @case id=http_cancel_body,desc=`cancel an active body read`,expect=`original cancellation reason and released pool slot`
30
+ * @see {@link component://docs/toolbox.md}
31
+ */
32
+ export interface HttpApi {
33
+ request(path: string, options?: HttpRequestOptions): Promise<HttpResponse>;
34
+ }
File without changes
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  KubernetesClient
3
- } from "../chunk-m391jmpw.js";
4
- import"../chunk-ae84rzq5.js";
5
- import"../chunk-1ts7pswj.js";
6
- import"../chunk-xgnz10sr.js";
7
- import"../chunk-6fnhzhdb.js";
8
- import"../chunk-x0yhfg29.js";
3
+ } from "../chunk-hbhbragw.js";
4
+ import"../chunk-5w85c7cs.js";
9
5
  import"../chunk-dpcge1xt.js";
10
- import"../chunk-r3rnsvwv.js";
6
+ import"../chunk-xeft7af0.js";
7
+ import"../chunk-ae84rzq5.js";
11
8
  import"../chunk-a9htb6cr.js";
12
- import"../chunk-rkt41za2.js";
13
9
  import"../chunk-v3hxvnrc.js";
14
- import"../chunk-nftzckdy.js";
10
+ import"../chunk-0d8vs5q8.js";
11
+ import"../chunk-xgnz10sr.js";
12
+ import"../chunk-6fnhzhdb.js";
13
+ import"../chunk-mvkxs8d0.js";
15
14
  import"../chunk-rq5fc007.js";
16
15
  import"../chunk-9shz0bw1.js";
16
+ import"../chunk-rkt41za2.js";
17
17
  export {
18
18
  KubernetesClient
19
19
  };
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  KubernetesClient
3
- } from "../chunk-m391jmpw.js";
4
- import"../chunk-ae84rzq5.js";
5
- import"../chunk-1ts7pswj.js";
6
- import"../chunk-xgnz10sr.js";
7
- import"../chunk-6fnhzhdb.js";
8
- import"../chunk-x0yhfg29.js";
3
+ } from "../chunk-hbhbragw.js";
4
+ import"../chunk-5w85c7cs.js";
9
5
  import"../chunk-dpcge1xt.js";
10
- import"../chunk-r3rnsvwv.js";
6
+ import"../chunk-xeft7af0.js";
7
+ import"../chunk-ae84rzq5.js";
11
8
  import {
12
9
  clientKey
13
10
  } from "../chunk-a9htb6cr.js";
14
- import"../chunk-rkt41za2.js";
15
11
  import"../chunk-v3hxvnrc.js";
16
- import"../chunk-nftzckdy.js";
12
+ import"../chunk-0d8vs5q8.js";
13
+ import"../chunk-xgnz10sr.js";
14
+ import"../chunk-6fnhzhdb.js";
15
+ import"../chunk-mvkxs8d0.js";
17
16
  import"../chunk-rq5fc007.js";
18
17
  import"../chunk-9shz0bw1.js";
18
+ import"../chunk-rkt41za2.js";
19
19
 
20
20
  // src/kubernetes/environment.ts
21
21
  class KubernetesEnvironment {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  KubernetesExecTransport
3
- } from "../chunk-r3rnsvwv.js";
4
- import"../chunk-rkt41za2.js";
3
+ } from "../chunk-xeft7af0.js";
5
4
  import"../chunk-v3hxvnrc.js";
5
+ import"../chunk-rkt41za2.js";
6
6
  export {
7
7
  KubernetesExecTransport
8
8
  };
@@ -8,8 +8,8 @@ import"../chunk-a9htb6cr.js";
8
8
  import {
9
9
  clientKey
10
10
  } from "../chunk-z5pm2emz.js";
11
- import"../chunk-rkt41za2.js";
12
11
  import"../chunk-v3hxvnrc.js";
12
+ import"../chunk-rkt41za2.js";
13
13
 
14
14
  // src/kubernetes/pod-log-datasource.ts
15
15
  class PodLogDataSource {
@@ -5,6 +5,9 @@ export interface PortForward {
5
5
  /** 完整 argv,进 evidence manifest 供审计复现 */
6
6
  command: string[];
7
7
  stop(): void;
8
+ /** Resolves after the process and its stdio have closed. */
9
+ exited?: Promise<number>;
10
+ isAlive?(): boolean;
8
11
  }
9
12
  export interface PortForwardTarget {
10
13
  kind: "service" | "pod";
@@ -44,4 +47,5 @@ export declare class PortForwardScope {
44
47
  onDiagnostic?: (line: string) => void;
45
48
  }): Promise<PortForwardResult>;
46
49
  stop(): void;
50
+ dispose(): Promise<void>;
47
51
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PortForwardScope,
3
3
  startPortForward
4
- } from "../chunk-nftzckdy.js";
4
+ } from "../chunk-mvkxs8d0.js";
5
5
  import"../chunk-rq5fc007.js";
6
6
  import"../chunk-9shz0bw1.js";
7
7
  export {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  KubernetesResourceTransport
3
- } from "../chunk-x0yhfg29.js";
3
+ } from "../chunk-5w85c7cs.js";
4
4
  import"../chunk-dpcge1xt.js";
5
5
  import"../chunk-a9htb6cr.js";
6
- import"../chunk-rkt41za2.js";
7
6
  import"../chunk-v3hxvnrc.js";
7
+ import"../chunk-rkt41za2.js";
8
8
  export {
9
9
  KubernetesResourceTransport
10
10
  };
@@ -1,6 +1,6 @@
1
1
  import type { Executor, KubectlOptions } from "./executor";
2
2
  import type { KubernetesEndpoint } from "./endpoint";
3
- import { type StartPortForward } from "./port-forward";
3
+ import { type StartPortForward, type PortForward } from "./port-forward";
4
4
  export interface ForwardedEndpoint extends KubernetesEndpoint {
5
5
  /** TLS 校验仍使用集群内逻辑地址,而不是本地 127.0.0.1。 */
6
6
  servername?: string;
@@ -23,9 +23,10 @@ export declare class ServicePortForwarder {
23
23
  signal?: AbortSignal;
24
24
  onDiagnostic?: (line: string) => void;
25
25
  }, starter?: StartPortForward): Promise<ServicePortForwarder>;
26
- get activeForwards(): readonly import("./port-forward").PortForward[];
26
+ get activeForwards(): readonly PortForward[];
27
27
  forward(endpoint: KubernetesEndpoint): Promise<ForwardedEndpoint>;
28
28
  /** 按 Service selector 把一个逻辑 endpoint 展开为每个 Running Pod 的独立 endpoint。 */
29
29
  forwardServiceTargets(endpoint: KubernetesEndpoint): Promise<ForwardedServiceTarget[]>;
30
30
  stop(): void;
31
+ dispose(): Promise<void>;
31
32
  }
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ServicePortForwarder
3
- } from "../chunk-1ts7pswj.js";
3
+ } from "../chunk-0d8vs5q8.js";
4
4
  import"../chunk-xgnz10sr.js";
5
5
  import"../chunk-6fnhzhdb.js";
6
- import"../chunk-nftzckdy.js";
6
+ import"../chunk-mvkxs8d0.js";
7
7
  import"../chunk-rq5fc007.js";
8
8
  import"../chunk-9shz0bw1.js";
9
9
  export {