Skip to content

feat(js): add customBuiltins to Bash and BashTool #1646

@mayneyao

Description

@mayneyao

Python has Bash(custom_builtins={...}) from #1315 but the JS bindings
(@everruns/bashkit) were missing this feature.

What was missing

  • Bash has persistent VFS across execute() calls but no way to
    register JS callbacks as persistent builtins
  • ScriptedTool.addTool() has callbacks but VFS is ephemeral per call
  • The issue described JS bindings already have this via Bash.defineCommand()
    but in reality defineCommand never existed

What was implemented

  • BashOptions.customBuiltins: Record<string, BuiltinCallback> — constructor-time
  • Bash.addBuiltin(name, callback) — post-construction
  • BashTool equivalent support
  • BuiltinContext with name, argv, stdin, env, cwd
  • 10 tests covering pipes, VFS persistence, reset survival, pipelines
import { Bash } from '@everruns/bashkit';

// Needed API that was missing
const bash = new Bash({
  customBuiltins: {
    'get-order': (ctx) =>
      JSON.stringify({ id: ctx.argv[0], status: 'shipped' }) + '\n',
  },
});

await bash.execute('mkdir -p /scratch');
await bash.execute('get-order 42 > /scratch/order.json');     // → VFS
const result = await bash.execute('cat /scratch/order.json');  // persists across calls

Notes

  • executeSync() deadlocks with custom builtins (same limitation as
    ScriptedTool). Use execute() (async).
  • Custom builtins survive reset() but are host-side config — pass
    customBuiltins again on snapshot restore.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions