@peac/cli 0.13.4 → 0.14.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.
@@ -0,0 +1,118 @@
1
+ /**
2
+ * CLI subprocess capture.
3
+ *
4
+ * Implements the bounded-capture wrapper used by `peac observe command`
5
+ * and `peac record command`. Hard implementation invariants:
6
+ *
7
+ * - Spawn discipline: `spawn(prog, args, { shell: false })`
8
+ * exclusively. NEVER `exec()`. The wrapper does NOT synthesize
9
+ * shell syntax or rewrite the command. `--shell-mode` is
10
+ * acknowledgement only.
11
+ * - Streaming capture: `node:crypto.createHash` updated chunk-by-chunk.
12
+ * Byte counter incremented chunk-by-chunk. Bounded sample buffer
13
+ * is the ONLY buffer retained, and ONLY when raw capture is
14
+ * double-opted-in. Full streams NEVER held in memory.
15
+ * - Stdin: `--capture-stdin-mode` controls BOTH whether the wrapper
16
+ * pipes parent stdin to the child AND what the wrapper records.
17
+ * `none` (default) closes child stdin and does NOT read parent stdin.
18
+ * The stdin pump must terminate when the child exits even if the
19
+ * parent stream is still open.
20
+ * - Timeout: `--timeout-ms` / `--kill-grace-ms` cascade SIGTERM then
21
+ * SIGKILL; the record IS still emitted. The nested SIGKILL timer
22
+ * is cleared on child close so it cannot keep the event loop alive.
23
+ * - Signal exit codes follow POSIX `128 + signal-num`: SIGINT=130,
24
+ * SIGTERM=143, SIGKILL=137; unknown signals fall back to 128.
25
+ * - Stdin pumping is listener-based (event handlers attached to the
26
+ * parent stream and child stdin). Backpressure pauses the parent
27
+ * until child stdin emits 'drain'. The pump is reliably abortable
28
+ * via an external AbortSignal even if the parent stream stays
29
+ * open and idle, and removes ONLY pump-owned listeners on cleanup
30
+ * (the parent is caller-owned).
31
+ */
32
+ import type { Readable } from 'node:stream';
33
+ /**
34
+ * Thrown by `captureCommand` when the child process fails to spawn
35
+ * (missing binary, ENOENT, EACCES, etc.). Node emits the `'error'`
36
+ * event in this case and never emits `'spawn'`/`'close'` -- without
37
+ * explicit handling the wrapper would hang waiting for `'close'`.
38
+ */
39
+ export declare class CliSpawnFailedError extends Error {
40
+ readonly cause?: unknown | undefined;
41
+ readonly code = "cli.spawn_failed";
42
+ constructor(message: string, cause?: unknown | undefined);
43
+ }
44
+ export type StdinMode = 'none' | 'length-only' | 'hashed';
45
+ export type CaptureMode = 'hashed' | 'redacted' | 'raw';
46
+ export interface CaptureOptions {
47
+ /** Resolved program path (passed verbatim to `spawn`). */
48
+ program: string;
49
+ /** Argv tail (passed verbatim to `spawn`; never wrapped in a shell). */
50
+ args: string[];
51
+ /** Working directory for the child (passed to `spawn`); not the recorded cwd. */
52
+ cwd: string;
53
+ /**
54
+ * Environment passed to the child. REQUIRED. Callers (the
55
+ * pipeline / pure handler) must construct the env explicitly so
56
+ * the env source is auditable; this function does NOT silently
57
+ * fall back to `process.env`.
58
+ */
59
+ env: NodeJS.ProcessEnv;
60
+ stdinMode: StdinMode;
61
+ /**
62
+ * Whether raw sample emission is enabled (requires `--capture-mode raw`
63
+ * AND `--unsafe-allow-raw-capture`). When false, no `sample_base64` is
64
+ * retained for stdout / stderr and the bounded sample buffer stays
65
+ * empty even though the streams are still hashed and counted.
66
+ */
67
+ rawCaptureEnabled: boolean;
68
+ /** Bounded sample cap for stdout (raw mode only). */
69
+ stdoutSampleBytes: number;
70
+ /** Bounded sample cap for stderr (raw mode only). */
71
+ stderrSampleBytes: number;
72
+ /** Wrapper timeout (ms). After this, the wrapper sends SIGTERM. */
73
+ timeoutMs: number;
74
+ /** SIGTERM-to-SIGKILL grace (ms). */
75
+ killGraceMs: number;
76
+ /**
77
+ * Optional readable from which to source parent stdin. Defaults to
78
+ * `process.stdin`. Tests inject a custom stream.
79
+ */
80
+ parentStdin?: Readable;
81
+ }
82
+ export interface StreamCaptureRef {
83
+ length: number;
84
+ /** sha256 hex digest with the canonical `sha256:` prefix. */
85
+ sha256: string;
86
+ truncated: boolean;
87
+ /** Present only when raw capture is enabled and the secret-scan does not suppress it. */
88
+ sample_base64?: string;
89
+ }
90
+ export interface StdinCaptureRef {
91
+ mode: StdinMode;
92
+ length?: number;
93
+ sha256?: string;
94
+ truncated?: boolean;
95
+ }
96
+ export interface CaptureResult {
97
+ exitCode: number;
98
+ /** OS-reported child exit signal. Distinct from `terminationSignal`. */
99
+ signal: string | null;
100
+ /** True when the wrapper sent termination signals due to `--timeout-ms` elapsing. */
101
+ timedOut: boolean;
102
+ /** Signal sent BY THE WRAPPER after timeout. */
103
+ terminationSignal: string | null;
104
+ startedAt: string;
105
+ finishedAt: string;
106
+ durationMs: number;
107
+ stdout: StreamCaptureRef;
108
+ stderr: StreamCaptureRef;
109
+ stdin: StdinCaptureRef;
110
+ }
111
+ export declare function exitCodeForSignal(signal: string | null | undefined): number;
112
+ /**
113
+ * Run the bounded-capture wrapper. The promise resolves when the child
114
+ * exits OR is killed by the wrapper after timeout; it does NOT reject
115
+ * on non-zero exit; the record IS still emitted regardless of child exit code.
116
+ */
117
+ export declare function captureCommand(opts: CaptureOptions): Promise<CaptureResult>;
118
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/lib/capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,aAAa,CAAC;AAEtD;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAI1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAH1B,QAAQ,CAAC,IAAI,sBAAsB;gBAEjC,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC;AAyCxD,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iFAAiF;IACjF,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qFAAqF;IACrF,QAAQ,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;CACxB;AAsBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAG3E;AAsND;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAgJjF"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * CLI capture limits and security defaults.
3
+ *
4
+ * Centralizes the bounded-capture caps and security-default constants
5
+ * used by `peac observe command` and `peac record command`. Mirrored
6
+ * (but enforced separately) by the Zod ranges in
7
+ * `@peac/schema/src/extensions/cli-execution.ts`; keep both sides in
8
+ * sync when changing.
9
+ *
10
+ * All values are POSIX-first. Windows behavior is not guaranteed by
11
+ * the current CLI carrier profile; see `docs/specs/CLI-CARRIER-PROFILE.md`.
12
+ */
13
+ /** Bounded-capture caps. */
14
+ export declare const CLI_LIMITS: {
15
+ /** Default max bytes retained in the stdout sample buffer (raw mode only). */
16
+ readonly defaultStdoutSampleBytes: 16384;
17
+ /** Default max bytes retained in the stderr sample buffer (raw mode only). */
18
+ readonly defaultStderrSampleBytes: 16384;
19
+ /** Hard ceiling for the stdout / stderr sample buffer (raw mode only). */
20
+ readonly maxStdoutSampleBytes: 65536;
21
+ readonly maxStderrSampleBytes: 65536;
22
+ /** Default max bytes recorded in argv (raw mode only). */
23
+ readonly defaultArgvCaptureBytes: 4096;
24
+ /** Hard ceiling for argv bytes (raw mode only). */
25
+ readonly maxArgvCaptureBytes: 16384;
26
+ /** Hard ceiling for env entry count (deny-by-default; allowlist <= this). */
27
+ readonly maxEnvEntries: 32;
28
+ /** Default wrapper timeout (10 minutes). */
29
+ readonly defaultTimeoutMs: 600000;
30
+ /** Wrapper timeout hard ceiling (24 hours). */
31
+ readonly maxTimeoutMs: 86400000;
32
+ /** Wrapper timeout floor (1 ms). */
33
+ readonly minTimeoutMs: 1;
34
+ /** Default SIGTERM-to-SIGKILL grace (5 seconds). */
35
+ readonly defaultKillGraceMs: 5000;
36
+ /** SIGTERM-to-SIGKILL grace hard ceiling (60 seconds). */
37
+ readonly maxKillGraceMs: 60000;
38
+ /** SIGTERM-to-SIGKILL grace floor. */
39
+ readonly minKillGraceMs: 0;
40
+ };
41
+ /**
42
+ * Shell binaries that, when detected as the program basename, REQUIRE
43
+ * the explicit `--shell-mode` acknowledgement. PEAC NEVER synthesizes
44
+ * shell syntax; the wrapper is an observer, not a shell orchestrator.
45
+ */
46
+ export declare const SHELL_BINARY_BASENAMES: Set<string>;
47
+ /** Returns true when the resolved program basename is a known shell binary. */
48
+ export declare function isShellBinary(programBasename: string): boolean;
49
+ //# sourceMappingURL=cli-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-limits.d.ts","sourceRoot":"","sources":["../../src/lib/cli-limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,4BAA4B;AAC5B,eAAO,MAAM,UAAU;IACrB,8EAA8E;;IAE9E,8EAA8E;;IAE9E,0EAA0E;;;IAI1E,0DAA0D;;IAE1D,mDAAmD;;IAGnD,6EAA6E;;IAG7E,4CAA4C;;IAE5C,+CAA+C;;IAE/C,oCAAoC;;IAGpC,oDAAoD;;IAEpD,0DAA0D;;IAE1D,sCAAsC;;CAE9B,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,aAQjC,CAAC;AAEH,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAE9D"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Shared command-option validation for `observe command` and
3
+ * `record command`. Single source of truth for:
4
+ *
5
+ * - numeric flag range / NaN-safe checks
6
+ * - env-allowlist key grammar + byte cap
7
+ * - record-only digest / opaque-ref preflights
8
+ * - raw capture / raw env / secret-scan unsafe-flag pairing
9
+ * - shell-binary detection acknowledgement
10
+ * - raw argv per-token cap
11
+ *
12
+ * Both commands consume `validateCoreCommandOptions` so their
13
+ * preflight semantics never drift. Record-command additionally calls
14
+ * `validateSigningOptions` for the signing-input mutex and canonical
15
+ * issuer URL check.
16
+ */
17
+ import type { ArgvMode, CwdMode, BinaryPathMode, EnvMode, StdinMode, ExitCodeMode, ExecutionMode } from './observation-builder.js';
18
+ /**
19
+ * Stable error codes shared by observe command and record command. The
20
+ * subcommands re-export the relevant subset under their own
21
+ * `OBSERVE_COMMAND_ERROR_CODES` / `RECORD_COMMAND_ERROR_CODES` for
22
+ * call-site clarity; both names point at these strings.
23
+ */
24
+ export declare const COMMAND_OPTION_ERROR_CODES: {
25
+ readonly programRequired: "cli.program_required";
26
+ readonly unsafeFlagRequired: "cli.unsafe_flag_required";
27
+ readonly secretScanDisableRequiresUnsafeFlag: "cli.secret_scan_disable_requires_unsafe_flag";
28
+ readonly shellModeRequired: "cli.shell_mode_required";
29
+ readonly argvTokenTooLong: "cli.argv_token_too_long";
30
+ readonly outOfRange: "cli.out_of_range";
31
+ readonly invalidPolicyDigest: "cli.invalid_policy_digest";
32
+ readonly invalidConfigDigest: "cli.invalid_config_digest";
33
+ readonly invalidApprovalRef: "cli.invalid_approval_ref";
34
+ readonly invalidEnvKey: "cli.invalid_env_key";
35
+ readonly signingInputRequired: "cli.signing_input_required";
36
+ readonly signingInputConflict: "cli.signing_input_conflict";
37
+ readonly issuerIdRequired: "cli.issuer_id_required";
38
+ readonly issuerIdInvalid: "cli.issuer_id_invalid";
39
+ };
40
+ export interface ValidationFailure {
41
+ code: string;
42
+ message: string;
43
+ }
44
+ /** Common option shape both subcommands share (no signing fields). */
45
+ export interface CoreCommandOptions {
46
+ captureMode: ArgvMode;
47
+ unsafeAllowRawCapture: boolean;
48
+ captureStdinMode: StdinMode;
49
+ captureStdoutBytes: number;
50
+ captureStderrBytes: number;
51
+ captureArgvBytes: number;
52
+ envAllow: string[];
53
+ envMode: EnvMode;
54
+ unsafeAllowRawEnv: boolean;
55
+ captureCwdMode: CwdMode;
56
+ captureBinaryPath: BinaryPathMode;
57
+ secretScan: boolean;
58
+ unsafeDisableSecretScan: boolean;
59
+ policyDigest?: string;
60
+ configDigest?: string;
61
+ approvalRef?: string;
62
+ executionMode: ExecutionMode;
63
+ shellMode: boolean;
64
+ timeoutMs: number;
65
+ killGraceMs: number;
66
+ exitCodeMode: ExitCodeMode;
67
+ }
68
+ /** Signing-input shape consumed by record command. */
69
+ export interface SigningOptions {
70
+ issuerKey?: string;
71
+ issuerId?: string;
72
+ unsafeEphemeralKey: boolean;
73
+ }
74
+ /** True iff `n` is a finite, in-range integer (rejects NaN, Infinity, floats). */
75
+ export declare function isValidIntInRange(n: unknown, min: number, max: number): boolean;
76
+ /** UTF-8 byte length of a string. */
77
+ export declare function utf8Bytes(s: string): number;
78
+ /** Platform-agnostic basename -- strips both `/` and `\`. */
79
+ export declare function basenameAny(p: string): string;
80
+ /**
81
+ * Validate flags shared by observe command and record command. Returns
82
+ * an array of failures; empty when the options + child argv are
83
+ * acceptable. Caller surfaces failures to stderr and exits 2 BEFORE
84
+ * spawning the child.
85
+ */
86
+ export declare function validateCoreCommandOptions(opts: CoreCommandOptions, childArgv: string[]): ValidationFailure[];
87
+ /**
88
+ * Validate signing-input flags consumed by record command. Enforces
89
+ * mutex (--issuer-key XOR --unsafe-ephemeral-key), required
90
+ * --issuer-id, and canonical-issuer-URL form. Caller appends these
91
+ * failures to the core failures and exits 2 BEFORE running the child.
92
+ */
93
+ export declare function validateSigningOptions(opts: SigningOptions): ValidationFailure[];
94
+ //# sourceMappingURL=command-option-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-option-validation.d.ts","sourceRoot":"","sources":["../../src/lib/command-option-validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EACV,QAAQ,EACR,OAAO,EACP,cAAc,EACd,OAAO,EACP,SAAS,EACT,YAAY,EACZ,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;CAgB7B,CAAC;AAEX,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,QAAQ,CAAC;IACtB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,SAAS,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,cAAc,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,uBAAuB,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAMD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/E;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,MAAM,EAAE,GAClB,iBAAiB,EAAE,CA6IrB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,EAAE,CA6BhF"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Issuer-key loader for `peac record command`.
3
+ *
4
+ * Implements the same issuer-key reference convention used by other
5
+ * PEAC tools: env:VAR_NAME and file:/path. Keeps the CLI signing UX
6
+ * aligned with the existing PEAC convention without coupling
7
+ * @peac/cli to any other package's loader implementation.
8
+ *
9
+ * Supported schemes:
10
+ * env:VAR_NAME loads JSON from process.env.VAR_NAME (or
11
+ * caller-supplied env)
12
+ * file:/path loads JSON from the file path
13
+ *
14
+ * The value at the resolved location is a JSON-encoded
15
+ * Ed25519PrivateJwk:
16
+ *
17
+ * { "kty": "OKP", "crv": "Ed25519", "x": <b64url>, "d": <b64url>,
18
+ * "kid": "optional" }
19
+ *
20
+ * `kid` is extracted from the JWK if present, otherwise derived from
21
+ * the public key (truncated SHA-256 of the base64url-encoded public
22
+ * key) so runs are reproducible.
23
+ *
24
+ * The loader NEVER logs key bytes; error messages reference field
25
+ * names and structural problems only.
26
+ */
27
+ export declare class IssuerKeyLoadError extends Error {
28
+ readonly cause?: unknown | undefined;
29
+ readonly code = "cli.issuer_key_load_failed";
30
+ constructor(message: string, cause?: unknown | undefined);
31
+ }
32
+ export declare class IssuerKeyInvalidError extends Error {
33
+ readonly cause?: unknown | undefined;
34
+ readonly code = "cli.issuer_key_invalid";
35
+ constructor(message: string, cause?: unknown | undefined);
36
+ }
37
+ export interface LoadedIssuerKey {
38
+ privateKey: Uint8Array;
39
+ publicKey: Uint8Array;
40
+ kid: string;
41
+ }
42
+ /**
43
+ * Load the issuer key from a `--issuer-key` reference.
44
+ *
45
+ * @param schemeUri - One of `env:VAR` or `file:/path`.
46
+ * @param env - Environment to consult for `env:` references.
47
+ * Defaults to `process.env`. Tests inject custom env.
48
+ */
49
+ export declare function loadIssuerKey(schemeUri: string, env?: NodeJS.ProcessEnv): Promise<LoadedIssuerKey>;
50
+ /**
51
+ * Derive a `kid` from a freshly-generated ephemeral public key. Same
52
+ * formula as the loader's fallback so observation records are
53
+ * consistent with the JWK-based path.
54
+ */
55
+ export declare function deriveKidFromPublicKey(publicKey: Uint8Array): Promise<string>;
56
+ //# sourceMappingURL=issuer-key-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuer-key-loader.d.ts","sourceRoot":"","sources":["../../src/lib/issuer-key-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,qBAAa,kBAAmB,SAAQ,KAAK;IAIzC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAH1B,QAAQ,CAAC,IAAI,gCAAgC;gBAE3C,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAI5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO;IAH1B,QAAQ,CAAC,IAAI,4BAA4B;gBAEvC,OAAO,EAAE,MAAM,EACN,KAAK,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,eAAe,CAAC,CAqF1B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAInF"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * CLI observation record builder.
3
+ *
4
+ * Assembles the final `org.peacprotocol/cli-execution` observation
5
+ * record from the raw capture result + the flag-derived capture policy.
6
+ * Applies argv encoding, env filtering (captures only what the policy
7
+ * records; never mutates the child's execution env), cwd / binary-path
8
+ * encoding, and secret-scan suppression on stdout / stderr samples.
9
+ *
10
+ * Builder hard-fail invariants (mirrors of the schema invariants;
11
+ * surface the failure before emission so a flag-layer bug cannot
12
+ * produce a misleading record):
13
+ * - command.program is basename-only; path-bearing tokens are
14
+ * reduced to their basename. Path disclosure is governed by
15
+ * --capture-binary-path and lives only under binary.path_*.
16
+ * - raw argv tokens that exceed argv_max_bytes hard-fail with
17
+ * `cli.argv_token_too_long`; raw mode never silently truncates.
18
+ * - env.mode='raw' with rawEnvEnabled=false hard-fails with
19
+ * `cli.env_mode_inconsistent` rather than silently downgrading
20
+ * to hashed.
21
+ */
22
+ export declare class CliObservationBuilderError extends Error {
23
+ readonly code: string;
24
+ constructor(code: string, message: string);
25
+ }
26
+ import { type CliExecutionObservation } from '@peac/schema';
27
+ import type { CaptureResult } from './capture.js';
28
+ export type ArgvMode = 'hashed' | 'redacted' | 'raw';
29
+ export type CwdMode = 'none' | 'hashed' | 'basename' | 'absolute';
30
+ export type BinaryPathMode = 'none' | 'hashed' | 'absolute';
31
+ export type EnvMode = 'hashed' | 'raw';
32
+ export type StdinMode = 'none' | 'length-only' | 'hashed';
33
+ export type ExitCodeMode = 'child' | 'record';
34
+ export type ExecutionMode = 'deterministic_script' | 'templated_flow' | 'agent_loop' | 'human_step' | 'hybrid';
35
+ export interface BuilderInput {
36
+ capture: CaptureResult;
37
+ /**
38
+ * The program token AS THE USER SUPPLIED IT (e.g. `node`, `./script.sh`,
39
+ * `/usr/bin/env`). This is what `command.program` records -- it does NOT
40
+ * leak the resolved absolute path. Path disclosure is governed
41
+ * exclusively by `--capture-binary-path` (recorded in `binary.path_*`).
42
+ */
43
+ programToken: string;
44
+ /**
45
+ * The resolved absolute path the wrapper actually spawned. Used
46
+ * internally for stat metadata and content digest under
47
+ * `--capture-binary-path hashed|absolute` -- NEVER recorded under
48
+ * `command.program`.
49
+ */
50
+ resolvedProgramPath: string;
51
+ /** Argv tail as supplied (post-`--`); never modified. */
52
+ rawArgv: string[];
53
+ cwd: string;
54
+ argvMode: ArgvMode;
55
+ cwdMode: CwdMode;
56
+ binaryPathMode: BinaryPathMode;
57
+ envMode: EnvMode;
58
+ stdinMode: StdinMode;
59
+ envAllowlist: string[];
60
+ parentEnv: NodeJS.ProcessEnv;
61
+ rawCaptureEnabled: boolean;
62
+ rawEnvEnabled: boolean;
63
+ secretScanEnabled: boolean;
64
+ secretScanDisabledUnsafely: boolean;
65
+ argvCaptureBytes: number;
66
+ stdoutSampleBytes: number;
67
+ stderrSampleBytes: number;
68
+ timeoutMs: number;
69
+ killGraceMs: number;
70
+ exitCodeMode: ExitCodeMode;
71
+ executionMode: ExecutionMode;
72
+ shellMode: boolean;
73
+ policyDigest?: string;
74
+ configDigest?: string;
75
+ approvalRef?: string;
76
+ peacCliVersion: string;
77
+ }
78
+ export declare function buildObservation(input: BuilderInput): Promise<CliExecutionObservation>;
79
+ //# sourceMappingURL=observation-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-builder.d.ts","sourceRoot":"","sources":["../../src/lib/observation-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAcD,OAAO,EAA8B,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAKlD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC;AACrD,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAClE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC5D,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AACvC,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,gBAAgB,GAChB,YAAY,GACZ,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,0BAA0B,EAAE,OAAO,CAAC;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;CACxB;AAoOD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAuG5F"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Shared CLI execution observation pipeline.
3
+ *
4
+ * Both `peac observe command` (unsigned JSON emission) and `peac
5
+ * record command` (Wire 0.2 JWS signing) reuse the same capture +
6
+ * build + validate pipeline so a record produced by one is
7
+ * indistinguishable from a record produced by the other (modulo the
8
+ * outer signing envelope). This module is the single source of truth
9
+ * for that shared behavior.
10
+ *
11
+ * Public surface intentionally narrow:
12
+ * - resolveProgramPath(token, childEnv) -- childEnv-aware PATH lookup
13
+ * - preflightOutputWritable(output) -- writability check before spawn
14
+ * - runObservationCore(opts, ...) -- capture + build + validate
15
+ *
16
+ * The pipeline is an OBSERVER, not a sandbox / permission system /
17
+ * shell orchestrator / process supervisor / job scheduler.
18
+ */
19
+ import { type CliExecutionObservation } from '@peac/schema';
20
+ import { type CaptureResult } from './capture.js';
21
+ import { preflightOutputWritable as neutralPreflightOutputWritable } from './output-preflight.js';
22
+ import { type ArgvMode, type CwdMode, type BinaryPathMode, type EnvMode, type StdinMode, type ExitCodeMode, type ExecutionMode } from './observation-builder.js';
23
+ /** Capture-pipeline options shared by both subcommands. */
24
+ export interface CoreObservationOptions {
25
+ captureMode: ArgvMode;
26
+ unsafeAllowRawCapture: boolean;
27
+ captureStdinMode: StdinMode;
28
+ captureStdoutBytes: number;
29
+ captureStderrBytes: number;
30
+ captureArgvBytes: number;
31
+ envAllow: string[];
32
+ envMode: EnvMode;
33
+ unsafeAllowRawEnv: boolean;
34
+ captureCwdMode: CwdMode;
35
+ captureBinaryPath: BinaryPathMode;
36
+ secretScan: boolean;
37
+ unsafeDisableSecretScan: boolean;
38
+ policyDigest?: string;
39
+ configDigest?: string;
40
+ approvalRef?: string;
41
+ executionMode: ExecutionMode;
42
+ shellMode: boolean;
43
+ timeoutMs: number;
44
+ killGraceMs: number;
45
+ exitCodeMode: ExitCodeMode;
46
+ }
47
+ export interface CoreObservationIO {
48
+ /** Environment passed to the spawned child (what the child RECEIVES). */
49
+ childEnv: NodeJS.ProcessEnv;
50
+ /** Environment inspected by --env-allow for record entries. */
51
+ captureEnv: NodeJS.ProcessEnv;
52
+ cwd: string;
53
+ peacCliVersion: string;
54
+ }
55
+ export type CoreObservationResult = {
56
+ ok: true;
57
+ observation: CliExecutionObservation;
58
+ capture: CaptureResult;
59
+ } | {
60
+ ok: false;
61
+ code: string;
62
+ message: string;
63
+ };
64
+ /**
65
+ * Resolve a program token to its absolute path. Resolution honors the
66
+ * supplied `childEnv` ONLY (the environment that will be passed to
67
+ * spawn). The ambient `process.env` is not consulted: callers must
68
+ * pass `childEnv` explicitly so the execution-environment source is
69
+ * auditable at the call site. When no executable is found in
70
+ * `childEnv.PATH`, returns the token unchanged so spawn surfaces a
71
+ * clear ENOENT error.
72
+ */
73
+ export declare function resolveProgramPath(token: string, childEnv: NodeJS.ProcessEnv): string;
74
+ /**
75
+ * Re-export of the neutral output-path preflight from
76
+ * `lib/output-preflight.ts`. Kept here so PR 2 callers
77
+ * (`observe command`, `record command`) and any future callers that
78
+ * already import this name from this module continue to work.
79
+ */
80
+ export declare const preflightOutputWritable: typeof neutralPreflightOutputWritable;
81
+ /**
82
+ * Run the shared capture + build + validate pipeline.
83
+ *
84
+ * Returns `{ ok: true, observation, capture }` when all stages succeed
85
+ * (observation is the schema-validated record; capture carries the
86
+ * child's exit info for downstream exit-code-mode handling).
87
+ * Returns `{ ok: false, code, message }` for any structured failure.
88
+ *
89
+ * Stages:
90
+ * 1. resolveProgramPath(programToken, childEnv)
91
+ * 2. captureCommand(...) (raises CliSpawnFailedError)
92
+ * 3. buildObservation(...) (raises CliObservationBuilderError)
93
+ * 4. CliExecutionSchema.safeParse(observation)
94
+ */
95
+ export declare function runObservationCore(opts: CoreObservationOptions, programToken: string, args: string[], io: CoreObservationIO): Promise<CoreObservationResult>;
96
+ //# sourceMappingURL=observation-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/observation-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,uBAAuB,IAAI,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAClG,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,0BAA0B,CAAC;AAElC,2DAA2D;AAC3D,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,QAAQ,CAAC;IACtB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,SAAS,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,cAAc,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,uBAAuB,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;IAC5B,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GAC1E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAuBrF;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,uCAAiC,CAAC;AAEtE;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,EAC5B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,qBAAqB,CAAC,CAkFhC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Race-free output-path writability preflight (neutral, surface-agnostic).
3
+ *
4
+ * Used by every CLI surface that supports `--output <file>` to verify the
5
+ * target path is writable BEFORE doing any side-effecting work (spawning a
6
+ * child process, loading an issuer key, signing, etc.). A record-producing
7
+ * wrapper must never do that work only to discover the record cannot be
8
+ * persisted.
9
+ *
10
+ * The preflight is deliberately non-invasive on the final target path:
11
+ * - if the final target exists, open it for append/write check and
12
+ * close it; never unlink the existing target
13
+ * - if the final target does NOT exist, create a uniquely-named
14
+ * sibling temp file in the parent directory with O_EXCL and
15
+ * immediately unlink that temp file; the final target path is
16
+ * not created or touched until the actual write step
17
+ *
18
+ * Result: between preflight and the eventual write, the CLI has NOT
19
+ * created or modified the final output path. Concurrent observers cannot
20
+ * race against a transient zero-byte target file produced by the preflight.
21
+ */
22
+ /**
23
+ * Verify that `--output <file>` will be writable. Returns null on
24
+ * success; otherwise an error message suitable for pairing with
25
+ * `cli.output_write_failed`.
26
+ */
27
+ export declare function preflightOutputWritable(output: string): string | null;
28
+ //# sourceMappingURL=output-preflight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-preflight.d.ts","sourceRoot":"","sources":["../../src/lib/output-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiErE"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Secret-scan regex set for bounded-capture samples.
3
+ *
4
+ * Secret-scan is ON by default. When raw sample emission is possible
5
+ * (`--capture-mode raw && --unsafe-allow-raw-capture`), the wrapper
6
+ * runs this regex set against each candidate sample BEFORE emission.
7
+ * If a token-like pattern matches, the sample is suppressed and
8
+ * replaced with `{ sample_suppressed_reason: "secret_pattern_detected",
9
+ * matched_pattern_category: <category> }`. The literal match is NEVER
10
+ * recorded.
11
+ *
12
+ * The regex set is intentionally small (5 named patterns). False
13
+ * positives are tolerated; the suppression itself is observable so a
14
+ * verifier can detect over-suppression.
15
+ *
16
+ * Disabling secret-scan under raw capture requires the third unsafe
17
+ * flag (`--unsafe-disable-secret-scan`); enforcement lives in the
18
+ * subcommand flag-parse layer, not here.
19
+ */
20
+ export type SecretCategory = 'bearer-token' | 'api-key' | 'jwt' | 'aws-access-key' | 'generic-high-entropy';
21
+ export interface SecretMatch {
22
+ category: SecretCategory;
23
+ }
24
+ /**
25
+ * Scan a buffer or string for token-like patterns. Returns the first
26
+ * match (by pattern declaration order); the literal match is NEVER
27
+ * returned to callers.
28
+ */
29
+ export declare function scanForSecrets(input: string | Uint8Array): SecretMatch | null;
30
+ /**
31
+ * Scan an argv element. Same shape as `scanForSecrets` but documents
32
+ * intent: argv elements are scanned independently of stream samples.
33
+ */
34
+ export declare function scanArgvElement(token: string): SecretMatch | null;
35
+ //# sourceMappingURL=secret-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-scan.d.ts","sourceRoot":"","sources":["../../src/lib/secret-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,SAAS,GACT,KAAK,GACL,gBAAgB,GAChB,sBAAsB,CAAC;AA0C3B,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,CAQ7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAEjE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peac/cli",
3
- "version": "0.13.4",
3
+ "version": "0.14.1",
4
4
  "description": "PEAC protocol command-line tools",
5
5
  "main": "dist/index.cjs",
6
6
  "types": "dist/index.d.ts",
@@ -38,13 +38,13 @@
38
38
  "dependencies": {
39
39
  "chalk": "^4.1.2",
40
40
  "commander": "^11.0.0",
41
- "@peac/kernel": "0.13.4",
42
- "@peac/audit": "0.13.4",
43
- "@peac/net-node": "0.13.4",
44
- "@peac/crypto": "0.13.4",
45
- "@peac/policy-kit": "0.13.4",
46
- "@peac/schema": "0.13.4",
47
- "@peac/protocol": "0.13.4"
41
+ "@peac/audit": "0.14.1",
42
+ "@peac/kernel": "0.14.1",
43
+ "@peac/net-node": "0.14.1",
44
+ "@peac/crypto": "0.14.1",
45
+ "@peac/policy-kit": "0.14.1",
46
+ "@peac/protocol": "0.14.1",
47
+ "@peac/schema": "0.14.1"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^22.19.11",