rterm-backend 3.7.7 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/gybackend.cjs +1712 -517
  2. package/package.json +1 -1
package/bin/gybackend.cjs CHANGED
@@ -11,10 +11,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
11
  var __getOwnPropNames = Object.getOwnPropertyNames;
12
12
  var __getProtoOf = Object.getPrototypeOf;
13
13
  var __hasOwnProp = Object.prototype.hasOwnProperty;
14
- var __glob = (map3) => (path33) => {
15
- var fn = map3[path33];
14
+ var __glob = (map3) => (path34) => {
15
+ var fn = map3[path34];
16
16
  if (fn) return fn();
17
- throw new Error("Module not found in bundle: " + path33);
17
+ throw new Error("Module not found in bundle: " + path34);
18
18
  };
19
19
  var __esm = (fn, res) => function __init() {
20
20
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
@@ -9040,7 +9040,7 @@ var require_eventemitter3 = __commonJS({
9040
9040
  if (listeners.fn) return 1;
9041
9041
  return listeners.length;
9042
9042
  };
9043
- EventEmitter4.prototype.emit = function emit11(event, a1, a2, a3, a4, a5) {
9043
+ EventEmitter4.prototype.emit = function emit12(event, a1, a2, a3, a4, a5) {
9044
9044
  var evt = prefix ? prefix + event : event;
9045
9045
  if (!this._events[evt]) return false;
9046
9046
  var listeners = this._events[evt], len = arguments.length, args, i;
@@ -12024,8 +12024,8 @@ var init_parseUtil = __esm({
12024
12024
  init_errors();
12025
12025
  init_en();
12026
12026
  makeIssue = (params) => {
12027
- const { data, path: path33, errorMaps, issueData } = params;
12028
- const fullPath = [...path33, ...issueData.path || []];
12027
+ const { data, path: path34, errorMaps, issueData } = params;
12028
+ const fullPath = [...path34, ...issueData.path || []];
12029
12029
  const fullIssue = {
12030
12030
  ...issueData,
12031
12031
  path: fullPath
@@ -12333,11 +12333,11 @@ var init_types = __esm({
12333
12333
  init_parseUtil();
12334
12334
  init_util();
12335
12335
  ParseInputLazyPath = class {
12336
- constructor(parent, value, path33, key) {
12336
+ constructor(parent, value, path34, key) {
12337
12337
  this._cachedPath = [];
12338
12338
  this.parent = parent;
12339
12339
  this.data = value;
12340
- this._path = path33;
12340
+ this._path = path34;
12341
12341
  this._key = key;
12342
12342
  }
12343
12343
  get path() {
@@ -27268,11 +27268,11 @@ var require_pdf_worker = __commonJS({
27268
27268
  var nameTree = new NameTree(nameTreeRef, xref);
27269
27269
  var names = nameTree.getAll();
27270
27270
  for (var name in names) {
27271
- var fs24 = new FileSpec(names[name], xref);
27271
+ var fs25 = new FileSpec(names[name], xref);
27272
27272
  if (!attachments) {
27273
27273
  attachments = /* @__PURE__ */ Object.create(null);
27274
27274
  }
27275
- attachments[(0, _util.stringToPDFString)(name)] = fs24.serializable;
27275
+ attachments[(0, _util.stringToPDFString)(name)] = fs25.serializable;
27276
27276
  }
27277
27277
  }
27278
27278
  return (0, _util.shadow)(this, "attachments", attachments);
@@ -32572,8 +32572,8 @@ var require_pdf_worker = __commonJS({
32572
32572
  if (font.data && (isAddToPathSet || this.options.disableFontFace)) {
32573
32573
  var buildPath = function buildPath2(fontChar) {
32574
32574
  if (!font.renderer.hasBuiltPath(fontChar)) {
32575
- var path33 = font.renderer.getPathJs(fontChar);
32576
- _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path33]);
32575
+ var path34 = font.renderer.getPathJs(fontChar);
32576
+ _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path34]);
32577
32577
  }
32578
32578
  };
32579
32579
  for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -75261,10 +75261,10 @@ var require_pdf = __commonJS({
75261
75261
  ctx.save();
75262
75262
  ctx.beginPath();
75263
75263
  for (var i = 0; i < paths.length; i++) {
75264
- var path33 = paths[i];
75265
- ctx.setTransform.apply(ctx, path33.transform);
75266
- ctx.translate(path33.x, path33.y);
75267
- path33.addToPath(ctx, path33.fontSize);
75264
+ var path34 = paths[i];
75265
+ ctx.setTransform.apply(ctx, path34.transform);
75266
+ ctx.translate(path34.x, path34.y);
75267
+ path34.addToPath(ctx, path34.fontSize);
75268
75268
  }
75269
75269
  ctx.restore();
75270
75270
  ctx.clip();
@@ -77124,7 +77124,7 @@ var require_pdf = __commonJS({
77124
77124
  throw new TypeError("Cannot call a class as a function");
77125
77125
  }
77126
77126
  }
77127
- var fs24 = require("fs");
77127
+ var fs25 = require("fs");
77128
77128
  var http2 = require("http");
77129
77129
  var https2 = require("https");
77130
77130
  var url2 = require("url");
@@ -77457,8 +77457,8 @@ var require_pdf = __commonJS({
77457
77457
  function PDFNodeStreamFsFullReader2(stream) {
77458
77458
  _classCallCheck(this, PDFNodeStreamFsFullReader2);
77459
77459
  var _this7 = _possibleConstructorReturn(this, (PDFNodeStreamFsFullReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsFullReader2)).call(this, stream));
77460
- var path33 = decodeURI(_this7._url.path);
77461
- fs24.lstat(path33, function(error40, stat) {
77460
+ var path34 = decodeURI(_this7._url.path);
77461
+ fs25.lstat(path34, function(error40, stat) {
77462
77462
  if (error40) {
77463
77463
  _this7._errored = true;
77464
77464
  _this7._reason = error40;
@@ -77466,7 +77466,7 @@ var require_pdf = __commonJS({
77466
77466
  return;
77467
77467
  }
77468
77468
  _this7._contentLength = stat.size;
77469
- _this7._setReadableStream(fs24.createReadStream(path33));
77469
+ _this7._setReadableStream(fs25.createReadStream(path34));
77470
77470
  _this7._headersCapability.resolve();
77471
77471
  });
77472
77472
  return _this7;
@@ -77478,7 +77478,7 @@ var require_pdf = __commonJS({
77478
77478
  function PDFNodeStreamFsRangeReader2(stream, start, end) {
77479
77479
  _classCallCheck(this, PDFNodeStreamFsRangeReader2);
77480
77480
  var _this8 = _possibleConstructorReturn(this, (PDFNodeStreamFsRangeReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsRangeReader2)).call(this, stream));
77481
- _this8._setReadableStream(fs24.createReadStream(decodeURI(_this8._url.path), {
77481
+ _this8._setReadableStream(fs25.createReadStream(decodeURI(_this8._url.path), {
77482
77482
  start,
77483
77483
  end: end - 1
77484
77484
  }));
@@ -89472,11 +89472,11 @@ var require_pdf_worker2 = __commonJS({
89472
89472
  var nameTree = new NameTree(nameTreeRef, xref);
89473
89473
  var names = nameTree.getAll();
89474
89474
  for (var name in names) {
89475
- var fs24 = new FileSpec(names[name], xref);
89475
+ var fs25 = new FileSpec(names[name], xref);
89476
89476
  if (!attachments) {
89477
89477
  attachments = /* @__PURE__ */ Object.create(null);
89478
89478
  }
89479
- attachments[(0, _util.stringToPDFString)(name)] = fs24.serializable;
89479
+ attachments[(0, _util.stringToPDFString)(name)] = fs25.serializable;
89480
89480
  }
89481
89481
  }
89482
89482
  return (0, _util.shadow)(this, "attachments", attachments);
@@ -94776,8 +94776,8 @@ var require_pdf_worker2 = __commonJS({
94776
94776
  if (font.data && (isAddToPathSet || this.options.disableFontFace)) {
94777
94777
  var buildPath = function buildPath2(fontChar) {
94778
94778
  if (!font.renderer.hasBuiltPath(fontChar)) {
94779
- var path33 = font.renderer.getPathJs(fontChar);
94780
- _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path33]);
94779
+ var path34 = font.renderer.getPathJs(fontChar);
94780
+ _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path34]);
94781
94781
  }
94782
94782
  };
94783
94783
  for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -137573,10 +137573,10 @@ var require_pdf2 = __commonJS({
137573
137573
  ctx.save();
137574
137574
  ctx.beginPath();
137575
137575
  for (var i = 0; i < paths.length; i++) {
137576
- var path33 = paths[i];
137577
- ctx.setTransform.apply(ctx, path33.transform);
137578
- ctx.translate(path33.x, path33.y);
137579
- path33.addToPath(ctx, path33.fontSize);
137576
+ var path34 = paths[i];
137577
+ ctx.setTransform.apply(ctx, path34.transform);
137578
+ ctx.translate(path34.x, path34.y);
137579
+ path34.addToPath(ctx, path34.fontSize);
137580
137580
  }
137581
137581
  ctx.restore();
137582
137582
  ctx.clip();
@@ -138960,7 +138960,7 @@ var require_pdf2 = __commonJS({
138960
138960
  throw new TypeError("Cannot call a class as a function");
138961
138961
  }
138962
138962
  }
138963
- var fs24 = require("fs");
138963
+ var fs25 = require("fs");
138964
138964
  var http2 = require("http");
138965
138965
  var https2 = require("https");
138966
138966
  var url2 = require("url");
@@ -139293,8 +139293,8 @@ var require_pdf2 = __commonJS({
139293
139293
  function PDFNodeStreamFsFullReader2(stream) {
139294
139294
  _classCallCheck(this, PDFNodeStreamFsFullReader2);
139295
139295
  var _this7 = _possibleConstructorReturn(this, (PDFNodeStreamFsFullReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsFullReader2)).call(this, stream));
139296
- var path33 = decodeURI(_this7._url.path);
139297
- fs24.lstat(path33, function(error40, stat) {
139296
+ var path34 = decodeURI(_this7._url.path);
139297
+ fs25.lstat(path34, function(error40, stat) {
139298
139298
  if (error40) {
139299
139299
  _this7._errored = true;
139300
139300
  _this7._reason = error40;
@@ -139302,7 +139302,7 @@ var require_pdf2 = __commonJS({
139302
139302
  return;
139303
139303
  }
139304
139304
  _this7._contentLength = stat.size;
139305
- _this7._setReadableStream(fs24.createReadStream(path33));
139305
+ _this7._setReadableStream(fs25.createReadStream(path34));
139306
139306
  _this7._headersCapability.resolve();
139307
139307
  });
139308
139308
  return _this7;
@@ -139314,7 +139314,7 @@ var require_pdf2 = __commonJS({
139314
139314
  function PDFNodeStreamFsRangeReader2(stream, start, end) {
139315
139315
  _classCallCheck(this, PDFNodeStreamFsRangeReader2);
139316
139316
  var _this8 = _possibleConstructorReturn(this, (PDFNodeStreamFsRangeReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsRangeReader2)).call(this, stream));
139317
- _this8._setReadableStream(fs24.createReadStream(decodeURI(_this8._url.path), {
139317
+ _this8._setReadableStream(fs25.createReadStream(decodeURI(_this8._url.path), {
139318
139318
  start,
139319
139319
  end: end - 1
139320
139320
  }));
@@ -156879,8 +156879,8 @@ var require_pdf_worker3 = __commonJS({
156879
156879
  if (font.data && (isAddToPathSet || this.options.disableFontFace)) {
156880
156880
  var buildPath = function buildPath2(fontChar) {
156881
156881
  if (!font.renderer.hasBuiltPath(fontChar)) {
156882
- var path33 = font.renderer.getPathJs(fontChar);
156883
- _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path33]);
156882
+ var path34 = font.renderer.getPathJs(fontChar);
156883
+ _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path34]);
156884
156884
  }
156885
156885
  };
156886
156886
  for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -161698,11 +161698,11 @@ var require_pdf_worker3 = __commonJS({
161698
161698
  var nameTree = new NameTree(nameTreeRef, xref);
161699
161699
  var names = nameTree.getAll();
161700
161700
  for (var name in names) {
161701
- var fs24 = new FileSpec(names[name], xref);
161701
+ var fs25 = new FileSpec(names[name], xref);
161702
161702
  if (!attachments) {
161703
161703
  attachments = /* @__PURE__ */ Object.create(null);
161704
161704
  }
161705
- attachments[(0, _util.stringToPDFString)(name)] = fs24.serializable;
161705
+ attachments[(0, _util.stringToPDFString)(name)] = fs25.serializable;
161706
161706
  }
161707
161707
  }
161708
161708
  return (0, _util.shadow)(this, "attachments", attachments);
@@ -191335,10 +191335,10 @@ var require_pdf3 = __commonJS({
191335
191335
  ctx.save();
191336
191336
  ctx.beginPath();
191337
191337
  for (var i = 0; i < paths.length; i++) {
191338
- var path33 = paths[i];
191339
- ctx.setTransform.apply(ctx, path33.transform);
191340
- ctx.translate(path33.x, path33.y);
191341
- path33.addToPath(ctx, path33.fontSize);
191338
+ var path34 = paths[i];
191339
+ ctx.setTransform.apply(ctx, path34.transform);
191340
+ ctx.translate(path34.x, path34.y);
191341
+ path34.addToPath(ctx, path34.fontSize);
191342
191342
  }
191343
191343
  ctx.restore();
191344
191344
  ctx.clip();
@@ -203583,11 +203583,11 @@ var require_pdf_worker4 = __commonJS({
203583
203583
  var nameTree = new NameTree(nameTreeRef, xref);
203584
203584
  var names = nameTree.getAll();
203585
203585
  for (var name in names) {
203586
- var fs24 = new FileSpec(names[name], xref);
203586
+ var fs25 = new FileSpec(names[name], xref);
203587
203587
  if (!attachments) {
203588
203588
  attachments = /* @__PURE__ */ Object.create(null);
203589
203589
  }
203590
- attachments[(0, _util.stringToPDFString)(name)] = fs24.serializable;
203590
+ attachments[(0, _util.stringToPDFString)(name)] = fs25.serializable;
203591
203591
  }
203592
203592
  }
203593
203593
  return (0, _util.shadow)(this, "attachments", attachments);
@@ -216733,8 +216733,8 @@ var require_pdf_worker4 = __commonJS({
216733
216733
  if (font.data && (isAddToPathSet || this.options.disableFontFace || state.fillColorSpace.name === "Pattern")) {
216734
216734
  var buildPath = function buildPath2(fontChar) {
216735
216735
  if (!font.renderer.hasBuiltPath(fontChar)) {
216736
- var path33 = font.renderer.getPathJs(fontChar);
216737
- _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path33]);
216736
+ var path34 = font.renderer.getPathJs(fontChar);
216737
+ _this5.handler.send("commonobj", [font.loadedName + "_path_" + fontChar, "FontPath", path34]);
216738
216738
  }
216739
216739
  };
216740
216740
  for (var i = 0, ii = glyphs.length; i < ii; i++) {
@@ -248698,10 +248698,10 @@ var require_pdf4 = __commonJS({
248698
248698
  ctx.save();
248699
248699
  ctx.beginPath();
248700
248700
  for (var i = 0; i < paths.length; i++) {
248701
- var path33 = paths[i];
248702
- ctx.setTransform.apply(ctx, path33.transform);
248703
- ctx.translate(path33.x, path33.y);
248704
- path33.addToPath(ctx, path33.fontSize);
248701
+ var path34 = paths[i];
248702
+ ctx.setTransform.apply(ctx, path34.transform);
248703
+ ctx.translate(path34.x, path34.y);
248704
+ path34.addToPath(ctx, path34.fontSize);
248705
248705
  }
248706
248706
  ctx.restore();
248707
248707
  ctx.clip();
@@ -253970,7 +253970,7 @@ var require_pdf4 = __commonJS({
253970
253970
  throw new TypeError("Cannot call a class as a function");
253971
253971
  }
253972
253972
  }
253973
- var fs24 = require("fs");
253973
+ var fs25 = require("fs");
253974
253974
  var http2 = require("http");
253975
253975
  var https2 = require("https");
253976
253976
  var url2 = require("url");
@@ -254324,11 +254324,11 @@ var require_pdf4 = __commonJS({
254324
254324
  function PDFNodeStreamFsFullReader2(stream) {
254325
254325
  _classCallCheck(this, PDFNodeStreamFsFullReader2);
254326
254326
  var _this7 = _possibleConstructorReturn(this, (PDFNodeStreamFsFullReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsFullReader2)).call(this, stream));
254327
- var path33 = decodeURIComponent(_this7._url.path);
254327
+ var path34 = decodeURIComponent(_this7._url.path);
254328
254328
  if (fileUriRegex.test(_this7._url.href)) {
254329
- path33 = path33.replace(/^\//, "");
254329
+ path34 = path34.replace(/^\//, "");
254330
254330
  }
254331
- fs24.lstat(path33, function(error40, stat) {
254331
+ fs25.lstat(path34, function(error40, stat) {
254332
254332
  if (error40) {
254333
254333
  _this7._errored = true;
254334
254334
  _this7._reason = error40;
@@ -254336,7 +254336,7 @@ var require_pdf4 = __commonJS({
254336
254336
  return;
254337
254337
  }
254338
254338
  _this7._contentLength = stat.size;
254339
- _this7._setReadableStream(fs24.createReadStream(path33));
254339
+ _this7._setReadableStream(fs25.createReadStream(path34));
254340
254340
  _this7._headersCapability.resolve();
254341
254341
  });
254342
254342
  return _this7;
@@ -254348,11 +254348,11 @@ var require_pdf4 = __commonJS({
254348
254348
  function PDFNodeStreamFsRangeReader2(stream, start, end) {
254349
254349
  _classCallCheck(this, PDFNodeStreamFsRangeReader2);
254350
254350
  var _this8 = _possibleConstructorReturn(this, (PDFNodeStreamFsRangeReader2.__proto__ || Object.getPrototypeOf(PDFNodeStreamFsRangeReader2)).call(this, stream));
254351
- var path33 = decodeURIComponent(_this8._url.path);
254351
+ var path34 = decodeURIComponent(_this8._url.path);
254352
254352
  if (fileUriRegex.test(_this8._url.href)) {
254353
- path33 = path33.replace(/^\//, "");
254353
+ path34 = path34.replace(/^\//, "");
254354
254354
  }
254355
- _this8._setReadableStream(fs24.createReadStream(path33, {
254355
+ _this8._setReadableStream(fs25.createReadStream(path34, {
254356
254356
  start,
254357
254357
  end: end - 1
254358
254358
  }));
@@ -257634,7 +257634,7 @@ function playbookNeedsOrchestration(playbook) {
257634
257634
  (s) => s.dependsOn !== void 0 || s.desiredState || s.captureVar
257635
257635
  );
257636
257636
  }
257637
- function emit7(context2, toolName, input, output) {
257637
+ function emit8(context2, toolName, input, output) {
257638
257638
  context2.sendEvent(context2.sessionId, {
257639
257639
  messageId: context2.messageId,
257640
257640
  type: "tool_call",
@@ -257650,7 +257650,7 @@ async function managePlaybook(args, context2) {
257650
257650
  const m2 = context2.automationManager;
257651
257651
  if (!m2) {
257652
257652
  const msg2 = noStore2();
257653
- emit7(context2, "manage_playbook", args, msg2);
257653
+ emit8(context2, "manage_playbook", args, msg2);
257654
257654
  return msg2;
257655
257655
  }
257656
257656
  const { action } = args;
@@ -257658,7 +257658,7 @@ async function managePlaybook(args, context2) {
257658
257658
  const all = m2.listPlaybooks();
257659
257659
  if (!all.length) {
257660
257660
  const msg3 = "No playbooks. Create one with manage_playbook action=create.";
257661
- emit7(context2, "manage_playbook", args, msg3);
257661
+ emit8(context2, "manage_playbook", args, msg3);
257662
257662
  return msg3;
257663
257663
  }
257664
257664
  const body = all.map((p) => {
@@ -257667,20 +257667,20 @@ async function managePlaybook(args, context2) {
257667
257667
  }).join("\n");
257668
257668
  const msg2 = `Playbooks (${all.length}):
257669
257669
  ${body}`;
257670
- emit7(context2, "manage_playbook", args, msg2);
257670
+ emit8(context2, "manage_playbook", args, msg2);
257671
257671
  return msg2;
257672
257672
  }
257673
257673
  if (action === "get") {
257674
257674
  const key = args.id ?? args.name;
257675
257675
  if (!key) {
257676
257676
  const msg3 = "get requires id or name.";
257677
- emit7(context2, "manage_playbook", args, msg3);
257677
+ emit8(context2, "manage_playbook", args, msg3);
257678
257678
  return msg3;
257679
257679
  }
257680
257680
  const p = m2.getPlaybook(key);
257681
257681
  if (!p) {
257682
257682
  const msg3 = `No playbook "${key}".`;
257683
- emit7(context2, "manage_playbook", args, msg3);
257683
+ emit8(context2, "manage_playbook", args, msg3);
257684
257684
  return msg3;
257685
257685
  }
257686
257686
  const steps = p.steps.map((s, i) => {
@@ -257694,13 +257694,13 @@ Scope: ${scope}
257694
257694
  Default onError: ${p.onError ?? "stop"}${p.requireApproval ? "\nMOP mode: requires an approved change record (manage_change) to run" : ""}
257695
257695
  Steps:
257696
257696
  ${steps}`;
257697
- emit7(context2, "manage_playbook", args, msg2);
257697
+ emit8(context2, "manage_playbook", args, msg2);
257698
257698
  return msg2;
257699
257699
  }
257700
257700
  if (action === "create") {
257701
257701
  if (!args.name || !args.steps?.length) {
257702
257702
  const msg2 = "create requires name + at least one step.";
257703
- emit7(context2, "manage_playbook", args, msg2);
257703
+ emit8(context2, "manage_playbook", args, msg2);
257704
257704
  return msg2;
257705
257705
  }
257706
257706
  try {
@@ -257715,18 +257715,18 @@ ${steps}`;
257715
257715
  requireApproval: args.requireApproval
257716
257716
  });
257717
257717
  const msg2 = `Created playbook "${p.name}" (id=${p.id}, ${p.steps.length} step(s)). ${p.requireApproval ? "MOP mode: run it via manage_change (plan \u2192 approve \u2192 run)." : "Run it with run_playbook."}`;
257718
- emit7(context2, "manage_playbook", args, msg2);
257718
+ emit8(context2, "manage_playbook", args, msg2);
257719
257719
  return msg2;
257720
257720
  } catch (error40) {
257721
257721
  const msg2 = `Could not create playbook: ${error40 instanceof Error ? error40.message : error40}`;
257722
- emit7(context2, "manage_playbook", args, msg2);
257722
+ emit8(context2, "manage_playbook", args, msg2);
257723
257723
  return msg2;
257724
257724
  }
257725
257725
  }
257726
257726
  if (action === "update") {
257727
257727
  if (!args.id) {
257728
257728
  const msg2 = "update requires id.";
257729
- emit7(context2, "manage_playbook", args, msg2);
257729
+ emit8(context2, "manage_playbook", args, msg2);
257730
257730
  return msg2;
257731
257731
  }
257732
257732
  try {
@@ -257742,51 +257742,51 @@ ${steps}`;
257742
257742
  ...args.requireApproval !== void 0 ? { requireApproval: args.requireApproval } : {}
257743
257743
  });
257744
257744
  const msg2 = `Updated playbook "${p.name}" (${p.steps.length} step(s)).`;
257745
- emit7(context2, "manage_playbook", args, msg2);
257745
+ emit8(context2, "manage_playbook", args, msg2);
257746
257746
  return msg2;
257747
257747
  } catch (error40) {
257748
257748
  const msg2 = `Could not update playbook: ${error40 instanceof Error ? error40.message : error40}`;
257749
- emit7(context2, "manage_playbook", args, msg2);
257749
+ emit8(context2, "manage_playbook", args, msg2);
257750
257750
  return msg2;
257751
257751
  }
257752
257752
  }
257753
257753
  if (action === "delete") {
257754
257754
  if (!args.id) {
257755
257755
  const msg3 = "delete requires id.";
257756
- emit7(context2, "manage_playbook", args, msg3);
257756
+ emit8(context2, "manage_playbook", args, msg3);
257757
257757
  return msg3;
257758
257758
  }
257759
257759
  const removed = m2.deletePlaybook(args.id);
257760
257760
  const msg2 = removed ? `Deleted playbook ${args.id}.` : `No playbook ${args.id}.`;
257761
- emit7(context2, "manage_playbook", args, msg2);
257761
+ emit8(context2, "manage_playbook", args, msg2);
257762
257762
  return msg2;
257763
257763
  }
257764
257764
  const msg = `Unknown action "${action}".`;
257765
- emit7(context2, "manage_playbook", args, msg);
257765
+ emit8(context2, "manage_playbook", args, msg);
257766
257766
  return msg;
257767
257767
  }
257768
257768
  async function runPlaybook(args, context2) {
257769
257769
  const m2 = context2.automationManager;
257770
257770
  if (!m2) {
257771
257771
  const msg2 = noStore2();
257772
- emit7(context2, "run_playbook", args, msg2);
257772
+ emit8(context2, "run_playbook", args, msg2);
257773
257773
  return msg2;
257774
257774
  }
257775
257775
  const key = args.id ?? args.name;
257776
257776
  if (!key) {
257777
257777
  const msg2 = "run_playbook requires id or name.";
257778
- emit7(context2, "run_playbook", args, msg2);
257778
+ emit8(context2, "run_playbook", args, msg2);
257779
257779
  return msg2;
257780
257780
  }
257781
257781
  const playbook = m2.getPlaybook(key);
257782
257782
  if (!playbook) {
257783
257783
  const msg2 = `No playbook "${key}". Use manage_playbook action=list to see valid playbooks.`;
257784
- emit7(context2, "run_playbook", args, msg2);
257784
+ emit8(context2, "run_playbook", args, msg2);
257785
257785
  return msg2;
257786
257786
  }
257787
257787
  if (playbook.requireApproval) {
257788
257788
  const msg2 = `Playbook "${playbook.name}" is in MOP mode (requireApproval). Run it through a change record: manage_change action=plan name="${playbook.name}" \u2192 approve \u2192 run.`;
257789
- emit7(context2, "run_playbook", args, msg2);
257789
+ emit8(context2, "run_playbook", args, msg2);
257790
257790
  return msg2;
257791
257791
  }
257792
257792
  if (args.dryRun) {
@@ -257814,7 +257814,7 @@ Targets (${plan.targets.length}): ${targetList}
257814
257814
 
257815
257815
  Steps (${plan.steps.length}):
257816
257816
  ${stepList}${notes}`;
257817
- emit7(context2, "run_playbook", args, msg2);
257817
+ emit8(context2, "run_playbook", args, msg2);
257818
257818
  return msg2;
257819
257819
  }
257820
257820
  const settings = {
@@ -257854,7 +257854,7 @@ ${stepList}${notes}`;
257854
257854
  }
257855
257855
  } catch (error40) {
257856
257856
  const msg2 = `Playbook "${playbook.name}" could not run: ${error40 instanceof Error ? error40.message : error40}`;
257857
- emit7(context2, "run_playbook", args, msg2);
257857
+ emit8(context2, "run_playbook", args, msg2);
257858
257858
  return msg2;
257859
257859
  }
257860
257860
  const lines = [];
@@ -257869,7 +257869,7 @@ ${stepList}${notes}`;
257869
257869
  const okTargets = record2.targets.filter((t) => t.ok).length;
257870
257870
  const msg = `Playbook "${record2.playbookName}" ${record2.ok ? "completed OK" : "FAILED"} (runId=${record2.runId}, ${okTargets}/${record2.targets.length} target(s) ok):
257871
257871
  ${lines.join("\n")}`;
257872
- emit7(context2, "run_playbook", args, msg);
257872
+ emit8(context2, "run_playbook", args, msg);
257873
257873
  return msg;
257874
257874
  }
257875
257875
  var stepSchema, managePlaybookSchema, runPlaybookSchema;
@@ -258310,8 +258310,8 @@ function extractFields(message) {
258310
258310
  if (ip) fields.ip = ip[1];
258311
258311
  const port = message.match(/[Pp]ort[:\s]+(\d{1,5})/);
258312
258312
  if (port) fields.port = port[1];
258313
- const path33 = message.match(/([A-Za-z]:\\[^\s"',;]+)/);
258314
- if (path33) fields.path = path33[1];
258313
+ const path34 = message.match(/([A-Za-z]:\\[^\s"',;]+)/);
258314
+ if (path34) fields.path = path34[1];
258315
258315
  const key = message.match(/(HKLM|HKCU|HKCR|HKU)\\[^\s"',;]+/i);
258316
258316
  if (key) fields.key = key[0];
258317
258317
  const proc = message.match(/[Pp]rocess(?:Name)?[:\s]+([A-Za-z0-9_.-]+\.exe)/);
@@ -265869,8 +265869,8 @@ var require_utils2 = __commonJS({
265869
265869
  }
265870
265870
  return ind;
265871
265871
  }
265872
- function removeDotSegments(path33) {
265873
- let input = path33;
265872
+ function removeDotSegments(path34) {
265873
+ let input = path34;
265874
265874
  const output = [];
265875
265875
  let nextSlash = -1;
265876
265876
  let len = 0;
@@ -266069,8 +266069,8 @@ var require_schemes = __commonJS({
266069
266069
  wsComponent.secure = void 0;
266070
266070
  }
266071
266071
  if (wsComponent.resourceName) {
266072
- const [path33, query] = wsComponent.resourceName.split("?");
266073
- wsComponent.path = path33 && path33 !== "/" ? path33 : void 0;
266072
+ const [path34, query] = wsComponent.resourceName.split("?");
266073
+ wsComponent.path = path34 && path34 !== "/" ? path34 : void 0;
266074
266074
  wsComponent.query = query;
266075
266075
  wsComponent.resourceName = void 0;
266076
266076
  }
@@ -275109,12 +275109,12 @@ var require_dist2 = __commonJS({
275109
275109
  throw new Error(`Unknown format "${name}"`);
275110
275110
  return f;
275111
275111
  };
275112
- function addFormats(ajv, list, fs24, exportName) {
275112
+ function addFormats(ajv, list, fs25, exportName) {
275113
275113
  var _a3;
275114
275114
  var _b;
275115
275115
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
275116
275116
  for (const f of list)
275117
- ajv.addFormat(f, fs24[f]);
275117
+ ajv.addFormat(f, fs25[f]);
275118
275118
  }
275119
275119
  module2.exports = exports2 = formatsPlugin;
275120
275120
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -275127,8 +275127,8 @@ var require_windows = __commonJS({
275127
275127
  "../../node_modules/isexe/windows.js"(exports2, module2) {
275128
275128
  module2.exports = isexe;
275129
275129
  isexe.sync = sync;
275130
- var fs24 = require("fs");
275131
- function checkPathExt(path33, options) {
275130
+ var fs25 = require("fs");
275131
+ function checkPathExt(path34, options) {
275132
275132
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
275133
275133
  if (!pathext) {
275134
275134
  return true;
@@ -275139,25 +275139,25 @@ var require_windows = __commonJS({
275139
275139
  }
275140
275140
  for (var i = 0; i < pathext.length; i++) {
275141
275141
  var p = pathext[i].toLowerCase();
275142
- if (p && path33.substr(-p.length).toLowerCase() === p) {
275142
+ if (p && path34.substr(-p.length).toLowerCase() === p) {
275143
275143
  return true;
275144
275144
  }
275145
275145
  }
275146
275146
  return false;
275147
275147
  }
275148
- function checkStat(stat, path33, options) {
275148
+ function checkStat(stat, path34, options) {
275149
275149
  if (!stat.isSymbolicLink() && !stat.isFile()) {
275150
275150
  return false;
275151
275151
  }
275152
- return checkPathExt(path33, options);
275152
+ return checkPathExt(path34, options);
275153
275153
  }
275154
- function isexe(path33, options, cb) {
275155
- fs24.stat(path33, function(er, stat) {
275156
- cb(er, er ? false : checkStat(stat, path33, options));
275154
+ function isexe(path34, options, cb) {
275155
+ fs25.stat(path34, function(er, stat) {
275156
+ cb(er, er ? false : checkStat(stat, path34, options));
275157
275157
  });
275158
275158
  }
275159
- function sync(path33, options) {
275160
- return checkStat(fs24.statSync(path33), path33, options);
275159
+ function sync(path34, options) {
275160
+ return checkStat(fs25.statSync(path34), path34, options);
275161
275161
  }
275162
275162
  }
275163
275163
  });
@@ -275167,14 +275167,14 @@ var require_mode = __commonJS({
275167
275167
  "../../node_modules/isexe/mode.js"(exports2, module2) {
275168
275168
  module2.exports = isexe;
275169
275169
  isexe.sync = sync;
275170
- var fs24 = require("fs");
275171
- function isexe(path33, options, cb) {
275172
- fs24.stat(path33, function(er, stat) {
275170
+ var fs25 = require("fs");
275171
+ function isexe(path34, options, cb) {
275172
+ fs25.stat(path34, function(er, stat) {
275173
275173
  cb(er, er ? false : checkStat(stat, options));
275174
275174
  });
275175
275175
  }
275176
- function sync(path33, options) {
275177
- return checkStat(fs24.statSync(path33), options);
275176
+ function sync(path34, options) {
275177
+ return checkStat(fs25.statSync(path34), options);
275178
275178
  }
275179
275179
  function checkStat(stat, options) {
275180
275180
  return stat.isFile() && checkMode(stat, options);
@@ -275198,7 +275198,7 @@ var require_mode = __commonJS({
275198
275198
  // ../../node_modules/isexe/index.js
275199
275199
  var require_isexe = __commonJS({
275200
275200
  "../../node_modules/isexe/index.js"(exports2, module2) {
275201
- var fs24 = require("fs");
275201
+ var fs25 = require("fs");
275202
275202
  var core2;
275203
275203
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
275204
275204
  core2 = require_windows();
@@ -275207,7 +275207,7 @@ var require_isexe = __commonJS({
275207
275207
  }
275208
275208
  module2.exports = isexe;
275209
275209
  isexe.sync = sync;
275210
- function isexe(path33, options, cb) {
275210
+ function isexe(path34, options, cb) {
275211
275211
  if (typeof options === "function") {
275212
275212
  cb = options;
275213
275213
  options = {};
@@ -275217,7 +275217,7 @@ var require_isexe = __commonJS({
275217
275217
  throw new TypeError("callback not provided");
275218
275218
  }
275219
275219
  return new Promise(function(resolve2, reject) {
275220
- isexe(path33, options || {}, function(er, is) {
275220
+ isexe(path34, options || {}, function(er, is) {
275221
275221
  if (er) {
275222
275222
  reject(er);
275223
275223
  } else {
@@ -275226,7 +275226,7 @@ var require_isexe = __commonJS({
275226
275226
  });
275227
275227
  });
275228
275228
  }
275229
- core2(path33, options || {}, function(er, is) {
275229
+ core2(path34, options || {}, function(er, is) {
275230
275230
  if (er) {
275231
275231
  if (er.code === "EACCES" || options && options.ignoreErrors) {
275232
275232
  er = null;
@@ -275236,9 +275236,9 @@ var require_isexe = __commonJS({
275236
275236
  cb(er, is);
275237
275237
  });
275238
275238
  }
275239
- function sync(path33, options) {
275239
+ function sync(path34, options) {
275240
275240
  try {
275241
- return core2.sync(path33, options || {});
275241
+ return core2.sync(path34, options || {});
275242
275242
  } catch (er) {
275243
275243
  if (options && options.ignoreErrors || er.code === "EACCES") {
275244
275244
  return false;
@@ -275254,7 +275254,7 @@ var require_isexe = __commonJS({
275254
275254
  var require_which = __commonJS({
275255
275255
  "../../node_modules/which/which.js"(exports2, module2) {
275256
275256
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
275257
- var path33 = require("path");
275257
+ var path34 = require("path");
275258
275258
  var COLON = isWindows ? ";" : ":";
275259
275259
  var isexe = require_isexe();
275260
275260
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -275292,7 +275292,7 @@ var require_which = __commonJS({
275292
275292
  return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
275293
275293
  const ppRaw = pathEnv[i];
275294
275294
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
275295
- const pCmd = path33.join(pathPart, cmd);
275295
+ const pCmd = path34.join(pathPart, cmd);
275296
275296
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
275297
275297
  resolve2(subStep(p, i, 0));
275298
275298
  });
@@ -275319,7 +275319,7 @@ var require_which = __commonJS({
275319
275319
  for (let i = 0; i < pathEnv.length; i++) {
275320
275320
  const ppRaw = pathEnv[i];
275321
275321
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
275322
- const pCmd = path33.join(pathPart, cmd);
275322
+ const pCmd = path34.join(pathPart, cmd);
275323
275323
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
275324
275324
  for (let j = 0; j < pathExt.length; j++) {
275325
275325
  const cur = p + pathExt[j];
@@ -275367,7 +275367,7 @@ var require_path_key = __commonJS({
275367
275367
  var require_resolveCommand = __commonJS({
275368
275368
  "../../node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
275369
275369
  "use strict";
275370
- var path33 = require("path");
275370
+ var path34 = require("path");
275371
275371
  var which = require_which();
275372
275372
  var getPathKey = require_path_key();
275373
275373
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -275385,7 +275385,7 @@ var require_resolveCommand = __commonJS({
275385
275385
  try {
275386
275386
  resolved = which.sync(parsed.command, {
275387
275387
  path: env[getPathKey({ env })],
275388
- pathExt: withoutPathExt ? path33.delimiter : void 0
275388
+ pathExt: withoutPathExt ? path34.delimiter : void 0
275389
275389
  });
275390
275390
  } catch (e) {
275391
275391
  } finally {
@@ -275394,7 +275394,7 @@ var require_resolveCommand = __commonJS({
275394
275394
  }
275395
275395
  }
275396
275396
  if (resolved) {
275397
- resolved = path33.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
275397
+ resolved = path34.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
275398
275398
  }
275399
275399
  return resolved;
275400
275400
  }
@@ -275448,8 +275448,8 @@ var require_shebang_command = __commonJS({
275448
275448
  if (!match) {
275449
275449
  return null;
275450
275450
  }
275451
- const [path33, argument] = match[0].replace(/#! ?/, "").split(" ");
275452
- const binary2 = path33.split("/").pop();
275451
+ const [path34, argument] = match[0].replace(/#! ?/, "").split(" ");
275452
+ const binary2 = path34.split("/").pop();
275453
275453
  if (binary2 === "env") {
275454
275454
  return argument;
275455
275455
  }
@@ -275462,16 +275462,16 @@ var require_shebang_command = __commonJS({
275462
275462
  var require_readShebang = __commonJS({
275463
275463
  "../../node_modules/cross-spawn/lib/util/readShebang.js"(exports2, module2) {
275464
275464
  "use strict";
275465
- var fs24 = require("fs");
275465
+ var fs25 = require("fs");
275466
275466
  var shebangCommand = require_shebang_command();
275467
275467
  function readShebang(command) {
275468
275468
  const size = 150;
275469
275469
  const buffer = Buffer.alloc(size);
275470
275470
  let fd;
275471
275471
  try {
275472
- fd = fs24.openSync(command, "r");
275473
- fs24.readSync(fd, buffer, 0, size, 0);
275474
- fs24.closeSync(fd);
275472
+ fd = fs25.openSync(command, "r");
275473
+ fs25.readSync(fd, buffer, 0, size, 0);
275474
+ fs25.closeSync(fd);
275475
275475
  } catch (e) {
275476
275476
  }
275477
275477
  return shebangCommand(buffer.toString());
@@ -275484,7 +275484,7 @@ var require_readShebang = __commonJS({
275484
275484
  var require_parse2 = __commonJS({
275485
275485
  "../../node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
275486
275486
  "use strict";
275487
- var path33 = require("path");
275487
+ var path34 = require("path");
275488
275488
  var resolveCommand = require_resolveCommand();
275489
275489
  var escape2 = require_escape();
275490
275490
  var readShebang = require_readShebang();
@@ -275509,7 +275509,7 @@ var require_parse2 = __commonJS({
275509
275509
  const needsShell = !isExecutableRegExp.test(commandFile);
275510
275510
  if (parsed.options.forceShell || needsShell) {
275511
275511
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
275512
- parsed.command = path33.normalize(parsed.command);
275512
+ parsed.command = path34.normalize(parsed.command);
275513
275513
  parsed.command = escape2.command(parsed.command);
275514
275514
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
275515
275515
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -276684,6 +276684,514 @@ var init_compoundingStore = __esm({
276684
276684
  }
276685
276685
  });
276686
276686
 
276687
+ // ../../packages/backend/src/services/ops/collabSession.ts
276688
+ function joinSession(sessionId, operator) {
276689
+ const r = rooms.get(sessionId) ?? { sessionId, operators: [], holder: null };
276690
+ if (!r.operators.includes(operator)) r.operators.push(operator);
276691
+ if (!r.holder) r.holder = operator;
276692
+ rooms.set(sessionId, r);
276693
+ return r;
276694
+ }
276695
+ function takeConn(sessionId, operator) {
276696
+ const r = rooms.get(sessionId);
276697
+ if (!r) throw new Error("no session");
276698
+ if (!r.operators.includes(operator)) r.operators.push(operator);
276699
+ r.holder = operator;
276700
+ return r;
276701
+ }
276702
+ function whoHasConn(sessionId) {
276703
+ return rooms.get(sessionId)?.holder ?? null;
276704
+ }
276705
+ var rooms;
276706
+ var init_collabSession = __esm({
276707
+ "../../packages/backend/src/services/ops/collabSession.ts"() {
276708
+ "use strict";
276709
+ rooms = /* @__PURE__ */ new Map();
276710
+ }
276711
+ });
276712
+
276713
+ // ../../packages/backend/src/services/ops/agentReplay.ts
276714
+ function replayWithStubs(runId, steps) {
276715
+ return {
276716
+ runId,
276717
+ steps: steps.map((s) => ({
276718
+ tool: s.tool,
276719
+ usedStub: true,
276720
+ output: s.stub
276721
+ })),
276722
+ wouldHaveCalled: steps.map((s) => s.tool)
276723
+ };
276724
+ }
276725
+ function breakpointBefore(tool2, nextTool) {
276726
+ return tool2 === nextTool;
276727
+ }
276728
+ var init_agentReplay = __esm({
276729
+ "../../packages/backend/src/services/ops/agentReplay.ts"() {
276730
+ "use strict";
276731
+ }
276732
+ });
276733
+
276734
+ // ../../packages/backend/src/services/ops/djoinPlaybook.ts
276735
+ function planOfflineJoin2(opts) {
276736
+ const domain2 = String(opts.domain || "").trim();
276737
+ const machine = String(opts.machine || "").trim();
276738
+ if (!domain2 || !machine) throw new Error("domain and machine required");
276739
+ return {
276740
+ domain: domain2,
276741
+ machine,
276742
+ provisionOn: opts.dcConnection,
276743
+ applyOn: opts.memberConnection,
276744
+ steps: [
276745
+ `On ${opts.dcConnection}: djoin /provision /domain ${domain2} /machine ${machine} /savefile C:\\temp\\${machine}.odj`,
276746
+ `Copy blob to ${opts.memberConnection} (no SMB \u2014 PSRP/WinRM file or pypsrp)`,
276747
+ `On ${opts.memberConnection}: djoin /requestODJ /loadfile C:\\temp\\${machine}.odj /localos /windowspath C:\\Windows`,
276748
+ `Restart ${opts.memberConnection}`,
276749
+ `Verify PartOfDomain and Get-ADComputer ${machine}`
276750
+ ]
276751
+ };
276752
+ }
276753
+ function djoinProvisionCommand(domain2, machine, savefile = "C:\\temp\\odj.blob") {
276754
+ return `djoin /provision /domain ${domain2} /machine ${machine} /savefile ${savefile}`;
276755
+ }
276756
+ function djoinRequestCommand(loadfile = "C:\\temp\\odj.blob") {
276757
+ return `djoin /requestODJ /loadfile ${loadfile} /localos /windowspath C:\\Windows`;
276758
+ }
276759
+ var init_djoinPlaybook = __esm({
276760
+ "../../packages/backend/src/services/ops/djoinPlaybook.ts"() {
276761
+ "use strict";
276762
+ }
276763
+ });
276764
+
276765
+ // ../../packages/backend/src/services/ops/netDevice.ts
276766
+ function parseCdpNeighbors(showCdp) {
276767
+ const out = [];
276768
+ const blocks2 = showCdp.split(/Device ID:/i);
276769
+ for (const b of blocks2.slice(1)) {
276770
+ const device = (b.split("\n")[0] || "").trim();
276771
+ const local = /Interface:\s*(\S+)/i.exec(b)?.[1] ?? "";
276772
+ const remote = /Port ID[^:]*:\s*(\S+)/i.exec(b)?.[1] ?? "";
276773
+ if (device) out.push({ device, localIntf: local, remoteIntf: remote });
276774
+ }
276775
+ return out;
276776
+ }
276777
+ function configDiff(running, startup) {
276778
+ const a = running.replace(/\r/g, "").trimEnd();
276779
+ const b = startup.replace(/\r/g, "").trimEnd();
276780
+ if (a === b) return { changed: false, unified: "" };
276781
+ return { changed: true, unified: `--- startup
276782
+ +++ running
276783
+ -${b.slice(0, 200)}
276784
+ +${a.slice(0, 200)}` };
276785
+ }
276786
+ function inConfigMode(prompt) {
276787
+ return /\(config[^)]*\)#\s*$/.test(prompt);
276788
+ }
276789
+ var init_netDevice = __esm({
276790
+ "../../packages/backend/src/services/ops/netDevice.ts"() {
276791
+ "use strict";
276792
+ }
276793
+ });
276794
+
276795
+ // ../../packages/backend/src/services/ops/opsStore.ts
276796
+ function mapIncident(r) {
276797
+ let tabIds = [];
276798
+ try {
276799
+ const parsed = JSON.parse(String(r.tab_ids ?? "[]"));
276800
+ if (Array.isArray(parsed)) tabIds = parsed.map(String);
276801
+ } catch {
276802
+ tabIds = [];
276803
+ }
276804
+ return {
276805
+ id: String(r.id),
276806
+ title: String(r.title),
276807
+ status: r.status === "closed" ? "closed" : "open",
276808
+ sessionId: r.session_id ? String(r.session_id) : void 0,
276809
+ tabIds,
276810
+ recordingId: r.recording_id ? String(r.recording_id) : void 0,
276811
+ runId: r.run_id ? String(r.run_id) : void 0,
276812
+ notes: r.notes ? String(r.notes) : void 0,
276813
+ openedAt: Number(r.opened_at ?? 0),
276814
+ closedAt: r.closed_at ? Number(r.closed_at) : void 0
276815
+ };
276816
+ }
276817
+ function mapJumpPath(r) {
276818
+ let hops = [];
276819
+ try {
276820
+ const parsed = JSON.parse(String(r.hops ?? "[]"));
276821
+ if (Array.isArray(parsed)) hops = parsed;
276822
+ } catch {
276823
+ hops = [];
276824
+ }
276825
+ return {
276826
+ name: String(r.name),
276827
+ hops,
276828
+ breakGlassUntil: r.break_glass_until ? Number(r.break_glass_until) : void 0,
276829
+ createdAt: Number(r.created_at ?? 0)
276830
+ };
276831
+ }
276832
+ function mapSnapshot(r) {
276833
+ return {
276834
+ connection: String(r.connection),
276835
+ command: String(r.command),
276836
+ output: String(r.output ?? ""),
276837
+ at: Number(r.at ?? 0)
276838
+ };
276839
+ }
276840
+ function mapApproval(r) {
276841
+ return {
276842
+ id: String(r.id),
276843
+ command: String(r.command),
276844
+ state: String(r.state) ?? "pending",
276845
+ twoPerson: Number(r.two_person ?? 0) === 1,
276846
+ requestedAt: Number(r.requested_at ?? 0),
276847
+ expiresAt: Number(r.expires_at ?? 0),
276848
+ decidedBy: r.decided_by ? String(r.decided_by) : void 0,
276849
+ decidedAt: r.decided_at ? Number(r.decided_at) : void 0
276850
+ };
276851
+ }
276852
+ var import_node_fs13, import_node_path29, OPS_DB_FILE, OpsStore;
276853
+ var init_opsStore = __esm({
276854
+ "../../packages/backend/src/services/ops/opsStore.ts"() {
276855
+ "use strict";
276856
+ import_node_fs13 = __toESM(require("node:fs"), 1);
276857
+ import_node_path29 = __toESM(require("node:path"), 1);
276858
+ init_betterSqlite3Runtime();
276859
+ init_historyStoragePaths();
276860
+ OPS_DB_FILE = "gyshell-ops.sqlite";
276861
+ OpsStore = class {
276862
+ db;
276863
+ constructor(options) {
276864
+ const filePath = options?.filePath || import_node_path29.default.join(resolveHistoryStorageDir(), OPS_DB_FILE);
276865
+ import_node_fs13.default.mkdirSync(import_node_path29.default.dirname(filePath), { recursive: true });
276866
+ this.db = openBetterSqlite3Database(filePath);
276867
+ this.db.pragma("journal_mode = WAL");
276868
+ this.db.exec(`
276869
+ CREATE TABLE IF NOT EXISTS incidents (
276870
+ id TEXT PRIMARY KEY,
276871
+ title TEXT NOT NULL,
276872
+ status TEXT NOT NULL DEFAULT 'open',
276873
+ session_id TEXT,
276874
+ tab_ids TEXT NOT NULL DEFAULT '[]',
276875
+ recording_id TEXT,
276876
+ run_id TEXT,
276877
+ notes TEXT,
276878
+ opened_at INTEGER NOT NULL,
276879
+ closed_at INTEGER
276880
+ );
276881
+ CREATE TABLE IF NOT EXISTS jump_paths (
276882
+ name TEXT PRIMARY KEY,
276883
+ hops TEXT NOT NULL DEFAULT '[]',
276884
+ break_glass_until INTEGER,
276885
+ created_at INTEGER NOT NULL
276886
+ );
276887
+ CREATE TABLE IF NOT EXISTS snapshots (
276888
+ connection TEXT NOT NULL,
276889
+ command TEXT NOT NULL,
276890
+ output TEXT NOT NULL,
276891
+ at INTEGER NOT NULL,
276892
+ PRIMARY KEY (connection, command)
276893
+ );
276894
+ CREATE TABLE IF NOT EXISTS approvals (
276895
+ id TEXT PRIMARY KEY,
276896
+ command TEXT NOT NULL,
276897
+ state TEXT NOT NULL DEFAULT 'pending',
276898
+ two_person INTEGER NOT NULL DEFAULT 0,
276899
+ requested_at INTEGER NOT NULL,
276900
+ expires_at INTEGER NOT NULL,
276901
+ decided_by TEXT,
276902
+ decided_at INTEGER,
276903
+ approvals TEXT NOT NULL DEFAULT '[]'
276904
+ );
276905
+ `);
276906
+ }
276907
+ // ── incidents ────────────────────────────────────────────────────────────
276908
+ openIncident(title, parts = {}) {
276909
+ const row = {
276910
+ id: `inc-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
276911
+ title,
276912
+ status: "open",
276913
+ tabIds: parts.tabIds ?? [],
276914
+ sessionId: parts.sessionId,
276915
+ recordingId: parts.recordingId,
276916
+ runId: parts.runId,
276917
+ notes: parts.notes,
276918
+ openedAt: Date.now()
276919
+ };
276920
+ this.db.prepare(
276921
+ `INSERT INTO incidents (id, title, status, session_id, tab_ids, recording_id, run_id, notes, opened_at)
276922
+ VALUES (@id, @title, @status, @sessionId, @tabIds, @recordingId, @runId, @notes, @openedAt)`
276923
+ ).run({ ...row, tabIds: JSON.stringify(row.tabIds) });
276924
+ return row;
276925
+ }
276926
+ getIncident(id) {
276927
+ const r = this.db.prepare(`SELECT * FROM incidents WHERE id = ?`).get(id);
276928
+ return r ? mapIncident(r) : void 0;
276929
+ }
276930
+ listIncidents(status) {
276931
+ const rows = status ? this.db.prepare(`SELECT * FROM incidents WHERE status = ? ORDER BY opened_at DESC`).all(status) : this.db.prepare(`SELECT * FROM incidents ORDER BY opened_at DESC`).all();
276932
+ return rows.map(mapIncident);
276933
+ }
276934
+ closeIncident(id, notes) {
276935
+ this.db.prepare(`UPDATE incidents SET status = 'closed', closed_at = ?, notes = COALESCE(?, notes) WHERE id = ?`).run(Date.now(), notes ?? null, id);
276936
+ return this.getIncident(id);
276937
+ }
276938
+ // ── jump paths / break-glass ─────────────────────────────────────────────
276939
+ defineJumpPath(name, hops) {
276940
+ const row = { name, hops, createdAt: Date.now() };
276941
+ this.db.prepare(
276942
+ `INSERT INTO jump_paths (name, hops, break_glass_until, created_at) VALUES (?, ?, NULL, ?)
276943
+ ON CONFLICT(name) DO UPDATE SET hops = excluded.hops`
276944
+ ).run(name, JSON.stringify(hops), row.createdAt);
276945
+ return row;
276946
+ }
276947
+ listJumpPaths() {
276948
+ return this.db.prepare(`SELECT * FROM jump_paths ORDER BY name`).all().map(
276949
+ mapJumpPath
276950
+ );
276951
+ }
276952
+ /** Grant time-boxed break-glass on a path. */
276953
+ grantBreakGlass(name, ttlMs) {
276954
+ const until = Date.now() + Math.max(0, ttlMs);
276955
+ this.db.prepare(`UPDATE jump_paths SET break_glass_until = ? WHERE name = ?`).run(until, name);
276956
+ return this.listJumpPaths().find((p) => p.name === name);
276957
+ }
276958
+ /** allowed = no break-glass needed, or break-glass still valid. */
276959
+ pathAllowed(name, now = Date.now()) {
276960
+ const p = this.listJumpPaths().find((x) => x.name === name);
276961
+ if (!p) return { allowed: false };
276962
+ if (!p.breakGlassUntil) return { allowed: false };
276963
+ const allowed = p.breakGlassUntil > now;
276964
+ return { allowed, breakGlassUntil: p.breakGlassUntil, expired: !allowed };
276965
+ }
276966
+ // ── output snapshots ─────────────────────────────────────────────────────
276967
+ rememberOutput(connection, command, output, at = Date.now()) {
276968
+ const row = { connection, command, output, at };
276969
+ this.db.prepare(
276970
+ `INSERT INTO snapshots (connection, command, output, at) VALUES (@connection, @command, @output, @at)
276971
+ ON CONFLICT(connection, command) DO UPDATE SET output = excluded.output, at = excluded.at`
276972
+ ).run(row);
276973
+ return row;
276974
+ }
276975
+ lastSnapshot(connection, command) {
276976
+ const r = this.db.prepare(`SELECT * FROM snapshots WHERE connection = ? AND command = ?`).get(connection, command);
276977
+ return r ? mapSnapshot(r) : void 0;
276978
+ }
276979
+ listSnapshots(connection) {
276980
+ const rows = connection ? this.db.prepare(`SELECT * FROM snapshots WHERE connection = ? ORDER BY at DESC`).all(connection) : this.db.prepare(`SELECT * FROM snapshots ORDER BY at DESC`);
276981
+ return rows.map(mapSnapshot);
276982
+ }
276983
+ /**
276984
+ * Diff the stored output for (connection, command) against nextOutput and
276985
+ * remember nextOutput as the new baseline (so the next call diffs again).
276986
+ */
276987
+ diffAndRemember(connection, command, nextOutput) {
276988
+ const prev = this.lastSnapshot(connection, command);
276989
+ const changed = prev ? prev.output !== nextOutput : false;
276990
+ this.rememberOutput(connection, command, nextOutput);
276991
+ return { previous: prev ? prev.output : null, current: nextOutput, changed };
276992
+ }
276993
+ // ── approvals (two-person + TTL) ─────────────────────────────────────────
276994
+ requestApproval(command, ttlMs, twoPerson = false, now = Date.now()) {
276995
+ const row = {
276996
+ id: `ap-${now.toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
276997
+ command,
276998
+ state: "pending",
276999
+ twoPerson,
277000
+ requestedAt: now,
277001
+ expiresAt: now + Math.max(0, ttlMs)
277002
+ };
277003
+ this.db.prepare(
277004
+ `INSERT INTO approvals (id, command, state, two_person, requested_at, expires_at, approvals)
277005
+ VALUES (@id, @command, @state, @twoPerson, @requestedAt, @expiresAt, '[]')`
277006
+ ).run({ ...row, twoPerson: row.twoPerson ? 1 : 0 });
277007
+ return row;
277008
+ }
277009
+ getApproval(id) {
277010
+ const r = this.db.prepare(`SELECT * FROM approvals WHERE id = ?`).get(id);
277011
+ return r ? mapApproval(r) : void 0;
277012
+ }
277013
+ listApprovals(state) {
277014
+ const rows = state ? this.db.prepare(`SELECT * FROM approvals WHERE state = ? ORDER BY requested_at DESC`).all(state) : this.db.prepare(`SELECT * FROM approvals ORDER BY requested_at DESC`);
277015
+ return rows.map(mapApproval);
277016
+ }
277017
+ approvers(id) {
277018
+ const r = this.db.prepare(`SELECT approvals FROM approvals WHERE id = ?`).get(id);
277019
+ try {
277020
+ const parsed = JSON.parse(r?.approvals ?? "[]");
277021
+ return Array.isArray(parsed) ? parsed : [];
277022
+ } catch {
277023
+ return [];
277024
+ }
277025
+ }
277026
+ /** Sweep pending approvals whose TTL has passed into 'expired'. Returns count. */
277027
+ sweepExpired(now = Date.now()) {
277028
+ const r = this.db.prepare(`UPDATE approvals SET state = 'expired' WHERE state = 'pending' AND expires_at <= ?`).run(now);
277029
+ return Number(r.changes ?? 0);
277030
+ }
277031
+ /**
277032
+ * Record a decision. A two-person approval needs TWO DISTINCT approvers before
277033
+ * it flips to approved; a denial takes effect immediately. Expired approvals
277034
+ * cannot be decided.
277035
+ */
277036
+ decide(id, who, approve, now = Date.now()) {
277037
+ const a = this.getApproval(id);
277038
+ if (!a) throw new Error(`unknown approval ${id}`);
277039
+ this.sweepExpired(now);
277040
+ const fresh = this.getApproval(id);
277041
+ if (fresh.state === "expired") return { ok: false, approval: fresh, reason: "expired" };
277042
+ if (fresh.state !== "pending") return { ok: false, approval: fresh, reason: `already ${fresh.state}` };
277043
+ if (!approve) {
277044
+ this.db.prepare(`UPDATE approvals SET state = 'denied', decided_by = ?, decided_at = ? WHERE id = ?`).run(who, now, id);
277045
+ return { ok: false, approval: this.getApproval(id), reason: "denied" };
277046
+ }
277047
+ const prior = this.approvers(id);
277048
+ if (prior.includes(who)) {
277049
+ return { ok: false, approval: fresh, reason: `approver "${who}" already approved \u2014 a second person is required` };
277050
+ }
277051
+ const next = [...prior, who];
277052
+ const needed = fresh.twoPerson ? 2 : 1;
277053
+ const approved = next.length >= needed;
277054
+ this.db.prepare(
277055
+ `UPDATE approvals SET approvals = ?, state = ?, decided_by = ?, decided_at = ? WHERE id = ?`
277056
+ ).run(JSON.stringify(next), approved ? "approved" : "pending", who, now, id);
277057
+ return {
277058
+ ok: approved,
277059
+ approval: this.getApproval(id),
277060
+ reason: approved ? void 0 : `need ${needed - next.length} more approver(s)`
277061
+ };
277062
+ }
277063
+ };
277064
+ }
277065
+ });
277066
+
277067
+ // ../../packages/backend/src/services/ops/opsService.ts
277068
+ var opsService_exports = {};
277069
+ __export(opsService_exports, {
277070
+ OpsService: () => OpsService
277071
+ });
277072
+ var OpsService;
277073
+ var init_opsService = __esm({
277074
+ "../../packages/backend/src/services/ops/opsService.ts"() {
277075
+ "use strict";
277076
+ init_collabSession();
277077
+ init_agentReplay();
277078
+ init_djoinPlaybook();
277079
+ init_netDevice();
277080
+ init_opsStore();
277081
+ OpsService = class {
277082
+ store;
277083
+ /** sessionId → operators, for the presence listing. */
277084
+ rooms = /* @__PURE__ */ new Map();
277085
+ constructor(deps = {}) {
277086
+ this.store = new OpsStore({ filePath: deps.filePath });
277087
+ }
277088
+ // ── collaborate (two operators, one session) ─────────────────────────────
277089
+ joinCollab(sessionId, operator) {
277090
+ const p = joinSession(sessionId, operator);
277091
+ this.rooms.set(sessionId, p);
277092
+ return p;
277093
+ }
277094
+ takeConn(sessionId, operator) {
277095
+ const p = takeConn(sessionId, operator);
277096
+ this.rooms.set(sessionId, p);
277097
+ return p;
277098
+ }
277099
+ whoHasConn(sessionId) {
277100
+ const p = this.rooms.get(sessionId) ?? joinSession(sessionId, "system");
277101
+ this.rooms.set(sessionId, p);
277102
+ return { sessionId, holder: whoHasConn(sessionId), operators: p.operators };
277103
+ }
277104
+ listCollabSessions() {
277105
+ return [...this.rooms.values()];
277106
+ }
277107
+ // ── incidents ────────────────────────────────────────────────────────────
277108
+ openIncident(title, parts) {
277109
+ return this.store.openIncident(title, parts);
277110
+ }
277111
+ getIncident(id) {
277112
+ return this.store.getIncident(id);
277113
+ }
277114
+ listIncidents(status) {
277115
+ return this.store.listIncidents(status);
277116
+ }
277117
+ closeIncident(id, notes) {
277118
+ return this.store.closeIncident(id, notes);
277119
+ }
277120
+ // ── jump paths + break-glass ─────────────────────────────────────────────
277121
+ defineJumpPath(name, hops) {
277122
+ return this.store.defineJumpPath(name, hops);
277123
+ }
277124
+ listJumpPaths() {
277125
+ return this.store.listJumpPaths();
277126
+ }
277127
+ grantBreakGlass(name, ttlMs) {
277128
+ if (!this.store.listJumpPaths().some((p) => p.name === name)) {
277129
+ throw new Error(`unknown jump path "${name}" \u2014 define it first`);
277130
+ }
277131
+ return this.store.grantBreakGlass(name, ttlMs);
277132
+ }
277133
+ pathAllowed(name) {
277134
+ return this.store.pathAllowed(name);
277135
+ }
277136
+ // ── output snapshots + drift ─────────────────────────────────────────────
277137
+ rememberOutput(connection, command, output) {
277138
+ return this.store.rememberOutput(connection, command, output);
277139
+ }
277140
+ listSnapshots(connection) {
277141
+ return this.store.listSnapshots(connection);
277142
+ }
277143
+ diffOutput(connection, command, nextOutput) {
277144
+ return this.store.diffAndRemember(connection, command, nextOutput);
277145
+ }
277146
+ // ── approvals (TTL + two-person) ─────────────────────────────────────────
277147
+ requestApproval(command, ttlMs, twoPerson = false) {
277148
+ return this.store.requestApproval(command, ttlMs, twoPerson);
277149
+ }
277150
+ listApprovals(state) {
277151
+ this.store.sweepExpired();
277152
+ return this.store.listApprovals(state);
277153
+ }
277154
+ getApproval(id) {
277155
+ this.store.sweepExpired();
277156
+ return this.store.getApproval(id);
277157
+ }
277158
+ decideApproval(id, who, approve) {
277159
+ return this.store.decide(id, who, approve);
277160
+ }
277161
+ sweepExpiredApprovals() {
277162
+ return this.store.sweepExpired();
277163
+ }
277164
+ // ── agent replay (debug without touching live hosts) ─────────────────────
277165
+ replay(runId, steps) {
277166
+ return replayWithStubs(runId, steps);
277167
+ }
277168
+ shouldBreakpointBefore(tool2, nextTool) {
277169
+ return breakpointBefore(tool2, nextTool);
277170
+ }
277171
+ // ── offline domain join ──────────────────────────────────────────────────
277172
+ planOfflineJoin(opts) {
277173
+ return planOfflineJoin2(opts);
277174
+ }
277175
+ djoinProvision(domain2, machine, savefile) {
277176
+ return djoinProvisionCommand(domain2, machine, savefile);
277177
+ }
277178
+ djoinRequest(loadfile) {
277179
+ return djoinRequestCommand(loadfile);
277180
+ }
277181
+ // ── network device helpers ───────────────────────────────────────────────
277182
+ parseCdp(showCdp) {
277183
+ return parseCdpNeighbors(showCdp);
277184
+ }
277185
+ configDiff(running, startup) {
277186
+ return configDiff(running, startup);
277187
+ }
277188
+ inConfigMode(prompt) {
277189
+ return inConfigMode(prompt);
277190
+ }
277191
+ };
277192
+ }
277193
+ });
277194
+
276687
277195
  // ../../node_modules/@nats-io/nats-core/lib/encoders.js
276688
277196
  var require_encoders = __commonJS({
276689
277197
  "../../node_modules/@nats-io/nats-core/lib/encoders.js"(exports2) {
@@ -285435,7 +285943,7 @@ var require_ws_transport = __commonJS({
285435
285943
  let protocol;
285436
285944
  let port;
285437
285945
  const host = url2.hostname;
285438
- const path33 = url2.pathname;
285946
+ const path34 = url2.pathname;
285439
285947
  const search = url2.search || "";
285440
285948
  switch (srcProto) {
285441
285949
  case "http:":
@@ -285455,7 +285963,7 @@ var require_ws_transport = __commonJS({
285455
285963
  protocol = encrypted === true ? "wss:" : "ws:";
285456
285964
  break;
285457
285965
  }
285458
- return `${protocol}//${host}:${port}${path33}${search}`;
285966
+ return `${protocol}//${host}:${port}${path34}${search}`;
285459
285967
  }
285460
285968
  function wsconnect(opts = {}) {
285461
285969
  (0, transport_1.setTransportFactory)({
@@ -287300,11 +287808,11 @@ var require_jsmconsumer_api = __commonJS({
287300
287808
  consumerName = cfg.name ?? cfg.durable_name ?? "";
287301
287809
  }
287302
287810
  if (consumerName !== "") {
287303
- let fs24 = cfg.filter_subject ?? void 0;
287304
- if (fs24 === ">") {
287305
- fs24 = void 0;
287811
+ let fs25 = cfg.filter_subject ?? void 0;
287812
+ if (fs25 === ">") {
287813
+ fs25 = void 0;
287306
287814
  }
287307
- subj = fs24 !== void 0 ? `${this.prefix}.CONSUMER.CREATE.${stream}.${consumerName}.${fs24}` : `${this.prefix}.CONSUMER.CREATE.${stream}.${consumerName}`;
287815
+ subj = fs25 !== void 0 ? `${this.prefix}.CONSUMER.CREATE.${stream}.${consumerName}.${fs25}` : `${this.prefix}.CONSUMER.CREATE.${stream}.${consumerName}`;
287308
287816
  } else {
287309
287817
  subj = cfg.durable_name ? `${this.prefix}.CONSUMER.DURABLE.CREATE.${stream}.${cfg.durable_name}` : `${this.prefix}.CONSUMER.CREATE.${stream}`;
287310
287818
  }
@@ -291854,8 +292362,8 @@ var init_natsEventBus = __esm({
291854
292362
  });
291855
292363
 
291856
292364
  // ../../packages/backend/src/runtimes/gybackend/startGyBackend.ts
291857
- var import_node_path29 = __toESM(require("node:path"), 1);
291858
- var import_node_fs13 = __toESM(require("node:fs"), 1);
292365
+ var import_node_path30 = __toESM(require("node:path"), 1);
292366
+ var import_node_fs14 = __toESM(require("node:fs"), 1);
291859
292367
  var import_node_process2 = __toESM(require("node:process"), 1);
291860
292368
 
291861
292369
  // ../../packages/backend/src/services/TerminalService.ts
@@ -293888,18 +294396,18 @@ var SSHBackend = class _SSHBackend {
293888
294396
  });
293889
294397
  return info.socket;
293890
294398
  }
293891
- async buildConnectSocketIfNeeded(sshConfig, emit11) {
294399
+ async buildConnectSocketIfNeeded(sshConfig, emit12) {
293892
294400
  if (sshConfig.jumpHost) {
293893
294401
  const jumpId = `[Jump:${sshConfig.jumpHost.host}]`;
293894
294402
  console.log(`${jumpId} Starting jump host connection flow...`);
293895
- emit11(
294403
+ emit12(
293896
294404
  `\x1B[36m\u25B9 ${jumpId} Establishing tunnel via jump host ${sshConfig.jumpHost.host}...\x1B[0m\r
293897
294405
  `
293898
294406
  );
293899
294407
  const jumpClient = new (loadSsh2()).Client();
293900
294408
  const jumpSock = await this.buildConnectSocketIfNeeded(
293901
294409
  sshConfig.jumpHost,
293902
- emit11
294410
+ emit12
293903
294411
  );
293904
294412
  if (jumpSock) {
293905
294413
  console.log(
@@ -293943,7 +294451,7 @@ var SSHBackend = class _SSHBackend {
293943
294451
  });
293944
294452
  jumpClient.connect(jumpConnectConfig);
293945
294453
  });
293946
- emit11(
294454
+ emit12(
293947
294455
  `\x1B[32m\u2714 ${jumpId} Jump host ready. Requesting forward to target ${sshConfig.host}:${sshConfig.port}...\x1B[0m\r
293948
294456
  `
293949
294457
  );
@@ -294259,25 +294767,25 @@ var SSHBackend = class _SSHBackend {
294259
294767
  };
294260
294768
  this.sessions.set(config2.id, instance);
294261
294769
  (async () => {
294262
- const emit11 = (data) => {
294770
+ const emit12 = (data) => {
294263
294771
  instance.dataCallbacks.forEach((cb) => cb(data));
294264
294772
  };
294265
294773
  const emitExit = (code) => {
294266
294774
  this.emitExitOnce(config2.id, instance, code);
294267
294775
  };
294268
294776
  client2.on("ready", async () => {
294269
- emit11("\x1B[2J\x1B[H\x1B[32m\u2714 Connection established.\x1B[0m\r\n");
294777
+ emit12("\x1B[2J\x1B[H\x1B[32m\u2714 Connection established.\x1B[0m\r\n");
294270
294778
  console.log(
294271
294779
  `[SSH] Connection ready for ${sshConfig.host}:${sshConfig.port}`
294272
294780
  );
294273
294781
  const rawShell = isRawShellPreset(sshConfig.algorithmsPreset);
294274
294782
  try {
294275
- emit11("\x1B[36m\u25B9 Setting up port forwards...\x1B[0m\r\n");
294783
+ emit12("\x1B[36m\u25B9 Setting up port forwards...\x1B[0m\r\n");
294276
294784
  console.log(`[SSH] Setting up port forwards...`);
294277
294785
  await this.setupPortForwards(instance, sshConfig);
294278
294786
  } catch (e) {
294279
294787
  console.error(`[SSH] Port forward setup failed:`, e);
294280
- emit11(`\x1B[31m\u2718 Port forward failed: ${e.message}\x1B[0m\r
294788
+ emit12(`\x1B[31m\u2718 Port forward failed: ${e.message}\x1B[0m\r
294281
294789
  `);
294282
294790
  }
294283
294791
  if (rawShell) {
@@ -294287,7 +294795,7 @@ var SSHBackend = class _SSHBackend {
294287
294795
  );
294288
294796
  } else {
294289
294797
  try {
294290
- emit11("\x1B[36m\u25B9 Detecting remote OS...\x1B[0m\r\n");
294798
+ emit12("\x1B[36m\u25B9 Detecting remote OS...\x1B[0m\r\n");
294291
294799
  console.log(`[SSH] Detecting remote OS...`);
294292
294800
  const uname = await this.execCollect(client2, "uname -s");
294293
294801
  const u = (uname.stdout || uname.stderr || "").toLowerCase();
@@ -294307,13 +294815,13 @@ var SSHBackend = class _SSHBackend {
294307
294815
  if (!instance.remoteOs) instance.remoteOs = "unix";
294308
294816
  console.log(`[SSH] Remote OS detected: ${instance.remoteOs}`);
294309
294817
  try {
294310
- emit11("\x1B[36m\u25B9 Initializing SFTP channel...\x1B[0m\r\n");
294818
+ emit12("\x1B[36m\u25B9 Initializing SFTP channel...\x1B[0m\r\n");
294311
294819
  await this.initializeSftp(instance);
294312
- emit11("\x1B[32m\u2714 SFTP channel ready.\x1B[0m\r\n");
294820
+ emit12("\x1B[32m\u2714 SFTP channel ready.\x1B[0m\r\n");
294313
294821
  } catch (error40) {
294314
294822
  const message = error40 instanceof Error ? error40.message : String(error40);
294315
294823
  instance.sftpInitError = message;
294316
- emit11(
294824
+ emit12(
294317
294825
  `\x1B[33m\u26A0 SFTP unavailable: ${message}. File panel features may be limited.\x1B[0m\r
294318
294826
  `
294319
294827
  );
@@ -294326,7 +294834,7 @@ var SSHBackend = class _SSHBackend {
294326
294834
  }
294327
294835
  }
294328
294836
  }
294329
- emit11("\x1B[36m\u25B9 Opening interactive shell...\x1B[0m\r\n");
294837
+ emit12("\x1B[36m\u25B9 Opening interactive shell...\x1B[0m\r\n");
294330
294838
  console.log(`[SSH] Opening interactive shell...`);
294331
294839
  const initialWindowSize = this.resolveRequestedWindowSize(instance, {
294332
294840
  cols: config2.cols,
@@ -294356,7 +294864,7 @@ var SSHBackend = class _SSHBackend {
294356
294864
  console.error(`[SSH] Failed to open shell:`, err);
294357
294865
  instance.initializationState = "failed";
294358
294866
  instance.isInitializing = false;
294359
- emit11(`\x1B[31m\u2718 Failed to open shell: ${err.message}\x1B[0m\r
294867
+ emit12(`\x1B[31m\u2718 Failed to open shell: ${err.message}\x1B[0m\r
294360
294868
  `);
294361
294869
  emitExit(-1);
294362
294870
  return;
@@ -294366,7 +294874,7 @@ var SSHBackend = class _SSHBackend {
294366
294874
  if (rawShell) {
294367
294875
  instance.initializationState = "ready";
294368
294876
  instance.isInitializing = false;
294369
- emit11("\x1B[32m\u2714 Shell ready.\x1B[0m\r\n");
294877
+ emit12("\x1B[32m\u2714 Shell ready.\x1B[0m\r\n");
294370
294878
  console.log(
294371
294879
  `[SSH] Raw-shell mode: shell ready immediately (preset=${sshConfig.algorithmsPreset}).`
294372
294880
  );
@@ -294374,14 +294882,14 @@ var SSHBackend = class _SSHBackend {
294374
294882
  const chunk2 = data.toString();
294375
294883
  const sanitizedChunk = this.stripReadyMarker(chunk2);
294376
294884
  this.consumeOscMarkers(instance, sanitizedChunk);
294377
- if (sanitizedChunk) emit11(sanitizedChunk);
294885
+ if (sanitizedChunk) emit12(sanitizedChunk);
294378
294886
  });
294379
294887
  stream.on("close", async (code) => {
294380
294888
  emitExit(typeof code === "number" ? code : 0);
294381
294889
  });
294382
294890
  return;
294383
294891
  }
294384
- emit11("\x1B[36m\u25B9 Initializing shell integration...\x1B[0m\r\n");
294892
+ emit12("\x1B[36m\u25B9 Initializing shell integration...\x1B[0m\r\n");
294385
294893
  console.log(
294386
294894
  `[SSH] Shell stream opened. Starting robust initialization...`
294387
294895
  );
@@ -294427,7 +294935,7 @@ var SSHBackend = class _SSHBackend {
294427
294935
  if (retryCount >= maxRetries) {
294428
294936
  instance.initializationState = "failed";
294429
294937
  instance.isInitializing = false;
294430
- emit11(
294938
+ emit12(
294431
294939
  "\x1B[31m\u2718 Initialization failed. Entering fallback mode.\x1B[0m\r\n"
294432
294940
  );
294433
294941
  console.error(
@@ -294436,7 +294944,7 @@ var SSHBackend = class _SSHBackend {
294436
294944
  clearInterval(watchdogInterval);
294437
294945
  return;
294438
294946
  }
294439
- emit11(
294947
+ emit12(
294440
294948
  `\x1B[33m\u26A0 Initialization timeout, retrying (${retryCount}/${maxRetries})...\x1B[0m\r
294441
294949
  `
294442
294950
  );
@@ -294450,7 +294958,7 @@ var SSHBackend = class _SSHBackend {
294450
294958
  if (instance.isInitializing) {
294451
294959
  instance.buffer += chunk2;
294452
294960
  if (instance.buffer.includes(GYSHELL_READY_MARKER2)) {
294453
- emit11("\x1B[2J\x1B[H");
294961
+ emit12("\x1B[2J\x1B[H");
294454
294962
  isReadySent = true;
294455
294963
  clearInterval(watchdogInterval);
294456
294964
  const sawContinuation = /(?:\r?\n)>>\s*\r?\n/.test(instance.buffer) || instance.buffer.trimEnd().endsWith("\n>>") || instance.buffer.trimEnd().endsWith("\r\n>>");
@@ -294461,7 +294969,7 @@ var SSHBackend = class _SSHBackend {
294461
294969
  const realContent = this.stripReadyMarker(
294462
294970
  parts.slice(1).join(GYSHELL_READY_MARKER2)
294463
294971
  ).trimStart();
294464
- if (realContent) emit11(realContent);
294972
+ if (realContent) emit12(realContent);
294465
294973
  }
294466
294974
  instance.buffer = "";
294467
294975
  if (sawContinuation && instance.remoteOs === "windows" && instance.stream) {
@@ -294477,7 +294985,7 @@ var SSHBackend = class _SSHBackend {
294477
294985
  const sanitizedChunk = this.stripReadyMarker(chunk2);
294478
294986
  this.consumeOscMarkers(instance, sanitizedChunk);
294479
294987
  if (sanitizedChunk) {
294480
- emit11(sanitizedChunk);
294988
+ emit12(sanitizedChunk);
294481
294989
  }
294482
294990
  }
294483
294991
  });
@@ -294491,7 +294999,7 @@ var SSHBackend = class _SSHBackend {
294491
294999
  console.error(`[SSH] Client error:`, err);
294492
295000
  instance.initializationState = "failed";
294493
295001
  instance.isInitializing = false;
294494
- emit11(`\x1B[31m\u2718 SSH Error: ${err.message}\x1B[0m\r
295002
+ emit12(`\x1B[31m\u2718 SSH Error: ${err.message}\x1B[0m\r
294495
295003
  `);
294496
295004
  emitExit(-1);
294497
295005
  });
@@ -294514,7 +295022,7 @@ var SSHBackend = class _SSHBackend {
294514
295022
  sshConfig.privateKeyPath
294515
295023
  );
294516
295024
  } catch (e) {
294517
- emit11(
295025
+ emit12(
294518
295026
  `\x1B[31m\u2718 Failed to read private key: ${e.message}\x1B[0m\r
294519
295027
  `
294520
295028
  );
@@ -294526,19 +295034,19 @@ var SSHBackend = class _SSHBackend {
294526
295034
  }
294527
295035
  try {
294528
295036
  await new Promise((r) => setTimeout(r, 50));
294529
- emit11(
295037
+ emit12(
294530
295038
  `\x1B[36m\u25B9 Connecting to ${sshConfig.host}:${sshConfig.port}...\x1B[0m\r
294531
295039
  `
294532
295040
  );
294533
295041
  console.log(
294534
295042
  `[SSH] Attempting to connect to ${sshConfig.host}:${sshConfig.port}...`
294535
295043
  );
294536
- const sock = await this.buildConnectSocketIfNeeded(sshConfig, emit11);
295044
+ const sock = await this.buildConnectSocketIfNeeded(sshConfig, emit12);
294537
295045
  if (sock) {
294538
295046
  console.log(
294539
295047
  `[SSH] SUCCESS: Connection to ${sshConfig.host} will be tunneled through sock (Jump Host/Proxy).`
294540
295048
  );
294541
- emit11(
295049
+ emit12(
294542
295050
  "\x1B[36m\u25B9 [Final] Using tunnel socket for target connection...\x1B[0m\r\n"
294543
295051
  );
294544
295052
  connectConfig.sock = sock;
@@ -294552,7 +295060,7 @@ var SSHBackend = class _SSHBackend {
294552
295060
  const errMsg = e instanceof Error ? e.message : String(e);
294553
295061
  instance.initializationState = "failed";
294554
295062
  instance.isInitializing = false;
294555
- emit11(`\x1B[31m\u2718 Connection failed: ${errMsg}\x1B[0m\r
295063
+ emit12(`\x1B[31m\u2718 Connection failed: ${errMsg}\x1B[0m\r
294556
295064
  `);
294557
295065
  emitExit(-1);
294558
295066
  }
@@ -296501,6 +297009,8 @@ var PSRPTransport = class {
296501
297009
  /** pypsrp WSMan.session_id — one uuid for the life of the transport. */
296502
297010
  sessionId = `uuid:${(0, import_node_crypto3.randomUUID)().toUpperCase()}`;
296503
297011
  http;
297012
+ /** Persistent runspace (v3.8.0): reuse one Microsoft.PowerShell shell across commands. */
297013
+ pool = null;
296504
297014
  constructor(opts) {
296505
297015
  this.http = new WinHttpAuth({
296506
297016
  host: opts.host,
@@ -296524,6 +297034,7 @@ var PSRPTransport = class {
296524
297034
  const wsmv = "http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd";
296525
297035
  return `<s:Envelope xmlns:s="${NS2.s}" xmlns:wsa="${NS2.a}" xmlns:wsman="${NS2.w}" xmlns:wsmv="${wsmv}" xmlns:rsp="${NS2.rsp}" xml:lang="en-US"><s:Header><wsa:Action s:mustUnderstand="true">${action}</wsa:Action><wsmv:DataLocale s:mustUnderstand="false" xml:lang="en-US" /><wsman:Locale s:mustUnderstand="false" xml:lang="en-US" /><wsman:MaxEnvelopeSize s:mustUnderstand="true">512000</wsman:MaxEnvelopeSize><wsa:MessageID>${mid}</wsa:MessageID><wsman:OperationTimeout>PT60.000S</wsman:OperationTimeout><wsa:ReplyTo><wsa:Address s:mustUnderstand="true">${NS2.a}/role/anonymous</wsa:Address></wsa:ReplyTo><wsman:ResourceURI s:mustUnderstand="true">${PSRP_SHELL_URI}</wsman:ResourceURI><wsmv:SessionId s:mustUnderstand="false">${this.sessionId}</wsmv:SessionId><wsa:To>${to}</wsa:To>${extraHeaders}</s:Header><s:Body>${body}</s:Body></s:Envelope>`;
296526
297036
  }
297037
+ /** Test hook: subclasses may override. */
296527
297038
  async post(action, body, extraHeaders) {
296528
297039
  const envelope = this.envelope(action, body, extraHeaders);
296529
297040
  const res = await this.http.post(envelope);
@@ -296537,6 +297048,57 @@ var PSRPTransport = class {
296537
297048
  * Receive loop (PIPELINE_OUTPUT / ERROR_RECORD / PIPELINE_STATE) → Delete.
296538
297049
  * The script travels inside the PSRP message body — no command-line length limit.
296539
297050
  */
297051
+ /** Open (or return) a persistent runspace pool. */
297052
+ async ensurePool(opts) {
297053
+ if (this.pool) return { shellId: this.pool.shellId, rpid: this.pool.rpid };
297054
+ const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
297055
+ const rpid = (0, import_node_crypto3.randomUUID)().toUpperCase();
297056
+ const creation = fragmentMessages([
297057
+ psrpMessage(MSG.SESSION_CAPABILITY, rpid, "00000000-0000-0000-0000-000000000000", sessionCapabilityXml()),
297058
+ psrpMessage(MSG.INIT_RUNSPACEPOOL, rpid, "00000000-0000-0000-0000-000000000000", initRunspacePoolXml())
297059
+ ], 1);
297060
+ const createBody = `<rsp:Shell ShellId="${rpid}"><rsp:InputStreams>stdin pr</rsp:InputStreams><rsp:OutputStreams>stdout</rsp:OutputStreams><creationXml xmlns="http://schemas.microsoft.com/powershell">` + creation.blob.toString("base64") + `</creationXml></rsp:Shell>`;
297061
+ const createHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option MustComply="true" Name="protocolversion">2.3</wsman:Option></wsman:OptionSet>`;
297062
+ const created = await this.post(
297063
+ "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create",
297064
+ createBody,
297065
+ createHeaders
297066
+ );
297067
+ this.assertOk(created, "Create");
297068
+ const shellId = extractShellId2(created.body);
297069
+ if (!shellId) throw new Error("PSRP Create succeeded but no ShellId returned.");
297070
+ await this.waitForRunspaceOpened(shellId, deadline, opts?.signal);
297071
+ this.pool = { shellId, rpid, nextObjectId: creation.nextObjectId };
297072
+ return { shellId, rpid };
297073
+ }
297074
+ async closePool() {
297075
+ const p = this.pool;
297076
+ this.pool = null;
297077
+ if (p) await this.deleteShell(p.shellId);
297078
+ }
297079
+ /**
297080
+ * Run a script on the persistent pool (opens one if needed). Does NOT delete
297081
+ * the shell — call closePool() when the tab dies.
297082
+ */
297083
+ async runScriptOnPool(script, opts) {
297084
+ const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
297085
+ const pool = await this.ensurePool(opts);
297086
+ const pipelineId = (0, import_node_crypto3.randomUUID)().toUpperCase();
297087
+ const createPipelineMsg = psrpMessage(MSG.CREATE_PIPELINE, pool.rpid, pipelineId, createPipelineXml(script));
297088
+ const frag = fragmentMessages([createPipelineMsg], this.pool.nextObjectId);
297089
+ this.pool.nextObjectId = frag.nextObjectId;
297090
+ const commandBody = `<rsp:CommandLine CommandId="${pipelineId}"><rsp:Command></rsp:Command><rsp:Arguments>${frag.blob.toString("base64")}</rsp:Arguments></rsp:CommandLine>`;
297091
+ const commandHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WINRS_SKIP_CMD_SHELL">False</wsman:Option></wsman:OptionSet>` + this.shellHeaders(pool.shellId);
297092
+ const commanded = await this.post(
297093
+ "http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command",
297094
+ commandBody,
297095
+ commandHeaders
297096
+ );
297097
+ this.assertOk(commanded, "Command");
297098
+ const commandId = firstText2(commanded.body, "CommandId");
297099
+ if (!commandId) throw new Error("PSRP Command succeeded but no CommandId returned.");
297100
+ return this.receivePipeline(pool.shellId, commandId, deadline, opts);
297101
+ }
296540
297102
  async runScript(script, opts) {
296541
297103
  const deadline = Date.now() + (opts?.timeoutMs ?? 12e4);
296542
297104
  const rpid = (0, import_node_crypto3.randomUUID)().toUpperCase();
@@ -296569,63 +297131,76 @@ var PSRPTransport = class {
296569
297131
  this.assertOk(commanded, "Command");
296570
297132
  const commandId = firstText2(commanded.body, "CommandId");
296571
297133
  if (!commandId) throw new Error("PSRP Command succeeded but no CommandId returned.");
296572
- let stdout = "";
296573
- let stderr = "";
296574
- let hadErrors = false;
296575
- let exitCode = 0;
296576
- let pipelineDone = false;
296577
- for (; ; ) {
296578
- if (opts?.signal?.aborted) throw new Error("AbortError");
296579
- if (Date.now() > deadline) {
296580
- throw new Error(`PSRP command timed out after ${opts?.timeoutMs ?? 12e4}ms`);
296581
- }
296582
- const receiveBody = `<rsp:Receive><rsp:DesiredStream CommandId="${commandId}">stdout</rsp:DesiredStream></rsp:Receive>`;
296583
- const receiveHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WSMAN_CMDSHELL_OPTION_KEEPALIVE">True</wsman:Option></wsman:OptionSet>` + this.shellHeaders(shellId);
296584
- const received = await this.post(
296585
- "http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive",
296586
- receiveBody,
296587
- receiveHeaders
296588
- );
296589
- this.assertOk(received, "Receive");
296590
- const streamRe = /<\w*:?Stream\b[^>]*\bName="(?:stdout|stderr|pr)"[^>]*>([\s\S]*?)<\/\w*:?Stream>/gi;
296591
- let m2;
296592
- while ((m2 = streamRe.exec(received.body)) !== null) {
296593
- const b64 = m2[1].replace(/\s+/g, "");
296594
- if (!b64) continue;
296595
- for (const raw of unfragmentMessages(import_node_buffer2.Buffer.from(b64, "base64"))) {
296596
- if (raw.length < 40) continue;
296597
- const messageType = raw.readUInt32LE(4);
296598
- const payload = raw.subarray(40).toString("utf8").replace(/^\uFEFF/, "");
296599
- if (messageType === MSG.PIPELINE_OUTPUT) {
296600
- const sRe = /<S[^>]*>([\s\S]*?)<\/S>/gi;
296601
- let sm;
296602
- while ((sm = sRe.exec(payload)) !== null) stdout += sm[1];
296603
- } else if (messageType === MSG.ERROR_RECORD) {
296604
- hadErrors = true;
296605
- const mRe = payload.match(/<S N="Message">([\s\S]*?)<\/S>/i);
296606
- stderr += (mRe ? mRe[1] : payload) + "\n";
296607
- } else if (messageType === MSG.PIPELINE_STATE) {
296608
- pipelineDone = true;
296609
- const stateMatch = payload.match(/<I32 N="State">(\d+)<\/I32>/i);
296610
- if (stateMatch) {
296611
- if (parseInt(stateMatch[1], 10) === 5) hadErrors = true;
296612
- }
296613
- const ec = payload.match(/N="ExitCode"[^>]*>(-?\d+)</i);
296614
- if (ec) exitCode = parseInt(ec[1], 10);
296615
- }
296616
- }
296617
- }
296618
- const wsExit = received.body.match(/<\w*:?ExitCode>\s*(-?\d+)\s*<\/\w*:?ExitCode>/i);
296619
- if (wsExit) exitCode = parseInt(wsExit[1], 10);
296620
- if (pipelineDone) break;
296621
- if (/CommandState\/Done/i.test(received.body)) break;
296622
- }
296623
- if (exitCode !== 0) hadErrors = true;
296624
- return { stdout, stderr, exitCode, hadErrors };
297134
+ return await this.receivePipeline(shellId, commandId, deadline, opts);
296625
297135
  } finally {
296626
297136
  await this.deleteShell(shellId);
296627
297137
  }
296628
297138
  }
297139
+ async receivePipeline(shellId, commandId, deadline, opts) {
297140
+ let stdout = "";
297141
+ let stderr = "";
297142
+ let hadErrors = false;
297143
+ let exitCode = 0;
297144
+ let pipelineDone = false;
297145
+ for (; ; ) {
297146
+ if (opts?.signal?.aborted) throw new Error("AbortError");
297147
+ if (Date.now() > deadline) {
297148
+ throw new Error(`PSRP command timed out after ${opts?.timeoutMs ?? 12e4}ms`);
297149
+ }
297150
+ const receiveBody = `<rsp:Receive><rsp:DesiredStream CommandId="${commandId}">stdout</rsp:DesiredStream></rsp:Receive>`;
297151
+ const receiveHeaders = `<wsman:OptionSet s:mustUnderstand="true"><wsman:Option Name="WSMAN_CMDSHELL_OPTION_KEEPALIVE">True</wsman:Option></wsman:OptionSet>` + this.shellHeaders(shellId);
297152
+ const received = await this.post(
297153
+ "http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive",
297154
+ receiveBody,
297155
+ receiveHeaders
297156
+ );
297157
+ this.assertOk(received, "Receive");
297158
+ const streamRe = /<\w*:?Stream\b[^>]*\bName="(?:stdout|stderr|pr)"[^>]*>([\s\S]*?)<\/\w*:?Stream>/gi;
297159
+ let m2;
297160
+ while ((m2 = streamRe.exec(received.body)) !== null) {
297161
+ const b64 = m2[1].replace(/\s+/g, "");
297162
+ if (!b64) continue;
297163
+ for (const raw of unfragmentMessages(import_node_buffer2.Buffer.from(b64, "base64"))) {
297164
+ if (raw.length < 40) continue;
297165
+ const messageType = raw.readUInt32LE(4);
297166
+ const payload = raw.subarray(40).toString("utf8").replace(/^\uFEFF/, "");
297167
+ if (messageType === MSG.PIPELINE_OUTPUT) {
297168
+ const sRe = /<S[^>]*>([\s\S]*?)<\/S>/gi;
297169
+ let sm;
297170
+ let extracted = false;
297171
+ while ((sm = sRe.exec(payload)) !== null) {
297172
+ stdout += sm[1];
297173
+ extracted = true;
297174
+ }
297175
+ if (!extracted) {
297176
+ const nRe = /<(?:I32|I64|B|ToString)[^>]*>([\s\S]*?)<\/(?:I32|I64|B|ToString)>/i;
297177
+ const nm = payload.match(nRe);
297178
+ if (nm) stdout += nm[1];
297179
+ else stdout += payload.replace(/<[^>]+>/g, "").trim();
297180
+ }
297181
+ } else if (messageType === MSG.ERROR_RECORD) {
297182
+ hadErrors = true;
297183
+ const mRe = payload.match(/<S N="Message">([\s\S]*?)<\/S>/i);
297184
+ stderr += (mRe ? mRe[1] : payload) + "\n";
297185
+ } else if (messageType === MSG.PIPELINE_STATE) {
297186
+ pipelineDone = true;
297187
+ const stateMatch = payload.match(/<I32 N="State">(\d+)<\/I32>/i);
297188
+ if (stateMatch) {
297189
+ if (parseInt(stateMatch[1], 10) === 5) hadErrors = true;
297190
+ }
297191
+ const ec = payload.match(/N="ExitCode"[^>]*>(-?\d+)</i);
297192
+ if (ec) exitCode = parseInt(ec[1], 10);
297193
+ }
297194
+ }
297195
+ }
297196
+ const wsExit = received.body.match(/<\w*:?ExitCode>\s*(-?\d+)\s*<\/\w*:?ExitCode>/i);
297197
+ if (wsExit) exitCode = parseInt(wsExit[1], 10);
297198
+ if (pipelineDone) break;
297199
+ if (/CommandState\/Done/i.test(received.body)) break;
297200
+ }
297201
+ if (exitCode !== 0) hadErrors = true;
297202
+ return { stdout, stderr, exitCode, hadErrors };
297203
+ }
296629
297204
  /**
296630
297205
  * Drain Receive until RUNSPACEPOOL_STATE reports Opened (state=2).
296631
297206
  * Must run after Create and before Command.
@@ -296830,7 +297405,7 @@ Run commands with exec_command / run_fleet_command. Interactive TUI apps are not
296830
297405
  \x1B[36m\u276F ${command}\x1B[0m\r
296831
297406
  `);
296832
297407
  const ps = this.translateCmdToPowerShell(command, instance.cwd);
296833
- const result = await transport.runScript(ps, {
297408
+ const result = await transport.runScriptOnPool(ps, {
296834
297409
  timeoutMs: options?.timeoutMs ?? DEFAULT_WINRM_TIMEOUT_MS,
296835
297410
  signal: options?.signal
296836
297411
  });
@@ -296951,6 +297526,9 @@ Run commands with exec_command / run_fleet_command. Interactive TUI apps are not
296951
297526
  void instance.winrm.deleteShell(instance.persistentShellId);
296952
297527
  instance.persistentShellId = void 0;
296953
297528
  }
297529
+ if (instance.psrp) {
297530
+ void instance.psrp.closePool();
297531
+ }
296954
297532
  instance.exitCallback?.(0);
296955
297533
  }
296956
297534
  onData(ptyId, callback) {
@@ -297003,11 +297581,11 @@ Run commands with exec_command / run_fleet_command. Interactive TUI apps are not
297003
297581
  var import_node_crypto5 = require("node:crypto");
297004
297582
  var injectedSerial = null;
297005
297583
  var lazySerial;
297006
- function constructPort(Ctor, path33, opts) {
297584
+ function constructPort(Ctor, path34, opts) {
297007
297585
  try {
297008
- return new Ctor(path33, opts);
297586
+ return new Ctor(path34, opts);
297009
297587
  } catch (e) {
297010
- if (e instanceof TypeError) return new Ctor({ path: path33, ...opts });
297588
+ if (e instanceof TypeError) return new Ctor({ path: path34, ...opts });
297011
297589
  throw e;
297012
297590
  }
297013
297591
  }
@@ -297025,7 +297603,7 @@ var SerialBackend = class {
297025
297603
  try {
297026
297604
  const mod = require("serialport");
297027
297605
  const Ctor = typeof mod?.SerialPort === "function" ? mod.SerialPort : mod;
297028
- lazySerial = ((path33, opts) => constructPort(Ctor, path33, opts));
297606
+ lazySerial = ((path34, opts) => constructPort(Ctor, path34, opts));
297029
297607
  } catch {
297030
297608
  lazySerial = null;
297031
297609
  }
@@ -301479,8 +302057,8 @@ function shallowCopy(obj) {
301479
302057
  }
301480
302058
  function replaceSecrets(root, secretsMap) {
301481
302059
  const result = shallowCopy(root);
301482
- for (const [path33, secretId] of Object.entries(secretsMap)) {
301483
- const [last, ...partsReverse] = path33.split(".").reverse();
302060
+ for (const [path34, secretId] of Object.entries(secretsMap)) {
302061
+ const [last, ...partsReverse] = path34.split(".").reverse();
301484
302062
  let current = result;
301485
302063
  for (const part of partsReverse.reverse()) {
301486
302064
  if (current[part] === void 0) break;
@@ -306544,9 +307122,9 @@ var Client = class _Client {
306544
307122
  }
306545
307123
  return headers;
306546
307124
  }
306547
- _getPlatformEndpointPath(path33) {
307125
+ _getPlatformEndpointPath(path34) {
306548
307126
  const needsV1Prefix = this.apiUrl.slice(-3) !== "/v1" && this.apiUrl.slice(-4) !== "/v1/";
306549
- return needsV1Prefix ? `/v1/platform/${path33}` : `/platform/${path33}`;
307127
+ return needsV1Prefix ? `/v1/platform/${path34}` : `/platform/${path34}`;
306550
307128
  }
306551
307129
  async processInputs(inputs) {
306552
307130
  if (this.hideInputs === false) {
@@ -306582,9 +307160,9 @@ var Client = class _Client {
306582
307160
  }
306583
307161
  return runParams;
306584
307162
  }
306585
- async _getResponse(path33, queryParams) {
307163
+ async _getResponse(path34, queryParams) {
306586
307164
  const paramsString = queryParams?.toString() ?? "";
306587
- const url2 = `${this.apiUrl}${path33}?${paramsString}`;
307165
+ const url2 = `${this.apiUrl}${path34}?${paramsString}`;
306588
307166
  const response = await this.caller.call(async () => {
306589
307167
  const res = await this._fetch(url2, {
306590
307168
  method: "GET",
@@ -306592,22 +307170,22 @@ var Client = class _Client {
306592
307170
  signal: AbortSignal.timeout(this.timeout_ms),
306593
307171
  ...this.fetchOptions
306594
307172
  });
306595
- await raiseForStatus(res, `fetch ${path33}`);
307173
+ await raiseForStatus(res, `fetch ${path34}`);
306596
307174
  return res;
306597
307175
  });
306598
307176
  return response;
306599
307177
  }
306600
- async _get(path33, queryParams) {
306601
- const response = await this._getResponse(path33, queryParams);
307178
+ async _get(path34, queryParams) {
307179
+ const response = await this._getResponse(path34, queryParams);
306602
307180
  return response.json();
306603
307181
  }
306604
- async *_getPaginated(path33, queryParams = new URLSearchParams(), transform2) {
307182
+ async *_getPaginated(path34, queryParams = new URLSearchParams(), transform2) {
306605
307183
  let offset = Number(queryParams.get("offset")) || 0;
306606
307184
  const limit2 = Number(queryParams.get("limit")) || 100;
306607
307185
  while (true) {
306608
307186
  queryParams.set("offset", String(offset));
306609
307187
  queryParams.set("limit", String(limit2));
306610
- const url2 = `${this.apiUrl}${path33}?${queryParams}`;
307188
+ const url2 = `${this.apiUrl}${path34}?${queryParams}`;
306611
307189
  const response = await this.caller.call(async () => {
306612
307190
  const res = await this._fetch(url2, {
306613
307191
  method: "GET",
@@ -306615,7 +307193,7 @@ var Client = class _Client {
306615
307193
  signal: AbortSignal.timeout(this.timeout_ms),
306616
307194
  ...this.fetchOptions
306617
307195
  });
306618
- await raiseForStatus(res, `fetch ${path33}`);
307196
+ await raiseForStatus(res, `fetch ${path34}`);
306619
307197
  return res;
306620
307198
  });
306621
307199
  const items = transform2 ? transform2(await response.json()) : await response.json();
@@ -306629,19 +307207,19 @@ var Client = class _Client {
306629
307207
  offset += items.length;
306630
307208
  }
306631
307209
  }
306632
- async *_getCursorPaginatedList(path33, body = null, requestMethod = "POST", dataKey = "runs") {
307210
+ async *_getCursorPaginatedList(path34, body = null, requestMethod = "POST", dataKey = "runs") {
306633
307211
  const bodyParams = body ? { ...body } : {};
306634
307212
  while (true) {
306635
307213
  const body2 = JSON.stringify(bodyParams);
306636
307214
  const response = await this.caller.call(async () => {
306637
- const res = await this._fetch(`${this.apiUrl}${path33}`, {
307215
+ const res = await this._fetch(`${this.apiUrl}${path34}`, {
306638
307216
  method: requestMethod,
306639
307217
  headers: { ...this.headers, "Content-Type": "application/json" },
306640
307218
  signal: AbortSignal.timeout(this.timeout_ms),
306641
307219
  ...this.fetchOptions,
306642
307220
  body: body2
306643
307221
  });
306644
- await raiseForStatus(res, `fetch ${path33}`);
307222
+ await raiseForStatus(res, `fetch ${path34}`);
306645
307223
  return res;
306646
307224
  });
306647
307225
  const responseBody = await response.json();
@@ -307570,8 +308148,8 @@ Context: ${context2}`);
307570
308148
  limit: Number(limit2) || 100
307571
308149
  };
307572
308150
  let currentOffset = Number(offset) || 0;
307573
- const path33 = "/runs/group";
307574
- const url2 = `${this.apiUrl}${path33}`;
308151
+ const path34 = "/runs/group";
308152
+ const url2 = `${this.apiUrl}${path34}`;
307575
308153
  while (true) {
307576
308154
  const currentBody = {
307577
308155
  ...baseBody,
@@ -307587,7 +308165,7 @@ Context: ${context2}`);
307587
308165
  ...this.fetchOptions,
307588
308166
  body
307589
308167
  });
307590
- await raiseForStatus(res, `Failed to fetch ${path33}`);
308168
+ await raiseForStatus(res, `Failed to fetch ${path34}`);
307591
308169
  return res;
307592
308170
  });
307593
308171
  const items = await response.json();
@@ -307904,20 +308482,20 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
307904
308482
  return result;
307905
308483
  }
307906
308484
  async hasProject({ projectId, projectName }) {
307907
- let path33 = "/sessions";
308485
+ let path34 = "/sessions";
307908
308486
  const params = new URLSearchParams();
307909
308487
  if (projectId !== void 0 && projectName !== void 0) {
307910
308488
  throw new Error("Must provide either projectName or projectId, not both");
307911
308489
  } else if (projectId !== void 0) {
307912
308490
  assertUuid(projectId);
307913
- path33 += `/${projectId}`;
308491
+ path34 += `/${projectId}`;
307914
308492
  } else if (projectName !== void 0) {
307915
308493
  params.append("name", projectName);
307916
308494
  } else {
307917
308495
  throw new Error("Must provide projectName or projectId");
307918
308496
  }
307919
308497
  const response = await this.caller.call(async () => {
307920
- const res = await this._fetch(`${this.apiUrl}${path33}?${params}`, {
308498
+ const res = await this._fetch(`${this.apiUrl}${path34}?${params}`, {
307921
308499
  method: "GET",
307922
308500
  headers: this.headers,
307923
308501
  signal: AbortSignal.timeout(this.timeout_ms),
@@ -307940,13 +308518,13 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
307940
308518
  }
307941
308519
  }
307942
308520
  async readProject({ projectId, projectName, includeStats }) {
307943
- let path33 = "/sessions";
308521
+ let path34 = "/sessions";
307944
308522
  const params = new URLSearchParams();
307945
308523
  if (projectId !== void 0 && projectName !== void 0) {
307946
308524
  throw new Error("Must provide either projectName or projectId, not both");
307947
308525
  } else if (projectId !== void 0) {
307948
308526
  assertUuid(projectId);
307949
- path33 += `/${projectId}`;
308527
+ path34 += `/${projectId}`;
307950
308528
  } else if (projectName !== void 0) {
307951
308529
  params.append("name", projectName);
307952
308530
  } else {
@@ -307955,7 +308533,7 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
307955
308533
  if (includeStats !== void 0) {
307956
308534
  params.append("include_stats", includeStats.toString());
307957
308535
  }
307958
- const response = await this._get(path33, params);
308536
+ const response = await this._get(path34, params);
307959
308537
  let result;
307960
308538
  if (Array.isArray(response)) {
307961
308539
  if (response.length === 0) {
@@ -308118,19 +308696,19 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308118
308696
  return result;
308119
308697
  }
308120
308698
  async readDataset({ datasetId, datasetName }) {
308121
- let path33 = "/datasets";
308699
+ let path34 = "/datasets";
308122
308700
  const params = new URLSearchParams({ limit: "1" });
308123
308701
  if (datasetId && datasetName) {
308124
308702
  throw new Error("Must provide either datasetName or datasetId, not both");
308125
308703
  } else if (datasetId) {
308126
308704
  assertUuid(datasetId);
308127
- path33 += `/${datasetId}`;
308705
+ path34 += `/${datasetId}`;
308128
308706
  } else if (datasetName) {
308129
308707
  params.append("name", datasetName);
308130
308708
  } else {
308131
308709
  throw new Error("Must provide datasetName or datasetId");
308132
308710
  }
308133
- const response = await this._get(path33, params);
308711
+ const response = await this._get(path34, params);
308134
308712
  let result;
308135
308713
  if (Array.isArray(response)) {
308136
308714
  if (response.length === 0) {
@@ -308174,20 +308752,20 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308174
308752
  return response;
308175
308753
  }
308176
308754
  async readDatasetOpenaiFinetuning({ datasetId, datasetName }) {
308177
- const path33 = "/datasets";
308755
+ const path34 = "/datasets";
308178
308756
  if (datasetId !== void 0) {
308179
308757
  } else if (datasetName !== void 0) {
308180
308758
  datasetId = (await this.readDataset({ datasetName })).id;
308181
308759
  } else {
308182
308760
  throw new Error("Must provide either datasetName or datasetId");
308183
308761
  }
308184
- const response = await this._getResponse(`${path33}/${datasetId}/openai_ft`);
308762
+ const response = await this._getResponse(`${path34}/${datasetId}/openai_ft`);
308185
308763
  const datasetText = await response.text();
308186
308764
  const dataset = datasetText.trim().split("\n").map((line) => JSON.parse(line));
308187
308765
  return dataset;
308188
308766
  }
308189
308767
  async *listDatasets({ limit: limit2 = 100, offset = 0, datasetIds, datasetName, datasetNameContains, metadata } = {}) {
308190
- const path33 = "/datasets";
308768
+ const path34 = "/datasets";
308191
308769
  const params = new URLSearchParams({
308192
308770
  limit: limit2.toString(),
308193
308771
  offset: offset.toString()
@@ -308206,7 +308784,7 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308206
308784
  if (metadata !== void 0) {
308207
308785
  params.append("metadata", JSON.stringify(metadata));
308208
308786
  }
308209
- for await (const datasets of this._getPaginated(path33, params)) {
308787
+ for await (const datasets of this._getPaginated(path34, params)) {
308210
308788
  yield* datasets;
308211
308789
  }
308212
308790
  }
@@ -308275,7 +308853,7 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308275
308853
  });
308276
308854
  }
308277
308855
  async deleteDataset({ datasetId, datasetName }) {
308278
- let path33 = "/datasets";
308856
+ let path34 = "/datasets";
308279
308857
  let datasetId_ = datasetId;
308280
308858
  if (datasetId !== void 0 && datasetName !== void 0) {
308281
308859
  throw new Error("Must provide either datasetName or datasetId, not both");
@@ -308285,18 +308863,18 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308285
308863
  }
308286
308864
  if (datasetId_ !== void 0) {
308287
308865
  assertUuid(datasetId_);
308288
- path33 += `/${datasetId_}`;
308866
+ path34 += `/${datasetId_}`;
308289
308867
  } else {
308290
308868
  throw new Error("Must provide datasetName or datasetId");
308291
308869
  }
308292
308870
  await this.caller.call(async () => {
308293
- const res = await this._fetch(this.apiUrl + path33, {
308871
+ const res = await this._fetch(this.apiUrl + path34, {
308294
308872
  method: "DELETE",
308295
308873
  headers: this.headers,
308296
308874
  signal: AbortSignal.timeout(this.timeout_ms),
308297
308875
  ...this.fetchOptions
308298
308876
  });
308299
- await raiseForStatus(res, `delete ${path33}`, true);
308877
+ await raiseForStatus(res, `delete ${path34}`, true);
308300
308878
  return res;
308301
308879
  });
308302
308880
  }
@@ -308487,8 +309065,8 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308487
309065
  }
308488
309066
  async readExample(exampleId) {
308489
309067
  assertUuid(exampleId);
308490
- const path33 = `/examples/${exampleId}`;
308491
- const rawExample = await this._get(path33);
309068
+ const path34 = `/examples/${exampleId}`;
309069
+ const rawExample = await this._get(path34);
308492
309070
  const { attachment_urls, ...rest } = rawExample;
308493
309071
  const example = rest;
308494
309072
  if (attachment_urls) {
@@ -308571,15 +309149,15 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308571
309149
  }
308572
309150
  async deleteExample(exampleId) {
308573
309151
  assertUuid(exampleId);
308574
- const path33 = `/examples/${exampleId}`;
309152
+ const path34 = `/examples/${exampleId}`;
308575
309153
  await this.caller.call(async () => {
308576
- const res = await this._fetch(this.apiUrl + path33, {
309154
+ const res = await this._fetch(this.apiUrl + path34, {
308577
309155
  method: "DELETE",
308578
309156
  headers: this.headers,
308579
309157
  signal: AbortSignal.timeout(this.timeout_ms),
308580
309158
  ...this.fetchOptions
308581
309159
  });
308582
- await raiseForStatus(res, `delete ${path33}`, true);
309160
+ await raiseForStatus(res, `delete ${path34}`, true);
308583
309161
  return res;
308584
309162
  });
308585
309163
  }
@@ -308592,9 +309170,9 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308592
309170
  async deleteExamples(exampleIds, options) {
308593
309171
  exampleIds.forEach((id) => assertUuid(id));
308594
309172
  if (options?.hardDelete) {
308595
- const path33 = this._getPlatformEndpointPath("datasets/examples/delete");
309173
+ const path34 = this._getPlatformEndpointPath("datasets/examples/delete");
308596
309174
  await this.caller.call(async () => {
308597
- const res = await this._fetch(`${this.apiUrl}${path33}`, {
309175
+ const res = await this._fetch(`${this.apiUrl}${path34}`, {
308598
309176
  method: "POST",
308599
309177
  headers: { ...this.headers, "Content-Type": "application/json" },
308600
309178
  body: JSON.stringify({
@@ -308828,21 +309406,21 @@ Message: ${Array.isArray(result.detail) ? result.detail.join("\n") : "Unspecifie
308828
309406
  }
308829
309407
  async readFeedback(feedbackId) {
308830
309408
  assertUuid(feedbackId);
308831
- const path33 = `/feedback/${feedbackId}`;
308832
- const response = await this._get(path33);
309409
+ const path34 = `/feedback/${feedbackId}`;
309410
+ const response = await this._get(path34);
308833
309411
  return response;
308834
309412
  }
308835
309413
  async deleteFeedback(feedbackId) {
308836
309414
  assertUuid(feedbackId);
308837
- const path33 = `/feedback/${feedbackId}`;
309415
+ const path34 = `/feedback/${feedbackId}`;
308838
309416
  await this.caller.call(async () => {
308839
- const res = await this._fetch(this.apiUrl + path33, {
309417
+ const res = await this._fetch(this.apiUrl + path34, {
308840
309418
  method: "DELETE",
308841
309419
  headers: this.headers,
308842
309420
  signal: AbortSignal.timeout(this.timeout_ms),
308843
309421
  ...this.fetchOptions
308844
309422
  });
308845
- await raiseForStatus(res, `delete ${path33}`, true);
309423
+ await raiseForStatus(res, `delete ${path34}`, true);
308846
309424
  return res;
308847
309425
  });
308848
309426
  }
@@ -312438,12 +313016,12 @@ function isInteger(str3) {
312438
313016
  }
312439
313017
  return true;
312440
313018
  }
312441
- function escapePathComponent(path33) {
312442
- if (path33.indexOf("/") === -1 && path33.indexOf("~") === -1) return path33;
312443
- return path33.replace(/~/g, "~0").replace(/\//g, "~1");
313019
+ function escapePathComponent(path34) {
313020
+ if (path34.indexOf("/") === -1 && path34.indexOf("~") === -1) return path34;
313021
+ return path34.replace(/~/g, "~0").replace(/\//g, "~1");
312444
313022
  }
312445
- function unescapePathComponent(path33) {
312446
- return path33.replace(/~1/g, "/").replace(/~0/g, "~");
313023
+ function unescapePathComponent(path34) {
313024
+ return path34.replace(/~1/g, "/").replace(/~0/g, "~");
312447
313025
  }
312448
313026
  function hasUndefined(obj) {
312449
313027
  if (obj === void 0) return true;
@@ -312637,8 +313215,8 @@ function applyOperation(document2, operation, validateOperation = false, mutateD
312637
313215
  else return returnValue;
312638
313216
  } else {
312639
313217
  if (!mutateDocument) document2 = _deepClone(document2);
312640
- const path33 = operation.path || "";
312641
- const keys = path33.split("/");
313218
+ const path34 = operation.path || "";
313219
+ const keys = path34.split("/");
312642
313220
  let obj = document2;
312643
313221
  let t = 1;
312644
313222
  let len = keys.length;
@@ -312761,7 +313339,7 @@ function _areEquals(a, b) {
312761
313339
  }
312762
313340
 
312763
313341
  // ../../node_modules/@langchain/core/dist/utils/fast-json-patch/src/duplex.js
312764
- function _generate(mirror, obj, patches, path33, invertible) {
313342
+ function _generate(mirror, obj, patches, path34, invertible) {
312765
313343
  if (obj === mirror) return;
312766
313344
  if (typeof obj.toJSON === "function") obj = obj.toJSON();
312767
313345
  var newKeys = _objectKeys(obj);
@@ -312773,40 +313351,40 @@ function _generate(mirror, obj, patches, path33, invertible) {
312773
313351
  var oldVal = mirror[key];
312774
313352
  if (hasOwnProperty(obj, key) && !(obj[key] === void 0 && oldVal !== void 0 && Array.isArray(obj) === false)) {
312775
313353
  var newVal = obj[key];
312776
- if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) _generate(oldVal, newVal, patches, path33 + "/" + escapePathComponent(key), invertible);
313354
+ if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) _generate(oldVal, newVal, patches, path34 + "/" + escapePathComponent(key), invertible);
312777
313355
  else if (oldVal !== newVal) {
312778
313356
  changed = true;
312779
313357
  if (invertible) patches.push({
312780
313358
  op: "test",
312781
- path: path33 + "/" + escapePathComponent(key),
313359
+ path: path34 + "/" + escapePathComponent(key),
312782
313360
  value: _deepClone(oldVal)
312783
313361
  });
312784
313362
  patches.push({
312785
313363
  op: "replace",
312786
- path: path33 + "/" + escapePathComponent(key),
313364
+ path: path34 + "/" + escapePathComponent(key),
312787
313365
  value: _deepClone(newVal)
312788
313366
  });
312789
313367
  }
312790
313368
  } else if (Array.isArray(mirror) === Array.isArray(obj)) {
312791
313369
  if (invertible) patches.push({
312792
313370
  op: "test",
312793
- path: path33 + "/" + escapePathComponent(key),
313371
+ path: path34 + "/" + escapePathComponent(key),
312794
313372
  value: _deepClone(oldVal)
312795
313373
  });
312796
313374
  patches.push({
312797
313375
  op: "remove",
312798
- path: path33 + "/" + escapePathComponent(key)
313376
+ path: path34 + "/" + escapePathComponent(key)
312799
313377
  });
312800
313378
  deleted = true;
312801
313379
  } else {
312802
313380
  if (invertible) patches.push({
312803
313381
  op: "test",
312804
- path: path33,
313382
+ path: path34,
312805
313383
  value: mirror
312806
313384
  });
312807
313385
  patches.push({
312808
313386
  op: "replace",
312809
- path: path33,
313387
+ path: path34,
312810
313388
  value: obj
312811
313389
  });
312812
313390
  changed = true;
@@ -312817,7 +313395,7 @@ function _generate(mirror, obj, patches, path33, invertible) {
312817
313395
  var key = newKeys[t];
312818
313396
  if (!hasOwnProperty(mirror, key) && obj[key] !== void 0) patches.push({
312819
313397
  op: "add",
312820
- path: path33 + "/" + escapePathComponent(key),
313398
+ path: path34 + "/" + escapePathComponent(key),
312821
313399
  value: _deepClone(obj[key])
312822
313400
  });
312823
313401
  }
@@ -314203,10 +314781,10 @@ function assignProp(target, prop, value) {
314203
314781
  configurable: true
314204
314782
  });
314205
314783
  }
314206
- function getElementAtPath(obj, path33) {
314207
- if (!path33)
314784
+ function getElementAtPath(obj, path34) {
314785
+ if (!path34)
314208
314786
  return obj;
314209
- return path33.reduce((acc, key) => acc?.[key], obj);
314787
+ return path34.reduce((acc, key) => acc?.[key], obj);
314210
314788
  }
314211
314789
  function promiseAllObject(promisesObj) {
314212
314790
  const keys = Object.keys(promisesObj);
@@ -314526,11 +315104,11 @@ function aborted(x, startIndex = 0) {
314526
315104
  }
314527
315105
  return false;
314528
315106
  }
314529
- function prefixIssues(path33, issues) {
315107
+ function prefixIssues(path34, issues) {
314530
315108
  return issues.map((iss) => {
314531
315109
  var _a3;
314532
315110
  (_a3 = iss).path ?? (_a3.path = []);
314533
- iss.path.unshift(path33);
315111
+ iss.path.unshift(path34);
314534
315112
  return iss;
314535
315113
  });
314536
315114
  }
@@ -314667,7 +315245,7 @@ function treeifyError(error40, _mapper) {
314667
315245
  return issue2.message;
314668
315246
  };
314669
315247
  const result = { errors: [] };
314670
- const processError = (error41, path33 = []) => {
315248
+ const processError = (error41, path34 = []) => {
314671
315249
  var _a3, _b;
314672
315250
  for (const issue2 of error41.issues) {
314673
315251
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -314677,7 +315255,7 @@ function treeifyError(error40, _mapper) {
314677
315255
  } else if (issue2.code === "invalid_element") {
314678
315256
  processError({ issues: issue2.issues }, issue2.path);
314679
315257
  } else {
314680
- const fullpath = [...path33, ...issue2.path];
315258
+ const fullpath = [...path34, ...issue2.path];
314681
315259
  if (fullpath.length === 0) {
314682
315260
  result.errors.push(mapper(issue2));
314683
315261
  continue;
@@ -314707,9 +315285,9 @@ function treeifyError(error40, _mapper) {
314707
315285
  processError(error40);
314708
315286
  return result;
314709
315287
  }
314710
- function toDotPath(path33) {
315288
+ function toDotPath(path34) {
314711
315289
  const segs = [];
314712
- for (const seg of path33) {
315290
+ for (const seg of path34) {
314713
315291
  if (typeof seg === "number")
314714
315292
  segs.push(`[${seg}]`);
314715
315293
  else if (typeof seg === "symbol")
@@ -326957,10 +327535,10 @@ var Runnable = class extends Serializable {
326957
327535
  }
326958
327536
  const paths = log.ops.filter((op) => op.path.startsWith("/logs/")).map((op) => op.path.split("/")[2]);
326959
327537
  const dedupedPaths = [...new Set(paths)];
326960
- for (const path33 of dedupedPaths) {
327538
+ for (const path34 of dedupedPaths) {
326961
327539
  let eventType;
326962
327540
  let data = {};
326963
- const logEntry = runLog.state.logs[path33];
327541
+ const logEntry = runLog.state.logs[path34];
326964
327542
  if (logEntry.end_time === void 0) if (logEntry.streamed_output.length > 0) eventType = "stream";
326965
327543
  else eventType = "start";
326966
327544
  else eventType = "end";
@@ -332653,7 +333231,7 @@ var initializeSax = function() {
332653
333231
  if (parser.opt.xmlns) parser.ns = Object.create(rootNS);
332654
333232
  parser.trackPosition = parser.opt.position !== false;
332655
333233
  if (parser.trackPosition) parser.position = parser.line = parser.column = 0;
332656
- emit11(parser, "onready");
333234
+ emit12(parser, "onready");
332657
333235
  }
332658
333236
  if (!Object.create) Object.create = function(o) {
332659
333237
  function F2() {
@@ -333119,16 +333697,16 @@ var initializeSax = function() {
333119
333697
  });
333120
333698
  for (var s in sax$1.STATE) sax$1.STATE[sax$1.STATE[s]] = s;
333121
333699
  S2 = sax$1.STATE;
333122
- function emit11(parser, event, data) {
333700
+ function emit12(parser, event, data) {
333123
333701
  parser[event] && parser[event](data);
333124
333702
  }
333125
333703
  function emitNode(parser, nodeType, data) {
333126
333704
  if (parser.textNode) closeText(parser);
333127
- emit11(parser, nodeType, data);
333705
+ emit12(parser, nodeType, data);
333128
333706
  }
333129
333707
  function closeText(parser) {
333130
333708
  parser.textNode = textopts(parser.opt, parser.textNode);
333131
- if (parser.textNode) emit11(parser, "ontext", parser.textNode);
333709
+ if (parser.textNode) emit12(parser, "ontext", parser.textNode);
333132
333710
  parser.textNode = "";
333133
333711
  }
333134
333712
  function textopts(opt, text) {
@@ -333141,7 +333719,7 @@ var initializeSax = function() {
333141
333719
  if (parser.trackPosition) er += "\nLine: " + parser.line + "\nColumn: " + parser.column + "\nChar: " + parser.c;
333142
333720
  er = new Error(er);
333143
333721
  parser.error = er;
333144
- emit11(parser, "onerror", er);
333722
+ emit12(parser, "onerror", er);
333145
333723
  return parser;
333146
333724
  }
333147
333725
  function end(parser) {
@@ -333150,7 +333728,7 @@ var initializeSax = function() {
333150
333728
  closeText(parser);
333151
333729
  parser.c = "";
333152
333730
  parser.closed = true;
333153
- emit11(parser, "onend");
333731
+ emit12(parser, "onend");
333154
333732
  SAXParser.call(parser, parser.strict, parser.opt);
333155
333733
  return parser;
333156
333734
  }
@@ -339025,13 +339603,13 @@ function combineAliasesAndInvert(constructor) {
339025
339603
  }, {});
339026
339604
  }
339027
339605
  async function reviver(value) {
339028
- const { optionalImportsMap, optionalImportEntrypoints: optionalImportEntrypoints$1, importMap, secretsMap, secretsFromEnv, path: path33, depth, maxDepth } = this;
339029
- const pathStr = path33.join(".");
339606
+ const { optionalImportsMap, optionalImportEntrypoints: optionalImportEntrypoints$1, importMap, secretsMap, secretsFromEnv, path: path34, depth, maxDepth } = this;
339607
+ const pathStr = path34.join(".");
339030
339608
  if (depth > maxDepth) throw new Error(`Maximum recursion depth (${maxDepth}) exceeded during deserialization. This may indicate a malicious payload or you may need to increase maxDepth.`);
339031
339609
  if (typeof value !== "object" || value == null) return value;
339032
339610
  if (Array.isArray(value)) return Promise.all(value.map((v, i) => reviver.call({
339033
339611
  ...this,
339034
- path: [...path33, `${i}`],
339612
+ path: [...path34, `${i}`],
339035
339613
  depth: depth + 1
339036
339614
  }, v)));
339037
339615
  const record2 = value;
@@ -339086,7 +339664,7 @@ async function reviver(value) {
339086
339664
  if (typeof builder !== "function") throw new Error(`Invalid identifer: ${pathStr} -> ${str3}`);
339087
339665
  const kwargs = await reviver.call({
339088
339666
  ...this,
339089
- path: [...path33, "kwargs"],
339667
+ path: [...path34, "kwargs"],
339090
339668
  depth: depth + 1
339091
339669
  }, serialized.kwargs);
339092
339670
  const instance = new builder(mapKeys(kwargs, keyFromJson, combineAliasesAndInvert(builder)));
@@ -339096,7 +339674,7 @@ async function reviver(value) {
339096
339674
  const result = {};
339097
339675
  for (const [key, val] of Object.entries(record2)) result[key] = await reviver.call({
339098
339676
  ...this,
339099
- path: [...path33, key],
339677
+ path: [...path34, key],
339100
339678
  depth: depth + 1
339101
339679
  }, val);
339102
339680
  return result;
@@ -344224,10 +344802,10 @@ var Graph$1 = class {
344224
344802
  this.edges.add([startKey, endKey]);
344225
344803
  return this;
344226
344804
  }
344227
- addConditionalEdges(source, path33, pathMap) {
344805
+ addConditionalEdges(source, path34, pathMap) {
344228
344806
  const options = typeof source === "object" ? source : {
344229
344807
  source,
344230
- path: path33,
344808
+ path: path34,
344231
344809
  pathMap
344232
344810
  };
344233
344811
  this.warnIfCompiled("Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.");
@@ -345290,6 +345868,28 @@ var MessagesZodState = external_exports.object({ messages: withLangGraph(externa
345290
345868
  // ../../node_modules/@langchain/langgraph/dist/index.js
345291
345869
  initializeAsyncLocalStorageSingleton();
345292
345870
 
345871
+ // ../../packages/backend/src/services/redaction/secretRedact.ts
345872
+ var PATTERNS = [
345873
+ { re: /\b(gys_at_[A-Za-z0-9_-]{16,})\b/g, label: "RTERM_TOKEN" },
345874
+ { re: /\b(ghp_[A-Za-z0-9]{20,})\b/g, label: "GITHUB_PAT" },
345875
+ { re: /\b(sk-[A-Za-z0-9_-]{20,})\b/g, label: "API_KEY" },
345876
+ { re: /\b(AKIA[0-9A-Z]{16})\b/g, label: "AWS_KEY" },
345877
+ { re: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, label: "PRIVATE_KEY" },
345878
+ { re: /(password|passwd|pwd|secret|token)\s*[:=]\s*["']?([^\s"']{6,})/gi, label: "CREDENTIAL" }
345879
+ ];
345880
+ function redactText(input, extraValues = []) {
345881
+ let out = String(input ?? "");
345882
+ for (const v of extraValues) {
345883
+ const t = String(v || "");
345884
+ if (t.length < 4) continue;
345885
+ out = out.split(t).join(`[REDACTED]`);
345886
+ }
345887
+ for (const p of PATTERNS) {
345888
+ out = out.replace(p.re, `[REDACTED:${p.label}]`);
345889
+ }
345890
+ return out;
345891
+ }
345892
+
345293
345893
  // ../../packages/backend/src/services/agentRunLedger.ts
345294
345894
  var import_node_fs3 = __toESM(require("node:fs"), 1);
345295
345895
  var import_node_path5 = __toESM(require("node:path"), 1);
@@ -345759,16 +346359,16 @@ var Diff = class {
345759
346359
  }
345760
346360
  }
345761
346361
  }
345762
- addToPath(path33, added, removed, oldPosInc, options) {
345763
- const last = path33.lastComponent;
346362
+ addToPath(path34, added, removed, oldPosInc, options) {
346363
+ const last = path34.lastComponent;
345764
346364
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
345765
346365
  return {
345766
- oldPos: path33.oldPos + oldPosInc,
346366
+ oldPos: path34.oldPos + oldPosInc,
345767
346367
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
345768
346368
  };
345769
346369
  } else {
345770
346370
  return {
345771
- oldPos: path33.oldPos + oldPosInc,
346371
+ oldPos: path34.oldPos + oldPosInc,
345772
346372
  lastComponent: { count: 1, added, removed, previousComponent: last }
345773
346373
  };
345774
346374
  }
@@ -350485,6 +351085,265 @@ ${usage}`;
350485
351085
  return msg;
350486
351086
  }
350487
351087
 
351088
+ // ../../packages/backend/src/services/AgentHelper/tools/ops_tools.ts
351089
+ init_zod();
351090
+ function emit6(context2, toolName, input, output) {
351091
+ context2.sendEvent(context2.sessionId, {
351092
+ messageId: context2.messageId,
351093
+ type: "tool_call",
351094
+ toolName,
351095
+ input: typeof input === "string" ? input : JSON.stringify(input),
351096
+ output
351097
+ });
351098
+ }
351099
+ function noService(context2, tool2, args) {
351100
+ const msg = "Ops service is not wired in this runtime.";
351101
+ emit6(context2, tool2, args, msg);
351102
+ return msg;
351103
+ }
351104
+ var manageIncidentSchema = external_exports.object({
351105
+ action: external_exports.enum(["open", "get", "list", "close"]).describe("open a bundle, get one, list, or close it."),
351106
+ id: external_exports.string().optional().describe("Incident id (get/close)."),
351107
+ title: external_exports.string().optional().describe("Incident title (open)."),
351108
+ notes: external_exports.string().optional().describe("Free-form notes (open/close)."),
351109
+ chatId: external_exports.string().optional().describe("Session id to attach (open)."),
351110
+ terminals: external_exports.array(external_exports.string()).optional().describe("Terminal ids to attach (open)."),
351111
+ recordingId: external_exports.string().optional().describe("Recording id to attach (open)."),
351112
+ runId: external_exports.string().optional().describe("Agent run id to attach (open)."),
351113
+ status: external_exports.enum(["open", "closed"]).optional().describe("Filter for list.")
351114
+ });
351115
+ var manageCollabSchema = external_exports.object({
351116
+ action: external_exports.enum(["join", "takeConn", "whoHasConn", "list"]).describe("Session presence for two operators."),
351117
+ sessionId: external_exports.string().optional().describe("Session id (join/takeConn/whoHasConn)."),
351118
+ operator: external_exports.string().optional().describe("Operator name (join/takeConn).")
351119
+ });
351120
+ var manageJumpPathSchema = external_exports.object({
351121
+ action: external_exports.enum(["define", "list", "breakGlass", "allowed"]).describe("Named jump paths + time-boxed break-glass."),
351122
+ name: external_exports.string().optional().describe("Path name (define/breakGlass/allowed)."),
351123
+ hops: external_exports.array(external_exports.object({ host: external_exports.string(), user: external_exports.string().optional(), port: external_exports.number().optional() })).optional().describe('Ordered hops for define \u2014 e.g. [{host:"jump"}, {host:"target",user:"admin"}].'),
351124
+ ttlSeconds: external_exports.number().optional().describe("Break-glass TTL in seconds (breakGlass). Default 3600.")
351125
+ });
351126
+ var manageApprovalSchema = external_exports.object({
351127
+ action: external_exports.enum(["request", "list", "get", "decide", "sweep"]).describe("Time-boxed approvals; twoPerson needs two distinct approvers."),
351128
+ id: external_exports.string().optional().describe("Approval id (get/decide)."),
351129
+ command: external_exports.string().optional().describe("The command awaiting approval (request)."),
351130
+ ttlSeconds: external_exports.number().optional().describe("TTL in seconds (request). Default 900."),
351131
+ twoPerson: external_exports.boolean().optional().describe("Require two distinct approvers (request)."),
351132
+ who: external_exports.string().optional().describe("Approver name (decide)."),
351133
+ approve: external_exports.boolean().optional().describe("true = approve, false = deny (decide)."),
351134
+ state: external_exports.enum(["pending", "approved", "denied", "expired"]).optional().describe("Filter for list.")
351135
+ });
351136
+ var snapshotOutputSchema = external_exports.object({
351137
+ action: external_exports.enum(["remember", "list", "diff"]).describe("Baseline command output and diff against it later (config drift)."),
351138
+ connection: external_exports.string().describe("Connection/tab name, e.g. CORP-WS2 or cisco-xe-1."),
351139
+ command: external_exports.string().optional().describe("The command whose output is being baselined (remember/diff)."),
351140
+ output: external_exports.string().optional().describe("The output text (remember/diff).")
351141
+ });
351142
+ var replayAgentRunSchema = external_exports.object({
351143
+ runId: external_exports.string().describe("Run id from the run ledger to replay."),
351144
+ steps: external_exports.array(
351145
+ external_exports.object({
351146
+ tool: external_exports.string(),
351147
+ args: external_exports.unknown().optional(),
351148
+ output: external_exports.string().optional().describe("Stubbed output \u2014 the real tool is NOT called.")
351149
+ })
351150
+ ).describe("Steps with stubbed outputs so a replay never touches live hosts.")
351151
+ });
351152
+ var planOfflineJoinSchema = external_exports.object({
351153
+ domain: external_exports.string().describe("Target AD domain, e.g. corp.local."),
351154
+ machine: external_exports.string().describe("Machine name to join, e.g. EC2AMAZ-C69VULQ."),
351155
+ dcConnection: external_exports.string().describe("Saved connection name for the DC, e.g. CORP-DC1."),
351156
+ memberConnection: external_exports.string().describe("Saved connection name for the member, e.g. CORP-WS2.")
351157
+ });
351158
+ var netDeviceSchema = external_exports.object({
351159
+ action: external_exports.enum(["parseCdp", "configDiff", "inConfigMode"]).describe("Network-device helpers."),
351160
+ output: external_exports.string().optional().describe("Text to parse (parseCdp) or the prompt to test (inConfigMode)."),
351161
+ running: external_exports.string().optional().describe("running-config text (configDiff)."),
351162
+ startup: external_exports.string().optional().describe("startup-config text (configDiff).")
351163
+ });
351164
+ async function manageIncident(args, context2) {
351165
+ const svc = context2.opsService;
351166
+ if (!svc) return noService(context2, "manage_incident", args);
351167
+ let msg;
351168
+ if (args.action === "open") {
351169
+ if (!args.title) {
351170
+ msg = "open requires a title";
351171
+ } else {
351172
+ const inc = svc.openIncident(args.title, {
351173
+ sessionId: args.chatId,
351174
+ tabIds: args.terminals,
351175
+ recordingId: args.recordingId,
351176
+ runId: args.runId,
351177
+ notes: args.notes
351178
+ });
351179
+ msg = `Opened incident ${inc.id} "${inc.title}"${inc.tabIds.length ? ` with ${inc.tabIds.length} terminal(s)` : ""}.`;
351180
+ }
351181
+ } else if (args.action === "get") {
351182
+ const inc = args.id ? svc.getIncident(args.id) : void 0;
351183
+ msg = inc ? JSON.stringify(inc) : `No incident ${args.id ?? "(missing id)"}`;
351184
+ } else if (args.action === "close") {
351185
+ const inc = args.id ? svc.closeIncident(args.id, args.notes) : void 0;
351186
+ msg = inc ? `Closed incident ${inc.id}.` : `No incident ${args.id ?? "(missing id)"}`;
351187
+ } else {
351188
+ const list = svc.listIncidents(args.status);
351189
+ msg = list.length ? list.map((i) => `- ${i.id} [${i.status}] ${i.title}${i.tabIds.length ? ` tabs=${i.tabIds.join(",")}` : ""}`).join("\n") : "No incidents.";
351190
+ }
351191
+ emit6(context2, "manage_incident", args, msg);
351192
+ return msg;
351193
+ }
351194
+ async function manageCollab(args, context2) {
351195
+ const svc = context2.opsService;
351196
+ if (!svc) return noService(context2, "manage_collab", args);
351197
+ const sessionId = args.sessionId || context2.sessionId;
351198
+ let msg;
351199
+ if (args.action === "list") {
351200
+ const rooms2 = svc.listCollabSessions();
351201
+ msg = rooms2.length ? rooms2.map((r) => `- ${r.sessionId} holder=${r.holder ?? "none"} operators=${r.operators.join(",") || "none"}`).join("\n") : "No shared sessions yet.";
351202
+ } else if (args.action === "whoHasConn") {
351203
+ const p = svc.whoHasConn(sessionId);
351204
+ msg = `Session ${p.sessionId}: holder=${p.holder ?? "none"} operators=${p.operators.join(",") || "none"}`;
351205
+ } else {
351206
+ const operator = args.operator || "agent";
351207
+ const p = args.action === "join" ? svc.joinCollab(sessionId, operator) : svc.takeConn(sessionId, operator);
351208
+ msg = `${operator} ${args.action === "join" ? "joined" : "has the conn"} for ${p.sessionId}; operators=${p.operators.join(",")} holder=${p.holder ?? "none"}`;
351209
+ }
351210
+ emit6(context2, "manage_collab", args, msg);
351211
+ return msg;
351212
+ }
351213
+ async function manageJumpPath(args, context2) {
351214
+ const svc = context2.opsService;
351215
+ if (!svc) return noService(context2, "manage_jump_path", args);
351216
+ let msg;
351217
+ if (args.action === "list") {
351218
+ const paths = svc.listJumpPaths();
351219
+ msg = paths.length ? paths.map((p) => {
351220
+ const bg = p.breakGlassUntil ? new Date(p.breakGlassUntil).toISOString() : "none";
351221
+ return `- ${p.name} hops=${p.hops.map((h) => h.host).join("->")} breakGlassUntil=${bg}`;
351222
+ }).join("\n") : "No jump paths defined.";
351223
+ } else if (args.action === "allowed") {
351224
+ if (!args.name) msg = "allowed requires name";
351225
+ else {
351226
+ const r = svc.pathAllowed(args.name);
351227
+ msg = `${args.name}: allowed=${r.allowed}${r.expired ? " (break-glass expired)" : ""}${r.breakGlassUntil ? ` until ${new Date(r.breakGlassUntil).toISOString()}` : ""}`;
351228
+ }
351229
+ } else if (args.action === "breakGlass") {
351230
+ if (!args.name) msg = "breakGlass requires name";
351231
+ else {
351232
+ const p = svc.grantBreakGlass(args.name, (args.ttlSeconds ?? 3600) * 1e3);
351233
+ msg = p ? `Break-glass granted on ${p.name} until ${new Date(p.breakGlassUntil ?? 0).toISOString()}` : `No jump path "${args.name}"`;
351234
+ }
351235
+ } else {
351236
+ if (!args.name || !args.hops?.length) msg = "define requires name and hops";
351237
+ else {
351238
+ const p = svc.defineJumpPath(args.name, args.hops);
351239
+ msg = `Defined jump path ${p.name} with ${p.hops.length} hop(s): ${p.hops.map((h) => h.host).join(" -> ")}`;
351240
+ }
351241
+ }
351242
+ emit6(context2, "manage_jump_path", args, msg);
351243
+ return msg;
351244
+ }
351245
+ async function manageApproval(args, context2) {
351246
+ const svc = context2.opsService;
351247
+ if (!svc) return noService(context2, "manage_approval", args);
351248
+ let msg;
351249
+ if (args.action === "request") {
351250
+ if (!args.command) msg = "request requires command";
351251
+ else {
351252
+ const a = svc.requestApproval(args.command, (args.ttlSeconds ?? 900) * 1e3, args.twoPerson === true);
351253
+ msg = `Approval ${a.id} requested for: ${a.command}
351254
+ twoPerson=${a.twoPerson} expires=${new Date(a.expiresAt).toISOString()}
351255
+ ` + (a.twoPerson ? "Two DISTINCT approvers are required before this may run." : "One approver suffices.");
351256
+ }
351257
+ } else if (args.action === "get") {
351258
+ const a = args.id ? svc.getApproval(args.id) : void 0;
351259
+ msg = a ? JSON.stringify(a) : `No approval ${args.id ?? "(missing id)"}`;
351260
+ } else if (args.action === "sweep") {
351261
+ msg = `Expired ${svc.sweepExpiredApprovals()} approval(s).`;
351262
+ } else if (args.action === "decide") {
351263
+ if (!args.id || !args.who || typeof args.approve !== "boolean") msg = "decide requires id, who and approve";
351264
+ else {
351265
+ const r = svc.decideApproval(args.id, args.who, args.approve);
351266
+ msg = `approval ${r.approval.id}: state=${r.approval.state}${r.reason ? ` (${r.reason})` : ""}`;
351267
+ }
351268
+ } else {
351269
+ const list = svc.listApprovals(args.state);
351270
+ msg = list.length ? list.map((a) => `- ${a.id} [${a.state}]${a.twoPerson ? " (2-person)" : ""} ${a.command} expires=${new Date(a.expiresAt).toISOString()}`).join("\n") : "No approvals.";
351271
+ }
351272
+ emit6(context2, "manage_approval", args, msg);
351273
+ return msg;
351274
+ }
351275
+ async function snapshotOutput(args, context2) {
351276
+ const svc = context2.opsService;
351277
+ if (!svc) return noService(context2, "snapshot_output", args);
351278
+ let msg;
351279
+ if (args.action === "list") {
351280
+ const snaps = svc.listSnapshots(args.connection);
351281
+ msg = snaps.length ? snaps.map((s) => `- ${s.connection} :: ${s.command} (${s.output.length} chars @ ${new Date(s.at).toISOString()})`).join("\n") : `No snapshots for ${args.connection}.`;
351282
+ } else if (args.action === "remember") {
351283
+ if (!args.command || args.output === void 0) msg = "remember requires command and output";
351284
+ else {
351285
+ svc.rememberOutput(args.connection, args.command, args.output);
351286
+ msg = `Baseline stored for ${args.connection} :: ${args.command} (${args.output.length} chars).`;
351287
+ }
351288
+ } else {
351289
+ if (!args.command || args.output === void 0) msg = "diff requires command and output";
351290
+ else {
351291
+ const d = svc.diffOutput(args.connection, args.command, args.output);
351292
+ msg = d.previous === null ? `No baseline existed \u2014 stored this output (${args.output.length} chars) as the baseline for ${args.connection} :: ${args.command}.` : `changed=${d.changed} for ${args.connection} :: ${args.command}`;
351293
+ }
351294
+ }
351295
+ emit6(context2, "snapshot_output", args, msg);
351296
+ return msg;
351297
+ }
351298
+ async function replayAgentRun(args, context2) {
351299
+ const svc = context2.opsService;
351300
+ if (!svc) return noService(context2, "replay_agent_run", args);
351301
+ const r = svc.replay(
351302
+ args.runId,
351303
+ args.steps.map((s) => ({
351304
+ tool: s.tool,
351305
+ args: s.args && typeof s.args === "object" && !Array.isArray(s.args) ? s.args : {},
351306
+ stub: s.output ?? ""
351307
+ }))
351308
+ );
351309
+ const msg = `Replay ${args.runId}: ${r.steps.length} step(s) completed. Tools that would have been called: ${r.wouldHaveCalled.join(", ") || "(none)"}. No live tool was called.`;
351310
+ emit6(context2, "replay_agent_run", args, msg);
351311
+ return msg;
351312
+ }
351313
+ async function planOfflineJoin(args, context2) {
351314
+ const svc = context2.opsService;
351315
+ if (!svc) return noService(context2, "plan_offline_join", args);
351316
+ svc.planOfflineJoin(args);
351317
+ const lines = [
351318
+ `Offline join plan for ${args.machine} into ${args.domain}:`,
351319
+ `1. on ${args.dcConnection}: ${svc.djoinProvision(args.domain, args.machine)}`,
351320
+ `2. copy the blob to ${args.memberConnection} (no SMB required)`,
351321
+ `3. on ${args.memberConnection}: ${svc.djoinRequest()}`,
351322
+ `4. reboot ${args.memberConnection}, then verify with estate_facts / collect_facts`,
351323
+ `Use this INSTEAD of Add-Computer when NetUseAdd \\\\DC\\IPC$ fails with 64 (network name no longer available).`
351324
+ ];
351325
+ const msg = lines.join("\n");
351326
+ emit6(context2, "plan_offline_join", args, msg);
351327
+ return msg;
351328
+ }
351329
+ async function netDevice(args, context2) {
351330
+ const svc = context2.opsService;
351331
+ if (!svc) return noService(context2, "net_device", args);
351332
+ let msg;
351333
+ if (args.action === "parseCdp") {
351334
+ const neighbors = svc.parseCdp(args.output ?? "");
351335
+ msg = neighbors.length ? neighbors.map((n2) => `- ${n2.device} local=${n2.localIntf} remote=${n2.remoteIntf}`).join("\n") : "No CDP neighbors parsed (empty or unrecognised output).";
351336
+ } else if (args.action === "inConfigMode") {
351337
+ msg = svc.inConfigMode(args.output ?? "") ? "Device prompt looks like CONFIG mode." : "Not in config mode.";
351338
+ } else {
351339
+ const d = svc.configDiff(args.running ?? "", args.startup ?? "");
351340
+ msg = d.changed ? `running-config DIFFERS from startup-config:
351341
+ ${d.unified.slice(0, 4e3)}` : "running-config matches startup-config.";
351342
+ }
351343
+ emit6(context2, "net_device", args, msg);
351344
+ return msg;
351345
+ }
351346
+
350488
351347
  // ../../packages/backend/src/services/AgentHelper/tools/fleet_tools.ts
350489
351348
  init_zod();
350490
351349
 
@@ -351333,7 +352192,7 @@ function importPuttyReg(content, opts) {
351333
352192
  }
351334
352193
 
351335
352194
  // ../../packages/backend/src/services/AgentHelper/tools/automation_tools.ts
351336
- function emit6(context2, _toolName, input, output) {
352195
+ function emit7(context2, _toolName, input, output) {
351337
352196
  context2.sendEvent(context2.sessionId, {
351338
352197
  messageId: context2.messageId,
351339
352198
  type: "tool_call",
@@ -351360,7 +352219,7 @@ async function manageDeviceMemory(args, context2) {
351360
352219
  const m2 = context2.automationManager;
351361
352220
  if (!m2) {
351362
352221
  const msg2 = noStore();
351363
- emit6(context2, "manage_device_memory", args, msg2);
352222
+ emit7(context2, "manage_device_memory", args, msg2);
351364
352223
  return msg2;
351365
352224
  }
351366
352225
  const { action } = args;
@@ -351368,25 +352227,25 @@ async function manageDeviceMemory(args, context2) {
351368
352227
  const all = m2.listDeviceMemory();
351369
352228
  if (!all.length) {
351370
352229
  const msg3 = "No device memory entries.";
351371
- emit6(context2, "manage_device_memory", args, msg3);
352230
+ emit7(context2, "manage_device_memory", args, msg3);
351372
352231
  return msg3;
351373
352232
  }
351374
352233
  const body = all.map((e) => `${e.host} (role=${e.role || "unspecified"}, ${e.incidents.length} incident(s))`).join("\n");
351375
352234
  const msg2 = `Device memory (${all.length}):
351376
352235
  ${body}`;
351377
- emit6(context2, "manage_device_memory", args, msg2);
352236
+ emit7(context2, "manage_device_memory", args, msg2);
351378
352237
  return msg2;
351379
352238
  }
351380
352239
  if (!args.host) {
351381
352240
  const msg2 = `action="${action}" requires a host.`;
351382
- emit6(context2, "manage_device_memory", args, msg2);
352241
+ emit7(context2, "manage_device_memory", args, msg2);
351383
352242
  return msg2;
351384
352243
  }
351385
352244
  if (action === "get") {
351386
352245
  const mem = m2.getDeviceMemory(args.host);
351387
352246
  if (!mem) {
351388
352247
  const msg3 = `No device memory for host "${args.host}".`;
351389
- emit6(context2, "manage_device_memory", args, msg3);
352248
+ emit7(context2, "manage_device_memory", args, msg3);
351390
352249
  return msg3;
351391
352250
  }
351392
352251
  const msg2 = `Device memory for ${args.host}:
@@ -351394,18 +352253,18 @@ role: ${mem.role || "unspecified"}
351394
352253
  standing instructions: ${mem.standingInstructions || "(none)"}
351395
352254
  incidents (${mem.incidents.length}):
351396
352255
  ${mem.incidents.map((i) => `- [${i.at}] ${i.summary}${i.ticketId ? ` (ticket: ${i.ticketId})` : ""}${i.resolution ? ` \u2014 ${i.resolution}` : ""}`).join("\n")}`;
351397
- emit6(context2, "manage_device_memory", args, msg2);
352256
+ emit7(context2, "manage_device_memory", args, msg2);
351398
352257
  return msg2;
351399
352258
  }
351400
352259
  if (action === "add_incident") {
351401
352260
  if (!args.incident) {
351402
352261
  const msg3 = "add_incident requires an `incident` object.";
351403
- emit6(context2, "manage_device_memory", args, msg3);
352262
+ emit7(context2, "manage_device_memory", args, msg3);
351404
352263
  return msg3;
351405
352264
  }
351406
352265
  const inc = m2.addIncident(args.host, args.incident);
351407
352266
  const msg2 = `Recorded incident for ${args.host} at ${inc.at}: ${inc.summary}.`;
351408
- emit6(context2, "manage_device_memory", args, msg2);
352267
+ emit7(context2, "manage_device_memory", args, msg2);
351409
352268
  return msg2;
351410
352269
  }
351411
352270
  if (action === "upsert") {
@@ -351416,17 +352275,17 @@ ${mem.incidents.map((i) => `- [${i.at}] ${i.summary}${i.ticketId ? ` (ticket: ${
351416
352275
  incidents: []
351417
352276
  });
351418
352277
  const msg2 = `Saved device memory for ${mem.host} (role=${mem.role || "unspecified"}).`;
351419
- emit6(context2, "manage_device_memory", args, msg2);
352278
+ emit7(context2, "manage_device_memory", args, msg2);
351420
352279
  return msg2;
351421
352280
  }
351422
352281
  if (action === "delete") {
351423
352282
  const removed = m2.deleteDeviceMemory(args.host);
351424
352283
  const msg2 = removed ? `Deleted device memory for ${args.host}.` : `No device memory for ${args.host}.`;
351425
- emit6(context2, "manage_device_memory", args, msg2);
352284
+ emit7(context2, "manage_device_memory", args, msg2);
351426
352285
  return msg2;
351427
352286
  }
351428
352287
  const msg = `Unknown action "${action}".`;
351429
- emit6(context2, "manage_device_memory", args, msg);
352288
+ emit7(context2, "manage_device_memory", args, msg);
351430
352289
  return msg;
351431
352290
  }
351432
352291
  var manageScriptSchema = external_exports.object({
@@ -351442,7 +352301,7 @@ async function manageScript(args, context2) {
351442
352301
  const m2 = context2.automationManager;
351443
352302
  if (!m2) {
351444
352303
  const msg2 = noStore();
351445
- emit6(context2, "manage_script", args, msg2);
352304
+ emit7(context2, "manage_script", args, msg2);
351446
352305
  return msg2;
351447
352306
  }
351448
352307
  const { action } = args;
@@ -351450,56 +352309,56 @@ async function manageScript(args, context2) {
351450
352309
  const all = m2.listScripts();
351451
352310
  if (!all.length) {
351452
352311
  const msg3 = "No saved scripts.";
351453
- emit6(context2, "manage_script", args, msg3);
352312
+ emit7(context2, "manage_script", args, msg3);
351454
352313
  return msg3;
351455
352314
  }
351456
352315
  const body = all.map((s) => `- ${s.name} (id=${s.id}): ${s.command.split("\n")[0].slice(0, 60)}${s.command.length > 60 ? "\u2026" : ""}`).join("\n");
351457
352316
  const msg2 = `Saved scripts (${all.length}):
351458
352317
  ${body}`;
351459
- emit6(context2, "manage_script", args, msg2);
352318
+ emit7(context2, "manage_script", args, msg2);
351460
352319
  return msg2;
351461
352320
  }
351462
352321
  if (action === "create") {
351463
352322
  if (!args.name || !args.command) {
351464
352323
  const msg3 = "create requires name + command.";
351465
- emit6(context2, "manage_script", args, msg3);
352324
+ emit7(context2, "manage_script", args, msg3);
351466
352325
  return msg3;
351467
352326
  }
351468
352327
  const s = m2.createScript({ name: args.name, command: args.command, description: args.description, targets: args.targets, tags: args.tags });
351469
352328
  const msg2 = `Created script "${s.name}" (id=${s.id}). Run it on open tabs with run_fleet_command or exec_command using its command body.`;
351470
- emit6(context2, "manage_script", args, msg2);
352329
+ emit7(context2, "manage_script", args, msg2);
351471
352330
  return msg2;
351472
352331
  }
351473
352332
  if (action === "update") {
351474
352333
  if (!args.id) {
351475
352334
  const msg3 = "update requires id.";
351476
- emit6(context2, "manage_script", args, msg3);
352335
+ emit7(context2, "manage_script", args, msg3);
351477
352336
  return msg3;
351478
352337
  }
351479
352338
  const existing = m2.listScripts().find((s2) => s2.id === args.id);
351480
352339
  if (!existing) {
351481
352340
  const msg3 = `No script with id="${args.id}".`;
351482
- emit6(context2, "manage_script", args, msg3);
352341
+ emit7(context2, "manage_script", args, msg3);
351483
352342
  return msg3;
351484
352343
  }
351485
352344
  const s = m2.updateScript({ ...existing, name: args.name ?? existing.name, command: args.command ?? existing.command, description: args.description ?? existing.description, targets: args.targets ?? existing.targets, tags: args.tags ?? existing.tags });
351486
352345
  const msg2 = `Updated script "${s.name}".`;
351487
- emit6(context2, "manage_script", args, msg2);
352346
+ emit7(context2, "manage_script", args, msg2);
351488
352347
  return msg2;
351489
352348
  }
351490
352349
  if (action === "delete") {
351491
352350
  if (!args.id) {
351492
352351
  const msg3 = "delete requires id.";
351493
- emit6(context2, "manage_script", args, msg3);
352352
+ emit7(context2, "manage_script", args, msg3);
351494
352353
  return msg3;
351495
352354
  }
351496
352355
  const removed = m2.deleteScript(args.id);
351497
352356
  const msg2 = removed ? `Deleted script ${args.id}.` : `No script ${args.id}.`;
351498
- emit6(context2, "manage_script", args, msg2);
352357
+ emit7(context2, "manage_script", args, msg2);
351499
352358
  return msg2;
351500
352359
  }
351501
352360
  const msg = `Unknown action "${action}".`;
351502
- emit6(context2, "manage_script", args, msg);
352361
+ emit7(context2, "manage_script", args, msg);
351503
352362
  return msg;
351504
352363
  }
351505
352364
  var manageGroupSchema = external_exports.object({
@@ -351512,7 +352371,7 @@ async function manageGroup(args, context2) {
351512
352371
  const m2 = context2.automationManager;
351513
352372
  if (!m2) {
351514
352373
  const msg2 = noStore();
351515
- emit6(context2, "manage_group", args, msg2);
352374
+ emit7(context2, "manage_group", args, msg2);
351516
352375
  return msg2;
351517
352376
  }
351518
352377
  const { action } = args;
@@ -351520,49 +352379,49 @@ async function manageGroup(args, context2) {
351520
352379
  const all = m2.listGroups();
351521
352380
  if (!all.length) {
351522
352381
  const msg3 = "No groups.";
351523
- emit6(context2, "manage_group", args, msg3);
352382
+ emit7(context2, "manage_group", args, msg3);
351524
352383
  return msg3;
351525
352384
  }
351526
352385
  const msg2 = `Groups (${all.length}):
351527
352386
  ${all.map((g) => `- ${g.name} (id=${g.id}${g.parentId ? `, parent=${g.parentId}` : ""})`).join("\n")}`;
351528
- emit6(context2, "manage_group", args, msg2);
352387
+ emit7(context2, "manage_group", args, msg2);
351529
352388
  return msg2;
351530
352389
  }
351531
352390
  if (action === "create") {
351532
352391
  if (!args.name) {
351533
352392
  const msg3 = "create requires name.";
351534
- emit6(context2, "manage_group", args, msg3);
352393
+ emit7(context2, "manage_group", args, msg3);
351535
352394
  return msg3;
351536
352395
  }
351537
352396
  const g = m2.createGroup(args.name, args.parentId ?? null);
351538
352397
  const msg2 = `Created group "${g.name}" (id=${g.id}). Assign a connection by setting its groupId via manage_ssh_connection.update or the Connections panel.`;
351539
- emit6(context2, "manage_group", args, msg2);
352398
+ emit7(context2, "manage_group", args, msg2);
351540
352399
  return msg2;
351541
352400
  }
351542
352401
  if (action === "update") {
351543
352402
  if (!args.id) {
351544
352403
  const msg3 = "update requires id.";
351545
- emit6(context2, "manage_group", args, msg3);
352404
+ emit7(context2, "manage_group", args, msg3);
351546
352405
  return msg3;
351547
352406
  }
351548
352407
  const g = m2.updateGroup({ id: args.id, name: args.name ?? "", parentId: args.parentId });
351549
352408
  const msg2 = `Updated group "${g.name}".`;
351550
- emit6(context2, "manage_group", args, msg2);
352409
+ emit7(context2, "manage_group", args, msg2);
351551
352410
  return msg2;
351552
352411
  }
351553
352412
  if (action === "delete") {
351554
352413
  if (!args.id) {
351555
352414
  const msg3 = "delete requires id.";
351556
- emit6(context2, "manage_group", args, msg3);
352415
+ emit7(context2, "manage_group", args, msg3);
351557
352416
  return msg3;
351558
352417
  }
351559
352418
  const removed = m2.deleteGroup(args.id);
351560
352419
  const msg2 = removed ? `Deleted group ${args.id} (children reparented to root).` : `No group ${args.id}.`;
351561
- emit6(context2, "manage_group", args, msg2);
352420
+ emit7(context2, "manage_group", args, msg2);
351562
352421
  return msg2;
351563
352422
  }
351564
352423
  const msg = `Unknown action "${action}".`;
351565
- emit6(context2, "manage_group", args, msg);
352424
+ emit7(context2, "manage_group", args, msg);
351566
352425
  return msg;
351567
352426
  }
351568
352427
  var manageScheduledTaskSchema = external_exports.object({
@@ -351592,7 +352451,7 @@ async function manageScheduledTask(args, context2) {
351592
352451
  const m2 = context2.automationManager;
351593
352452
  if (!m2) {
351594
352453
  const msg2 = noStore();
351595
- emit6(context2, "manage_scheduled_task", args, msg2);
352454
+ emit7(context2, "manage_scheduled_task", args, msg2);
351596
352455
  return msg2;
351597
352456
  }
351598
352457
  const { action } = args;
@@ -351600,30 +352459,30 @@ async function manageScheduledTask(args, context2) {
351600
352459
  const all = m2.listScheduledTasks();
351601
352460
  if (!all.length) {
351602
352461
  const msg3 = "No scheduled tasks.";
351603
- emit6(context2, "manage_scheduled_task", args, msg3);
352462
+ emit7(context2, "manage_scheduled_task", args, msg3);
351604
352463
  return msg3;
351605
352464
  }
351606
352465
  const msg2 = `Scheduled tasks (${all.length}):
351607
352466
  ${all.map((t) => `- ${t.name} (id=${t.id}, cron="${t.cron}", enabled=${t.enabled}${t.lastRunAt ? `, lastRun=${t.lastRunAt}` : ""})`).join("\n")}`;
351608
- emit6(context2, "manage_scheduled_task", args, msg2);
352467
+ emit7(context2, "manage_scheduled_task", args, msg2);
351609
352468
  return msg2;
351610
352469
  }
351611
352470
  if (action === "create") {
351612
352471
  if (!args.name || !args.cron) {
351613
352472
  const msg3 = "create requires name + cron.";
351614
- emit6(context2, "manage_scheduled_task", args, msg3);
352473
+ emit7(context2, "manage_scheduled_task", args, msg3);
351615
352474
  return msg3;
351616
352475
  }
351617
352476
  if (!args.scriptId && !args.command && !args.playbookId) {
351618
352477
  const msg3 = "create requires scriptId, command, or playbookId.";
351619
- emit6(context2, "manage_scheduled_task", args, msg3);
352478
+ emit7(context2, "manage_scheduled_task", args, msg3);
351620
352479
  return msg3;
351621
352480
  }
351622
352481
  const { validateCron: validateCron2 } = await Promise.resolve().then(() => (init_schedulerService(), schedulerService_exports));
351623
352482
  const v = validateCron2(args.cron);
351624
352483
  if (!v.ok) {
351625
352484
  const msg3 = `Invalid cron "${args.cron}": ${v.reason}`;
351626
- emit6(context2, "manage_scheduled_task", args, msg3);
352485
+ emit7(context2, "manage_scheduled_task", args, msg3);
351627
352486
  return msg3;
351628
352487
  }
351629
352488
  const t = m2.createScheduledTask({
@@ -351647,47 +352506,47 @@ ${all.map((t) => `- ${t.name} (id=${t.id}, cron="${t.cron}", enabled=${t.enabled
351647
352506
  alertAfterFailures: args.alertAfterFailures
351648
352507
  });
351649
352508
  const msg2 = `Created scheduled task "${t.name}" (id=${t.id}, cron="${t.cron}"${args.timezone ? ` @ ${args.timezone}` : ""}). It will be evaluated by the local scheduler.`;
351650
- emit6(context2, "manage_scheduled_task", args, msg2);
352509
+ emit7(context2, "manage_scheduled_task", args, msg2);
351651
352510
  return msg2;
351652
352511
  }
351653
352512
  if (action === "update") {
351654
352513
  if (!args.id) {
351655
352514
  const msg3 = "update requires id.";
351656
- emit6(context2, "manage_scheduled_task", args, msg3);
352515
+ emit7(context2, "manage_scheduled_task", args, msg3);
351657
352516
  return msg3;
351658
352517
  }
351659
352518
  const existing = m2.listScheduledTasks().find((t2) => t2.id === args.id);
351660
352519
  if (!existing) {
351661
352520
  const msg3 = `No task ${args.id}.`;
351662
- emit6(context2, "manage_scheduled_task", args, msg3);
352521
+ emit7(context2, "manage_scheduled_task", args, msg3);
351663
352522
  return msg3;
351664
352523
  }
351665
352524
  const t = m2.updateScheduledTask({ ...existing, name: args.name ?? existing.name, cron: args.cron ?? existing.cron, scriptId: args.scriptId ?? existing.scriptId, command: args.command ?? existing.command, enabled: args.enabled ?? existing.enabled, groupId: args.groupId, tags: args.tags, targets: args.targets });
351666
352525
  const msg2 = `Updated task "${t.name}".`;
351667
- emit6(context2, "manage_scheduled_task", args, msg2);
352526
+ emit7(context2, "manage_scheduled_task", args, msg2);
351668
352527
  return msg2;
351669
352528
  }
351670
352529
  if (action === "delete") {
351671
352530
  if (!args.id) {
351672
352531
  const msg3 = "delete requires id.";
351673
- emit6(context2, "manage_scheduled_task", args, msg3);
352532
+ emit7(context2, "manage_scheduled_task", args, msg3);
351674
352533
  return msg3;
351675
352534
  }
351676
352535
  const removed = m2.deleteScheduledTask(args.id);
351677
352536
  const msg2 = removed ? `Deleted task ${args.id}.` : `No task ${args.id}.`;
351678
- emit6(context2, "manage_scheduled_task", args, msg2);
352537
+ emit7(context2, "manage_scheduled_task", args, msg2);
351679
352538
  return msg2;
351680
352539
  }
351681
352540
  if (action === "validate") {
351682
352541
  if (!args.cron) {
351683
352542
  const msg3 = "validate requires cron.";
351684
- emit6(context2, "manage_scheduled_task", args, msg3);
352543
+ emit7(context2, "manage_scheduled_task", args, msg3);
351685
352544
  return msg3;
351686
352545
  }
351687
352546
  const { validateCron: validateCron2 } = await Promise.resolve().then(() => (init_schedulerService(), schedulerService_exports));
351688
352547
  const v = validateCron2(args.cron);
351689
352548
  const msg2 = v.ok ? `Cron "${args.cron}" is valid.` : `Invalid cron "${args.cron}": ${v.reason}`;
351690
- emit6(context2, "manage_scheduled_task", args, msg2);
352549
+ emit7(context2, "manage_scheduled_task", args, msg2);
351691
352550
  return msg2;
351692
352551
  }
351693
352552
  if (action === "drift") {
@@ -351696,20 +352555,20 @@ ${all.map((t) => `- ${t.name} (id=${t.id}, cron="${t.cron}", enabled=${t.enabled
351696
352555
  const flagged = drift.filter((d) => d.drifted);
351697
352556
  const msg2 = flagged.length === 0 ? `No drift detected across ${drift.length} enabled task(s).` : `Drifted task(s) (${flagged.length}):
351698
352557
  ${flagged.map((d) => `- ${d.taskName} (id=${d.taskId}): ${Number.isFinite(d.minutesSinceLastRun) ? `${Math.round(d.minutesSinceLastRun)} min since last run` : "never ran"} vs expected \u2264${d.expectedIntervalMinutes} min`).join("\n")}`;
351699
- emit6(context2, "manage_scheduled_task", args, msg2);
352558
+ emit7(context2, "manage_scheduled_task", args, msg2);
351700
352559
  return msg2;
351701
352560
  }
351702
352561
  if (action === "history") {
351703
352562
  const sched = context2.scheduledTaskHistory;
351704
352563
  if (!sched) {
351705
352564
  const msg3 = "Run history is not available in this runtime (headless daemon exposes it via the gateway).";
351706
- emit6(context2, "manage_scheduled_task", args, msg3);
352565
+ emit7(context2, "manage_scheduled_task", args, msg3);
351707
352566
  return msg3;
351708
352567
  }
351709
352568
  const tasks = args.id ? m2.listScheduledTasks().filter((t) => t.id === args.id) : m2.listScheduledTasks();
351710
352569
  if (tasks.length === 0) {
351711
352570
  const msg3 = args.id ? `No task ${args.id}.` : "No scheduled tasks.";
351712
- emit6(context2, "manage_scheduled_task", args, msg3);
352571
+ emit7(context2, "manage_scheduled_task", args, msg3);
351713
352572
  return msg3;
351714
352573
  }
351715
352574
  const lines = tasks.map((t) => {
@@ -351722,34 +352581,34 @@ ${flagged.map((d) => `- ${d.taskName} (id=${d.taskId}): ${Number.isFinite(d.minu
351722
352581
  });
351723
352582
  const msg2 = `Scheduled task history:
351724
352583
  ${lines.join("\n")}`;
351725
- emit6(context2, "manage_scheduled_task", args, msg2);
352584
+ emit7(context2, "manage_scheduled_task", args, msg2);
351726
352585
  return msg2;
351727
352586
  }
351728
352587
  if (action === "runNow") {
351729
352588
  if (!args.id) {
351730
352589
  const msg3 = "runNow requires id.";
351731
- emit6(context2, "manage_scheduled_task", args, msg3);
352590
+ emit7(context2, "manage_scheduled_task", args, msg3);
351732
352591
  return msg3;
351733
352592
  }
351734
352593
  const task2 = m2.listScheduledTasks().find((t) => t.id === args.id);
351735
352594
  if (!task2) {
351736
352595
  const msg3 = `No task ${args.id}.`;
351737
- emit6(context2, "manage_scheduled_task", args, msg3);
352596
+ emit7(context2, "manage_scheduled_task", args, msg3);
351738
352597
  return msg3;
351739
352598
  }
351740
352599
  const sched = context2.scheduledTaskRunner;
351741
352600
  if (!sched) {
351742
352601
  const msg3 = "Run-now is not available in this runtime.";
351743
- emit6(context2, "manage_scheduled_task", args, msg3);
352602
+ emit7(context2, "manage_scheduled_task", args, msg3);
351744
352603
  return msg3;
351745
352604
  }
351746
352605
  const r = await sched(task2);
351747
352606
  const msg2 = r.ran ? `Task "${task2.name}" executed now.` : `Task "${task2.name}" not run: ${r.reason}.`;
351748
- emit6(context2, "manage_scheduled_task", args, msg2);
352607
+ emit7(context2, "manage_scheduled_task", args, msg2);
351749
352608
  return msg2;
351750
352609
  }
351751
352610
  const msg = `Unknown action "${action}".`;
351752
- emit6(context2, "manage_scheduled_task", args, msg);
352611
+ emit7(context2, "manage_scheduled_task", args, msg);
351753
352612
  return msg;
351754
352613
  }
351755
352614
  var manageTemplateSchema = external_exports.object({
@@ -351765,7 +352624,7 @@ async function manageTemplate(args, context2) {
351765
352624
  const m2 = context2.automationManager;
351766
352625
  if (!m2) {
351767
352626
  const msg2 = noStore();
351768
- emit6(context2, "manage_template", args, msg2);
352627
+ emit7(context2, "manage_template", args, msg2);
351769
352628
  return msg2;
351770
352629
  }
351771
352630
  const { action } = args;
@@ -351773,57 +352632,57 @@ async function manageTemplate(args, context2) {
351773
352632
  const all = m2.listTemplates();
351774
352633
  if (!all.length) {
351775
352634
  const msg3 = "No templates.";
351776
- emit6(context2, "manage_template", args, msg3);
352635
+ emit7(context2, "manage_template", args, msg3);
351777
352636
  return msg3;
351778
352637
  }
351779
352638
  const msg2 = `Templates (${all.length}):
351780
352639
  ${all.map((t) => `- ${t.name} (id=${t.id}, ${t.versions.length} version(s))`).join("\n")}`;
351781
- emit6(context2, "manage_template", args, msg2);
352640
+ emit7(context2, "manage_template", args, msg2);
351782
352641
  return msg2;
351783
352642
  }
351784
352643
  if (action === "create") {
351785
352644
  if (!args.name || !args.body) {
351786
352645
  const msg3 = "create requires name + body.";
351787
- emit6(context2, "manage_template", args, msg3);
352646
+ emit7(context2, "manage_template", args, msg3);
351788
352647
  return msg3;
351789
352648
  }
351790
352649
  const t = m2.createTemplate({ name: args.name, body: args.body, variables: args.variables ?? [] });
351791
352650
  const msg2 = `Created template "${t.name}" (id=${t.id}). Use action="render" to preview, action="version" to save a rendered version.`;
351792
- emit6(context2, "manage_template", args, msg2);
352651
+ emit7(context2, "manage_template", args, msg2);
351793
352652
  return msg2;
351794
352653
  }
351795
352654
  if (action === "update") {
351796
352655
  if (!args.id) {
351797
352656
  const msg3 = "update requires id.";
351798
- emit6(context2, "manage_template", args, msg3);
352657
+ emit7(context2, "manage_template", args, msg3);
351799
352658
  return msg3;
351800
352659
  }
351801
352660
  const t = m2.updateTemplate({ id: args.id, name: args.name, body: args.body, variables: args.variables });
351802
352661
  const msg2 = `Updated template "${t.name}".`;
351803
- emit6(context2, "manage_template", args, msg2);
352662
+ emit7(context2, "manage_template", args, msg2);
351804
352663
  return msg2;
351805
352664
  }
351806
352665
  if (action === "delete") {
351807
352666
  if (!args.id) {
351808
352667
  const msg3 = "delete requires id.";
351809
- emit6(context2, "manage_template", args, msg3);
352668
+ emit7(context2, "manage_template", args, msg3);
351810
352669
  return msg3;
351811
352670
  }
351812
352671
  const removed = m2.deleteTemplate(args.id);
351813
352672
  const msg2 = removed ? `Deleted template ${args.id}.` : `No template ${args.id}.`;
351814
- emit6(context2, "manage_template", args, msg2);
352673
+ emit7(context2, "manage_template", args, msg2);
351815
352674
  return msg2;
351816
352675
  }
351817
352676
  if (action === "render") {
351818
352677
  if (!args.id) {
351819
352678
  const msg3 = "render requires id.";
351820
- emit6(context2, "manage_template", args, msg3);
352679
+ emit7(context2, "manage_template", args, msg3);
351821
352680
  return msg3;
351822
352681
  }
351823
352682
  const t = m2.listTemplates().find((x) => x.id === args.id);
351824
352683
  if (!t) {
351825
352684
  const msg3 = `No template ${args.id}.`;
351826
- emit6(context2, "manage_template", args, msg3);
352685
+ emit7(context2, "manage_template", args, msg3);
351827
352686
  return msg3;
351828
352687
  }
351829
352688
  const defaults2 = {};
@@ -351834,19 +352693,19 @@ ${all.map((t) => `- ${t.name} (id=${t.id}, ${t.versions.length} version(s))`).jo
351834
352693
  <rendered>
351835
352694
  ${rendered}
351836
352695
  </rendered>`;
351837
- emit6(context2, "manage_template", args, msg2);
352696
+ emit7(context2, "manage_template", args, msg2);
351838
352697
  return msg2;
351839
352698
  }
351840
352699
  if (action === "version") {
351841
352700
  if (!args.id) {
351842
352701
  const msg3 = "version requires id.";
351843
- emit6(context2, "manage_template", args, msg3);
352702
+ emit7(context2, "manage_template", args, msg3);
351844
352703
  return msg3;
351845
352704
  }
351846
352705
  const t = m2.listTemplates().find((x) => x.id === args.id);
351847
352706
  if (!t) {
351848
352707
  const msg3 = `No template ${args.id}.`;
351849
- emit6(context2, "manage_template", args, msg3);
352708
+ emit7(context2, "manage_template", args, msg3);
351850
352709
  return msg3;
351851
352710
  }
351852
352711
  const defaults2 = {};
@@ -351860,11 +352719,11 @@ ${rendered}
351860
352719
  Diff vs previous version:
351861
352720
  ${diffStrings(prev.rendered, rendered)}` : "\n\n(first version)";
351862
352721
  const msg2 = `Saved version ${t.versions.length + 1} of "${t.name}" at ${v.at}.${diff}`;
351863
- emit6(context2, "manage_template", args, msg2);
352722
+ emit7(context2, "manage_template", args, msg2);
351864
352723
  return msg2;
351865
352724
  }
351866
352725
  const msg = `Unknown action "${action}".`;
351867
- emit6(context2, "manage_template", args, msg);
352726
+ emit7(context2, "manage_template", args, msg);
351868
352727
  return msg;
351869
352728
  }
351870
352729
  var importPuttySchema = external_exports.object({
@@ -351874,13 +352733,13 @@ async function importPutty(args, context2) {
351874
352733
  const cm = context2.connectionManager;
351875
352734
  if (!cm) {
351876
352735
  const msg2 = "Connection management is not available in this runtime.";
351877
- emit6(context2, "import_putty", args, msg2);
352736
+ emit7(context2, "import_putty", args, msg2);
351878
352737
  return msg2;
351879
352738
  }
351880
352739
  const entries = importPuttyReg(args.regContent);
351881
352740
  if (!entries.length) {
351882
352741
  const msg2 = "No SSH sessions found in the provided PuTTY export (only ssh-protocol sessions with a HostName are imported).";
351883
- emit6(context2, "import_putty", args, msg2);
352742
+ emit7(context2, "import_putty", args, msg2);
351884
352743
  return msg2;
351885
352744
  }
351886
352745
  let created = 0;
@@ -351891,7 +352750,7 @@ async function importPutty(args, context2) {
351891
352750
  created++;
351892
352751
  }
351893
352752
  const msg = `Imported ${created} SSH connection(s) from PuTTY${entries.length !== created ? ` (${entries.length - created} skipped as duplicates or non-ssh)` : ""}. Imported: ${entries.map((e) => e.name).join(", ")}. Open them with open_terminal_tab by Name.`;
351894
- emit6(context2, "import_putty", args, msg);
352753
+ emit7(context2, "import_putty", args, msg);
351895
352754
  return msg;
351896
352755
  }
351897
352756
 
@@ -351902,7 +352761,7 @@ init_playbook_tools();
351902
352761
  init_zod();
351903
352762
  init_playbookRunner();
351904
352763
  init_scheduledTaskRunner();
351905
- function emit8(context2, toolName, input, output) {
352764
+ function emit9(context2, toolName, input, output) {
351906
352765
  context2.sendEvent(context2.sessionId, {
351907
352766
  messageId: context2.messageId,
351908
352767
  type: "tool_call",
@@ -351942,12 +352801,12 @@ async function manageChange(args, context2) {
351942
352801
  const ledger = context2.changeLedger;
351943
352802
  if (!m2) {
351944
352803
  const msg2 = "Automation store is not available in this runtime.";
351945
- emit8(context2, "manage_change", args, msg2);
352804
+ emit9(context2, "manage_change", args, msg2);
351946
352805
  return msg2;
351947
352806
  }
351948
352807
  if (!ledger) {
351949
352808
  const msg2 = "Change ledger is not available in this runtime.";
351950
- emit8(context2, "manage_change", args, msg2);
352809
+ emit9(context2, "manage_change", args, msg2);
351951
352810
  return msg2;
351952
352811
  }
351953
352812
  const { action } = args;
@@ -351955,13 +352814,13 @@ async function manageChange(args, context2) {
351955
352814
  const key = args.playbookId ?? args.name;
351956
352815
  if (!key) {
351957
352816
  const msg3 = "plan requires playbookId or name.";
351958
- emit8(context2, "manage_change", args, msg3);
352817
+ emit9(context2, "manage_change", args, msg3);
351959
352818
  return msg3;
351960
352819
  }
351961
352820
  const playbook = m2.getPlaybook(key);
351962
352821
  if (!playbook) {
351963
352822
  const msg3 = `No playbook "${key}".`;
351964
- emit8(context2, "manage_change", args, msg3);
352823
+ emit9(context2, "manage_change", args, msg3);
351965
352824
  return msg3;
351966
352825
  }
351967
352826
  const settings = settingsFromContext(context2);
@@ -351981,58 +352840,58 @@ Targets (${targets.length || 1}): ${targets.length ? targets.map((t) => t.name).
351981
352840
  Steps:
351982
352841
  ${steps}
351983
352842
  Next: manage_change action=approve changeId=${changeId}, then action=run.`;
351984
- emit8(context2, "manage_change", args, msg2);
352843
+ emit9(context2, "manage_change", args, msg2);
351985
352844
  return msg2;
351986
352845
  }
351987
352846
  if (action === "approve") {
351988
352847
  if (!args.changeId) {
351989
352848
  const msg3 = "approve requires changeId.";
351990
- emit8(context2, "manage_change", args, msg3);
352849
+ emit9(context2, "manage_change", args, msg3);
351991
352850
  return msg3;
351992
352851
  }
351993
352852
  const existing = ledger.getChange(args.changeId);
351994
352853
  if (!existing) {
351995
352854
  const msg3 = `No change "${args.changeId}".`;
351996
- emit8(context2, "manage_change", args, msg3);
352855
+ emit9(context2, "manage_change", args, msg3);
351997
352856
  return msg3;
351998
352857
  }
351999
352858
  if (existing.change.status !== "planned") {
352000
352859
  const msg3 = `Change ${args.changeId} is ${existing.change.status} \u2014 only planned changes can be approved.`;
352001
- emit8(context2, "manage_change", args, msg3);
352860
+ emit9(context2, "manage_change", args, msg3);
352002
352861
  return msg3;
352003
352862
  }
352004
352863
  ledger.approveChange(args.changeId, args.approvedBy);
352005
352864
  const msg2 = `Change ${args.changeId} approved${args.approvedBy ? ` by ${args.approvedBy}` : ""}. Execute with manage_change action=run changeId=${args.changeId}.`;
352006
- emit8(context2, "manage_change", args, msg2);
352865
+ emit9(context2, "manage_change", args, msg2);
352007
352866
  return msg2;
352008
352867
  }
352009
352868
  if (action === "run") {
352010
352869
  if (!args.changeId) {
352011
352870
  const msg3 = "run requires changeId.";
352012
- emit8(context2, "manage_change", args, msg3);
352871
+ emit9(context2, "manage_change", args, msg3);
352013
352872
  return msg3;
352014
352873
  }
352015
352874
  const existing = ledger.getChange(args.changeId);
352016
352875
  if (!existing) {
352017
352876
  const msg3 = `No change "${args.changeId}". Plan one first with manage_change action=plan.`;
352018
- emit8(context2, "manage_change", args, msg3);
352877
+ emit9(context2, "manage_change", args, msg3);
352019
352878
  return msg3;
352020
352879
  }
352021
352880
  if (existing.change.status !== "approved") {
352022
352881
  const msg3 = `Change ${args.changeId} is ${existing.change.status} \u2014 it must be approved before execution (manage_change action=approve).`;
352023
- emit8(context2, "manage_change", args, msg3);
352882
+ emit9(context2, "manage_change", args, msg3);
352024
352883
  return msg3;
352025
352884
  }
352026
352885
  const playbook = m2.getPlaybook(existing.change.playbookId);
352027
352886
  if (!playbook) {
352028
352887
  ledger.finishChange(args.changeId, "failed", "playbook no longer exists");
352029
352888
  const msg3 = `Playbook ${existing.change.playbookId} no longer exists; change marked failed.`;
352030
- emit8(context2, "manage_change", args, msg3);
352889
+ emit9(context2, "manage_change", args, msg3);
352031
352890
  return msg3;
352032
352891
  }
352033
352892
  if (!ledger.markExecuting(args.changeId)) {
352034
352893
  const msg3 = `Change ${args.changeId} could not transition to executing (status=${existing.change.status}).`;
352035
- emit8(context2, "manage_change", args, msg3);
352894
+ emit9(context2, "manage_change", args, msg3);
352036
352895
  return msg3;
352037
352896
  }
352038
352897
  const settings = settingsFromContext(context2);
@@ -352054,7 +352913,7 @@ Next: manage_change action=approve changeId=${changeId}, then action=run.`;
352054
352913
  const errMsg = error40 instanceof Error ? error40.message : String(error40);
352055
352914
  ledger.finishChange(args.changeId, "failed", errMsg);
352056
352915
  const msg3 = `Change ${args.changeId} failed to execute: ${errMsg}`;
352057
- emit8(context2, "manage_change", args, msg3);
352916
+ emit9(context2, "manage_change", args, msg3);
352058
352917
  return msg3;
352059
352918
  }
352060
352919
  const finalStatus = deriveFinalStatus(record2);
@@ -352072,19 +352931,19 @@ Next: manage_change action=approve changeId=${changeId}, then action=run.`;
352072
352931
  }
352073
352932
  const msg2 = `Change ${args.changeId} finished with status=${finalStatus} (runId=${record2.runId}).
352074
352933
  ${lines.join("\n")}`;
352075
- emit8(context2, "manage_change", args, msg2);
352934
+ emit9(context2, "manage_change", args, msg2);
352076
352935
  return msg2;
352077
352936
  }
352078
352937
  if (action === "status") {
352079
352938
  if (!args.changeId) {
352080
352939
  const msg3 = "status requires changeId.";
352081
- emit8(context2, "manage_change", args, msg3);
352940
+ emit9(context2, "manage_change", args, msg3);
352082
352941
  return msg3;
352083
352942
  }
352084
352943
  const got = ledger.getChange(args.changeId);
352085
352944
  if (!got) {
352086
352945
  const msg3 = `No change "${args.changeId}".`;
352087
- emit8(context2, "manage_change", args, msg3);
352946
+ emit9(context2, "manage_change", args, msg3);
352088
352947
  return msg3;
352089
352948
  }
352090
352949
  const { change, steps } = got;
@@ -352103,14 +352962,14 @@ ${meta}
352103
352962
  Targets: ${change.targetsSnapshot ?? "n/a"}
352104
352963
  Events:
352105
352964
  ${body}`;
352106
- emit8(context2, "manage_change", args, msg2);
352965
+ emit9(context2, "manage_change", args, msg2);
352107
352966
  return msg2;
352108
352967
  }
352109
352968
  if (action === "list") {
352110
352969
  const rows = ledger.listChanges({ status: args.status, limit: args.limit ?? 20 });
352111
352970
  if (!rows.length) {
352112
352971
  const msg3 = "No changes recorded yet. Plan one with manage_change action=plan.";
352113
- emit8(context2, "manage_change", args, msg3);
352972
+ emit9(context2, "manage_change", args, msg3);
352114
352973
  return msg3;
352115
352974
  }
352116
352975
  const body = rows.map(
@@ -352118,18 +352977,18 @@ ${body}`;
352118
352977
  ).join("\n");
352119
352978
  const msg2 = `Changes (${rows.length}):
352120
352979
  ${body}`;
352121
- emit8(context2, "manage_change", args, msg2);
352980
+ emit9(context2, "manage_change", args, msg2);
352122
352981
  return msg2;
352123
352982
  }
352124
352983
  const msg = `Unknown action "${action}".`;
352125
- emit8(context2, "manage_change", args, msg);
352984
+ emit9(context2, "manage_change", args, msg);
352126
352985
  return msg;
352127
352986
  }
352128
352987
 
352129
352988
  // ../../packages/backend/src/services/AgentHelper/tools/trigger_tools.ts
352130
352989
  init_zod();
352131
352990
  var import_crypto6 = require("crypto");
352132
- function emit9(context2, name, input, output) {
352991
+ function emit10(context2, name, input, output) {
352133
352992
  context2.sendEvent(context2.sessionId, {
352134
352993
  messageId: context2.messageId,
352135
352994
  type: "tool_call",
@@ -352158,7 +353017,7 @@ async function manageTrigger(args, context2) {
352158
353017
  const m2 = context2.automationManager;
352159
353018
  if (!m2 || typeof m2.listTriggers !== "function") {
352160
353019
  const msg2 = "Automation store with trigger support is not available in this runtime.";
352161
- emit9(context2, "manage_trigger", args, msg2);
353020
+ emit10(context2, "manage_trigger", args, msg2);
352162
353021
  return msg2;
352163
353022
  }
352164
353023
  const engine = context2.triggerEngine;
@@ -352167,7 +353026,7 @@ async function manageTrigger(args, context2) {
352167
353026
  const all = m2.listTriggers();
352168
353027
  if (!all.length) {
352169
353028
  const msg3 = "No triggers configured.";
352170
- emit9(context2, "manage_trigger", args, msg3);
353029
+ emit10(context2, "manage_trigger", args, msg3);
352171
353030
  return msg3;
352172
353031
  }
352173
353032
  const body = all.map((t) => {
@@ -352176,14 +353035,14 @@ async function manageTrigger(args, context2) {
352176
353035
  }).join("\n");
352177
353036
  const msg2 = `Triggers (${all.length}):
352178
353037
  ${body}`;
352179
- emit9(context2, "manage_trigger", args, msg2);
353038
+ emit10(context2, "manage_trigger", args, msg2);
352180
353039
  return msg2;
352181
353040
  }
352182
353041
  if (action === "fires") {
352183
353042
  const fires = engine?.listFires?.() ?? [];
352184
353043
  if (!fires.length) {
352185
353044
  const msg3 = "No trigger firings recorded yet.";
352186
- emit9(context2, "manage_trigger", args, msg3);
353045
+ emit10(context2, "manage_trigger", args, msg3);
352187
353046
  return msg3;
352188
353047
  }
352189
353048
  const limit2 = args.limit ?? 20;
@@ -352192,23 +353051,23 @@ ${body}`;
352192
353051
  ).join("\n");
352193
353052
  const msg2 = `Recent trigger firings (${Math.min(limit2, fires.length)} of ${fires.length}):
352194
353053
  ${body}`;
352195
- emit9(context2, "manage_trigger", args, msg2);
353054
+ emit10(context2, "manage_trigger", args, msg2);
352196
353055
  return msg2;
352197
353056
  }
352198
353057
  if (action === "create") {
352199
353058
  if (!args.name) {
352200
353059
  const msg3 = "create requires a name.";
352201
- emit9(context2, "manage_trigger", args, msg3);
353060
+ emit10(context2, "manage_trigger", args, msg3);
352202
353061
  return msg3;
352203
353062
  }
352204
353063
  if (!args.kind) {
352205
353064
  const msg3 = "create requires a kind (pattern|threshold|webhook|schedule).";
352206
- emit9(context2, "manage_trigger", args, msg3);
353065
+ emit10(context2, "manage_trigger", args, msg3);
352207
353066
  return msg3;
352208
353067
  }
352209
353068
  if (!args.playbookId) {
352210
353069
  const msg3 = "create requires playbookId.";
352211
- emit9(context2, "manage_trigger", args, msg3);
353070
+ emit10(context2, "manage_trigger", args, msg3);
352212
353071
  return msg3;
352213
353072
  }
352214
353073
  const entry = {
@@ -352234,20 +353093,20 @@ ${body}`;
352234
353093
  } catch {
352235
353094
  }
352236
353095
  const msg2 = `Created trigger "${entry.name}" (${entry.id}) [${entry.kind}] \u2192 ${entry.action} ${entry.playbookId}.`;
352237
- emit9(context2, "manage_trigger", args, msg2);
353096
+ emit10(context2, "manage_trigger", args, msg2);
352238
353097
  return msg2;
352239
353098
  }
352240
353099
  if (action === "update") {
352241
353100
  const key = args.id ?? args.name;
352242
353101
  if (!key) {
352243
353102
  const msg3 = "update requires id or name.";
352244
- emit9(context2, "manage_trigger", args, msg3);
353103
+ emit10(context2, "manage_trigger", args, msg3);
352245
353104
  return msg3;
352246
353105
  }
352247
353106
  const existing = m2.listTriggers().find((t) => t.id === key || t.name.trim().toLowerCase() === key.trim().toLowerCase());
352248
353107
  if (!existing) {
352249
353108
  const msg3 = `No trigger "${key}".`;
352250
- emit9(context2, "manage_trigger", args, msg3);
353109
+ emit10(context2, "manage_trigger", args, msg3);
352251
353110
  return msg3;
352252
353111
  }
352253
353112
  const merged = {
@@ -352270,14 +353129,14 @@ ${body}`;
352270
353129
  } catch {
352271
353130
  }
352272
353131
  const msg2 = `Updated trigger "${merged.name}" (${merged.id}).`;
352273
- emit9(context2, "manage_trigger", args, msg2);
353132
+ emit10(context2, "manage_trigger", args, msg2);
352274
353133
  return msg2;
352275
353134
  }
352276
353135
  if (action === "delete") {
352277
353136
  const key = args.id ?? args.name;
352278
353137
  if (!key) {
352279
353138
  const msg3 = "delete requires id or name.";
352280
- emit9(context2, "manage_trigger", args, msg3);
353139
+ emit10(context2, "manage_trigger", args, msg3);
352281
353140
  return msg3;
352282
353141
  }
352283
353142
  const ok = m2.deleteTrigger(key);
@@ -352288,14 +353147,14 @@ ${body}`;
352288
353147
  }
352289
353148
  }
352290
353149
  const msg2 = ok ? `Deleted trigger "${key}".` : `No trigger "${key}".`;
352291
- emit9(context2, "manage_trigger", args, msg2);
353150
+ emit10(context2, "manage_trigger", args, msg2);
352292
353151
  return msg2;
352293
353152
  }
352294
353153
  if (action === "enable" || action === "disable") {
352295
353154
  const key = args.id ?? args.name;
352296
353155
  if (!key) {
352297
353156
  const msg3 = `${action} requires id or name.`;
352298
- emit9(context2, "manage_trigger", args, msg3);
353157
+ emit10(context2, "manage_trigger", args, msg3);
352299
353158
  return msg3;
352300
353159
  }
352301
353160
  const ok = m2.setTriggerEnabled(key, action === "enable");
@@ -352307,11 +353166,11 @@ ${body}`;
352307
353166
  }
352308
353167
  }
352309
353168
  const msg2 = ok ? `Trigger "${key}" ${action}d.` : `No trigger "${key}".`;
352310
- emit9(context2, "manage_trigger", args, msg2);
353169
+ emit10(context2, "manage_trigger", args, msg2);
352311
353170
  return msg2;
352312
353171
  }
352313
353172
  const msg = `Unknown action "${action}".`;
352314
- emit9(context2, "manage_trigger", args, msg);
353173
+ emit10(context2, "manage_trigger", args, msg);
352315
353174
  return msg;
352316
353175
  }
352317
353176
 
@@ -352669,10 +353528,10 @@ async function listGatewayMethods(args, context2) {
352669
353528
  const lines = methods.map((mm) => `- ${mm.name} [${mm.category}] ${mm.description}${mm.params ? " (params: " + Object.entries(mm.params).map(([k, v]) => `${k}${v.optional ? "?" : ""}:${v.type}`).join(", ") + ")" : ""}`);
352670
353529
  const out = `Gateway methods (${methods.length} of ${payload.count}, registry v${payload.version}):
352671
353530
  ${lines.join("\n")}`;
352672
- emit10(context2, "list_gateway_methods", args, out);
353531
+ emit11(context2, "list_gateway_methods", args, out);
352673
353532
  return out;
352674
353533
  }
352675
- function emit10(context2, toolName, input, output) {
353534
+ function emit11(context2, toolName, input, output) {
352676
353535
  context2.sendEvent(context2.sessionId, {
352677
353536
  messageId: context2.messageId,
352678
353537
  type: "tool_call",
@@ -352685,7 +353544,7 @@ function obs(context2, toolName, args) {
352685
353544
  const o = context2.observability;
352686
353545
  if (!o) {
352687
353546
  const msg = `${toolName} is not available in this runtime (observability not wired).`;
352688
- emit10(context2, toolName, args, msg);
353547
+ emit11(context2, toolName, args, msg);
352689
353548
  return { o: null, msg };
352690
353549
  }
352691
353550
  return { o, msg: null };
@@ -352697,7 +353556,7 @@ async function getMetrics(args, context2) {
352697
353556
  const { o, msg } = obs(context2, "get_metrics", args);
352698
353557
  if (!o) return msg;
352699
353558
  const out = args.format === "prometheus" ? o.metricsExport.renderPrometheus() || "# no host metrics recorded yet" : await o.dashboard.summary();
352700
- emit10(context2, "get_metrics", args, out);
353559
+ emit11(context2, "get_metrics", args, out);
352701
353560
  return out;
352702
353561
  }
352703
353562
  var manageSecretSchema = external_exports.object({
@@ -352712,7 +353571,7 @@ async function manageSecret(args, context2) {
352712
353571
  const v = o.secrets;
352713
353572
  if (!v.unlocked()) {
352714
353573
  const m2 = "Secrets vault is locked \u2014 start RTerm with RTERM_SECRETS_MASTER_KEY set.";
352715
- emit10(context2, "manage_secret", args, m2);
353574
+ emit11(context2, "manage_secret", args, m2);
352716
353575
  return m2;
352717
353576
  }
352718
353577
  let out;
@@ -352739,7 +353598,7 @@ async function manageSecret(args, context2) {
352739
353598
  out = v.has(args.key) ? `'${args.key}' exists.` : `'${args.key}' does not exist.`;
352740
353599
  }
352741
353600
  }
352742
- emit10(context2, "manage_secret", args, out);
353601
+ emit11(context2, "manage_secret", args, out);
352743
353602
  return out;
352744
353603
  }
352745
353604
  var manageOncallSchema = external_exports.object({
@@ -352791,7 +353650,7 @@ async function manageOncall(args, context2) {
352791
353650
  } catch (e) {
352792
353651
  out = `on-call error: ${e instanceof Error ? e.message : String(e)}`;
352793
353652
  }
352794
- emit10(context2, "manage_oncall", args, out);
353653
+ emit11(context2, "manage_oncall", args, out);
352795
353654
  return out;
352796
353655
  }
352797
353656
  var getCostSchema = external_exports.object({
@@ -352815,7 +353674,7 @@ async function getCost(args, context2) {
352815
353674
  const b = o.cost.listBudgets();
352816
353675
  out = b.length ? b.map((x) => `- ${x.id}: ${x.model ?? "*"}/${x.profileId ?? "*"} ${x.period} cap $${x.capUsd}`).join("\n") : "No budgets configured.";
352817
353676
  }
352818
- emit10(context2, "get_cost", args, out);
353677
+ emit11(context2, "get_cost", args, out);
352819
353678
  return out;
352820
353679
  }
352821
353680
  var manageRecordingSchema = external_exports.object({
@@ -352881,7 +353740,7 @@ async function manageRecording(args, context2) {
352881
353740
  } catch (e) {
352882
353741
  out = `recording error: ${e instanceof Error ? e.message : String(e)}`;
352883
353742
  }
352884
- emit10(context2, "manage_recording", args, out);
353743
+ emit11(context2, "manage_recording", args, out);
352885
353744
  return out;
352886
353745
  }
352887
353746
  var manageGitopsSchema = external_exports.object({
@@ -352913,7 +353772,7 @@ async function manageGitops(args, context2) {
352913
353772
  } catch (e) {
352914
353773
  out = `gitops error: ${e instanceof Error ? e.message : String(e)}`;
352915
353774
  }
352916
- emit10(context2, "manage_gitops", args, out);
353775
+ emit11(context2, "manage_gitops", args, out);
352917
353776
  return out;
352918
353777
  }
352919
353778
  var managePlaybookVersionSchema = external_exports.object({
@@ -352960,7 +353819,7 @@ async function managePlaybookVersion(args, context2) {
352960
353819
  } catch (e) {
352961
353820
  out = `playbook error: ${e instanceof Error ? e.message : String(e)}`;
352962
353821
  }
352963
- emit10(context2, "manage_playbook_version", args, out);
353822
+ emit11(context2, "manage_playbook_version", args, out);
352964
353823
  return out;
352965
353824
  }
352966
353825
  var getCloudInventorySchema = external_exports.object({
@@ -352987,7 +353846,7 @@ async function getCloudInventory(args, context2) {
352987
353846
  } catch (e) {
352988
353847
  out = `cloud error: ${e instanceof Error ? e.message : String(e)}`;
352989
353848
  }
352990
- emit10(context2, "get_cloud_inventory", args, out);
353849
+ emit11(context2, "get_cloud_inventory", args, out);
352991
353850
  return out;
352992
353851
  }
352993
353852
  var getMonitorStatusSchema = external_exports.object({
@@ -353002,7 +353861,7 @@ async function getMonitorStatus(args, context2) {
353002
353861
  } else {
353003
353862
  out = o.monitorStatus.summary();
353004
353863
  }
353005
- emit10(context2, "get_monitor_status", args, out);
353864
+ emit11(context2, "get_monitor_status", args, out);
353006
353865
  return out;
353007
353866
  }
353008
353867
  var getLiveDashboardSchema = external_exports.object({
@@ -353018,7 +353877,7 @@ async function getLiveDashboard(args, context2) {
353018
353877
  const s = await o.dashboard.summary();
353019
353878
  out = s;
353020
353879
  }
353021
- emit10(context2, "get_live_dashboard", args, out);
353880
+ emit11(context2, "get_live_dashboard", args, out);
353022
353881
  return out;
353023
353882
  }
353024
353883
  var ingestApmSpansSchema = external_exports.object({
@@ -353031,7 +353890,7 @@ async function ingestApmSpans(args, context2) {
353031
353890
  const { ingestOtlp: ingestOtlp2 } = await Promise.resolve().then(() => (init_spanLedger(), spanLedger_exports));
353032
353891
  const n2 = ingestOtlp2(o.spanLedger, args.payload, args.defaultService);
353033
353892
  const out = `Ingested ${n2} APM span(s) into the trace store.`;
353034
- emit10(context2, "ingest_apm_spans", args, out);
353893
+ emit11(context2, "ingest_apm_spans", args, out);
353035
353894
  return out;
353036
353895
  }
353037
353896
  var getApmSummarySchema = external_exports.object({});
@@ -353040,7 +353899,7 @@ async function getApmSummary(_args, context2) {
353040
353899
  if (!o) return msg;
353041
353900
  const stats = o.spanLedger.serviceStats();
353042
353901
  const out = stats.length ? `APM: ${o.spanLedger.size()} spans across ${stats.length} service(s). ` + stats.map((x) => `${x.service}(${x.spans}${x.errors ? ", " + x.errors + " err" : ""})`).join(", ") : "APM: no spans ingested yet.";
353043
- emit10(context2, "get_apm_summary", _args, out);
353902
+ emit11(context2, "get_apm_summary", _args, out);
353044
353903
  return out;
353045
353904
  }
353046
353905
  var ingestDemBeaconSchema = external_exports.object({
@@ -353051,7 +353910,7 @@ async function ingestDemBeacon(args, context2) {
353051
353910
  if (!o) return msg;
353052
353911
  const s = o.rumLedger.ingestBeacon(args.payload);
353053
353912
  const out = s ? `Ingested RUM beacon for ${s.page}${s.lcpMs ? ` (LCP ${s.lcpMs}ms)` : ""}.` : "Beacon ignored \u2014 needs a `page` field.";
353054
- emit10(context2, "ingest_dem_beacon", args, out);
353913
+ emit11(context2, "ingest_dem_beacon", args, out);
353055
353914
  return out;
353056
353915
  }
353057
353916
  var getDemSummarySchema = external_exports.object({});
@@ -353060,7 +353919,7 @@ async function getDemSummary(_args, context2) {
353060
353919
  if (!o) return msg;
353061
353920
  const pages = o.rumLedger.pageStats();
353062
353921
  const out = pages.length ? `DEM: ${o.rumLedger.size()} sessions across ${pages.length} page(s). ` + pages.map((p) => `${p.page}(${p.sessions}${p.errorRate ? `, ${(p.errorRate * 100).toFixed(0)}% err` : ""})`).join(", ") : "DEM: no RUM sessions ingested yet.";
353063
- emit10(context2, "get_dem_summary", _args, out);
353922
+ emit11(context2, "get_dem_summary", _args, out);
353064
353923
  return out;
353065
353924
  }
353066
353925
  var collectInfraSchema = external_exports.object({
@@ -353105,7 +353964,7 @@ async function collectInfra(args, context2) {
353105
353964
  } catch (e) {
353106
353965
  out = `infra collect failed (kubectl or cluster unavailable): ${e instanceof Error ? e.message : String(e)}`;
353107
353966
  }
353108
- emit10(context2, "collect_infra", args, out);
353967
+ emit11(context2, "collect_infra", args, out);
353109
353968
  return out;
353110
353969
  }
353111
353970
  var manageEtwSchema = external_exports.object({
@@ -353164,7 +354023,7 @@ ${buildStopCommands2(s).join("\n")}`;
353164
354023
  } catch (e) {
353165
354024
  out = `etw error: ${e instanceof Error ? e.message : String(e)}`;
353166
354025
  }
353167
- emit10(context2, "manage_etw", args, out);
354026
+ emit11(context2, "manage_etw", args, out);
353168
354027
  return out;
353169
354028
  }
353170
354029
 
@@ -353557,6 +354416,46 @@ function buildToolsForModel(readFileSupport) {
353557
354416
  name: "manage_etw",
353558
354417
  description: "Windows ETW diagnostics \u2014 start/stop a trace (logman), parse captured Get-WinEvent/Get-Counter output, list sessions. Use against a Windows host for network/file/registry/process/DNS diagnostics.",
353559
354418
  schema: manageEtwSchema
354419
+ },
354420
+ {
354421
+ name: "manage_incident",
354422
+ description: "Incident bundles \u2014 pack chat + terminals + recording + run id into one INC-* you can reopen (open/get/list/close).",
354423
+ schema: manageIncidentSchema
354424
+ },
354425
+ {
354426
+ name: "manage_collab",
354427
+ description: 'Two-operator session presence: join, takeConn ("I have the conn"), whoHasConn, list.',
354428
+ schema: manageCollabSchema
354429
+ },
354430
+ {
354431
+ name: "manage_jump_path",
354432
+ description: "Named multi-hop jump paths with time-boxed break-glass (define/list/breakGlass/allowed).",
354433
+ schema: manageJumpPathSchema
354434
+ },
354435
+ {
354436
+ name: "manage_approval",
354437
+ description: "Queued HITL approvals with TTL auto-deny and optional two-person approve (request/list/get/decide/sweep).",
354438
+ schema: manageApprovalSchema
354439
+ },
354440
+ {
354441
+ name: "snapshot_output",
354442
+ description: "Remember command output per connection and diff against the last snapshot.",
354443
+ schema: snapshotOutputSchema
354444
+ },
354445
+ {
354446
+ name: "replay_agent_run",
354447
+ description: "Replay agent steps with stubbed tool outputs \u2014 debug without touching live hosts.",
354448
+ schema: replayAgentRunSchema
354449
+ },
354450
+ {
354451
+ name: "plan_offline_join",
354452
+ description: "Plan offline domain join (djoin provision on DC + requestODJ on member) when SMB IPC$ is blocked.",
354453
+ schema: planOfflineJoinSchema
354454
+ },
354455
+ {
354456
+ name: "net_device",
354457
+ description: "Network device helpers: parse CDP neighbors, diff running vs startup config, detect config mode.",
354458
+ schema: netDeviceSchema
353560
354459
  }
353561
354460
  ].map((tool2) => convertToOpenAITool(tool2));
353562
354461
  }
@@ -353617,6 +354516,14 @@ var toolImplementations = {
353617
354516
  collectInfra,
353618
354517
  manageEtw,
353619
354518
  listGatewayMethods,
354519
+ manageIncident,
354520
+ manageCollab,
354521
+ manageJumpPath,
354522
+ manageApproval,
354523
+ snapshotOutput,
354524
+ replayAgentRun,
354525
+ planOfflineJoin,
354526
+ netDevice,
353620
354527
  writeFile,
353621
354528
  editFile,
353622
354529
  writeAndEdit,
@@ -355327,12 +356234,12 @@ function encodeURIPath(str3) {
355327
356234
  return str3.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
355328
356235
  }
355329
356236
  var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
355330
- var createPathTagFunction = (pathEncoder = encodeURIPath) => function path33(statics, ...params) {
356237
+ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path34(statics, ...params) {
355331
356238
  if (statics.length === 1)
355332
356239
  return statics[0];
355333
356240
  let postPath = false;
355334
356241
  const invalidSegments = [];
355335
- const path34 = statics.reduce((previousValue, currentValue, index2) => {
356242
+ const path35 = statics.reduce((previousValue, currentValue, index2) => {
355336
356243
  if (/[?#]/.test(currentValue)) {
355337
356244
  postPath = true;
355338
356245
  }
@@ -355349,7 +356256,7 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path33(sta
355349
356256
  }
355350
356257
  return previousValue + currentValue + (index2 === params.length ? "" : encoded);
355351
356258
  }, "");
355352
- const pathOnly = path34.split(/[?#]/, 1)[0];
356259
+ const pathOnly = path35.split(/[?#]/, 1)[0];
355353
356260
  const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
355354
356261
  let match;
355355
356262
  while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
@@ -355370,10 +356277,10 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path33(sta
355370
356277
  }, "");
355371
356278
  throw new OpenAIError(`Path parameters result in path with invalid segments:
355372
356279
  ${invalidSegments.map((e) => e.error).join("\n")}
355373
- ${path34}
356280
+ ${path35}
355374
356281
  ${underline}`);
355375
356282
  }
355376
- return path34;
356283
+ return path35;
355377
356284
  };
355378
356285
  var path8 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
355379
356286
 
@@ -355746,11 +356653,11 @@ var AbstractChatCompletionRunner = class extends EventStream {
355746
356653
  this._addMessage(message);
355747
356654
  return chatCompletion;
355748
356655
  }
355749
- _addMessage(message, emit11 = true) {
356656
+ _addMessage(message, emit12 = true) {
355750
356657
  if (!("content" in message))
355751
356658
  message.content = null;
355752
356659
  this.messages.push(message);
355753
- if (emit11) {
356660
+ if (emit12) {
355754
356661
  this._emit("message", message);
355755
356662
  if (isToolMessage2(message) && message.content) {
355756
356663
  this._emit("functionToolCallResult", message.content);
@@ -356002,8 +356909,8 @@ var ChatCompletionRunner = class _ChatCompletionRunner extends AbstractChatCompl
356002
356909
  runner._run(() => runner._runTools(client2, params, opts));
356003
356910
  return runner;
356004
356911
  }
356005
- _addMessage(message, emit11 = true) {
356006
- super._addMessage(message, emit11);
356912
+ _addMessage(message, emit12 = true) {
356913
+ super._addMessage(message, emit12);
356007
356914
  if (isAssistantMessage(message) && message.content) {
356008
356915
  this._emit("content", message.content);
356009
356916
  }
@@ -360190,9 +361097,9 @@ var OpenAI = class {
360190
361097
  this.apiKey = token;
360191
361098
  return true;
360192
361099
  }
360193
- buildURL(path33, query, defaultBaseURL) {
361100
+ buildURL(path34, query, defaultBaseURL) {
360194
361101
  const baseURL = !__classPrivateFieldGet(this, _OpenAI_instances, "m", _OpenAI_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
360195
- const url2 = isAbsoluteURL(path33) ? new URL(path33) : new URL(baseURL + (baseURL.endsWith("/") && path33.startsWith("/") ? path33.slice(1) : path33));
361102
+ const url2 = isAbsoluteURL(path34) ? new URL(path34) : new URL(baseURL + (baseURL.endsWith("/") && path34.startsWith("/") ? path34.slice(1) : path34));
360196
361103
  const defaultQuery = this.defaultQuery();
360197
361104
  if (!isEmptyObj(defaultQuery)) {
360198
361105
  query = { ...defaultQuery, ...query };
@@ -360216,24 +361123,24 @@ var OpenAI = class {
360216
361123
  */
360217
361124
  async prepareRequest(request, { url: url2, options }) {
360218
361125
  }
360219
- get(path33, opts) {
360220
- return this.methodRequest("get", path33, opts);
361126
+ get(path34, opts) {
361127
+ return this.methodRequest("get", path34, opts);
360221
361128
  }
360222
- post(path33, opts) {
360223
- return this.methodRequest("post", path33, opts);
361129
+ post(path34, opts) {
361130
+ return this.methodRequest("post", path34, opts);
360224
361131
  }
360225
- patch(path33, opts) {
360226
- return this.methodRequest("patch", path33, opts);
361132
+ patch(path34, opts) {
361133
+ return this.methodRequest("patch", path34, opts);
360227
361134
  }
360228
- put(path33, opts) {
360229
- return this.methodRequest("put", path33, opts);
361135
+ put(path34, opts) {
361136
+ return this.methodRequest("put", path34, opts);
360230
361137
  }
360231
- delete(path33, opts) {
360232
- return this.methodRequest("delete", path33, opts);
361138
+ delete(path34, opts) {
361139
+ return this.methodRequest("delete", path34, opts);
360233
361140
  }
360234
- methodRequest(method, path33, opts) {
361141
+ methodRequest(method, path34, opts) {
360235
361142
  return this.request(Promise.resolve(opts).then((opts2) => {
360236
- return { method, path: path33, ...opts2 };
361143
+ return { method, path: path34, ...opts2 };
360237
361144
  }));
360238
361145
  }
360239
361146
  request(options, remainingRetries = null) {
@@ -360337,8 +361244,8 @@ var OpenAI = class {
360337
361244
  }));
360338
361245
  return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
360339
361246
  }
360340
- getAPIList(path33, Page2, opts) {
360341
- return this.requestAPIList(Page2, { method: "get", path: path33, ...opts });
361247
+ getAPIList(path34, Page2, opts) {
361248
+ return this.requestAPIList(Page2, { method: "get", path: path34, ...opts });
360342
361249
  }
360343
361250
  requestAPIList(Page2, options) {
360344
361251
  const request = this.makeRequest(options, null, void 0);
@@ -360416,8 +361323,8 @@ var OpenAI = class {
360416
361323
  }
360417
361324
  async buildRequest(inputOptions, { retryCount = 0 } = {}) {
360418
361325
  const options = { ...inputOptions };
360419
- const { method, path: path33, query, defaultBaseURL } = options;
360420
- const url2 = this.buildURL(path33, query, defaultBaseURL);
361326
+ const { method, path: path34, query, defaultBaseURL } = options;
361327
+ const url2 = this.buildURL(path34, query, defaultBaseURL);
360421
361328
  if ("timeout" in options)
360422
361329
  validatePositiveInteger("timeout", options.timeout);
360423
361330
  options.timeout = options.timeout ?? this.timeout;
@@ -362033,23 +362940,23 @@ function isNullable(schema2) {
362033
362940
  }
362034
362941
  return false;
362035
362942
  }
362036
- function ensureStrictJsonSchema(jsonSchema, path33, root) {
362943
+ function ensureStrictJsonSchema(jsonSchema, path34, root) {
362037
362944
  if (typeof jsonSchema === "boolean") {
362038
- throw new TypeError(`Expected object schema but got boolean; path=${path33.join("/")}`);
362945
+ throw new TypeError(`Expected object schema but got boolean; path=${path34.join("/")}`);
362039
362946
  }
362040
362947
  if (!isObject4(jsonSchema)) {
362041
- throw new TypeError(`Expected ${JSON.stringify(jsonSchema)} to be an object; path=${path33.join("/")}`);
362948
+ throw new TypeError(`Expected ${JSON.stringify(jsonSchema)} to be an object; path=${path34.join("/")}`);
362042
362949
  }
362043
362950
  const defs = jsonSchema.$defs;
362044
362951
  if (isObject4(defs)) {
362045
362952
  for (const [defName, defSchema] of Object.entries(defs)) {
362046
- ensureStrictJsonSchema(defSchema, [...path33, "$defs", defName], root);
362953
+ ensureStrictJsonSchema(defSchema, [...path34, "$defs", defName], root);
362047
362954
  }
362048
362955
  }
362049
362956
  const definitions = jsonSchema.definitions;
362050
362957
  if (isObject4(definitions)) {
362051
362958
  for (const [definitionName, definitionSchema] of Object.entries(definitions)) {
362052
- ensureStrictJsonSchema(definitionSchema, [...path33, "definitions", definitionName], root);
362959
+ ensureStrictJsonSchema(definitionSchema, [...path34, "definitions", definitionName], root);
362053
362960
  }
362054
362961
  }
362055
362962
  const typ = jsonSchema.type;
@@ -362061,31 +362968,31 @@ function ensureStrictJsonSchema(jsonSchema, path33, root) {
362061
362968
  if (isObject4(properties)) {
362062
362969
  for (const [key, value] of Object.entries(properties)) {
362063
362970
  if (!isNullable(value) && !required2.includes(key)) {
362064
- throw new Error(`Zod field at \`${[...path33, "properties", key].join("/")}\` uses \`.optional()\` without \`.nullable()\` which is not supported by the API. See: https://platform.openai.com/docs/guides/structured-outputs?api-mode=responses#all-fields-must-be-required`);
362971
+ throw new Error(`Zod field at \`${[...path34, "properties", key].join("/")}\` uses \`.optional()\` without \`.nullable()\` which is not supported by the API. See: https://platform.openai.com/docs/guides/structured-outputs?api-mode=responses#all-fields-must-be-required`);
362065
362972
  }
362066
362973
  }
362067
362974
  jsonSchema.required = Object.keys(properties);
362068
362975
  jsonSchema.properties = Object.fromEntries(Object.entries(properties).map(([key, propSchema]) => [
362069
362976
  key,
362070
- ensureStrictJsonSchema(propSchema, [...path33, "properties", key], root)
362977
+ ensureStrictJsonSchema(propSchema, [...path34, "properties", key], root)
362071
362978
  ]));
362072
362979
  }
362073
362980
  const items = jsonSchema.items;
362074
362981
  if (isObject4(items)) {
362075
- jsonSchema.items = ensureStrictJsonSchema(items, [...path33, "items"], root);
362982
+ jsonSchema.items = ensureStrictJsonSchema(items, [...path34, "items"], root);
362076
362983
  }
362077
362984
  const anyOf = jsonSchema.anyOf;
362078
362985
  if (Array.isArray(anyOf)) {
362079
- jsonSchema.anyOf = anyOf.map((variant, i) => ensureStrictJsonSchema(variant, [...path33, "anyOf", String(i)], root));
362986
+ jsonSchema.anyOf = anyOf.map((variant, i) => ensureStrictJsonSchema(variant, [...path34, "anyOf", String(i)], root));
362080
362987
  }
362081
362988
  const allOf = jsonSchema.allOf;
362082
362989
  if (Array.isArray(allOf)) {
362083
362990
  if (allOf.length === 1) {
362084
- const resolved = ensureStrictJsonSchema(allOf[0], [...path33, "allOf", "0"], root);
362991
+ const resolved = ensureStrictJsonSchema(allOf[0], [...path34, "allOf", "0"], root);
362085
362992
  Object.assign(jsonSchema, resolved);
362086
362993
  delete jsonSchema.allOf;
362087
362994
  } else {
362088
- jsonSchema.allOf = allOf.map((entry, i) => ensureStrictJsonSchema(entry, [...path33, "allOf", String(i)], root));
362995
+ jsonSchema.allOf = allOf.map((entry, i) => ensureStrictJsonSchema(entry, [...path34, "allOf", String(i)], root));
362089
362996
  }
362090
362997
  }
362091
362998
  if (jsonSchema.default === null) {
@@ -362094,7 +363001,7 @@ function ensureStrictJsonSchema(jsonSchema, path33, root) {
362094
363001
  const ref = jsonSchema.$ref;
362095
363002
  if (ref && hasMoreThanNKeys(jsonSchema, 1)) {
362096
363003
  if (typeof ref !== "string") {
362097
- throw new TypeError(`Received non-string $ref - ${ref}; path=${path33.join("/")}`);
363004
+ throw new TypeError(`Received non-string $ref - ${ref}; path=${path34.join("/")}`);
362098
363005
  }
362099
363006
  const resolved = resolveRef(root, ref);
362100
363007
  if (typeof resolved === "boolean") {
@@ -362105,7 +363012,7 @@ function ensureStrictJsonSchema(jsonSchema, path33, root) {
362105
363012
  }
362106
363013
  Object.assign(jsonSchema, { ...resolved, ...jsonSchema });
362107
363014
  delete jsonSchema.$ref;
362108
- return ensureStrictJsonSchema(jsonSchema, path33, root);
363015
+ return ensureStrictJsonSchema(jsonSchema, path34, root);
362109
363016
  }
362110
363017
  return jsonSchema;
362111
363018
  }
@@ -366967,7 +367874,7 @@ function reconcileToolCalls(toolCalls) {
366967
367874
  var TOOL_RESULT_MAX_CHARS = 32768;
366968
367875
  function stringifyToolResult(result) {
366969
367876
  const raw = typeof result === "string" ? result : JSON.stringify(result);
366970
- return clipTextMiddle(raw, TOOL_RESULT_MAX_CHARS);
367877
+ return redactText(clipTextMiddle(raw, TOOL_RESULT_MAX_CHARS));
366971
367878
  }
366972
367879
  function clipTextMiddle(input, maxChars) {
366973
367880
  if (maxChars <= 0) return "";
@@ -367013,6 +367920,7 @@ var AgentService_v2 = class {
367013
367920
  * agent run (start/finish lifecycle + per-call token usage). */
367014
367921
  agentRunLedger;
367015
367922
  compoundingStore;
367923
+ opsService;
367016
367924
  changeLedger;
367017
367925
  mcpToolService;
367018
367926
  skillService;
@@ -367150,6 +368058,9 @@ var AgentService_v2 = class {
367150
368058
  setCompoundingStore(store) {
367151
368059
  this.compoundingStore = store ?? void 0;
367152
368060
  }
368061
+ setOpsService(svc) {
368062
+ this.opsService = svc ?? void 0;
368063
+ }
367153
368064
  setFeedbackWaiter(waiter) {
367154
368065
  this.waitForFeedback = waiter;
367155
368066
  }
@@ -368675,6 +369586,78 @@ Actually, your intention might be different. Please re-read the description of t
368675
369586
  }
368676
369587
  break;
368677
369588
  }
369589
+ case "manage_incident": {
369590
+ try {
369591
+ const validatedArgs = manageIncidentSchema.parse(toolCall.args || {});
369592
+ result = await toolImplementations.manageIncident(validatedArgs, executionContext);
369593
+ } catch (err) {
369594
+ result = `Parameter validation error for manage_incident: ${err.message}`;
369595
+ }
369596
+ break;
369597
+ }
369598
+ case "manage_collab": {
369599
+ try {
369600
+ const validatedArgs = manageCollabSchema.parse(toolCall.args || {});
369601
+ result = await toolImplementations.manageCollab(validatedArgs, executionContext);
369602
+ } catch (err) {
369603
+ result = `Parameter validation error for manage_collab: ${err.message}`;
369604
+ }
369605
+ break;
369606
+ }
369607
+ case "manage_jump_path": {
369608
+ try {
369609
+ const validatedArgs = manageJumpPathSchema.parse(toolCall.args || {});
369610
+ result = await toolImplementations.manageJumpPath(validatedArgs, executionContext);
369611
+ } catch (err) {
369612
+ result = `Parameter validation error for manage_jump_path: ${err.message}`;
369613
+ }
369614
+ break;
369615
+ }
369616
+ case "manage_approval": {
369617
+ try {
369618
+ const validatedArgs = manageApprovalSchema.parse(toolCall.args || {});
369619
+ result = await toolImplementations.manageApproval(validatedArgs, executionContext);
369620
+ } catch (err) {
369621
+ result = `Parameter validation error for manage_approval: ${err.message}`;
369622
+ }
369623
+ break;
369624
+ }
369625
+ case "snapshot_output": {
369626
+ try {
369627
+ const validatedArgs = snapshotOutputSchema.parse(toolCall.args || {});
369628
+ result = await toolImplementations.snapshotOutput(validatedArgs, executionContext);
369629
+ } catch (err) {
369630
+ result = `Parameter validation error for snapshot_output: ${err.message}`;
369631
+ }
369632
+ break;
369633
+ }
369634
+ case "replay_agent_run": {
369635
+ try {
369636
+ const validatedArgs = replayAgentRunSchema.parse(toolCall.args || {});
369637
+ result = await toolImplementations.replayAgentRun(validatedArgs, executionContext);
369638
+ } catch (err) {
369639
+ result = `Parameter validation error for replay_agent_run: ${err.message}`;
369640
+ }
369641
+ break;
369642
+ }
369643
+ case "plan_offline_join": {
369644
+ try {
369645
+ const validatedArgs = planOfflineJoinSchema.parse(toolCall.args || {});
369646
+ result = await toolImplementations.planOfflineJoin(validatedArgs, executionContext);
369647
+ } catch (err) {
369648
+ result = `Parameter validation error for plan_offline_join: ${err.message}`;
369649
+ }
369650
+ break;
369651
+ }
369652
+ case "net_device": {
369653
+ try {
369654
+ const validatedArgs = netDeviceSchema.parse(toolCall.args || {});
369655
+ result = await toolImplementations.netDevice(validatedArgs, executionContext);
369656
+ } catch (err) {
369657
+ result = `Parameter validation error for net_device: ${err.message}`;
369658
+ }
369659
+ break;
369660
+ }
368678
369661
  case "manage_device_memory": {
368679
369662
  try {
368680
369663
  const validatedArgs = manageDeviceMemorySchema.parse(toolCall.args || {});
@@ -369152,6 +370135,22 @@ Actually, your intention might be different. Please re-read the description of t
369152
370135
  return ti.manageGoal(args, executionContext);
369153
370136
  case "estate_facts":
369154
370137
  return ti.estateFacts(args, executionContext);
370138
+ case "manage_incident":
370139
+ return ti.manageIncident(args, executionContext);
370140
+ case "manage_collab":
370141
+ return ti.manageCollab(args, executionContext);
370142
+ case "manage_jump_path":
370143
+ return ti.manageJumpPath(args, executionContext);
370144
+ case "manage_approval":
370145
+ return ti.manageApproval(args, executionContext);
370146
+ case "snapshot_output":
370147
+ return ti.snapshotOutput(args, executionContext);
370148
+ case "replay_agent_run":
370149
+ return ti.replayAgentRun(args, executionContext);
370150
+ case "plan_offline_join":
370151
+ return ti.planOfflineJoin(args, executionContext);
370152
+ case "net_device":
370153
+ return ti.netDevice(args, executionContext);
369155
370154
  case "list_gateway_methods":
369156
370155
  return ti.listGatewayMethods(args, executionContext);
369157
370156
  case "collect_facts":
@@ -369610,6 +370609,7 @@ ${reminder}`;
369610
370609
  sessionLogger: this.sessionLogger,
369611
370610
  agentRunLedger: this.agentRunLedger,
369612
370611
  compoundingStore: this.compoundingStore,
370612
+ opsService: this.opsService,
369613
370613
  changeLedger: this.changeLedger,
369614
370614
  triggerEngine: this.triggerEngine,
369615
370615
  observability: this.observability,
@@ -373029,6 +374029,154 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
373029
374029
 
373030
374030
  // ../../packages/backend/src/services/Gateway/WebSocketGatewayAdapter.ts
373031
374031
  var import_node_module4 = require("node:module");
374032
+
374033
+ // ../../packages/backend/src/services/Gateway/opsBridge.ts
374034
+ function requireOps(deps) {
374035
+ const o = deps.ops();
374036
+ if (!o) throw new Error("ops service is not available on this runtime");
374037
+ return o;
374038
+ }
374039
+ var DEFAULT_APPROVAL_TTL_SECONDS = 900;
374040
+ function createOpsBridge(deps) {
374041
+ return {
374042
+ // ── collab ─────────────────────────────────────────────────────────────
374043
+ collabJoin: async (p) => requireOps(deps).joinCollab(p.sessionId, p.operator),
374044
+ collabTakeConn: async (p) => requireOps(deps).takeConn(p.sessionId, p.operator),
374045
+ collabWhoHasConn: async (p) => requireOps(deps).whoHasConn(p.sessionId),
374046
+ collabList: async () => ({ sessions: requireOps(deps).listCollabSessions() }),
374047
+ // ── incidents ──────────────────────────────────────────────────────────
374048
+ incidentOpen: async (p) => requireOps(deps).openIncident(p.title, {
374049
+ sessionId: p.chatId,
374050
+ tabIds: p.terminals,
374051
+ recordingId: p.recordingId,
374052
+ runId: p.runId,
374053
+ notes: p.notes
374054
+ }),
374055
+ incidentGet: async (p) => {
374056
+ const inc = requireOps(deps).getIncident(p.id);
374057
+ if (!inc) throw new Error(`no incident ${p.id}`);
374058
+ return inc;
374059
+ },
374060
+ incidentList: async (p) => ({ incidents: requireOps(deps).listIncidents(p?.status) }),
374061
+ incidentClose: async (p) => {
374062
+ const inc = requireOps(deps).closeIncident(p.id, p.notes);
374063
+ if (!inc) throw new Error(`no incident ${p.id}`);
374064
+ return inc;
374065
+ },
374066
+ // ── jump paths / break-glass ───────────────────────────────────────────
374067
+ jumpPathDefine: async (p) => requireOps(deps).defineJumpPath(p.name, p.hops),
374068
+ jumpPathList: async () => ({ paths: requireOps(deps).listJumpPaths() }),
374069
+ jumpPathBreakGlass: async (p) => requireOps(deps).grantBreakGlass(p.name, Math.max(0, p.ttlSeconds) * 1e3),
374070
+ jumpPathAllowed: async (p) => requireOps(deps).pathAllowed(p.name),
374071
+ // ── output snapshots ───────────────────────────────────────────────────
374072
+ snapshotRemember: async (p) => requireOps(deps).rememberOutput(p.connection, p.command, p.output),
374073
+ snapshotList: async (p) => ({ snapshots: requireOps(deps).listSnapshots(p?.connection) }),
374074
+ snapshotDiff: async (p) => requireOps(deps).diffOutput(p.connection, p.command, p.output),
374075
+ // ── approvals ──────────────────────────────────────────────────────────
374076
+ approvalRequest: async (p) => requireOps(deps).requestApproval(
374077
+ p.command,
374078
+ Math.max(1, p.ttlSeconds ?? DEFAULT_APPROVAL_TTL_SECONDS) * 1e3,
374079
+ p.twoPerson === true
374080
+ ),
374081
+ approvalList: async (p) => ({ approvals: requireOps(deps).listApprovals(p?.state) }),
374082
+ approvalGet: async (p) => {
374083
+ const a = requireOps(deps).getApproval(p.id);
374084
+ if (!a) throw new Error(`no approval ${p.id}`);
374085
+ return a;
374086
+ },
374087
+ approvalDecide: async (p) => requireOps(deps).decideApproval(p.id, p.who, p.approve),
374088
+ approvalSweep: async () => ({ expired: requireOps(deps).sweepExpiredApprovals() }),
374089
+ // ── agent replay ───────────────────────────────────────────────────────
374090
+ replayRun: async (p) => requireOps(deps).replay(
374091
+ p.runId,
374092
+ p.steps.map((s) => ({
374093
+ tool: s.tool,
374094
+ args: s.args && typeof s.args === "object" && !Array.isArray(s.args) ? s.args : {},
374095
+ stub: typeof s.output === "string" ? s.output : ""
374096
+ }))
374097
+ ),
374098
+ // ── offline domain join ────────────────────────────────────────────────
374099
+ djoinPlan: async (p) => requireOps(deps).planOfflineJoin(p),
374100
+ // ── network device ─────────────────────────────────────────────────────
374101
+ netParseCdp: async (p) => ({ neighbors: requireOps(deps).parseCdp(p.output) }),
374102
+ netConfigDiff: async (p) => requireOps(deps).configDiff(p.running, p.startup),
374103
+ netInConfigMode: async (p) => ({ inConfigMode: requireOps(deps).inConfigMode(p.prompt) })
374104
+ };
374105
+ }
374106
+ var OPS_METHODS = [
374107
+ "ops:collabJoin",
374108
+ "ops:collabTakeConn",
374109
+ "ops:collabWhoHasConn",
374110
+ "ops:collabList",
374111
+ "ops:incidentOpen",
374112
+ "ops:incidentGet",
374113
+ "ops:incidentList",
374114
+ "ops:incidentClose",
374115
+ "ops:jumpPathDefine",
374116
+ "ops:jumpPathList",
374117
+ "ops:jumpPathBreakGlass",
374118
+ "ops:jumpPathAllowed",
374119
+ "ops:snapshotRemember",
374120
+ "ops:snapshotList",
374121
+ "ops:snapshotDiff",
374122
+ "ops:approvalRequest",
374123
+ "ops:approvalList",
374124
+ "ops:approvalGet",
374125
+ "ops:approvalDecide",
374126
+ "ops:approvalSweep",
374127
+ "ops:replayRun",
374128
+ "ops:djoinPlan",
374129
+ "ops:netParseCdp",
374130
+ "ops:netConfigDiff",
374131
+ "ops:netInConfigMode"
374132
+ ];
374133
+ var OPS_METHOD_INFO = [
374134
+ { name: "ops:collabJoin", description: "Join a shared agent session as an operator (two-operator collab).", since: "3.8.1" },
374135
+ { name: "ops:collabTakeConn", description: "Take the conn for a shared session \u2014 records who is currently driving.", since: "3.8.1" },
374136
+ { name: "ops:collabWhoHasConn", description: "Who currently holds the conn for a session, plus joined operators.", since: "3.8.1" },
374137
+ { name: "ops:collabList", description: "List sessions with operators and current holder.", since: "3.8.1" },
374138
+ { name: "ops:incidentOpen", description: "Open an incident bundle (chat + terminals + recording + run id). Persisted.", since: "3.8.1" },
374139
+ { name: "ops:incidentGet", description: "Fetch one incident bundle by id.", since: "3.8.1" },
374140
+ { name: "ops:incidentList", description: "List incident bundles (optionally by status).", since: "3.8.1" },
374141
+ { name: "ops:incidentClose", description: "Close an incident bundle with optional notes.", since: "3.8.1" },
374142
+ { name: "ops:jumpPathDefine", description: "Define a named multi-hop jump path (laptop \u2192 jump \u2192 target).", since: "3.8.1" },
374143
+ { name: "ops:jumpPathList", description: "List defined jump paths and their break-glass state.", since: "3.8.1" },
374144
+ { name: "ops:jumpPathBreakGlass", description: "Grant time-boxed break-glass (TTL seconds) on a jump path.", since: "3.8.1" },
374145
+ { name: "ops:jumpPathAllowed", description: "Is a jump path usable right now (break-glass valid) or expired?", since: "3.8.1" },
374146
+ { name: "ops:snapshotRemember", description: "Store command output as the baseline for a connection+command.", since: "3.8.1" },
374147
+ { name: "ops:snapshotList", description: "List stored output snapshots.", since: "3.8.1" },
374148
+ { name: "ops:snapshotDiff", description: "Diff new output against the stored baseline, then update the baseline.", since: "3.8.1" },
374149
+ { name: "ops:approvalRequest", description: "Request an approval with a TTL; twoPerson requires two distinct approvers.", since: "3.8.1" },
374150
+ { name: "ops:approvalList", description: "List approvals (sweeps expired first).", since: "3.8.1" },
374151
+ { name: "ops:approvalGet", description: "Get one approval by id.", since: "3.8.1" },
374152
+ { name: "ops:approvalDecide", description: "Approve or deny an approval as a named person.", since: "3.8.1" },
374153
+ { name: "ops:approvalSweep", description: "Expire pending approvals past their TTL; returns the count.", since: "3.8.1" },
374154
+ { name: "ops:replayRun", description: "Replay agent steps with stubbed tool outputs \u2014 debug without touching live hosts.", since: "3.8.1" },
374155
+ { name: "ops:djoinPlan", description: "Plan offline domain join (djoin provision + request) across a DC and a member.", since: "3.8.1" },
374156
+ { name: "ops:netParseCdp", description: "Parse `show cdp neighbors` output into structured neighbors.", since: "3.8.1" },
374157
+ { name: "ops:netConfigDiff", description: "Diff running-config vs startup-config for a network device.", since: "3.8.1" },
374158
+ { name: "ops:netInConfigMode", description: "Detect whether a device prompt is in config mode.", since: "3.8.1" }
374159
+ ];
374160
+
374161
+ // ../../packages/backend/src/services/security/tokenScopes.ts
374162
+ var SCOPE_FULL = "*";
374163
+ function methodAllowed(method, scopes) {
374164
+ if (!scopes || scopes.length === 0) return true;
374165
+ if (scopes.includes(SCOPE_FULL)) return true;
374166
+ const m2 = String(method || "");
374167
+ for (const s of scopes) {
374168
+ if (s === m2) return true;
374169
+ if (s.endsWith(":*")) {
374170
+ const prefix = s.slice(0, -1);
374171
+ if (m2.startsWith(prefix)) return true;
374172
+ if (prefix === "terminals:" && m2.startsWith("terminal:")) return true;
374173
+ }
374174
+ if (s.endsWith("*") && m2.startsWith(s.slice(0, -1))) return true;
374175
+ }
374176
+ return false;
374177
+ }
374178
+
374179
+ // ../../packages/backend/src/services/Gateway/WebSocketGatewayAdapter.ts
373032
374180
  var import_meta7 = {};
373033
374181
  var nodeRequire = (0, import_node_module4.createRequire)(
373034
374182
  typeof __filename !== "undefined" ? __filename : import_meta7.url
@@ -373133,6 +374281,7 @@ var WebSocketGatewayAdapter = class {
373133
374281
  server = null;
373134
374282
  transportIdBySocket = /* @__PURE__ */ new Map();
373135
374283
  isSameMachineBySocket = /* @__PURE__ */ new WeakMap();
374284
+ scopesBySocket = /* @__PURE__ */ new WeakMap();
373136
374285
  serverFactory;
373137
374286
  logger;
373138
374287
  start() {
@@ -373230,6 +374379,12 @@ var WebSocketGatewayAdapter = class {
373230
374379
  this.isLoopbackAddress(String(remote))
373231
374380
  );
373232
374381
  this.gateway.registerTransport(transport);
374382
+ const token = this.extractAccessToken(request);
374383
+ const scopeFn = this.options.accessTokenAuth?.scopesForToken;
374384
+ if (token && scopeFn) {
374385
+ const scopes = await scopeFn(token);
374386
+ if (scopes && scopes.length) this.scopesBySocket.set(socket, scopes);
374387
+ }
373233
374388
  state.authorized = true;
373234
374389
  this.logger.info(
373235
374390
  `[WebSocketGatewayAdapter] Client connected: ${remote} (${transport.id})`
@@ -373527,6 +374682,13 @@ var WebSocketGatewayAdapter = class {
373527
374682
  );
373528
374683
  }
373529
374684
  async executeRequest(request, socket) {
374685
+ const scopes = this.scopesBySocket.get(socket);
374686
+ if (scopes && !methodAllowed(request.method, scopes)) {
374687
+ throw new WebSocketRpcError(
374688
+ "FORBIDDEN",
374689
+ `Token is not allowed to call ${request.method}`
374690
+ );
374691
+ }
373530
374692
  const params = request.params ?? {};
373531
374693
  if (request.method.startsWith("observability:")) {
373532
374694
  const bridge = this.options.observabilityBridge;
@@ -373569,6 +374731,24 @@ var WebSocketGatewayAdapter = class {
373569
374731
  }
373570
374732
  return await fn(params);
373571
374733
  }
374734
+ if (request.method.startsWith("ops:")) {
374735
+ const ops = this.options.opsBridge;
374736
+ if (!ops) {
374737
+ throw new WebSocketRpcError(
374738
+ "METHOD_NOT_FOUND",
374739
+ `${request.method} is not available on this websocket gateway.`
374740
+ );
374741
+ }
374742
+ const opName = request.method.slice("ops:".length);
374743
+ const opFn = ops[opName];
374744
+ if (typeof opFn !== "function") {
374745
+ throw new WebSocketRpcError(
374746
+ "METHOD_NOT_FOUND",
374747
+ `Unknown ops method: ${request.method}`
374748
+ );
374749
+ }
374750
+ return await opFn(params);
374751
+ }
373572
374752
  switch (request.method) {
373573
374753
  case "gateway:ping":
373574
374754
  return { pong: true, ts: Date.now() };
@@ -373576,7 +374756,11 @@ var WebSocketGatewayAdapter = class {
373576
374756
  return { sameMachine: this.isSameMachineBySocket.get(socket) === true };
373577
374757
  case "gateway:describe": {
373578
374758
  const obs2 = OBSERVABILITY_METHODS.map((name) => ({ name }));
373579
- const payload = buildDescribePayload(obs2);
374759
+ const opsMethods = OPS_METHODS.map((name) => {
374760
+ const info = OPS_METHOD_INFO.find((m2) => m2.name === name);
374761
+ return { name, description: info?.description, since: info?.since };
374762
+ });
374763
+ const payload = buildDescribePayload([...obs2, ...opsMethods]);
373580
374764
  const category = typeof params.category === "string" && params.category ? params.category : void 0;
373581
374765
  const prefix = typeof params.prefix === "string" && params.prefix ? params.prefix : void 0;
373582
374766
  let methods = payload.methods;
@@ -382942,20 +384126,25 @@ var FileAccessTokenStore = class {
382942
384126
  });
382943
384127
  }
382944
384128
  async verify(tokenRaw) {
384129
+ const identified = await this.identify(tokenRaw);
384130
+ return identified !== null;
384131
+ }
384132
+ /** Return the matching token's id+name, or null. Used as operator identity. */
384133
+ async identify(tokenRaw) {
382945
384134
  const token = String(tokenRaw || "").trim();
382946
- if (!token) return false;
384135
+ if (!token) return null;
382947
384136
  const payload = await this.readPayload();
382948
384137
  for (const record2 of payload.tokens) {
382949
384138
  try {
382950
384139
  const expected = Buffer.from(record2.tokenHash, "base64");
382951
384140
  const actual = await deriveTokenHash(token, record2.tokenSalt);
382952
384141
  if (expected.length === actual.length && (0, import_node_crypto19.timingSafeEqual)(expected, actual)) {
382953
- return true;
384142
+ return { id: record2.id, name: record2.name };
382954
384143
  }
382955
384144
  } catch {
382956
384145
  }
382957
384146
  }
382958
- return false;
384147
+ return null;
382959
384148
  }
382960
384149
  async runExclusive(operation) {
382961
384150
  const run = this.mutationQueue.then(operation, operation);
@@ -384986,8 +386175,8 @@ var IdleTimeoutService = class {
384986
386175
  };
384987
386176
 
384988
386177
  // ../../packages/backend/src/services/Gateway/restApi.ts
384989
- function matchRestRoute(routes, method, path33) {
384990
- const normalized = path33.replace(/\/+$/, "") || "/";
386178
+ function matchRestRoute(routes, method, path34) {
386179
+ const normalized = path34.replace(/\/+$/, "") || "/";
384991
386180
  const verb = method.toUpperCase();
384992
386181
  for (const route of routes) {
384993
386182
  if (route.method !== verb) continue;
@@ -393116,11 +394305,11 @@ function createObservability(deps) {
393116
394305
  const policyEngine = new AgtPolicyEngine({
393117
394306
  loadPolicy: async () => {
393118
394307
  const req = (0, import_node_module5.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta8.url);
393119
- const fs24 = req("node:fs");
393120
- const path33 = req("node:path");
393121
- const policyPath = path33.join(".", "policy.yaml");
393122
- if (fs24.existsSync(policyPath)) {
393123
- return parsePolicyYaml(fs24.readFileSync(policyPath, "utf8"));
394308
+ const fs25 = req("node:fs");
394309
+ const path34 = req("node:path");
394310
+ const policyPath = path34.join(".", "policy.yaml");
394311
+ if (fs25.existsSync(policyPath)) {
394312
+ return parsePolicyYaml(fs25.readFileSync(policyPath, "utf8"));
393124
394313
  }
393125
394314
  return {
393126
394315
  name: "rterm-default",
@@ -393162,18 +394351,18 @@ function createObservability(deps) {
393162
394351
  const scanRoots = [pluginScanRoot, "./plugins"];
393163
394352
  try {
393164
394353
  const req = (0, import_node_module5.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta8.url);
393165
- const fs24 = req("node:fs");
393166
- if (fs24.existsSync(bundlePluginRoot)) scanRoots.push(bundlePluginRoot);
394354
+ const fs25 = req("node:fs");
394355
+ if (fs25.existsSync(bundlePluginRoot)) scanRoots.push(bundlePluginRoot);
393167
394356
  } catch {
393168
394357
  }
393169
394358
  try {
393170
394359
  const req = (0, import_node_module5.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta8.url);
393171
- const fs24 = req("node:fs");
393172
- const path33 = req("node:path");
394360
+ const fs25 = req("node:fs");
394361
+ const path34 = req("node:path");
393173
394362
  const resourcesPath = process.resourcesPath;
393174
394363
  if (resourcesPath) {
393175
- const resourcesPlugins = path33.join(resourcesPath, "plugins");
393176
- if (fs24.existsSync(resourcesPlugins)) scanRoots.push(resourcesPlugins);
394364
+ const resourcesPlugins = path34.join(resourcesPath, "plugins");
394365
+ if (fs25.existsSync(resourcesPlugins)) scanRoots.push(resourcesPlugins);
393177
394366
  }
393178
394367
  } catch {
393179
394368
  }
@@ -395860,9 +397049,9 @@ function numberFromEnv(name, fallback) {
395860
397049
  function resolveDataDir() {
395861
397050
  const custom3 = (import_node_process2.default.env.GYBACKEND_DATA_DIR || "").trim();
395862
397051
  if (custom3) {
395863
- return import_node_path29.default.resolve(custom3);
397052
+ return import_node_path30.default.resolve(custom3);
395864
397053
  }
395865
- return import_node_path29.default.join(import_node_process2.default.cwd(), ".gybackend-data");
397054
+ return import_node_path30.default.join(import_node_process2.default.cwd(), ".gybackend-data");
395866
397055
  }
395867
397056
  async function startGyBackend() {
395868
397057
  const dataDir = resolveDataDir();
@@ -395895,7 +397084,7 @@ async function startGyBackend() {
395895
397084
  const modelCapabilityService = new ModelCapabilityService();
395896
397085
  const imageAttachmentService = new ImageAttachmentService(dataDir);
395897
397086
  const terminalStateStore = new TerminalStateStore(
395898
- import_node_path29.default.join(dataDir, "terminal-tabs-state.json")
397087
+ import_node_path30.default.join(dataDir, "terminal-tabs-state.json")
395899
397088
  );
395900
397089
  const terminalService = new TerminalService({
395901
397090
  terminalStateStore
@@ -395986,6 +397175,9 @@ async function startGyBackend() {
395986
397175
  const { CompoundingStore: CompoundingStore2 } = await Promise.resolve().then(() => (init_compoundingStore(), compoundingStore_exports));
395987
397176
  const compoundingStore = new CompoundingStore2();
395988
397177
  agentService.setCompoundingStore(compoundingStore);
397178
+ const { OpsService: OpsService2 } = await Promise.resolve().then(() => (init_opsService(), opsService_exports));
397179
+ const opsService = new OpsService2();
397180
+ agentService.setOpsService(opsService);
395989
397181
  try {
395990
397182
  const { connectionIdentity: connectionIdentity2 } = await Promise.resolve().then(() => (init_compoundingKnowledge(), compoundingKnowledge_exports));
395991
397183
  const winrm = settingsService.getSettings()?.connections?.winrm ?? [];
@@ -396111,7 +397303,7 @@ async function startGyBackend() {
396111
397303
  console.warn("[gybackend] Plugin tool wiring skipped:", e instanceof Error ? e.message : String(e));
396112
397304
  });
396113
397305
  if (settingsService.getSettings().sessionLogging?.enabled) {
396114
- const logDir = import_node_path29.default.join(
397306
+ const logDir = import_node_path30.default.join(
396115
397307
  import_node_process2.default.env.GYSHELL_STORE_DIR || "",
396116
397308
  "session-logs"
396117
397309
  );
@@ -396229,21 +397421,21 @@ async function startGyBackend() {
396229
397421
  authFailureLimit: 5,
396230
397422
  authLockoutMs: 6e4
396231
397423
  });
396232
- const settingsDir = import_node_path29.default.dirname(settingsService.getSettingsPath?.() ?? "");
396233
- const backupsDir = settingsDir ? import_node_path29.default.join(settingsDir, "backups") : "";
397424
+ const settingsDir = import_node_path30.default.dirname(settingsService.getSettingsPath?.() ?? "");
397425
+ const backupsDir = settingsDir ? import_node_path30.default.join(settingsDir, "backups") : "";
396234
397426
  const settingsBackupService = new SettingsBackupService(
396235
397427
  backupsDir ? {
396236
- read: () => import_node_fs13.default.readFileSync(settingsService.getSettingsPath(), "utf8"),
396237
- write: (c) => import_node_fs13.default.writeFileSync(settingsService.getSettingsPath(), c),
396238
- listBackups: () => import_node_fs13.default.existsSync(backupsDir) ? import_node_fs13.default.readdirSync(backupsDir) : [],
396239
- readBackup: (n2) => import_node_fs13.default.readFileSync(import_node_path29.default.join(backupsDir, n2), "utf8"),
397428
+ read: () => import_node_fs14.default.readFileSync(settingsService.getSettingsPath(), "utf8"),
397429
+ write: (c) => import_node_fs14.default.writeFileSync(settingsService.getSettingsPath(), c),
397430
+ listBackups: () => import_node_fs14.default.existsSync(backupsDir) ? import_node_fs14.default.readdirSync(backupsDir) : [],
397431
+ readBackup: (n2) => import_node_fs14.default.readFileSync(import_node_path30.default.join(backupsDir, n2), "utf8"),
396240
397432
  writeBackup: (n2, c) => {
396241
- import_node_fs13.default.mkdirSync(backupsDir, { recursive: true });
396242
- import_node_fs13.default.writeFileSync(import_node_path29.default.join(backupsDir, n2), c);
397433
+ import_node_fs14.default.mkdirSync(backupsDir, { recursive: true });
397434
+ import_node_fs14.default.writeFileSync(import_node_path30.default.join(backupsDir, n2), c);
396243
397435
  },
396244
397436
  deleteBackup: (n2) => {
396245
- const p = import_node_path29.default.join(backupsDir, n2);
396246
- if (import_node_fs13.default.existsSync(p)) import_node_fs13.default.unlinkSync(p);
397437
+ const p = import_node_path30.default.join(backupsDir, n2);
397438
+ if (import_node_fs14.default.existsSync(p)) import_node_fs14.default.unlinkSync(p);
396247
397439
  }
396248
397440
  } : { read: () => "", write: () => {
396249
397441
  }, listBackups: () => [], readBackup: () => "", writeBackup: () => {
@@ -396751,6 +397943,9 @@ async function startGyBackend() {
396751
397943
  observabilityBridge: createObservabilityBridge({
396752
397944
  observability: () => observability,
396753
397945
  terminalService: () => terminalService
397946
+ }),
397947
+ opsBridge: createOpsBridge({
397948
+ ops: () => opsService
396754
397949
  })
396755
397950
  });
396756
397951
  restDispatchTarget = adapter;