poe-code 14.0.20 → 14.0.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-code",
3
- "version": "14.0.20",
3
+ "version": "14.0.21",
4
4
  "description": "CLI tool to configure Poe API for developer workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -219,10 +219,6 @@
219
219
  "browser": null,
220
220
  "import": "./packages/safe-js/dist/cli.js"
221
221
  },
222
- "./safe-bash-mcp": {
223
- "types": "./packages/safe-bash-mcp/dist/index.d.ts",
224
- "import": "./packages/safe-bash-mcp/dist/index.js"
225
- },
226
222
  "./safe-bash/browser": {
227
223
  "types": "./packages/safe-bash/dist/browser.d.ts",
228
224
  "import": "./packages/safe-bash/dist/browser.js"
@@ -312,8 +308,7 @@
312
308
  "poe-agent": "dist/bin/poe-agent.js",
313
309
  "poe-superintendent-mcp": "packages/superintendent/dist/mcp.js",
314
310
  "poe-safejs": "packages/safe-js/dist/cli.js",
315
- "poe-safe-js": "packages/safe-js/dist/cli.js",
316
- "poe-safe-bash-mcp": "packages/safe-bash-mcp/dist/cli.js"
311
+ "poe-safe-js": "packages/safe-js/dist/cli.js"
317
312
  },
318
313
  "files": [
319
314
  "LICENSE",
@@ -385,8 +380,7 @@
385
380
  "packages/toolcraft-schema/dist",
386
381
  "packages/workspace-resolver/dist",
387
382
  "packages/worktree/dist",
388
- "packages/safe-fs/dist/**/*.d.ts",
389
- "packages/safe-bash-mcp/dist"
383
+ "packages/safe-fs/dist/**/*.d.ts"
390
384
  ],
391
385
  "engines": {
392
386
  "node": ">=18.18"
@@ -515,7 +509,6 @@
515
509
  "@poe-code/safe-js": "*",
516
510
  "virtual-bash": "*",
517
511
  "poe-code": "file:.",
518
- "safe-bash-mcp": "*",
519
512
  "safe-bash-playground": "*",
520
513
  "buffer": "6.0.3"
521
514
  },
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
- import { resolve } from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import { parseArgs } from "node:util";
5
- import { createSafeBashMcpServer } from "./index.js";
6
- const { values } = parseArgs({
7
- options: { config: { type: "string" } },
8
- strict: true,
9
- allowPositionals: false
10
- });
11
- const options = values.config === undefined
12
- ? {}
13
- : (await import(pathToFileURL(resolve(values.config)).href)).default;
14
- if (options === undefined) {
15
- throw new TypeError("The config module must default-export SafeBashMcpOptions");
16
- }
17
- const server = createSafeBashMcpServer(options);
18
- try {
19
- await server.listen();
20
- }
21
- finally {
22
- await server.close();
23
- }
@@ -1,21 +0,0 @@
1
- import { Shell, type ShellOptions } from "poe-code/safe-bash";
2
- import { type Server } from "../../tiny-stdio-mcp-server/dist/index.js";
3
- export interface SafeBashMcpOptions extends Partial<ShellOptions> {
4
- readonly createShell?: (options: ShellOptions) => Shell;
5
- }
6
- export interface ShellExecuteInput {
7
- readonly command: string;
8
- readonly cwd?: string;
9
- readonly env?: Record<string, string>;
10
- readonly stdin?: string;
11
- }
12
- export interface ShellExecuteOutput {
13
- readonly stdout: string;
14
- readonly stderr: string;
15
- readonly exitCode: number;
16
- }
17
- export type SafeBashMcpServer = Server & {
18
- readonly shell: Shell;
19
- close(): Promise<void>;
20
- };
21
- export declare function createSafeBashMcpServer(options?: SafeBashMcpOptions): SafeBashMcpServer;
@@ -1,141 +0,0 @@
1
- import { createMemoryFileSystem } from "poe-code/safe-fs";
2
- import { CommandRegistry, Shell, createStandardCommands } from "poe-code/safe-bash";
3
- import { createServer } from "tiny-stdio-mcp-server";
4
- const inputSchema = {
5
- type: "object",
6
- properties: {
7
- command: { type: "string", minLength: 1, description: "Bash source interpreted by safe-bash, never a host shell" },
8
- cwd: { type: "string", description: "Working directory in the configured virtual filesystem for this call" },
9
- env: { type: "object", additionalProperties: { type: "string" }, description: "Environment overrides for this call" },
10
- stdin: { type: "string", description: "Standard input for this call" }
11
- },
12
- required: ["command"],
13
- additionalProperties: false
14
- };
15
- const outputSchema = {
16
- type: "object",
17
- properties: {
18
- stdout: { type: "string" },
19
- stderr: { type: "string" },
20
- exitCode: { type: "integer" }
21
- },
22
- required: ["stdout", "stderr", "exitCode"],
23
- additionalProperties: false
24
- };
25
- export function createSafeBashMcpServer(options = {}) {
26
- if (options === null || typeof options !== "object" || Array.isArray(options)) {
27
- throw new TypeError("Safe-bash MCP options must be an object");
28
- }
29
- const { createShell, ...shellOptions } = options;
30
- const resolvedOptions = {
31
- ...shellOptions,
32
- fs: options.fs ?? createMemoryFileSystem(),
33
- commands: options.commands ?? new CommandRegistry(createStandardCommands())
34
- };
35
- const shell = createShell ? createShell(resolvedOptions) : new Shell(resolvedOptions);
36
- const lifetime = new AbortController();
37
- let closing;
38
- const close = () => {
39
- if (closing === undefined) {
40
- closing = shell.dispose();
41
- lifetime.abort();
42
- }
43
- return closing;
44
- };
45
- let pending = Promise.resolve();
46
- const server = createServer({ name: "safe-bash-mcp", version: "0.1.0" });
47
- server.tool("shell_execute", "Execute Bash in a shared virtual filesystem. Calls run in order; cwd and environment changes do not persist across calls.", inputSchema, async ({ command, ...execOptions }) => {
48
- const execution = pending.then(() => {
49
- if (lifetime.signal.aborted)
50
- throw new Error("Safe-bash MCP server is closed");
51
- return shell.exec(command, execOptions);
52
- });
53
- pending = execution.then(() => undefined, () => undefined);
54
- const { stdout, stderr, exitCode } = await execution;
55
- const output = { stdout, stderr, exitCode };
56
- return {
57
- content: [{ type: "text", text: JSON.stringify(output) }],
58
- structuredContent: output,
59
- isError: exitCode !== 0
60
- };
61
- }, outputSchema);
62
- const connect = server.connect;
63
- return Object.assign(server, {
64
- shell,
65
- close,
66
- async connect(transport) {
67
- const readable = new PassThrough();
68
- let stopped = false;
69
- let failure;
70
- const stop = () => {
71
- if (stopped)
72
- return;
73
- stopped = true;
74
- void close().catch(() => undefined);
75
- transport.readable.unpipe(readable);
76
- readable.end();
77
- };
78
- const fail = (error) => {
79
- failure ??= error;
80
- stop();
81
- };
82
- const writable = new Writable({
83
- write(chunk, encoding, callback) {
84
- if (!stopped) {
85
- try {
86
- transport.writable.write(chunk, encoding);
87
- }
88
- catch (error) {
89
- fail(error);
90
- }
91
- }
92
- callback();
93
- }
94
- });
95
- const connection = connect({ readable, writable });
96
- transport.readable.once("end", stop);
97
- transport.readable.once("close", stop);
98
- transport.readable.on("error", fail);
99
- transport.writable.once("close", stop);
100
- transport.writable.on("error", fail);
101
- lifetime.signal.addEventListener("abort", stop, { once: true });
102
- try {
103
- if (lifetime.signal.aborted ||
104
- transport.readable.readableEnded ||
105
- transport.readable.destroyed ||
106
- transport.writable.destroyed) {
107
- stop();
108
- }
109
- else {
110
- transport.readable.pipe(readable);
111
- }
112
- await connection;
113
- }
114
- catch (error) {
115
- failure ??= error;
116
- }
117
- finally {
118
- stop();
119
- transport.readable.removeListener("end", stop);
120
- transport.readable.removeListener("close", stop);
121
- transport.readable.removeListener("error", fail);
122
- transport.writable.removeListener("close", stop);
123
- transport.writable.removeListener("error", fail);
124
- lifetime.signal.removeEventListener("abort", stop);
125
- readable.destroy();
126
- writable.destroy();
127
- }
128
- try {
129
- await close();
130
- }
131
- catch (error) {
132
- if (failure !== undefined)
133
- throw new AggregateError([failure, error], "MCP transport and shell cleanup failed");
134
- throw error;
135
- }
136
- if (failure !== undefined)
137
- throw failure;
138
- }
139
- });
140
- }
141
- import { PassThrough, Writable } from "node:stream";