just-bash 2.9.8 → 2.10.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.
package/README.md CHANGED
@@ -26,6 +26,7 @@ Supports optional network access via `curl` with secure-by-default URL filtering
26
26
  - [Default Layout](#default-layout)
27
27
  - [Network Access](#network-access)
28
28
  - [Execution Protection](#execution-protection)
29
+ - [AST Transform Plugins](#ast-transform-plugins)
29
30
  - [Development](#development)
30
31
 
31
32
  ## Security model
@@ -73,6 +74,22 @@ const env = new Bash({
73
74
  await env.exec("echo $TEMP", { env: { TEMP: "value" }, cwd: "/tmp" });
74
75
  ```
75
76
 
77
+ #### Lazy Files
78
+
79
+ File values can be functions (sync or async). The function is called on first read and the result is cached — if the file is written to before being read, the function is never called:
80
+
81
+ ```typescript
82
+ const env = new Bash({
83
+ files: {
84
+ "/data/config.json": () => JSON.stringify({ key: "value" }),
85
+ "/data/remote.txt": async () => (await fetch("https://example.com")).text(),
86
+ "/data/static.txt": "always loaded",
87
+ },
88
+ });
89
+ ```
90
+
91
+ This is useful for large or expensive-to-compute content that may not be needed.
92
+
76
93
  ### Custom Commands
77
94
 
78
95
  Extend just-bash with your own TypeScript commands using `defineCommand`:
@@ -435,6 +452,30 @@ const env = new Bash({
435
452
 
436
453
  All limits have sensible defaults. Error messages include hints on which limit to increase. Feel free to increase if your scripts intentionally go beyond them.
437
454
 
455
+ ## AST Transform Plugins
456
+
457
+ Parse bash scripts into an AST, run transform plugins, and serialize back to executable bash. Useful for instrumenting scripts (e.g., capturing per-command stdout/stderr) or analyzing them (e.g., extracting command names) before execution.
458
+
459
+ ```typescript
460
+ import { Bash, BashTransformPipeline, TeePlugin, CommandCollectorPlugin } from "just-bash";
461
+
462
+ // Standalone pipeline — output can be run by any shell
463
+ const pipeline = new BashTransformPipeline()
464
+ .use(new TeePlugin({ outputDir: "/tmp/logs" }))
465
+ .use(new CommandCollectorPlugin());
466
+ const result = pipeline.transform("echo hello | grep hello");
467
+ result.script; // transformed bash string
468
+ result.metadata.commands; // ["echo", "grep", "tee"]
469
+
470
+ // Integrated API — exec() auto-applies transforms and returns metadata
471
+ const bash = new Bash();
472
+ bash.registerTransformPlugin(new CommandCollectorPlugin());
473
+ const execResult = await bash.exec("echo hello | grep hello");
474
+ execResult.metadata?.commands; // ["echo", "grep"]
475
+ ```
476
+
477
+ See [src/transform/README.md](src/transform/README.md) for the full API, built-in plugins, and how to write custom plugins.
478
+
438
479
  ## Development
439
480
 
440
481
  ```bash
package/dist/Bash.d.ts CHANGED
@@ -13,6 +13,7 @@ import type { IFileSystem, InitialFiles } from "./fs/interface.js";
13
13
  import { type ExecutionLimits } from "./limits.js";
14
14
  import { type NetworkConfig } from "./network/index.js";
15
15
  import type { DefenseInDepthConfig } from "./security/types.js";
16
+ import type { BashTransformResult, TransformPlugin } from "./transform/types.js";
16
17
  import type { BashExecResult, Command, FeatureCoverageWriter, TraceCallback } from "./types.js";
17
18
  export type { ExecutionLimits } from "./limits.js";
18
19
  /**
@@ -167,6 +168,7 @@ export declare class Bash {
167
168
  private logger?;
168
169
  private defenseInDepthConfig?;
169
170
  private coverageWriter?;
171
+ private transformPlugins;
170
172
  private state;
171
173
  constructor(options?: BashOptions);
172
174
  registerCommand(command: Command): void;
@@ -176,4 +178,6 @@ export declare class Bash {
176
178
  writeFile(path: string, content: string): Promise<void>;
177
179
  getCwd(): string;
178
180
  getEnv(): Record<string, string>;
181
+ registerTransformPlugin(plugin: TransformPlugin<any>): void;
182
+ transform(commandLine: string): BashTransformResult;
179
183
  }