terminal-commands 0.1.1 → 0.1.3

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
@@ -18,6 +18,11 @@ approval prompts are enabled.
18
18
 
19
19
  Command-line programs still execute with your operating-system user permissions. A program can access more than the dedicated filesystem tools, so review every command approval carefully.
20
20
 
21
+ The MCP command surface exposes process lifecycle operations separately: `start_process` starts
22
+ an approved executable and returns a session ID, `read_process_output` reads bounded output,
23
+ `list_processes` lists sessions, and `terminate_process` stops a session. This keeps terminal
24
+ workflows available while making each model-callable operation explicit.
25
+
21
26
  ## Run
22
27
 
23
28
  ```bash
package/dist/agent.js CHANGED
@@ -11894,7 +11894,7 @@ function attachSchema(issues, start, inst) {
11894
11894
  (_a3 = issues[i]).schema ?? (_a3.schema = inst);
11895
11895
  }
11896
11896
  }
11897
- function finalizeIssue(iss, ctx, config2) {
11897
+ function finalizeIssue(iss, ctx, config3) {
11898
11898
  var _a3;
11899
11899
  const traits = iss.inst?._zod?.traits;
11900
11900
  if (traits?.has("$ZodType")) {
@@ -11904,7 +11904,7 @@ function finalizeIssue(iss, ctx, config2) {
11904
11904
  iss.schema = iss.inst;
11905
11905
  }
11906
11906
  const schemaError = iss.schema !== iss.inst ? iss.schema?._zod.def?.error : void 0;
11907
- const message = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(schemaError?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config2.customError?.(iss)) ?? unwrapMessage(config2.localeError?.(iss)) ?? "Invalid input";
11907
+ const message = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(schemaError?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config3.customError?.(iss)) ?? unwrapMessage(config3.localeError?.(iss)) ?? "Invalid input";
11908
11908
  const full = {};
11909
11909
  for (const k of Object.keys(iss)) {
11910
11910
  if (k === "inst" || k === "schema" || k === "continue" || k === "input" || k === "__proto__")
@@ -33537,21 +33537,21 @@ var Client = class extends Protocol {
33537
33537
  * Handlers are silently skipped if the server doesn't advertise the corresponding listChanged capability.
33538
33538
  * @internal
33539
33539
  */
33540
- _setupListChangedHandlers(config2) {
33541
- if (config2.tools && this._serverCapabilities?.tools?.listChanged) {
33542
- this._setupListChangedHandler("tools", ToolListChangedNotificationSchema, config2.tools, async () => {
33540
+ _setupListChangedHandlers(config3) {
33541
+ if (config3.tools && this._serverCapabilities?.tools?.listChanged) {
33542
+ this._setupListChangedHandler("tools", ToolListChangedNotificationSchema, config3.tools, async () => {
33543
33543
  const result = await this.listTools();
33544
33544
  return result.tools;
33545
33545
  });
33546
33546
  }
33547
- if (config2.prompts && this._serverCapabilities?.prompts?.listChanged) {
33548
- this._setupListChangedHandler("prompts", PromptListChangedNotificationSchema, config2.prompts, async () => {
33547
+ if (config3.prompts && this._serverCapabilities?.prompts?.listChanged) {
33548
+ this._setupListChangedHandler("prompts", PromptListChangedNotificationSchema, config3.prompts, async () => {
33549
33549
  const result = await this.listPrompts();
33550
33550
  return result.prompts;
33551
33551
  });
33552
33552
  }
33553
- if (config2.resources && this._serverCapabilities?.resources?.listChanged) {
33554
- this._setupListChangedHandler("resources", ResourceListChangedNotificationSchema, config2.resources, async () => {
33553
+ if (config3.resources && this._serverCapabilities?.resources?.listChanged) {
33554
+ this._setupListChangedHandler("resources", ResourceListChangedNotificationSchema, config3.resources, async () => {
33555
33555
  const result = await this.listResources();
33556
33556
  return result.resources;
33557
33557
  });
@@ -34881,12 +34881,12 @@ var CR = 13;
34881
34881
  var SPACE = 32;
34882
34882
  function noop(_arg) {
34883
34883
  }
34884
- function createParser(config2) {
34885
- if (typeof config2 == "function")
34884
+ function createParser(config3) {
34885
+ if (typeof config3 == "function")
34886
34886
  throw new TypeError(
34887
34887
  "`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?"
34888
34888
  );
34889
- const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config2, pendingFragments = [];
34889
+ const { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config3, pendingFragments = [];
34890
34890
  let pendingFragmentsLength = 0, isFirstChunk = true, id, data = "", dataLines = 0, eventType, terminated = false;
34891
34891
  function feed(chunk) {
34892
34892
  if (terminated)
@@ -35480,7 +35480,11 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
35480
35480
  var wrapper_default = import_websocket.default;
35481
35481
 
35482
35482
  // src/agent-core.ts
35483
- var destructiveTools = /* @__PURE__ */ new Set(["run_program", "write_text_file"]);
35483
+ var destructiveTools = /* @__PURE__ */ new Set([
35484
+ "start_process",
35485
+ "terminate_process",
35486
+ "write_text_file"
35487
+ ]);
35484
35488
  var requestSchema = external_exports.object({
35485
35489
  type: external_exports.literal("request"),
35486
35490
  requestId: external_exports.string().uuid(),
@@ -35488,7 +35492,10 @@ var requestSchema = external_exports.object({
35488
35492
  "get_system_info",
35489
35493
  "list_directory",
35490
35494
  "read_text_file",
35491
- "run_program",
35495
+ "start_process",
35496
+ "read_process_output",
35497
+ "terminate_process",
35498
+ "list_processes",
35492
35499
  "write_text_file"
35493
35500
  ]),
35494
35501
  arguments: external_exports.record(external_exports.string(), external_exports.unknown())
@@ -35505,18 +35512,18 @@ async function authorizeToolCall(tool, args, allowDestructive, approve) {
35505
35512
  }
35506
35513
  }
35507
35514
  async function connectOnce(options) {
35508
- const { config: config2, signal } = options;
35515
+ const { config: config3, signal } = options;
35509
35516
  const client = new Client({
35510
35517
  name: "terminal-commands-cli",
35511
35518
  version: "0.1.0"
35512
35519
  });
35513
35520
  await client.connect(
35514
35521
  new StreamableHTTPClientTransport(
35515
- new URL(config2.MACHINE_TERMINAL_LOCAL_MCP_URL)
35522
+ new URL(config3.MACHINE_TERMINAL_LOCAL_MCP_URL)
35516
35523
  )
35517
35524
  );
35518
- const token = options.getToken ? await options.getToken() : config2.MACHINE_TERMINAL_DEVICE_TOKEN;
35519
- const socket = new wrapper_default(config2.MACHINE_TERMINAL_GATEWAY_URL, {
35525
+ const token = options.getToken ? await options.getToken() : config3.MACHINE_TERMINAL_DEVICE_TOKEN;
35526
+ const socket = new wrapper_default(config3.MACHINE_TERMINAL_GATEWAY_URL, {
35520
35527
  headers: { Authorization: `Bearer ${token}` }
35521
35528
  });
35522
35529
  const stop2 = () => socket.close(1e3, "Client stopping.");
@@ -35525,8 +35532,8 @@ async function connectOnce(options) {
35525
35532
  socket.send(
35526
35533
  JSON.stringify({
35527
35534
  type: "hello",
35528
- deviceId: config2.MACHINE_TERMINAL_DEVICE_ID,
35529
- name: config2.MACHINE_TERMINAL_DEVICE_NAME,
35535
+ deviceId: config3.MACHINE_TERMINAL_DEVICE_ID,
35536
+ name: config3.MACHINE_TERMINAL_DEVICE_NAME,
35530
35537
  platform: `${os.platform()}-${os.arch()}`
35531
35538
  })
35532
35539
  );
@@ -35618,11 +35625,12 @@ var schema = external_exports.object({
35618
35625
  MACHINE_TERMINAL_DEVICE_ID: external_exports.string().min(1).max(128),
35619
35626
  MACHINE_TERMINAL_DEVICE_NAME: external_exports.string().min(1).max(128).default(os2.hostname()),
35620
35627
  MACHINE_TERMINAL_LOCAL_MCP_URL: external_exports.string().url().default("http://127.0.0.1:3333/mcp"),
35621
- MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: external_exports.enum(["0", "1"]).default("0")
35628
+ MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: external_exports.enum(["0", "1"]).default("0"),
35629
+ MACHINE_TERMINAL_AUTO_APPROVE: external_exports.enum(["0", "1"]).default("0")
35622
35630
  });
35623
35631
  function loadAgentConfig(environment = process.env) {
35624
- const config2 = schema.parse(environment);
35625
- const gateway = new URL(config2.MACHINE_TERMINAL_GATEWAY_URL);
35632
+ const config3 = schema.parse(environment);
35633
+ const gateway = new URL(config3.MACHINE_TERMINAL_GATEWAY_URL);
35626
35634
  if (!(/* @__PURE__ */ new Set(["wss:", "ws:"])).has(gateway.protocol)) {
35627
35635
  throw new Error("MACHINE_TERMINAL_GATEWAY_URL must use wss:// or ws://.");
35628
35636
  }
@@ -35631,7 +35639,87 @@ function loadAgentConfig(environment = process.env) {
35631
35639
  "Unencrypted ws:// is allowed only for loopback development."
35632
35640
  );
35633
35641
  }
35634
- return config2;
35642
+ return {
35643
+ ...config3,
35644
+ MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: config3.MACHINE_TERMINAL_AUTO_APPROVE === "1" ? "1" : config3.MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE
35645
+ };
35646
+ }
35647
+
35648
+ // src/approval.ts
35649
+ import { createInterface } from "node:readline/promises";
35650
+
35651
+ // src/cli-format.ts
35652
+ var isColorEnabled = Boolean(process.stdout.isTTY) && process.env.NO_COLOR === void 0 && process.env.TERM !== "dumb";
35653
+ var CODES = {
35654
+ reset: "\x1B[0m",
35655
+ bold: "\x1B[1m",
35656
+ dim: "\x1B[2m",
35657
+ red: "\x1B[31m",
35658
+ green: "\x1B[32m",
35659
+ yellow: "\x1B[33m",
35660
+ blue: "\x1B[34m",
35661
+ cyan: "\x1B[36m",
35662
+ gray: "\x1B[90m"
35663
+ };
35664
+ function paint(code, text) {
35665
+ if (!isColorEnabled) return text;
35666
+ return `${CODES[code]}${text}${CODES.reset}`;
35667
+ }
35668
+ var bold = (text) => paint("bold", text);
35669
+ var dim = (text) => paint("dim", text);
35670
+ var warn = (text) => paint("yellow", text);
35671
+
35672
+ // src/approval.ts
35673
+ function approvalSummary(tool, args) {
35674
+ if (tool === "write_text_file") {
35675
+ const bytes = Buffer.byteLength(String(args.contents ?? ""));
35676
+ return `Write ${bytes} bytes to ${String(args.path ?? "an unknown path")}${args.overwrite ? " (overwrite)" : ""}`;
35677
+ }
35678
+ if (tool === "start_process") {
35679
+ const command = [
35680
+ String(args.program ?? ""),
35681
+ ...Array.isArray(args.args) ? args.args.map(String) : []
35682
+ ];
35683
+ return `Start: ${command.join(" ")}`;
35684
+ }
35685
+ if (tool === "terminate_process") {
35686
+ return `Terminate process session ${String(args.sessionId ?? "")}`;
35687
+ }
35688
+ return `Run destructive tool: ${tool}`;
35689
+ }
35690
+ function createAutoApprover() {
35691
+ return (tool, args) => {
35692
+ console.log(
35693
+ `
35694
+ ${warn("Approval requested:")} ${approvalSummary(tool, args)} ${dim("(auto-approved)")}`
35695
+ );
35696
+ return Promise.resolve(true);
35697
+ };
35698
+ }
35699
+ function createTerminalApprover() {
35700
+ let queue = Promise.resolve(false);
35701
+ return (tool, args) => {
35702
+ queue = queue.catch(() => false).then(async () => {
35703
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
35704
+ const prompt = createInterface({
35705
+ input: process.stdin,
35706
+ output: process.stdout
35707
+ });
35708
+ try {
35709
+ console.log(
35710
+ `
35711
+ ${warn("Approval requested:")} ${approvalSummary(tool, args)}`
35712
+ );
35713
+ const answer = await prompt.question(
35714
+ `${bold("Approve this action?")} [y/N] `
35715
+ );
35716
+ return (/* @__PURE__ */ new Set(["y", "yes"])).has(answer.trim().toLowerCase());
35717
+ } finally {
35718
+ prompt.close();
35719
+ }
35720
+ });
35721
+ return queue;
35722
+ };
35635
35723
  }
35636
35724
 
35637
35725
  // src/agent.ts
@@ -35639,8 +35727,10 @@ var controller = new AbortController();
35639
35727
  var stop = () => controller.abort();
35640
35728
  process.on("SIGINT", stop);
35641
35729
  process.on("SIGTERM", stop);
35730
+ var config2 = loadAgentConfig();
35642
35731
  void runAgent({
35643
- config: loadAgentConfig(),
35732
+ config: config2,
35733
+ approve: config2.MACHINE_TERMINAL_AUTO_APPROVE === "1" ? createAutoApprover() : createTerminalApprover(),
35644
35734
  signal: controller.signal,
35645
35735
  log: (message) => console.error(`Terminal Commands: ${message}`)
35646
35736
  }).catch((error62) => {
package/dist/cli.js CHANGED
@@ -10984,7 +10984,6 @@ import { spawn } from "node:child_process";
10984
10984
  import { fileURLToPath } from "node:url";
10985
10985
  import os5 from "node:os";
10986
10986
  import path3 from "node:path";
10987
- import { createInterface } from "node:readline/promises";
10988
10987
 
10989
10988
  // src/agent-core.ts
10990
10989
  import os from "node:os";
@@ -35488,7 +35487,11 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
35488
35487
  var wrapper_default = import_websocket.default;
35489
35488
 
35490
35489
  // src/agent-core.ts
35491
- var destructiveTools = /* @__PURE__ */ new Set(["run_program", "write_text_file"]);
35490
+ var destructiveTools = /* @__PURE__ */ new Set([
35491
+ "start_process",
35492
+ "terminate_process",
35493
+ "write_text_file"
35494
+ ]);
35492
35495
  var requestSchema = external_exports.object({
35493
35496
  type: external_exports.literal("request"),
35494
35497
  requestId: external_exports.string().uuid(),
@@ -35496,7 +35499,10 @@ var requestSchema = external_exports.object({
35496
35499
  "get_system_info",
35497
35500
  "list_directory",
35498
35501
  "read_text_file",
35499
- "run_program",
35502
+ "start_process",
35503
+ "read_process_output",
35504
+ "terminate_process",
35505
+ "list_processes",
35500
35506
  "write_text_file"
35501
35507
  ]),
35502
35508
  arguments: external_exports.record(external_exports.string(), external_exports.unknown())
@@ -35626,7 +35632,8 @@ var schema = external_exports.object({
35626
35632
  MACHINE_TERMINAL_DEVICE_ID: external_exports.string().min(1).max(128),
35627
35633
  MACHINE_TERMINAL_DEVICE_NAME: external_exports.string().min(1).max(128).default(os2.hostname()),
35628
35634
  MACHINE_TERMINAL_LOCAL_MCP_URL: external_exports.string().url().default("http://127.0.0.1:3333/mcp"),
35629
- MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: external_exports.enum(["0", "1"]).default("0")
35635
+ MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: external_exports.enum(["0", "1"]).default("0"),
35636
+ MACHINE_TERMINAL_AUTO_APPROVE: external_exports.enum(["0", "1"]).default("0")
35630
35637
  });
35631
35638
  function loadAgentConfig(environment = process.env) {
35632
35639
  const config2 = schema.parse(environment);
@@ -35639,7 +35646,103 @@ function loadAgentConfig(environment = process.env) {
35639
35646
  "Unencrypted ws:// is allowed only for loopback development."
35640
35647
  );
35641
35648
  }
35642
- return config2;
35649
+ return {
35650
+ ...config2,
35651
+ MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE: config2.MACHINE_TERMINAL_AUTO_APPROVE === "1" ? "1" : config2.MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE
35652
+ };
35653
+ }
35654
+
35655
+ // src/approval.ts
35656
+ import { createInterface } from "node:readline/promises";
35657
+
35658
+ // src/cli-format.ts
35659
+ var isColorEnabled = Boolean(process.stdout.isTTY) && process.env.NO_COLOR === void 0 && process.env.TERM !== "dumb";
35660
+ var CODES = {
35661
+ reset: "\x1B[0m",
35662
+ bold: "\x1B[1m",
35663
+ dim: "\x1B[2m",
35664
+ red: "\x1B[31m",
35665
+ green: "\x1B[32m",
35666
+ yellow: "\x1B[33m",
35667
+ blue: "\x1B[34m",
35668
+ cyan: "\x1B[36m",
35669
+ gray: "\x1B[90m"
35670
+ };
35671
+ function paint(code, text) {
35672
+ if (!isColorEnabled) return text;
35673
+ return `${CODES[code]}${text}${CODES.reset}`;
35674
+ }
35675
+ var bold = (text) => paint("bold", text);
35676
+ var dim = (text) => paint("dim", text);
35677
+ var ok = (text) => paint("green", text);
35678
+ var warn = (text) => paint("yellow", text);
35679
+ var danger = (text) => paint("red", text);
35680
+ var info = (text) => paint("cyan", text);
35681
+ var muted = (text) => paint("gray", text);
35682
+ function heading(text) {
35683
+ const rule = "\u2500".repeat(Math.max(text.length, 3));
35684
+ return `${bold(info(text))}
35685
+ ${muted(rule)}`;
35686
+ }
35687
+ function keyValueBlock(rows) {
35688
+ const width = rows.reduce(
35689
+ (widest, [label]) => Math.max(widest, label.length),
35690
+ 0
35691
+ );
35692
+ return rows.map(([label, value]) => ` ${dim(label.padEnd(width))} ${value}`).join("\n");
35693
+ }
35694
+
35695
+ // src/approval.ts
35696
+ function approvalSummary(tool, args) {
35697
+ if (tool === "write_text_file") {
35698
+ const bytes = Buffer.byteLength(String(args.contents ?? ""));
35699
+ return `Write ${bytes} bytes to ${String(args.path ?? "an unknown path")}${args.overwrite ? " (overwrite)" : ""}`;
35700
+ }
35701
+ if (tool === "start_process") {
35702
+ const command = [
35703
+ String(args.program ?? ""),
35704
+ ...Array.isArray(args.args) ? args.args.map(String) : []
35705
+ ];
35706
+ return `Start: ${command.join(" ")}`;
35707
+ }
35708
+ if (tool === "terminate_process") {
35709
+ return `Terminate process session ${String(args.sessionId ?? "")}`;
35710
+ }
35711
+ return `Run destructive tool: ${tool}`;
35712
+ }
35713
+ function createAutoApprover() {
35714
+ return (tool, args) => {
35715
+ console.log(
35716
+ `
35717
+ ${warn("Approval requested:")} ${approvalSummary(tool, args)} ${dim("(auto-approved)")}`
35718
+ );
35719
+ return Promise.resolve(true);
35720
+ };
35721
+ }
35722
+ function createTerminalApprover() {
35723
+ let queue = Promise.resolve(false);
35724
+ return (tool, args) => {
35725
+ queue = queue.catch(() => false).then(async () => {
35726
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
35727
+ const prompt = createInterface({
35728
+ input: process.stdin,
35729
+ output: process.stdout
35730
+ });
35731
+ try {
35732
+ console.log(
35733
+ `
35734
+ ${warn("Approval requested:")} ${approvalSummary(tool, args)}`
35735
+ );
35736
+ const answer = await prompt.question(
35737
+ `${bold("Approve this action?")} [y/N] `
35738
+ );
35739
+ return (/* @__PURE__ */ new Set(["y", "yes"])).has(answer.trim().toLowerCase());
35740
+ } finally {
35741
+ prompt.close();
35742
+ }
35743
+ });
35744
+ return queue;
35745
+ };
35643
35746
  }
35644
35747
 
35645
35748
  // src/cli-options.ts
@@ -36021,43 +36124,6 @@ function renderHelp(command = "help") {
36021
36124
  return lines.join("\n");
36022
36125
  }
36023
36126
 
36024
- // src/cli-format.ts
36025
- var isColorEnabled = Boolean(process.stdout.isTTY) && process.env.NO_COLOR === void 0 && process.env.TERM !== "dumb";
36026
- var CODES = {
36027
- reset: "\x1B[0m",
36028
- bold: "\x1B[1m",
36029
- dim: "\x1B[2m",
36030
- red: "\x1B[31m",
36031
- green: "\x1B[32m",
36032
- yellow: "\x1B[33m",
36033
- blue: "\x1B[34m",
36034
- cyan: "\x1B[36m",
36035
- gray: "\x1B[90m"
36036
- };
36037
- function paint(code, text) {
36038
- if (!isColorEnabled) return text;
36039
- return `${CODES[code]}${text}${CODES.reset}`;
36040
- }
36041
- var bold = (text) => paint("bold", text);
36042
- var dim = (text) => paint("dim", text);
36043
- var ok = (text) => paint("green", text);
36044
- var warn = (text) => paint("yellow", text);
36045
- var danger = (text) => paint("red", text);
36046
- var info = (text) => paint("cyan", text);
36047
- var muted = (text) => paint("gray", text);
36048
- function heading(text) {
36049
- const rule = "\u2500".repeat(Math.max(text.length, 3));
36050
- return `${bold(info(text))}
36051
- ${muted(rule)}`;
36052
- }
36053
- function keyValueBlock(rows) {
36054
- const width = rows.reduce(
36055
- (widest, [label]) => Math.max(widest, label.length),
36056
- 0
36057
- );
36058
- return rows.map(([label, value]) => ` ${dim(label.padEnd(width))} ${value}`).join("\n");
36059
- }
36060
-
36061
36127
  // src/credential-store.ts
36062
36128
  import { promises as fs2 } from "node:fs";
36063
36129
  import { randomUUID } from "node:crypto";
@@ -36347,54 +36413,6 @@ function describeSettings(settings, deviceId) {
36347
36413
  ])
36348
36414
  ].join("\n");
36349
36415
  }
36350
- function approvalSummary(tool, args) {
36351
- if (tool === "write_text_file") {
36352
- const bytes = Buffer.byteLength(String(args.contents ?? ""));
36353
- return `Write ${bytes} bytes to ${String(args.path ?? "an unknown path")}${args.overwrite ? " (overwrite)" : ""}`;
36354
- }
36355
- if (tool === "run_program") {
36356
- const command = [
36357
- String(args.program ?? ""),
36358
- ...Array.isArray(args.args) ? args.args.map(String) : []
36359
- ];
36360
- return `Run: ${command.join(" ")}`;
36361
- }
36362
- return `Run destructive tool: ${tool}`;
36363
- }
36364
- function createAutoApprover() {
36365
- return (tool, args) => {
36366
- console.log(
36367
- `
36368
- ${warn("Approval requested:")} ${approvalSummary(tool, args)} ${dim("(auto-approved)")}`
36369
- );
36370
- return Promise.resolve(true);
36371
- };
36372
- }
36373
- function createTerminalApprover() {
36374
- let queue = Promise.resolve(false);
36375
- return (tool, args) => {
36376
- queue = queue.catch(() => false).then(async () => {
36377
- if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
36378
- const prompt = createInterface({
36379
- input: process.stdin,
36380
- output: process.stdout
36381
- });
36382
- try {
36383
- console.log(
36384
- `
36385
- ${warn("Approval requested:")} ${approvalSummary(tool, args)}`
36386
- );
36387
- const answer = await prompt.question(
36388
- `${bold("Approve this action?")} [y/N] `
36389
- );
36390
- return (/* @__PURE__ */ new Set(["y", "yes"])).has(answer.trim().toLowerCase());
36391
- } finally {
36392
- prompt.close();
36393
- }
36394
- });
36395
- return queue;
36396
- };
36397
- }
36398
36416
  async function login(environment) {
36399
36417
  const auth2 = resolveAuth(environment);
36400
36418
  const code = await requestDeviceCode(auth2);