@rzx/ohs 1.1.23 → 1.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -13786,6 +13786,7 @@ var init_auto_review = __esm(() => {
13786
13786
  "large_change",
13787
13787
  "many_files",
13788
13788
  "sensitive_path",
13789
+ "sensitive_content_path",
13789
13790
  "production_delete_or_rename",
13790
13791
  "patch_truncated",
13791
13792
  "not_git_repository",
@@ -13796,6 +13797,7 @@ var init_auto_review = __esm(() => {
13796
13797
  "review_output_invalid",
13797
13798
  "review_child_failed",
13798
13799
  "review_child_timed_out",
13800
+ "review_preempted_by_user",
13799
13801
  "parent_run_not_completed",
13800
13802
  "daemon_restarted"
13801
13803
  ];
@@ -359267,6 +359269,9 @@ function normalizeToolInput2(schema, input) {
359267
359269
  const propertyNames = Object.keys(properties);
359268
359270
  if (propertyNames.length === 0)
359269
359271
  return input;
359272
+ if (!Object.prototype.hasOwnProperty.call(properties, "arguments") && Object.keys(input).length === 1 && isRecord11(input.arguments) && validateToolInput2(schema, input.arguments) === null) {
359273
+ return input.arguments;
359274
+ }
359270
359275
  const normalized = { ...input };
359271
359276
  const copiedFrom = /* @__PURE__ */ new Set;
359272
359277
  for (const key of propertyNames) {
@@ -375986,7 +375991,7 @@ function deriveChildAgentOptions(input) {
375986
375991
  permissionMode: child.permissionMode ?? configuration.permissionMode,
375987
375992
  hostToolCeiling: configuration.hostToolCeiling,
375988
375993
  roleAllowedTools: child.allowedTools,
375989
- ...input.internalToolLimitNone ? { internalToolLimitNone: true } : {},
375994
+ ...input.internalTextOnly ? { internalTextOnly: true } : {},
375990
375995
  disallowedTools: mergeToolLists(configuration.disallowedTools, child.disallowedTools),
375991
375996
  maxTurns: resolveChildMaxTurns({
375992
375997
  roleMaxTurns: child.maxTurns,
@@ -376596,7 +376601,7 @@ function resolveAutoApproveTools(settings, overrides, trustedBuiltinToolNames) {
376596
376601
  return merged.size > 0 ? [...merged] : undefined;
376597
376602
  }
376598
376603
  function resolveEffectiveAllowedTools(options) {
376599
- if (options.internalToolLimitNone)
376604
+ if (options.internalTextOnly)
376600
376605
  return { kind: "none" };
376601
376606
  const knownToolNames = options.knownToolNames ?? [];
376602
376607
  const hostCeiling = resolveToolLimit(options.hostToolCeiling ?? options.settingsAllowedTools ?? [], knownToolNames);
@@ -376637,7 +376642,7 @@ async function createVykorRuntime(options) {
376637
376642
  roleAllowedTools: configuration.roleAllowedTools,
376638
376643
  settingsAllowedTools: settings.permission.allowedTools,
376639
376644
  knownToolNames,
376640
- internalToolLimitNone: configuration.internalToolLimitNone
376645
+ internalTextOnly: configuration.internalTextOnly
376641
376646
  });
376642
376647
  const effectiveDenied = new Set(normalizeToolNames2([
376643
376648
  ...settings.permission.deniedTools ?? [],
@@ -376658,6 +376663,7 @@ async function createVykorRuntime(options) {
376658
376663
  trustedLocalReadOnlyToolNames: [...trustedBuiltinToolNames]
376659
376664
  });
376660
376665
  const hookExecutor = new HookExecutor({
376666
+ disabled: configuration.internalTextOnly === true,
376661
376667
  cwd: options.executionEnvironment?.workspace.executionRoot ?? hostCwd,
376662
376668
  sessionId: options.sessionId,
376663
376669
  settings,
@@ -381935,7 +381941,7 @@ async function composeVykorAgentInternal(options, internal, cleanup, rollback) {
381935
381941
  const cwd = options.cwd ?? process.cwd();
381936
381942
  const settings = options.settings ?? await loadSettings2({});
381937
381943
  const discovery = await discoverVykorExtensions(cwd, settings, {
381938
- pluginsEnabled: options.pluginsEnabled
381944
+ pluginsEnabled: options.internalTextOnly ? false : options.pluginsEnabled
381939
381945
  });
381940
381946
  for (const warning of discovery.warnings) {
381941
381947
  process.stderr.write(`[plugins] ${warning}
@@ -382017,11 +382023,11 @@ async function composeVykorAgentInternal(options, internal, cleanup, rollback) {
382017
382023
  settings,
382018
382024
  runtime,
382019
382025
  discovery,
382020
- extensions: options.extensions,
382021
- mcpServers: options.mcpServers,
382026
+ extensions: options.internalTextOnly ? [] : options.extensions,
382027
+ mcpServers: options.internalTextOnly ? {} : options.mcpServers,
382022
382028
  memory: environment.memory,
382023
382029
  executionEnvironment,
382024
- mcpRuntimeRegistry: options.mcpRuntimeRegistry
382030
+ mcpRuntimeRegistry: options.internalTextOnly ? undefined : options.mcpRuntimeRegistry
382025
382031
  });
382026
382032
  const session = createAgentSession2({
382027
382033
  queryEngine: runtime.queryEngine,
@@ -382827,7 +382833,7 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
382827
382833
  });
382828
382834
  }
382829
382835
  runChildForCompletedRun(input, parent, sensitiveInitialContent, capabilityView) {
382830
- return this.runMaintenance("review", async () => {
382836
+ return this.runMaintenance("post_run_child", async () => {
382831
382837
  const scope = {
382832
382838
  agentId: this.id,
382833
382839
  sessionId: this.id,
@@ -382838,10 +382844,12 @@ var require2, __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __get
382838
382844
  signal: parent.signal ?? new AbortController().signal
382839
382845
  };
382840
382846
  const invocation = await this.childManager.spawnSystemChild(scope, input, sensitiveInitialContent, capabilityView);
382841
- const result2 = await invocation.result;
382842
- await this.childManager.close(invocation.id, "System review finished").catch(() => {
382843
- return;
382844
- });
382847
+ let result2;
382848
+ try {
382849
+ result2 = await invocation.result;
382850
+ } finally {
382851
+ await this.childManager.close(invocation.id, "Post-run child finished");
382852
+ }
382845
382853
  return { invocation, result: result2 };
382846
382854
  });
382847
382855
  }
@@ -387555,7 +387563,7 @@ rm -- "$1"`, WslFileOperations2 = class {
387555
387563
  child: input,
387556
387564
  cwd: lease.cwd,
387557
387565
  sessionId,
387558
- ...system ? { internalToolLimitNone: true } : {}
387566
+ ...system ? { internalTextOnly: true } : {}
387559
387567
  }), {
387560
387568
  childId,
387561
387569
  parentSessionId: parentScope.sessionId,
@@ -387613,16 +387621,10 @@ rm -- "$1"`, WslFileOperations2 = class {
387613
387621
  throw new Error("Parent run interrupted");
387614
387622
  }
387615
387623
  const receipt = await this.beginRun(record2, {
387616
- content: options.initialContent ?? childInitialTask(input)
387624
+ content: options.initialContent ?? childInitialTask(input),
387625
+ ...system ? { metadata: { sensitiveInput: true } } : {}
387617
387626
  });
387618
387627
  budgetReservation.commit();
387619
- if (system) {
387620
- record2.result.catch(() => {}).finally(() => {
387621
- if (this.records.has(childId)) {
387622
- this.close(childId, "System review finished").catch(() => {});
387623
- }
387624
- });
387625
- }
387626
387628
  return {
387627
387629
  id: childId,
387628
387630
  sessionId,
@@ -388275,6 +388277,7 @@ rm -- "$1"`, WslFileOperations2 = class {
388275
388277
  return this.mode;
388276
388278
  }
388277
388279
  }, HookExecutor = class {
388280
+ disabled;
388278
388281
  hooks = /* @__PURE__ */ new Map;
388279
388282
  client;
388280
388283
  defaultModel;
@@ -388283,6 +388286,7 @@ rm -- "$1"`, WslFileOperations2 = class {
388283
388286
  settings;
388284
388287
  processExecutor;
388285
388288
  constructor(options) {
388289
+ this.disabled = options?.disabled ?? false;
388286
388290
  this.client = options?.client;
388287
388291
  this.defaultModel = options?.defaultModel;
388288
388292
  this.cwd = options?.cwd ?? process.cwd();
@@ -388329,6 +388333,8 @@ rm -- "$1"`, WslFileOperations2 = class {
388329
388333
  return results;
388330
388334
  }
388331
388335
  getHooksForEvent(event, context) {
388336
+ if (this.disabled)
388337
+ return [];
388332
388338
  const subject = context ? matchSubject(context) : "";
388333
388339
  const filtered = [...this.hooks.values()].filter((h2) => {
388334
388340
  if (h2.event !== event || !h2.enabled)
@@ -403568,6 +403574,7 @@ Complete the user's request by providing accurate, documentation-based guidance.
403568
403574
  "large_change",
403569
403575
  "many_files",
403570
403576
  "sensitive_path",
403577
+ "sensitive_content_path",
403571
403578
  "production_delete_or_rename",
403572
403579
  "patch_truncated",
403573
403580
  "not_git_repository",
@@ -403578,6 +403585,7 @@ Complete the user's request by providing accurate, documentation-based guidance.
403578
403585
  "review_output_invalid",
403579
403586
  "review_child_failed",
403580
403587
  "review_child_timed_out",
403588
+ "review_preempted_by_user",
403581
403589
  "parent_run_not_completed",
403582
403590
  "daemon_restarted"
403583
403591
  ];
@@ -475155,6 +475163,9 @@ class SessionEventPublisher {
475155
475163
  // ../../packages/server/src/session/export-session.ts
475156
475164
  import { mkdir as mkdir16, writeFile as writeFile10 } from "node:fs/promises";
475157
475165
  import { isAbsolute as isAbsolute11, join as join40 } from "node:path";
475166
+ function hasSensitiveInput(inputs) {
475167
+ return inputs.some((item) => item.metadata.sensitiveInput === true || item.metadata.autoReviewSensitive === true);
475168
+ }
475158
475169
  function partsForMessage(messageId, parts) {
475159
475170
  return parts.filter((part) => part.messageId === messageId).filter(isCommittedModelPart).sort((a, b) => a.seq - b.seq);
475160
475171
  }
@@ -475176,6 +475187,7 @@ function markdownFromParts(parts) {
475176
475187
  `);
475177
475188
  }
475178
475189
  function buildMarkdown(input) {
475190
+ const sensitiveSession = hasSensitiveInput(input.inputs);
475179
475191
  const lines = [
475180
475192
  "# Vykor Conversation Export",
475181
475193
  "",
@@ -475188,6 +475200,10 @@ function buildMarkdown(input) {
475188
475200
  ""
475189
475201
  ];
475190
475202
  for (const message of [...input.messages].sort((a, b) => a.seq - b.seq)) {
475203
+ if (sensitiveSession) {
475204
+ lines.push(`## ${message.role}`, "", REDACTED_CONTENT, "", "---", "");
475205
+ continue;
475206
+ }
475191
475207
  const messageParts = partsForMessage(message.id, input.parts);
475192
475208
  if (message.role === "user") {
475193
475209
  lines.push("## User", "", markdownFromParts(messageParts), "", "---", "");
@@ -475212,7 +475228,11 @@ function buildMarkdown(input) {
475212
475228
  `);
475213
475229
  }
475214
475230
  function buildJson(input) {
475231
+ const sensitiveSession = hasSensitiveInput(input.inputs);
475215
475232
  const messages = [...input.messages].sort((a, b) => a.seq - b.seq).map((message) => {
475233
+ if (sensitiveSession) {
475234
+ return { role: message.role, content: REDACTED_CONTENT, parts: [] };
475235
+ }
475216
475236
  const messageParts = partsForMessage(message.id, input.parts);
475217
475237
  if (message.role === "user" || message.role === "system") {
475218
475238
  return { role: message.role, content: textFromParts2(messageParts), parts: messageParts };
@@ -475235,7 +475255,7 @@ function buildJson(input) {
475235
475255
  model: input.session.model,
475236
475256
  exported_at: new Date().toISOString(),
475237
475257
  message_count: input.messages.length,
475238
- inputs: [...input.inputs].sort((a, b) => a.seq - b.seq),
475258
+ inputs: [...input.inputs].sort((a, b) => a.seq - b.seq).map((item) => sensitiveSession ? { ...item, content: REDACTED_CONTENT, items: [], attachments: [] } : item),
475239
475259
  messages
475240
475260
  }, null, 2);
475241
475261
  }
@@ -475256,6 +475276,7 @@ async function writeSessionExport(input) {
475256
475276
  messageCount: input.messages.length
475257
475277
  };
475258
475278
  }
475279
+ var REDACTED_CONTENT = "[redacted: sensitive content]";
475259
475280
  var init_export_session = __esm(() => {
475260
475281
  init_src();
475261
475282
  init_src4();
@@ -476794,7 +476815,12 @@ function assembleSessionRunServices(options) {
476794
476815
  },
476795
476816
  runtimeQueue: {
476796
476817
  hasRuntime: options.agentPool.configured,
476797
- enqueueRun: (run, inputId) => engine.runtimeBridge.enqueueRun(run, inputId),
476818
+ enqueueRun: (run, inputId) => {
476819
+ if (!run.metadata?.goalRunKind || run.metadata.goalRunKind === "user") {
476820
+ options.preemptAutoReview?.(run.sessionId);
476821
+ }
476822
+ return engine.runtimeBridge.enqueueRun(run, inputId);
476823
+ },
476798
476824
  runState: (sessionId, runId) => engine.runtimeBridge.runState(sessionId, runId),
476799
476825
  steer: (sessionId, input) => engine.runtimeBridge.steer(sessionId, input)
476800
476826
  },
@@ -477873,6 +477899,7 @@ var init_auto_review_result = __esm(() => {
477873
477899
  class SessionAutoReviewService {
477874
477900
  options;
477875
477901
  baselines = new Map;
477902
+ activeReviews = new Map;
477876
477903
  now;
477877
477904
  log;
477878
477905
  constructor(options) {
@@ -477882,6 +477909,9 @@ class SessionAutoReviewService {
477882
477909
  return;
477883
477910
  });
477884
477911
  }
477912
+ preemptForUserInput(sessionId) {
477913
+ this.activeReviews.get(sessionId)?.abort("user_input");
477914
+ }
477885
477915
  async captureBaseline(input) {
477886
477916
  if (input.mode === "off") {
477887
477917
  this.transition(input.sessionId, input.runId, {
@@ -477934,8 +477964,37 @@ class SessionAutoReviewService {
477934
477964
  finishedAt: this.now()
477935
477965
  });
477936
477966
  }
477967
+ const controller = new AbortController;
477968
+ this.activeReviews.set(input.sessionId, controller);
477969
+ const signal = AbortSignal.any([input.signal, controller.signal]);
477970
+ let onAbort;
477937
477971
  try {
477938
- const compared = await this.options.inspector.compare(input.cwd, entry.baseline);
477972
+ if (this.options.hasUserWork?.(input.sessionId))
477973
+ controller.abort("user_input");
477974
+ const interrupted = new Promise((resolve) => {
477975
+ onAbort = () => resolve("interrupted");
477976
+ if (signal.aborted)
477977
+ onAbort();
477978
+ else
477979
+ signal.addEventListener("abort", onAbort, { once: true });
477980
+ });
477981
+ const compared = signal.aborted ? "interrupted" : await Promise.race([
477982
+ this.options.inspector.compare(input.cwd, entry.baseline),
477983
+ interrupted
477984
+ ]);
477985
+ if (onAbort)
477986
+ signal.removeEventListener("abort", onAbort);
477987
+ if (compared === "interrupted" || signal.aborted) {
477988
+ const userPreempted = signal.reason === "user_input";
477989
+ return this.settle(input.sessionId, input.runId, {
477990
+ mode: entry.mode,
477991
+ riskLevel: "unknown",
477992
+ status: userPreempted ? "skipped" : "failed",
477993
+ reasons: [userPreempted ? "review_preempted_by_user" : "review_child_failed"],
477994
+ startedAt,
477995
+ finishedAt: this.now()
477996
+ });
477997
+ }
477939
477998
  if (isUnavailable(compared)) {
477940
477999
  return this.settle(input.sessionId, input.runId, {
477941
478000
  mode: entry.mode,
@@ -477946,7 +478005,7 @@ class SessionAutoReviewService {
477946
478005
  finishedAt: this.now()
477947
478006
  });
477948
478007
  }
477949
- return await this.runReview(input, entry.mode, compared, startedAt);
478008
+ return await this.runReview({ ...input, signal }, entry.mode, compared, startedAt);
477950
478009
  } catch (error) {
477951
478010
  this.log({ event: "auto_review.error", runId: input.runId, error: errorText(error) });
477952
478011
  return this.settle(input.sessionId, input.runId, {
@@ -477957,6 +478016,11 @@ class SessionAutoReviewService {
477957
478016
  startedAt,
477958
478017
  finishedAt: this.now()
477959
478018
  });
478019
+ } finally {
478020
+ if (onAbort)
478021
+ signal.removeEventListener("abort", onAbort);
478022
+ if (this.activeReviews.get(input.sessionId) === controller)
478023
+ this.activeReviews.delete(input.sessionId);
477960
478024
  }
477961
478025
  }
477962
478026
  async runReview(input, mode, changeSet, startedAt) {
@@ -478030,8 +478094,8 @@ class SessionAutoReviewService {
478030
478094
  return this.settle(input.sessionId, input.runId, {
478031
478095
  mode,
478032
478096
  riskLevel: decision.level,
478033
- status: "failed",
478034
- reasons: ["review_child_failed"],
478097
+ status: input.signal.reason === "user_input" ? "skipped" : "failed",
478098
+ reasons: [input.signal.reason === "user_input" ? "review_preempted_by_user" : "review_child_failed"],
478035
478099
  patchTruncated: changeSet.patchTruncated,
478036
478100
  ...invocationId ? { reviewTaskId: invocationId } : {},
478037
478101
  startedAt,
@@ -478039,6 +478103,19 @@ class SessionAutoReviewService {
478039
478103
  });
478040
478104
  }
478041
478105
  const finishedAt = this.now();
478106
+ if (input.signal.aborted) {
478107
+ const userPreempted = input.signal.reason === "user_input";
478108
+ return this.settle(input.sessionId, input.runId, {
478109
+ mode,
478110
+ riskLevel: decision.level,
478111
+ status: userPreempted ? "skipped" : "failed",
478112
+ reasons: [userPreempted ? "review_preempted_by_user" : "review_child_failed"],
478113
+ patchTruncated: changeSet.patchTruncated,
478114
+ ...invocationId !== undefined ? { reviewTaskId: invocationId } : {},
478115
+ startedAt,
478116
+ finishedAt
478117
+ });
478118
+ }
478042
478119
  if (childResult.status !== "completed") {
478043
478120
  const timedOut = childResult.failureKind === "timeout";
478044
478121
  return this.settle(input.sessionId, input.runId, {
@@ -478290,14 +478367,14 @@ class DefaultGitRunChangeInspector {
478290
478367
  return unavailable4("preexisting_dirty_overlap");
478291
478368
  }
478292
478369
  }
478293
- const newPaths = currentPaths.filter((path) => !(path in baseline.dirty));
478294
- const contextPaths = first.entries.map((entry) => entry.oldPath).filter((path) => path !== undefined && !(path in baseline.dirty));
478370
+ const newPaths = currentPaths.filter((path) => !Object.hasOwn(baseline.dirty, path));
478371
+ const contextPaths = first.entries.map((entry) => entry.oldPath).filter((path) => path !== undefined && !Object.hasOwn(baseline.dirty, path));
478295
478372
  result = await this.buildWorktreeChangeSet(cwd, first, newPaths, contextPaths);
478296
478373
  } else {
478297
478374
  const ancestor = await this.isAncestor(cwd, baseline.head, first.head);
478298
478375
  if (!ancestor)
478299
478376
  return unavailable4("non_linear_head_change");
478300
- const currentDirty = {};
478377
+ const currentDirty = Object.create(null);
478301
478378
  for (const path of currentPaths)
478302
478379
  currentDirty[path] = collected.entries[path];
478303
478380
  if (!sameDirtyMap(currentDirty, baseline.dirty)) {
@@ -478305,6 +478382,8 @@ class DefaultGitRunChangeInspector {
478305
478382
  }
478306
478383
  result = await this.buildCommitChangeSet(cwd, baseline.head, first.head);
478307
478384
  }
478385
+ if (result && isUnavailable2(result))
478386
+ return result;
478308
478387
  if (!result)
478309
478388
  return unavailable4("git_inspection_failed");
478310
478389
  const second = await readRepoState(this.executor, cwd);
@@ -478323,6 +478402,8 @@ class DefaultGitRunChangeInspector {
478323
478402
  const nameStatus = await this.readNameStatus(cwd, ["HEAD", "--", ...pathspec]);
478324
478403
  if (!nameStatus)
478325
478404
  return;
478405
+ if (hasSensitiveContentPath(newPaths, nameStatus))
478406
+ return unavailable4("sensitive_content_path");
478326
478407
  const numstat = await this.readNumstat(cwd, ["HEAD", "--", ...pathspec]);
478327
478408
  if (!numstat)
478328
478409
  return;
@@ -478374,6 +478455,9 @@ class DefaultGitRunChangeInspector {
478374
478455
  const nameStatus = await this.readNameStatus(cwd, [baseHead, head]);
478375
478456
  if (!nameStatus)
478376
478457
  return;
478458
+ if (hasSensitiveContentPath([...nameStatus.keys()], nameStatus)) {
478459
+ return unavailable4("sensitive_content_path");
478460
+ }
478377
478461
  const numstat = await this.readNumstat(cwd, [baseHead, head]);
478378
478462
  if (!numstat)
478379
478463
  return;
@@ -478400,8 +478484,8 @@ class DefaultGitRunChangeInspector {
478400
478484
  };
478401
478485
  }
478402
478486
  async collect(state, cwd, paths) {
478403
- const entries = {};
478404
- const hashes = {};
478487
+ const entries = Object.create(null);
478488
+ const hashes = Object.create(null);
478405
478489
  for (const path of paths) {
478406
478490
  const status = state.statusByPath.get(path) ?? "";
478407
478491
  if (isUnmergedStatus(status))
@@ -478449,6 +478533,19 @@ class DefaultGitRunChangeInspector {
478449
478533
  return parsed?.get(path) ?? 0;
478450
478534
  }
478451
478535
  }
478536
+ function isUnavailable2(value) {
478537
+ return value.attribution === "unavailable";
478538
+ }
478539
+ function hasSensitiveContentPath(paths, nameStatus) {
478540
+ return paths.some((path) => {
478541
+ const oldPath = nameStatus.get(path)?.oldPath;
478542
+ return isSensitiveContentPath(path) || oldPath !== undefined && isSensitiveContentPath(oldPath);
478543
+ });
478544
+ }
478545
+ function isSensitiveContentPath(path) {
478546
+ const name = path.replace(/\\/g, "/").split("/").at(-1)?.toLowerCase() ?? "";
478547
+ return /^\.env(?:\.|$)/.test(name) || name === ".npmrc" || name === ".pypirc" || name === "credentials.json" || /\.(?:pem|key|p12|pfx|jks|keystore)$/.test(name);
478548
+ }
478452
478549
  function unavailable4(reason) {
478453
478550
  return { attribution: "unavailable", reason };
478454
478551
  }
@@ -576576,6 +576673,7 @@ class DaemonApplication {
576576
576673
  session: store,
576577
576674
  events: this.eventPublisher,
576578
576675
  inspector: createGitRunChangeInspector(),
576676
+ hasUserWork: (sessionId) => this.runControl.hasUserWork(sessionId),
576579
576677
  log: (entry) => {
576580
576678
  options.log({
576581
576679
  level: "warn",
@@ -576611,6 +576709,7 @@ class DaemonApplication {
576611
576709
  agentPool: this.agentPool,
576612
576710
  runExecutor,
576613
576711
  events: this.eventPublisher,
576712
+ preemptAutoReview: (sessionId) => autoReview.preemptForUserInput(sessionId),
576614
576713
  attachmentLimits: this.attachments.limits,
576615
576714
  materializeSteerInput,
576616
576715
  assertReady: () => this.assertReady(),
@@ -584611,4 +584710,4 @@ program.command("doctor").description("Check environment and dependencies").acti
584611
584710
  });
584612
584711
  program.parse();
584613
584712
 
584614
- //# debugId=38334AAE109FB55C64756E2164756E21
584713
+ //# debugId=BB50289069DAC80B64756E2164756E21