@defai.digital/automatosx 11.2.9 → 11.3.0

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
@@ -19,7 +19,7 @@ import { Mutex } from 'async-mutex';
19
19
  import { promisify } from 'util';
20
20
  import yargs from 'yargs';
21
21
  import { hideBin } from 'yargs/helpers';
22
- import { randomUUID, createHash } from 'crypto';
22
+ import crypto2, { randomUUID, createHash } from 'crypto';
23
23
  import * as yaml4 from 'js-yaml';
24
24
  import yaml4__default, { load, dump } from 'js-yaml';
25
25
  import Table from 'cli-table3';
@@ -2943,8 +2943,18 @@ var init_base_provider = __esm({
2943
2943
  /**
2944
2944
  * Check if CLI is available - Template method pattern
2945
2945
  * Uses getCLICommand() to determine which CLI to check
2946
+ *
2947
+ * v11.2.9 Fix: Always return true in mock mode (AX_MOCK_PROVIDERS=true)
2948
+ * This allows integration tests in CI to run without installing actual provider CLIs
2946
2949
  */
2947
2950
  async checkCLIAvailable() {
2951
+ if (process.env.AX_MOCK_PROVIDERS === "true") {
2952
+ logger.debug(`${this.getCLICommand()} CLI availability check (mock mode)`, {
2953
+ available: true,
2954
+ mockMode: true
2955
+ });
2956
+ return true;
2957
+ }
2948
2958
  try {
2949
2959
  const cliCommand2 = this.getCLICommand();
2950
2960
  const result = findOnPath(cliCommand2);
@@ -9263,7 +9273,7 @@ var PRECOMPILED_CONFIG = {
9263
9273
  "enableFreeTierPrioritization": true,
9264
9274
  "enableWorkloadAwareRouting": true
9265
9275
  },
9266
- "version": "11.2.9"
9276
+ "version": "11.3.0"
9267
9277
  };
9268
9278
 
9269
9279
  // src/core/config/schemas.ts
@@ -22176,8 +22186,8 @@ var ProjectContextLoader = class {
22176
22186
  const projectMatch = markdown.match(/>\s*Project:\s*(.+?)$/im);
22177
22187
  if (projectMatch && projectMatch[1]) {
22178
22188
  const parts = projectMatch[1].trim().split(/\s+v/);
22179
- metadata.name = parts[0];
22180
- if (parts[1]) {
22189
+ metadata.name = parts[0] || "";
22190
+ if (parts.length > 1 && parts[1]) {
22181
22191
  metadata.version = parts[1];
22182
22192
  }
22183
22193
  }
@@ -36225,10 +36235,10 @@ var runCommand = {
36225
36235
  }).positional("task", {
36226
36236
  describe: "Task to execute",
36227
36237
  type: "string"
36228
- }).option("no-auto-select", {
36229
- describe: "Disable agent auto-selection (v11.1.0+)",
36238
+ }).option("auto-select", {
36239
+ describe: "Enable agent auto-selection when agent not found (v11.1.0+)",
36230
36240
  type: "boolean",
36231
- default: false
36241
+ default: true
36232
36242
  }).option("provider", {
36233
36243
  describe: "Override provider (claude, gemini, openai)",
36234
36244
  type: "string"
@@ -36370,7 +36380,7 @@ var runCommand = {
36370
36380
  console.log(chalk5.gray(' ax run backend "implement API" # uses specified agent'));
36371
36381
  process.exit(1);
36372
36382
  }
36373
- if (!agentProvided && argv.noAutoSelect) {
36383
+ if (!agentProvided && argv.autoSelect === false) {
36374
36384
  console.log(chalk5.red.bold("\n\u274C Error: Agent name is required when --no-auto-select is used\n"));
36375
36385
  console.log(chalk5.gray("Usage: ax run <agent> <task> --no-auto-select"));
36376
36386
  process.exit(1);
@@ -36505,7 +36515,7 @@ var runCommand = {
36505
36515
  }
36506
36516
  }
36507
36517
  } catch (error) {
36508
- if (argv.noAutoSelect) {
36518
+ if (argv.autoSelect === false) {
36509
36519
  console.error(chalk5.red.bold(`
36510
36520
  \u274C Agent not found: ${actualAgent}
36511
36521
  `));
@@ -44867,24 +44877,24 @@ async function handleList(config, argv) {
44867
44877
  });
44868
44878
  }
44869
44879
  }
44870
- let displayProviders = argv.available ? providers.filter((p) => p.enabled && !p.limitInfo?.isBlocked) : providers;
44880
+ let displayProviders2 = argv.available ? providers.filter((p) => p.enabled && !p.limitInfo?.isBlocked) : providers;
44871
44881
  switch (argv.sort) {
44872
44882
  case "cost":
44873
- displayProviders.sort((a, b) => {
44883
+ displayProviders2.sort((a, b) => {
44874
44884
  const costA = a.metadata ? (a.metadata.costPerToken.input + a.metadata.costPerToken.output) / 2 : Infinity;
44875
44885
  const costB = b.metadata ? (b.metadata.costPerToken.input + b.metadata.costPerToken.output) / 2 : Infinity;
44876
44886
  return costA - costB;
44877
44887
  });
44878
44888
  break;
44879
44889
  case "latency":
44880
- displayProviders.sort((a, b) => {
44890
+ displayProviders2.sort((a, b) => {
44881
44891
  const latA = a.metadata?.latencyEstimate.p95 || Infinity;
44882
44892
  const latB = b.metadata?.latencyEstimate.p95 || Infinity;
44883
44893
  return latA - latB;
44884
44894
  });
44885
44895
  break;
44886
44896
  case "reliability":
44887
- displayProviders.sort((a, b) => {
44897
+ displayProviders2.sort((a, b) => {
44888
44898
  const relA = a.metadata?.reliability.availability || 0;
44889
44899
  const relB = b.metadata?.reliability.availability || 0;
44890
44900
  return relB - relA;
@@ -44892,15 +44902,15 @@ async function handleList(config, argv) {
44892
44902
  break;
44893
44903
  case "priority":
44894
44904
  default:
44895
- displayProviders.sort((a, b) => a.priority - b.priority);
44905
+ displayProviders2.sort((a, b) => a.priority - b.priority);
44896
44906
  break;
44897
44907
  }
44898
44908
  if (argv.json) {
44899
- console.log(JSON.stringify({ providers: displayProviders }, null, 2));
44909
+ console.log(JSON.stringify({ providers: displayProviders2 }, null, 2));
44900
44910
  return;
44901
44911
  }
44902
44912
  console.log(chalk5.gray("Provider Status & Metadata:\n"));
44903
- for (const provider of displayProviders) {
44913
+ for (const provider of displayProviders2) {
44904
44914
  const status = provider.enabled ? provider.limitInfo?.isBlocked ? chalk5.red("\u25CF BLOCKED") : chalk5.green("\u25CF ENABLED") : chalk5.gray("\u25CB DISABLED");
44905
44915
  console.log(`${status} ${chalk5.bold(provider.name)} ${chalk5.gray(`(priority: ${provider.priority})`)}`);
44906
44916
  if (provider.metadata && argv.verbose) {
@@ -46147,9 +46157,11 @@ async function checkDiskSpace(workingDir, verbose) {
46147
46157
  timeout: 5e3
46148
46158
  });
46149
46159
  const parts = dfOutput.trim().split(/\s+/);
46150
- const availableKB = parseInt(parts[3] || "0", 10);
46151
- const availableMB = Math.round(availableKB / 1024);
46152
- const availableGB = (availableKB / (1024 * 1024)).toFixed(2);
46160
+ const rawAvailable = parts.length > 3 ? parts[3] : "0";
46161
+ const availableKB = parseInt(rawAvailable || "0", 10);
46162
+ const safeAvailableKB = isNaN(availableKB) ? 0 : availableKB;
46163
+ const availableMB = Math.round(safeAvailableKB / 1024);
46164
+ const availableGB = (safeAvailableKB / (1024 * 1024)).toFixed(2);
46153
46165
  const hasEnoughSpace = availableMB > 100;
46154
46166
  results.push({
46155
46167
  name: "Available Disk Space",
@@ -48519,6 +48531,2880 @@ var uninstallCommand = {
48519
48531
  }
48520
48532
  };
48521
48533
 
48534
+ // src/cli/commands/mode.ts
48535
+ init_esm_shims();
48536
+ init_logger();
48537
+
48538
+ // src/core/workflow/index.ts
48539
+ init_esm_shims();
48540
+
48541
+ // src/core/workflow/workflow-mode.ts
48542
+ init_esm_shims();
48543
+ var WorkflowModeSchema = z.enum(["default", "plan", "iterate", "review"]);
48544
+ z.object({
48545
+ name: WorkflowModeSchema,
48546
+ description: z.string(),
48547
+ displayName: z.string(),
48548
+ allowedTools: z.array(z.string()).optional(),
48549
+ blockedTools: z.array(z.string()).optional(),
48550
+ systemInstructions: z.string(),
48551
+ allowNesting: z.boolean(),
48552
+ maxNestingDepth: z.number().int().positive().optional(),
48553
+ autoExitConditions: z.object({
48554
+ maxTurns: z.number().int().positive().optional(),
48555
+ onToolUse: z.array(z.string()).optional(),
48556
+ onKeywords: z.array(z.string()).optional()
48557
+ }).optional()
48558
+ });
48559
+ var WRITE_TOOLS = [
48560
+ "Write",
48561
+ "Edit",
48562
+ "NotebookEdit",
48563
+ "Bash"
48564
+ ];
48565
+ var DEFAULT_MODE_CONFIG = {
48566
+ name: "default",
48567
+ displayName: "Default",
48568
+ description: "Standard operation mode with all tools available",
48569
+ systemInstructions: "",
48570
+ allowNesting: true,
48571
+ maxNestingDepth: 3
48572
+ };
48573
+ var PLAN_MODE_CONFIG = {
48574
+ name: "plan",
48575
+ displayName: "Plan Mode",
48576
+ description: "Planning mode - read-only exploration without code modifications",
48577
+ blockedTools: [...WRITE_TOOLS],
48578
+ systemInstructions: `## Plan Mode Active
48579
+
48580
+ You are in **Plan Mode**. This mode is for exploration and planning only.
48581
+
48582
+ **Restrictions:**
48583
+ - You CANNOT use Write, Edit, or Bash tools that modify files
48584
+ - Focus on reading, searching, and understanding the codebase
48585
+ - Create a comprehensive plan before implementation
48586
+
48587
+ **Your Goals:**
48588
+ 1. Explore the codebase to understand existing patterns
48589
+ 2. Identify files that need to be modified
48590
+ 3. Design an implementation approach
48591
+ 4. Document your plan clearly
48592
+ 5. Use ExitPlanMode when ready to implement
48593
+
48594
+ **Remember:** No code modifications in this mode. Plan first, implement later.`,
48595
+ allowNesting: false,
48596
+ autoExitConditions: {
48597
+ onToolUse: ["ExitPlanMode"]
48598
+ }
48599
+ };
48600
+ var ITERATE_MODE_CONFIG = {
48601
+ name: "iterate",
48602
+ displayName: "Iterate Mode",
48603
+ description: "Continuous iteration mode for implementation with automatic continuation",
48604
+ systemInstructions: `## Iterate Mode Active
48605
+
48606
+ You are in **Iterate Mode**. This mode enables continuous task execution.
48607
+
48608
+ **Behavior:**
48609
+ - Continue working until the task is complete
48610
+ - After each step, assess progress and continue
48611
+ - Don't stop to ask for confirmation unless critical
48612
+ - Mark todos as completed as you finish them
48613
+
48614
+ **Guidelines:**
48615
+ 1. Work through tasks systematically
48616
+ 2. Test changes as you go when possible
48617
+ 3. Update todo list to track progress
48618
+ 4. Only pause for critical decisions or blockers
48619
+
48620
+ **Remember:** Keep iterating until the task is done or you hit a blocker.`,
48621
+ allowNesting: true,
48622
+ maxNestingDepth: 2
48623
+ };
48624
+ var REVIEW_MODE_CONFIG = {
48625
+ name: "review",
48626
+ displayName: "Review Mode",
48627
+ description: "Code review mode - analyze code quality, security, and best practices",
48628
+ blockedTools: [...WRITE_TOOLS],
48629
+ systemInstructions: `## Review Mode Active
48630
+
48631
+ You are in **Review Mode**. This mode is for code review and analysis.
48632
+
48633
+ **Focus Areas:**
48634
+ - Code quality and readability
48635
+ - Security vulnerabilities (OWASP Top 10)
48636
+ - Performance issues
48637
+ - Best practices and patterns
48638
+ - Test coverage gaps
48639
+
48640
+ **Output Format:**
48641
+ Provide structured feedback:
48642
+ 1. **Critical Issues** - Must fix before merge
48643
+ 2. **Warnings** - Should address
48644
+ 3. **Suggestions** - Nice to have improvements
48645
+ 4. **Positive Notes** - Good patterns observed
48646
+
48647
+ **Remember:** No code modifications. Provide actionable feedback only.`,
48648
+ allowNesting: false
48649
+ };
48650
+ var WORKFLOW_MODE_CONFIGS = {
48651
+ default: DEFAULT_MODE_CONFIG,
48652
+ plan: PLAN_MODE_CONFIG,
48653
+ iterate: ITERATE_MODE_CONFIG,
48654
+ review: REVIEW_MODE_CONFIG
48655
+ };
48656
+ function getWorkflowModeConfig(mode) {
48657
+ return WORKFLOW_MODE_CONFIGS[mode];
48658
+ }
48659
+ function isToolAllowedInMode(tool, mode) {
48660
+ const config = getWorkflowModeConfig(mode);
48661
+ if (config.allowedTools && config.allowedTools.length > 0) {
48662
+ return config.allowedTools.includes(tool);
48663
+ }
48664
+ if (config.blockedTools && config.blockedTools.length > 0) {
48665
+ return !config.blockedTools.includes(tool);
48666
+ }
48667
+ return true;
48668
+ }
48669
+ function isValidWorkflowMode(mode) {
48670
+ return mode in WORKFLOW_MODE_CONFIGS;
48671
+ }
48672
+ var WORKFLOW_MODES = WORKFLOW_MODE_CONFIGS;
48673
+
48674
+ // src/core/workflow/workflow-mode-manager.ts
48675
+ init_esm_shims();
48676
+ init_logger();
48677
+ var WorkflowModeManager = class {
48678
+ name = "workflow-mode";
48679
+ modeStack = [];
48680
+ transitionListeners = /* @__PURE__ */ new Set();
48681
+ turnCount = 0;
48682
+ constructor(initialMode = "default") {
48683
+ this.modeStack.push({
48684
+ mode: initialMode,
48685
+ enteredAt: Date.now(),
48686
+ enteredAtTurn: 0,
48687
+ reason: "initial"
48688
+ });
48689
+ logger.debug("WorkflowModeManager initialized", {
48690
+ initialMode
48691
+ });
48692
+ }
48693
+ /**
48694
+ * Get the current active mode
48695
+ */
48696
+ getCurrentMode() {
48697
+ const top = this.modeStack[this.modeStack.length - 1];
48698
+ return top?.mode ?? "default";
48699
+ }
48700
+ /**
48701
+ * Get the current mode configuration
48702
+ */
48703
+ getCurrentModeConfig() {
48704
+ const mode = this.getCurrentMode();
48705
+ const entry = this.modeStack[this.modeStack.length - 1];
48706
+ const baseConfig = getWorkflowModeConfig(mode);
48707
+ if (entry?.customConfig) {
48708
+ return {
48709
+ ...baseConfig,
48710
+ ...entry.customConfig,
48711
+ // Deep merge for nested objects
48712
+ autoExitConditions: {
48713
+ ...baseConfig.autoExitConditions,
48714
+ ...entry.customConfig.autoExitConditions
48715
+ }
48716
+ };
48717
+ }
48718
+ return baseConfig;
48719
+ }
48720
+ /**
48721
+ * Get the full mode stack
48722
+ */
48723
+ getModeStack() {
48724
+ return [...this.modeStack];
48725
+ }
48726
+ /**
48727
+ * Get the current stack depth
48728
+ */
48729
+ getStackDepth() {
48730
+ return this.modeStack.length;
48731
+ }
48732
+ /**
48733
+ * Push a new mode onto the stack
48734
+ */
48735
+ pushMode(mode, options) {
48736
+ const currentConfig = this.getCurrentModeConfig();
48737
+ if (!currentConfig.allowNesting) {
48738
+ logger.warn("Cannot push mode: current mode does not allow nesting", {
48739
+ currentMode: this.getCurrentMode(),
48740
+ attemptedMode: mode
48741
+ });
48742
+ return false;
48743
+ }
48744
+ const maxDepth = currentConfig.maxNestingDepth ?? 3;
48745
+ if (this.modeStack.length >= maxDepth) {
48746
+ logger.warn("Cannot push mode: max nesting depth reached", {
48747
+ currentDepth: this.modeStack.length,
48748
+ maxDepth
48749
+ });
48750
+ return false;
48751
+ }
48752
+ const previousMode = this.getCurrentMode();
48753
+ this.modeStack.push({
48754
+ mode,
48755
+ enteredAt: Date.now(),
48756
+ enteredAtTurn: this.turnCount,
48757
+ customConfig: options?.customConfig,
48758
+ reason: options?.reason
48759
+ });
48760
+ this.emitTransition({
48761
+ from: previousMode,
48762
+ to: mode,
48763
+ type: "push",
48764
+ timestamp: Date.now(),
48765
+ reason: options?.reason
48766
+ });
48767
+ logger.info("Pushed workflow mode", {
48768
+ from: previousMode,
48769
+ to: mode,
48770
+ stackDepth: this.modeStack.length,
48771
+ reason: options?.reason
48772
+ });
48773
+ return true;
48774
+ }
48775
+ /**
48776
+ * Pop the current mode from the stack
48777
+ */
48778
+ popMode(reason) {
48779
+ if (this.modeStack.length <= 1) {
48780
+ logger.warn("Cannot pop mode: at base level");
48781
+ return null;
48782
+ }
48783
+ const popped = this.modeStack.pop();
48784
+ const newMode = this.getCurrentMode();
48785
+ if (popped) {
48786
+ this.emitTransition({
48787
+ from: popped.mode,
48788
+ to: newMode,
48789
+ type: "pop",
48790
+ timestamp: Date.now(),
48791
+ reason
48792
+ });
48793
+ logger.info("Popped workflow mode", {
48794
+ from: popped.mode,
48795
+ to: newMode,
48796
+ stackDepth: this.modeStack.length,
48797
+ reason
48798
+ });
48799
+ }
48800
+ return popped?.mode ?? null;
48801
+ }
48802
+ /**
48803
+ * Replace the current mode (pop then push)
48804
+ */
48805
+ replaceMode(mode, options) {
48806
+ const previousMode = this.getCurrentMode();
48807
+ if (this.modeStack.length === 1) {
48808
+ this.modeStack[0] = {
48809
+ mode,
48810
+ enteredAt: Date.now(),
48811
+ enteredAtTurn: this.turnCount,
48812
+ customConfig: options?.customConfig,
48813
+ reason: options?.reason
48814
+ };
48815
+ } else {
48816
+ this.modeStack.pop();
48817
+ this.modeStack.push({
48818
+ mode,
48819
+ enteredAt: Date.now(),
48820
+ enteredAtTurn: this.turnCount,
48821
+ customConfig: options?.customConfig,
48822
+ reason: options?.reason
48823
+ });
48824
+ }
48825
+ this.emitTransition({
48826
+ from: previousMode,
48827
+ to: mode,
48828
+ type: "replace",
48829
+ timestamp: Date.now(),
48830
+ reason: options?.reason
48831
+ });
48832
+ logger.info("Replaced workflow mode", {
48833
+ from: previousMode,
48834
+ to: mode,
48835
+ reason: options?.reason
48836
+ });
48837
+ return true;
48838
+ }
48839
+ /**
48840
+ * Set mode directly (clears stack and sets new base mode)
48841
+ */
48842
+ setMode(mode, options) {
48843
+ const previousMode = this.getCurrentMode();
48844
+ this.modeStack = [{
48845
+ mode,
48846
+ enteredAt: Date.now(),
48847
+ enteredAtTurn: this.turnCount,
48848
+ customConfig: options?.customConfig,
48849
+ reason: options?.reason
48850
+ }];
48851
+ this.emitTransition({
48852
+ from: previousMode,
48853
+ to: mode,
48854
+ type: "replace",
48855
+ timestamp: Date.now(),
48856
+ reason: options?.reason
48857
+ });
48858
+ logger.info("Set workflow mode", {
48859
+ from: previousMode,
48860
+ to: mode,
48861
+ reason: options?.reason
48862
+ });
48863
+ }
48864
+ /**
48865
+ * Check if a tool is allowed in the current mode
48866
+ */
48867
+ isToolAllowed(tool) {
48868
+ return isToolAllowedInMode(tool, this.getCurrentMode());
48869
+ }
48870
+ /**
48871
+ * Get list of blocked tools in current mode
48872
+ */
48873
+ getBlockedTools() {
48874
+ const config = this.getCurrentModeConfig();
48875
+ return config.blockedTools || [];
48876
+ }
48877
+ /**
48878
+ * Filter a list of tools based on current mode
48879
+ */
48880
+ filterTools(tools) {
48881
+ return tools.filter((tool) => this.isToolAllowed(tool.name));
48882
+ }
48883
+ /**
48884
+ * Update turn count (for auto-exit tracking)
48885
+ */
48886
+ updateTurnCount(turn) {
48887
+ this.turnCount = turn;
48888
+ this.checkAutoExit();
48889
+ }
48890
+ /**
48891
+ * Check and handle auto-exit conditions
48892
+ */
48893
+ checkAutoExit() {
48894
+ const config = this.getCurrentModeConfig();
48895
+ const entry = this.modeStack[this.modeStack.length - 1];
48896
+ if (!config.autoExitConditions || !entry) return;
48897
+ if (config.autoExitConditions.maxTurns) {
48898
+ const turnsInMode = this.turnCount - entry.enteredAtTurn;
48899
+ if (turnsInMode >= config.autoExitConditions.maxTurns) {
48900
+ logger.info("Auto-exiting mode due to max turns", {
48901
+ mode: this.getCurrentMode(),
48902
+ turnsInMode,
48903
+ maxTurns: config.autoExitConditions.maxTurns
48904
+ });
48905
+ this.popMode("max_turns_reached");
48906
+ }
48907
+ }
48908
+ }
48909
+ /**
48910
+ * Notify that a tool was used (for auto-exit on tool use)
48911
+ */
48912
+ notifyToolUsed(tool) {
48913
+ const config = this.getCurrentModeConfig();
48914
+ if (config.autoExitConditions?.onToolUse?.includes(tool)) {
48915
+ logger.info("Auto-exiting mode due to tool use", {
48916
+ mode: this.getCurrentMode(),
48917
+ tool
48918
+ });
48919
+ this.popMode(`tool_used:${tool}`);
48920
+ }
48921
+ }
48922
+ /**
48923
+ * Add a mode transition listener
48924
+ */
48925
+ onTransition(listener) {
48926
+ this.transitionListeners.add(listener);
48927
+ return () => this.transitionListeners.delete(listener);
48928
+ }
48929
+ /**
48930
+ * Emit a transition event to all listeners
48931
+ */
48932
+ emitTransition(event) {
48933
+ for (const listener of this.transitionListeners) {
48934
+ try {
48935
+ listener(event);
48936
+ } catch (error) {
48937
+ logger.error("Mode transition listener error", {
48938
+ error: error instanceof Error ? error.message : String(error)
48939
+ });
48940
+ }
48941
+ }
48942
+ }
48943
+ // InstructionProvider implementation
48944
+ /**
48945
+ * Check if mode instructions should be generated
48946
+ */
48947
+ shouldGenerate(context) {
48948
+ return this.getCurrentMode() !== "default";
48949
+ }
48950
+ /**
48951
+ * Get mode-specific instructions
48952
+ */
48953
+ async getInstructions(context) {
48954
+ const config = this.getCurrentModeConfig();
48955
+ const instructions = [];
48956
+ if (config.systemInstructions && config.systemInstructions.length > 0) {
48957
+ instructions.push({
48958
+ type: "mode",
48959
+ priority: "high",
48960
+ content: config.systemInstructions,
48961
+ source: "automatosx",
48962
+ createdAt: Date.now(),
48963
+ id: `mode-${config.name}-${Date.now()}`
48964
+ });
48965
+ }
48966
+ if (config.blockedTools && config.blockedTools.length > 0) {
48967
+ instructions.push({
48968
+ type: "mode",
48969
+ priority: "critical",
48970
+ content: `**Tool Restrictions:** The following tools are NOT available in ${config.displayName}: ${config.blockedTools.join(", ")}`,
48971
+ source: "automatosx",
48972
+ createdAt: Date.now(),
48973
+ id: `mode-blocked-tools-${Date.now()}`
48974
+ });
48975
+ }
48976
+ return instructions;
48977
+ }
48978
+ /**
48979
+ * Reset to default state
48980
+ */
48981
+ reset() {
48982
+ const previousMode = this.getCurrentMode();
48983
+ this.modeStack = [{
48984
+ mode: "default",
48985
+ enteredAt: Date.now(),
48986
+ enteredAtTurn: 0,
48987
+ reason: "reset"
48988
+ }];
48989
+ this.turnCount = 0;
48990
+ if (previousMode !== "default") {
48991
+ this.emitTransition({
48992
+ from: previousMode,
48993
+ to: "default",
48994
+ type: "replace",
48995
+ timestamp: Date.now(),
48996
+ reason: "reset"
48997
+ });
48998
+ }
48999
+ logger.debug("WorkflowModeManager reset");
49000
+ }
49001
+ /**
49002
+ * Get status information for debugging
49003
+ */
49004
+ getStatus() {
49005
+ return {
49006
+ currentMode: this.getCurrentMode(),
49007
+ stackDepth: this.modeStack.length,
49008
+ stack: this.modeStack.map((entry) => ({
49009
+ mode: entry.mode,
49010
+ enteredAt: entry.enteredAt,
49011
+ reason: entry.reason
49012
+ })),
49013
+ blockedTools: this.getBlockedTools(),
49014
+ turnCount: this.turnCount
49015
+ };
49016
+ }
49017
+ };
49018
+
49019
+ // src/cli/commands/mode.ts
49020
+ var modeCommand = {
49021
+ command: "mode [mode]",
49022
+ describe: "Manage workflow modes for embedded instructions (v11.3.0)",
49023
+ builder: (yargs2) => {
49024
+ return yargs2.positional("mode", {
49025
+ describe: "Workflow mode to set (default, plan, iterate, review)",
49026
+ type: "string"
49027
+ }).option("list", {
49028
+ alias: "l",
49029
+ describe: "List available workflow modes",
49030
+ type: "boolean",
49031
+ default: false
49032
+ }).option("status", {
49033
+ alias: "s",
49034
+ describe: "Show current workflow mode status",
49035
+ type: "boolean",
49036
+ default: false
49037
+ }).example("$0 mode plan", "Enter plan mode (restricts code-modifying tools)").example("$0 mode iterate", "Enter iterate mode (for autonomous execution)").example("$0 mode default", "Return to default mode").example("$0 mode --list", "List all available modes").example("$0 mode --status", "Show current mode status");
49038
+ },
49039
+ handler: async (argv) => {
49040
+ try {
49041
+ if (argv.list) {
49042
+ displayModeList();
49043
+ return;
49044
+ }
49045
+ if (argv.status || !argv.mode) {
49046
+ displayModeStatus();
49047
+ return;
49048
+ }
49049
+ const modeName = argv.mode.toLowerCase();
49050
+ if (!isValidWorkflowMode(modeName)) {
49051
+ console.error(chalk5.red.bold(`
49052
+ \u274C Invalid workflow mode: ${argv.mode}
49053
+ `));
49054
+ console.log(chalk5.gray("Available modes:"));
49055
+ Object.keys(WORKFLOW_MODES).forEach((mode) => {
49056
+ console.log(chalk5.cyan(` \u2022 ${mode}`));
49057
+ });
49058
+ console.log();
49059
+ process.exit(1);
49060
+ }
49061
+ const modeConfig = WORKFLOW_MODES[modeName];
49062
+ console.log(chalk5.green.bold(`
49063
+ \u2705 Workflow mode set to: ${modeName}
49064
+ `));
49065
+ console.log(chalk5.gray(`Description: ${modeConfig.description}`));
49066
+ if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
49067
+ console.log(chalk5.yellow("\nRestricted tools in this mode:"));
49068
+ modeConfig.blockedTools.forEach((tool) => {
49069
+ console.log(chalk5.yellow(` \u2022 ${tool}`));
49070
+ });
49071
+ }
49072
+ if (modeConfig.allowedTools && modeConfig.allowedTools.length > 0) {
49073
+ console.log(chalk5.cyan("\nAllowed tools in this mode:"));
49074
+ modeConfig.allowedTools.forEach((tool) => {
49075
+ console.log(chalk5.cyan(` \u2022 ${tool}`));
49076
+ });
49077
+ }
49078
+ console.log();
49079
+ console.log(chalk5.gray("Note: Mode setting applies to the current session."));
49080
+ console.log(chalk5.gray("Use with --iterate flag in ax run for persistent mode.\n"));
49081
+ logger.info("Workflow mode set", { mode: modeName });
49082
+ } catch (error) {
49083
+ const err = error instanceof Error ? error : new Error(String(error));
49084
+ console.error(chalk5.red.bold(`
49085
+ \u274C Error: ${err.message}
49086
+ `));
49087
+ logger.error("Mode command failed", { error: err.message });
49088
+ process.exit(1);
49089
+ }
49090
+ }
49091
+ };
49092
+ function displayModeList() {
49093
+ console.log(chalk5.blue.bold("\n\u{1F4CB} Available Workflow Modes\n"));
49094
+ console.log(chalk5.dim("\u2500".repeat(60)));
49095
+ for (const [name, config] of Object.entries(WORKFLOW_MODES)) {
49096
+ console.log();
49097
+ console.log(chalk5.cyan.bold(` ${name}`));
49098
+ console.log(chalk5.gray(` ${config.description}`));
49099
+ if (config.blockedTools && config.blockedTools.length > 0) {
49100
+ console.log(chalk5.yellow(` Blocked: ${config.blockedTools.join(", ")}`));
49101
+ }
49102
+ if (config.maxNestingDepth !== void 0) {
49103
+ console.log(chalk5.gray(` Max nesting depth: ${config.maxNestingDepth}`));
49104
+ }
49105
+ }
49106
+ console.log();
49107
+ console.log(chalk5.dim("\u2500".repeat(60)));
49108
+ console.log(chalk5.gray("\nUsage: ax mode <mode-name>"));
49109
+ console.log(chalk5.gray("Example: ax mode plan\n"));
49110
+ }
49111
+ function displayModeStatus() {
49112
+ const currentMode = "default";
49113
+ const modeConfig = WORKFLOW_MODES[currentMode];
49114
+ console.log(chalk5.blue.bold("\n\u{1F4CA} Workflow Mode Status\n"));
49115
+ console.log(chalk5.dim("\u2500".repeat(50)));
49116
+ console.log(` Current mode: ${chalk5.cyan.bold(currentMode)}`);
49117
+ console.log(` Description: ${chalk5.gray(modeConfig.description)}`);
49118
+ if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
49119
+ console.log(` Blocked tools: ${chalk5.yellow(modeConfig.blockedTools.length)}`);
49120
+ } else {
49121
+ console.log(` Blocked tools: ${chalk5.green("none")}`);
49122
+ }
49123
+ console.log(chalk5.dim("\u2500".repeat(50)));
49124
+ console.log();
49125
+ console.log(chalk5.gray("To change mode: ax mode <mode-name>"));
49126
+ console.log(chalk5.gray("To list modes: ax mode --list\n"));
49127
+ }
49128
+
49129
+ // src/cli/commands/debug-instructions.ts
49130
+ init_esm_shims();
49131
+ init_logger();
49132
+
49133
+ // src/core/orchestration/orchestration-service.ts
49134
+ init_esm_shims();
49135
+ init_logger();
49136
+
49137
+ // src/core/orchestration/types.ts
49138
+ init_esm_shims();
49139
+ z.object({
49140
+ type: z.enum(["task", "memory", "session", "delegation", "mode"]),
49141
+ priority: z.enum(["critical", "high", "normal", "low"]),
49142
+ content: z.string().min(1).max(5e3),
49143
+ source: z.literal("automatosx"),
49144
+ expiresAfter: z.number().int().positive().optional(),
49145
+ createdAt: z.number(),
49146
+ id: z.string().optional()
49147
+ });
49148
+ var TodoItemSchema = z.object({
49149
+ id: z.string(),
49150
+ content: z.string().min(1).max(1e3),
49151
+ status: z.enum(["pending", "in_progress", "completed"]),
49152
+ activeForm: z.string().min(1).max(1e3),
49153
+ createdAt: z.number(),
49154
+ updatedAt: z.number().optional(),
49155
+ metadata: z.record(z.string(), z.unknown()).optional()
49156
+ });
49157
+ z.object({
49158
+ name: z.enum(["default", "plan", "iterate", "review"]),
49159
+ description: z.string(),
49160
+ allowedTools: z.array(z.string()).optional(),
49161
+ blockedTools: z.array(z.string()).optional(),
49162
+ systemInstructions: z.string(),
49163
+ allowNesting: z.boolean()
49164
+ });
49165
+ z.object({
49166
+ todos: z.array(TodoItemSchema),
49167
+ currentTask: z.string().optional(),
49168
+ agentName: z.string().optional(),
49169
+ turnCount: z.number().int().nonnegative(),
49170
+ workflowMode: z.enum(["default", "plan", "iterate", "review"]),
49171
+ sessionId: z.string().optional(),
49172
+ parentAgent: z.string().optional(),
49173
+ memories: z.array(z.object({
49174
+ content: z.string(),
49175
+ relevance: z.number().min(0).max(1),
49176
+ agent: z.string().optional(),
49177
+ timestamp: z.number()
49178
+ })).optional()
49179
+ });
49180
+ var DEFAULT_TOKEN_BUDGET = {
49181
+ maxTotal: 2e3,
49182
+ perType: {
49183
+ task: 500,
49184
+ memory: 600,
49185
+ session: 300,
49186
+ delegation: 200,
49187
+ mode: 400
49188
+ },
49189
+ criticalReserve: 300
49190
+ };
49191
+ var TokenBudgetConfigSchema = z.object({
49192
+ maxTotal: z.number().int().positive().max(1e4),
49193
+ perType: z.record(
49194
+ z.enum(["task", "memory", "session", "delegation", "mode"]),
49195
+ z.number().int().nonnegative()
49196
+ ),
49197
+ criticalReserve: z.number().int().nonnegative()
49198
+ });
49199
+ var DEFAULT_ORCHESTRATION_CONFIG = {
49200
+ enabled: true,
49201
+ tokenBudget: DEFAULT_TOKEN_BUDGET,
49202
+ todoIntegration: {
49203
+ enabled: true,
49204
+ reminderFrequency: 3,
49205
+ compactMode: false
49206
+ },
49207
+ memoryIntegration: {
49208
+ enabled: true,
49209
+ maxEntries: 5,
49210
+ minRelevance: 0.5
49211
+ },
49212
+ sessionIntegration: {
49213
+ enabled: true,
49214
+ showCollaboration: true
49215
+ },
49216
+ agentTemplates: {
49217
+ enabled: true,
49218
+ reminderFrequency: 5
49219
+ }
49220
+ };
49221
+ z.object({
49222
+ enabled: z.boolean(),
49223
+ tokenBudget: TokenBudgetConfigSchema,
49224
+ todoIntegration: z.object({
49225
+ enabled: z.boolean(),
49226
+ reminderFrequency: z.number().int().positive(),
49227
+ compactMode: z.boolean()
49228
+ }),
49229
+ memoryIntegration: z.object({
49230
+ enabled: z.boolean(),
49231
+ maxEntries: z.number().int().nonnegative(),
49232
+ minRelevance: z.number().min(0).max(1)
49233
+ }),
49234
+ sessionIntegration: z.object({
49235
+ enabled: z.boolean(),
49236
+ showCollaboration: z.boolean()
49237
+ }),
49238
+ agentTemplates: z.object({
49239
+ enabled: z.boolean(),
49240
+ reminderFrequency: z.number().int().positive()
49241
+ })
49242
+ });
49243
+
49244
+ // src/core/orchestration/instruction-injector.ts
49245
+ init_esm_shims();
49246
+ init_logger();
49247
+
49248
+ // src/core/orchestration/token-budget.ts
49249
+ init_esm_shims();
49250
+ init_logger();
49251
+ var TokenBudgetManager = class _TokenBudgetManager {
49252
+ config;
49253
+ /** Characters per token estimate (conservative) */
49254
+ static CHARS_PER_TOKEN = 4;
49255
+ constructor(config) {
49256
+ this.config = {
49257
+ ...DEFAULT_TOKEN_BUDGET,
49258
+ ...config,
49259
+ perType: {
49260
+ ...DEFAULT_TOKEN_BUDGET.perType,
49261
+ ...config?.perType
49262
+ }
49263
+ };
49264
+ logger.debug("TokenBudgetManager initialized", {
49265
+ maxTotal: this.config.maxTotal,
49266
+ criticalReserve: this.config.criticalReserve
49267
+ });
49268
+ }
49269
+ /**
49270
+ * Estimate tokens for a string
49271
+ */
49272
+ estimateTokens(content) {
49273
+ const characters = content.length;
49274
+ const tokens = Math.ceil(characters / _TokenBudgetManager.CHARS_PER_TOKEN);
49275
+ return {
49276
+ tokens,
49277
+ characters,
49278
+ isEstimate: true
49279
+ };
49280
+ }
49281
+ /**
49282
+ * Estimate tokens for an instruction (including formatting overhead)
49283
+ */
49284
+ estimateInstructionTokens(instruction) {
49285
+ const overhead = 50;
49286
+ const contentTokens = this.estimateTokens(instruction.content).tokens;
49287
+ return contentTokens + overhead;
49288
+ }
49289
+ /**
49290
+ * Allocate budget for instructions
49291
+ *
49292
+ * Priority order:
49293
+ * 1. Critical instructions (always included, use reserve)
49294
+ * 2. High priority (included if budget allows)
49295
+ * 3. Normal priority (included if budget allows)
49296
+ * 4. Low priority (only if significant budget remains)
49297
+ */
49298
+ allocateBudget(instructions) {
49299
+ const included = [];
49300
+ const excluded = [];
49301
+ const perTypeUsage = {
49302
+ task: 0,
49303
+ memory: 0,
49304
+ session: 0,
49305
+ delegation: 0,
49306
+ mode: 0
49307
+ };
49308
+ let tokensUsed = 0;
49309
+ const availableBudget = this.config.maxTotal;
49310
+ const priorityOrder = {
49311
+ critical: 0,
49312
+ high: 1,
49313
+ normal: 2,
49314
+ low: 3
49315
+ };
49316
+ const sorted = [...instructions].sort((a, b) => {
49317
+ const aPriority = priorityOrder[a.priority] ?? 2;
49318
+ const bPriority = priorityOrder[b.priority] ?? 2;
49319
+ const priorityDiff = aPriority - bPriority;
49320
+ if (priorityDiff !== 0) return priorityDiff;
49321
+ return a.createdAt - b.createdAt;
49322
+ });
49323
+ for (const instruction of sorted) {
49324
+ const instructionTokens = this.estimateInstructionTokens(instruction);
49325
+ const typeLimit = this.config.perType[instruction.type] || 0;
49326
+ const currentTypeUsage = perTypeUsage[instruction.type] || 0;
49327
+ const wouldExceedTotal = tokensUsed + instructionTokens > availableBudget;
49328
+ const wouldExceedTypeLimit = currentTypeUsage + instructionTokens > typeLimit;
49329
+ if (instruction.priority === "critical") {
49330
+ const criticalBudget = availableBudget + this.config.criticalReserve;
49331
+ if (tokensUsed + instructionTokens <= criticalBudget) {
49332
+ included.push(instruction);
49333
+ tokensUsed += instructionTokens;
49334
+ perTypeUsage[instruction.type] = currentTypeUsage + instructionTokens;
49335
+ continue;
49336
+ }
49337
+ }
49338
+ if (!wouldExceedTotal && !wouldExceedTypeLimit) {
49339
+ included.push(instruction);
49340
+ tokensUsed += instructionTokens;
49341
+ perTypeUsage[instruction.type] = currentTypeUsage + instructionTokens;
49342
+ } else {
49343
+ excluded.push(instruction);
49344
+ logger.debug("Instruction excluded from budget", {
49345
+ type: instruction.type,
49346
+ priority: instruction.priority,
49347
+ tokens: instructionTokens,
49348
+ reason: wouldExceedTotal ? "total_limit" : "type_limit"
49349
+ });
49350
+ }
49351
+ }
49352
+ const result = {
49353
+ included,
49354
+ excluded,
49355
+ tokensUsed,
49356
+ remaining: availableBudget - tokensUsed,
49357
+ perTypeUsage
49358
+ };
49359
+ logger.debug("Budget allocation complete", {
49360
+ included: included.length,
49361
+ excluded: excluded.length,
49362
+ tokensUsed,
49363
+ remaining: result.remaining
49364
+ });
49365
+ return result;
49366
+ }
49367
+ /**
49368
+ * Check if an instruction fits within budget
49369
+ */
49370
+ fitsInBudget(instruction, currentUsage, typeUsage) {
49371
+ const instructionTokens = this.estimateInstructionTokens(instruction);
49372
+ const typeLimit = this.config.perType[instruction.type] || 0;
49373
+ const currentTypeUsage = typeUsage[instruction.type] || 0;
49374
+ if (instruction.priority === "critical") {
49375
+ return currentUsage + instructionTokens <= this.config.maxTotal + this.config.criticalReserve;
49376
+ }
49377
+ return currentUsage + instructionTokens <= this.config.maxTotal && currentTypeUsage + instructionTokens <= typeLimit;
49378
+ }
49379
+ /**
49380
+ * Get current configuration
49381
+ */
49382
+ getConfig() {
49383
+ return { ...this.config };
49384
+ }
49385
+ /**
49386
+ * Update configuration
49387
+ */
49388
+ updateConfig(updates) {
49389
+ this.config = {
49390
+ ...this.config,
49391
+ ...updates,
49392
+ perType: {
49393
+ ...this.config.perType,
49394
+ ...updates.perType
49395
+ }
49396
+ };
49397
+ logger.debug("TokenBudgetManager config updated", {
49398
+ maxTotal: this.config.maxTotal
49399
+ });
49400
+ }
49401
+ /**
49402
+ * Get remaining budget for a specific type
49403
+ */
49404
+ getRemainingTypeBudget(type, currentTypeUsage) {
49405
+ const limit = this.config.perType[type] || 0;
49406
+ const used = currentTypeUsage[type] || 0;
49407
+ return Math.max(0, limit - used);
49408
+ }
49409
+ /**
49410
+ * Format budget status for debugging
49411
+ */
49412
+ formatBudgetStatus(allocation) {
49413
+ const lines = [
49414
+ `Token Budget Status:`,
49415
+ ` Total: ${allocation.tokensUsed}/${this.config.maxTotal} (${allocation.remaining} remaining)`,
49416
+ ` Per-Type Usage:`
49417
+ ];
49418
+ for (const [type, used] of Object.entries(allocation.perTypeUsage)) {
49419
+ const limit = this.config.perType[type] || 0;
49420
+ lines.push(` ${type}: ${used}/${limit}`);
49421
+ }
49422
+ if (allocation.excluded.length > 0) {
49423
+ lines.push(` Excluded: ${allocation.excluded.length} instruction(s)`);
49424
+ }
49425
+ return lines.join("\n");
49426
+ }
49427
+ };
49428
+
49429
+ // src/core/orchestration/instruction-injector.ts
49430
+ var OrchestrationInstructionInjector = class {
49431
+ providers = /* @__PURE__ */ new Map();
49432
+ budgetManager;
49433
+ config;
49434
+ lastInjectionTime = 0;
49435
+ instructionCache = /* @__PURE__ */ new Map();
49436
+ constructor(config) {
49437
+ this.config = {
49438
+ ...DEFAULT_ORCHESTRATION_CONFIG,
49439
+ ...config
49440
+ };
49441
+ this.budgetManager = new TokenBudgetManager(this.config.tokenBudget);
49442
+ logger.debug("OrchestrationInstructionInjector initialized", {
49443
+ enabled: this.config.enabled,
49444
+ providers: this.providers.size
49445
+ });
49446
+ }
49447
+ /**
49448
+ * Register an instruction provider
49449
+ */
49450
+ registerProvider(provider) {
49451
+ if (this.providers.has(provider.name)) {
49452
+ logger.warn("Provider already registered, replacing", {
49453
+ name: provider.name
49454
+ });
49455
+ }
49456
+ this.providers.set(provider.name, provider);
49457
+ logger.debug("Instruction provider registered", {
49458
+ name: provider.name,
49459
+ totalProviders: this.providers.size
49460
+ });
49461
+ }
49462
+ /**
49463
+ * Unregister an instruction provider
49464
+ */
49465
+ unregisterProvider(name) {
49466
+ const removed = this.providers.delete(name);
49467
+ if (removed) {
49468
+ logger.debug("Instruction provider unregistered", { name });
49469
+ }
49470
+ return removed;
49471
+ }
49472
+ /**
49473
+ * Get all registered providers
49474
+ */
49475
+ getProviders() {
49476
+ return Array.from(this.providers.values());
49477
+ }
49478
+ /**
49479
+ * Generate and inject instructions based on context
49480
+ */
49481
+ async inject(context, options = {}) {
49482
+ if (!this.config.enabled) {
49483
+ return this.emptyResult();
49484
+ }
49485
+ const startTime = Date.now();
49486
+ const allInstructions = [];
49487
+ for (const provider of this.providers.values()) {
49488
+ try {
49489
+ if (!provider.shouldGenerate(context)) {
49490
+ continue;
49491
+ }
49492
+ const instructions = await provider.getInstructions(context);
49493
+ let filtered = instructions;
49494
+ if (options.includeTypes) {
49495
+ filtered = filtered.filter((i) => options.includeTypes.includes(i.type));
49496
+ }
49497
+ if (options.excludeTypes) {
49498
+ filtered = filtered.filter((i) => !options.excludeTypes.includes(i.type));
49499
+ }
49500
+ allInstructions.push(...filtered);
49501
+ } catch (error) {
49502
+ logger.error("Provider failed to generate instructions", {
49503
+ provider: provider.name,
49504
+ error: error instanceof Error ? error.message : String(error)
49505
+ });
49506
+ }
49507
+ }
49508
+ const activeInstructions = this.filterExpiredInstructions(
49509
+ allInstructions,
49510
+ context.turnCount
49511
+ );
49512
+ let allocation;
49513
+ if (options.skipBudget) {
49514
+ allocation = {
49515
+ included: activeInstructions,
49516
+ excluded: [],
49517
+ tokensUsed: activeInstructions.reduce(
49518
+ (sum, i) => sum + this.budgetManager.estimateInstructionTokens(i),
49519
+ 0
49520
+ ),
49521
+ remaining: 0,
49522
+ perTypeUsage: this.calculateTypeUsage(activeInstructions)
49523
+ };
49524
+ } else {
49525
+ allocation = this.budgetManager.allocateBudget(activeInstructions);
49526
+ }
49527
+ const formattedText = this.formatInstructions(allocation.included);
49528
+ this.lastInjectionTime = Date.now();
49529
+ const duration = Date.now() - startTime;
49530
+ logger.debug("Instruction injection complete", {
49531
+ providers: this.providers.size,
49532
+ instructionsGenerated: allInstructions.length,
49533
+ instructionsIncluded: allocation.included.length,
49534
+ tokensUsed: allocation.tokensUsed,
49535
+ durationMs: duration
49536
+ });
49537
+ return {
49538
+ formattedText,
49539
+ instructions: allocation.included,
49540
+ allocation,
49541
+ hasInstructions: allocation.included.length > 0
49542
+ };
49543
+ }
49544
+ /**
49545
+ * Format instructions as system reminder tags
49546
+ */
49547
+ formatInstructions(instructions) {
49548
+ if (instructions.length === 0) {
49549
+ return "";
49550
+ }
49551
+ const grouped = /* @__PURE__ */ new Map();
49552
+ for (const instruction of instructions) {
49553
+ const existing = grouped.get(instruction.type) || [];
49554
+ existing.push(instruction);
49555
+ grouped.set(instruction.type, existing);
49556
+ }
49557
+ const parts = [];
49558
+ const typeOrder = ["mode", "task", "memory", "session", "delegation"];
49559
+ for (const type of typeOrder) {
49560
+ const typeInstructions = grouped.get(type);
49561
+ if (!typeInstructions || typeInstructions.length === 0) continue;
49562
+ for (const instruction of typeInstructions) {
49563
+ parts.push(this.formatSingleInstruction(instruction));
49564
+ }
49565
+ }
49566
+ return parts.join("\n");
49567
+ }
49568
+ /**
49569
+ * Format a single instruction as a system reminder
49570
+ */
49571
+ formatSingleInstruction(instruction) {
49572
+ return `<system-reminder>
49573
+ ${instruction.content}
49574
+ </system-reminder>`;
49575
+ }
49576
+ /**
49577
+ * Filter out expired instructions
49578
+ */
49579
+ filterExpiredInstructions(instructions, currentTurn) {
49580
+ return instructions.filter((instruction) => {
49581
+ if (instruction.expiresAfter === void 0) {
49582
+ return true;
49583
+ }
49584
+ const turnsSinceCreation = currentTurn;
49585
+ return turnsSinceCreation < instruction.expiresAfter;
49586
+ });
49587
+ }
49588
+ /**
49589
+ * Calculate per-type token usage
49590
+ */
49591
+ calculateTypeUsage(instructions) {
49592
+ const usage = {
49593
+ task: 0,
49594
+ memory: 0,
49595
+ session: 0,
49596
+ delegation: 0,
49597
+ mode: 0
49598
+ };
49599
+ for (const instruction of instructions) {
49600
+ const tokens = this.budgetManager.estimateInstructionTokens(instruction);
49601
+ usage[instruction.type] = (usage[instruction.type] || 0) + tokens;
49602
+ }
49603
+ return usage;
49604
+ }
49605
+ /**
49606
+ * Create an empty result
49607
+ */
49608
+ emptyResult() {
49609
+ return {
49610
+ formattedText: "",
49611
+ instructions: [],
49612
+ allocation: {
49613
+ included: [],
49614
+ excluded: [],
49615
+ tokensUsed: 0,
49616
+ remaining: this.budgetManager.getConfig().maxTotal,
49617
+ perTypeUsage: {
49618
+ task: 0,
49619
+ memory: 0,
49620
+ session: 0,
49621
+ delegation: 0,
49622
+ mode: 0
49623
+ }
49624
+ },
49625
+ hasInstructions: false
49626
+ };
49627
+ }
49628
+ /**
49629
+ * Clear instruction cache
49630
+ */
49631
+ clearCache() {
49632
+ this.instructionCache.clear();
49633
+ logger.debug("Instruction cache cleared");
49634
+ }
49635
+ /**
49636
+ * Get current configuration
49637
+ */
49638
+ getConfig() {
49639
+ return { ...this.config };
49640
+ }
49641
+ /**
49642
+ * Update configuration
49643
+ */
49644
+ updateConfig(updates) {
49645
+ this.config = {
49646
+ ...this.config,
49647
+ ...updates
49648
+ };
49649
+ if (updates.tokenBudget) {
49650
+ this.budgetManager.updateConfig(updates.tokenBudget);
49651
+ }
49652
+ logger.debug("OrchestrationInstructionInjector config updated", {
49653
+ enabled: this.config.enabled
49654
+ });
49655
+ }
49656
+ /**
49657
+ * Get budget manager for direct access
49658
+ */
49659
+ getBudgetManager() {
49660
+ return this.budgetManager;
49661
+ }
49662
+ /**
49663
+ * Check if orchestration is enabled
49664
+ */
49665
+ isEnabled() {
49666
+ return this.config.enabled;
49667
+ }
49668
+ /**
49669
+ * Enable or disable orchestration
49670
+ */
49671
+ setEnabled(enabled) {
49672
+ this.config.enabled = enabled;
49673
+ logger.debug("Orchestration enabled state changed", { enabled });
49674
+ }
49675
+ };
49676
+
49677
+ // src/core/orchestration/todo-instruction-provider.ts
49678
+ init_esm_shims();
49679
+ init_logger();
49680
+ var DEFAULT_TODO_CONFIG = {
49681
+ enabled: true,
49682
+ reminderFrequency: 3,
49683
+ compactMode: false,
49684
+ maxCompactItems: 5,
49685
+ showCompleted: false
49686
+ };
49687
+ var TodoInstructionProvider = class {
49688
+ name = "todo";
49689
+ config;
49690
+ lastStateHash = "";
49691
+ lastReminderTurn = 0;
49692
+ constructor(config) {
49693
+ this.config = {
49694
+ ...DEFAULT_TODO_CONFIG,
49695
+ ...config
49696
+ };
49697
+ logger.debug("TodoInstructionProvider initialized", {
49698
+ enabled: this.config.enabled,
49699
+ reminderFrequency: this.config.reminderFrequency
49700
+ });
49701
+ }
49702
+ /**
49703
+ * Check if provider should generate instructions
49704
+ */
49705
+ shouldGenerate(context) {
49706
+ if (!this.config.enabled) {
49707
+ return false;
49708
+ }
49709
+ if (!context.todos || context.todos.length === 0) {
49710
+ return false;
49711
+ }
49712
+ const currentHash = this.computeStateHash(context.todos);
49713
+ const stateChanged = currentHash !== this.lastStateHash;
49714
+ const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
49715
+ const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
49716
+ return stateChanged || reminderDue;
49717
+ }
49718
+ /**
49719
+ * Generate instructions based on todo state
49720
+ */
49721
+ async getInstructions(context) {
49722
+ const instructions = [];
49723
+ if (!context.todos || context.todos.length === 0) {
49724
+ return instructions;
49725
+ }
49726
+ const currentHash = this.computeStateHash(context.todos);
49727
+ const stateChanged = currentHash !== this.lastStateHash;
49728
+ const activeTodos = context.todos.filter(
49729
+ (todo) => todo.status !== "completed" || this.config.showCompleted
49730
+ );
49731
+ const inProgressTasks = activeTodos.filter((todo) => todo.status === "in_progress");
49732
+ const pendingTasks = activeTodos.filter((todo) => todo.status === "pending");
49733
+ const completedTasks = context.todos.filter((todo) => todo.status === "completed");
49734
+ let content;
49735
+ let priority;
49736
+ if (stateChanged) {
49737
+ content = this.formatFullTodoList(inProgressTasks, pendingTasks, completedTasks);
49738
+ priority = "high";
49739
+ } else if (this.config.compactMode) {
49740
+ content = this.formatCompactReminder(inProgressTasks, pendingTasks);
49741
+ priority = "normal";
49742
+ } else {
49743
+ content = this.formatStandardReminder(inProgressTasks, pendingTasks);
49744
+ priority = "normal";
49745
+ }
49746
+ instructions.push({
49747
+ type: "task",
49748
+ priority,
49749
+ content,
49750
+ source: "automatosx",
49751
+ createdAt: Date.now(),
49752
+ expiresAfter: this.config.reminderFrequency + 1,
49753
+ id: `todo-${currentHash.substring(0, 8)}`
49754
+ });
49755
+ this.lastStateHash = currentHash;
49756
+ this.lastReminderTurn = context.turnCount;
49757
+ logger.debug("Todo instructions generated", {
49758
+ inProgress: inProgressTasks.length,
49759
+ pending: pendingTasks.length,
49760
+ completed: completedTasks.length,
49761
+ stateChanged
49762
+ });
49763
+ return instructions;
49764
+ }
49765
+ /**
49766
+ * Format full todo list (used when state changes)
49767
+ */
49768
+ formatFullTodoList(inProgress, pending, completed) {
49769
+ const lines = [
49770
+ "## Current Task List"
49771
+ ];
49772
+ if (inProgress.length > 0) {
49773
+ lines.push("");
49774
+ lines.push("### Currently Working On:");
49775
+ for (const task of inProgress) {
49776
+ lines.push(`- **${task.activeForm}**`);
49777
+ }
49778
+ }
49779
+ if (pending.length > 0) {
49780
+ lines.push("");
49781
+ lines.push("### Pending Tasks:");
49782
+ for (const task of pending) {
49783
+ lines.push(`- [ ] ${task.content}`);
49784
+ }
49785
+ }
49786
+ if (this.config.showCompleted && completed.length > 0) {
49787
+ lines.push("");
49788
+ lines.push("### Completed:");
49789
+ for (const task of completed.slice(-3)) {
49790
+ lines.push(`- [x] ${task.content}`);
49791
+ }
49792
+ }
49793
+ lines.push("");
49794
+ lines.push("**Remember:** Complete the current in-progress task before starting new ones.");
49795
+ lines.push("Mark tasks as completed as soon as they are done.");
49796
+ return lines.join("\n");
49797
+ }
49798
+ /**
49799
+ * Format standard reminder
49800
+ */
49801
+ formatStandardReminder(inProgress, pending) {
49802
+ const lines = [];
49803
+ if (inProgress.length > 0) {
49804
+ lines.push(`**Current Task:** ${inProgress[0].activeForm}`);
49805
+ }
49806
+ if (pending.length > 0) {
49807
+ lines.push(`**Next:** ${pending[0].content}`);
49808
+ if (pending.length > 1) {
49809
+ lines.push(`(${pending.length - 1} more tasks pending)`);
49810
+ }
49811
+ }
49812
+ return lines.join("\n");
49813
+ }
49814
+ /**
49815
+ * Format compact reminder (minimal tokens)
49816
+ */
49817
+ formatCompactReminder(inProgress, pending) {
49818
+ const parts = [];
49819
+ if (inProgress.length > 0) {
49820
+ parts.push(`Doing: ${inProgress[0].activeForm}`);
49821
+ }
49822
+ if (pending.length > 0) {
49823
+ const count = Math.min(pending.length, this.config.maxCompactItems);
49824
+ parts.push(`Next: ${pending.slice(0, count).map((t) => t.content).join(", ")}`);
49825
+ }
49826
+ return parts.join(" | ");
49827
+ }
49828
+ /**
49829
+ * Compute hash of todo state for change detection
49830
+ */
49831
+ computeStateHash(todos) {
49832
+ const stateString = todos.map((t) => `${t.id}:${t.status}:${t.content}`).sort().join("|");
49833
+ return crypto2.createHash("sha256").update(stateString).digest("hex").substring(0, 16);
49834
+ }
49835
+ /**
49836
+ * Get current configuration
49837
+ */
49838
+ getConfig() {
49839
+ return { ...this.config };
49840
+ }
49841
+ /**
49842
+ * Update configuration
49843
+ */
49844
+ updateConfig(updates) {
49845
+ this.config = {
49846
+ ...this.config,
49847
+ ...updates
49848
+ };
49849
+ logger.debug("TodoInstructionProvider config updated", {
49850
+ enabled: this.config.enabled,
49851
+ compactMode: this.config.compactMode
49852
+ });
49853
+ }
49854
+ /**
49855
+ * Reset state tracking (useful for testing)
49856
+ */
49857
+ reset() {
49858
+ this.lastStateHash = "";
49859
+ this.lastReminderTurn = 0;
49860
+ logger.debug("TodoInstructionProvider state reset");
49861
+ }
49862
+ };
49863
+
49864
+ // src/core/orchestration/memory-instruction-provider.ts
49865
+ init_esm_shims();
49866
+ init_logger();
49867
+ var DEFAULT_MEMORY_CONFIG = {
49868
+ enabled: true,
49869
+ maxEntries: 5,
49870
+ minRelevance: 0.5,
49871
+ searchFrequency: 3,
49872
+ maxAge: 0,
49873
+ // No limit by default
49874
+ includeMetadata: true,
49875
+ cacheTTL: 6e4
49876
+ // 1 minute
49877
+ };
49878
+ var MemoryInstructionProvider = class {
49879
+ name = "memory";
49880
+ config;
49881
+ searchProvider;
49882
+ cache;
49883
+ lastSearchTurn = 0;
49884
+ constructor(searchProvider, config) {
49885
+ this.config = {
49886
+ ...DEFAULT_MEMORY_CONFIG,
49887
+ ...config
49888
+ };
49889
+ this.searchProvider = searchProvider;
49890
+ logger.debug("MemoryInstructionProvider initialized", {
49891
+ enabled: this.config.enabled,
49892
+ maxEntries: this.config.maxEntries,
49893
+ hasSearchProvider: !!searchProvider
49894
+ });
49895
+ }
49896
+ /**
49897
+ * Set the memory search provider
49898
+ */
49899
+ setSearchProvider(provider) {
49900
+ this.searchProvider = provider;
49901
+ this.clearCache();
49902
+ logger.debug("Memory search provider set");
49903
+ }
49904
+ /**
49905
+ * Check if provider should generate instructions
49906
+ */
49907
+ shouldGenerate(context) {
49908
+ if (!this.config.enabled) {
49909
+ return false;
49910
+ }
49911
+ if (!this.searchProvider) {
49912
+ return false;
49913
+ }
49914
+ if (!context.currentTask && context.todos.length === 0) {
49915
+ return false;
49916
+ }
49917
+ const turnsSinceSearch = context.turnCount - this.lastSearchTurn;
49918
+ const searchDue = turnsSinceSearch >= this.config.searchFrequency;
49919
+ const cacheValid = this.cache && Date.now() - this.cache.timestamp < this.config.cacheTTL;
49920
+ return searchDue || !cacheValid;
49921
+ }
49922
+ /**
49923
+ * Generate instructions based on relevant memories
49924
+ */
49925
+ async getInstructions(context) {
49926
+ const instructions = [];
49927
+ if (!this.searchProvider) {
49928
+ return instructions;
49929
+ }
49930
+ const searchQuery = this.buildSearchQuery(context);
49931
+ if (!searchQuery) {
49932
+ return instructions;
49933
+ }
49934
+ try {
49935
+ const memories = await this.searchMemories(searchQuery, context);
49936
+ if (memories.length === 0) {
49937
+ return instructions;
49938
+ }
49939
+ this.lastSearchTurn = context.turnCount;
49940
+ const content = this.formatMemories(memories);
49941
+ instructions.push({
49942
+ type: "memory",
49943
+ priority: "normal",
49944
+ content,
49945
+ source: "automatosx",
49946
+ createdAt: Date.now(),
49947
+ expiresAfter: this.config.searchFrequency + 1,
49948
+ id: `memory-${Date.now()}`
49949
+ });
49950
+ logger.debug("Memory instructions generated", {
49951
+ memoriesFound: memories.length,
49952
+ query: searchQuery.substring(0, 50)
49953
+ });
49954
+ } catch (error) {
49955
+ logger.error("Failed to search memories", {
49956
+ error: error instanceof Error ? error.message : String(error)
49957
+ });
49958
+ }
49959
+ return instructions;
49960
+ }
49961
+ /**
49962
+ * Build search query from context
49963
+ */
49964
+ buildSearchQuery(context) {
49965
+ const parts = [];
49966
+ if (context.currentTask) {
49967
+ parts.push(context.currentTask);
49968
+ }
49969
+ const inProgressTodos = context.todos.filter((t) => t.status === "in_progress");
49970
+ for (const todo of inProgressTodos.slice(0, 2)) {
49971
+ parts.push(todo.content);
49972
+ }
49973
+ if (context.agentName) {
49974
+ parts.push(context.agentName);
49975
+ }
49976
+ if (parts.length === 0) {
49977
+ return null;
49978
+ }
49979
+ return parts.join(" ");
49980
+ }
49981
+ /**
49982
+ * Search for relevant memories
49983
+ */
49984
+ async searchMemories(query, context) {
49985
+ if (!this.searchProvider) {
49986
+ return [];
49987
+ }
49988
+ if (this.cache && this.cache.query === query) {
49989
+ const age = Date.now() - this.cache.timestamp;
49990
+ if (age < this.config.cacheTTL) {
49991
+ logger.debug("Using cached memory results", {
49992
+ cacheAge: age,
49993
+ resultCount: this.cache.results.length
49994
+ });
49995
+ return this.cache.results;
49996
+ }
49997
+ }
49998
+ const results = await this.searchProvider.search({
49999
+ text: query,
50000
+ limit: this.config.maxEntries * 2,
50001
+ // Get extra in case some are filtered
50002
+ filters: context.agentName ? { agentId: context.agentName } : void 0
50003
+ });
50004
+ const filtered = results.filter((r) => r.score >= this.config.minRelevance).filter((r) => this.isWithinMaxAge(r.createdAt)).slice(0, this.config.maxEntries);
50005
+ const memories = filtered.map((r) => ({
50006
+ content: r.content,
50007
+ relevance: r.score,
50008
+ agent: r.metadata?.agentId,
50009
+ timestamp: r.createdAt.getTime()
50010
+ }));
50011
+ this.cache = {
50012
+ query,
50013
+ results: memories,
50014
+ timestamp: Date.now()
50015
+ };
50016
+ return memories;
50017
+ }
50018
+ /**
50019
+ * Check if memory is within max age limit
50020
+ */
50021
+ isWithinMaxAge(createdAt) {
50022
+ if (this.config.maxAge === 0) {
50023
+ return true;
50024
+ }
50025
+ const age = Date.now() - createdAt.getTime();
50026
+ return age <= this.config.maxAge;
50027
+ }
50028
+ /**
50029
+ * Format memories into instruction content
50030
+ */
50031
+ formatMemories(memories) {
50032
+ const lines = [
50033
+ "## Relevant Context from Memory",
50034
+ ""
50035
+ ];
50036
+ for (let i = 0; i < memories.length; i++) {
50037
+ const memory = memories[i];
50038
+ if (!memory) continue;
50039
+ const relevancePercent = Math.round(memory.relevance * 100);
50040
+ if (this.config.includeMetadata && memory.agent) {
50041
+ lines.push(`### Memory ${i + 1} (${relevancePercent}% relevant, from ${memory.agent})`);
50042
+ } else {
50043
+ lines.push(`### Memory ${i + 1} (${relevancePercent}% relevant)`);
50044
+ }
50045
+ const maxLength = 500;
50046
+ const content = memory.content.length > maxLength ? memory.content.substring(0, maxLength) + "..." : memory.content;
50047
+ lines.push(content);
50048
+ lines.push("");
50049
+ }
50050
+ lines.push("**Note:** Use this context to inform your decisions, but verify current state.");
50051
+ return lines.join("\n");
50052
+ }
50053
+ /**
50054
+ * Clear the memory cache
50055
+ */
50056
+ clearCache() {
50057
+ this.cache = void 0;
50058
+ logger.debug("Memory cache cleared");
50059
+ }
50060
+ /**
50061
+ * Get current configuration
50062
+ */
50063
+ getConfig() {
50064
+ return { ...this.config };
50065
+ }
50066
+ /**
50067
+ * Update configuration
50068
+ */
50069
+ updateConfig(updates) {
50070
+ this.config = {
50071
+ ...this.config,
50072
+ ...updates
50073
+ };
50074
+ if (updates.minRelevance !== void 0 || updates.maxEntries !== void 0) {
50075
+ this.clearCache();
50076
+ }
50077
+ logger.debug("MemoryInstructionProvider config updated", {
50078
+ enabled: this.config.enabled,
50079
+ maxEntries: this.config.maxEntries
50080
+ });
50081
+ }
50082
+ /**
50083
+ * Reset state
50084
+ */
50085
+ reset() {
50086
+ this.cache = void 0;
50087
+ this.lastSearchTurn = 0;
50088
+ logger.debug("MemoryInstructionProvider reset");
50089
+ }
50090
+ /**
50091
+ * Check if search provider is configured
50092
+ */
50093
+ hasSearchProvider() {
50094
+ return !!this.searchProvider;
50095
+ }
50096
+ };
50097
+
50098
+ // src/core/orchestration/session-instruction-provider.ts
50099
+ init_esm_shims();
50100
+ init_logger();
50101
+ var DEFAULT_SESSION_CONFIG = {
50102
+ enabled: true,
50103
+ showCollaboration: true,
50104
+ showProgress: true,
50105
+ reminderFrequency: 5,
50106
+ showHandoffContext: true
50107
+ };
50108
+ var SessionInstructionProvider = class {
50109
+ name = "session";
50110
+ config;
50111
+ stateProvider;
50112
+ lastReminderTurn = 0;
50113
+ cachedState;
50114
+ cacheExpiry = 0;
50115
+ CACHE_TTL = 3e4;
50116
+ // 30 seconds
50117
+ constructor(stateProvider, config) {
50118
+ this.config = {
50119
+ ...DEFAULT_SESSION_CONFIG,
50120
+ ...config
50121
+ };
50122
+ this.stateProvider = stateProvider;
50123
+ logger.debug("SessionInstructionProvider initialized", {
50124
+ enabled: this.config.enabled,
50125
+ hasStateProvider: !!stateProvider
50126
+ });
50127
+ }
50128
+ /**
50129
+ * Set the session state provider
50130
+ */
50131
+ setStateProvider(provider) {
50132
+ this.stateProvider = provider;
50133
+ this.clearCache();
50134
+ logger.debug("Session state provider set");
50135
+ }
50136
+ /**
50137
+ * Check if provider should generate instructions
50138
+ */
50139
+ shouldGenerate(context) {
50140
+ if (!this.config.enabled) {
50141
+ return false;
50142
+ }
50143
+ if (!context.sessionId && !this.stateProvider) {
50144
+ return false;
50145
+ }
50146
+ const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
50147
+ return turnsSinceReminder >= this.config.reminderFrequency;
50148
+ }
50149
+ /**
50150
+ * Generate instructions based on session state
50151
+ */
50152
+ async getInstructions(context) {
50153
+ const instructions = [];
50154
+ const state = await this.getSessionState(context);
50155
+ if (!state && !context.sessionId) {
50156
+ return instructions;
50157
+ }
50158
+ const content = this.formatSessionContext(context, state);
50159
+ if (content) {
50160
+ instructions.push({
50161
+ type: "session",
50162
+ priority: "normal",
50163
+ content,
50164
+ source: "automatosx",
50165
+ createdAt: Date.now(),
50166
+ expiresAfter: this.config.reminderFrequency,
50167
+ id: `session-${context.sessionId || "default"}-${Date.now()}`
50168
+ });
50169
+ }
50170
+ this.lastReminderTurn = context.turnCount;
50171
+ logger.debug("Session instructions generated", {
50172
+ sessionId: context.sessionId,
50173
+ hasState: !!state
50174
+ });
50175
+ return instructions;
50176
+ }
50177
+ /**
50178
+ * Get session state from provider or cache
50179
+ */
50180
+ async getSessionState(context) {
50181
+ if (!context.sessionId) {
50182
+ return null;
50183
+ }
50184
+ if (this.cachedState && this.cachedState.id === context.sessionId && Date.now() < this.cacheExpiry) {
50185
+ return this.cachedState;
50186
+ }
50187
+ if (!this.stateProvider) {
50188
+ return null;
50189
+ }
50190
+ try {
50191
+ const state = await this.stateProvider.getSessionState(context.sessionId);
50192
+ if (state) {
50193
+ this.cachedState = state;
50194
+ this.cacheExpiry = Date.now() + this.CACHE_TTL;
50195
+ }
50196
+ return state;
50197
+ } catch (error) {
50198
+ logger.error("Failed to get session state", {
50199
+ sessionId: context.sessionId,
50200
+ error: error instanceof Error ? error.message : String(error)
50201
+ });
50202
+ return null;
50203
+ }
50204
+ }
50205
+ /**
50206
+ * Format session context into instruction content
50207
+ */
50208
+ formatSessionContext(context, state) {
50209
+ const lines = [];
50210
+ if (context.sessionId) {
50211
+ lines.push("## Session Context");
50212
+ lines.push("");
50213
+ }
50214
+ if (this.config.showCollaboration && state && state.participants.length > 1) {
50215
+ lines.push("### Multi-Agent Collaboration");
50216
+ lines.push(`- **Session:** ${state.id.substring(0, 8)}...`);
50217
+ lines.push(`- **Participants:** ${state.participants.join(", ")}`);
50218
+ if (state.activeAgent) {
50219
+ lines.push(`- **Currently Active:** ${state.activeAgent}`);
50220
+ }
50221
+ lines.push("");
50222
+ }
50223
+ if (this.config.showProgress && state) {
50224
+ const totalTasks = state.completedTasks + state.remainingTasks;
50225
+ if (totalTasks > 0) {
50226
+ const progress = Math.round(state.completedTasks / totalTasks * 100);
50227
+ lines.push("### Session Progress");
50228
+ lines.push(`- Completed: ${state.completedTasks}/${totalTasks} (${progress}%)`);
50229
+ if (state.remainingTasks > 0) {
50230
+ lines.push(`- Remaining: ${state.remainingTasks} task(s)`);
50231
+ }
50232
+ lines.push("");
50233
+ }
50234
+ }
50235
+ if (this.config.showHandoffContext && context.parentAgent) {
50236
+ lines.push("### Delegation Context");
50237
+ lines.push(`- **Delegated from:** ${context.parentAgent}`);
50238
+ if (context.currentTask) {
50239
+ lines.push(`- **Task:** ${context.currentTask}`);
50240
+ }
50241
+ lines.push("");
50242
+ lines.push("**Note:** Complete this task and return control to the parent agent.");
50243
+ lines.push("");
50244
+ }
50245
+ if (context.agentName && !context.parentAgent) {
50246
+ lines.push(`**Current Agent:** ${context.agentName}`);
50247
+ lines.push("");
50248
+ }
50249
+ if (lines.length <= 2) {
50250
+ return null;
50251
+ }
50252
+ return lines.join("\n");
50253
+ }
50254
+ /**
50255
+ * Clear cached state
50256
+ */
50257
+ clearCache() {
50258
+ this.cachedState = void 0;
50259
+ this.cacheExpiry = 0;
50260
+ logger.debug("Session cache cleared");
50261
+ }
50262
+ /**
50263
+ * Get current configuration
50264
+ */
50265
+ getConfig() {
50266
+ return { ...this.config };
50267
+ }
50268
+ /**
50269
+ * Update configuration
50270
+ */
50271
+ updateConfig(updates) {
50272
+ this.config = {
50273
+ ...this.config,
50274
+ ...updates
50275
+ };
50276
+ logger.debug("SessionInstructionProvider config updated", {
50277
+ enabled: this.config.enabled
50278
+ });
50279
+ }
50280
+ /**
50281
+ * Reset state
50282
+ */
50283
+ reset() {
50284
+ this.lastReminderTurn = 0;
50285
+ this.clearCache();
50286
+ logger.debug("SessionInstructionProvider reset");
50287
+ }
50288
+ /**
50289
+ * Check if state provider is configured
50290
+ */
50291
+ hasStateProvider() {
50292
+ return !!this.stateProvider;
50293
+ }
50294
+ };
50295
+
50296
+ // src/agents/agent-instruction-injector.ts
50297
+ init_esm_shims();
50298
+ init_logger();
50299
+
50300
+ // src/agents/instruction-templates.ts
50301
+ init_esm_shims();
50302
+ var BACKEND_TEMPLATE = {
50303
+ domain: "backend",
50304
+ displayName: "Backend Engineer",
50305
+ domainReminders: [
50306
+ "Follow RESTful API design principles",
50307
+ "Use proper HTTP status codes",
50308
+ "Implement input validation at API boundaries",
50309
+ "Consider database query performance",
50310
+ "Handle errors gracefully with meaningful messages"
50311
+ ],
50312
+ qualityChecklist: [
50313
+ "API endpoints follow REST conventions",
50314
+ "Database queries are optimized (no N+1)",
50315
+ "Input is validated before processing",
50316
+ "Errors are logged with context",
50317
+ "Sensitive data is not exposed in responses"
50318
+ ],
50319
+ delegationTriggers: [
50320
+ {
50321
+ keywords: ["security", "authentication", "authorization", "OWASP", "vulnerability"],
50322
+ suggestedAgent: "security",
50323
+ reason: "Security-related tasks benefit from specialized security review"
50324
+ },
50325
+ {
50326
+ keywords: ["frontend", "UI", "React", "CSS", "component"],
50327
+ suggestedAgent: "frontend",
50328
+ reason: "Frontend implementation should be handled by frontend specialist"
50329
+ },
50330
+ {
50331
+ keywords: ["test", "testing", "unit test", "integration test"],
50332
+ suggestedAgent: "quality",
50333
+ reason: "Testing strategy benefits from QA expertise"
50334
+ }
50335
+ ],
50336
+ antiPatterns: [
50337
+ "Avoid SQL injection by using parameterized queries",
50338
+ "Don't expose internal error details to clients",
50339
+ "Avoid synchronous blocking operations",
50340
+ "Don't hardcode configuration values"
50341
+ ],
50342
+ bestPractices: [
50343
+ "Use prepared statements for database queries",
50344
+ "Implement proper logging with correlation IDs",
50345
+ "Use dependency injection for testability",
50346
+ "Follow the principle of least privilege"
50347
+ ]
50348
+ };
50349
+ var FRONTEND_TEMPLATE = {
50350
+ domain: "frontend",
50351
+ displayName: "Frontend Engineer",
50352
+ domainReminders: [
50353
+ "Ensure accessibility (WCAG compliance)",
50354
+ "Optimize for performance (Core Web Vitals)",
50355
+ "Handle loading and error states",
50356
+ "Implement responsive design",
50357
+ "Consider keyboard navigation"
50358
+ ],
50359
+ qualityChecklist: [
50360
+ "Components are accessible (ARIA labels, roles)",
50361
+ "Loading states are handled",
50362
+ "Error boundaries catch failures gracefully",
50363
+ "Forms have proper validation feedback",
50364
+ "Images have alt text"
50365
+ ],
50366
+ delegationTriggers: [
50367
+ {
50368
+ keywords: ["API", "endpoint", "database", "backend", "server"],
50369
+ suggestedAgent: "backend",
50370
+ reason: "Backend changes should be handled by backend specialist"
50371
+ },
50372
+ {
50373
+ keywords: ["security", "XSS", "CSRF", "sanitize"],
50374
+ suggestedAgent: "security",
50375
+ reason: "Security concerns require specialized review"
50376
+ }
50377
+ ],
50378
+ antiPatterns: [
50379
+ "Avoid inline styles for reusable components",
50380
+ "Don't mutate state directly",
50381
+ "Avoid excessive re-renders",
50382
+ "Don't ignore accessibility requirements"
50383
+ ],
50384
+ bestPractices: [
50385
+ "Use semantic HTML elements",
50386
+ "Implement proper form validation",
50387
+ "Optimize bundle size",
50388
+ "Use React.memo for expensive components"
50389
+ ]
50390
+ };
50391
+ var SECURITY_TEMPLATE = {
50392
+ domain: "security",
50393
+ displayName: "Security Engineer",
50394
+ domainReminders: [
50395
+ "Apply OWASP Top 10 security guidelines",
50396
+ "Validate and sanitize ALL user input",
50397
+ "Use parameterized queries to prevent SQL injection",
50398
+ "Implement proper authentication and authorization",
50399
+ "Never expose sensitive data in logs or responses"
50400
+ ],
50401
+ qualityChecklist: [
50402
+ "Input validation is present at all entry points",
50403
+ "Authentication tokens are handled securely",
50404
+ "Sensitive data is encrypted at rest and in transit",
50405
+ "Error messages don't leak implementation details",
50406
+ "Dependencies are checked for known vulnerabilities"
50407
+ ],
50408
+ delegationTriggers: [
50409
+ {
50410
+ keywords: ["performance", "optimization", "speed", "latency"],
50411
+ suggestedAgent: "backend",
50412
+ reason: "Performance optimization is a backend concern"
50413
+ }
50414
+ ],
50415
+ antiPatterns: [
50416
+ "Never trust user input without validation",
50417
+ "Don't store passwords in plain text",
50418
+ "Avoid security through obscurity",
50419
+ "Don't disable security features for convenience"
50420
+ ],
50421
+ bestPractices: [
50422
+ "Follow the principle of least privilege",
50423
+ "Implement defense in depth",
50424
+ "Use secure defaults",
50425
+ "Fail securely (deny by default)"
50426
+ ]
50427
+ };
50428
+ var QUALITY_TEMPLATE = {
50429
+ domain: "quality",
50430
+ displayName: "Quality Assurance Engineer",
50431
+ domainReminders: [
50432
+ "Write tests that verify behavior, not implementation",
50433
+ "Cover edge cases and error scenarios",
50434
+ "Ensure test isolation (no shared state)",
50435
+ "Use meaningful test descriptions",
50436
+ "Follow the Arrange-Act-Assert pattern"
50437
+ ],
50438
+ qualityChecklist: [
50439
+ "Unit tests cover critical paths",
50440
+ "Integration tests verify component interactions",
50441
+ "Edge cases are tested",
50442
+ "Error handling is verified",
50443
+ "Tests are maintainable and readable"
50444
+ ],
50445
+ delegationTriggers: [
50446
+ {
50447
+ keywords: ["implement", "build", "create", "develop"],
50448
+ suggestedAgent: "backend",
50449
+ reason: "Implementation tasks should go to domain specialists"
50450
+ },
50451
+ {
50452
+ keywords: ["security", "vulnerability", "penetration"],
50453
+ suggestedAgent: "security",
50454
+ reason: "Security testing requires specialized expertise"
50455
+ }
50456
+ ],
50457
+ antiPatterns: [
50458
+ "Avoid testing implementation details",
50459
+ "Don't use flaky tests",
50460
+ "Avoid excessive mocking",
50461
+ "Don't ignore failing tests"
50462
+ ],
50463
+ bestPractices: [
50464
+ "Test behavior, not implementation",
50465
+ "Use descriptive test names",
50466
+ "Keep tests independent",
50467
+ "Follow the testing pyramid"
50468
+ ]
50469
+ };
50470
+ var ARCHITECTURE_TEMPLATE = {
50471
+ domain: "architecture",
50472
+ displayName: "Software Architect",
50473
+ domainReminders: [
50474
+ "Consider scalability implications",
50475
+ "Document architectural decisions (ADRs)",
50476
+ "Evaluate trade-offs explicitly",
50477
+ "Design for maintainability",
50478
+ "Consider operational concerns"
50479
+ ],
50480
+ qualityChecklist: [
50481
+ "Architecture supports future scaling",
50482
+ "Components have clear boundaries",
50483
+ "Dependencies are managed properly",
50484
+ "System is observable (logging, metrics)",
50485
+ "Failure modes are handled"
50486
+ ],
50487
+ delegationTriggers: [
50488
+ {
50489
+ keywords: ["implement", "code", "fix", "bug"],
50490
+ suggestedAgent: "backend",
50491
+ reason: "Implementation details should be handled by domain specialists"
50492
+ },
50493
+ {
50494
+ keywords: ["security", "compliance", "audit"],
50495
+ suggestedAgent: "security",
50496
+ reason: "Security architecture needs specialized review"
50497
+ }
50498
+ ],
50499
+ antiPatterns: [
50500
+ "Avoid premature optimization",
50501
+ "Don't over-engineer solutions",
50502
+ "Avoid tight coupling between components",
50503
+ "Don't ignore non-functional requirements"
50504
+ ],
50505
+ bestPractices: [
50506
+ "Design for change",
50507
+ "Use well-known patterns",
50508
+ "Document decisions and rationale",
50509
+ "Consider operational requirements"
50510
+ ]
50511
+ };
50512
+ var DEVOPS_TEMPLATE = {
50513
+ domain: "devops",
50514
+ displayName: "DevOps Engineer",
50515
+ domainReminders: [
50516
+ "Automate repetitive tasks",
50517
+ "Implement proper monitoring and alerting",
50518
+ "Follow infrastructure as code principles",
50519
+ "Consider disaster recovery",
50520
+ "Optimize for reliability and cost"
50521
+ ],
50522
+ qualityChecklist: [
50523
+ "Deployments are automated and repeatable",
50524
+ "Monitoring covers key metrics",
50525
+ "Alerts are actionable",
50526
+ "Backups are tested",
50527
+ "Security is integrated into CI/CD"
50528
+ ],
50529
+ delegationTriggers: [
50530
+ {
50531
+ keywords: ["code", "feature", "bug", "implement"],
50532
+ suggestedAgent: "backend",
50533
+ reason: "Application code changes should go to developers"
50534
+ },
50535
+ {
50536
+ keywords: ["security", "credentials", "secrets"],
50537
+ suggestedAgent: "security",
50538
+ reason: "Security-sensitive changes need security review"
50539
+ }
50540
+ ],
50541
+ antiPatterns: [
50542
+ "Avoid manual deployments",
50543
+ "Don't store secrets in code",
50544
+ "Avoid single points of failure",
50545
+ "Don't ignore monitoring gaps"
50546
+ ],
50547
+ bestPractices: [
50548
+ "Use infrastructure as code",
50549
+ "Implement CI/CD pipelines",
50550
+ "Follow GitOps practices",
50551
+ "Use immutable infrastructure"
50552
+ ]
50553
+ };
50554
+ var WRITER_TEMPLATE = {
50555
+ domain: "writer",
50556
+ displayName: "Technical Writer",
50557
+ domainReminders: [
50558
+ "Write for the target audience",
50559
+ "Use clear, concise language",
50560
+ "Include practical examples",
50561
+ "Structure content logically",
50562
+ "Keep documentation up to date"
50563
+ ],
50564
+ qualityChecklist: [
50565
+ "Documentation matches current code",
50566
+ "Examples are working and tested",
50567
+ "Content is well-organized",
50568
+ "Technical terms are explained",
50569
+ "Links and references are valid"
50570
+ ],
50571
+ delegationTriggers: [
50572
+ {
50573
+ keywords: ["implement", "code", "fix", "develop"],
50574
+ suggestedAgent: "backend",
50575
+ reason: "Code changes should be handled by developers"
50576
+ }
50577
+ ],
50578
+ antiPatterns: [
50579
+ "Avoid jargon without explanation",
50580
+ "Don't assume reader knowledge",
50581
+ "Avoid outdated examples",
50582
+ "Don't ignore code comments"
50583
+ ],
50584
+ bestPractices: [
50585
+ "Use consistent terminology",
50586
+ "Include code examples",
50587
+ "Keep documentation near code",
50588
+ "Update docs with code changes"
50589
+ ]
50590
+ };
50591
+ var STANDARD_TEMPLATE = {
50592
+ domain: "standard",
50593
+ displayName: "General Assistant",
50594
+ domainReminders: [
50595
+ "Understand the task before starting",
50596
+ "Ask clarifying questions when needed",
50597
+ "Break complex tasks into smaller steps",
50598
+ "Verify your work before completing",
50599
+ "Document your changes"
50600
+ ],
50601
+ qualityChecklist: [
50602
+ "Task requirements are understood",
50603
+ "Changes are tested",
50604
+ "Code follows project conventions",
50605
+ "Documentation is updated",
50606
+ "No regressions introduced"
50607
+ ],
50608
+ delegationTriggers: [
50609
+ {
50610
+ keywords: ["security", "vulnerability", "authentication"],
50611
+ suggestedAgent: "security",
50612
+ reason: "Security tasks need specialized attention"
50613
+ },
50614
+ {
50615
+ keywords: ["test", "testing", "QA", "quality"],
50616
+ suggestedAgent: "quality",
50617
+ reason: "Testing benefits from QA expertise"
50618
+ },
50619
+ {
50620
+ keywords: ["architecture", "design", "scalability"],
50621
+ suggestedAgent: "architecture",
50622
+ reason: "Architectural decisions need careful consideration"
50623
+ }
50624
+ ],
50625
+ antiPatterns: [
50626
+ "Avoid making changes without understanding context",
50627
+ "Don't skip testing",
50628
+ "Avoid large, monolithic changes",
50629
+ "Don't ignore existing patterns"
50630
+ ],
50631
+ bestPractices: [
50632
+ "Follow existing code conventions",
50633
+ "Write self-documenting code",
50634
+ "Test your changes",
50635
+ "Keep changes focused"
50636
+ ]
50637
+ };
50638
+ var AGENT_TEMPLATES = {
50639
+ backend: BACKEND_TEMPLATE,
50640
+ frontend: FRONTEND_TEMPLATE,
50641
+ fullstack: { ...BACKEND_TEMPLATE, domain: "fullstack", displayName: "Fullstack Engineer" },
50642
+ security: SECURITY_TEMPLATE,
50643
+ quality: QUALITY_TEMPLATE,
50644
+ architecture: ARCHITECTURE_TEMPLATE,
50645
+ devops: DEVOPS_TEMPLATE,
50646
+ data: { ...BACKEND_TEMPLATE, domain: "data", displayName: "Data Engineer" },
50647
+ mobile: { ...FRONTEND_TEMPLATE, domain: "mobile", displayName: "Mobile Engineer" },
50648
+ writer: WRITER_TEMPLATE,
50649
+ researcher: { ...STANDARD_TEMPLATE, domain: "researcher", displayName: "Researcher" },
50650
+ standard: STANDARD_TEMPLATE
50651
+ };
50652
+ function getAgentTemplate(domain) {
50653
+ return AGENT_TEMPLATES[domain] || STANDARD_TEMPLATE;
50654
+ }
50655
+ function isValidAgentDomain(domain) {
50656
+ return domain in AGENT_TEMPLATES;
50657
+ }
50658
+ function getDelegationSuggestions(text, currentDomain) {
50659
+ const template = getAgentTemplate(currentDomain);
50660
+ const suggestions = [];
50661
+ const textLower = text.toLowerCase();
50662
+ for (const trigger of template.delegationTriggers) {
50663
+ const matchedKeywords = trigger.keywords.filter(
50664
+ (kw) => textLower.includes(kw.toLowerCase())
50665
+ );
50666
+ if (matchedKeywords.length > 0) {
50667
+ suggestions.push({
50668
+ agent: trigger.suggestedAgent,
50669
+ reason: trigger.reason,
50670
+ keywords: matchedKeywords
50671
+ });
50672
+ }
50673
+ }
50674
+ return suggestions;
50675
+ }
50676
+
50677
+ // src/agents/agent-instruction-injector.ts
50678
+ var DEFAULT_AGENT_CONFIG = {
50679
+ enabled: true,
50680
+ reminderFrequency: 5,
50681
+ delegationDetection: true,
50682
+ minDelegationKeywords: 1,
50683
+ includeQualityChecklist: true,
50684
+ qualityChecklistFrequency: 10,
50685
+ includeAntiPatterns: true
50686
+ };
50687
+ var AgentInstructionInjector = class {
50688
+ name = "agent-template";
50689
+ config;
50690
+ lastReminderTurn = 0;
50691
+ lastQualityCheckTurn = 0;
50692
+ currentDomain;
50693
+ recentTaskText = "";
50694
+ constructor(config) {
50695
+ this.config = {
50696
+ ...DEFAULT_AGENT_CONFIG,
50697
+ ...config
50698
+ };
50699
+ logger.debug("AgentInstructionInjector initialized", {
50700
+ enabled: this.config.enabled,
50701
+ reminderFrequency: this.config.reminderFrequency
50702
+ });
50703
+ }
50704
+ /**
50705
+ * Set the current agent domain
50706
+ */
50707
+ setDomain(domain) {
50708
+ if (isValidAgentDomain(domain)) {
50709
+ this.currentDomain = domain;
50710
+ logger.debug("Agent domain set", { domain });
50711
+ } else {
50712
+ this.currentDomain = "standard";
50713
+ logger.debug("Unknown domain, using standard", { domain });
50714
+ }
50715
+ }
50716
+ /**
50717
+ * Get the current domain
50718
+ */
50719
+ getDomain() {
50720
+ return this.currentDomain;
50721
+ }
50722
+ /**
50723
+ * Check if provider should generate instructions
50724
+ */
50725
+ shouldGenerate(context) {
50726
+ if (!this.config.enabled) {
50727
+ return false;
50728
+ }
50729
+ const domain = this.resolveDomain(context);
50730
+ if (!domain) {
50731
+ return false;
50732
+ }
50733
+ const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
50734
+ const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
50735
+ const turnsSinceQuality = context.turnCount - this.lastQualityCheckTurn;
50736
+ const qualityDue = this.config.includeQualityChecklist && turnsSinceQuality >= this.config.qualityChecklistFrequency;
50737
+ const hasDelegationTriggers = this.config.delegationDetection && this.checkDelegationTriggers(context);
50738
+ return reminderDue || qualityDue || hasDelegationTriggers;
50739
+ }
50740
+ /**
50741
+ * Generate instructions based on agent domain
50742
+ */
50743
+ async getInstructions(context) {
50744
+ const instructions = [];
50745
+ const domain = this.resolveDomain(context);
50746
+ if (!domain) {
50747
+ return instructions;
50748
+ }
50749
+ const template = getAgentTemplate(domain);
50750
+ const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
50751
+ const turnsSinceQuality = context.turnCount - this.lastQualityCheckTurn;
50752
+ if (turnsSinceReminder >= this.config.reminderFrequency) {
50753
+ const reminderContent = this.formatDomainReminders(template);
50754
+ instructions.push({
50755
+ type: "delegation",
50756
+ priority: "normal",
50757
+ content: reminderContent,
50758
+ source: "automatosx",
50759
+ createdAt: Date.now(),
50760
+ expiresAfter: this.config.reminderFrequency,
50761
+ id: `agent-reminder-${domain}-${Date.now()}`
50762
+ });
50763
+ this.lastReminderTurn = context.turnCount;
50764
+ }
50765
+ if (this.config.includeQualityChecklist && turnsSinceQuality >= this.config.qualityChecklistFrequency) {
50766
+ const checklistContent = this.formatQualityChecklist(template);
50767
+ instructions.push({
50768
+ type: "delegation",
50769
+ priority: "normal",
50770
+ content: checklistContent,
50771
+ source: "automatosx",
50772
+ createdAt: Date.now(),
50773
+ expiresAfter: this.config.qualityChecklistFrequency,
50774
+ id: `agent-quality-${domain}-${Date.now()}`
50775
+ });
50776
+ this.lastQualityCheckTurn = context.turnCount;
50777
+ }
50778
+ if (this.config.delegationDetection) {
50779
+ const taskText = this.extractTaskText(context);
50780
+ if (taskText !== this.recentTaskText) {
50781
+ this.recentTaskText = taskText;
50782
+ const delegationContent = this.checkAndFormatDelegation(template, taskText);
50783
+ if (delegationContent) {
50784
+ instructions.push({
50785
+ type: "delegation",
50786
+ priority: "high",
50787
+ content: delegationContent,
50788
+ source: "automatosx",
50789
+ createdAt: Date.now(),
50790
+ expiresAfter: 3,
50791
+ id: `agent-delegation-${Date.now()}`
50792
+ });
50793
+ }
50794
+ }
50795
+ }
50796
+ logger.debug("Agent instructions generated", {
50797
+ domain,
50798
+ instructionCount: instructions.length
50799
+ });
50800
+ return instructions;
50801
+ }
50802
+ /**
50803
+ * Resolve domain from context or current setting
50804
+ */
50805
+ resolveDomain(context) {
50806
+ if (context.agentName && isValidAgentDomain(context.agentName)) {
50807
+ return context.agentName;
50808
+ }
50809
+ return this.currentDomain;
50810
+ }
50811
+ /**
50812
+ * Extract task text from context for delegation detection
50813
+ */
50814
+ extractTaskText(context) {
50815
+ const parts = [];
50816
+ if (context.currentTask) {
50817
+ parts.push(context.currentTask);
50818
+ }
50819
+ for (const todo of context.todos.filter((t) => t.status === "in_progress")) {
50820
+ parts.push(todo.content);
50821
+ }
50822
+ return parts.join(" ");
50823
+ }
50824
+ /**
50825
+ * Check if delegation triggers are present
50826
+ */
50827
+ checkDelegationTriggers(context) {
50828
+ const domain = this.resolveDomain(context);
50829
+ if (!domain) return false;
50830
+ const taskText = this.extractTaskText(context);
50831
+ if (!taskText) return false;
50832
+ const suggestions = getDelegationSuggestions(taskText, domain);
50833
+ return suggestions.some((s) => s.keywords.length >= this.config.minDelegationKeywords);
50834
+ }
50835
+ /**
50836
+ * Format domain reminders
50837
+ */
50838
+ formatDomainReminders(template) {
50839
+ const lines = [
50840
+ `## ${template.displayName} Reminders`,
50841
+ ""
50842
+ ];
50843
+ for (const reminder of template.domainReminders) {
50844
+ lines.push(`- ${reminder}`);
50845
+ }
50846
+ if (this.config.includeAntiPatterns && template.antiPatterns.length > 0) {
50847
+ lines.push("");
50848
+ lines.push("**Avoid:**");
50849
+ for (const antiPattern of template.antiPatterns.slice(0, 3)) {
50850
+ lines.push(`- ${antiPattern}`);
50851
+ }
50852
+ }
50853
+ return lines.join("\n");
50854
+ }
50855
+ /**
50856
+ * Format quality checklist
50857
+ */
50858
+ formatQualityChecklist(template) {
50859
+ const lines = [
50860
+ `## Quality Checklist (${template.displayName})`,
50861
+ "",
50862
+ "Before completing, verify:"
50863
+ ];
50864
+ for (const item of template.qualityChecklist) {
50865
+ lines.push(`- [ ] ${item}`);
50866
+ }
50867
+ return lines.join("\n");
50868
+ }
50869
+ /**
50870
+ * Check for delegation triggers and format suggestion
50871
+ */
50872
+ checkAndFormatDelegation(template, taskText) {
50873
+ const suggestions = getDelegationSuggestions(taskText, template.domain);
50874
+ const relevantSuggestions = suggestions.filter(
50875
+ (s) => s.keywords.length >= this.config.minDelegationKeywords
50876
+ );
50877
+ if (relevantSuggestions.length === 0) {
50878
+ return null;
50879
+ }
50880
+ const lines = [
50881
+ "## Delegation Suggestion",
50882
+ ""
50883
+ ];
50884
+ for (const suggestion of relevantSuggestions) {
50885
+ lines.push(`**Consider delegating to @${suggestion.agent}**`);
50886
+ lines.push(`- Reason: ${suggestion.reason}`);
50887
+ lines.push(`- Triggered by: ${suggestion.keywords.join(", ")}`);
50888
+ lines.push("");
50889
+ }
50890
+ lines.push("Use `DELEGATE TO @agent: task` or `@agent task` syntax to delegate.");
50891
+ return lines.join("\n");
50892
+ }
50893
+ /**
50894
+ * Get current configuration
50895
+ */
50896
+ getConfig() {
50897
+ return { ...this.config };
50898
+ }
50899
+ /**
50900
+ * Update configuration
50901
+ */
50902
+ updateConfig(updates) {
50903
+ this.config = {
50904
+ ...this.config,
50905
+ ...updates
50906
+ };
50907
+ logger.debug("AgentInstructionInjector config updated", {
50908
+ enabled: this.config.enabled
50909
+ });
50910
+ }
50911
+ /**
50912
+ * Reset state
50913
+ */
50914
+ reset() {
50915
+ this.lastReminderTurn = 0;
50916
+ this.lastQualityCheckTurn = 0;
50917
+ this.recentTaskText = "";
50918
+ logger.debug("AgentInstructionInjector reset");
50919
+ }
50920
+ };
50921
+
50922
+ // src/core/orchestration/orchestration-service.ts
50923
+ var OrchestrationService = class {
50924
+ config;
50925
+ injector;
50926
+ tokenBudgetManager;
50927
+ workflowModeManager;
50928
+ agentInjector;
50929
+ todoProvider;
50930
+ memoryProvider;
50931
+ sessionProvider;
50932
+ turnCount = 0;
50933
+ currentTodos = [];
50934
+ constructor(serviceConfig = {}) {
50935
+ this.config = {
50936
+ ...DEFAULT_ORCHESTRATION_CONFIG,
50937
+ ...serviceConfig
50938
+ };
50939
+ this.injector = new OrchestrationInstructionInjector(this.config);
50940
+ this.tokenBudgetManager = new TokenBudgetManager(this.config.tokenBudget);
50941
+ this.workflowModeManager = new WorkflowModeManager();
50942
+ this.agentInjector = new AgentInstructionInjector({
50943
+ enabled: this.config.agentTemplates?.enabled ?? true,
50944
+ reminderFrequency: this.config.agentTemplates?.reminderFrequency ?? 5
50945
+ });
50946
+ this.initializeProviders(serviceConfig);
50947
+ logger.debug("OrchestrationService initialized", {
50948
+ todoEnabled: this.config.todoIntegration?.enabled,
50949
+ memoryEnabled: this.config.memoryIntegration?.enabled,
50950
+ sessionEnabled: this.config.sessionIntegration?.enabled,
50951
+ agentTemplatesEnabled: this.config.agentTemplates?.enabled
50952
+ });
50953
+ }
50954
+ /**
50955
+ * Initialize instruction providers
50956
+ */
50957
+ initializeProviders(serviceConfig) {
50958
+ if (this.config.todoIntegration?.enabled !== false) {
50959
+ this.todoProvider = new TodoInstructionProvider({
50960
+ enabled: true,
50961
+ reminderFrequency: this.config.todoIntegration?.reminderFrequency ?? 3,
50962
+ compactMode: this.config.todoIntegration?.compactMode ?? false
50963
+ });
50964
+ this.injector.registerProvider(this.todoProvider);
50965
+ }
50966
+ if (this.config.memoryIntegration?.enabled !== false && serviceConfig.memorySearchProvider) {
50967
+ this.memoryProvider = new MemoryInstructionProvider(
50968
+ serviceConfig.memorySearchProvider,
50969
+ {
50970
+ enabled: true,
50971
+ maxEntries: this.config.memoryIntegration?.maxEntries ?? 5,
50972
+ minRelevance: this.config.memoryIntegration?.minRelevance ?? 0.5
50973
+ }
50974
+ );
50975
+ this.injector.registerProvider(this.memoryProvider);
50976
+ }
50977
+ if (this.config.sessionIntegration?.enabled !== false) {
50978
+ this.sessionProvider = new SessionInstructionProvider(
50979
+ serviceConfig.sessionStateProvider,
50980
+ {
50981
+ enabled: true,
50982
+ showCollaboration: this.config.sessionIntegration?.showCollaboration ?? true,
50983
+ showProgress: true,
50984
+ reminderFrequency: 5,
50985
+ showHandoffContext: true
50986
+ }
50987
+ );
50988
+ this.injector.registerProvider(this.sessionProvider);
50989
+ }
50990
+ if (this.config.agentTemplates?.enabled !== false) {
50991
+ if (serviceConfig.agentDomain) {
50992
+ this.agentInjector.setDomain(serviceConfig.agentDomain);
50993
+ }
50994
+ this.injector.registerProvider(this.agentInjector);
50995
+ }
50996
+ }
50997
+ /**
50998
+ * Set the current agent domain for agent-specific instructions
50999
+ */
51000
+ setAgentDomain(domain) {
51001
+ this.agentInjector.setDomain(domain);
51002
+ logger.debug("Agent domain set", { domain });
51003
+ }
51004
+ /**
51005
+ * Set the memory search provider
51006
+ */
51007
+ setMemoryProvider(provider) {
51008
+ if (this.memoryProvider) {
51009
+ this.memoryProvider.setSearchProvider(provider);
51010
+ } else if (this.config.memoryIntegration?.enabled !== false) {
51011
+ this.memoryProvider = new MemoryInstructionProvider(provider, {
51012
+ enabled: true,
51013
+ maxEntries: this.config.memoryIntegration?.maxEntries ?? 5,
51014
+ minRelevance: this.config.memoryIntegration?.minRelevance ?? 0.5
51015
+ });
51016
+ this.injector.registerProvider(this.memoryProvider);
51017
+ }
51018
+ }
51019
+ /**
51020
+ * Set the session state provider
51021
+ */
51022
+ setSessionProvider(provider) {
51023
+ if (this.sessionProvider) {
51024
+ this.sessionProvider.setStateProvider(provider);
51025
+ }
51026
+ }
51027
+ /**
51028
+ * Update the current todo list
51029
+ */
51030
+ updateTodos(todos) {
51031
+ this.currentTodos = todos;
51032
+ }
51033
+ /**
51034
+ * Set the workflow mode
51035
+ */
51036
+ setWorkflowMode(mode) {
51037
+ this.workflowModeManager.setMode(mode);
51038
+ logger.debug("Workflow mode set", { mode });
51039
+ }
51040
+ /**
51041
+ * Get current workflow mode
51042
+ */
51043
+ getWorkflowMode() {
51044
+ return this.workflowModeManager.getCurrentMode();
51045
+ }
51046
+ /**
51047
+ * Check if a tool is allowed in current workflow mode
51048
+ */
51049
+ isToolAllowed(toolName) {
51050
+ return this.workflowModeManager.isToolAllowed(toolName);
51051
+ }
51052
+ /**
51053
+ * Filter tools based on current workflow mode
51054
+ */
51055
+ filterTools(tools) {
51056
+ return this.workflowModeManager.filterTools(tools);
51057
+ }
51058
+ /**
51059
+ * Increment turn count (called after each agent response)
51060
+ */
51061
+ incrementTurn() {
51062
+ this.turnCount++;
51063
+ }
51064
+ /**
51065
+ * Get current turn count
51066
+ */
51067
+ getTurnCount() {
51068
+ return this.turnCount;
51069
+ }
51070
+ /**
51071
+ * Generate and inject instructions for the current context
51072
+ */
51073
+ async injectInstructions(options = {}) {
51074
+ const context = {
51075
+ todos: this.currentTodos,
51076
+ turnCount: this.turnCount,
51077
+ workflowMode: this.workflowModeManager.getCurrentMode(),
51078
+ currentTask: options.task,
51079
+ agentName: options.agentName,
51080
+ sessionId: options.sessionId,
51081
+ parentAgent: options.parentAgent
51082
+ };
51083
+ const result = await this.injector.inject(context);
51084
+ logger.debug("Instructions injected", {
51085
+ instructionCount: result.instructions.length,
51086
+ tokensUsed: result.allocation.tokensUsed,
51087
+ hasInstructions: result.hasInstructions
51088
+ });
51089
+ return {
51090
+ content: result.formattedText,
51091
+ instructions: result.instructions,
51092
+ tokenCount: result.allocation.tokensUsed,
51093
+ applied: result.hasInstructions
51094
+ };
51095
+ }
51096
+ /**
51097
+ * Format instructions as system reminder tags
51098
+ */
51099
+ formatAsSystemReminder(content) {
51100
+ if (!content || content.trim().length === 0) {
51101
+ return "";
51102
+ }
51103
+ return `<system-reminder>
51104
+ ${content}
51105
+ </system-reminder>`;
51106
+ }
51107
+ /**
51108
+ * Get debug information about current orchestration state
51109
+ */
51110
+ getDebugInfo() {
51111
+ const budgetConfig = this.tokenBudgetManager.getConfig();
51112
+ const providers = this.injector.getProviders().map((p) => p.name);
51113
+ return {
51114
+ turnCount: this.turnCount,
51115
+ workflowMode: this.workflowModeManager.getCurrentMode(),
51116
+ todoCount: this.currentTodos.length,
51117
+ providers,
51118
+ tokenBudget: {
51119
+ used: 0,
51120
+ // Would need to track this
51121
+ total: budgetConfig.maxTotal,
51122
+ remaining: budgetConfig.maxTotal
51123
+ }
51124
+ };
51125
+ }
51126
+ /**
51127
+ * Reset all state (for new conversations)
51128
+ */
51129
+ reset() {
51130
+ this.turnCount = 0;
51131
+ this.currentTodos = [];
51132
+ this.workflowModeManager.reset();
51133
+ this.agentInjector.reset();
51134
+ this.injector.clearCache();
51135
+ if (this.todoProvider) {
51136
+ this.todoProvider.reset();
51137
+ }
51138
+ if (this.memoryProvider) {
51139
+ this.memoryProvider.clearCache();
51140
+ }
51141
+ if (this.sessionProvider) {
51142
+ this.sessionProvider.reset();
51143
+ }
51144
+ logger.debug("OrchestrationService reset");
51145
+ }
51146
+ /**
51147
+ * Update configuration
51148
+ */
51149
+ updateConfig(updates) {
51150
+ this.config = {
51151
+ ...this.config,
51152
+ ...updates
51153
+ };
51154
+ if (updates.tokenBudget) {
51155
+ this.tokenBudgetManager = new TokenBudgetManager(updates.tokenBudget);
51156
+ }
51157
+ logger.debug("OrchestrationService config updated", { updates });
51158
+ }
51159
+ /**
51160
+ * Get current configuration
51161
+ */
51162
+ getConfig() {
51163
+ return { ...this.config };
51164
+ }
51165
+ };
51166
+
51167
+ // src/cli/commands/debug-instructions.ts
51168
+ var debugInstructionsCommand = {
51169
+ command: "debug:instructions",
51170
+ describe: "Show current embedded instructions state (v11.3.0)",
51171
+ builder: (yargs2) => {
51172
+ return yargs2.option("tokens", {
51173
+ alias: "t",
51174
+ describe: "Show token budget details",
51175
+ type: "boolean",
51176
+ default: false
51177
+ }).option("providers", {
51178
+ alias: "p",
51179
+ describe: "Show registered instruction providers",
51180
+ type: "boolean",
51181
+ default: false
51182
+ }).option("templates", {
51183
+ describe: "Show available agent templates",
51184
+ type: "boolean",
51185
+ default: false
51186
+ }).option("agent", {
51187
+ alias: "a",
51188
+ describe: "Show template for specific agent domain",
51189
+ type: "string"
51190
+ }).option("verbose", {
51191
+ alias: "v",
51192
+ describe: "Show verbose output",
51193
+ type: "boolean",
51194
+ default: false
51195
+ }).example("$0 debug:instructions", "Show overall instruction state").example("$0 debug:instructions --tokens", "Show token budget details").example("$0 debug:instructions --providers", "List instruction providers").example("$0 debug:instructions --templates", "List agent templates").example("$0 debug:instructions --agent backend", "Show backend agent template");
51196
+ },
51197
+ handler: async (argv) => {
51198
+ try {
51199
+ if (argv.tokens) {
51200
+ displayTokenBudget(argv.verbose);
51201
+ return;
51202
+ }
51203
+ if (argv.providers) {
51204
+ displayProviders(argv.verbose);
51205
+ return;
51206
+ }
51207
+ if (argv.templates) {
51208
+ displayAgentTemplates(argv.verbose);
51209
+ return;
51210
+ }
51211
+ if (argv.agent) {
51212
+ displayAgentTemplate(argv.agent, argv.verbose);
51213
+ return;
51214
+ }
51215
+ displayOverallState(argv.verbose);
51216
+ } catch (error) {
51217
+ const err = error instanceof Error ? error : new Error(String(error));
51218
+ console.error(chalk5.red.bold(`
51219
+ \u274C Error: ${err.message}
51220
+ `));
51221
+ logger.error("Debug instructions command failed", { error: err.message });
51222
+ process.exit(1);
51223
+ }
51224
+ }
51225
+ };
51226
+ function displayOverallState(verbose) {
51227
+ console.log(chalk5.blue.bold("\n\u{1F50D} Embedded Instructions Debug Info\n"));
51228
+ console.log(chalk5.dim("\u2550".repeat(60)));
51229
+ const service = new OrchestrationService();
51230
+ const debugInfo = service.getDebugInfo();
51231
+ console.log(chalk5.cyan("\n\u{1F4CA} Current State"));
51232
+ console.log(chalk5.dim("\u2500".repeat(40)));
51233
+ console.log(` Turn count: ${chalk5.yellow(debugInfo.turnCount)}`);
51234
+ console.log(` Workflow mode: ${chalk5.cyan(debugInfo.workflowMode)}`);
51235
+ console.log(` Active todos: ${chalk5.yellow(debugInfo.todoCount)}`);
51236
+ console.log(` Registered providers: ${chalk5.green(debugInfo.providers.length)}`);
51237
+ console.log(chalk5.cyan("\n\u{1F4B0} Token Budget"));
51238
+ console.log(chalk5.dim("\u2500".repeat(40)));
51239
+ console.log(` Used: ${chalk5.yellow(debugInfo.tokenBudget.used)} / ${debugInfo.tokenBudget.total}`);
51240
+ const usagePercent = Math.round(debugInfo.tokenBudget.used / debugInfo.tokenBudget.total * 100);
51241
+ const barLength = 30;
51242
+ const filledLength = Math.round(usagePercent / 100 * barLength);
51243
+ const bar = "\u2588".repeat(filledLength) + "\u2591".repeat(barLength - filledLength);
51244
+ const barColor = usagePercent > 80 ? chalk5.red : usagePercent > 50 ? chalk5.yellow : chalk5.green;
51245
+ console.log(` ${barColor(bar)} ${usagePercent}%`);
51246
+ if (debugInfo.providers.length > 0) {
51247
+ console.log(chalk5.cyan("\n\u{1F50C} Active Providers"));
51248
+ console.log(chalk5.dim("\u2500".repeat(40)));
51249
+ debugInfo.providers.forEach((provider, index) => {
51250
+ console.log(` ${index + 1}. ${chalk5.green(provider)}`);
51251
+ });
51252
+ }
51253
+ console.log(chalk5.cyan("\n\u{1F504} Workflow Modes"));
51254
+ console.log(chalk5.dim("\u2500".repeat(40)));
51255
+ Object.keys(WORKFLOW_MODES).forEach((mode) => {
51256
+ const isCurrent = mode === debugInfo.workflowMode;
51257
+ const prefix = isCurrent ? chalk5.green("\u25BA") : " ";
51258
+ const modeText = isCurrent ? chalk5.green.bold(mode) : chalk5.gray(mode);
51259
+ console.log(` ${prefix} ${modeText}`);
51260
+ });
51261
+ console.log(chalk5.dim("\n" + "\u2550".repeat(60)));
51262
+ console.log(chalk5.gray("\nUse --tokens, --providers, or --templates for detailed info.\n"));
51263
+ }
51264
+ function displayTokenBudget(verbose) {
51265
+ console.log(chalk5.blue.bold("\n\u{1F4B0} Token Budget Details\n"));
51266
+ console.log(chalk5.dim("\u2500".repeat(50)));
51267
+ const budgetManager = new TokenBudgetManager();
51268
+ const config = budgetManager.getConfig();
51269
+ console.log(`
51270
+ Total budget: ${chalk5.cyan(config.maxTotal)} tokens`);
51271
+ console.log(` Critical reserve: ${chalk5.yellow(config.criticalReserve)} tokens`);
51272
+ console.log(` Available: ${chalk5.green(config.maxTotal - config.criticalReserve)} tokens`);
51273
+ console.log(chalk5.cyan("\n Per-Type Allocations:"));
51274
+ const typeAllocations = [
51275
+ { type: "task", budget: 500, description: "Todo/task reminders" },
51276
+ { type: "memory", budget: 400, description: "Memory context" },
51277
+ { type: "session", budget: 300, description: "Session state" },
51278
+ { type: "delegation", budget: 300, description: "Agent delegation hints" },
51279
+ { type: "mode", budget: 200, description: "Workflow mode instructions" }
51280
+ ];
51281
+ typeAllocations.forEach(({ type, budget, description }) => {
51282
+ console.log(` \u2022 ${chalk5.cyan(type)}: ${budget} tokens`);
51283
+ if (verbose) {
51284
+ console.log(chalk5.gray(` ${description}`));
51285
+ }
51286
+ });
51287
+ console.log(chalk5.cyan("\n Token Estimation:"));
51288
+ console.log(chalk5.gray(" ~4 characters = 1 token (approximation)"));
51289
+ console.log(chalk5.gray(" Actual usage may vary by content"));
51290
+ console.log(chalk5.dim("\n\u2500".repeat(50)));
51291
+ console.log();
51292
+ }
51293
+ function displayProviders(verbose) {
51294
+ console.log(chalk5.blue.bold("\n\u{1F50C} Instruction Providers\n"));
51295
+ console.log(chalk5.dim("\u2500".repeat(50)));
51296
+ const providers = [
51297
+ {
51298
+ name: "TodoInstructionProvider",
51299
+ description: "Generates task reminders from todo list",
51300
+ triggers: "Todo state changes, periodic reminders",
51301
+ priority: "high"
51302
+ },
51303
+ {
51304
+ name: "MemoryInstructionProvider",
51305
+ description: "Injects relevant context from memory",
51306
+ triggers: "Task keywords, memory relevance",
51307
+ priority: "normal"
51308
+ },
51309
+ {
51310
+ name: "SessionInstructionProvider",
51311
+ description: "Shows multi-agent collaboration state",
51312
+ triggers: "Session changes, periodic reminders",
51313
+ priority: "normal"
51314
+ },
51315
+ {
51316
+ name: "AgentInstructionInjector",
51317
+ description: "Domain-specific reminders and delegation hints",
51318
+ triggers: "Agent domain, task keywords",
51319
+ priority: "normal"
51320
+ },
51321
+ {
51322
+ name: "WorkflowModeManager",
51323
+ description: "Mode-specific instructions and tool filtering",
51324
+ triggers: "Mode changes",
51325
+ priority: "high"
51326
+ }
51327
+ ];
51328
+ providers.forEach((provider, index) => {
51329
+ console.log(`
51330
+ ${index + 1}. ${chalk5.cyan.bold(provider.name)}`);
51331
+ console.log(chalk5.gray(` ${provider.description}`));
51332
+ if (verbose) {
51333
+ console.log(` Triggers: ${chalk5.yellow(provider.triggers)}`);
51334
+ console.log(` Priority: ${chalk5.green(provider.priority)}`);
51335
+ }
51336
+ });
51337
+ console.log(chalk5.dim("\n\u2500".repeat(50)));
51338
+ console.log();
51339
+ }
51340
+ function displayAgentTemplates(verbose) {
51341
+ console.log(chalk5.blue.bold("\n\u{1F4CB} Agent Instruction Templates\n"));
51342
+ console.log(chalk5.dim("\u2500".repeat(50)));
51343
+ for (const [domain, template] of Object.entries(AGENT_TEMPLATES)) {
51344
+ console.log(`
51345
+ ${chalk5.cyan.bold(template.displayName)} (${domain})`);
51346
+ if (verbose) {
51347
+ console.log(chalk5.gray(` Reminders: ${template.domainReminders.length}`));
51348
+ console.log(chalk5.gray(` Checklist items: ${template.qualityChecklist.length}`));
51349
+ console.log(chalk5.gray(` Delegation triggers: ${template.delegationTriggers.length}`));
51350
+ console.log(chalk5.gray(` Anti-patterns: ${template.antiPatterns.length}`));
51351
+ console.log(chalk5.gray(` Best practices: ${template.bestPractices.length}`));
51352
+ }
51353
+ }
51354
+ console.log(chalk5.dim("\n\u2500".repeat(50)));
51355
+ console.log(chalk5.gray("\nUse --agent <domain> to see template details.\n"));
51356
+ }
51357
+ function displayAgentTemplate(domain, verbose) {
51358
+ const template = AGENT_TEMPLATES[domain];
51359
+ if (!template) {
51360
+ console.error(chalk5.red.bold(`
51361
+ \u274C Unknown agent domain: ${domain}
51362
+ `));
51363
+ console.log(chalk5.gray("Available domains:"));
51364
+ Object.keys(AGENT_TEMPLATES).forEach((d) => {
51365
+ console.log(chalk5.cyan(` \u2022 ${d}`));
51366
+ });
51367
+ console.log();
51368
+ process.exit(1);
51369
+ }
51370
+ console.log(chalk5.blue.bold(`
51371
+ \u{1F4CB} ${template.displayName} Agent Template
51372
+ `));
51373
+ console.log(chalk5.dim("\u2550".repeat(60)));
51374
+ console.log(chalk5.cyan("\n\u{1F514} Domain Reminders:"));
51375
+ template.domainReminders.forEach((reminder, i) => {
51376
+ console.log(` ${i + 1}. ${reminder}`);
51377
+ });
51378
+ console.log(chalk5.cyan("\n\u2705 Quality Checklist:"));
51379
+ template.qualityChecklist.forEach((item, i) => {
51380
+ console.log(` ${i + 1}. ${item}`);
51381
+ });
51382
+ if (template.delegationTriggers.length > 0) {
51383
+ console.log(chalk5.cyan("\n\u{1F500} Delegation Triggers:"));
51384
+ template.delegationTriggers.forEach((trigger, i) => {
51385
+ console.log(` ${i + 1}. \u2192 ${chalk5.yellow(trigger.suggestedAgent)}`);
51386
+ console.log(chalk5.gray(` Keywords: ${trigger.keywords.join(", ")}`));
51387
+ if (verbose) {
51388
+ console.log(chalk5.gray(` Reason: ${trigger.reason}`));
51389
+ }
51390
+ });
51391
+ }
51392
+ if (verbose && template.antiPatterns.length > 0) {
51393
+ console.log(chalk5.red("\n\u26A0\uFE0F Anti-Patterns to Avoid:"));
51394
+ template.antiPatterns.forEach((pattern, i) => {
51395
+ console.log(` ${i + 1}. ${pattern}`);
51396
+ });
51397
+ }
51398
+ if (verbose && template.bestPractices.length > 0) {
51399
+ console.log(chalk5.green("\n\u2728 Best Practices:"));
51400
+ template.bestPractices.forEach((practice, i) => {
51401
+ console.log(` ${i + 1}. ${practice}`);
51402
+ });
51403
+ }
51404
+ console.log(chalk5.dim("\n\u2550".repeat(60)));
51405
+ console.log();
51406
+ }
51407
+
48522
51408
  // src/cli/index.ts
48523
51409
  installExitHandlers();
48524
51410
  var VERSION2 = getVersion();
@@ -48541,7 +51427,7 @@ globalTracker.mark("cli_start");
48541
51427
  type: "string",
48542
51428
  description: "Path to custom config file",
48543
51429
  global: true
48544
- }).command(setupCommand).command(initCommand).command(configureCommand).command(cliCommand).command(agentCommand).command(listCommand).command(runCommand).command(resumeCommand).command(runsCommand).command(sessionCommand).command(workspaceCommand).command(cacheCommand).command(configCommand).command(statusCommand4).command(doctorCommand2).command(cleanupCommand2).command(analyticsCommand).command(memoryCommand).command(mcpCommand).command(geminiCommand).command(providerLimitsCommand).command(providersCommand).command(flagsCommand).command(specCommand).command(genCommand).command(updateCommand).command(uninstallCommand).demandCommand(1, "You must provide a command. Run --help for usage.").help().version(VERSION2).alias("h", "help").alias("v", "version").strict().wrap(Math.min(120, yargs().terminalWidth())).parse();
51430
+ }).command(setupCommand).command(initCommand).command(configureCommand).command(cliCommand).command(agentCommand).command(listCommand).command(runCommand).command(resumeCommand).command(runsCommand).command(sessionCommand).command(workspaceCommand).command(cacheCommand).command(configCommand).command(statusCommand4).command(doctorCommand2).command(cleanupCommand2).command(analyticsCommand).command(memoryCommand).command(mcpCommand).command(geminiCommand).command(providerLimitsCommand).command(providersCommand).command(flagsCommand).command(specCommand).command(genCommand).command(updateCommand).command(uninstallCommand).command(modeCommand).command(debugInstructionsCommand).demandCommand(1, "You must provide a command. Run --help for usage.").help().version(VERSION2).alias("h", "help").alias("v", "version").strict().wrap(Math.min(120, yargs().terminalWidth())).parse();
48545
51431
  globalTracker.mark("yargs_parse_end");
48546
51432
  globalTracker.measure("yargs_parsing", "yargs_parse_start", "yargs_parse_end");
48547
51433
  globalTracker.mark("options_setup_start");