@evalops/maestro 0.10.33 → 0.10.37

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/dist/cli.js CHANGED
@@ -90803,6 +90803,43 @@ function coerceEnv(env) {
90803
90803
  }
90804
90804
  return result2;
90805
90805
  }
90806
+ function isTruthyEnv(value) {
90807
+ if (!value) {
90808
+ return false;
90809
+ }
90810
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
90811
+ }
90812
+ function restorePlatformTrustedToolEnv(env, base, policy) {
90813
+ if (base.MAESTRO_SURFACE !== PLATFORM_WORKER_SURFACE) {
90814
+ return;
90815
+ }
90816
+ if (!isTruthyEnv(base[PLATFORM_TRUSTED_TOOL_ENV_FLAG])) {
90817
+ return;
90818
+ }
90819
+ const inherit = policy.inherit ?? "all";
90820
+ const coreSet = new Set(CORE_ENV_VARS.map((name) => name.toUpperCase()));
90821
+ for (const key of PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST) {
90822
+ if (inherit === "none") {
90823
+ continue;
90824
+ }
90825
+ if (inherit === "core" && !coreSet.has(key.toUpperCase())) {
90826
+ continue;
90827
+ }
90828
+ if (policy.exclude?.length && matchesAny(key, policy.exclude)) {
90829
+ continue;
90830
+ }
90831
+ if (policy.include_only?.length && !matchesAny(key, policy.include_only)) {
90832
+ continue;
90833
+ }
90834
+ if (policy.set && Object.prototype.hasOwnProperty.call(policy.set, key)) {
90835
+ continue;
90836
+ }
90837
+ const value = base[key];
90838
+ if (typeof value === "string") {
90839
+ env[key] = value;
90840
+ }
90841
+ }
90842
+ }
90806
90843
  function applyShellEnvironmentPolicy(baseEnv, policy) {
90807
90844
  const resolvedPolicy = policy ?? {
90808
90845
  inherit: "all",
@@ -90850,6 +90887,7 @@ function applyShellEnvironmentPolicy(baseEnv, policy) {
90850
90887
  }
90851
90888
  }
90852
90889
  }
90890
+ restorePlatformTrustedToolEnv(env, base, resolvedPolicy);
90853
90891
  return env;
90854
90892
  }
90855
90893
  function resolveShellEnvironment(overrides, options = {}) {
@@ -90867,6 +90905,9 @@ function resolveShellEnvironment(overrides, options = {}) {
90867
90905
  }
90868
90906
  var CORE_ENV_VARS;
90869
90907
  var DEFAULT_EXCLUDES;
90908
+ var PLATFORM_WORKER_SURFACE = "platform-agent-runtime";
90909
+ var PLATFORM_TRUSTED_TOOL_ENV_FLAG = "MAESTRO_PLATFORM_TRUSTED_TOOL_ENV";
90910
+ var PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST;
90870
90911
  var init_shell_env = __esm2(() => {
90871
90912
  init_config2();
90872
90913
  CORE_ENV_VARS = [
@@ -90881,6 +90922,31 @@ var init_shell_env = __esm2(() => {
90881
90922
  "TMP"
90882
90923
  ];
90883
90924
  DEFAULT_EXCLUDES = ["*KEY*", "*SECRET*", "*TOKEN*"];
90925
+ PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST = [
90926
+ "CODEX_WORKER_GIT_TOKEN",
90927
+ "CODEX_WORKER_GIT_USERNAME",
90928
+ "GH_TOKEN",
90929
+ "GITHUB_TOKEN",
90930
+ "GIT_ASKPASS",
90931
+ "GIT_TERMINAL_PROMPT",
90932
+ "CODEX_WORKER_RUNTIME_TOKEN",
90933
+ "AGENT_RUNTIME_TOKEN",
90934
+ "MAESTRO_AGENT_RUNTIME_SERVICE_TOKEN",
90935
+ "AGENT_RUNTIME_SERVICE_TOKEN",
90936
+ "MAESTRO_PLATFORM_A2A_TOKEN",
90937
+ "MAESTRO_AGENT_OPERATING_PLANE_TOKEN",
90938
+ "CODEX_WORKER_AGENT_REGISTRY_TOKEN",
90939
+ "AGENT_REGISTRY_SERVICE_TOKEN",
90940
+ "MAESTRO_AGENT_REGISTRY_SERVICE_TOKEN",
90941
+ "MAESTRO_PLATFORM_A2A_ENABLED",
90942
+ "MAESTRO_AGENT_RUNTIME_A2A_ENABLED",
90943
+ "MAESTRO_PLATFORM_A2A_EXTENSIONS",
90944
+ "MAESTRO_AGENT_RUNTIME_SERVICE_URL",
90945
+ "MAESTRO_PLATFORM_A2A_URL",
90946
+ "MAESTRO_AGENT_REGISTRY_SERVICE_URL",
90947
+ "MAESTRO_AGENT_RUNTIME_ORG_ID",
90948
+ "MAESTRO_AGENT_RUNTIME_WORKSPACE_ID"
90949
+ ];
90884
90950
  });
90885
90951
  function fileExists(path23) {
90886
90952
  try {
@@ -92411,14 +92477,22 @@ function renderTaskList(tasks, respond) {
92411
92477
  return;
92412
92478
  }
92413
92479
  const lines = tasks.map((task) => `${formatTaskSummary(task)}
92414
- ${task.command}`);
92480
+ ${sanitizeWithStaticMask(task.command)}`);
92415
92481
  respond.text(lines.join(`
92416
92482
  `));
92417
92483
  }
92484
+ function buildSanitizedTaskDetail(task) {
92485
+ const detail = buildTaskDetail(task);
92486
+ return {
92487
+ ...detail,
92488
+ command: sanitizeWithStaticMask(detail.command)
92489
+ };
92490
+ }
92418
92491
  var backgroundTaskSchema;
92419
92492
  var backgroundTasksTool;
92420
92493
  var init_tool_handler = __esm2(() => {
92421
92494
  init_typebox_helpers();
92495
+ init_secret_redactor();
92422
92496
  init_background_tasks();
92423
92497
  init_tool_dsl();
92424
92498
  backgroundTaskSchema = Type8.Union([
@@ -92558,13 +92632,13 @@ var init_tool_handler = __esm2(() => {
92558
92632
  `Execution mode: ${task.shellMode === "shell" ? "shell" : "direct"}`,
92559
92633
  "Use action=list to view tasks or action=stop to terminate."
92560
92634
  ].join(`
92561
- `)).detail(buildTaskDetail(task));
92635
+ `)).detail(buildSanitizedTaskDetail(task));
92562
92636
  return respond;
92563
92637
  }
92564
92638
  if (params.action === "list") {
92565
92639
  const tasks = backgroundTaskManager.getTasks();
92566
92640
  renderTaskList(tasks, respond);
92567
- respond.detail(tasks.map((task) => buildTaskDetail(task)));
92641
+ respond.detail(tasks.map((task) => buildSanitizedTaskDetail(task)));
92568
92642
  return respond;
92569
92643
  }
92570
92644
  if (params.action === "stop") {
@@ -92574,7 +92648,7 @@ var init_tool_handler = __esm2(() => {
92574
92648
  } else {
92575
92649
  const statusLabel = result2.stopped ? "Stopped" : "Stop signal sent";
92576
92650
  const summary2 = formatTaskSummary(result2.task);
92577
- respond.text(`${statusLabel} ${summary2}`).detail(buildTaskDetail(result2.task));
92651
+ respond.text(`${statusLabel} ${summary2}`).detail(buildSanitizedTaskDetail(result2.task));
92578
92652
  }
92579
92653
  return respond;
92580
92654
  }
@@ -92620,7 +92694,7 @@ function formatTaskFailures() {
92620
92694
  const lines = ["# \u26A0\uFE0F Background Task Alerts"];
92621
92695
  for (const task of recentFailures) {
92622
92696
  const reason = task.failureReason ? `Reason: ${task.failureReason}` : typeof task.exitCode === "number" && task.exitCode !== 0 ? `Exit Code: ${task.exitCode}` : "Exited unexpectedly";
92623
- lines.push(`- Task "${task.command}" (${task.id}) stopped. ${reason}`);
92697
+ lines.push(`- Task "${sanitizeWithStaticMask(task.command)}" (${task.id}) stopped. ${reason}`);
92624
92698
  lines.push(` (Use background_tasks action=logs taskId=${task.id} to investigate)`);
92625
92699
  }
92626
92700
  return lines.join(`
@@ -93098,7 +93172,7 @@ var init_background_tasks = __esm2(() => {
93098
93172
  if (!task) {
93099
93173
  throw new ToolError(`Task not found or logs expired: ${taskId}`);
93100
93174
  }
93101
- const text2 = this.tailLog(task, lines);
93175
+ const text2 = this.sanitizeLogSnippet(this.tailLog(task, lines));
93102
93176
  if (!task.logTruncated) {
93103
93177
  return text2;
93104
93178
  }
@@ -155947,6 +156021,9 @@ var init_nested_agent_guard = __esm2(() => {
155947
156021
  ];
155948
156022
  nestedAgentGuard = new NestedAgentGuard();
155949
156023
  });
156024
+ function sanitizeToolOutput(value) {
156025
+ return sanitizeWithStaticMask(value);
156026
+ }
155950
156027
  function isMutatingCommand(command) {
155951
156028
  const mutationPatterns = [
155952
156029
  /(^|\s)(rm|mv|cp|chmod|chown|truncate|dd|mkfs|ln)\b/i,
@@ -155967,6 +156044,7 @@ var init_bash2 = __esm2(() => {
155967
156044
  init_execpolicy();
155968
156045
  init_nested_agent_guard();
155969
156046
  init_safe_mode();
156047
+ init_secret_redactor();
155970
156048
  init_shell_env();
155971
156049
  init_background_tasks();
155972
156050
  init_shell_utils();
@@ -156073,7 +156151,7 @@ ${formatGuardianResult(guardian)}`
156073
156151
  `)).detail({
156074
156152
  taskId: task.id,
156075
156153
  logPath: task.logPath,
156076
- command: interpolatedCommand,
156154
+ command: sanitizeToolOutput(interpolatedCommand),
156077
156155
  cwd: resolvedCwd,
156078
156156
  status: task.status
156079
156157
  });
@@ -156099,7 +156177,7 @@ Exit code: ${result2.exitCode}`;
156099
156177
  content: [
156100
156178
  {
156101
156179
  type: "text",
156102
- text: output.trim() || "Command executed successfully (no output)"
156180
+ text: sanitizeToolOutput(output).trim() || "Command executed successfully (no output)"
156103
156181
  }
156104
156182
  ],
156105
156183
  details: void 0
@@ -156206,7 +156284,7 @@ Exit code: ${code}`;
156206
156284
  content: [
156207
156285
  {
156208
156286
  type: "text",
156209
- text: output.trim() || "Command executed successfully (no output)"
156287
+ text: sanitizeToolOutput(output).trim() || "Command executed successfully (no output)"
156210
156288
  }
156211
156289
  ],
156212
156290
  details: void 0
@@ -201319,22 +201397,24 @@ function createInlineTool(def) {
201319
201397
  const displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);
201320
201398
  truncationMessages.push(`stderr exceeded ${displayedKB}KB limit and was truncated`);
201321
201399
  }
201400
+ const stdout = sanitizeWithStaticMask(result2.stdout);
201401
+ const stderr = sanitizeWithStaticMask(result2.stderr);
201322
201402
  const truncationNotice = truncationMessages.length > 0 ? `Warning: Output truncated: ${truncationMessages.join("; ")}. Consider piping output to a file or using head/tail.` : "";
201323
201403
  if (result2.exitCode !== 0) {
201324
- const baseError = result2.stderr.trim() || `Exit code: ${result2.exitCode}`;
201404
+ const baseError = stderr.trim() || `Exit code: ${result2.exitCode}`;
201325
201405
  const errorMsg = truncationNotice ? `${baseError}
201326
201406
 
201327
201407
  ${truncationNotice}` : baseError;
201328
201408
  return context2.respond.error(`Command failed: ${errorMsg}
201329
201409
 
201330
201410
  Stdout:
201331
- ${result2.stdout}`);
201411
+ ${stdout}`);
201332
201412
  }
201333
- const output = result2.stdout.trim();
201334
- if (result2.stderr.trim()) {
201413
+ const output = stdout.trim();
201414
+ if (stderr.trim()) {
201335
201415
  const combined = output ? `${output}
201336
201416
 
201337
- [stderr]: ${result2.stderr.trim()}` : `[stderr]: ${result2.stderr.trim()}`;
201417
+ [stderr]: ${stderr.trim()}` : `[stderr]: ${stderr.trim()}`;
201338
201418
  return context2.respond.text(truncationNotice ? `${combined}
201339
201419
 
201340
201420
  ${truncationNotice}` : combined);
@@ -201347,7 +201427,7 @@ ${truncationNotice}` : truncationNotice;
201347
201427
  }
201348
201428
  return context2.respond.text(output || "(no output)");
201349
201429
  } catch (error) {
201350
- const message = error instanceof Error ? error.message : String(error);
201430
+ const message = sanitizeWithStaticMask(error instanceof Error ? error.message : String(error));
201351
201431
  return context2.respond.error(`Failed to execute command: ${message}`);
201352
201432
  }
201353
201433
  }
@@ -201453,6 +201533,7 @@ var init_inline_tools = __esm2(() => {
201453
201533
  init_constants();
201454
201534
  init_logger();
201455
201535
  init_path_expansion();
201536
+ init_secret_redactor();
201456
201537
  init_shell_env();
201457
201538
  init_tool_dsl();
201458
201539
  logger181 = createLogger("inline-tools");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evalops/contracts",
3
- "version": "0.10.33",
3
+ "version": "0.10.37",
4
4
  "description": "Shared Maestro contracts for frontend/backend integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evalops/tui",
3
- "version": "0.10.33",
3
+ "version": "0.10.37",
4
4
  "description": "Terminal UI library with differential rendering for Maestro",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +1 @@
1
- {"version":3,"file":"tool-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/background/tool-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0KH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiG9B,CAAC"}
1
+ {"version":3,"file":"tool-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/background/tool-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoLH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiG9B,CAAC"}
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { Type } from "@sinclair/typebox";
6
6
  import { StringEnum } from "../../agent/providers/typebox-helpers.js";
7
+ import { sanitizeWithStaticMask } from "../../utils/secret-redactor.js";
7
8
  import { backgroundTaskManager } from "../background-tasks.js";
8
9
  import { createTool } from "../tool-dsl.js";
9
10
  import { buildTaskDetail, formatTaskSummary, } from "./task-types.js";
@@ -109,9 +110,16 @@ function renderTaskList(tasks, respond) {
109
110
  respond.text("No background tasks are running.");
110
111
  return;
111
112
  }
112
- const lines = tasks.map((task) => `${formatTaskSummary(task)}\n ${task.command}`);
113
+ const lines = tasks.map((task) => `${formatTaskSummary(task)}\n ${sanitizeWithStaticMask(task.command)}`);
113
114
  respond.text(lines.join("\n"));
114
115
  }
116
+ function buildSanitizedTaskDetail(task) {
117
+ const detail = buildTaskDetail(task);
118
+ return {
119
+ ...detail,
120
+ command: sanitizeWithStaticMask(detail.command),
121
+ };
122
+ }
115
123
  // ─────────────────────────────────────────────────────────────────────────────
116
124
  // Tool
117
125
  // ─────────────────────────────────────────────────────────────────────────────
@@ -163,13 +171,13 @@ export const backgroundTasksTool = createTool({
163
171
  `Execution mode: ${task.shellMode === "shell" ? "shell" : "direct"}`,
164
172
  "Use action=list to view tasks or action=stop to terminate.",
165
173
  ].join("\n"))
166
- .detail(buildTaskDetail(task));
174
+ .detail(buildSanitizedTaskDetail(task));
167
175
  return respond;
168
176
  }
169
177
  if (params.action === "list") {
170
178
  const tasks = backgroundTaskManager.getTasks();
171
179
  renderTaskList(tasks, respond);
172
- respond.detail(tasks.map((task) => buildTaskDetail(task)));
180
+ respond.detail(tasks.map((task) => buildSanitizedTaskDetail(task)));
173
181
  return respond;
174
182
  }
175
183
  if (params.action === "stop") {
@@ -182,7 +190,7 @@ export const backgroundTasksTool = createTool({
182
190
  const summary = formatTaskSummary(result.task);
183
191
  respond
184
192
  .text(`${statusLabel} ${summary}`)
185
- .detail(buildTaskDetail(result.task));
193
+ .detail(buildSanitizedTaskDetail(result.task));
186
194
  }
187
195
  return respond;
188
196
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-handler.js","sourceRoot":"","sources":["../../../src/tools/background/tool-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Background Task Tool Handler\n * TypeBox schema definition and tool handler for the background_tasks tool.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { StringEnum } from \"../../agent/providers/typebox-helpers.js\";\nimport { backgroundTaskManager } from \"../background-tasks.js\";\nimport { createTool } from \"../tool-dsl.js\";\nimport type { ToolResponseBuilder } from \"../tool-dsl.js\";\nimport {\n\ttype BackgroundTask,\n\ttype TaskStartOptions,\n\tbuildTaskDetail,\n\tformatTaskSummary,\n} from \"./task-types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Schema\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst backgroundTaskSchema = Type.Union([\n\tType.Object({\n\t\taction: Type.Literal(\"start\"),\n\t\tcommand: Type.String({\n\t\t\tdescription: \"Command to run in the background\",\n\t\t\tminLength: 1,\n\t\t}),\n\t\tshell: Type.Optional(\n\t\t\tType.Boolean({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Run the command through the system shell (allows pipes/redirection). Defaults to false for direct execution.\",\n\t\t\t}),\n\t\t),\n\t\tcwd: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"Working directory for the command\",\n\t\t\t\tminLength: 1,\n\t\t\t}),\n\t\t),\n\t\tenv: Type.Optional(\n\t\t\tType.Record(Type.String({ minLength: 1 }), Type.String(), {\n\t\t\t\tdescription: \"Additional environment variables for the command\",\n\t\t\t}),\n\t\t),\n\t\trestart: Type.Optional(\n\t\t\tType.Object({\n\t\t\t\tmaxAttempts: Type.Integer({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Maximum number of restart attempts when the task exits with a non-zero status\",\n\t\t\t\t\tminimum: 1,\n\t\t\t\t\tmaximum: 5,\n\t\t\t\t}),\n\t\t\t\tdelayMs: Type.Integer({\n\t\t\t\t\tdescription: \"Delay in milliseconds between restart attempts\",\n\t\t\t\t\tminimum: 50,\n\t\t\t\t\tmaximum: 60_000,\n\t\t\t\t}),\n\t\t\t\tstrategy: Type.Optional(StringEnum([\"fixed\", \"exponential\"])),\n\t\t\t\tmaxDelayMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription: \"Upper bound for exponential backoff delays\",\n\t\t\t\t\t\tminimum: 50,\n\t\t\t\t\t\tmaximum: 600_000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tjitterRatio: Type.Optional(\n\t\t\t\t\tType.Number({\n\t\t\t\t\t\tdescription: \"Random jitter ratio applied to restart delays (0-1)\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 1,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t\tlimits: Type.Optional(\n\t\t\tType.Object({\n\t\t\t\tlogSizeLimit: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Per-task log size limit in bytes (overrides default). Minimum 0, maximum 50MB.\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 50 * 1024 * 1024,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tlogSegments: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Number of gzip-compressed log segments to retain when rotating.\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 10,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tretentionMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Milliseconds to retain finished task metadata and logs before cleanup.\",\n\t\t\t\t\t\tminimum: 1_000,\n\t\t\t\t\t\tmaximum: 24 * 60 * 60 * 1000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmaxRssKb: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Maximum resident set size in kilobytes before the task is terminated (0 disables).\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 4 * 1024 * 1024,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmaxCpuMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Maximum combined user+system CPU time in milliseconds before termination (0 disables).\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 24 * 60 * 60 * 1000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"stop\"),\n\t\ttaskId: Type.String({\n\t\t\tdescription: \"Identifier of the background task to stop\",\n\t\t\tminLength: 1,\n\t\t}),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"list\"),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"logs\"),\n\t\ttaskId: Type.String({\n\t\t\tdescription: \"Identifier of the background task\",\n\t\t\tminLength: 1,\n\t\t}),\n\t\tlines: Type.Optional(\n\t\t\tType.Number({\n\t\t\t\tdescription: \"Number of log lines to show\",\n\t\t\t\tminimum: 1,\n\t\t\t\tmaximum: 200,\n\t\t\t}),\n\t\t),\n\t}),\n]);\n\ntype BackgroundTaskSchema = typeof backgroundTaskSchema;\n\ntype BackgroundTaskToolDetails = unknown;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction renderTaskList(\n\ttasks: BackgroundTask[],\n\trespond: ToolResponseBuilder<unknown>,\n): void {\n\tif (tasks.length === 0) {\n\t\trespond.text(\"No background tasks are running.\");\n\t\treturn;\n\t}\n\n\tconst lines = tasks.map(\n\t\t(task) => `${formatTaskSummary(task)}\\n ${task.command}`,\n\t);\n\trespond.text(lines.join(\"\\n\"));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tool\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const backgroundTasksTool = createTool<\n\tBackgroundTaskSchema,\n\tBackgroundTaskToolDetails\n>({\n\tname: \"background_tasks\",\n\tlabel: \"background tasks\",\n\tdescription: \"Run commands in the background and manage their lifecycle.\",\n\tschema: backgroundTaskSchema,\n\tgetToolUseSummary(params) {\n\t\tif (params.action === \"start\") return \"Started background task\";\n\t\tif (params.action === \"stop\") return \"Stopped background task\";\n\t\tif (params.action === \"logs\") return \"Viewed background logs\";\n\t\tif (params.action === \"list\") return \"Listed background tasks\";\n\t\treturn \"Checked background tasks\";\n\t},\n\tgetActivityDescription(params) {\n\t\tif (params.action === \"start\") return \"Starting background task\";\n\t\tif (params.action === \"stop\") return \"Stopping background task\";\n\t\tif (params.action === \"logs\") return \"Reading background logs\";\n\t\tif (params.action === \"list\") return \"Listing background tasks\";\n\t\treturn \"Checking background tasks\";\n\t},\n\tasync run(params, { respond }) {\n\t\tif (params.action === \"start\") {\n\t\t\tconst restart =\n\t\t\t\tparams.restart &&\n\t\t\t\t({\n\t\t\t\t\t...params.restart,\n\t\t\t\t\tstrategy:\n\t\t\t\t\t\tparams.restart.strategy === \"exponential\" ? \"exponential\" : \"fixed\",\n\t\t\t\t} satisfies TaskStartOptions[\"restart\"]);\n\t\t\tconst task = backgroundTaskManager.start(params.command, {\n\t\t\t\tcwd: params.cwd,\n\t\t\t\tenv: params.env,\n\t\t\t\tuseShell: params.shell ?? false,\n\t\t\t\trestart,\n\t\t\t\tlimits: params.limits,\n\t\t\t});\n\t\t\trespond\n\t\t\t\t.text(\n\t\t\t\t\t[\n\t\t\t\t\t\t`Started ${formatTaskSummary(task)}`,\n\t\t\t\t\t\t`Logs: ${task.logPath}`,\n\t\t\t\t\t\t`Execution mode: ${task.shellMode === \"shell\" ? \"shell\" : \"direct\"}`,\n\t\t\t\t\t\t\"Use action=list to view tasks or action=stop to terminate.\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t)\n\t\t\t\t.detail(buildTaskDetail(task));\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"list\") {\n\t\t\tconst tasks = backgroundTaskManager.getTasks();\n\t\t\trenderTaskList(tasks, respond);\n\t\t\trespond.detail(tasks.map((task) => buildTaskDetail(task)));\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"stop\") {\n\t\t\tconst result = await backgroundTaskManager.stopTask(params.taskId);\n\t\t\tif (!result) {\n\t\t\t\trespond.error(`Task not found: ${params.taskId}`);\n\t\t\t} else {\n\t\t\t\tconst statusLabel = result.stopped ? \"Stopped\" : \"Stop signal sent\";\n\t\t\t\tconst summary = formatTaskSummary(result.task);\n\t\t\t\trespond\n\t\t\t\t\t.text(`${statusLabel} ${summary}`)\n\t\t\t\t\t.detail(buildTaskDetail(result.task));\n\t\t\t}\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"logs\") {\n\t\t\tconst lines = params.lines ?? 40;\n\t\t\ttry {\n\t\t\t\tconst logText = backgroundTaskManager.getLogs(params.taskId, lines);\n\t\t\t\tconst task = backgroundTaskManager.getTask(params.taskId);\n\t\t\t\trespond\n\t\t\t\t\t.text(`Last ${lines} lines for ${params.taskId}:\\n\\n${logText}`)\n\t\t\t\t\t.detail({\n\t\t\t\t\t\ttaskId: params.taskId,\n\t\t\t\t\t\tlines,\n\t\t\t\t\t\tlogTruncated: Boolean(task?.logTruncated),\n\t\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst message =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: `Unable to read logs for ${params.taskId}`;\n\t\t\t\trespond.error(message);\n\t\t\t}\n\t\t\treturn respond;\n\t\t}\n\n\t\trespond.error(\"Unsupported action\");\n\t\treturn respond;\n\t},\n});\n"]}
1
+ {"version":3,"file":"tool-handler.js","sourceRoot":"","sources":["../../../src/tools/background/tool-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Background Task Tool Handler\n * TypeBox schema definition and tool handler for the background_tasks tool.\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { StringEnum } from \"../../agent/providers/typebox-helpers.js\";\nimport { sanitizeWithStaticMask } from \"../../utils/secret-redactor.js\";\nimport { backgroundTaskManager } from \"../background-tasks.js\";\nimport { createTool } from \"../tool-dsl.js\";\nimport type { ToolResponseBuilder } from \"../tool-dsl.js\";\nimport {\n\ttype BackgroundTask,\n\ttype TaskStartOptions,\n\tbuildTaskDetail,\n\tformatTaskSummary,\n} from \"./task-types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Schema\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst backgroundTaskSchema = Type.Union([\n\tType.Object({\n\t\taction: Type.Literal(\"start\"),\n\t\tcommand: Type.String({\n\t\t\tdescription: \"Command to run in the background\",\n\t\t\tminLength: 1,\n\t\t}),\n\t\tshell: Type.Optional(\n\t\t\tType.Boolean({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Run the command through the system shell (allows pipes/redirection). Defaults to false for direct execution.\",\n\t\t\t}),\n\t\t),\n\t\tcwd: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tdescription: \"Working directory for the command\",\n\t\t\t\tminLength: 1,\n\t\t\t}),\n\t\t),\n\t\tenv: Type.Optional(\n\t\t\tType.Record(Type.String({ minLength: 1 }), Type.String(), {\n\t\t\t\tdescription: \"Additional environment variables for the command\",\n\t\t\t}),\n\t\t),\n\t\trestart: Type.Optional(\n\t\t\tType.Object({\n\t\t\t\tmaxAttempts: Type.Integer({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Maximum number of restart attempts when the task exits with a non-zero status\",\n\t\t\t\t\tminimum: 1,\n\t\t\t\t\tmaximum: 5,\n\t\t\t\t}),\n\t\t\t\tdelayMs: Type.Integer({\n\t\t\t\t\tdescription: \"Delay in milliseconds between restart attempts\",\n\t\t\t\t\tminimum: 50,\n\t\t\t\t\tmaximum: 60_000,\n\t\t\t\t}),\n\t\t\t\tstrategy: Type.Optional(StringEnum([\"fixed\", \"exponential\"])),\n\t\t\t\tmaxDelayMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription: \"Upper bound for exponential backoff delays\",\n\t\t\t\t\t\tminimum: 50,\n\t\t\t\t\t\tmaximum: 600_000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tjitterRatio: Type.Optional(\n\t\t\t\t\tType.Number({\n\t\t\t\t\t\tdescription: \"Random jitter ratio applied to restart delays (0-1)\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 1,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t\tlimits: Type.Optional(\n\t\t\tType.Object({\n\t\t\t\tlogSizeLimit: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Per-task log size limit in bytes (overrides default). Minimum 0, maximum 50MB.\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 50 * 1024 * 1024,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tlogSegments: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Number of gzip-compressed log segments to retain when rotating.\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 10,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tretentionMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Milliseconds to retain finished task metadata and logs before cleanup.\",\n\t\t\t\t\t\tminimum: 1_000,\n\t\t\t\t\t\tmaximum: 24 * 60 * 60 * 1000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmaxRssKb: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Maximum resident set size in kilobytes before the task is terminated (0 disables).\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 4 * 1024 * 1024,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tmaxCpuMs: Type.Optional(\n\t\t\t\t\tType.Integer({\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Maximum combined user+system CPU time in milliseconds before termination (0 disables).\",\n\t\t\t\t\t\tminimum: 0,\n\t\t\t\t\t\tmaximum: 24 * 60 * 60 * 1000,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"stop\"),\n\t\ttaskId: Type.String({\n\t\t\tdescription: \"Identifier of the background task to stop\",\n\t\t\tminLength: 1,\n\t\t}),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"list\"),\n\t}),\n\tType.Object({\n\t\taction: Type.Literal(\"logs\"),\n\t\ttaskId: Type.String({\n\t\t\tdescription: \"Identifier of the background task\",\n\t\t\tminLength: 1,\n\t\t}),\n\t\tlines: Type.Optional(\n\t\t\tType.Number({\n\t\t\t\tdescription: \"Number of log lines to show\",\n\t\t\t\tminimum: 1,\n\t\t\t\tmaximum: 200,\n\t\t\t}),\n\t\t),\n\t}),\n]);\n\ntype BackgroundTaskSchema = typeof backgroundTaskSchema;\n\ntype BackgroundTaskToolDetails = unknown;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction renderTaskList(\n\ttasks: BackgroundTask[],\n\trespond: ToolResponseBuilder<unknown>,\n): void {\n\tif (tasks.length === 0) {\n\t\trespond.text(\"No background tasks are running.\");\n\t\treturn;\n\t}\n\n\tconst lines = tasks.map(\n\t\t(task) =>\n\t\t\t`${formatTaskSummary(task)}\\n ${sanitizeWithStaticMask(task.command)}`,\n\t);\n\trespond.text(lines.join(\"\\n\"));\n}\n\nfunction buildSanitizedTaskDetail(task: BackgroundTask) {\n\tconst detail = buildTaskDetail(task);\n\treturn {\n\t\t...detail,\n\t\tcommand: sanitizeWithStaticMask(detail.command),\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tool\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const backgroundTasksTool = createTool<\n\tBackgroundTaskSchema,\n\tBackgroundTaskToolDetails\n>({\n\tname: \"background_tasks\",\n\tlabel: \"background tasks\",\n\tdescription: \"Run commands in the background and manage their lifecycle.\",\n\tschema: backgroundTaskSchema,\n\tgetToolUseSummary(params) {\n\t\tif (params.action === \"start\") return \"Started background task\";\n\t\tif (params.action === \"stop\") return \"Stopped background task\";\n\t\tif (params.action === \"logs\") return \"Viewed background logs\";\n\t\tif (params.action === \"list\") return \"Listed background tasks\";\n\t\treturn \"Checked background tasks\";\n\t},\n\tgetActivityDescription(params) {\n\t\tif (params.action === \"start\") return \"Starting background task\";\n\t\tif (params.action === \"stop\") return \"Stopping background task\";\n\t\tif (params.action === \"logs\") return \"Reading background logs\";\n\t\tif (params.action === \"list\") return \"Listing background tasks\";\n\t\treturn \"Checking background tasks\";\n\t},\n\tasync run(params, { respond }) {\n\t\tif (params.action === \"start\") {\n\t\t\tconst restart =\n\t\t\t\tparams.restart &&\n\t\t\t\t({\n\t\t\t\t\t...params.restart,\n\t\t\t\t\tstrategy:\n\t\t\t\t\t\tparams.restart.strategy === \"exponential\" ? \"exponential\" : \"fixed\",\n\t\t\t\t} satisfies TaskStartOptions[\"restart\"]);\n\t\t\tconst task = backgroundTaskManager.start(params.command, {\n\t\t\t\tcwd: params.cwd,\n\t\t\t\tenv: params.env,\n\t\t\t\tuseShell: params.shell ?? false,\n\t\t\t\trestart,\n\t\t\t\tlimits: params.limits,\n\t\t\t});\n\t\t\trespond\n\t\t\t\t.text(\n\t\t\t\t\t[\n\t\t\t\t\t\t`Started ${formatTaskSummary(task)}`,\n\t\t\t\t\t\t`Logs: ${task.logPath}`,\n\t\t\t\t\t\t`Execution mode: ${task.shellMode === \"shell\" ? \"shell\" : \"direct\"}`,\n\t\t\t\t\t\t\"Use action=list to view tasks or action=stop to terminate.\",\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t)\n\t\t\t\t.detail(buildSanitizedTaskDetail(task));\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"list\") {\n\t\t\tconst tasks = backgroundTaskManager.getTasks();\n\t\t\trenderTaskList(tasks, respond);\n\t\t\trespond.detail(tasks.map((task) => buildSanitizedTaskDetail(task)));\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"stop\") {\n\t\t\tconst result = await backgroundTaskManager.stopTask(params.taskId);\n\t\t\tif (!result) {\n\t\t\t\trespond.error(`Task not found: ${params.taskId}`);\n\t\t\t} else {\n\t\t\t\tconst statusLabel = result.stopped ? \"Stopped\" : \"Stop signal sent\";\n\t\t\t\tconst summary = formatTaskSummary(result.task);\n\t\t\t\trespond\n\t\t\t\t\t.text(`${statusLabel} ${summary}`)\n\t\t\t\t\t.detail(buildSanitizedTaskDetail(result.task));\n\t\t\t}\n\t\t\treturn respond;\n\t\t}\n\n\t\tif (params.action === \"logs\") {\n\t\t\tconst lines = params.lines ?? 40;\n\t\t\ttry {\n\t\t\t\tconst logText = backgroundTaskManager.getLogs(params.taskId, lines);\n\t\t\t\tconst task = backgroundTaskManager.getTask(params.taskId);\n\t\t\t\trespond\n\t\t\t\t\t.text(`Last ${lines} lines for ${params.taskId}:\\n\\n${logText}`)\n\t\t\t\t\t.detail({\n\t\t\t\t\t\ttaskId: params.taskId,\n\t\t\t\t\t\tlines,\n\t\t\t\t\t\tlogTruncated: Boolean(task?.logTruncated),\n\t\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst message =\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: `Unable to read logs for ${params.taskId}`;\n\t\t\t\trespond.error(message);\n\t\t\t}\n\t\t\treturn respond;\n\t\t}\n\n\t\trespond.error(\"Unsupported action\");\n\t\treturn respond;\n\t},\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"background-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/background-tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"background-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/background-tasks.ts"],"names":[],"mappings":"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"}
@@ -72,7 +72,7 @@ import { readNonNegativeInt, readPositiveInt, readThresholdEnv, } from "../utils
72
72
  import { createLogger } from "../utils/logger.js";
73
73
  import { resolveEnvPath } from "../utils/path-expansion.js";
74
74
  import { safejoin } from "../utils/path-validation.js";
75
- import { redactSecrets } from "../utils/secret-redactor.js";
75
+ import { redactSecrets, sanitizeWithStaticMask, } from "../utils/secret-redactor.js";
76
76
  import { resolveShellEnvironment } from "../utils/shell-env.js";
77
77
  import { createRestartPolicy, shouldNotifyRestart, updateNotifyThreshold, } from "./background/index.js";
78
78
  import { deleteArchives, previewLastLine, tailLogs, } from "./background/log-files.js";
@@ -552,7 +552,7 @@ class BackgroundTaskManager extends EventEmitter {
552
552
  if (!task) {
553
553
  throw new ToolError(`Task not found or logs expired: ${taskId}`);
554
554
  }
555
- const text = this.tailLog(task, lines);
555
+ const text = this.sanitizeLogSnippet(this.tailLog(task, lines));
556
556
  if (!task.logTruncated) {
557
557
  return text;
558
558
  }
@@ -587,7 +587,7 @@ export function formatTaskFailures() {
587
587
  : typeof task.exitCode === "number" && task.exitCode !== 0
588
588
  ? `Exit Code: ${task.exitCode}`
589
589
  : "Exited unexpectedly";
590
- lines.push(`- Task "${task.command}" (${task.id}) stopped. ${reason}`);
590
+ lines.push(`- Task "${sanitizeWithStaticMask(task.command)}" (${task.id}) stopped. ${reason}`);
591
591
  // Add a hint about logs
592
592
  lines.push(` (Use background_tasks action=logs taskId=${task.id} to investigate)`);
593
593
  }
@@ -1 +1 @@
1
- {"version":3,"file":"background-tasks.js","sourceRoot":"","sources":["../../src/tools/background-tasks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Background Tasks Tool - Long-running process management with resource monitoring\n *\n * This module provides infrastructure for running, monitoring, and managing\n * background processes (dev servers, watchers, build tasks, etc.). It's designed\n * for reliability and observability in an AI agent context where processes may\n * run for extended periods without direct human oversight.\n *\n * ## Architecture Overview\n *\n * ```\n * ┌─────────────────────────────────────────────────────────────────────┐\n * │ BackgroundTaskManager │\n * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐ │\n * │ │ Task Start │→ │ Process │→ │ Resource Monitor │ │\n * │ │ & Spawn │ │ Lifecycle │ │ (CPU/Memory Polling) │ │\n * │ └─────────────┘ └─────────────┘ └─────────────────────────────┘ │\n * │ ↓ ↓ ↓ │\n * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐ │\n * │ │ Log Writer │ │ Restart │ │ Limit Enforcement │ │\n * │ │ (Rotating) │ │ Controller │ │ (Kill on Breach) │ │\n * │ └─────────────┘ └─────────────┘ └─────────────────────────────┘ │\n * └─────────────────────────────────────────────────────────────────────┘\n * ```\n *\n * ## Key Features\n *\n * ### 1. Resource Monitoring\n * Polls /proc/<pid>/stat (Linux) or ps (macOS) to track:\n * - Resident Set Size (RSS) memory usage\n * - User and system CPU time\n * - Enforces configurable limits with automatic termination\n *\n * ### 2. Automatic Restart\n * Configurable restart policy with:\n * - Fixed or exponential backoff delays\n * - Jitter to prevent thundering herd\n * - Maximum attempt limits\n * - Notifications on restart threshold\n *\n * ### 3. Log Management\n * - Per-task log files with configurable size limits\n * - Automatic rotation with gzip compression\n * - Tail access for recent output retrieval\n * - Secret redaction in log output\n *\n * ### 4. Lifecycle Management\n * - Graceful shutdown with process tree killing\n * - Automatic cleanup of finished task metadata\n * - Task retention period for post-mortem analysis\n *\n * ## Configuration via Environment Variables\n *\n * | Variable | Description | Default |\n * |---------------------------------------|----------------------------------|------------|\n * | MAESTRO_BACKGROUND_TASK_MAX | Max concurrent tasks | 4 |\n * | MAESTRO_BACKGROUND_TASK_LOG_BYTES | Per-task log size limit | 5MB |\n * | MAESTRO_BACKGROUND_TASK_RETENTION_MS | How long to keep finished tasks | 10 min |\n * | MAESTRO_BACKGROUND_TASK_MAX_RSS_KB | Memory limit per task | 768MB |\n * | MAESTRO_BACKGROUND_TASK_MAX_CPU_MS | CPU time limit per task | 10 min |\n * | MAESTRO_BACKGROUND_TASK_TICKS | Clock ticks per second (Linux) | 100 |\n *\n * @module tools/background-tasks\n */\n\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport { existsSync, mkdirSync, unlinkSync } from \"node:fs\";\n\nimport { PATHS } from \"../config/constants.js\";\nimport {\n\ttype BackgroundTaskSettings,\n\tgetBackgroundTaskSettings,\n\tsubscribeBackgroundTaskSettings,\n} from \"../runtime/background-settings.js\";\nimport {\n\tgetBackgroundTaskHistory,\n\trecordBackgroundTaskEvent,\n} from \"../telemetry.js\";\nimport {\n\treadNonNegativeInt,\n\treadPositiveInt,\n\treadThresholdEnv,\n} from \"../utils/env-parser.js\";\nimport { createLogger } from \"../utils/logger.js\";\nimport { resolveEnvPath } from \"../utils/path-expansion.js\";\nimport { safejoin } from \"../utils/path-validation.js\";\nimport { redactSecrets } from \"../utils/secret-redactor.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport {\n\ttype RestartPolicy,\n\tcreateRestartPolicy,\n\tshouldNotifyRestart,\n\tupdateNotifyThreshold,\n} from \"./background/index.js\";\nimport {\n\tdeleteArchives,\n\tpreviewLastLine,\n\ttailLogs,\n} from \"./background/log-files.js\";\nimport { BackgroundTaskRuntime } from \"./background/task-runtime.js\";\nimport {\n\ttype BackgroundTask,\n\ttype BackgroundTaskHealth,\n\ttype BackgroundTaskHistoryEntry,\n\ttype BackgroundTaskLimits,\n\ttype BackgroundTaskNotification,\n\ttype BackgroundTaskStatus,\n\ttype ResourceLimitBreach,\n\ttype TaskLimitOverrides,\n\ttype TaskRuntimeLimits,\n\ttype TaskStartOptions,\n\tformatTaskSummary,\n} from \"./background/task-types.js\";\nimport { killProcessTree, validateShellParams } from \"./shell-utils.js\";\nimport { ToolError } from \"./tool-dsl.js\";\n\nconst LOG_TAIL_BYTES = 200_000;\nconst DEFAULT_RSS_KB = readNonNegativeInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX_RSS_KB\",\n\t768 * 1024,\n);\nconst DEFAULT_CPU_MS = readNonNegativeInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX_CPU_MS\",\n\t10 * 60 * 1000,\n);\nconst RESTART_NOTIFY_THRESHOLD = readThresholdEnv(\n\t\"MAESTRO_BACKGROUND_TASK_NOTIFY_RESTARTS\",\n\t2,\n);\n\nconst MAX_CONCURRENT_TASKS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX\",\n\t4,\n\t1,\n);\nconst MAX_LOG_FILE_BYTES = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_LOG_BYTES\",\n\t5 * 1024 * 1024,\n\t50_000,\n);\nconst TASK_RETENTION_MS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_RETENTION_MS\",\n\t10 * 60 * 1000,\n\t1_000,\n);\nconst MAX_LOG_SEGMENTS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_LOG_SEGMENTS\",\n\t2,\n\t0,\n);\n// Re-export for backwards compatibility\nexport {\n\textractProcStatFields,\n\ttype TaskResourceUsage,\n} from \"./background/index.js\";\n\nexport { evaluateResourceLimitBreach } from \"./background/resource-limits.js\";\n\nclass BackgroundTaskManager extends EventEmitter {\n\tprivate limits: BackgroundTaskLimits;\n\tprivate readonly defaultLimits: BackgroundTaskLimits;\n\tprivate tasks = new Map<string, BackgroundTask>();\n\tprivate cleanupTimers = new Map<string, NodeJS.Timeout>();\n\tprivate logDir: string | null = null;\n\tprivate logDirBase: string | null = null;\n\tprivate notificationBucket = new Map<\n\t\tstring,\n\t\t{ count: number; reset: number }\n\t>();\n\tprivate settings: BackgroundTaskSettings;\n\tprivate unsubscribeSettings?: () => void;\n\tprivate secretCounter = 0;\n\tprivate readonly logger = createLogger(\"background-tasks\");\n\tprivate readonly runtime = new BackgroundTaskRuntime({\n\t\temitTaskNotification: (payload) => this.emitTaskNotification(payload),\n\t\temitTaskTelemetry: (task, event) => this.emitTaskTelemetry(task, event),\n\t\tmaybeNotifyRestart: (task, policy) => this.maybeNotifyRestart(task, policy),\n\t\tnotifyFailure: (task, code, signal) =>\n\t\t\tthis.notifyFailure(task, code, signal),\n\t\tscheduleCleanup: (task) => this.scheduleCleanup(task),\n\t\tsetFailureReason: (task, reason) => this.setFailureReason(task, reason),\n\t});\n\n\tprivate ensureSettingsSubscription(): void {\n\t\tif (this.unsubscribeSettings) {\n\t\t\treturn;\n\t\t}\n\t\tthis.unsubscribeSettings = subscribeBackgroundTaskSettings((next) => {\n\t\t\tthis.settings = next;\n\t\t});\n\t}\n\n\tconstructor() {\n\t\tsuper();\n\t\tconst initialLimits: BackgroundTaskLimits = {\n\t\t\tmaxTasks: MAX_CONCURRENT_TASKS,\n\t\t\tlogSizeLimit: MAX_LOG_FILE_BYTES,\n\t\t\tretentionMs: TASK_RETENTION_MS,\n\t\t\tlogSegments: MAX_LOG_SEGMENTS,\n\t\t\tmaxRssKb: DEFAULT_RSS_KB,\n\t\t\tmaxCpuMs: DEFAULT_CPU_MS,\n\t\t};\n\t\tthis.limits = initialLimits;\n\t\tthis.defaultLimits = { ...initialLimits };\n\t\tthis.settings = getBackgroundTaskSettings();\n\t\tthis.ensureSettingsSubscription();\n\t}\n\n\tprivate shouldNotify(): boolean {\n\t\treturn this.settings.notificationsEnabled;\n\t}\n\n\tprivate shouldEmitNotification(taskId: string): boolean {\n\t\tconst now = Date.now();\n\t\tconst bucket = this.notificationBucket.get(taskId);\n\t\tif (!bucket || now > bucket.reset) {\n\t\t\tthis.notificationBucket.set(taskId, { count: 1, reset: now + 60_000 });\n\t\t\treturn true;\n\t\t}\n\t\tif (bucket.count >= 10) {\n\t\t\treturn false;\n\t\t}\n\t\tbucket.count += 1;\n\t\treturn true;\n\t}\n\n\tprivate emitTaskNotification(payload: BackgroundTaskNotification): void {\n\t\tif (!this.shouldNotify() || !this.shouldEmitNotification(payload.taskId)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.emit(\"notification\", payload);\n\t\tif (this.settings.notificationsEnabled) {\n\t\t\tconst logMethod =\n\t\t\t\tpayload.level === \"warn\" ? this.logger.warn : this.logger.info;\n\t\t\tlogMethod.call(this.logger, payload.message, {\n\t\t\t\ttaskId: payload.taskId,\n\t\t\t\treason: payload.reason,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate maybeNotifyRestart(\n\t\ttask: BackgroundTask,\n\t\tpolicy: RestartPolicy,\n\t): void {\n\t\tif (!Number.isFinite(RESTART_NOTIFY_THRESHOLD)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!shouldNotifyRestart(policy)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"restart\",\n\t\t\tlevel: \"warn\",\n\t\t\tattempts: policy.attempts,\n\t\t\tmaxAttempts: policy.maxAttempts,\n\t\t\tmessage: `restarting (${policy.attempts}/${policy.maxAttempts})`,\n\t\t\treason:\n\t\t\t\ttask.exitCode !== undefined\n\t\t\t\t\t? `last exit ${task.exitCode}`\n\t\t\t\t\t: task.signal\n\t\t\t\t\t\t? `signal ${task.signal}`\n\t\t\t\t\t\t: undefined,\n\t\t});\n\t\tupdateNotifyThreshold(policy);\n\t}\n\n\tprivate notifyFailure(\n\t\ttask: BackgroundTask,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t): void {\n\t\tif (task.failureReason) {\n\t\t\treturn;\n\t\t}\n\t\tconst parts: string[] = [];\n\t\tif (code !== null && code !== undefined) {\n\t\t\tparts.push(`exit ${code}`);\n\t\t}\n\t\tif (signal) {\n\t\t\tparts.push(`signal ${signal}`);\n\t\t}\n\t\tthis.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"failure\",\n\t\t\tlevel: \"warn\",\n\t\t\treason: parts.join(\", \") || undefined,\n\t\t\tmessage: \"failed without restart\",\n\t\t});\n\t}\n\n\tconfigureLimits(overrides: Partial<BackgroundTaskLimits>): void {\n\t\tthis.limits = { ...this.limits, ...overrides };\n\t}\n\n\tresetLimits(): void {\n\t\tthis.limits = { ...this.defaultLimits };\n\t}\n\n\tprivate resolveTaskLimits(overrides?: TaskLimitOverrides): TaskRuntimeLimits {\n\t\tconst defaults = this.limits;\n\t\tconst maxBytes = 50 * 1024 * 1024;\n\t\tconst limit = overrides?.logSizeLimit;\n\t\tconst segments = overrides?.logSegments;\n\t\tconst retention = overrides?.retentionMs;\n\t\tconst rssLimit = overrides?.maxRssKb ?? defaults.maxRssKb ?? 0;\n\t\tconst cpuLimit = overrides?.maxCpuMs ?? defaults.maxCpuMs ?? 0;\n\t\tconst maxRssCap = 4 * 1024 * 1024; // 4 GB\n\t\tconst maxCpuCap = 24 * 60 * 60 * 1000; // 24h\n\t\treturn {\n\t\t\tlogSizeLimit: Math.min(\n\t\t\t\tMath.max(limit ?? defaults.logSizeLimit, 0),\n\t\t\t\tmaxBytes,\n\t\t\t),\n\t\t\tlogSegments: Math.min(Math.max(segments ?? defaults.logSegments, 0), 10),\n\t\t\tretentionMs: Math.min(\n\t\t\t\tMath.max(retention ?? defaults.retentionMs, 1_000),\n\t\t\t\t24 * 60 * 60 * 1000,\n\t\t\t),\n\t\t\tmaxRssKb: Math.min(Math.max(rssLimit, 0), maxRssCap),\n\t\t\tmaxCpuMs: Math.min(Math.max(cpuLimit, 0), maxCpuCap),\n\t\t};\n\t}\n\n\tprivate normalizeRestartOptions(\n\t\trestart?: TaskStartOptions[\"restart\"],\n\t): RestartPolicy | undefined {\n\t\tif (!restart) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn createRestartPolicy(restart, RESTART_NOTIFY_THRESHOLD);\n\t}\n\n\tprivate getLogDir(): string {\n\t\tconst expanded =\n\t\t\tresolveEnvPath(process.env.MAESTRO_BACKGROUND_LOG_DIR) ??\n\t\t\tPATHS.BACKGROUND_TASK_LOG_DIR;\n\t\tconst shouldRefresh =\n\t\t\tthis.logDir === null ||\n\t\t\tthis.logDirBase !== expanded ||\n\t\t\t!existsSync(this.logDir);\n\t\tif (shouldRefresh) {\n\t\t\tif (!existsSync(expanded)) {\n\t\t\t\tmkdirSync(expanded, { recursive: true });\n\t\t\t}\n\t\t\tthis.logDir = expanded;\n\t\t\tthis.logDirBase = expanded;\n\t\t}\n\t\tif (this.logDir === null) {\n\t\t\tthrow new ToolError(\"Failed to initialize background task log directory\");\n\t\t}\n\t\treturn this.logDir;\n\t}\n\n\tprivate createLogPath(id: string): string {\n\t\tconst dir = this.getLogDir();\n\t\treturn safejoin(dir, `${id}.log`);\n\t}\n\n\tprivate emitTaskTelemetry(\n\t\ttask: BackgroundTask,\n\t\tevent: \"started\" | \"restarted\" | \"exited\" | \"failed\" | \"stopped\",\n\t): void {\n\t\tconst failureReason = this.sanitizeFailureReason(task.failureReason);\n\t\tconst command = this.sanitizeLogSnippet(task.command);\n\t\trecordBackgroundTaskEvent({\n\t\t\tevent,\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand,\n\t\t\tshellMode: task.shellMode,\n\t\t\tcwd: task.cwd,\n\t\t\trestartAttempts: task.restartPolicy?.attempts ?? 0,\n\t\t\tlogTruncated: task.logTruncated ?? false,\n\t\t\texitCode: task.exitCode ?? undefined,\n\t\t\tsignal: task.signal ?? undefined,\n\t\t\tresourceUsage: task.resourceUsage,\n\t\t\tfailureReason,\n\t\t\tlimitBreach: task.lastLimitBreach,\n\t\t});\n\t}\n\n\tprivate generateTaskId(): string {\n\t\treturn `task-${Date.now()}-${randomUUID().slice(0, 8)}`;\n\t}\n\n\tprivate enforceCapacity(): void {\n\t\tconst running = [...this.tasks.values()].filter(\n\t\t\t(task) => task.status === \"running\" || task.status === \"restarting\",\n\t\t).length;\n\t\tif (running >= this.limits.maxTasks) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Cannot start background task: maximum of ${this.limits.maxTasks} running task(s) reached.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate scheduleCleanup(task: BackgroundTask): void {\n\t\tif (this.cleanupTimers.has(task.id)) {\n\t\t\treturn;\n\t\t}\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.cleanupTimers.delete(task.id);\n\t\t\tthis.removeTask(task.id);\n\t\t}, task.limits.retentionMs);\n\t\ttimer.unref();\n\t\tthis.cleanupTimers.set(task.id, timer);\n\t}\n\n\tprivate clearCleanupTimer(id: string): void {\n\t\tconst timer = this.cleanupTimers.get(id);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.cleanupTimers.delete(id);\n\t\t}\n\t}\n\n\tprivate removeTask(id: string, force = false): void {\n\t\tconst task = this.tasks.get(id);\n\t\tif (!task) {\n\t\t\treturn;\n\t\t}\n\t\tif (!force && (task.status === \"running\" || task.status === \"restarting\")) {\n\t\t\treturn;\n\t\t}\n\t\tthis.runtime.disposeTask(task);\n\t\tthis.tasks.delete(id);\n\t\tthis.clearCleanupTimer(id);\n\t\ttry {\n\t\t\tunlinkSync(task.logPath);\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t\tdeleteArchives(task.logPath, task.limits.logSegments);\n\t}\n\n\tprivate cleanupExpiredTasks(force = false): void {\n\t\tconst now = Date.now();\n\t\tfor (const [id, task] of this.tasks.entries()) {\n\t\t\tif (\n\t\t\t\t(task.status === \"running\" || task.status === \"restarting\") &&\n\t\t\t\t!force\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tforce ||\n\t\t\t\t!task.finishedAt ||\n\t\t\t\tnow - task.finishedAt >= task.limits.retentionMs\n\t\t\t) {\n\t\t\t\tthis.removeTask(id, true);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate tailLog(task: BackgroundTask, lines: number): string {\n\t\treturn tailLogs(\n\t\t\ttask.logPath,\n\t\t\ttask.limits.logSegments,\n\t\t\tLOG_TAIL_BYTES,\n\t\t\tlines,\n\t\t);\n\t}\n\n\tprivate previewLogLine(\n\t\ttask: BackgroundTask,\n\t\tlines: number,\n\t): string | undefined {\n\t\treturn previewLastLine(\n\t\t\ttask.logPath,\n\t\t\ttask.limits.logSegments,\n\t\t\tLOG_TAIL_BYTES,\n\t\t\tlines,\n\t\t\t(value) => this.sanitizeLogSnippet(value),\n\t\t);\n\t}\n\n\tprivate sanitizeLogSnippet(value: string): string {\n\t\tif (!value) {\n\t\t\treturn value;\n\t\t}\n\t\treturn redactSecrets(value, (secret) => this.maskSecret(secret));\n\t}\n\n\tprivate sanitizeFailureReason(reason?: string | null): string | undefined {\n\t\tif (!reason) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.sanitizeLogSnippet(reason);\n\t}\n\n\tprivate setFailureReason(task: BackgroundTask, reason: string): void {\n\t\ttask.failureReason = this.sanitizeLogSnippet(reason);\n\t}\n\n\tprivate maskSecret(_raw: string): string {\n\t\tthis.secretCounter += 1;\n\t\tconst token = randomBytes(4).toString(\"hex\");\n\t\treturn `[secret:${this.secretCounter.toString(36)}-${token}]`;\n\t}\n\n\tprivate summarizeCommand(command: string): string {\n\t\tconst trimmed = command.trim();\n\t\tconst limit = 80;\n\t\tconst buffer = 64;\n\t\tconst sliceEnd =\n\t\t\ttrimmed.length <= limit\n\t\t\t\t? trimmed.length\n\t\t\t\t: Math.min(trimmed.length, limit + buffer);\n\t\tconst window = trimmed.slice(0, sliceEnd);\n\t\tconst sanitized = this.sanitizeLogSnippet(window);\n\t\tif (sanitized.length <= limit) {\n\t\t\treturn sanitized;\n\t\t}\n\t\tconst truncated = sanitized.slice(0, limit - 1);\n\t\tconst lastOpen = truncated.lastIndexOf(\"[secret\");\n\t\tconst lastClose = truncated.lastIndexOf(\"]\");\n\t\tconst safeSlice =\n\t\t\tlastOpen !== -1 && (lastClose === -1 || lastClose < lastOpen)\n\t\t\t\t? truncated.slice(0, lastOpen)\n\t\t\t\t: truncated;\n\t\treturn `${safeSlice}…`;\n\t}\n\n\tprivate async waitForCompletion(\n\t\ttask: BackgroundTask,\n\t\ttimeoutMs: number,\n\t): Promise<boolean> {\n\t\tlet timeout: NodeJS.Timeout | undefined;\n\t\tconst result = await Promise.race([\n\t\t\ttask.completion.then(() => true),\n\t\t\tnew Promise<boolean>((resolve) => {\n\t\t\t\ttimeout = setTimeout(() => resolve(false), timeoutMs);\n\t\t\t}),\n\t\t]);\n\t\tif (timeout) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t\treturn result;\n\t}\n\n\tstart(command: string, options: TaskStartOptions = {}): BackgroundTask {\n\t\tthis.ensureSettingsSubscription();\n\t\tthis.cleanupExpiredTasks();\n\t\tthis.enforceCapacity();\n\t\tconst { cwd, env, useShell = false, restart } = options;\n\t\tconst id = this.generateTaskId();\n\t\tconst { resolvedCwd } = validateShellParams(command, cwd, env);\n\t\tconst resolvedEnv = resolveShellEnvironment(env, {\n\t\t\tworkspaceDir: process.cwd(),\n\t\t});\n\t\tconst logPath = this.createLogPath(id);\n\t\tconst taskLimits = this.resolveTaskLimits(options.limits);\n\t\tconst task: BackgroundTask = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tcwd: resolvedCwd,\n\t\t\tenv: resolvedEnv,\n\t\t\tstartedAt: Date.now(),\n\t\t\tpid: undefined,\n\t\t\tstatus: \"running\",\n\t\t\tlogPath,\n\t\t\tprocess: {} as BackgroundTask[\"process\"],\n\t\t\tcompletion: Promise.resolve(),\n\t\t\tshellMode: useShell ? \"shell\" : \"exec\",\n\t\t\trestartPolicy: this.normalizeRestartOptions(restart),\n\t\t\trestartTimer: null,\n\t\t\tlogTruncated: false,\n\t\t\tlimits: taskLimits,\n\t\t\tmonitoringMode: \"disabled\",\n\t\t};\n\n\t\tthis.tasks.set(id, task);\n\t\tthis.runtime.launchProcess(task);\n\t\treturn task;\n\t}\n\n\tgetTasks(): BackgroundTask[] {\n\t\tthis.cleanupExpiredTasks();\n\t\treturn [...this.tasks.values()];\n\t}\n\n\tgetTask(id: string): BackgroundTask | undefined {\n\t\tthis.cleanupExpiredTasks();\n\t\treturn this.tasks.get(id);\n\t}\n\n\tgetHealthSnapshot(options?: {\n\t\tmaxEntries?: number;\n\t\tlogLines?: number;\n\t\thistoryLimit?: number;\n\t}): BackgroundTaskHealth | null {\n\t\tthis.ensureSettingsSubscription();\n\t\tconst tasks = this.getTasks();\n\t\tconst maxEntries = Math.max(1, options?.maxEntries ?? 3);\n\t\tconst logLines = Math.max(1, options?.logLines ?? 1);\n\t\tconst includeDetails = this.settings.statusDetailsEnabled;\n\t\tconst historyLimit = Math.max(1, options?.historyLimit ?? 10);\n\t\tconst rawHistory = includeDetails\n\t\t\t? getBackgroundTaskHistory(historyLimit)\n\t\t\t: [];\n\t\tif (tasks.length === 0 && rawHistory.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst sorted = [...tasks].sort((a, b) => b.startedAt - a.startedAt);\n\t\tconst detailedEntries = includeDetails\n\t\t\t? sorted.slice(0, maxEntries).map((task) => {\n\t\t\t\t\tconst issues: string[] = [];\n\t\t\t\t\tif (task.failureReason) {\n\t\t\t\t\t\tissues.push(task.failureReason);\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\ttask.restartPolicy &&\n\t\t\t\t\t\tNumber.isFinite(RESTART_NOTIFY_THRESHOLD) &&\n\t\t\t\t\t\ttask.restartPolicy.attempts >= RESTART_NOTIFY_THRESHOLD\n\t\t\t\t\t) {\n\t\t\t\t\t\tissues.push(\n\t\t\t\t\t\t\t`Restart attempts ${task.restartPolicy.attempts}/${task.restartPolicy.maxAttempts}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (task.logTruncated) {\n\t\t\t\t\t\tissues.push(\"Logs truncated\");\n\t\t\t\t\t}\n\t\t\t\t\tconst restarts = task.restartPolicy\n\t\t\t\t\t\t? `${task.restartPolicy.attempts}/${task.restartPolicy.maxAttempts}`\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tconst durationMs = (task.finishedAt ?? Date.now()) - task.startedAt;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: task.id,\n\t\t\t\t\t\tstatus: task.status,\n\t\t\t\t\t\tsummary: this.sanitizeLogSnippet(formatTaskSummary(task)),\n\t\t\t\t\t\tcommand: this.summarizeCommand(task.command),\n\t\t\t\t\t\trestarts,\n\t\t\t\t\t\tissues,\n\t\t\t\t\t\tlastLogLine: this.previewLogLine(task, logLines),\n\t\t\t\t\t\tlogTruncated: task.logTruncated ?? false,\n\t\t\t\t\t\tdurationSeconds: Math.max(1, Math.round(durationMs / 1000)),\n\t\t\t\t\t};\n\t\t\t\t})\n\t\t\t: [];\n\t\tconst history: BackgroundTaskHistoryEntry[] = rawHistory.map((entry) => ({\n\t\t\tevent: entry.event,\n\t\t\ttaskId: entry.taskId,\n\t\t\tstatus: entry.status as BackgroundTaskStatus,\n\t\t\tcommand: this.summarizeCommand(entry.command),\n\t\t\ttimestamp: entry.timestamp,\n\t\t\trestartAttempts: entry.restartAttempts,\n\t\t\tfailureReason: entry.failureReason\n\t\t\t\t? this.sanitizeLogSnippet(entry.failureReason)\n\t\t\t\t: undefined,\n\t\t\tlimitBreach: entry.limitBreach,\n\t\t}));\n\t\treturn {\n\t\t\ttotal: tasks.length,\n\t\t\trunning: tasks.filter((task) => task.status === \"running\").length,\n\t\t\trestarting: tasks.filter((task) => task.status === \"restarting\").length,\n\t\t\tfailed: tasks.filter((task) => task.status === \"failed\").length,\n\t\t\tentries: detailedEntries,\n\t\t\ttruncated: includeDetails && tasks.length > detailedEntries.length,\n\t\t\tnotificationsEnabled: this.settings.notificationsEnabled,\n\t\t\tdetailsRedacted: !includeDetails,\n\t\t\thistory,\n\t\t\thistoryTruncated: includeDetails && rawHistory.length === historyLimit,\n\t\t};\n\t}\n\n\tasync stopTask(\n\t\tid: string,\n\t): Promise<{ task: BackgroundTask; stopped: boolean } | null> {\n\t\tconst task = this.tasks.get(id);\n\t\tif (!task) {\n\t\t\treturn null;\n\t\t}\n\t\ttask.stopRequested = true;\n\t\tthis.runtime.disableRestart(task);\n\t\tif (task.status === \"restarting\") {\n\t\t\tthis.runtime.stopUsageMonitor(task);\n\t\t\ttask.status = \"stopped\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.scheduleCleanup(task);\n\t\t\treturn { task, stopped: true };\n\t\t}\n\t\tif (task.status !== \"running\") {\n\t\t\treturn { task, stopped: false };\n\t\t}\n\t\tif (!task.pid) {\n\t\t\treturn { task, stopped: false };\n\t\t}\n\n\t\tkillProcessTree(task.pid);\n\t\tconst stopped = await this.waitForCompletion(task, 2000);\n\t\treturn { task, stopped };\n\t}\n\n\tasync stopAll(): Promise<void> {\n\t\tconst stops = [...this.tasks.keys()].map((id) => this.stopTask(id));\n\t\tawait Promise.all(stops);\n\t\tthis.cleanupExpiredTasks(true);\n\t}\n\n\tclear(): void {\n\t\tthis.unsubscribeSettings?.();\n\t\tthis.unsubscribeSettings = undefined;\n\t\tfor (const id of [...this.tasks.keys()]) {\n\t\t\tthis.removeTask(id, true);\n\t\t}\n\t\tthis.tasks.clear();\n\t\tfor (const timer of this.cleanupTimers.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tthis.cleanupTimers.clear();\n\t}\n\n\tgetLogs(taskId: string, lines: number): string {\n\t\tconst task = this.tasks.get(taskId);\n\t\tif (!task) {\n\t\t\tthrow new ToolError(`Task not found or logs expired: ${taskId}`);\n\t\t}\n\t\tconst text = this.tailLog(task, lines);\n\t\tif (!task.logTruncated) {\n\t\t\treturn text;\n\t\t}\n\t\tconst limitKb = Math.round(task.limits.logSizeLimit / 1024);\n\t\tconst notice = `Log output truncated at ${limitKb} KB.`;\n\t\treturn `${text}\\n\\n${notice}`;\n\t}\n}\n\nexport const backgroundTaskManager = new BackgroundTaskManager();\n\n// Re-export types used by downstream consumers\nexport type {\n\tBackgroundTaskHealth,\n\tBackgroundTaskHealthEntry,\n\tBackgroundTaskNotification,\n} from \"./background/task-types.js\";\nexport { backgroundTasksTool } from \"./background/tool-handler.js\";\n\nexport function formatTaskFailures(): string | null {\n\tconst tasks = backgroundTaskManager.getTasks();\n\tconst failedTasks = tasks.filter((task) => task.status === \"failed\");\n\n\tif (failedTasks.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Only show recent failures (last 5 minutes) to avoid nagging about old news\n\tconst RECENT_THRESHOLD = 5 * 60 * 1000;\n\tconst now = Date.now();\n\tconst recentFailures = failedTasks.filter((task) => {\n\t\tif (!task.finishedAt) return false;\n\t\treturn now - task.finishedAt < RECENT_THRESHOLD;\n\t});\n\n\tif (recentFailures.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst lines = [\"# ⚠️ Background Task Alerts\"];\n\tfor (const task of recentFailures) {\n\t\tconst reason = task.failureReason\n\t\t\t? `Reason: ${task.failureReason}`\n\t\t\t: typeof task.exitCode === \"number\" && task.exitCode !== 0\n\t\t\t\t? `Exit Code: ${task.exitCode}`\n\t\t\t\t: \"Exited unexpectedly\";\n\t\tlines.push(`- Task \"${task.command}\" (${task.id}) stopped. ${reason}`);\n\t\t// Add a hint about logs\n\t\tlines.push(\n\t\t\t` (Use background_tasks action=logs taskId=${task.id} to investigate)`,\n\t\t);\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
1
+ {"version":3,"file":"background-tasks.js","sourceRoot":"","sources":["../../src/tools/background-tasks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Background Tasks Tool - Long-running process management with resource monitoring\n *\n * This module provides infrastructure for running, monitoring, and managing\n * background processes (dev servers, watchers, build tasks, etc.). It's designed\n * for reliability and observability in an AI agent context where processes may\n * run for extended periods without direct human oversight.\n *\n * ## Architecture Overview\n *\n * ```\n * ┌─────────────────────────────────────────────────────────────────────┐\n * │ BackgroundTaskManager │\n * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐ │\n * │ │ Task Start │→ │ Process │→ │ Resource Monitor │ │\n * │ │ & Spawn │ │ Lifecycle │ │ (CPU/Memory Polling) │ │\n * │ └─────────────┘ └─────────────┘ └─────────────────────────────┘ │\n * │ ↓ ↓ ↓ │\n * │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────────┐ │\n * │ │ Log Writer │ │ Restart │ │ Limit Enforcement │ │\n * │ │ (Rotating) │ │ Controller │ │ (Kill on Breach) │ │\n * │ └─────────────┘ └─────────────┘ └─────────────────────────────┘ │\n * └─────────────────────────────────────────────────────────────────────┘\n * ```\n *\n * ## Key Features\n *\n * ### 1. Resource Monitoring\n * Polls /proc/<pid>/stat (Linux) or ps (macOS) to track:\n * - Resident Set Size (RSS) memory usage\n * - User and system CPU time\n * - Enforces configurable limits with automatic termination\n *\n * ### 2. Automatic Restart\n * Configurable restart policy with:\n * - Fixed or exponential backoff delays\n * - Jitter to prevent thundering herd\n * - Maximum attempt limits\n * - Notifications on restart threshold\n *\n * ### 3. Log Management\n * - Per-task log files with configurable size limits\n * - Automatic rotation with gzip compression\n * - Tail access for recent output retrieval\n * - Secret redaction in log output\n *\n * ### 4. Lifecycle Management\n * - Graceful shutdown with process tree killing\n * - Automatic cleanup of finished task metadata\n * - Task retention period for post-mortem analysis\n *\n * ## Configuration via Environment Variables\n *\n * | Variable | Description | Default |\n * |---------------------------------------|----------------------------------|------------|\n * | MAESTRO_BACKGROUND_TASK_MAX | Max concurrent tasks | 4 |\n * | MAESTRO_BACKGROUND_TASK_LOG_BYTES | Per-task log size limit | 5MB |\n * | MAESTRO_BACKGROUND_TASK_RETENTION_MS | How long to keep finished tasks | 10 min |\n * | MAESTRO_BACKGROUND_TASK_MAX_RSS_KB | Memory limit per task | 768MB |\n * | MAESTRO_BACKGROUND_TASK_MAX_CPU_MS | CPU time limit per task | 10 min |\n * | MAESTRO_BACKGROUND_TASK_TICKS | Clock ticks per second (Linux) | 100 |\n *\n * @module tools/background-tasks\n */\n\nimport { randomBytes, randomUUID } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport { existsSync, mkdirSync, unlinkSync } from \"node:fs\";\n\nimport { PATHS } from \"../config/constants.js\";\nimport {\n\ttype BackgroundTaskSettings,\n\tgetBackgroundTaskSettings,\n\tsubscribeBackgroundTaskSettings,\n} from \"../runtime/background-settings.js\";\nimport {\n\tgetBackgroundTaskHistory,\n\trecordBackgroundTaskEvent,\n} from \"../telemetry.js\";\nimport {\n\treadNonNegativeInt,\n\treadPositiveInt,\n\treadThresholdEnv,\n} from \"../utils/env-parser.js\";\nimport { createLogger } from \"../utils/logger.js\";\nimport { resolveEnvPath } from \"../utils/path-expansion.js\";\nimport { safejoin } from \"../utils/path-validation.js\";\nimport {\n\tredactSecrets,\n\tsanitizeWithStaticMask,\n} from \"../utils/secret-redactor.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport {\n\ttype RestartPolicy,\n\tcreateRestartPolicy,\n\tshouldNotifyRestart,\n\tupdateNotifyThreshold,\n} from \"./background/index.js\";\nimport {\n\tdeleteArchives,\n\tpreviewLastLine,\n\ttailLogs,\n} from \"./background/log-files.js\";\nimport { BackgroundTaskRuntime } from \"./background/task-runtime.js\";\nimport {\n\ttype BackgroundTask,\n\ttype BackgroundTaskHealth,\n\ttype BackgroundTaskHistoryEntry,\n\ttype BackgroundTaskLimits,\n\ttype BackgroundTaskNotification,\n\ttype BackgroundTaskStatus,\n\ttype ResourceLimitBreach,\n\ttype TaskLimitOverrides,\n\ttype TaskRuntimeLimits,\n\ttype TaskStartOptions,\n\tformatTaskSummary,\n} from \"./background/task-types.js\";\nimport { killProcessTree, validateShellParams } from \"./shell-utils.js\";\nimport { ToolError } from \"./tool-dsl.js\";\n\nconst LOG_TAIL_BYTES = 200_000;\nconst DEFAULT_RSS_KB = readNonNegativeInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX_RSS_KB\",\n\t768 * 1024,\n);\nconst DEFAULT_CPU_MS = readNonNegativeInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX_CPU_MS\",\n\t10 * 60 * 1000,\n);\nconst RESTART_NOTIFY_THRESHOLD = readThresholdEnv(\n\t\"MAESTRO_BACKGROUND_TASK_NOTIFY_RESTARTS\",\n\t2,\n);\n\nconst MAX_CONCURRENT_TASKS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_MAX\",\n\t4,\n\t1,\n);\nconst MAX_LOG_FILE_BYTES = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_LOG_BYTES\",\n\t5 * 1024 * 1024,\n\t50_000,\n);\nconst TASK_RETENTION_MS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_RETENTION_MS\",\n\t10 * 60 * 1000,\n\t1_000,\n);\nconst MAX_LOG_SEGMENTS = readPositiveInt(\n\t\"MAESTRO_BACKGROUND_TASK_LOG_SEGMENTS\",\n\t2,\n\t0,\n);\n// Re-export for backwards compatibility\nexport {\n\textractProcStatFields,\n\ttype TaskResourceUsage,\n} from \"./background/index.js\";\n\nexport { evaluateResourceLimitBreach } from \"./background/resource-limits.js\";\n\nclass BackgroundTaskManager extends EventEmitter {\n\tprivate limits: BackgroundTaskLimits;\n\tprivate readonly defaultLimits: BackgroundTaskLimits;\n\tprivate tasks = new Map<string, BackgroundTask>();\n\tprivate cleanupTimers = new Map<string, NodeJS.Timeout>();\n\tprivate logDir: string | null = null;\n\tprivate logDirBase: string | null = null;\n\tprivate notificationBucket = new Map<\n\t\tstring,\n\t\t{ count: number; reset: number }\n\t>();\n\tprivate settings: BackgroundTaskSettings;\n\tprivate unsubscribeSettings?: () => void;\n\tprivate secretCounter = 0;\n\tprivate readonly logger = createLogger(\"background-tasks\");\n\tprivate readonly runtime = new BackgroundTaskRuntime({\n\t\temitTaskNotification: (payload) => this.emitTaskNotification(payload),\n\t\temitTaskTelemetry: (task, event) => this.emitTaskTelemetry(task, event),\n\t\tmaybeNotifyRestart: (task, policy) => this.maybeNotifyRestart(task, policy),\n\t\tnotifyFailure: (task, code, signal) =>\n\t\t\tthis.notifyFailure(task, code, signal),\n\t\tscheduleCleanup: (task) => this.scheduleCleanup(task),\n\t\tsetFailureReason: (task, reason) => this.setFailureReason(task, reason),\n\t});\n\n\tprivate ensureSettingsSubscription(): void {\n\t\tif (this.unsubscribeSettings) {\n\t\t\treturn;\n\t\t}\n\t\tthis.unsubscribeSettings = subscribeBackgroundTaskSettings((next) => {\n\t\t\tthis.settings = next;\n\t\t});\n\t}\n\n\tconstructor() {\n\t\tsuper();\n\t\tconst initialLimits: BackgroundTaskLimits = {\n\t\t\tmaxTasks: MAX_CONCURRENT_TASKS,\n\t\t\tlogSizeLimit: MAX_LOG_FILE_BYTES,\n\t\t\tretentionMs: TASK_RETENTION_MS,\n\t\t\tlogSegments: MAX_LOG_SEGMENTS,\n\t\t\tmaxRssKb: DEFAULT_RSS_KB,\n\t\t\tmaxCpuMs: DEFAULT_CPU_MS,\n\t\t};\n\t\tthis.limits = initialLimits;\n\t\tthis.defaultLimits = { ...initialLimits };\n\t\tthis.settings = getBackgroundTaskSettings();\n\t\tthis.ensureSettingsSubscription();\n\t}\n\n\tprivate shouldNotify(): boolean {\n\t\treturn this.settings.notificationsEnabled;\n\t}\n\n\tprivate shouldEmitNotification(taskId: string): boolean {\n\t\tconst now = Date.now();\n\t\tconst bucket = this.notificationBucket.get(taskId);\n\t\tif (!bucket || now > bucket.reset) {\n\t\t\tthis.notificationBucket.set(taskId, { count: 1, reset: now + 60_000 });\n\t\t\treturn true;\n\t\t}\n\t\tif (bucket.count >= 10) {\n\t\t\treturn false;\n\t\t}\n\t\tbucket.count += 1;\n\t\treturn true;\n\t}\n\n\tprivate emitTaskNotification(payload: BackgroundTaskNotification): void {\n\t\tif (!this.shouldNotify() || !this.shouldEmitNotification(payload.taskId)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.emit(\"notification\", payload);\n\t\tif (this.settings.notificationsEnabled) {\n\t\t\tconst logMethod =\n\t\t\t\tpayload.level === \"warn\" ? this.logger.warn : this.logger.info;\n\t\t\tlogMethod.call(this.logger, payload.message, {\n\t\t\t\ttaskId: payload.taskId,\n\t\t\t\treason: payload.reason,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate maybeNotifyRestart(\n\t\ttask: BackgroundTask,\n\t\tpolicy: RestartPolicy,\n\t): void {\n\t\tif (!Number.isFinite(RESTART_NOTIFY_THRESHOLD)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!shouldNotifyRestart(policy)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"restart\",\n\t\t\tlevel: \"warn\",\n\t\t\tattempts: policy.attempts,\n\t\t\tmaxAttempts: policy.maxAttempts,\n\t\t\tmessage: `restarting (${policy.attempts}/${policy.maxAttempts})`,\n\t\t\treason:\n\t\t\t\ttask.exitCode !== undefined\n\t\t\t\t\t? `last exit ${task.exitCode}`\n\t\t\t\t\t: task.signal\n\t\t\t\t\t\t? `signal ${task.signal}`\n\t\t\t\t\t\t: undefined,\n\t\t});\n\t\tupdateNotifyThreshold(policy);\n\t}\n\n\tprivate notifyFailure(\n\t\ttask: BackgroundTask,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t): void {\n\t\tif (task.failureReason) {\n\t\t\treturn;\n\t\t}\n\t\tconst parts: string[] = [];\n\t\tif (code !== null && code !== undefined) {\n\t\t\tparts.push(`exit ${code}`);\n\t\t}\n\t\tif (signal) {\n\t\t\tparts.push(`signal ${signal}`);\n\t\t}\n\t\tthis.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"failure\",\n\t\t\tlevel: \"warn\",\n\t\t\treason: parts.join(\", \") || undefined,\n\t\t\tmessage: \"failed without restart\",\n\t\t});\n\t}\n\n\tconfigureLimits(overrides: Partial<BackgroundTaskLimits>): void {\n\t\tthis.limits = { ...this.limits, ...overrides };\n\t}\n\n\tresetLimits(): void {\n\t\tthis.limits = { ...this.defaultLimits };\n\t}\n\n\tprivate resolveTaskLimits(overrides?: TaskLimitOverrides): TaskRuntimeLimits {\n\t\tconst defaults = this.limits;\n\t\tconst maxBytes = 50 * 1024 * 1024;\n\t\tconst limit = overrides?.logSizeLimit;\n\t\tconst segments = overrides?.logSegments;\n\t\tconst retention = overrides?.retentionMs;\n\t\tconst rssLimit = overrides?.maxRssKb ?? defaults.maxRssKb ?? 0;\n\t\tconst cpuLimit = overrides?.maxCpuMs ?? defaults.maxCpuMs ?? 0;\n\t\tconst maxRssCap = 4 * 1024 * 1024; // 4 GB\n\t\tconst maxCpuCap = 24 * 60 * 60 * 1000; // 24h\n\t\treturn {\n\t\t\tlogSizeLimit: Math.min(\n\t\t\t\tMath.max(limit ?? defaults.logSizeLimit, 0),\n\t\t\t\tmaxBytes,\n\t\t\t),\n\t\t\tlogSegments: Math.min(Math.max(segments ?? defaults.logSegments, 0), 10),\n\t\t\tretentionMs: Math.min(\n\t\t\t\tMath.max(retention ?? defaults.retentionMs, 1_000),\n\t\t\t\t24 * 60 * 60 * 1000,\n\t\t\t),\n\t\t\tmaxRssKb: Math.min(Math.max(rssLimit, 0), maxRssCap),\n\t\t\tmaxCpuMs: Math.min(Math.max(cpuLimit, 0), maxCpuCap),\n\t\t};\n\t}\n\n\tprivate normalizeRestartOptions(\n\t\trestart?: TaskStartOptions[\"restart\"],\n\t): RestartPolicy | undefined {\n\t\tif (!restart) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn createRestartPolicy(restart, RESTART_NOTIFY_THRESHOLD);\n\t}\n\n\tprivate getLogDir(): string {\n\t\tconst expanded =\n\t\t\tresolveEnvPath(process.env.MAESTRO_BACKGROUND_LOG_DIR) ??\n\t\t\tPATHS.BACKGROUND_TASK_LOG_DIR;\n\t\tconst shouldRefresh =\n\t\t\tthis.logDir === null ||\n\t\t\tthis.logDirBase !== expanded ||\n\t\t\t!existsSync(this.logDir);\n\t\tif (shouldRefresh) {\n\t\t\tif (!existsSync(expanded)) {\n\t\t\t\tmkdirSync(expanded, { recursive: true });\n\t\t\t}\n\t\t\tthis.logDir = expanded;\n\t\t\tthis.logDirBase = expanded;\n\t\t}\n\t\tif (this.logDir === null) {\n\t\t\tthrow new ToolError(\"Failed to initialize background task log directory\");\n\t\t}\n\t\treturn this.logDir;\n\t}\n\n\tprivate createLogPath(id: string): string {\n\t\tconst dir = this.getLogDir();\n\t\treturn safejoin(dir, `${id}.log`);\n\t}\n\n\tprivate emitTaskTelemetry(\n\t\ttask: BackgroundTask,\n\t\tevent: \"started\" | \"restarted\" | \"exited\" | \"failed\" | \"stopped\",\n\t): void {\n\t\tconst failureReason = this.sanitizeFailureReason(task.failureReason);\n\t\tconst command = this.sanitizeLogSnippet(task.command);\n\t\trecordBackgroundTaskEvent({\n\t\t\tevent,\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand,\n\t\t\tshellMode: task.shellMode,\n\t\t\tcwd: task.cwd,\n\t\t\trestartAttempts: task.restartPolicy?.attempts ?? 0,\n\t\t\tlogTruncated: task.logTruncated ?? false,\n\t\t\texitCode: task.exitCode ?? undefined,\n\t\t\tsignal: task.signal ?? undefined,\n\t\t\tresourceUsage: task.resourceUsage,\n\t\t\tfailureReason,\n\t\t\tlimitBreach: task.lastLimitBreach,\n\t\t});\n\t}\n\n\tprivate generateTaskId(): string {\n\t\treturn `task-${Date.now()}-${randomUUID().slice(0, 8)}`;\n\t}\n\n\tprivate enforceCapacity(): void {\n\t\tconst running = [...this.tasks.values()].filter(\n\t\t\t(task) => task.status === \"running\" || task.status === \"restarting\",\n\t\t).length;\n\t\tif (running >= this.limits.maxTasks) {\n\t\t\tthrow new ToolError(\n\t\t\t\t`Cannot start background task: maximum of ${this.limits.maxTasks} running task(s) reached.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate scheduleCleanup(task: BackgroundTask): void {\n\t\tif (this.cleanupTimers.has(task.id)) {\n\t\t\treturn;\n\t\t}\n\t\tconst timer = setTimeout(() => {\n\t\t\tthis.cleanupTimers.delete(task.id);\n\t\t\tthis.removeTask(task.id);\n\t\t}, task.limits.retentionMs);\n\t\ttimer.unref();\n\t\tthis.cleanupTimers.set(task.id, timer);\n\t}\n\n\tprivate clearCleanupTimer(id: string): void {\n\t\tconst timer = this.cleanupTimers.get(id);\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\tthis.cleanupTimers.delete(id);\n\t\t}\n\t}\n\n\tprivate removeTask(id: string, force = false): void {\n\t\tconst task = this.tasks.get(id);\n\t\tif (!task) {\n\t\t\treturn;\n\t\t}\n\t\tif (!force && (task.status === \"running\" || task.status === \"restarting\")) {\n\t\t\treturn;\n\t\t}\n\t\tthis.runtime.disposeTask(task);\n\t\tthis.tasks.delete(id);\n\t\tthis.clearCleanupTimer(id);\n\t\ttry {\n\t\t\tunlinkSync(task.logPath);\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t\tdeleteArchives(task.logPath, task.limits.logSegments);\n\t}\n\n\tprivate cleanupExpiredTasks(force = false): void {\n\t\tconst now = Date.now();\n\t\tfor (const [id, task] of this.tasks.entries()) {\n\t\t\tif (\n\t\t\t\t(task.status === \"running\" || task.status === \"restarting\") &&\n\t\t\t\t!force\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tforce ||\n\t\t\t\t!task.finishedAt ||\n\t\t\t\tnow - task.finishedAt >= task.limits.retentionMs\n\t\t\t) {\n\t\t\t\tthis.removeTask(id, true);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate tailLog(task: BackgroundTask, lines: number): string {\n\t\treturn tailLogs(\n\t\t\ttask.logPath,\n\t\t\ttask.limits.logSegments,\n\t\t\tLOG_TAIL_BYTES,\n\t\t\tlines,\n\t\t);\n\t}\n\n\tprivate previewLogLine(\n\t\ttask: BackgroundTask,\n\t\tlines: number,\n\t): string | undefined {\n\t\treturn previewLastLine(\n\t\t\ttask.logPath,\n\t\t\ttask.limits.logSegments,\n\t\t\tLOG_TAIL_BYTES,\n\t\t\tlines,\n\t\t\t(value) => this.sanitizeLogSnippet(value),\n\t\t);\n\t}\n\n\tprivate sanitizeLogSnippet(value: string): string {\n\t\tif (!value) {\n\t\t\treturn value;\n\t\t}\n\t\treturn redactSecrets(value, (secret) => this.maskSecret(secret));\n\t}\n\n\tprivate sanitizeFailureReason(reason?: string | null): string | undefined {\n\t\tif (!reason) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.sanitizeLogSnippet(reason);\n\t}\n\n\tprivate setFailureReason(task: BackgroundTask, reason: string): void {\n\t\ttask.failureReason = this.sanitizeLogSnippet(reason);\n\t}\n\n\tprivate maskSecret(_raw: string): string {\n\t\tthis.secretCounter += 1;\n\t\tconst token = randomBytes(4).toString(\"hex\");\n\t\treturn `[secret:${this.secretCounter.toString(36)}-${token}]`;\n\t}\n\n\tprivate summarizeCommand(command: string): string {\n\t\tconst trimmed = command.trim();\n\t\tconst limit = 80;\n\t\tconst buffer = 64;\n\t\tconst sliceEnd =\n\t\t\ttrimmed.length <= limit\n\t\t\t\t? trimmed.length\n\t\t\t\t: Math.min(trimmed.length, limit + buffer);\n\t\tconst window = trimmed.slice(0, sliceEnd);\n\t\tconst sanitized = this.sanitizeLogSnippet(window);\n\t\tif (sanitized.length <= limit) {\n\t\t\treturn sanitized;\n\t\t}\n\t\tconst truncated = sanitized.slice(0, limit - 1);\n\t\tconst lastOpen = truncated.lastIndexOf(\"[secret\");\n\t\tconst lastClose = truncated.lastIndexOf(\"]\");\n\t\tconst safeSlice =\n\t\t\tlastOpen !== -1 && (lastClose === -1 || lastClose < lastOpen)\n\t\t\t\t? truncated.slice(0, lastOpen)\n\t\t\t\t: truncated;\n\t\treturn `${safeSlice}…`;\n\t}\n\n\tprivate async waitForCompletion(\n\t\ttask: BackgroundTask,\n\t\ttimeoutMs: number,\n\t): Promise<boolean> {\n\t\tlet timeout: NodeJS.Timeout | undefined;\n\t\tconst result = await Promise.race([\n\t\t\ttask.completion.then(() => true),\n\t\t\tnew Promise<boolean>((resolve) => {\n\t\t\t\ttimeout = setTimeout(() => resolve(false), timeoutMs);\n\t\t\t}),\n\t\t]);\n\t\tif (timeout) {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t\treturn result;\n\t}\n\n\tstart(command: string, options: TaskStartOptions = {}): BackgroundTask {\n\t\tthis.ensureSettingsSubscription();\n\t\tthis.cleanupExpiredTasks();\n\t\tthis.enforceCapacity();\n\t\tconst { cwd, env, useShell = false, restart } = options;\n\t\tconst id = this.generateTaskId();\n\t\tconst { resolvedCwd } = validateShellParams(command, cwd, env);\n\t\tconst resolvedEnv = resolveShellEnvironment(env, {\n\t\t\tworkspaceDir: process.cwd(),\n\t\t});\n\t\tconst logPath = this.createLogPath(id);\n\t\tconst taskLimits = this.resolveTaskLimits(options.limits);\n\t\tconst task: BackgroundTask = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tcwd: resolvedCwd,\n\t\t\tenv: resolvedEnv,\n\t\t\tstartedAt: Date.now(),\n\t\t\tpid: undefined,\n\t\t\tstatus: \"running\",\n\t\t\tlogPath,\n\t\t\tprocess: {} as BackgroundTask[\"process\"],\n\t\t\tcompletion: Promise.resolve(),\n\t\t\tshellMode: useShell ? \"shell\" : \"exec\",\n\t\t\trestartPolicy: this.normalizeRestartOptions(restart),\n\t\t\trestartTimer: null,\n\t\t\tlogTruncated: false,\n\t\t\tlimits: taskLimits,\n\t\t\tmonitoringMode: \"disabled\",\n\t\t};\n\n\t\tthis.tasks.set(id, task);\n\t\tthis.runtime.launchProcess(task);\n\t\treturn task;\n\t}\n\n\tgetTasks(): BackgroundTask[] {\n\t\tthis.cleanupExpiredTasks();\n\t\treturn [...this.tasks.values()];\n\t}\n\n\tgetTask(id: string): BackgroundTask | undefined {\n\t\tthis.cleanupExpiredTasks();\n\t\treturn this.tasks.get(id);\n\t}\n\n\tgetHealthSnapshot(options?: {\n\t\tmaxEntries?: number;\n\t\tlogLines?: number;\n\t\thistoryLimit?: number;\n\t}): BackgroundTaskHealth | null {\n\t\tthis.ensureSettingsSubscription();\n\t\tconst tasks = this.getTasks();\n\t\tconst maxEntries = Math.max(1, options?.maxEntries ?? 3);\n\t\tconst logLines = Math.max(1, options?.logLines ?? 1);\n\t\tconst includeDetails = this.settings.statusDetailsEnabled;\n\t\tconst historyLimit = Math.max(1, options?.historyLimit ?? 10);\n\t\tconst rawHistory = includeDetails\n\t\t\t? getBackgroundTaskHistory(historyLimit)\n\t\t\t: [];\n\t\tif (tasks.length === 0 && rawHistory.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst sorted = [...tasks].sort((a, b) => b.startedAt - a.startedAt);\n\t\tconst detailedEntries = includeDetails\n\t\t\t? sorted.slice(0, maxEntries).map((task) => {\n\t\t\t\t\tconst issues: string[] = [];\n\t\t\t\t\tif (task.failureReason) {\n\t\t\t\t\t\tissues.push(task.failureReason);\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\ttask.restartPolicy &&\n\t\t\t\t\t\tNumber.isFinite(RESTART_NOTIFY_THRESHOLD) &&\n\t\t\t\t\t\ttask.restartPolicy.attempts >= RESTART_NOTIFY_THRESHOLD\n\t\t\t\t\t) {\n\t\t\t\t\t\tissues.push(\n\t\t\t\t\t\t\t`Restart attempts ${task.restartPolicy.attempts}/${task.restartPolicy.maxAttempts}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (task.logTruncated) {\n\t\t\t\t\t\tissues.push(\"Logs truncated\");\n\t\t\t\t\t}\n\t\t\t\t\tconst restarts = task.restartPolicy\n\t\t\t\t\t\t? `${task.restartPolicy.attempts}/${task.restartPolicy.maxAttempts}`\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\tconst durationMs = (task.finishedAt ?? Date.now()) - task.startedAt;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: task.id,\n\t\t\t\t\t\tstatus: task.status,\n\t\t\t\t\t\tsummary: this.sanitizeLogSnippet(formatTaskSummary(task)),\n\t\t\t\t\t\tcommand: this.summarizeCommand(task.command),\n\t\t\t\t\t\trestarts,\n\t\t\t\t\t\tissues,\n\t\t\t\t\t\tlastLogLine: this.previewLogLine(task, logLines),\n\t\t\t\t\t\tlogTruncated: task.logTruncated ?? false,\n\t\t\t\t\t\tdurationSeconds: Math.max(1, Math.round(durationMs / 1000)),\n\t\t\t\t\t};\n\t\t\t\t})\n\t\t\t: [];\n\t\tconst history: BackgroundTaskHistoryEntry[] = rawHistory.map((entry) => ({\n\t\t\tevent: entry.event,\n\t\t\ttaskId: entry.taskId,\n\t\t\tstatus: entry.status as BackgroundTaskStatus,\n\t\t\tcommand: this.summarizeCommand(entry.command),\n\t\t\ttimestamp: entry.timestamp,\n\t\t\trestartAttempts: entry.restartAttempts,\n\t\t\tfailureReason: entry.failureReason\n\t\t\t\t? this.sanitizeLogSnippet(entry.failureReason)\n\t\t\t\t: undefined,\n\t\t\tlimitBreach: entry.limitBreach,\n\t\t}));\n\t\treturn {\n\t\t\ttotal: tasks.length,\n\t\t\trunning: tasks.filter((task) => task.status === \"running\").length,\n\t\t\trestarting: tasks.filter((task) => task.status === \"restarting\").length,\n\t\t\tfailed: tasks.filter((task) => task.status === \"failed\").length,\n\t\t\tentries: detailedEntries,\n\t\t\ttruncated: includeDetails && tasks.length > detailedEntries.length,\n\t\t\tnotificationsEnabled: this.settings.notificationsEnabled,\n\t\t\tdetailsRedacted: !includeDetails,\n\t\t\thistory,\n\t\t\thistoryTruncated: includeDetails && rawHistory.length === historyLimit,\n\t\t};\n\t}\n\n\tasync stopTask(\n\t\tid: string,\n\t): Promise<{ task: BackgroundTask; stopped: boolean } | null> {\n\t\tconst task = this.tasks.get(id);\n\t\tif (!task) {\n\t\t\treturn null;\n\t\t}\n\t\ttask.stopRequested = true;\n\t\tthis.runtime.disableRestart(task);\n\t\tif (task.status === \"restarting\") {\n\t\t\tthis.runtime.stopUsageMonitor(task);\n\t\t\ttask.status = \"stopped\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.scheduleCleanup(task);\n\t\t\treturn { task, stopped: true };\n\t\t}\n\t\tif (task.status !== \"running\") {\n\t\t\treturn { task, stopped: false };\n\t\t}\n\t\tif (!task.pid) {\n\t\t\treturn { task, stopped: false };\n\t\t}\n\n\t\tkillProcessTree(task.pid);\n\t\tconst stopped = await this.waitForCompletion(task, 2000);\n\t\treturn { task, stopped };\n\t}\n\n\tasync stopAll(): Promise<void> {\n\t\tconst stops = [...this.tasks.keys()].map((id) => this.stopTask(id));\n\t\tawait Promise.all(stops);\n\t\tthis.cleanupExpiredTasks(true);\n\t}\n\n\tclear(): void {\n\t\tthis.unsubscribeSettings?.();\n\t\tthis.unsubscribeSettings = undefined;\n\t\tfor (const id of [...this.tasks.keys()]) {\n\t\t\tthis.removeTask(id, true);\n\t\t}\n\t\tthis.tasks.clear();\n\t\tfor (const timer of this.cleanupTimers.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tthis.cleanupTimers.clear();\n\t}\n\n\tgetLogs(taskId: string, lines: number): string {\n\t\tconst task = this.tasks.get(taskId);\n\t\tif (!task) {\n\t\t\tthrow new ToolError(`Task not found or logs expired: ${taskId}`);\n\t\t}\n\t\tconst text = this.sanitizeLogSnippet(this.tailLog(task, lines));\n\t\tif (!task.logTruncated) {\n\t\t\treturn text;\n\t\t}\n\t\tconst limitKb = Math.round(task.limits.logSizeLimit / 1024);\n\t\tconst notice = `Log output truncated at ${limitKb} KB.`;\n\t\treturn `${text}\\n\\n${notice}`;\n\t}\n}\n\nexport const backgroundTaskManager = new BackgroundTaskManager();\n\n// Re-export types used by downstream consumers\nexport type {\n\tBackgroundTaskHealth,\n\tBackgroundTaskHealthEntry,\n\tBackgroundTaskNotification,\n} from \"./background/task-types.js\";\nexport { backgroundTasksTool } from \"./background/tool-handler.js\";\n\nexport function formatTaskFailures(): string | null {\n\tconst tasks = backgroundTaskManager.getTasks();\n\tconst failedTasks = tasks.filter((task) => task.status === \"failed\");\n\n\tif (failedTasks.length === 0) {\n\t\treturn null;\n\t}\n\n\t// Only show recent failures (last 5 minutes) to avoid nagging about old news\n\tconst RECENT_THRESHOLD = 5 * 60 * 1000;\n\tconst now = Date.now();\n\tconst recentFailures = failedTasks.filter((task) => {\n\t\tif (!task.finishedAt) return false;\n\t\treturn now - task.finishedAt < RECENT_THRESHOLD;\n\t});\n\n\tif (recentFailures.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst lines = [\"# ⚠️ Background Task Alerts\"];\n\tfor (const task of recentFailures) {\n\t\tconst reason = task.failureReason\n\t\t\t? `Reason: ${task.failureReason}`\n\t\t\t: typeof task.exitCode === \"number\" && task.exitCode !== 0\n\t\t\t\t? `Exit Code: ${task.exitCode}`\n\t\t\t\t: \"Exited unexpectedly\";\n\t\tlines.push(\n\t\t\t`- Task \"${sanitizeWithStaticMask(task.command)}\" (${task.id}) stopped. ${reason}`,\n\t\t);\n\t\t// Add a hint about logs\n\t\tlines.push(\n\t\t\t` (Use background_tasks action=logs taskId=${task.id} to investigate)`,\n\t\t);\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAmEH;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IACnC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;CACnE,CAAC;AA2BF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;EAmTnB,CAAC"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAwEH;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IACnC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;CACnE,CAAC;AA2BF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;EAsTnB,CAAC"}
@@ -34,6 +34,7 @@ import { formatGuardianResult, runGuardian, shouldGuardCommand, } from "../guard
34
34
  import { checkCommand } from "../safety/execpolicy.js";
35
35
  import { checkBashCommandForNestedAgent } from "../safety/nested-agent-guard.js";
36
36
  import { requirePlanCheck } from "../safety/safe-mode.js";
37
+ import { sanitizeWithStaticMask } from "../utils/secret-redactor.js";
37
38
  import { resolveShellEnvironment } from "../utils/shell-env.js";
38
39
  import { backgroundTaskManager } from "./background-tasks.js";
39
40
  import { getShellConfig, killProcessTree, validateShellParams, } from "./shell-utils.js";
@@ -71,6 +72,9 @@ const MAX_TIMEOUT_SECONDS = 600;
71
72
  // Output buffer limit (40KB) to prevent memory exhaustion from verbose commands
72
73
  // Commands that exceed this will have output truncated with a warning
73
74
  const MAX_BUFFER = 40 * 1024;
75
+ function sanitizeToolOutput(value) {
76
+ return sanitizeWithStaticMask(value);
77
+ }
74
78
  /**
75
79
  * Check if a command is likely to modify the filesystem.
76
80
  *
@@ -199,7 +203,7 @@ Timeout: 90s default, 600s max. Output truncates at 40KB.`,
199
203
  return respond.text(lines.join("\n")).detail({
200
204
  taskId: task.id,
201
205
  logPath: task.logPath,
202
- command: interpolatedCommand,
206
+ command: sanitizeToolOutput(interpolatedCommand),
203
207
  cwd: resolvedCwd,
204
208
  status: task.status,
205
209
  });
@@ -228,7 +232,8 @@ Timeout: 90s default, 600s max. Output truncates at 40KB.`,
228
232
  content: [
229
233
  {
230
234
  type: "text",
231
- text: output.trim() || "Command executed successfully (no output)",
235
+ text: sanitizeToolOutput(output).trim() ||
236
+ "Command executed successfully (no output)",
232
237
  },
233
238
  ],
234
239
  details: undefined,
@@ -351,7 +356,8 @@ Timeout: 90s default, 600s max. Output truncates at 40KB.`,
351
356
  content: [
352
357
  {
353
358
  type: "text",
354
- text: output.trim() || "Command executed successfully (no output)",
359
+ text: sanitizeToolOutput(output).trim() ||
360
+ "Command executed successfully (no output)",
355
361
  },
356
362
  ],
357
363
  details: undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bash Tool - Shell command execution for the agent.\n *\n * This module provides the agent with the ability to execute arbitrary bash\n * commands in the user's shell environment. It's one of the most powerful\n * tools in the toolbox, enabling system operations, file manipulation,\n * git commands, and running build/test scripts.\n *\n * ## Security Features\n *\n * - **Guardian Integration**: Commands matching certain patterns (git push, npm publish)\n * trigger the Guardian system for additional security checks.\n * - **Safe Mode**: Mutating commands require a plan to be set when safe mode is enabled.\n * - **Output Limits**: stdout/stderr capped at 40KB to prevent memory issues.\n * - **Timeout**: Default 90s timeout, max 600s to prevent runaway processes.\n * - **Process Tree Killing**: On abort/timeout, kills the entire process tree.\n *\n * ## Execution Modes\n *\n * 1. **Foreground (default)**: Waits for command completion, returns output.\n * 2. **Background**: Starts as managed background task, returns immediately.\n * 3. **Sandbox**: Routes execution through sandbox environment when enabled.\n *\n * ## Variable Interpolation\n *\n * Commands support variable interpolation for common paths:\n * - `${cwd}` - Current working directory\n * - `${home}` - User's home directory\n * - `${env.VAR}` - Environment variables\n */\n\nimport { spawn } from \"node:child_process\";\nimport { Type } from \"@sinclair/typebox\";\nimport {\n\tformatGuardianResult,\n\trunGuardian,\n\tshouldGuardCommand,\n} from \"../guardian/index.js\";\nimport { checkCommand } from \"../safety/execpolicy.js\";\nimport { checkBashCommandForNestedAgent } from \"../safety/nested-agent-guard.js\";\nimport { requirePlanCheck } from \"../safety/safe-mode.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport { backgroundTaskManager } from \"./background-tasks.js\";\nimport {\n\tgetShellConfig,\n\tkillProcessTree,\n\tvalidateShellParams,\n} from \"./shell-utils.js\";\nimport { createTool, interpolateContext } from \"./tool-dsl.js\";\n\n/**\n * Schema for bash tool parameters.\n * Defines the structure and validation for command execution options.\n */\nconst bashSchema = Type.Object({\n\tcommand: Type.String({\n\t\tdescription: \"Bash command to execute\",\n\t\tminLength: 1,\n\t}),\n\ttimeout: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: \"Timeout in seconds (optional, no default timeout)\",\n\t\t\texclusiveMinimum: 0,\n\t\t}),\n\t),\n\tcwd: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Working directory for the command (relative or absolute)\",\n\t\t\tminLength: 1,\n\t\t}),\n\t),\n\tenv: Type.Optional(\n\t\tType.Record(Type.String({ minLength: 1 }), Type.String(), {\n\t\t\tdescription: \"Additional environment variables for the command\",\n\t\t}),\n\t),\n\trunInBackground: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Run command as a managed background task (use background_tasks tool to inspect/stop)\",\n\t\t\tdefault: false,\n\t\t}),\n\t),\n});\n\n// Default timeout for command execution (90 seconds)\n// Most commands complete quickly, but builds/tests may take longer\nconst DEFAULT_TIMEOUT_SECONDS = 90;\n\n// Maximum allowed timeout (10 minutes) to prevent indefinite hangs\nconst MAX_TIMEOUT_SECONDS = 600;\n\n// Output buffer limit (40KB) to prevent memory exhaustion from verbose commands\n// Commands that exceed this will have output truncated with a warning\nconst MAX_BUFFER = 40 * 1024;\n\n/**\n * Details returned when a command is started as a background task.\n * Used to track and manage long-running processes.\n */\nexport type BashBackgroundDetails = {\n\t/** Unique identifier for the background task */\n\ttaskId: string;\n\t/** Path to the log file containing command output */\n\tlogPath: string;\n\t/** The command that was executed */\n\tcommand: string;\n\t/** Working directory where command is running */\n\tcwd?: string;\n\t/** Current status of the background task */\n\tstatus: \"running\" | \"stopped\" | \"exited\" | \"failed\" | \"restarting\";\n};\n\n/**\n * Check if a command is likely to modify the filesystem.\n *\n * Used by safe mode to determine if a command requires plan approval.\n * Matches common file-modifying commands and patterns.\n *\n * @param command - The command string to analyze\n * @returns true if the command appears to modify files\n */\nfunction isMutatingCommand(command: string): boolean {\n\tconst mutationPatterns = [\n\t\t// File operations: rm, mv, cp, chmod, chown, truncate, dd, mkfs, ln\n\t\t/(^|\\s)(rm|mv|cp|chmod|chown|truncate|dd|mkfs|ln)\\b/i,\n\t\t// tee writes to files\n\t\t/\\btee\\b/i,\n\t\t// sed with -i flag modifies files in place\n\t\t/\\bsed\\b[^|;]*\\s-i\\b/i,\n\t\t// sudo can modify protected files\n\t\t/(^|\\s)sudo\\b/i,\n\t\t// Output redirection creates/overwrites files\n\t\t/>|>>/,\n\t];\n\treturn mutationPatterns.some((re) => re.test(command));\n}\n\n/**\n * The bash tool instance created using the tool DSL.\n *\n * This tool executes shell commands and handles:\n * - Variable interpolation (${cwd}, ${home}, ${env.VAR})\n * - Safe mode checks for mutating commands\n * - Guardian integration for sensitive operations\n * - Background task management\n * - Sandbox execution when enabled\n * - Output capture with truncation\n * - Timeout handling with process tree cleanup\n */\nexport const bashTool = createTool<typeof bashSchema, BashBackgroundDetails>({\n\tname: \"bash\",\n\tlabel: \"bash\",\n\tdescription: `Execute bash commands.\n\nUsage guidelines:\n- ALWAYS quote paths with spaces: cd \"/path with spaces\"\n- DO NOT use: find, grep, cat, head, tail, ls (use search, read, list tools instead)\n- Prefer rg over grep if you must search\n- Chain commands with ';' or '&&', avoid cd\n- Use 'gh' CLI for GitHub operations (gh pr create, gh issue list, gh repo view)\n\nSupports interpolation in command:\n- \\${cwd} - current working directory\n- \\${home} - user home directory\n- \\${env.VAR} - environment variable\n\nTimeout: 90s default, 600s max. Output truncates at 40KB.`,\n\tschema: bashSchema,\n\tasync run(\n\t\t{ command, timeout, cwd, env, runInBackground },\n\t\t{ signal, sandbox, respond },\n\t) {\n\t\t// Step 1: Interpolate variables in the command string\n\t\t// Replaces ${cwd}, ${home}, ${env.VAR} with actual values\n\t\tconst interpolatedCommand = interpolateContext(command);\n\n\t\t// Step 2: Check execpolicy for command approval\n\t\t// Policies in ~/.maestro/execpolicy and .maestro/execpolicy\n\t\tconst policyResult = checkCommand(interpolatedCommand, process.cwd());\n\t\tif (policyResult.decision === \"forbidden\") {\n\t\t\tconst matchInfo = policyResult.matchedRules\n\t\t\t\t.map((r) =>\n\t\t\t\t\tr.type === \"prefix\"\n\t\t\t\t\t\t? `prefix: ${r.matchedPrefix.join(\" \")}`\n\t\t\t\t\t\t: `heuristic: ${r.command.join(\" \")}`,\n\t\t\t\t)\n\t\t\t\t.join(\", \");\n\t\t\treturn respond.text(\n\t\t\t\t`Command blocked by execpolicy: ${interpolatedCommand}\\n\\nDecision: forbidden\\nMatched rules: ${matchInfo || \"none\"}\\n\\nTo allow this command, add a prefix_rule to .maestro/execpolicy`,\n\t\t\t);\n\t\t}\n\n\t\t// Step 2.5: Check for nested agent spawning\n\t\t// Prevents CPU exhaustion from recursive agent spawning\n\t\tconst nestedAgentError =\n\t\t\tcheckBashCommandForNestedAgent(interpolatedCommand);\n\t\tif (nestedAgentError) {\n\t\t\treturn respond.text(\n\t\t\t\t`${nestedAgentError}\\n\\nCommand: ${interpolatedCommand.slice(0, 100)}...`,\n\t\t\t);\n\t\t}\n\n\t\t// Step 3: Safe mode check - mutating commands require a plan\n\t\tif (isMutatingCommand(interpolatedCommand)) {\n\t\t\trequirePlanCheck(\"bash\");\n\t\t}\n\n\t\t// Step 4: Guardian check - sensitive commands (git push, npm publish) may be blocked\n\t\tconst guardCheck = shouldGuardCommand(interpolatedCommand);\n\t\tif (guardCheck.shouldGuard) {\n\t\t\tconst guardian = await runGuardian({\n\t\t\t\ttrigger: guardCheck.trigger ?? \"git\",\n\t\t\t\ttarget: \"staged\",\n\t\t\t});\n\t\t\t// Block execution if guardian check fails\n\t\t\tif (guardian.status === \"failed\" || guardian.status === \"error\") {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Maestro Guardian blocked ${guardCheck.trigger ?? \"git\"}\\n\\n${formatGuardianResult(guardian)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Step 5: Calculate effective timeout (user timeout clamped to max)\n\t\tconst effectiveTimeout = Math.min(\n\t\t\ttimeout ?? DEFAULT_TIMEOUT_SECONDS,\n\t\t\tMAX_TIMEOUT_SECONDS,\n\t\t);\n\n\t\t// ============================================\n\t\t// Background execution mode\n\t\t// ============================================\n\t\tif (runInBackground) {\n\t\t\t// Background tasks can't run in sandbox - sandbox doesn't support detached processes\n\t\t\tif (sandbox) {\n\t\t\t\treturn respond.text(\n\t\t\t\t\t\"Background execution is not available in sandbox mode. Retry without runInBackground or disable sandbox.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Validate and resolve the working directory\n\t\t\tconst { resolvedCwd } = validateShellParams(\n\t\t\t\tinterpolatedCommand,\n\t\t\t\tcwd,\n\t\t\t\tenv,\n\t\t\t);\n\n\t\t\t// Start the command as a managed background task\n\t\t\t// Output is captured to a log file instead of returned directly\n\t\t\tconst task = backgroundTaskManager.start(interpolatedCommand, {\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tenv: env as Record<string, string> | undefined,\n\t\t\t\tuseShell: true,\n\t\t\t});\n\n\t\t\t// Provide instructions for monitoring the background task\n\t\t\tconst lines = [\n\t\t\t\t`Started background task ${task.id} (status=${task.status})`,\n\t\t\t\t`Logs: ${task.logPath}`,\n\t\t\t\t\"Use background_tasks action=logs taskId=<id> to view output, action=stop to terminate.\",\n\t\t\t];\n\n\t\t\treturn respond.text(lines.join(\"\\n\")).detail({\n\t\t\t\ttaskId: task.id,\n\t\t\t\tlogPath: task.logPath,\n\t\t\t\tcommand: interpolatedCommand,\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tstatus: task.status,\n\t\t\t});\n\t\t}\n\n\t\t// ============================================\n\t\t// Sandbox execution mode\n\t\t// ============================================\n\t\tif (sandbox) {\n\t\t\t// Execute in isolated sandbox environment (e.g., Docker container)\n\t\t\tconst result = await sandbox.exec(interpolatedCommand, cwd, env);\n\n\t\t\t// Combine stdout and stderr for output\n\t\t\tlet output = \"\";\n\t\t\tif (result.stdout) {\n\t\t\t\toutput += result.stdout;\n\t\t\t}\n\t\t\tif (result.stderr) {\n\t\t\t\tif (output) output += \"\\n\";\n\t\t\t\toutput += result.stderr;\n\t\t\t}\n\n\t\t\t// Include exit code for non-zero exits to help with debugging\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\toutput += `\\n\\nExit code: ${result.exitCode}`;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: output.trim() || \"Command executed successfully (no output)\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t}\n\n\t\t// ============================================\n\t\t// Foreground execution mode (default)\n\t\t// ============================================\n\t\t// Execute command synchronously and capture output\n\t\treturn new Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: undefined;\n\t\t}>((resolve, reject) => {\n\t\t\t// Validate working directory and environment\n\t\t\tlet resolvedCwd: string | undefined;\n\t\t\ttry {\n\t\t\t\t({ resolvedCwd } = validateShellParams(interpolatedCommand, cwd, env));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get shell configuration (bash -lc on most systems)\n\t\t\tconst { shell, args } = getShellConfig();\n\t\t\t// Merge custom env vars with process environment\n\t\t\tconst mergedEnv = resolveShellEnvironment(env, {\n\t\t\t\tworkspaceDir: process.cwd(),\n\t\t\t});\n\n\t\t\t// Spawn the child process in detached mode for clean process tree handling\n\t\t\tconst child = spawn(shell, [...args, interpolatedCommand], {\n\t\t\t\tdetached: true, // Allows killProcessTree to work correctly\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"], // No stdin, capture stdout/stderr\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tenv: mergedEnv,\n\t\t\t});\n\n\t\t\t// Output buffers with truncation tracking\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet timedOut = false;\n\t\t\tlet stdoutTruncated = false;\n\t\t\tlet stderrTruncated = false;\n\n\t\t\t// Set up timeout handler\n\t\t\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\t\t\tif (effectiveTimeout > 0) {\n\t\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\t\ttimedOut = true;\n\t\t\t\t\tonAbort();\n\t\t\t\t}, effectiveTimeout * 1000);\n\t\t\t}\n\n\t\t\t// Abort handler - kills the entire process tree\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Cleanup function to remove event listeners and clear timeout\n\t\t\tconst cleanup = () => {\n\t\t\t\tif (timeoutHandle) {\n\t\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\t}\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Capture stdout with buffer limit\n\t\t\tif (child.stdout) {\n\t\t\t\tchild.stdout.on(\"data\", (data) => {\n\t\t\t\t\tif (stdout.length < MAX_BUFFER) {\n\t\t\t\t\t\tstdout += data.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstdoutTruncated = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Capture stderr with buffer limit\n\t\t\tif (child.stderr) {\n\t\t\t\tchild.stderr.on(\"data\", (data) => {\n\t\t\t\t\tif (stderr.length < MAX_BUFFER) {\n\t\t\t\t\t\tstderr += data.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstderrTruncated = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle spawn errors (e.g., command not found)\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t});\n\n\t\t\t// Handle process completion\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tcleanup();\n\n\t\t\t\t// Combine stdout and stderr\n\t\t\t\tlet output = stdout;\n\t\t\t\tif (stderr) {\n\t\t\t\t\tif (output) output += \"\\n\";\n\t\t\t\t\toutput += stderr;\n\t\t\t\t}\n\n\t\t\t\t// Provide helpful truncation feedback\n\t\t\t\tconst truncationMessages: string[] = [];\n\t\t\t\tif (stdoutTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stdout exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (stderrTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stderr exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (truncationMessages.length > 0) {\n\t\t\t\t\toutput += `\\n\\n⚠️ Output truncated: ${truncationMessages.join(\"; \")}. Consider piping output to a file or using head/tail.`;\n\t\t\t\t}\n\n\t\t\t\t// Add timeout or exit code information\n\t\t\t\tif (timedOut) {\n\t\t\t\t\toutput += `\\n\\n⏱️ Command timed out after ${effectiveTimeout}s`;\n\t\t\t\t} else if (code !== 0) {\n\t\t\t\t\toutput += `\\n\\nExit code: ${code}`;\n\t\t\t\t}\n\n\t\t\t\tresolve({\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\t\toutput.trim() || \"Command executed successfully (no output)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Allow external abort signal to cancel execution\n\t\t\tif (signal) {\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t});\n\t},\n});\n"]}
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EACN,oBAAoB,EACpB,WAAW,EACX,kBAAkB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACN,cAAc,EACd,eAAe,EACf,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE/D;;;GAGG;AACH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;QACpB,WAAW,EAAE,yBAAyB;QACtC,SAAS,EAAE,CAAC;KACZ,CAAC;IACF,OAAO,EAAE,IAAI,CAAC,QAAQ,CACrB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EAAE,mDAAmD;QAChE,gBAAgB,EAAE,CAAC;KACnB,CAAC,CACF;IACD,GAAG,EAAE,IAAI,CAAC,QAAQ,CACjB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EAAE,0DAA0D;QACvE,SAAS,EAAE,CAAC;KACZ,CAAC,CACF;IACD,GAAG,EAAE,IAAI,CAAC,QAAQ,CACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;QACzD,WAAW,EAAE,kDAAkD;KAC/D,CAAC,CACF;IACD,eAAe,EAAE,IAAI,CAAC,QAAQ,CAC7B,IAAI,CAAC,OAAO,CAAC;QACZ,WAAW,EACV,sFAAsF;QACvF,OAAO,EAAE,KAAK;KACd,CAAC,CACF;CACD,CAAC,CAAC;AAEH,qDAAqD;AACrD,mEAAmE;AACnE,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC,mEAAmE;AACnE,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,gFAAgF;AAChF,sEAAsE;AACtE,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7B,SAAS,kBAAkB,CAAC,KAAa;IACxC,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAmBD;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACzC,MAAM,gBAAgB,GAAG;QACxB,oEAAoE;QACpE,qDAAqD;QACrD,sBAAsB;QACtB,UAAU;QACV,2CAA2C;QAC3C,sBAAsB;QACtB,kCAAkC;QAClC,eAAe;QACf,8CAA8C;QAC9C,MAAM;KACN,CAAC;IACF,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAA2C;IAC5E,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,MAAM;IACb,WAAW,EAAE;;;;;;;;;;;;;;0DAc4C;IACzD,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,GAAG,CACR,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,EAC/C,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;QAE5B,sDAAsD;QACtD,0DAA0D;QAC1D,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAExD,gDAAgD;QAChD,4DAA4D;QAC5D,MAAM,YAAY,GAAG,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACtE,IAAI,YAAY,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACV,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAClB,CAAC,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;gBACxC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CACtC;iBACA,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,OAAO,OAAO,CAAC,IAAI,CAClB,kCAAkC,mBAAmB,2CAA2C,SAAS,IAAI,MAAM,qEAAqE,CACxL,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,wDAAwD;QACxD,MAAM,gBAAgB,GACrB,8BAA8B,CAAC,mBAAmB,CAAC,CAAC;QACrD,IAAI,gBAAgB,EAAE,CAAC;YACtB,OAAO,OAAO,CAAC,IAAI,CAClB,GAAG,gBAAgB,gBAAgB,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CACzE,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,IAAI,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC5C,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAED,qFAAqF;QACrF,MAAM,UAAU,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;QAC3D,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;gBAClC,OAAO,EAAE,UAAU,CAAC,OAAO,IAAI,KAAK;gBACpC,MAAM,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,0CAA0C;YAC1C,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;gBACjE,OAAO;oBACN,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,4BAA4B,UAAU,CAAC,OAAO,IAAI,KAAK,OAAO,oBAAoB,CAAC,QAAQ,CAAC,EAAE;yBACpG;qBACD;oBACD,OAAO,EAAE,SAAS;iBAClB,CAAC;YACH,CAAC;QACF,CAAC;QAED,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAChC,OAAO,IAAI,uBAAuB,EAClC,mBAAmB,CACnB,CAAC;QAEF,+CAA+C;QAC/C,4BAA4B;QAC5B,+CAA+C;QAC/C,IAAI,eAAe,EAAE,CAAC;YACrB,qFAAqF;YACrF,IAAI,OAAO,EAAE,CAAC;gBACb,OAAO,OAAO,CAAC,IAAI,CAClB,0GAA0G,CAC1G,CAAC;YACH,CAAC;YAED,6CAA6C;YAC7C,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAC1C,mBAAmB,EACnB,GAAG,EACH,GAAG,CACH,CAAC;YAEF,iDAAiD;YACjD,gEAAgE;YAChE,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,mBAAmB,EAAE;gBAC7D,GAAG,EAAE,WAAW;gBAChB,GAAG,EAAE,GAAyC;gBAC9C,QAAQ,EAAE,IAAI;aACd,CAAC,CAAC;YAEH,0DAA0D;YAC1D,MAAM,KAAK,GAAG;gBACb,2BAA2B,IAAI,CAAC,EAAE,YAAY,IAAI,CAAC,MAAM,GAAG;gBAC5D,SAAS,IAAI,CAAC,OAAO,EAAE;gBACvB,wFAAwF;aACxF,CAAC;YAEF,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC5C,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,kBAAkB,CAAC,mBAAmB,CAAC;gBAChD,GAAG,EAAE,WAAW;gBAChB,MAAM,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC,CAAC;QACJ,CAAC;QAED,+CAA+C;QAC/C,yBAAyB;QACzB,+CAA+C;QAC/C,IAAI,OAAO,EAAE,CAAC;YACb,mEAAmE;YACnE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAEjE,uCAAuC;YACvC,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;YACzB,CAAC;YACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,IAAI,MAAM;oBAAE,MAAM,IAAI,IAAI,CAAC;gBAC3B,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;YACzB,CAAC;YAED,8DAA8D;YAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,kBAAkB,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC/C,CAAC;YAED,OAAO;gBACN,OAAO,EAAE;oBACR;wBACC,IAAI,EAAE,MAAM;wBACZ,IAAI,EACH,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;4BACjC,2CAA2C;qBAC5C;iBACD;gBACD,OAAO,EAAE,SAAS;aAClB,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,sCAAsC;QACtC,+CAA+C;QAC/C,mDAAmD;QACnD,OAAO,IAAI,OAAO,CAGf,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtB,6CAA6C;YAC7C,IAAI,WAA+B,CAAC;YACpC,IAAI,CAAC;gBACJ,CAAC,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YACxE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACR,CAAC;YAED,qDAAqD;YACrD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,cAAc,EAAE,CAAC;YACzC,iDAAiD;YACjD,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,EAAE;gBAC9C,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE;aAC3B,CAAC,CAAC;YAEH,2EAA2E;YAC3E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,EAAE;gBAC1D,QAAQ,EAAE,IAAI,EAAE,2CAA2C;gBAC3D,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kCAAkC;gBACrE,GAAG,EAAE,WAAW;gBAChB,GAAG,EAAE,SAAS;aACd,CAAC,CAAC;YAEH,0CAA0C;YAC1C,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,eAAe,GAAG,KAAK,CAAC;YAC5B,IAAI,eAAe,GAAG,KAAK,CAAC;YAE5B,yBAAyB;YACzB,IAAI,aAAyC,CAAC;YAC9C,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBAC1B,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC/B,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,EAAE,CAAC;gBACX,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,gDAAgD;YAChD,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;oBACf,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC5B,CAAC;YACF,CAAC,CAAC;YAEF,+DAA+D;YAC/D,MAAM,OAAO,GAAG,GAAG,EAAE;gBACpB,IAAI,aAAa,EAAE,CAAC;oBACnB,YAAY,CAAC,aAAa,CAAC,CAAC;gBAC7B,CAAC;gBACD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,CAAC;YACF,CAAC,CAAC;YAEF,mCAAmC;YACnC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAClB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBAChC,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;wBAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC3B,CAAC;yBAAM,CAAC;wBACP,eAAe,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;YAED,mCAAmC;YACnC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAClB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBAChC,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;wBAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC3B,CAAC;yBAAM,CAAC;wBACP,eAAe,GAAG,IAAI,CAAC;oBACxB,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;YAED,gDAAgD;YAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC3B,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;YAEH,4BAA4B;YAC5B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,OAAO,EAAE,CAAC;gBAEV,4BAA4B;gBAC5B,IAAI,MAAM,GAAG,MAAM,CAAC;gBACpB,IAAI,MAAM,EAAE,CAAC;oBACZ,IAAI,MAAM;wBAAE,MAAM,IAAI,IAAI,CAAC;oBAC3B,MAAM,IAAI,MAAM,CAAC;gBAClB,CAAC;gBAED,sCAAsC;gBACtC,MAAM,kBAAkB,GAAa,EAAE,CAAC;gBACxC,IAAI,eAAe,EAAE,CAAC;oBACrB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;oBAClD,kBAAkB,CAAC,IAAI,CACtB,mBAAmB,WAAW,4BAA4B,CAC1D,CAAC;gBACH,CAAC;gBACD,IAAI,eAAe,EAAE,CAAC;oBACrB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;oBAClD,kBAAkB,CAAC,IAAI,CACtB,mBAAmB,WAAW,4BAA4B,CAC1D,CAAC;gBACH,CAAC;gBACD,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnC,MAAM,IAAI,4BAA4B,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,wDAAwD,CAAC;gBAC7H,CAAC;gBAED,uCAAuC;gBACvC,IAAI,QAAQ,EAAE,CAAC;oBACd,MAAM,IAAI,kCAAkC,gBAAgB,GAAG,CAAC;gBACjE,CAAC;qBAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,kBAAkB,IAAI,EAAE,CAAC;gBACpC,CAAC;gBAED,OAAO,CAAC;oBACP,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,MAAM;4BACZ,IAAI,EACH,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;gCACjC,2CAA2C;yBAC5C;qBACD;oBACD,OAAO,EAAE,SAAS;iBAClB,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,kDAAkD;YAClD,IAAI,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;CACD,CAAC,CAAC","sourcesContent":["/**\n * Bash Tool - Shell command execution for the agent.\n *\n * This module provides the agent with the ability to execute arbitrary bash\n * commands in the user's shell environment. It's one of the most powerful\n * tools in the toolbox, enabling system operations, file manipulation,\n * git commands, and running build/test scripts.\n *\n * ## Security Features\n *\n * - **Guardian Integration**: Commands matching certain patterns (git push, npm publish)\n * trigger the Guardian system for additional security checks.\n * - **Safe Mode**: Mutating commands require a plan to be set when safe mode is enabled.\n * - **Output Limits**: stdout/stderr capped at 40KB to prevent memory issues.\n * - **Timeout**: Default 90s timeout, max 600s to prevent runaway processes.\n * - **Process Tree Killing**: On abort/timeout, kills the entire process tree.\n *\n * ## Execution Modes\n *\n * 1. **Foreground (default)**: Waits for command completion, returns output.\n * 2. **Background**: Starts as managed background task, returns immediately.\n * 3. **Sandbox**: Routes execution through sandbox environment when enabled.\n *\n * ## Variable Interpolation\n *\n * Commands support variable interpolation for common paths:\n * - `${cwd}` - Current working directory\n * - `${home}` - User's home directory\n * - `${env.VAR}` - Environment variables\n */\n\nimport { spawn } from \"node:child_process\";\nimport { Type } from \"@sinclair/typebox\";\nimport {\n\tformatGuardianResult,\n\trunGuardian,\n\tshouldGuardCommand,\n} from \"../guardian/index.js\";\nimport { checkCommand } from \"../safety/execpolicy.js\";\nimport { checkBashCommandForNestedAgent } from \"../safety/nested-agent-guard.js\";\nimport { requirePlanCheck } from \"../safety/safe-mode.js\";\nimport { sanitizeWithStaticMask } from \"../utils/secret-redactor.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport { backgroundTaskManager } from \"./background-tasks.js\";\nimport {\n\tgetShellConfig,\n\tkillProcessTree,\n\tvalidateShellParams,\n} from \"./shell-utils.js\";\nimport { createTool, interpolateContext } from \"./tool-dsl.js\";\n\n/**\n * Schema for bash tool parameters.\n * Defines the structure and validation for command execution options.\n */\nconst bashSchema = Type.Object({\n\tcommand: Type.String({\n\t\tdescription: \"Bash command to execute\",\n\t\tminLength: 1,\n\t}),\n\ttimeout: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription: \"Timeout in seconds (optional, no default timeout)\",\n\t\t\texclusiveMinimum: 0,\n\t\t}),\n\t),\n\tcwd: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Working directory for the command (relative or absolute)\",\n\t\t\tminLength: 1,\n\t\t}),\n\t),\n\tenv: Type.Optional(\n\t\tType.Record(Type.String({ minLength: 1 }), Type.String(), {\n\t\t\tdescription: \"Additional environment variables for the command\",\n\t\t}),\n\t),\n\trunInBackground: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Run command as a managed background task (use background_tasks tool to inspect/stop)\",\n\t\t\tdefault: false,\n\t\t}),\n\t),\n});\n\n// Default timeout for command execution (90 seconds)\n// Most commands complete quickly, but builds/tests may take longer\nconst DEFAULT_TIMEOUT_SECONDS = 90;\n\n// Maximum allowed timeout (10 minutes) to prevent indefinite hangs\nconst MAX_TIMEOUT_SECONDS = 600;\n\n// Output buffer limit (40KB) to prevent memory exhaustion from verbose commands\n// Commands that exceed this will have output truncated with a warning\nconst MAX_BUFFER = 40 * 1024;\n\nfunction sanitizeToolOutput(value: string): string {\n\treturn sanitizeWithStaticMask(value);\n}\n\n/**\n * Details returned when a command is started as a background task.\n * Used to track and manage long-running processes.\n */\nexport type BashBackgroundDetails = {\n\t/** Unique identifier for the background task */\n\ttaskId: string;\n\t/** Path to the log file containing command output */\n\tlogPath: string;\n\t/** The command that was executed */\n\tcommand: string;\n\t/** Working directory where command is running */\n\tcwd?: string;\n\t/** Current status of the background task */\n\tstatus: \"running\" | \"stopped\" | \"exited\" | \"failed\" | \"restarting\";\n};\n\n/**\n * Check if a command is likely to modify the filesystem.\n *\n * Used by safe mode to determine if a command requires plan approval.\n * Matches common file-modifying commands and patterns.\n *\n * @param command - The command string to analyze\n * @returns true if the command appears to modify files\n */\nfunction isMutatingCommand(command: string): boolean {\n\tconst mutationPatterns = [\n\t\t// File operations: rm, mv, cp, chmod, chown, truncate, dd, mkfs, ln\n\t\t/(^|\\s)(rm|mv|cp|chmod|chown|truncate|dd|mkfs|ln)\\b/i,\n\t\t// tee writes to files\n\t\t/\\btee\\b/i,\n\t\t// sed with -i flag modifies files in place\n\t\t/\\bsed\\b[^|;]*\\s-i\\b/i,\n\t\t// sudo can modify protected files\n\t\t/(^|\\s)sudo\\b/i,\n\t\t// Output redirection creates/overwrites files\n\t\t/>|>>/,\n\t];\n\treturn mutationPatterns.some((re) => re.test(command));\n}\n\n/**\n * The bash tool instance created using the tool DSL.\n *\n * This tool executes shell commands and handles:\n * - Variable interpolation (${cwd}, ${home}, ${env.VAR})\n * - Safe mode checks for mutating commands\n * - Guardian integration for sensitive operations\n * - Background task management\n * - Sandbox execution when enabled\n * - Output capture with truncation\n * - Timeout handling with process tree cleanup\n */\nexport const bashTool = createTool<typeof bashSchema, BashBackgroundDetails>({\n\tname: \"bash\",\n\tlabel: \"bash\",\n\tdescription: `Execute bash commands.\n\nUsage guidelines:\n- ALWAYS quote paths with spaces: cd \"/path with spaces\"\n- DO NOT use: find, grep, cat, head, tail, ls (use search, read, list tools instead)\n- Prefer rg over grep if you must search\n- Chain commands with ';' or '&&', avoid cd\n- Use 'gh' CLI for GitHub operations (gh pr create, gh issue list, gh repo view)\n\nSupports interpolation in command:\n- \\${cwd} - current working directory\n- \\${home} - user home directory\n- \\${env.VAR} - environment variable\n\nTimeout: 90s default, 600s max. Output truncates at 40KB.`,\n\tschema: bashSchema,\n\tasync run(\n\t\t{ command, timeout, cwd, env, runInBackground },\n\t\t{ signal, sandbox, respond },\n\t) {\n\t\t// Step 1: Interpolate variables in the command string\n\t\t// Replaces ${cwd}, ${home}, ${env.VAR} with actual values\n\t\tconst interpolatedCommand = interpolateContext(command);\n\n\t\t// Step 2: Check execpolicy for command approval\n\t\t// Policies in ~/.maestro/execpolicy and .maestro/execpolicy\n\t\tconst policyResult = checkCommand(interpolatedCommand, process.cwd());\n\t\tif (policyResult.decision === \"forbidden\") {\n\t\t\tconst matchInfo = policyResult.matchedRules\n\t\t\t\t.map((r) =>\n\t\t\t\t\tr.type === \"prefix\"\n\t\t\t\t\t\t? `prefix: ${r.matchedPrefix.join(\" \")}`\n\t\t\t\t\t\t: `heuristic: ${r.command.join(\" \")}`,\n\t\t\t\t)\n\t\t\t\t.join(\", \");\n\t\t\treturn respond.text(\n\t\t\t\t`Command blocked by execpolicy: ${interpolatedCommand}\\n\\nDecision: forbidden\\nMatched rules: ${matchInfo || \"none\"}\\n\\nTo allow this command, add a prefix_rule to .maestro/execpolicy`,\n\t\t\t);\n\t\t}\n\n\t\t// Step 2.5: Check for nested agent spawning\n\t\t// Prevents CPU exhaustion from recursive agent spawning\n\t\tconst nestedAgentError =\n\t\t\tcheckBashCommandForNestedAgent(interpolatedCommand);\n\t\tif (nestedAgentError) {\n\t\t\treturn respond.text(\n\t\t\t\t`${nestedAgentError}\\n\\nCommand: ${interpolatedCommand.slice(0, 100)}...`,\n\t\t\t);\n\t\t}\n\n\t\t// Step 3: Safe mode check - mutating commands require a plan\n\t\tif (isMutatingCommand(interpolatedCommand)) {\n\t\t\trequirePlanCheck(\"bash\");\n\t\t}\n\n\t\t// Step 4: Guardian check - sensitive commands (git push, npm publish) may be blocked\n\t\tconst guardCheck = shouldGuardCommand(interpolatedCommand);\n\t\tif (guardCheck.shouldGuard) {\n\t\t\tconst guardian = await runGuardian({\n\t\t\t\ttrigger: guardCheck.trigger ?? \"git\",\n\t\t\t\ttarget: \"staged\",\n\t\t\t});\n\t\t\t// Block execution if guardian check fails\n\t\t\tif (guardian.status === \"failed\" || guardian.status === \"error\") {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Maestro Guardian blocked ${guardCheck.trigger ?? \"git\"}\\n\\n${formatGuardianResult(guardian)}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Step 5: Calculate effective timeout (user timeout clamped to max)\n\t\tconst effectiveTimeout = Math.min(\n\t\t\ttimeout ?? DEFAULT_TIMEOUT_SECONDS,\n\t\t\tMAX_TIMEOUT_SECONDS,\n\t\t);\n\n\t\t// ============================================\n\t\t// Background execution mode\n\t\t// ============================================\n\t\tif (runInBackground) {\n\t\t\t// Background tasks can't run in sandbox - sandbox doesn't support detached processes\n\t\t\tif (sandbox) {\n\t\t\t\treturn respond.text(\n\t\t\t\t\t\"Background execution is not available in sandbox mode. Retry without runInBackground or disable sandbox.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Validate and resolve the working directory\n\t\t\tconst { resolvedCwd } = validateShellParams(\n\t\t\t\tinterpolatedCommand,\n\t\t\t\tcwd,\n\t\t\t\tenv,\n\t\t\t);\n\n\t\t\t// Start the command as a managed background task\n\t\t\t// Output is captured to a log file instead of returned directly\n\t\t\tconst task = backgroundTaskManager.start(interpolatedCommand, {\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tenv: env as Record<string, string> | undefined,\n\t\t\t\tuseShell: true,\n\t\t\t});\n\n\t\t\t// Provide instructions for monitoring the background task\n\t\t\tconst lines = [\n\t\t\t\t`Started background task ${task.id} (status=${task.status})`,\n\t\t\t\t`Logs: ${task.logPath}`,\n\t\t\t\t\"Use background_tasks action=logs taskId=<id> to view output, action=stop to terminate.\",\n\t\t\t];\n\n\t\t\treturn respond.text(lines.join(\"\\n\")).detail({\n\t\t\t\ttaskId: task.id,\n\t\t\t\tlogPath: task.logPath,\n\t\t\t\tcommand: sanitizeToolOutput(interpolatedCommand),\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tstatus: task.status,\n\t\t\t});\n\t\t}\n\n\t\t// ============================================\n\t\t// Sandbox execution mode\n\t\t// ============================================\n\t\tif (sandbox) {\n\t\t\t// Execute in isolated sandbox environment (e.g., Docker container)\n\t\t\tconst result = await sandbox.exec(interpolatedCommand, cwd, env);\n\n\t\t\t// Combine stdout and stderr for output\n\t\t\tlet output = \"\";\n\t\t\tif (result.stdout) {\n\t\t\t\toutput += result.stdout;\n\t\t\t}\n\t\t\tif (result.stderr) {\n\t\t\t\tif (output) output += \"\\n\";\n\t\t\t\toutput += result.stderr;\n\t\t\t}\n\n\t\t\t// Include exit code for non-zero exits to help with debugging\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\toutput += `\\n\\nExit code: ${result.exitCode}`;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\tsanitizeToolOutput(output).trim() ||\n\t\t\t\t\t\t\t\"Command executed successfully (no output)\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t}\n\n\t\t// ============================================\n\t\t// Foreground execution mode (default)\n\t\t// ============================================\n\t\t// Execute command synchronously and capture output\n\t\treturn new Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: undefined;\n\t\t}>((resolve, reject) => {\n\t\t\t// Validate working directory and environment\n\t\t\tlet resolvedCwd: string | undefined;\n\t\t\ttry {\n\t\t\t\t({ resolvedCwd } = validateShellParams(interpolatedCommand, cwd, env));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get shell configuration (bash -lc on most systems)\n\t\t\tconst { shell, args } = getShellConfig();\n\t\t\t// Merge custom env vars with process environment\n\t\t\tconst mergedEnv = resolveShellEnvironment(env, {\n\t\t\t\tworkspaceDir: process.cwd(),\n\t\t\t});\n\n\t\t\t// Spawn the child process in detached mode for clean process tree handling\n\t\t\tconst child = spawn(shell, [...args, interpolatedCommand], {\n\t\t\t\tdetached: true, // Allows killProcessTree to work correctly\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"], // No stdin, capture stdout/stderr\n\t\t\t\tcwd: resolvedCwd,\n\t\t\t\tenv: mergedEnv,\n\t\t\t});\n\n\t\t\t// Output buffers with truncation tracking\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tlet timedOut = false;\n\t\t\tlet stdoutTruncated = false;\n\t\t\tlet stderrTruncated = false;\n\n\t\t\t// Set up timeout handler\n\t\t\tlet timeoutHandle: NodeJS.Timeout | undefined;\n\t\t\tif (effectiveTimeout > 0) {\n\t\t\t\ttimeoutHandle = setTimeout(() => {\n\t\t\t\t\ttimedOut = true;\n\t\t\t\t\tonAbort();\n\t\t\t\t}, effectiveTimeout * 1000);\n\t\t\t}\n\n\t\t\t// Abort handler - kills the entire process tree\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (child.pid) {\n\t\t\t\t\tkillProcessTree(child.pid);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Cleanup function to remove event listeners and clear timeout\n\t\t\tconst cleanup = () => {\n\t\t\t\tif (timeoutHandle) {\n\t\t\t\t\tclearTimeout(timeoutHandle);\n\t\t\t\t}\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Capture stdout with buffer limit\n\t\t\tif (child.stdout) {\n\t\t\t\tchild.stdout.on(\"data\", (data) => {\n\t\t\t\t\tif (stdout.length < MAX_BUFFER) {\n\t\t\t\t\t\tstdout += data.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstdoutTruncated = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Capture stderr with buffer limit\n\t\t\tif (child.stderr) {\n\t\t\t\tchild.stderr.on(\"data\", (data) => {\n\t\t\t\t\tif (stderr.length < MAX_BUFFER) {\n\t\t\t\t\t\tstderr += data.toString();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstderrTruncated = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle spawn errors (e.g., command not found)\n\t\t\tchild.on(\"error\", (error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t});\n\n\t\t\t// Handle process completion\n\t\t\tchild.on(\"close\", (code) => {\n\t\t\t\tcleanup();\n\n\t\t\t\t// Combine stdout and stderr\n\t\t\t\tlet output = stdout;\n\t\t\t\tif (stderr) {\n\t\t\t\t\tif (output) output += \"\\n\";\n\t\t\t\t\toutput += stderr;\n\t\t\t\t}\n\n\t\t\t\t// Provide helpful truncation feedback\n\t\t\t\tconst truncationMessages: string[] = [];\n\t\t\t\tif (stdoutTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stdout exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (stderrTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stderr exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (truncationMessages.length > 0) {\n\t\t\t\t\toutput += `\\n\\n⚠️ Output truncated: ${truncationMessages.join(\"; \")}. Consider piping output to a file or using head/tail.`;\n\t\t\t\t}\n\n\t\t\t\t// Add timeout or exit code information\n\t\t\t\tif (timedOut) {\n\t\t\t\t\toutput += `\\n\\n⏱️ Command timed out after ${effectiveTimeout}s`;\n\t\t\t\t} else if (code !== 0) {\n\t\t\t\t\toutput += `\\n\\nExit code: ${code}`;\n\t\t\t\t}\n\n\t\t\t\tresolve({\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext:\n\t\t\t\t\t\t\t\tsanitizeToolOutput(output).trim() ||\n\t\t\t\t\t\t\t\t\"Command executed successfully (no output)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// Allow external abort signal to cancel execution\n\t\t\tif (signal) {\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t});\n\t},\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"inline-tools.d.ts","sourceRoot":"","sources":["../../src/tools/inline-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AAwapE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CA6EhE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb,CAMA"}
1
+ {"version":3,"file":"inline-tools.d.ts","sourceRoot":"","sources":["../../src/tools/inline-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AA4apE;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CA6EhE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb,CAMA"}
@@ -41,6 +41,7 @@ import { Type } from "@sinclair/typebox";
41
41
  import { PATHS } from "../config/constants.js";
42
42
  import { createLogger } from "../utils/logger.js";
43
43
  import { expandTildePath } from "../utils/path-expansion.js";
44
+ import { sanitizeWithStaticMask } from "../utils/secret-redactor.js";
44
45
  import { resolveShellEnvironment } from "../utils/shell-env.js";
45
46
  import { createTool } from "./tool-dsl.js";
46
47
  const logger = createLogger("inline-tools");
@@ -260,22 +261,24 @@ function createInlineTool(def) {
260
261
  const displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);
261
262
  truncationMessages.push(`stderr exceeded ${displayedKB}KB limit and was truncated`);
262
263
  }
264
+ const stdout = sanitizeWithStaticMask(result.stdout);
265
+ const stderr = sanitizeWithStaticMask(result.stderr);
263
266
  const truncationNotice = truncationMessages.length > 0
264
267
  ? `Warning: Output truncated: ${truncationMessages.join("; ")}. Consider piping output to a file or using head/tail.`
265
268
  : "";
266
269
  if (result.exitCode !== 0) {
267
- const baseError = result.stderr.trim() || `Exit code: ${result.exitCode}`;
270
+ const baseError = stderr.trim() || `Exit code: ${result.exitCode}`;
268
271
  const errorMsg = truncationNotice
269
272
  ? `${baseError}\n\n${truncationNotice}`
270
273
  : baseError;
271
- return context.respond.error(`Command failed: ${errorMsg}\n\nStdout:\n${result.stdout}`);
274
+ return context.respond.error(`Command failed: ${errorMsg}\n\nStdout:\n${stdout}`);
272
275
  }
273
276
  // Return stdout as the result
274
- const output = result.stdout.trim();
275
- if (result.stderr.trim()) {
277
+ const output = stdout.trim();
278
+ if (stderr.trim()) {
276
279
  const combined = output
277
- ? `${output}\n\n[stderr]: ${result.stderr.trim()}`
278
- : `[stderr]: ${result.stderr.trim()}`;
280
+ ? `${output}\n\n[stderr]: ${stderr.trim()}`
281
+ : `[stderr]: ${stderr.trim()}`;
279
282
  return context.respond.text(truncationNotice ? `${combined}\n\n${truncationNotice}` : combined);
280
283
  }
281
284
  if (truncationNotice) {
@@ -287,7 +290,7 @@ function createInlineTool(def) {
287
290
  return context.respond.text(output || "(no output)");
288
291
  }
289
292
  catch (error) {
290
- const message = error instanceof Error ? error.message : String(error);
293
+ const message = sanitizeWithStaticMask(error instanceof Error ? error.message : String(error));
291
294
  return context.respond.error(`Failed to execute command: ${message}`);
292
295
  }
293
296
  },
@@ -1 +1 @@
1
- {"version":3,"file":"inline-tools.js","sourceRoot":"","sources":["../../src/tools/inline-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Inline Tool Definitions - Load custom tools from .maestro/tools.json\n *\n * Allows users to define shell-based tools without requiring full MCP server setup.\n * Tools receive parameters as JSON via stdin and return results via stdout.\n *\n * ## Configuration\n *\n * Project-level: `.maestro/tools.json`\n * User-level: `~/.maestro/tools.json`\n *\n * Project tools override user tools with the same name.\n *\n * ## Format\n *\n * ```json\n * {\n * \"tools\": [\n * {\n * \"name\": \"deploy\",\n * \"description\": \"Deploy to an environment\",\n * \"command\": \"./scripts/deploy.sh\",\n * \"parameters\": {\n * \"environment\": {\n * \"type\": \"string\",\n * \"enum\": [\"staging\", \"prod\"],\n * \"description\": \"Target environment\"\n * }\n * }\n * }\n * ]\n * }\n * ```\n *\n * @module tools/inline-tools\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { type TSchema, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, ToolAnnotations } from \"../agent/types.js\";\nimport { PATHS } from \"../config/constants.js\";\nimport { createLogger } from \"../utils/logger.js\";\nimport { expandTildePath } from \"../utils/path-expansion.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport { createTool } from \"./tool-dsl.js\";\n\nconst logger = createLogger(\"inline-tools\");\n\n// Output buffer limit (40KB) to prevent memory exhaustion from verbose inline tools.\nconst MAX_INLINE_BUFFER = 40 * 1024;\n\n/**\n * JSON Schema parameter definition (simplified subset)\n */\ninterface InlineParameterDef {\n\ttype: \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\" | \"object\";\n\tdescription?: string;\n\tenum?: (string | number)[];\n\tdefault?: unknown;\n\titems?: InlineParameterDef;\n}\n\n/**\n * Inline tool definition from .maestro/tools.json\n */\ninterface InlineToolDef {\n\tname: string;\n\tdescription: string;\n\tcommand: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tparameters?: Record<string, InlineParameterDef>;\n\ttimeout?: number;\n\t/** Tool behavior hints */\n\tannotations?: {\n\t\treadOnly?: boolean;\n\t\tdestructive?: boolean;\n\t\trequiresApproval?: boolean;\n\t};\n}\n\n/**\n * Configuration file format\n */\ninterface InlineToolsConfig {\n\ttools: InlineToolDef[];\n}\n\n/**\n * Convert a parameter definition to a TypeBox schema\n */\nfunction parameterToTypeBox(name: string, param: InlineParameterDef): TSchema {\n\tconst options: Record<string, unknown> = {};\n\tif (param.description) {\n\t\toptions.description = param.description;\n\t}\n\tif (param.default !== undefined) {\n\t\toptions.default = param.default;\n\t}\n\n\tswitch (param.type) {\n\t\tcase \"string\":\n\t\t\tif (param.enum) {\n\t\t\t\treturn Type.Union(\n\t\t\t\t\tparam.enum.map((v) => Type.Literal(v as string)),\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Type.String(options);\n\t\tcase \"number\":\n\t\t\treturn Type.Number(options);\n\t\tcase \"integer\":\n\t\t\treturn Type.Integer(options);\n\t\tcase \"boolean\":\n\t\t\treturn Type.Boolean(options);\n\t\tcase \"array\":\n\t\t\tif (param.items) {\n\t\t\t\treturn Type.Array(\n\t\t\t\t\tparameterToTypeBox(`${name}[]`, param.items),\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Type.Array(Type.Unknown(), options);\n\t\tcase \"object\":\n\t\t\treturn Type.Object({}, options);\n\t\tdefault:\n\t\t\treturn Type.Unknown(options);\n\t}\n}\n\n/**\n * Build a TypeBox schema from inline tool parameters\n */\nfunction buildSchema(parameters?: Record<string, InlineParameterDef>): TSchema {\n\tif (!parameters || Object.keys(parameters).length === 0) {\n\t\treturn Type.Object({});\n\t}\n\n\tconst properties: Record<string, TSchema> = {};\n\tconst required: string[] = [];\n\n\tfor (const [name, param] of Object.entries(parameters)) {\n\t\tproperties[name] = parameterToTypeBox(name, param);\n\t\t// Parameters without defaults are required\n\t\tif (param.default === undefined) {\n\t\t\trequired.push(name);\n\t\t}\n\t}\n\n\treturn Type.Object(properties, { required });\n}\n\n/**\n * Execute a command with parameters passed via stdin\n */\nasync function executeCommand(\n\tcommand: string,\n\tparams: Record<string, unknown>,\n\toptions: {\n\t\tcwd?: string;\n\t\tenv?: Record<string, string>;\n\t\ttimeout?: number;\n\t\tsignal?: AbortSignal;\n\t},\n): Promise<{\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n\tstdoutTruncated: boolean;\n\tstderrTruncated: boolean;\n}> {\n\treturn new Promise((resolvePromise, rejectPromise) => {\n\t\tconst cwd = options.cwd\n\t\t\t? resolve(expandTildePath(options.cwd))\n\t\t\t: process.cwd();\n\t\tconst timeout = options.timeout ?? 120000; // 2 minute default\n\n\t\tconst env = resolveShellEnvironment(options.env, {\n\t\t\tworkspaceDir: process.cwd(),\n\t\t});\n\n\t\t// Spawn the command in shell mode for compatibility\n\t\tconst child = spawn(command, [], {\n\t\t\tshell: true,\n\t\t\tcwd,\n\t\t\tenv,\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t});\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\t\tlet stdoutTruncated = false;\n\t\tlet stderrTruncated = false;\n\t\tlet killed = false;\n\t\tlet settled = false;\n\n\t\tconst resolveOnce = (value: {\n\t\t\tstdout: string;\n\t\t\tstderr: string;\n\t\t\texitCode: number;\n\t\t\tstdoutTruncated: boolean;\n\t\t\tstderrTruncated: boolean;\n\t\t}) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tresolvePromise(value);\n\t\t};\n\n\t\tconst rejectOnce = (error: Error) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\trejectPromise(error);\n\t\t};\n\n\t\t// Handle timeout\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\tkilled = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t\trejectOnce(new Error(`Command timed out after ${timeout}ms`));\n\t\t}, timeout);\n\n\t\t// Handle abort signal\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener(\"abort\", () => {\n\t\t\t\tkilled = true;\n\t\t\t\tchild.kill(\"SIGTERM\");\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(new Error(\"Command aborted\"));\n\t\t\t});\n\t\t}\n\n\t\tchild.stdout?.on(\"data\", (data) => {\n\t\t\tif (stdout.length < MAX_INLINE_BUFFER) {\n\t\t\t\tstdout += data.toString();\n\t\t\t\tif (stdout.length > MAX_INLINE_BUFFER) {\n\t\t\t\t\tstdout = stdout.slice(0, MAX_INLINE_BUFFER);\n\t\t\t\t\tstdoutTruncated = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstdoutTruncated = true;\n\t\t\t}\n\t\t});\n\n\t\tchild.stderr?.on(\"data\", (data) => {\n\t\t\tif (stderr.length < MAX_INLINE_BUFFER) {\n\t\t\t\tstderr += data.toString();\n\t\t\t\tif (stderr.length > MAX_INLINE_BUFFER) {\n\t\t\t\t\tstderr = stderr.slice(0, MAX_INLINE_BUFFER);\n\t\t\t\t\tstderrTruncated = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstderrTruncated = true;\n\t\t\t}\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tclearTimeout(timeoutId);\n\t\t\trejectOnce(error);\n\t\t});\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (!killed) {\n\t\t\t\tresolveOnce({\n\t\t\t\t\tstdout,\n\t\t\t\t\tstderr,\n\t\t\t\t\texitCode: code ?? 0,\n\t\t\t\t\tstdoutTruncated,\n\t\t\t\t\tstderrTruncated,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Send parameters as JSON via stdin\n\t\tconst input = JSON.stringify(params);\n\t\tif (child.stdin) {\n\t\t\tchild.stdin.on(\"error\", (error) => {\n\t\t\t\t// If the child exits quickly (e.g. `exit 1`), stdin may be closed before\n\t\t\t\t// we can write. Treat EPIPE as non-fatal and rely on the exit code.\n\t\t\t\tif (\n\t\t\t\t\terror &&\n\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t\"code\" in error &&\n\t\t\t\t\t(error as { code?: string }).code === \"EPIPE\"\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(error instanceof Error ? error : new Error(String(error)));\n\t\t\t});\n\n\t\t\tchild.stdin.write(input, (err) => {\n\t\t\t\tif (!err) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\ttypeof err === \"object\" &&\n\t\t\t\t\terr !== null &&\n\t\t\t\t\t\"code\" in err &&\n\t\t\t\t\t(err as { code?: string }).code === \"EPIPE\"\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t\tchild.stdin.end();\n\t\t}\n\t});\n}\n\n/**\n * Create an AgentTool from an inline tool definition\n */\nfunction createInlineTool(def: InlineToolDef): AgentTool {\n\tconst schema = buildSchema(def.parameters);\n\n\t// Map annotations to tool annotations\n\tconst annotations: ToolAnnotations | undefined = def.annotations\n\t\t? {\n\t\t\t\treadOnlyHint: def.annotations.readOnly,\n\t\t\t\tdestructiveHint: def.annotations.destructive,\n\t\t\t}\n\t\t: undefined;\n\n\treturn createTool({\n\t\tname: def.name,\n\t\tlabel: def.name,\n\t\tdescription: def.description,\n\t\tschema,\n\t\tannotations,\n\t\ttoolType: \"shell\",\n\t\trun: async (params, context) => {\n\t\t\ttry {\n\t\t\t\tconst result = await executeCommand(\n\t\t\t\t\tdef.command,\n\t\t\t\t\tparams as Record<string, unknown>,\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: def.cwd,\n\t\t\t\t\t\tenv: def.env,\n\t\t\t\t\t\ttimeout: def.timeout,\n\t\t\t\t\t\tsignal: context.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tconst truncationMessages: string[] = [];\n\t\t\t\tif (result.stdoutTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stdout exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (result.stderrTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stderr exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst truncationNotice =\n\t\t\t\t\ttruncationMessages.length > 0\n\t\t\t\t\t\t? `Warning: Output truncated: ${truncationMessages.join(\n\t\t\t\t\t\t\t\t\"; \",\n\t\t\t\t\t\t\t)}. Consider piping output to a file or using head/tail.`\n\t\t\t\t\t\t: \"\";\n\n\t\t\t\tif (result.exitCode !== 0) {\n\t\t\t\t\tconst baseError =\n\t\t\t\t\t\tresult.stderr.trim() || `Exit code: ${result.exitCode}`;\n\t\t\t\t\tconst errorMsg = truncationNotice\n\t\t\t\t\t\t? `${baseError}\\n\\n${truncationNotice}`\n\t\t\t\t\t\t: baseError;\n\t\t\t\t\treturn context.respond.error(\n\t\t\t\t\t\t`Command failed: ${errorMsg}\\n\\nStdout:\\n${result.stdout}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Return stdout as the result\n\t\t\t\tconst output = result.stdout.trim();\n\t\t\t\tif (result.stderr.trim()) {\n\t\t\t\t\tconst combined = output\n\t\t\t\t\t\t? `${output}\\n\\n[stderr]: ${result.stderr.trim()}`\n\t\t\t\t\t\t: `[stderr]: ${result.stderr.trim()}`;\n\t\t\t\t\treturn context.respond.text(\n\t\t\t\t\t\ttruncationNotice ? `${combined}\\n\\n${truncationNotice}` : combined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (truncationNotice) {\n\t\t\t\t\tconst text = output\n\t\t\t\t\t\t? `${output}\\n\\n${truncationNotice}`\n\t\t\t\t\t\t: truncationNotice;\n\t\t\t\t\treturn context.respond.text(text);\n\t\t\t\t}\n\t\t\t\treturn context.respond.text(output || \"(no output)\");\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\treturn context.respond.error(`Failed to execute command: ${message}`);\n\t\t\t}\n\t\t},\n\t}) as AgentTool;\n}\n\n/**\n * Load inline tools configuration from a file\n */\nfunction loadConfigFile(filePath: string): InlineToolsConfig | null {\n\tif (!existsSync(filePath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst contents = readFileSync(filePath, \"utf8\");\n\t\tconst config = JSON.parse(contents) as InlineToolsConfig;\n\n\t\t// Basic validation\n\t\tif (!config.tools || !Array.isArray(config.tools)) {\n\t\t\tlogger.warn(\"Invalid inline tools config: missing 'tools' array\", {\n\t\t\t\tfilePath,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t\"Failed to load inline tools config\",\n\t\t\terror instanceof Error ? error : undefined,\n\t\t\t{ filePath },\n\t\t);\n\t\treturn null;\n\t}\n}\n\n/**\n * Validate an inline tool definition\n */\nfunction validateToolDef(def: InlineToolDef, source: string): string[] {\n\tconst errors: string[] = [];\n\n\tif (!def.name || typeof def.name !== \"string\") {\n\t\terrors.push(`Tool missing required 'name' field in ${source}`);\n\t} else if (!/^[a-z][a-z0-9_-]*$/i.test(def.name)) {\n\t\terrors.push(\n\t\t\t`Invalid tool name '${def.name}' in ${source}: must start with letter and contain only letters, numbers, underscores, hyphens`,\n\t\t);\n\t}\n\n\tif (!def.description || typeof def.description !== \"string\") {\n\t\terrors.push(\n\t\t\t`Tool '${def.name}' missing required 'description' in ${source}`,\n\t\t);\n\t}\n\n\tif (!def.command || typeof def.command !== \"string\") {\n\t\terrors.push(`Tool '${def.name}' missing required 'command' in ${source}`);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Load all inline tools from project and user configuration files\n *\n * @param projectDir - Project directory (defaults to cwd)\n * @returns Array of AgentTools created from inline definitions\n */\nexport function loadInlineTools(projectDir?: string): AgentTool[] {\n\tconst cwd = projectDir ?? process.cwd();\n\tconst tools: AgentTool[] = [];\n\tconst loadedNames = new Set<string>();\n\n\t// Load project-level config first (higher priority)\n\tconst projectConfigPath = join(cwd, \".maestro\", \"tools.json\");\n\tconst projectConfig = loadConfigFile(projectConfigPath);\n\n\tif (projectConfig) {\n\t\tfor (const def of projectConfig.tools) {\n\t\t\tconst errors = validateToolDef(def, projectConfigPath);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tfor (const error of errors) {\n\t\t\t\t\tlogger.warn(error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst tool = createInlineTool(def);\n\t\t\t\ttools.push(tool);\n\t\t\t\tloadedNames.add(def.name);\n\t\t\t\tlogger.debug(\"Loaded inline tool\", {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\tsource: \"project\",\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Failed to create inline tool '${def.name}'`,\n\t\t\t\t\terror instanceof Error ? error : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load user-level config (lower priority, skip if name already loaded)\n\tconst userConfigPath = join(PATHS.MAESTRO_HOME, \"tools.json\");\n\tconst userConfig = loadConfigFile(userConfigPath);\n\n\tif (userConfig) {\n\t\tfor (const def of userConfig.tools) {\n\t\t\t// Skip if project already defined a tool with this name\n\t\t\tif (loadedNames.has(def.name)) {\n\t\t\t\tlogger.debug(\"Skipping user tool (overridden by project)\", {\n\t\t\t\t\tname: def.name,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst errors = validateToolDef(def, userConfigPath);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tfor (const error of errors) {\n\t\t\t\t\tlogger.warn(error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst tool = createInlineTool(def);\n\t\t\t\ttools.push(tool);\n\t\t\t\tloadedNames.add(def.name);\n\t\t\t\tlogger.debug(\"Loaded inline tool\", { name: def.name, source: \"user\" });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Failed to create inline tool '${def.name}'`,\n\t\t\t\t\terror instanceof Error ? error : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (tools.length > 0) {\n\t\tlogger.info(\"Loaded inline tools\", { count: tools.length });\n\t}\n\n\treturn tools;\n}\n\n/**\n * Get the paths where inline tools config files are expected\n */\nexport function getInlineToolsConfigPaths(projectDir?: string): {\n\tproject: string;\n\tuser: string;\n} {\n\tconst cwd = projectDir ?? process.cwd();\n\treturn {\n\t\tproject: join(cwd, \".maestro\", \"tools.json\"),\n\t\tuser: join(PATHS.MAESTRO_HOME, \"tools.json\"),\n\t};\n}\n"]}
1
+ {"version":3,"file":"inline-tools.js","sourceRoot":"","sources":["../../src/tools/inline-tools.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Inline Tool Definitions - Load custom tools from .maestro/tools.json\n *\n * Allows users to define shell-based tools without requiring full MCP server setup.\n * Tools receive parameters as JSON via stdin and return results via stdout.\n *\n * ## Configuration\n *\n * Project-level: `.maestro/tools.json`\n * User-level: `~/.maestro/tools.json`\n *\n * Project tools override user tools with the same name.\n *\n * ## Format\n *\n * ```json\n * {\n * \"tools\": [\n * {\n * \"name\": \"deploy\",\n * \"description\": \"Deploy to an environment\",\n * \"command\": \"./scripts/deploy.sh\",\n * \"parameters\": {\n * \"environment\": {\n * \"type\": \"string\",\n * \"enum\": [\"staging\", \"prod\"],\n * \"description\": \"Target environment\"\n * }\n * }\n * }\n * ]\n * }\n * ```\n *\n * @module tools/inline-tools\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { type TSchema, Type } from \"@sinclair/typebox\";\nimport type { AgentTool, ToolAnnotations } from \"../agent/types.js\";\nimport { PATHS } from \"../config/constants.js\";\nimport { createLogger } from \"../utils/logger.js\";\nimport { expandTildePath } from \"../utils/path-expansion.js\";\nimport { sanitizeWithStaticMask } from \"../utils/secret-redactor.js\";\nimport { resolveShellEnvironment } from \"../utils/shell-env.js\";\nimport { createTool } from \"./tool-dsl.js\";\n\nconst logger = createLogger(\"inline-tools\");\n\n// Output buffer limit (40KB) to prevent memory exhaustion from verbose inline tools.\nconst MAX_INLINE_BUFFER = 40 * 1024;\n\n/**\n * JSON Schema parameter definition (simplified subset)\n */\ninterface InlineParameterDef {\n\ttype: \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\" | \"object\";\n\tdescription?: string;\n\tenum?: (string | number)[];\n\tdefault?: unknown;\n\titems?: InlineParameterDef;\n}\n\n/**\n * Inline tool definition from .maestro/tools.json\n */\ninterface InlineToolDef {\n\tname: string;\n\tdescription: string;\n\tcommand: string;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tparameters?: Record<string, InlineParameterDef>;\n\ttimeout?: number;\n\t/** Tool behavior hints */\n\tannotations?: {\n\t\treadOnly?: boolean;\n\t\tdestructive?: boolean;\n\t\trequiresApproval?: boolean;\n\t};\n}\n\n/**\n * Configuration file format\n */\ninterface InlineToolsConfig {\n\ttools: InlineToolDef[];\n}\n\n/**\n * Convert a parameter definition to a TypeBox schema\n */\nfunction parameterToTypeBox(name: string, param: InlineParameterDef): TSchema {\n\tconst options: Record<string, unknown> = {};\n\tif (param.description) {\n\t\toptions.description = param.description;\n\t}\n\tif (param.default !== undefined) {\n\t\toptions.default = param.default;\n\t}\n\n\tswitch (param.type) {\n\t\tcase \"string\":\n\t\t\tif (param.enum) {\n\t\t\t\treturn Type.Union(\n\t\t\t\t\tparam.enum.map((v) => Type.Literal(v as string)),\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Type.String(options);\n\t\tcase \"number\":\n\t\t\treturn Type.Number(options);\n\t\tcase \"integer\":\n\t\t\treturn Type.Integer(options);\n\t\tcase \"boolean\":\n\t\t\treturn Type.Boolean(options);\n\t\tcase \"array\":\n\t\t\tif (param.items) {\n\t\t\t\treturn Type.Array(\n\t\t\t\t\tparameterToTypeBox(`${name}[]`, param.items),\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn Type.Array(Type.Unknown(), options);\n\t\tcase \"object\":\n\t\t\treturn Type.Object({}, options);\n\t\tdefault:\n\t\t\treturn Type.Unknown(options);\n\t}\n}\n\n/**\n * Build a TypeBox schema from inline tool parameters\n */\nfunction buildSchema(parameters?: Record<string, InlineParameterDef>): TSchema {\n\tif (!parameters || Object.keys(parameters).length === 0) {\n\t\treturn Type.Object({});\n\t}\n\n\tconst properties: Record<string, TSchema> = {};\n\tconst required: string[] = [];\n\n\tfor (const [name, param] of Object.entries(parameters)) {\n\t\tproperties[name] = parameterToTypeBox(name, param);\n\t\t// Parameters without defaults are required\n\t\tif (param.default === undefined) {\n\t\t\trequired.push(name);\n\t\t}\n\t}\n\n\treturn Type.Object(properties, { required });\n}\n\n/**\n * Execute a command with parameters passed via stdin\n */\nasync function executeCommand(\n\tcommand: string,\n\tparams: Record<string, unknown>,\n\toptions: {\n\t\tcwd?: string;\n\t\tenv?: Record<string, string>;\n\t\ttimeout?: number;\n\t\tsignal?: AbortSignal;\n\t},\n): Promise<{\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n\tstdoutTruncated: boolean;\n\tstderrTruncated: boolean;\n}> {\n\treturn new Promise((resolvePromise, rejectPromise) => {\n\t\tconst cwd = options.cwd\n\t\t\t? resolve(expandTildePath(options.cwd))\n\t\t\t: process.cwd();\n\t\tconst timeout = options.timeout ?? 120000; // 2 minute default\n\n\t\tconst env = resolveShellEnvironment(options.env, {\n\t\t\tworkspaceDir: process.cwd(),\n\t\t});\n\n\t\t// Spawn the command in shell mode for compatibility\n\t\tconst child = spawn(command, [], {\n\t\t\tshell: true,\n\t\t\tcwd,\n\t\t\tenv,\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t});\n\n\t\tlet stdout = \"\";\n\t\tlet stderr = \"\";\n\t\tlet stdoutTruncated = false;\n\t\tlet stderrTruncated = false;\n\t\tlet killed = false;\n\t\tlet settled = false;\n\n\t\tconst resolveOnce = (value: {\n\t\t\tstdout: string;\n\t\t\tstderr: string;\n\t\t\texitCode: number;\n\t\t\tstdoutTruncated: boolean;\n\t\t\tstderrTruncated: boolean;\n\t\t}) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tresolvePromise(value);\n\t\t};\n\n\t\tconst rejectOnce = (error: Error) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\trejectPromise(error);\n\t\t};\n\n\t\t// Handle timeout\n\t\tconst timeoutId = setTimeout(() => {\n\t\t\tkilled = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t\trejectOnce(new Error(`Command timed out after ${timeout}ms`));\n\t\t}, timeout);\n\n\t\t// Handle abort signal\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener(\"abort\", () => {\n\t\t\t\tkilled = true;\n\t\t\t\tchild.kill(\"SIGTERM\");\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(new Error(\"Command aborted\"));\n\t\t\t});\n\t\t}\n\n\t\tchild.stdout?.on(\"data\", (data) => {\n\t\t\tif (stdout.length < MAX_INLINE_BUFFER) {\n\t\t\t\tstdout += data.toString();\n\t\t\t\tif (stdout.length > MAX_INLINE_BUFFER) {\n\t\t\t\t\tstdout = stdout.slice(0, MAX_INLINE_BUFFER);\n\t\t\t\t\tstdoutTruncated = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstdoutTruncated = true;\n\t\t\t}\n\t\t});\n\n\t\tchild.stderr?.on(\"data\", (data) => {\n\t\t\tif (stderr.length < MAX_INLINE_BUFFER) {\n\t\t\t\tstderr += data.toString();\n\t\t\t\tif (stderr.length > MAX_INLINE_BUFFER) {\n\t\t\t\t\tstderr = stderr.slice(0, MAX_INLINE_BUFFER);\n\t\t\t\t\tstderrTruncated = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstderrTruncated = true;\n\t\t\t}\n\t\t});\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tclearTimeout(timeoutId);\n\t\t\trejectOnce(error);\n\t\t});\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tclearTimeout(timeoutId);\n\t\t\tif (!killed) {\n\t\t\t\tresolveOnce({\n\t\t\t\t\tstdout,\n\t\t\t\t\tstderr,\n\t\t\t\t\texitCode: code ?? 0,\n\t\t\t\t\tstdoutTruncated,\n\t\t\t\t\tstderrTruncated,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Send parameters as JSON via stdin\n\t\tconst input = JSON.stringify(params);\n\t\tif (child.stdin) {\n\t\t\tchild.stdin.on(\"error\", (error) => {\n\t\t\t\t// If the child exits quickly (e.g. `exit 1`), stdin may be closed before\n\t\t\t\t// we can write. Treat EPIPE as non-fatal and rely on the exit code.\n\t\t\t\tif (\n\t\t\t\t\terror &&\n\t\t\t\t\ttypeof error === \"object\" &&\n\t\t\t\t\t\"code\" in error &&\n\t\t\t\t\t(error as { code?: string }).code === \"EPIPE\"\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(error instanceof Error ? error : new Error(String(error)));\n\t\t\t});\n\n\t\t\tchild.stdin.write(input, (err) => {\n\t\t\t\tif (!err) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\ttypeof err === \"object\" &&\n\t\t\t\t\terr !== null &&\n\t\t\t\t\t\"code\" in err &&\n\t\t\t\t\t(err as { code?: string }).code === \"EPIPE\"\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\trejectOnce(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t\tchild.stdin.end();\n\t\t}\n\t});\n}\n\n/**\n * Create an AgentTool from an inline tool definition\n */\nfunction createInlineTool(def: InlineToolDef): AgentTool {\n\tconst schema = buildSchema(def.parameters);\n\n\t// Map annotations to tool annotations\n\tconst annotations: ToolAnnotations | undefined = def.annotations\n\t\t? {\n\t\t\t\treadOnlyHint: def.annotations.readOnly,\n\t\t\t\tdestructiveHint: def.annotations.destructive,\n\t\t\t}\n\t\t: undefined;\n\n\treturn createTool({\n\t\tname: def.name,\n\t\tlabel: def.name,\n\t\tdescription: def.description,\n\t\tschema,\n\t\tannotations,\n\t\ttoolType: \"shell\",\n\t\trun: async (params, context) => {\n\t\t\ttry {\n\t\t\t\tconst result = await executeCommand(\n\t\t\t\t\tdef.command,\n\t\t\t\t\tparams as Record<string, unknown>,\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: def.cwd,\n\t\t\t\t\t\tenv: def.env,\n\t\t\t\t\t\ttimeout: def.timeout,\n\t\t\t\t\t\tsignal: context.signal,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tconst truncationMessages: string[] = [];\n\t\t\t\tif (result.stdoutTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stdout exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (result.stderrTruncated) {\n\t\t\t\t\tconst displayedKB = Math.round(MAX_INLINE_BUFFER / 1024);\n\t\t\t\t\ttruncationMessages.push(\n\t\t\t\t\t\t`stderr exceeded ${displayedKB}KB limit and was truncated`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst stdout = sanitizeWithStaticMask(result.stdout);\n\t\t\t\tconst stderr = sanitizeWithStaticMask(result.stderr);\n\t\t\t\tconst truncationNotice =\n\t\t\t\t\ttruncationMessages.length > 0\n\t\t\t\t\t\t? `Warning: Output truncated: ${truncationMessages.join(\n\t\t\t\t\t\t\t\t\"; \",\n\t\t\t\t\t\t\t)}. Consider piping output to a file or using head/tail.`\n\t\t\t\t\t\t: \"\";\n\n\t\t\t\tif (result.exitCode !== 0) {\n\t\t\t\t\tconst baseError = stderr.trim() || `Exit code: ${result.exitCode}`;\n\t\t\t\t\tconst errorMsg = truncationNotice\n\t\t\t\t\t\t? `${baseError}\\n\\n${truncationNotice}`\n\t\t\t\t\t\t: baseError;\n\t\t\t\t\treturn context.respond.error(\n\t\t\t\t\t\t`Command failed: ${errorMsg}\\n\\nStdout:\\n${stdout}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Return stdout as the result\n\t\t\t\tconst output = stdout.trim();\n\t\t\t\tif (stderr.trim()) {\n\t\t\t\t\tconst combined = output\n\t\t\t\t\t\t? `${output}\\n\\n[stderr]: ${stderr.trim()}`\n\t\t\t\t\t\t: `[stderr]: ${stderr.trim()}`;\n\t\t\t\t\treturn context.respond.text(\n\t\t\t\t\t\ttruncationNotice ? `${combined}\\n\\n${truncationNotice}` : combined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (truncationNotice) {\n\t\t\t\t\tconst text = output\n\t\t\t\t\t\t? `${output}\\n\\n${truncationNotice}`\n\t\t\t\t\t\t: truncationNotice;\n\t\t\t\t\treturn context.respond.text(text);\n\t\t\t\t}\n\t\t\t\treturn context.respond.text(output || \"(no output)\");\n\t\t\t} catch (error) {\n\t\t\t\tconst message = sanitizeWithStaticMask(\n\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t);\n\t\t\t\treturn context.respond.error(`Failed to execute command: ${message}`);\n\t\t\t}\n\t\t},\n\t}) as AgentTool;\n}\n\n/**\n * Load inline tools configuration from a file\n */\nfunction loadConfigFile(filePath: string): InlineToolsConfig | null {\n\tif (!existsSync(filePath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst contents = readFileSync(filePath, \"utf8\");\n\t\tconst config = JSON.parse(contents) as InlineToolsConfig;\n\n\t\t// Basic validation\n\t\tif (!config.tools || !Array.isArray(config.tools)) {\n\t\t\tlogger.warn(\"Invalid inline tools config: missing 'tools' array\", {\n\t\t\t\tfilePath,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t\"Failed to load inline tools config\",\n\t\t\terror instanceof Error ? error : undefined,\n\t\t\t{ filePath },\n\t\t);\n\t\treturn null;\n\t}\n}\n\n/**\n * Validate an inline tool definition\n */\nfunction validateToolDef(def: InlineToolDef, source: string): string[] {\n\tconst errors: string[] = [];\n\n\tif (!def.name || typeof def.name !== \"string\") {\n\t\terrors.push(`Tool missing required 'name' field in ${source}`);\n\t} else if (!/^[a-z][a-z0-9_-]*$/i.test(def.name)) {\n\t\terrors.push(\n\t\t\t`Invalid tool name '${def.name}' in ${source}: must start with letter and contain only letters, numbers, underscores, hyphens`,\n\t\t);\n\t}\n\n\tif (!def.description || typeof def.description !== \"string\") {\n\t\terrors.push(\n\t\t\t`Tool '${def.name}' missing required 'description' in ${source}`,\n\t\t);\n\t}\n\n\tif (!def.command || typeof def.command !== \"string\") {\n\t\terrors.push(`Tool '${def.name}' missing required 'command' in ${source}`);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Load all inline tools from project and user configuration files\n *\n * @param projectDir - Project directory (defaults to cwd)\n * @returns Array of AgentTools created from inline definitions\n */\nexport function loadInlineTools(projectDir?: string): AgentTool[] {\n\tconst cwd = projectDir ?? process.cwd();\n\tconst tools: AgentTool[] = [];\n\tconst loadedNames = new Set<string>();\n\n\t// Load project-level config first (higher priority)\n\tconst projectConfigPath = join(cwd, \".maestro\", \"tools.json\");\n\tconst projectConfig = loadConfigFile(projectConfigPath);\n\n\tif (projectConfig) {\n\t\tfor (const def of projectConfig.tools) {\n\t\t\tconst errors = validateToolDef(def, projectConfigPath);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tfor (const error of errors) {\n\t\t\t\t\tlogger.warn(error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst tool = createInlineTool(def);\n\t\t\t\ttools.push(tool);\n\t\t\t\tloadedNames.add(def.name);\n\t\t\t\tlogger.debug(\"Loaded inline tool\", {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\tsource: \"project\",\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Failed to create inline tool '${def.name}'`,\n\t\t\t\t\terror instanceof Error ? error : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load user-level config (lower priority, skip if name already loaded)\n\tconst userConfigPath = join(PATHS.MAESTRO_HOME, \"tools.json\");\n\tconst userConfig = loadConfigFile(userConfigPath);\n\n\tif (userConfig) {\n\t\tfor (const def of userConfig.tools) {\n\t\t\t// Skip if project already defined a tool with this name\n\t\t\tif (loadedNames.has(def.name)) {\n\t\t\t\tlogger.debug(\"Skipping user tool (overridden by project)\", {\n\t\t\t\t\tname: def.name,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst errors = validateToolDef(def, userConfigPath);\n\t\t\tif (errors.length > 0) {\n\t\t\t\tfor (const error of errors) {\n\t\t\t\t\tlogger.warn(error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst tool = createInlineTool(def);\n\t\t\t\ttools.push(tool);\n\t\t\t\tloadedNames.add(def.name);\n\t\t\t\tlogger.debug(\"Loaded inline tool\", { name: def.name, source: \"user\" });\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Failed to create inline tool '${def.name}'`,\n\t\t\t\t\terror instanceof Error ? error : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (tools.length > 0) {\n\t\tlogger.info(\"Loaded inline tools\", { count: tools.length });\n\t}\n\n\treturn tools;\n}\n\n/**\n * Get the paths where inline tools config files are expected\n */\nexport function getInlineToolsConfigPaths(projectDir?: string): {\n\tproject: string;\n\tuser: string;\n} {\n\tconst cwd = projectDir ?? process.cwd();\n\treturn {\n\t\tproject: join(cwd, \".maestro\", \"tools.json\"),\n\t\tuser: join(PATHS.MAESTRO_HOME, \"tools.json\"),\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"shell-env.d.ts","sourceRoot":"","sources":["../../src/utils/shell-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,KAAK,sBAAsB,EAAc,MAAM,oBAAoB,CAAC;AAgB7E,MAAM,WAAW,8BAA8B;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAkBD;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,MAAM,CAAC,EAAE,sBAAsB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuDxB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC9C,OAAO,GAAE,8BAAmC,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB"}
1
+ {"version":3,"file":"shell-env.d.ts","sourceRoot":"","sources":["../../src/utils/shell-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,KAAK,sBAAsB,EAAc,MAAM,oBAAoB,CAAC;AA2C7E,MAAM,WAAW,8BAA8B;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,sBAAsB,CAAC;CAChC;AA6DD;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,MAAM,CAAC,EAAE,sBAAsB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyDxB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC9C,OAAO,GAAE,8BAAmC,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB"}
@@ -22,6 +22,33 @@ const CORE_ENV_VARS = [
22
22
  "TMP",
23
23
  ];
24
24
  const DEFAULT_EXCLUDES = ["*KEY*", "*SECRET*", "*TOKEN*"];
25
+ const PLATFORM_WORKER_SURFACE = "platform-agent-runtime";
26
+ const PLATFORM_TRUSTED_TOOL_ENV_FLAG = "MAESTRO_PLATFORM_TRUSTED_TOOL_ENV";
27
+ const PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST = [
28
+ "CODEX_WORKER_GIT_TOKEN",
29
+ "CODEX_WORKER_GIT_USERNAME",
30
+ "GH_TOKEN",
31
+ "GITHUB_TOKEN",
32
+ "GIT_ASKPASS",
33
+ "GIT_TERMINAL_PROMPT",
34
+ "CODEX_WORKER_RUNTIME_TOKEN",
35
+ "AGENT_RUNTIME_TOKEN",
36
+ "MAESTRO_AGENT_RUNTIME_SERVICE_TOKEN",
37
+ "AGENT_RUNTIME_SERVICE_TOKEN",
38
+ "MAESTRO_PLATFORM_A2A_TOKEN",
39
+ "MAESTRO_AGENT_OPERATING_PLANE_TOKEN",
40
+ "CODEX_WORKER_AGENT_REGISTRY_TOKEN",
41
+ "AGENT_REGISTRY_SERVICE_TOKEN",
42
+ "MAESTRO_AGENT_REGISTRY_SERVICE_TOKEN",
43
+ "MAESTRO_PLATFORM_A2A_ENABLED",
44
+ "MAESTRO_AGENT_RUNTIME_A2A_ENABLED",
45
+ "MAESTRO_PLATFORM_A2A_EXTENSIONS",
46
+ "MAESTRO_AGENT_RUNTIME_SERVICE_URL",
47
+ "MAESTRO_PLATFORM_A2A_URL",
48
+ "MAESTRO_AGENT_REGISTRY_SERVICE_URL",
49
+ "MAESTRO_AGENT_RUNTIME_ORG_ID",
50
+ "MAESTRO_AGENT_RUNTIME_WORKSPACE_ID",
51
+ ];
25
52
  function matchesAny(name, patterns) {
26
53
  return patterns.some((pattern) => minimatch(name, pattern, { nocase: true, dot: true }));
27
54
  }
@@ -34,6 +61,43 @@ function coerceEnv(env) {
34
61
  }
35
62
  return result;
36
63
  }
64
+ function isTruthyEnv(value) {
65
+ if (!value) {
66
+ return false;
67
+ }
68
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
69
+ }
70
+ function restorePlatformTrustedToolEnv(env, base, policy) {
71
+ if (base.MAESTRO_SURFACE !== PLATFORM_WORKER_SURFACE) {
72
+ return;
73
+ }
74
+ if (!isTruthyEnv(base[PLATFORM_TRUSTED_TOOL_ENV_FLAG])) {
75
+ return;
76
+ }
77
+ const inherit = policy.inherit ?? "all";
78
+ const coreSet = new Set(CORE_ENV_VARS.map((name) => name.toUpperCase()));
79
+ for (const key of PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST) {
80
+ if (inherit === "none") {
81
+ continue;
82
+ }
83
+ if (inherit === "core" && !coreSet.has(key.toUpperCase())) {
84
+ continue;
85
+ }
86
+ if (policy.exclude?.length && matchesAny(key, policy.exclude)) {
87
+ continue;
88
+ }
89
+ if (policy.include_only?.length && !matchesAny(key, policy.include_only)) {
90
+ continue;
91
+ }
92
+ if (policy.set && Object.prototype.hasOwnProperty.call(policy.set, key)) {
93
+ continue;
94
+ }
95
+ const value = base[key];
96
+ if (typeof value === "string") {
97
+ env[key] = value;
98
+ }
99
+ }
100
+ }
37
101
  /**
38
102
  * Apply a ShellEnvironmentPolicy to a base environment map.
39
103
  */
@@ -86,6 +150,7 @@ export function applyShellEnvironmentPolicy(baseEnv, policy) {
86
150
  }
87
151
  }
88
152
  }
153
+ restorePlatformTrustedToolEnv(env, base, resolvedPolicy);
89
154
  return env;
90
155
  }
91
156
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../src/utils/shell-env.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shell Environment Policy - Filtered environment for user-command execution\n *\n * Applies a configurable policy to the process environment before passing it\n * to shell-based tools (bash/background tasks/sandboxed exec).\n *\n * By default, variables containing KEY/SECRET/TOKEN are excluded to reduce\n * accidental credential leakage into arbitrary commands. Use\n * `shell_environment_policy.ignore_default_excludes = true` to opt out.\n */\n\nimport { minimatch } from \"minimatch\";\nimport { type ShellEnvironmentPolicy, loadConfig } from \"../config/index.js\";\n\nconst CORE_ENV_VARS = [\n\t\"HOME\",\n\t\"LOGNAME\",\n\t\"PATH\",\n\t\"SHELL\",\n\t\"USER\",\n\t\"USERNAME\",\n\t\"TMPDIR\",\n\t\"TEMP\",\n\t\"TMP\",\n];\n\nconst DEFAULT_EXCLUDES = [\"*KEY*\", \"*SECRET*\", \"*TOKEN*\"];\n\nexport interface ResolveShellEnvironmentOptions {\n\tbaseEnv?: NodeJS.ProcessEnv;\n\tworkspaceDir?: string;\n\tpolicy?: ShellEnvironmentPolicy;\n}\n\nfunction matchesAny(name: string, patterns: string[]): boolean {\n\treturn patterns.some((pattern) =>\n\t\tminimatch(name, pattern, { nocase: true, dot: true }),\n\t);\n}\n\nfunction coerceEnv(env: NodeJS.ProcessEnv): Record<string, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(env)) {\n\t\tif (typeof value === \"string\") {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Apply a ShellEnvironmentPolicy to a base environment map.\n */\nexport function applyShellEnvironmentPolicy(\n\tbaseEnv: NodeJS.ProcessEnv,\n\tpolicy?: ShellEnvironmentPolicy,\n): Record<string, string> {\n\tconst resolvedPolicy: ShellEnvironmentPolicy = policy ?? {\n\t\tinherit: \"all\",\n\t\tignore_default_excludes: false,\n\t};\n\tconst inherit = resolvedPolicy.inherit ?? \"all\";\n\tconst ignoreDefaultExcludes = resolvedPolicy.ignore_default_excludes ?? false;\n\n\tconst base = coerceEnv(baseEnv);\n\tlet env: Record<string, string> = {};\n\n\tif (inherit === \"core\") {\n\t\tconst coreSet = new Set(CORE_ENV_VARS.map((name) => name.toUpperCase()));\n\t\tfor (const [key, value] of Object.entries(base)) {\n\t\t\tif (coreSet.has(key.toUpperCase())) {\n\t\t\t\tenv[key] = value;\n\t\t\t}\n\t\t}\n\t} else if (inherit === \"none\") {\n\t\tenv = {};\n\t} else {\n\t\tenv = { ...base };\n\t}\n\n\tif (!ignoreDefaultExcludes) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (matchesAny(key, DEFAULT_EXCLUDES)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (resolvedPolicy.exclude?.length) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (matchesAny(key, resolvedPolicy.exclude)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (resolvedPolicy.set) {\n\t\tfor (const [key, value] of Object.entries(resolvedPolicy.set)) {\n\t\t\tenv[key] = value;\n\t\t}\n\t}\n\n\tif (resolvedPolicy.include_only?.length) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (!matchesAny(key, resolvedPolicy.include_only)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn env;\n}\n\n/**\n * Resolve the effective shell environment for a command.\n *\n * Applies config policy, then merges explicit overrides (always win).\n */\nexport function resolveShellEnvironment(\n\toverrides?: Record<string, string | undefined>,\n\toptions: ResolveShellEnvironmentOptions = {},\n): Record<string, string> {\n\tconst workspaceDir = options.workspaceDir ?? process.cwd();\n\tconst configPolicy =\n\t\toptions.policy ?? loadConfig(workspaceDir).shell_environment_policy;\n\tconst env = applyShellEnvironmentPolicy(\n\t\toptions.baseEnv ?? process.env,\n\t\tconfigPolicy,\n\t);\n\tif (overrides) {\n\t\tfor (const [key, value] of Object.entries(overrides)) {\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tenv[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn env;\n}\n"]}
1
+ {"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../src/utils/shell-env.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shell Environment Policy - Filtered environment for user-command execution\n *\n * Applies a configurable policy to the process environment before passing it\n * to shell-based tools (bash/background tasks/sandboxed exec).\n *\n * By default, variables containing KEY/SECRET/TOKEN are excluded to reduce\n * accidental credential leakage into arbitrary commands. Use\n * `shell_environment_policy.ignore_default_excludes = true` to opt out.\n */\n\nimport { minimatch } from \"minimatch\";\nimport { type ShellEnvironmentPolicy, loadConfig } from \"../config/index.js\";\n\nconst CORE_ENV_VARS = [\n\t\"HOME\",\n\t\"LOGNAME\",\n\t\"PATH\",\n\t\"SHELL\",\n\t\"USER\",\n\t\"USERNAME\",\n\t\"TMPDIR\",\n\t\"TEMP\",\n\t\"TMP\",\n];\n\nconst DEFAULT_EXCLUDES = [\"*KEY*\", \"*SECRET*\", \"*TOKEN*\"];\nconst PLATFORM_WORKER_SURFACE = \"platform-agent-runtime\";\nconst PLATFORM_TRUSTED_TOOL_ENV_FLAG = \"MAESTRO_PLATFORM_TRUSTED_TOOL_ENV\";\nconst PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST = [\n\t\"CODEX_WORKER_GIT_TOKEN\",\n\t\"CODEX_WORKER_GIT_USERNAME\",\n\t\"GH_TOKEN\",\n\t\"GITHUB_TOKEN\",\n\t\"GIT_ASKPASS\",\n\t\"GIT_TERMINAL_PROMPT\",\n\t\"CODEX_WORKER_RUNTIME_TOKEN\",\n\t\"AGENT_RUNTIME_TOKEN\",\n\t\"MAESTRO_AGENT_RUNTIME_SERVICE_TOKEN\",\n\t\"AGENT_RUNTIME_SERVICE_TOKEN\",\n\t\"MAESTRO_PLATFORM_A2A_TOKEN\",\n\t\"MAESTRO_AGENT_OPERATING_PLANE_TOKEN\",\n\t\"CODEX_WORKER_AGENT_REGISTRY_TOKEN\",\n\t\"AGENT_REGISTRY_SERVICE_TOKEN\",\n\t\"MAESTRO_AGENT_REGISTRY_SERVICE_TOKEN\",\n\t\"MAESTRO_PLATFORM_A2A_ENABLED\",\n\t\"MAESTRO_AGENT_RUNTIME_A2A_ENABLED\",\n\t\"MAESTRO_PLATFORM_A2A_EXTENSIONS\",\n\t\"MAESTRO_AGENT_RUNTIME_SERVICE_URL\",\n\t\"MAESTRO_PLATFORM_A2A_URL\",\n\t\"MAESTRO_AGENT_REGISTRY_SERVICE_URL\",\n\t\"MAESTRO_AGENT_RUNTIME_ORG_ID\",\n\t\"MAESTRO_AGENT_RUNTIME_WORKSPACE_ID\",\n];\n\nexport interface ResolveShellEnvironmentOptions {\n\tbaseEnv?: NodeJS.ProcessEnv;\n\tworkspaceDir?: string;\n\tpolicy?: ShellEnvironmentPolicy;\n}\n\nfunction matchesAny(name: string, patterns: string[]): boolean {\n\treturn patterns.some((pattern) =>\n\t\tminimatch(name, pattern, { nocase: true, dot: true }),\n\t);\n}\n\nfunction coerceEnv(env: NodeJS.ProcessEnv): Record<string, string> {\n\tconst result: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(env)) {\n\t\tif (typeof value === \"string\") {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction isTruthyEnv(value?: string): boolean {\n\tif (!value) {\n\t\treturn false;\n\t}\n\treturn [\"1\", \"true\", \"yes\", \"on\"].includes(value.toLowerCase());\n}\n\nfunction restorePlatformTrustedToolEnv(\n\tenv: Record<string, string>,\n\tbase: Record<string, string>,\n\tpolicy: ShellEnvironmentPolicy,\n): void {\n\tif (base.MAESTRO_SURFACE !== PLATFORM_WORKER_SURFACE) {\n\t\treturn;\n\t}\n\tif (!isTruthyEnv(base[PLATFORM_TRUSTED_TOOL_ENV_FLAG])) {\n\t\treturn;\n\t}\n\tconst inherit = policy.inherit ?? \"all\";\n\tconst coreSet = new Set(CORE_ENV_VARS.map((name) => name.toUpperCase()));\n\tfor (const key of PLATFORM_TRUSTED_TOOL_ENV_ALLOWLIST) {\n\t\tif (inherit === \"none\") {\n\t\t\tcontinue;\n\t\t}\n\t\tif (inherit === \"core\" && !coreSet.has(key.toUpperCase())) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (policy.exclude?.length && matchesAny(key, policy.exclude)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (policy.include_only?.length && !matchesAny(key, policy.include_only)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (policy.set && Object.prototype.hasOwnProperty.call(policy.set, key)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst value = base[key];\n\t\tif (typeof value === \"string\") {\n\t\t\tenv[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Apply a ShellEnvironmentPolicy to a base environment map.\n */\nexport function applyShellEnvironmentPolicy(\n\tbaseEnv: NodeJS.ProcessEnv,\n\tpolicy?: ShellEnvironmentPolicy,\n): Record<string, string> {\n\tconst resolvedPolicy: ShellEnvironmentPolicy = policy ?? {\n\t\tinherit: \"all\",\n\t\tignore_default_excludes: false,\n\t};\n\tconst inherit = resolvedPolicy.inherit ?? \"all\";\n\tconst ignoreDefaultExcludes = resolvedPolicy.ignore_default_excludes ?? false;\n\n\tconst base = coerceEnv(baseEnv);\n\tlet env: Record<string, string> = {};\n\n\tif (inherit === \"core\") {\n\t\tconst coreSet = new Set(CORE_ENV_VARS.map((name) => name.toUpperCase()));\n\t\tfor (const [key, value] of Object.entries(base)) {\n\t\t\tif (coreSet.has(key.toUpperCase())) {\n\t\t\t\tenv[key] = value;\n\t\t\t}\n\t\t}\n\t} else if (inherit === \"none\") {\n\t\tenv = {};\n\t} else {\n\t\tenv = { ...base };\n\t}\n\n\tif (!ignoreDefaultExcludes) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (matchesAny(key, DEFAULT_EXCLUDES)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (resolvedPolicy.exclude?.length) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (matchesAny(key, resolvedPolicy.exclude)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\tif (resolvedPolicy.set) {\n\t\tfor (const [key, value] of Object.entries(resolvedPolicy.set)) {\n\t\t\tenv[key] = value;\n\t\t}\n\t}\n\n\tif (resolvedPolicy.include_only?.length) {\n\t\tfor (const key of Object.keys(env)) {\n\t\t\tif (!matchesAny(key, resolvedPolicy.include_only)) {\n\t\t\t\tdelete env[key];\n\t\t\t}\n\t\t}\n\t}\n\n\trestorePlatformTrustedToolEnv(env, base, resolvedPolicy);\n\n\treturn env;\n}\n\n/**\n * Resolve the effective shell environment for a command.\n *\n * Applies config policy, then merges explicit overrides (always win).\n */\nexport function resolveShellEnvironment(\n\toverrides?: Record<string, string | undefined>,\n\toptions: ResolveShellEnvironmentOptions = {},\n): Record<string, string> {\n\tconst workspaceDir = options.workspaceDir ?? process.cwd();\n\tconst configPolicy =\n\t\toptions.policy ?? loadConfig(workspaceDir).shell_environment_policy;\n\tconst env = applyShellEnvironmentPolicy(\n\t\toptions.baseEnv ?? process.env,\n\t\tconfigPolicy,\n\t);\n\tif (overrides) {\n\t\tfor (const [key, value] of Object.entries(overrides)) {\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tenv[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn env;\n}\n"]}
package/dist/version.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "0.10.33",
3
- "notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.33 is now available."
2
+ "version": "0.10.37",
3
+ "notes": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development v0.10.37 is now available."
4
4
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@evalops/maestro",
3
3
  "description": "Maestro by EvalOps - Deterministic coding agent with TUI/CLI and Web UI for AI-assisted development",
4
- "version": "0.10.33",
4
+ "version": "0.10.37",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "workspaces": [