@defai.digital/automatosx 11.3.0 → 11.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3013,8 +3013,12 @@ ${fullPrompt}
3013
3013
  logger.debug(`Full prompt saved to ${debugPath}`);
3014
3014
  }
3015
3015
  const result = await this.executeCLI(fullPrompt);
3016
+ const latencyMs = Date.now() - startTime;
3016
3017
  this.health.consecutiveFailures = 0;
3017
3018
  this.health.available = true;
3019
+ this.health.errorRate = 0;
3020
+ this.health.latencyMs = latencyMs;
3021
+ this.health.lastCheck = Date.now();
3018
3022
  const response = {
3019
3023
  content: result,
3020
3024
  model: "default",
@@ -3025,7 +3029,7 @@ ${fullPrompt}
3025
3029
  completion: 0,
3026
3030
  total: 0
3027
3031
  },
3028
- latencyMs: Date.now() - startTime,
3032
+ latencyMs,
3029
3033
  finishReason: "stop",
3030
3034
  cached: false
3031
3035
  };
@@ -3045,6 +3049,8 @@ ${fullPrompt}
3045
3049
  this.health.consecutiveFailures++;
3046
3050
  this.health.available = false;
3047
3051
  this.health.errorRate = 1;
3052
+ this.health.latencyMs = Date.now() - startTime;
3053
+ this.health.lastCheck = Date.now();
3048
3054
  throw this.handleError(error);
3049
3055
  }
3050
3056
  }
@@ -3065,6 +3071,8 @@ ${fullPrompt}
3065
3071
  } catch (error) {
3066
3072
  this.health.available = false;
3067
3073
  this.health.errorRate = 1;
3074
+ this.health.lastCheck = Date.now();
3075
+ this.health.consecutiveFailures = this.health.consecutiveFailures + 1;
3068
3076
  return false;
3069
3077
  }
3070
3078
  }
@@ -3072,13 +3080,13 @@ ${fullPrompt}
3072
3080
  * Get health status
3073
3081
  */
3074
3082
  async healthCheck() {
3075
- const isAvailable = await this.isAvailable();
3083
+ await this.isAvailable();
3076
3084
  return {
3077
- available: isAvailable,
3085
+ available: this.health.available,
3078
3086
  latencyMs: this.health.latencyMs,
3079
- errorRate: isAvailable ? 0 : 1,
3080
- consecutiveFailures: isAvailable ? 0 : this.health.consecutiveFailures + 1,
3081
- lastCheckTime: Date.now()
3087
+ errorRate: this.health.errorRate,
3088
+ consecutiveFailures: this.health.consecutiveFailures,
3089
+ lastCheckTime: this.health.lastCheck
3082
3090
  };
3083
3091
  }
3084
3092
  /**
@@ -3796,8 +3804,9 @@ var init_cli_wrapper = __esm({
3796
3804
  child.stdin.write(prompt);
3797
3805
  child.stdin.end();
3798
3806
  }
3807
+ let rl = null;
3799
3808
  if (child.stdout && renderer) {
3800
- const rl = readline2__default.createInterface({
3809
+ rl = readline2__default.createInterface({
3801
3810
  input: child.stdout,
3802
3811
  crlfDelay: Infinity
3803
3812
  });
@@ -3805,6 +3814,11 @@ var init_cli_wrapper = __esm({
3805
3814
  stdout += line + "\n";
3806
3815
  renderer.processLine(line);
3807
3816
  });
3817
+ rl.on("error", (error) => {
3818
+ logger.warn("Readline error during streaming", {
3819
+ error: error.message
3820
+ });
3821
+ });
3808
3822
  } else if (child.stdout) {
3809
3823
  child.stdout.on("data", (data) => {
3810
3824
  stdout += data.toString();
@@ -3820,6 +3834,10 @@ var init_cli_wrapper = __esm({
3820
3834
  clearTimeout(timeoutHandle);
3821
3835
  timeoutHandle = null;
3822
3836
  }
3837
+ if (rl) {
3838
+ rl.close();
3839
+ rl = null;
3840
+ }
3823
3841
  this.activeProcesses.delete(child);
3824
3842
  if (hasTimedOut) {
3825
3843
  return;
@@ -3847,6 +3865,10 @@ var init_cli_wrapper = __esm({
3847
3865
  clearTimeout(timeoutHandle);
3848
3866
  timeoutHandle = null;
3849
3867
  }
3868
+ if (rl) {
3869
+ rl.close();
3870
+ rl = null;
3871
+ }
3850
3872
  this.activeProcesses.delete(child);
3851
3873
  if (!hasTimedOut) {
3852
3874
  if (renderer) {
@@ -5539,11 +5561,17 @@ ${result.content.substring(0, 1e3)}
5539
5561
  setupAutoSave() {
5540
5562
  this.autoSaveTimer = setInterval(async () => {
5541
5563
  if (this.pendingCheckpoint) {
5542
- await this.save(
5543
- this.pendingCheckpoint.workflowId,
5544
- this.pendingCheckpoint
5545
- );
5546
- this.pendingCheckpoint = null;
5564
+ try {
5565
+ await this.save(
5566
+ this.pendingCheckpoint.workflowId,
5567
+ this.pendingCheckpoint
5568
+ );
5569
+ this.pendingCheckpoint = null;
5570
+ } catch (error) {
5571
+ logger.warn("Auto-save failed", {
5572
+ error: error instanceof Error ? error.message : String(error)
5573
+ });
5574
+ }
5547
5575
  }
5548
5576
  }, this.options.autoSaveInterval);
5549
5577
  }
@@ -5555,13 +5583,29 @@ ${result.content.substring(0, 1e3)}
5555
5583
  }
5556
5584
  /**
5557
5585
  * Cleanup resources
5586
+ * BUG FIX: Flush pending checkpoint before destroying to prevent data loss
5558
5587
  */
5559
- destroy() {
5588
+ async destroy() {
5560
5589
  if (this.autoSaveTimer) {
5561
5590
  clearInterval(this.autoSaveTimer);
5562
5591
  this.autoSaveTimer = null;
5563
5592
  }
5564
- this.pendingCheckpoint = null;
5593
+ if (this.pendingCheckpoint) {
5594
+ try {
5595
+ await this.save(
5596
+ this.pendingCheckpoint.workflowId,
5597
+ this.pendingCheckpoint
5598
+ );
5599
+ logger.debug("Pending checkpoint flushed on destroy", {
5600
+ workflowId: this.pendingCheckpoint.workflowId
5601
+ });
5602
+ } catch (error) {
5603
+ logger.warn("Failed to flush pending checkpoint on destroy", {
5604
+ error: error instanceof Error ? error.message : String(error)
5605
+ });
5606
+ }
5607
+ this.pendingCheckpoint = null;
5608
+ }
5565
5609
  this.sdkCheckpointManager = null;
5566
5610
  logger.debug("CheckpointAdapter destroyed");
5567
5611
  }
@@ -7042,7 +7086,10 @@ var init_adapter2 = __esm({
7042
7086
  }
7043
7087
  if (this.checkpointAdapter) {
7044
7088
  try {
7045
- this.checkpointAdapter.destroy();
7089
+ const result = this.checkpointAdapter.destroy();
7090
+ if (result instanceof Promise) {
7091
+ await result;
7092
+ }
7046
7093
  this.checkpointAdapter = null;
7047
7094
  logger.debug("CheckpointAdapter destroyed");
7048
7095
  } catch (error) {
@@ -9273,7 +9320,7 @@ var PRECOMPILED_CONFIG = {
9273
9320
  "enableFreeTierPrioritization": true,
9274
9321
  "enableWorkloadAwareRouting": true
9275
9322
  },
9276
- "version": "11.3.0"
9323
+ "version": "11.3.1"
9277
9324
  };
9278
9325
 
9279
9326
  // src/core/config/schemas.ts
@@ -10127,6 +10174,7 @@ async function saveConfigFile(path7, config) {
10127
10174
  content = JSON.stringify(config, null, 2);
10128
10175
  }
10129
10176
  await writeFile(path7, content, "utf-8");
10177
+ configCache.clear();
10130
10178
  logger.info("Config saved successfully", { path: normalizePath(path7), format: ext });
10131
10179
  } catch (error) {
10132
10180
  if (error instanceof ConfigError) {
@@ -13201,12 +13249,6 @@ var setupCommand = {
13201
13249
  describe: "Force setup even if .automatosx already exists",
13202
13250
  type: "boolean",
13203
13251
  default: false
13204
- }).option("spec-kit", {
13205
- describe: "Automatically initialize GitHub Spec-Kit for spec-driven development",
13206
- type: "boolean"
13207
- }).option("skip-spec-kit", {
13208
- describe: "Skip Spec-Kit initialization (useful for CI/CD)",
13209
- type: "boolean"
13210
13252
  }).option("claude-code", {
13211
13253
  describe: "Setup Claude Code integration (generates manifests and registers MCP server)",
13212
13254
  type: "boolean",
@@ -13396,7 +13438,6 @@ var setupCommand = {
13396
13438
  console.log(chalk5.cyan("\u{1F4DD} Updating .gitignore..."));
13397
13439
  await updateGitignore(projectDir);
13398
13440
  console.log(chalk5.green(" \u2713 .gitignore updated"));
13399
- const specKitInitialized = await maybeInitializeSpecKit(projectDir, argv);
13400
13441
  let claudeCodeSetupSucceeded = false;
13401
13442
  if (argv.claudeCode) {
13402
13443
  console.log(chalk5.blue("\n\u{1F527} Setting up Claude Code integration...\n"));
@@ -13450,13 +13491,6 @@ var setupCommand = {
13450
13491
  console.log(chalk5.gray(' ax run backend "implement auth" --workflow auth-flow'));
13451
13492
  console.log(chalk5.gray(' ax run backend "create API" --workflow api-flow'));
13452
13493
  console.log(chalk5.gray(" \u2022 Available: auth-flow, feature-flow, api-flow, refactor-flow\n"));
13453
- if (specKitInitialized) {
13454
- console.log(chalk5.cyan("Spec Files (.specify/):"));
13455
- console.log(chalk5.gray(" \u2022 Spec files created for documentation"));
13456
- console.log(chalk5.gray(" \u2022 Use agents to work with specs:"));
13457
- console.log(chalk5.gray(' ax run product "Write spec for feature X"'));
13458
- console.log(chalk5.gray(" \u2022 Note: ax spec run removed in v11.0.0, use --workflow instead\n"));
13459
- }
13460
13494
  console.log(chalk5.cyan("Iterate Mode (Autonomous Multi-Iteration):"));
13461
13495
  console.log(chalk5.gray(" \u2022 Enable with --iterate flag for autonomous task loops"));
13462
13496
  console.log(chalk5.gray(' \u2022 Example: ax run quality "find bugs" --iterate --iterate-max-iterations 5'));
@@ -13891,9 +13925,9 @@ async function initializeGitRepository(projectDir) {
13891
13925
  logger.info("Git repository already exists, skipping initialization");
13892
13926
  return true;
13893
13927
  }
13894
- const { spawn: spawn9 } = await import('child_process');
13928
+ const { spawn: spawn10 } = await import('child_process');
13895
13929
  await new Promise((resolve13, reject) => {
13896
- const child = spawn9("git", ["init"], {
13930
+ const child = spawn10("git", ["init"], {
13897
13931
  cwd: projectDir,
13898
13932
  stdio: "pipe",
13899
13933
  shell: false
@@ -13974,155 +14008,6 @@ async function updateGitignore(projectDir) {
13974
14008
  logger.warn("Failed to update .gitignore", { error: error.message });
13975
14009
  }
13976
14010
  }
13977
- async function maybeInitializeSpecKit(projectDir, argv) {
13978
- const specifyDir = join(projectDir, ".specify");
13979
- const specifyExists = await checkExists2(specifyDir);
13980
- if (specifyExists) {
13981
- logger.info("Spec-Kit directory already exists, skipping initialization", {
13982
- path: specifyDir
13983
- });
13984
- return true;
13985
- }
13986
- if (argv.skipSpecKit) {
13987
- logger.info("Skipping Spec-Kit initialization (--skip-spec-kit flag)");
13988
- return false;
13989
- }
13990
- if (argv.specKit) {
13991
- console.log(chalk5.cyan("\n\u{1F4CB} Initializing GitHub Spec-Kit..."));
13992
- return await initializeSpecKit(projectDir);
13993
- }
13994
- if (process.stdout.isTTY && process.stdin.isTTY) {
13995
- console.log(chalk5.cyan("\n\u{1F4CB} GitHub Spec-Kit Integration"));
13996
- console.log(chalk5.gray(" Spec-Kit enables spec-driven development workflows."));
13997
- console.log(chalk5.gray(" It creates .specify/ directory with spec.md, plan.md, and tasks.md"));
13998
- console.log(chalk5.gray(" for structured planning and task management.\n"));
13999
- try {
14000
- const prompt = new PromptHelper();
14001
- try {
14002
- const answer = await prompt.question(
14003
- chalk5.cyan(" Initialize Spec-Kit now? (y/N): ")
14004
- );
14005
- const shouldInit = answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
14006
- if (shouldInit) {
14007
- console.log(chalk5.cyan("\n Initializing Spec-Kit..."));
14008
- return await initializeSpecKit(projectDir);
14009
- } else {
14010
- logger.info("User declined Spec-Kit initialization");
14011
- return false;
14012
- }
14013
- } finally {
14014
- prompt.close();
14015
- }
14016
- } catch (error) {
14017
- logger.warn("Failed to prompt for Spec-Kit initialization", {
14018
- error: error.message
14019
- });
14020
- return false;
14021
- }
14022
- }
14023
- logger.info("Non-interactive mode, skipping Spec-Kit initialization");
14024
- return false;
14025
- }
14026
- async function initializeSpecKit(projectDir) {
14027
- try {
14028
- const specifyDir = join(projectDir, ".specify");
14029
- await mkdir(specifyDir, { recursive: true });
14030
- const specTemplate = `# Project Specification
14031
-
14032
- ## Overview
14033
- <!-- Brief description of what this project does -->
14034
-
14035
- ## Goals
14036
- <!-- List the main goals and objectives -->
14037
-
14038
- ## Requirements
14039
- <!-- Detailed requirements -->
14040
-
14041
- ### Functional Requirements
14042
- <!-- What the system should do -->
14043
-
14044
- ### Non-Functional Requirements
14045
- <!-- Performance, security, scalability, etc. -->
14046
-
14047
- ## Success Criteria
14048
- <!-- How do we measure success? -->
14049
-
14050
- ## Out of Scope
14051
- <!-- What this project explicitly does NOT include -->
14052
- `;
14053
- const planTemplate = `# Technical Plan
14054
-
14055
- ## Architecture
14056
- <!-- High-level architecture diagram or description -->
14057
-
14058
- ## Technology Stack
14059
- <!-- Languages, frameworks, libraries, tools -->
14060
-
14061
- ## Implementation Approach
14062
- <!-- Step-by-step approach to implementation -->
14063
-
14064
- ## Data Model
14065
- <!-- Database schema, data structures -->
14066
-
14067
- ## API Design
14068
- <!-- API endpoints, interfaces -->
14069
-
14070
- ## Security Considerations
14071
- <!-- Authentication, authorization, data protection -->
14072
-
14073
- ## Testing Strategy
14074
- <!-- Unit tests, integration tests, E2E tests -->
14075
-
14076
- ## Deployment Plan
14077
- <!-- How will this be deployed? -->
14078
-
14079
- ## Risks and Mitigations
14080
- <!-- Potential risks and how to handle them -->
14081
- `;
14082
- const tasksTemplate = `# Tasks
14083
-
14084
- <!-- Task format: - [ ] id:task-id ops:"command" dep:dependency-id -->
14085
- <!-- Example: -->
14086
- <!-- - [ ] id:setup:env ops:"ax run devops 'Setup development environment'" -->
14087
- <!-- - [ ] id:impl:api ops:"ax run backend 'Implement REST API'" dep:setup:env -->
14088
- <!-- - [ ] id:test:api ops:"ax run quality 'Write API tests'" dep:impl:api -->
14089
-
14090
- ## Phase 1: Setup
14091
- - [ ] id:setup:env ops:"ax run devops 'Setup development environment'"
14092
- - [ ] id:setup:db ops:"ax run backend 'Setup database schema'" dep:setup:env
14093
-
14094
- ## Phase 2: Implementation
14095
- - [ ] id:impl:core ops:"ax run backend 'Implement core functionality'" dep:setup:db
14096
-
14097
- ## Phase 3: Testing
14098
- - [ ] id:test:unit ops:"ax run quality 'Write unit tests'" dep:impl:core
14099
- - [ ] id:test:integration ops:"ax run quality 'Write integration tests'" dep:impl:core
14100
-
14101
- ## Phase 4: Documentation
14102
- - [ ] id:docs:api ops:"ax run writer 'Write API documentation'" dep:impl:core
14103
- `;
14104
- await writeFile(join(specifyDir, "spec.md"), specTemplate, "utf8");
14105
- await writeFile(join(specifyDir, "plan.md"), planTemplate, "utf8");
14106
- await writeFile(join(specifyDir, "tasks.md"), tasksTemplate, "utf8");
14107
- console.log(chalk5.green(" \u2713 Spec-Kit set up successfully"));
14108
- console.log(chalk5.gray(" Files created: .specify/spec.md, plan.md, tasks.md"));
14109
- logger.info("Spec-Kit set up successfully", {
14110
- projectDir,
14111
- specifyDir
14112
- });
14113
- return true;
14114
- } catch (error) {
14115
- const errorMessage = error.message;
14116
- console.log(chalk5.yellow(" \u26A0\uFE0F Failed to initialize Spec-Kit"));
14117
- console.log(chalk5.gray(` ${errorMessage}
14118
- `));
14119
- logger.warn("Spec-Kit initialization failed (non-critical)", {
14120
- error: errorMessage,
14121
- projectDir
14122
- });
14123
- return false;
14124
- }
14125
- }
14126
14011
  async function setupGeminiIntegration(projectDir, packageRoot) {
14127
14012
  const geminiDir = join(projectDir, ".gemini");
14128
14013
  await mkdir(geminiDir, { recursive: true });
@@ -16156,12 +16041,12 @@ var listCommand = {
16156
16041
  };
16157
16042
  async function listAgents(pathResolver, format) {
16158
16043
  const agentsDir = pathResolver.getAgentsDirectory();
16159
- const { existsSync: existsSync25 } = await import('fs');
16044
+ const { existsSync: existsSync26 } = await import('fs');
16160
16045
  const projectDir = await detectProjectRoot();
16161
16046
  const examplesDir = join(projectDir, "examples", "agents");
16162
16047
  try {
16163
16048
  const agentFiles = [];
16164
- if (existsSync25(agentsDir)) {
16049
+ if (existsSync26(agentsDir)) {
16165
16050
  const files = await readdir(agentsDir);
16166
16051
  for (const file of files) {
16167
16052
  if (file.endsWith(".yaml") || file.endsWith(".yml")) {
@@ -16173,7 +16058,7 @@ async function listAgents(pathResolver, format) {
16173
16058
  }
16174
16059
  }
16175
16060
  }
16176
- if (existsSync25(examplesDir)) {
16061
+ if (existsSync26(examplesDir)) {
16177
16062
  const files = await readdir(examplesDir);
16178
16063
  for (const file of files) {
16179
16064
  if (file.endsWith(".yaml") || file.endsWith(".yml")) {
@@ -36212,6 +36097,707 @@ function formatForSave(result, format, metadata) {
36212
36097
  }
36213
36098
  return formatOutput(result, format, true);
36214
36099
  }
36100
+
36101
+ // src/core/workflow/index.ts
36102
+ init_esm_shims();
36103
+
36104
+ // src/core/workflow/workflow-mode.ts
36105
+ init_esm_shims();
36106
+ var WorkflowModeSchema = z.enum(["default", "plan", "iterate", "review"]);
36107
+ z.object({
36108
+ name: WorkflowModeSchema,
36109
+ description: z.string(),
36110
+ displayName: z.string(),
36111
+ allowedTools: z.array(z.string()).optional(),
36112
+ blockedTools: z.array(z.string()).optional(),
36113
+ systemInstructions: z.string(),
36114
+ allowNesting: z.boolean(),
36115
+ maxNestingDepth: z.number().int().positive().optional(),
36116
+ autoExitConditions: z.object({
36117
+ maxTurns: z.number().int().positive().optional(),
36118
+ onToolUse: z.array(z.string()).optional(),
36119
+ onKeywords: z.array(z.string()).optional()
36120
+ }).optional()
36121
+ });
36122
+ var WRITE_TOOLS = [
36123
+ "Write",
36124
+ "Edit",
36125
+ "NotebookEdit",
36126
+ "Bash"
36127
+ ];
36128
+ var DEFAULT_MODE_CONFIG = {
36129
+ name: "default",
36130
+ displayName: "Default",
36131
+ description: "Standard operation mode with all tools available",
36132
+ systemInstructions: "",
36133
+ allowNesting: true,
36134
+ maxNestingDepth: 3
36135
+ };
36136
+ var PLAN_MODE_CONFIG = {
36137
+ name: "plan",
36138
+ displayName: "Plan Mode",
36139
+ description: "Planning mode - read-only exploration without code modifications",
36140
+ blockedTools: [...WRITE_TOOLS],
36141
+ systemInstructions: `## Plan Mode Active
36142
+
36143
+ You are in **Plan Mode**. This mode is for exploration and planning only.
36144
+
36145
+ **Restrictions:**
36146
+ - You CANNOT use Write, Edit, or Bash tools that modify files
36147
+ - Focus on reading, searching, and understanding the codebase
36148
+ - Create a comprehensive plan before implementation
36149
+
36150
+ **Your Goals:**
36151
+ 1. Explore the codebase to understand existing patterns
36152
+ 2. Identify files that need to be modified
36153
+ 3. Design an implementation approach
36154
+ 4. Document your plan clearly
36155
+ 5. Use ExitPlanMode when ready to implement
36156
+
36157
+ **Remember:** No code modifications in this mode. Plan first, implement later.`,
36158
+ allowNesting: false,
36159
+ autoExitConditions: {
36160
+ onToolUse: ["ExitPlanMode"]
36161
+ }
36162
+ };
36163
+ var ITERATE_MODE_CONFIG = {
36164
+ name: "iterate",
36165
+ displayName: "Iterate Mode",
36166
+ description: "Continuous iteration mode for implementation with automatic continuation",
36167
+ systemInstructions: `## Iterate Mode Active
36168
+
36169
+ You are in **Iterate Mode**. This mode enables continuous task execution.
36170
+
36171
+ **Behavior:**
36172
+ - Continue working until the task is complete
36173
+ - After each step, assess progress and continue
36174
+ - Don't stop to ask for confirmation unless critical
36175
+ - Mark todos as completed as you finish them
36176
+
36177
+ **Guidelines:**
36178
+ 1. Work through tasks systematically
36179
+ 2. Test changes as you go when possible
36180
+ 3. Update todo list to track progress
36181
+ 4. Only pause for critical decisions or blockers
36182
+
36183
+ **Remember:** Keep iterating until the task is done or you hit a blocker.`,
36184
+ allowNesting: true,
36185
+ maxNestingDepth: 2
36186
+ };
36187
+ var REVIEW_MODE_CONFIG = {
36188
+ name: "review",
36189
+ displayName: "Review Mode",
36190
+ description: "Code review mode - analyze code quality, security, and best practices",
36191
+ blockedTools: [...WRITE_TOOLS],
36192
+ systemInstructions: `## Review Mode Active
36193
+
36194
+ You are in **Review Mode**. This mode is for code review and analysis.
36195
+
36196
+ **Focus Areas:**
36197
+ - Code quality and readability
36198
+ - Security vulnerabilities (OWASP Top 10)
36199
+ - Performance issues
36200
+ - Best practices and patterns
36201
+ - Test coverage gaps
36202
+
36203
+ **Output Format:**
36204
+ Provide structured feedback:
36205
+ 1. **Critical Issues** - Must fix before merge
36206
+ 2. **Warnings** - Should address
36207
+ 3. **Suggestions** - Nice to have improvements
36208
+ 4. **Positive Notes** - Good patterns observed
36209
+
36210
+ **Remember:** No code modifications. Provide actionable feedback only.`,
36211
+ allowNesting: false
36212
+ };
36213
+ var WORKFLOW_MODE_CONFIGS = {
36214
+ default: DEFAULT_MODE_CONFIG,
36215
+ plan: PLAN_MODE_CONFIG,
36216
+ iterate: ITERATE_MODE_CONFIG,
36217
+ review: REVIEW_MODE_CONFIG
36218
+ };
36219
+ function getWorkflowModeConfig(mode) {
36220
+ return WORKFLOW_MODE_CONFIGS[mode];
36221
+ }
36222
+ function isToolAllowedInMode(tool, mode) {
36223
+ const config = getWorkflowModeConfig(mode);
36224
+ if (config.allowedTools && config.allowedTools.length > 0) {
36225
+ return config.allowedTools.includes(tool);
36226
+ }
36227
+ if (config.blockedTools && config.blockedTools.length > 0) {
36228
+ return !config.blockedTools.includes(tool);
36229
+ }
36230
+ return true;
36231
+ }
36232
+ function isValidWorkflowMode(mode) {
36233
+ return Object.prototype.hasOwnProperty.call(WORKFLOW_MODE_CONFIGS, mode);
36234
+ }
36235
+ var WORKFLOW_MODES = WORKFLOW_MODE_CONFIGS;
36236
+
36237
+ // src/core/workflow/workflow-mode-manager.ts
36238
+ init_esm_shims();
36239
+ init_logger();
36240
+
36241
+ // src/core/orchestration/types.ts
36242
+ init_esm_shims();
36243
+ var INSTRUCTION_SOURCE = "automatosx";
36244
+ z.object({
36245
+ type: z.enum(["task", "memory", "session", "delegation", "mode", "context"]),
36246
+ priority: z.enum(["critical", "high", "normal", "low"]),
36247
+ content: z.string().min(1).max(5e3),
36248
+ source: z.literal(INSTRUCTION_SOURCE),
36249
+ expiresAfter: z.number().int().positive().optional(),
36250
+ createdAt: z.number(),
36251
+ createdAtTurn: z.number().int().nonnegative().optional(),
36252
+ id: z.string().optional()
36253
+ });
36254
+ var TodoItemSchema = z.object({
36255
+ id: z.string(),
36256
+ content: z.string().min(1).max(1e3),
36257
+ status: z.enum(["pending", "in_progress", "completed"]),
36258
+ activeForm: z.string().min(1).max(1e3),
36259
+ createdAt: z.number(),
36260
+ updatedAt: z.number().optional(),
36261
+ metadata: z.record(z.string(), z.unknown()).optional()
36262
+ });
36263
+ z.object({
36264
+ name: z.enum(["default", "plan", "iterate", "review"]),
36265
+ description: z.string(),
36266
+ displayName: z.string(),
36267
+ allowedTools: z.array(z.string()).optional(),
36268
+ blockedTools: z.array(z.string()).optional(),
36269
+ systemInstructions: z.string(),
36270
+ allowNesting: z.boolean(),
36271
+ maxNestingDepth: z.number().int().positive().optional(),
36272
+ autoExitConditions: z.object({
36273
+ maxTurns: z.number().int().positive().optional(),
36274
+ onToolUse: z.array(z.string()).optional(),
36275
+ onKeywords: z.array(z.string()).optional()
36276
+ }).optional()
36277
+ });
36278
+ z.object({
36279
+ todos: z.array(TodoItemSchema),
36280
+ currentTask: z.string().optional(),
36281
+ agentName: z.string().optional(),
36282
+ turnCount: z.number().int().nonnegative(),
36283
+ workflowMode: z.enum(["default", "plan", "iterate", "review"]),
36284
+ sessionId: z.string().optional(),
36285
+ parentAgent: z.string().optional(),
36286
+ memories: z.array(z.object({
36287
+ content: z.string(),
36288
+ relevance: z.number().min(0).max(1),
36289
+ agent: z.string().optional(),
36290
+ timestamp: z.number()
36291
+ })).optional()
36292
+ });
36293
+ var DEFAULT_TOKEN_BUDGET = {
36294
+ maxTotal: 2e3,
36295
+ perType: {
36296
+ task: 500,
36297
+ memory: 600,
36298
+ session: 300,
36299
+ delegation: 200,
36300
+ mode: 400,
36301
+ context: 300
36302
+ },
36303
+ criticalReserve: 300
36304
+ };
36305
+ var TokenBudgetConfigSchema = z.object({
36306
+ maxTotal: z.number().int().positive().max(1e4),
36307
+ perType: z.record(
36308
+ z.enum(["task", "memory", "session", "delegation", "mode", "context"]),
36309
+ z.number().int().nonnegative()
36310
+ ),
36311
+ criticalReserve: z.number().int().nonnegative()
36312
+ });
36313
+ var DEFAULT_ORCHESTRATION_CONFIG = {
36314
+ enabled: true,
36315
+ tokenBudget: DEFAULT_TOKEN_BUDGET,
36316
+ todoIntegration: {
36317
+ enabled: true,
36318
+ reminderFrequency: 3,
36319
+ compactMode: false
36320
+ },
36321
+ memoryIntegration: {
36322
+ enabled: true,
36323
+ maxEntries: 5,
36324
+ minRelevance: 0.5
36325
+ },
36326
+ sessionIntegration: {
36327
+ enabled: true,
36328
+ showCollaboration: true
36329
+ },
36330
+ agentTemplates: {
36331
+ enabled: true,
36332
+ reminderFrequency: 5
36333
+ }
36334
+ };
36335
+ z.object({
36336
+ enabled: z.boolean(),
36337
+ tokenBudget: TokenBudgetConfigSchema,
36338
+ todoIntegration: z.object({
36339
+ enabled: z.boolean(),
36340
+ reminderFrequency: z.number().int().positive(),
36341
+ compactMode: z.boolean()
36342
+ }),
36343
+ memoryIntegration: z.object({
36344
+ enabled: z.boolean(),
36345
+ maxEntries: z.number().int().nonnegative(),
36346
+ minRelevance: z.number().min(0).max(1)
36347
+ }),
36348
+ sessionIntegration: z.object({
36349
+ enabled: z.boolean(),
36350
+ showCollaboration: z.boolean()
36351
+ }),
36352
+ agentTemplates: z.object({
36353
+ enabled: z.boolean(),
36354
+ reminderFrequency: z.number().int().positive()
36355
+ })
36356
+ });
36357
+
36358
+ // src/core/workflow/workflow-mode-manager.ts
36359
+ var WorkflowModeManager = class {
36360
+ name = "workflow-mode";
36361
+ modeStack = [];
36362
+ transitionListeners = /* @__PURE__ */ new Set();
36363
+ turnCount = 0;
36364
+ constructor(initialMode = "default") {
36365
+ this.modeStack.push({
36366
+ mode: initialMode,
36367
+ enteredAt: Date.now(),
36368
+ enteredAtTurn: 0,
36369
+ reason: "initial"
36370
+ });
36371
+ logger.debug("WorkflowModeManager initialized", {
36372
+ initialMode
36373
+ });
36374
+ }
36375
+ /**
36376
+ * Get the top entry from the mode stack (private helper to reduce repetition)
36377
+ */
36378
+ getTopEntry() {
36379
+ return this.modeStack[this.modeStack.length - 1];
36380
+ }
36381
+ /**
36382
+ * Get the current active mode
36383
+ */
36384
+ getCurrentMode() {
36385
+ return this.getTopEntry()?.mode ?? "default";
36386
+ }
36387
+ /**
36388
+ * Get the current mode configuration
36389
+ */
36390
+ getCurrentModeConfig() {
36391
+ const mode = this.getCurrentMode();
36392
+ const entry = this.getTopEntry();
36393
+ const baseConfig = getWorkflowModeConfig(mode);
36394
+ if (entry?.customConfig) {
36395
+ const mergedAutoExit = entry.customConfig.autoExitConditions || baseConfig.autoExitConditions ? {
36396
+ ...baseConfig.autoExitConditions ?? {},
36397
+ ...entry.customConfig.autoExitConditions ?? {}
36398
+ } : void 0;
36399
+ return {
36400
+ ...baseConfig,
36401
+ ...entry.customConfig,
36402
+ // Deep merge for nested objects
36403
+ autoExitConditions: mergedAutoExit
36404
+ };
36405
+ }
36406
+ return baseConfig;
36407
+ }
36408
+ /**
36409
+ * Get the full mode stack
36410
+ */
36411
+ getModeStack() {
36412
+ return [...this.modeStack];
36413
+ }
36414
+ /**
36415
+ * Get the current stack depth
36416
+ */
36417
+ getStackDepth() {
36418
+ return this.modeStack.length;
36419
+ }
36420
+ /**
36421
+ * Push a new mode onto the stack
36422
+ */
36423
+ pushMode(mode, options) {
36424
+ const currentConfig = this.getCurrentModeConfig();
36425
+ if (!currentConfig.allowNesting) {
36426
+ logger.warn("Cannot push mode: current mode does not allow nesting", {
36427
+ currentMode: this.getCurrentMode(),
36428
+ attemptedMode: mode
36429
+ });
36430
+ return false;
36431
+ }
36432
+ const maxDepth = currentConfig.maxNestingDepth ?? 3;
36433
+ if (this.modeStack.length >= maxDepth) {
36434
+ logger.warn("Cannot push mode: max nesting depth reached", {
36435
+ currentDepth: this.modeStack.length,
36436
+ maxDepth
36437
+ });
36438
+ return false;
36439
+ }
36440
+ const previousMode = this.getCurrentMode();
36441
+ this.modeStack.push({
36442
+ mode,
36443
+ enteredAt: Date.now(),
36444
+ enteredAtTurn: this.turnCount,
36445
+ customConfig: options?.customConfig,
36446
+ reason: options?.reason
36447
+ });
36448
+ this.emitTransition({
36449
+ from: previousMode,
36450
+ to: mode,
36451
+ type: "push",
36452
+ timestamp: Date.now(),
36453
+ reason: options?.reason
36454
+ });
36455
+ logger.info("Pushed workflow mode", {
36456
+ from: previousMode,
36457
+ to: mode,
36458
+ stackDepth: this.modeStack.length,
36459
+ reason: options?.reason
36460
+ });
36461
+ return true;
36462
+ }
36463
+ /**
36464
+ * Pop the current mode from the stack
36465
+ */
36466
+ popMode(reason) {
36467
+ if (this.modeStack.length <= 1) {
36468
+ logger.warn("Cannot pop mode: at base level");
36469
+ return null;
36470
+ }
36471
+ const popped = this.modeStack.pop();
36472
+ const newMode = this.getCurrentMode();
36473
+ if (popped) {
36474
+ this.emitTransition({
36475
+ from: popped.mode,
36476
+ to: newMode,
36477
+ type: "pop",
36478
+ timestamp: Date.now(),
36479
+ reason
36480
+ });
36481
+ logger.info("Popped workflow mode", {
36482
+ from: popped.mode,
36483
+ to: newMode,
36484
+ stackDepth: this.modeStack.length,
36485
+ reason
36486
+ });
36487
+ }
36488
+ return popped?.mode ?? null;
36489
+ }
36490
+ /**
36491
+ * Replace the current mode (pop then push)
36492
+ */
36493
+ replaceMode(mode, options) {
36494
+ const previousMode = this.getCurrentMode();
36495
+ if (this.modeStack.length === 1) {
36496
+ this.modeStack[0] = {
36497
+ mode,
36498
+ enteredAt: Date.now(),
36499
+ enteredAtTurn: this.turnCount,
36500
+ customConfig: options?.customConfig,
36501
+ reason: options?.reason
36502
+ };
36503
+ } else {
36504
+ this.modeStack.pop();
36505
+ this.modeStack.push({
36506
+ mode,
36507
+ enteredAt: Date.now(),
36508
+ enteredAtTurn: this.turnCount,
36509
+ customConfig: options?.customConfig,
36510
+ reason: options?.reason
36511
+ });
36512
+ }
36513
+ this.emitTransition({
36514
+ from: previousMode,
36515
+ to: mode,
36516
+ type: "replace",
36517
+ timestamp: Date.now(),
36518
+ reason: options?.reason
36519
+ });
36520
+ logger.info("Replaced workflow mode", {
36521
+ from: previousMode,
36522
+ to: mode,
36523
+ reason: options?.reason
36524
+ });
36525
+ return true;
36526
+ }
36527
+ /**
36528
+ * Set mode directly (clears stack and sets new base mode)
36529
+ */
36530
+ setMode(mode, options) {
36531
+ const previousMode = this.getCurrentMode();
36532
+ this.modeStack = [{
36533
+ mode,
36534
+ enteredAt: Date.now(),
36535
+ enteredAtTurn: this.turnCount,
36536
+ customConfig: options?.customConfig,
36537
+ reason: options?.reason
36538
+ }];
36539
+ this.emitTransition({
36540
+ from: previousMode,
36541
+ to: mode,
36542
+ type: "replace",
36543
+ timestamp: Date.now(),
36544
+ reason: options?.reason
36545
+ });
36546
+ logger.info("Set workflow mode", {
36547
+ from: previousMode,
36548
+ to: mode,
36549
+ reason: options?.reason
36550
+ });
36551
+ }
36552
+ /**
36553
+ * Check if a tool is allowed in the current mode
36554
+ */
36555
+ isToolAllowed(tool) {
36556
+ return isToolAllowedInMode(tool, this.getCurrentMode());
36557
+ }
36558
+ /**
36559
+ * Get list of blocked tools in current mode
36560
+ */
36561
+ getBlockedTools() {
36562
+ const config = this.getCurrentModeConfig();
36563
+ return config.blockedTools || [];
36564
+ }
36565
+ /**
36566
+ * Filter a list of tools based on current mode
36567
+ */
36568
+ filterTools(tools) {
36569
+ return tools.filter((tool) => this.isToolAllowed(tool.name));
36570
+ }
36571
+ /**
36572
+ * Update turn count (for auto-exit tracking)
36573
+ */
36574
+ updateTurnCount(turn) {
36575
+ this.turnCount = turn;
36576
+ this.checkAutoExit();
36577
+ }
36578
+ /**
36579
+ * Check and handle auto-exit conditions
36580
+ */
36581
+ checkAutoExit() {
36582
+ const config = this.getCurrentModeConfig();
36583
+ const entry = this.getTopEntry();
36584
+ if (!config.autoExitConditions || !entry) return;
36585
+ if (config.autoExitConditions.maxTurns) {
36586
+ const turnsInMode = this.turnCount - entry.enteredAtTurn;
36587
+ if (turnsInMode >= config.autoExitConditions.maxTurns) {
36588
+ logger.info("Auto-exiting mode due to max turns", {
36589
+ mode: this.getCurrentMode(),
36590
+ turnsInMode,
36591
+ maxTurns: config.autoExitConditions.maxTurns
36592
+ });
36593
+ this.popMode("max_turns_reached");
36594
+ }
36595
+ }
36596
+ }
36597
+ /**
36598
+ * Notify that a tool was used (for auto-exit on tool use)
36599
+ */
36600
+ notifyToolUsed(tool) {
36601
+ const config = this.getCurrentModeConfig();
36602
+ if (config.autoExitConditions?.onToolUse?.includes(tool)) {
36603
+ logger.info("Auto-exiting mode due to tool use", {
36604
+ mode: this.getCurrentMode(),
36605
+ tool
36606
+ });
36607
+ this.popMode(`tool_used:${tool}`);
36608
+ }
36609
+ }
36610
+ /**
36611
+ * Add a mode transition listener
36612
+ */
36613
+ onTransition(listener) {
36614
+ this.transitionListeners.add(listener);
36615
+ return () => this.transitionListeners.delete(listener);
36616
+ }
36617
+ /**
36618
+ * Emit a transition event to all listeners
36619
+ */
36620
+ emitTransition(event) {
36621
+ for (const listener of this.transitionListeners) {
36622
+ try {
36623
+ listener(event);
36624
+ } catch (error) {
36625
+ logger.error("Mode transition listener error", {
36626
+ error: error instanceof Error ? error.message : String(error)
36627
+ });
36628
+ }
36629
+ }
36630
+ }
36631
+ // InstructionProvider implementation
36632
+ /**
36633
+ * Check if mode instructions should be generated
36634
+ */
36635
+ shouldGenerate(context) {
36636
+ return this.getCurrentMode() !== "default";
36637
+ }
36638
+ /**
36639
+ * Get mode-specific instructions
36640
+ */
36641
+ async getInstructions(context) {
36642
+ const config = this.getCurrentModeConfig();
36643
+ const instructions = [];
36644
+ if (config.systemInstructions && config.systemInstructions.length > 0) {
36645
+ instructions.push({
36646
+ type: "mode",
36647
+ priority: "high",
36648
+ content: config.systemInstructions,
36649
+ source: INSTRUCTION_SOURCE,
36650
+ createdAt: Date.now(),
36651
+ id: `mode-${config.name}-${Date.now()}`
36652
+ });
36653
+ }
36654
+ if (config.blockedTools && config.blockedTools.length > 0) {
36655
+ instructions.push({
36656
+ type: "mode",
36657
+ priority: "critical",
36658
+ content: `**Tool Restrictions:** The following tools are NOT available in ${config.displayName}: ${config.blockedTools.join(", ")}`,
36659
+ source: INSTRUCTION_SOURCE,
36660
+ createdAt: Date.now(),
36661
+ id: `mode-blocked-tools-${Date.now()}`
36662
+ });
36663
+ }
36664
+ return instructions;
36665
+ }
36666
+ /**
36667
+ * Reset to default state
36668
+ */
36669
+ reset() {
36670
+ const previousMode = this.getCurrentMode();
36671
+ this.modeStack = [{
36672
+ mode: "default",
36673
+ enteredAt: Date.now(),
36674
+ enteredAtTurn: 0,
36675
+ reason: "reset"
36676
+ }];
36677
+ this.turnCount = 0;
36678
+ if (previousMode !== "default") {
36679
+ this.emitTransition({
36680
+ from: previousMode,
36681
+ to: "default",
36682
+ type: "replace",
36683
+ timestamp: Date.now(),
36684
+ reason: "reset"
36685
+ });
36686
+ }
36687
+ logger.debug("WorkflowModeManager reset");
36688
+ }
36689
+ /**
36690
+ * Get status information for debugging
36691
+ */
36692
+ getStatus() {
36693
+ return {
36694
+ currentMode: this.getCurrentMode(),
36695
+ stackDepth: this.modeStack.length,
36696
+ stack: this.modeStack.map((entry) => ({
36697
+ mode: entry.mode,
36698
+ enteredAt: entry.enteredAt,
36699
+ reason: entry.reason
36700
+ })),
36701
+ blockedTools: this.getBlockedTools(),
36702
+ turnCount: this.turnCount
36703
+ };
36704
+ }
36705
+ };
36706
+
36707
+ // src/core/workflow/mode-state-manager.ts
36708
+ init_esm_shims();
36709
+ init_logger();
36710
+ init_path_resolver();
36711
+ var ModeStateSchema = z.object({
36712
+ mode: z.enum(["default", "plan", "iterate", "review"]),
36713
+ setAt: z.number(),
36714
+ setBy: z.string().optional(),
36715
+ reason: z.string().optional(),
36716
+ expiresAt: z.number().optional()
36717
+ });
36718
+ var STATE_FILE_PATH = ".automatosx/state/mode.json";
36719
+ var DEFAULT_EXPIRATION_MS = 4 * 60 * 60 * 1e3;
36720
+ async function getStateFilePath() {
36721
+ const projectRoot = await detectProjectRoot(process.cwd());
36722
+ return join(projectRoot, STATE_FILE_PATH);
36723
+ }
36724
+ async function loadModeState() {
36725
+ try {
36726
+ const statePath = await getStateFilePath();
36727
+ if (!existsSync(statePath)) {
36728
+ logger.debug("No mode state file found", { path: statePath });
36729
+ return null;
36730
+ }
36731
+ const content = readFileSync(statePath, "utf-8");
36732
+ const parsed = JSON.parse(content);
36733
+ const result = ModeStateSchema.safeParse(parsed);
36734
+ if (!result.success) {
36735
+ logger.warn("Invalid mode state file", {
36736
+ path: statePath,
36737
+ error: result.error.message
36738
+ });
36739
+ return null;
36740
+ }
36741
+ const state = result.data;
36742
+ if (state.expiresAt && Date.now() > state.expiresAt) {
36743
+ logger.debug("Mode state expired", {
36744
+ mode: state.mode,
36745
+ expiredAt: new Date(state.expiresAt).toISOString()
36746
+ });
36747
+ return null;
36748
+ }
36749
+ logger.debug("Loaded mode state", {
36750
+ mode: state.mode,
36751
+ setAt: new Date(state.setAt).toISOString()
36752
+ });
36753
+ return state;
36754
+ } catch (error) {
36755
+ logger.error("Failed to load mode state", {
36756
+ error: error instanceof Error ? error.message : String(error)
36757
+ });
36758
+ return null;
36759
+ }
36760
+ }
36761
+ async function saveModeState(mode, options) {
36762
+ try {
36763
+ const statePath = await getStateFilePath();
36764
+ const stateDir = dirname(statePath);
36765
+ if (!existsSync(stateDir)) {
36766
+ mkdirSync(stateDir, { recursive: true });
36767
+ }
36768
+ const state = {
36769
+ mode,
36770
+ setAt: Date.now(),
36771
+ setBy: options?.setBy ?? "cli",
36772
+ reason: options?.reason,
36773
+ expiresAt: Date.now() + (options?.expiresIn ?? DEFAULT_EXPIRATION_MS)
36774
+ };
36775
+ writeFileSync(statePath, JSON.stringify(state, null, 2), "utf-8");
36776
+ logger.debug("Saved mode state", {
36777
+ mode,
36778
+ expiresAt: new Date(state.expiresAt).toISOString()
36779
+ });
36780
+ return true;
36781
+ } catch (error) {
36782
+ logger.error("Failed to save mode state", {
36783
+ error: error instanceof Error ? error.message : String(error)
36784
+ });
36785
+ return false;
36786
+ }
36787
+ }
36788
+ async function getCurrentPersistedMode() {
36789
+ const state = await loadModeState();
36790
+ return state?.mode ?? "default";
36791
+ }
36792
+ function isModePersistenceEnabled() {
36793
+ return process.env.AX_DISABLE_MODE_PERSISTENCE !== "true";
36794
+ }
36795
+
36796
+ // src/core/workflow/workflow-progress-provider.ts
36797
+ init_esm_shims();
36798
+ init_logger();
36799
+
36800
+ // src/cli/commands/run.ts
36215
36801
  function displayAutoSelectionResult(selection, verbosity, showBanner = true) {
36216
36802
  if (!showBanner || !verbosity.shouldShow("showBanner")) return;
36217
36803
  const confidenceEmoji = selection.confidence === "high" ? "\u2705" : selection.confidence === "medium" ? "\u26A1" : "\u{1F4A1}";
@@ -36311,10 +36897,6 @@ var runCommand = {
36311
36897
  describe: "Show execution timeline after completion (requires --parallel)",
36312
36898
  type: "boolean",
36313
36899
  default: true
36314
- }).option("no-spec", {
36315
- describe: "Bypass spec-kit suggestion for complex tasks (v5.8.3+)",
36316
- type: "boolean",
36317
- default: false
36318
36900
  }).option("sandbox", {
36319
36901
  describe: "Sandbox mode for code execution (v6.0.7 Phase 3)",
36320
36902
  type: "string",
@@ -36446,6 +37028,32 @@ var runCommand = {
36446
37028
  process.exit(1);
36447
37029
  }
36448
37030
  }
37031
+ if (!argv.workflow && !argv.iterate && isModePersistenceEnabled()) {
37032
+ const persistedMode = await getCurrentPersistedMode();
37033
+ if (persistedMode === "iterate") {
37034
+ argv.iterate = true;
37035
+ if (verbosity.shouldShow("showBanner")) {
37036
+ console.log(chalk5.cyan(`\u{1F4CB} Using persisted mode: iterate`));
37037
+ console.log(chalk5.gray(` (set via \`ax mode iterate\`, use \`ax mode default\` to clear)
37038
+ `));
37039
+ }
37040
+ logger.info("Applied persisted iterate mode");
37041
+ } else if (persistedMode === "plan") {
37042
+ if (verbosity.shouldShow("showBanner")) {
37043
+ console.log(chalk5.cyan(`\u{1F4CB} Using persisted mode: plan`));
37044
+ console.log(chalk5.gray(` (read-only exploration mode)
37045
+ `));
37046
+ }
37047
+ logger.info("Applied persisted plan mode");
37048
+ } else if (persistedMode === "review") {
37049
+ if (verbosity.shouldShow("showBanner")) {
37050
+ console.log(chalk5.cyan(`\u{1F4CB} Using persisted mode: review`));
37051
+ console.log(chalk5.gray(` (code review mode)
37052
+ `));
37053
+ }
37054
+ logger.info("Applied persisted review mode");
37055
+ }
37056
+ }
36449
37057
  if (verbosity.isQuiet()) {
36450
37058
  argv.showDependencyGraph = false;
36451
37059
  argv.showTimeline = false;
@@ -38062,11 +38670,11 @@ async function getCurrentVersion() {
38062
38670
  return result.dependencies["@defai.digital/automatosx"]?.version || "unknown";
38063
38671
  } catch (error) {
38064
38672
  const { readFile: readFile24 } = await import('fs/promises');
38065
- const { dirname: dirname14, join: join49 } = await import('path');
38673
+ const { dirname: dirname15, join: join50 } = await import('path');
38066
38674
  const { fileURLToPath: fileURLToPath5 } = await import('url');
38067
38675
  const __filename3 = fileURLToPath5(import.meta.url);
38068
- const __dirname4 = dirname14(__filename3);
38069
- const pkgPath = join49(__dirname4, "../../../package.json");
38676
+ const __dirname4 = dirname15(__filename3);
38677
+ const pkgPath = join50(__dirname4, "../../../package.json");
38070
38678
  const content = await readFile24(pkgPath, "utf-8");
38071
38679
  const pkg = JSON.parse(content);
38072
38680
  return pkg.version;
@@ -45098,10 +45706,10 @@ async function handleReset() {
45098
45706
  `));
45099
45707
  }
45100
45708
  async function handleTrace(workspacePath, argv) {
45101
- const { existsSync: existsSync25, readFileSync: readFileSync8, watchFile } = await import('fs');
45102
- const { join: join49 } = await import('path');
45103
- const traceFile = join49(workspacePath, ".automatosx/logs/router.trace.jsonl");
45104
- if (!existsSync25(traceFile)) {
45709
+ const { existsSync: existsSync26, readFileSync: readFileSync9, watchFile } = await import('fs');
45710
+ const { join: join50 } = await import('path');
45711
+ const traceFile = join50(workspacePath, ".automatosx/logs/router.trace.jsonl");
45712
+ if (!existsSync26(traceFile)) {
45105
45713
  console.log(chalk5.yellow("\n\u26A0\uFE0F No trace log found\n"));
45106
45714
  console.log(chalk5.gray(`Expected location: ${traceFile}
45107
45715
  `));
@@ -45118,7 +45726,7 @@ async function handleTrace(workspacePath, argv) {
45118
45726
  `));
45119
45727
  if (argv.follow) {
45120
45728
  console.log(chalk5.gray("Following trace log (Ctrl+C to exit)...\n"));
45121
- const content = readFileSync8(traceFile, "utf-8");
45729
+ const content = readFileSync9(traceFile, "utf-8");
45122
45730
  const lines = content.split("\n").filter((l) => l.trim());
45123
45731
  const recentLines = lines.slice(-(argv.lines || 20));
45124
45732
  for (const line of recentLines) {
@@ -45128,7 +45736,7 @@ async function handleTrace(workspacePath, argv) {
45128
45736
  const { unwatchFile } = await import('fs');
45129
45737
  watchFile(traceFile, { interval: 500 }, (curr, prev) => {
45130
45738
  if (curr.size > lastSize) {
45131
- const newContent = readFileSync8(traceFile, "utf-8");
45739
+ const newContent = readFileSync9(traceFile, "utf-8");
45132
45740
  const newLines = newContent.slice(lastSize).split("\n").filter((l) => l.trim());
45133
45741
  for (const line of newLines) {
45134
45742
  displayTraceEvent(line);
@@ -45146,7 +45754,7 @@ async function handleTrace(workspacePath, argv) {
45146
45754
  await new Promise(() => {
45147
45755
  });
45148
45756
  } else {
45149
- const content = readFileSync8(traceFile, "utf-8");
45757
+ const content = readFileSync9(traceFile, "utf-8");
45150
45758
  const lines = content.split("\n").filter((l) => l.trim());
45151
45759
  const recentLines = lines.slice(-(argv.lines || 20));
45152
45760
  if (recentLines.length === 0) {
@@ -47306,10 +47914,14 @@ var OptimizationAnalyzer = class {
47306
47914
  * Analyze usage and generate recommendations
47307
47915
  */
47308
47916
  async analyze(timeRange) {
47309
- logger.debug("Analyzing for optimization opportunities", { timeRange });
47917
+ logger.debug("Analyzing for optimization opportunities", {
47918
+ timeRange,
47919
+ provider: timeRange.provider
47920
+ });
47310
47921
  const summary = await this.analytics.generateSummary({
47311
47922
  startDate: timeRange.start,
47312
- endDate: timeRange.end
47923
+ endDate: timeRange.end,
47924
+ provider: timeRange.provider
47313
47925
  });
47314
47926
  const recommendations = [];
47315
47927
  recommendations.push(...this.findModelDowngradeOpportunities(summary));
@@ -47396,6 +48008,7 @@ var OptimizationAnalyzer = class {
47396
48008
  type: "cache_hit",
47397
48009
  startDate: timeRange.start,
47398
48010
  endDate: timeRange.end,
48011
+ provider: timeRange.provider,
47399
48012
  limit: 1e4
47400
48013
  });
47401
48014
  const totalExecutions = summary.executions.total;
@@ -47538,10 +48151,11 @@ var analyticsCommand = {
47538
48151
  }
47539
48152
  };
47540
48153
  async function summaryHandler(argv) {
48154
+ let telemetry;
47541
48155
  try {
47542
48156
  const config = await loadConfig(process.cwd());
47543
48157
  const telemetryConfig = config.telemetry || { enabled: false };
47544
- const telemetry = getTelemetryCollector({
48158
+ telemetry = getTelemetryCollector({
47545
48159
  ...telemetryConfig,
47546
48160
  enabled: true
47547
48161
  });
@@ -47549,15 +48163,19 @@ async function summaryHandler(argv) {
47549
48163
  const timeRange = parseTimePeriod(argv.period || "7d");
47550
48164
  const summary = await analytics.generateSummary({
47551
48165
  startDate: timeRange.startDate,
47552
- endDate: timeRange.endDate
48166
+ endDate: timeRange.endDate,
48167
+ provider: argv.provider
47553
48168
  });
47554
48169
  if (argv.format === "json") {
47555
48170
  console.log(JSON.stringify(summary, null, 2));
47556
48171
  return;
47557
48172
  }
47558
48173
  console.log(chalk5.bold.cyan("\n\u{1F4CA} AutomatosX Analytics Summary\n"));
47559
- console.log(chalk5.dim(`Period: ${formatPeriod(argv.period || "7d")}
47560
- `));
48174
+ console.log(chalk5.dim(`Period: ${formatPeriod(argv.period || "7d")}`));
48175
+ if (argv.provider) {
48176
+ console.log(chalk5.dim(`Provider filter: ${argv.provider}`));
48177
+ }
48178
+ console.log();
47561
48179
  console.log(chalk5.bold("Executions"));
47562
48180
  console.log(` Total: ${summary.executions.total}`);
47563
48181
  console.log(` Successful: ${chalk5.green(summary.executions.successful)}`);
@@ -47601,13 +48219,16 @@ async function summaryHandler(argv) {
47601
48219
  });
47602
48220
  logger.error("Analytics summary failed", { error: error.message });
47603
48221
  process.exit(1);
48222
+ } finally {
48223
+ await telemetry?.close();
47604
48224
  }
47605
48225
  }
47606
48226
  async function optimizeHandler(argv) {
48227
+ let telemetry;
47607
48228
  try {
47608
48229
  const config = await loadConfig(process.cwd());
47609
48230
  const telemetryConfig = config.telemetry || { enabled: false };
47610
- const telemetry = getTelemetryCollector({
48231
+ telemetry = getTelemetryCollector({
47611
48232
  ...telemetryConfig,
47612
48233
  enabled: true
47613
48234
  });
@@ -47616,15 +48237,19 @@ async function optimizeHandler(argv) {
47616
48237
  const timeRange = parseTimePeriod(argv.period || "7d");
47617
48238
  const recommendations = await optimizer.analyze({
47618
48239
  start: timeRange.startDate,
47619
- end: timeRange.endDate
48240
+ end: timeRange.endDate,
48241
+ provider: argv.provider
47620
48242
  });
47621
48243
  if (argv.format === "json") {
47622
48244
  console.log(JSON.stringify(recommendations, null, 2));
47623
48245
  return;
47624
48246
  }
47625
48247
  console.log(chalk5.bold.cyan("\n\u{1F4A1} Optimization Recommendations\n"));
47626
- console.log(chalk5.dim(`Period: ${formatPeriod(argv.period || "7d")}
47627
- `));
48248
+ console.log(chalk5.dim(`Period: ${formatPeriod(argv.period || "7d")}`));
48249
+ if (argv.provider) {
48250
+ console.log(chalk5.dim(`Provider filter: ${argv.provider}`));
48251
+ }
48252
+ console.log();
47628
48253
  if (recommendations.length === 0) {
47629
48254
  console.log(chalk5.green("\u2705 No optimization opportunities found. You're doing great!\n"));
47630
48255
  return;
@@ -47657,13 +48282,16 @@ async function optimizeHandler(argv) {
47657
48282
  });
47658
48283
  logger.error("Optimization analysis failed", { error: error.message });
47659
48284
  process.exit(1);
48285
+ } finally {
48286
+ await telemetry?.close();
47660
48287
  }
47661
48288
  }
47662
48289
  async function clearHandler(argv) {
48290
+ let telemetry;
47663
48291
  try {
47664
48292
  const config = await loadConfig(process.cwd());
47665
48293
  const telemetryConfig = config.telemetry || { enabled: false };
47666
- const telemetry = getTelemetryCollector({
48294
+ telemetry = getTelemetryCollector({
47667
48295
  ...telemetryConfig,
47668
48296
  enabled: true
47669
48297
  });
@@ -47690,13 +48318,16 @@ async function clearHandler(argv) {
47690
48318
  });
47691
48319
  logger.error("Clear telemetry failed", { error: error.message });
47692
48320
  process.exit(1);
48321
+ } finally {
48322
+ await telemetry?.close();
47693
48323
  }
47694
48324
  }
47695
48325
  async function statusHandler(argv) {
48326
+ let telemetry;
47696
48327
  try {
47697
48328
  const config = await loadConfig(process.cwd());
47698
48329
  const telemetryConfig = config.telemetry || { enabled: false };
47699
- const telemetry = getTelemetryCollector({
48330
+ telemetry = getTelemetryCollector({
47700
48331
  ...telemetryConfig,
47701
48332
  enabled: true
47702
48333
  });
@@ -47723,6 +48354,8 @@ async function statusHandler(argv) {
47723
48354
  });
47724
48355
  logger.error("Telemetry status failed", { error: error.message });
47725
48356
  process.exit(1);
48357
+ } finally {
48358
+ await telemetry?.close();
47726
48359
  }
47727
48360
  }
47728
48361
  function parseTimePeriod(period) {
@@ -48534,489 +49167,6 @@ var uninstallCommand = {
48534
49167
  // src/cli/commands/mode.ts
48535
49168
  init_esm_shims();
48536
49169
  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
49170
  var modeCommand = {
49021
49171
  command: "mode [mode]",
49022
49172
  describe: "Manage workflow modes for embedded instructions (v11.3.0)",
@@ -49043,7 +49193,7 @@ var modeCommand = {
49043
49193
  return;
49044
49194
  }
49045
49195
  if (argv.status || !argv.mode) {
49046
- displayModeStatus();
49196
+ await displayModeStatus();
49047
49197
  return;
49048
49198
  }
49049
49199
  const modeName = argv.mode.toLowerCase();
@@ -49059,10 +49209,29 @@ var modeCommand = {
49059
49209
  process.exit(1);
49060
49210
  }
49061
49211
  const modeConfig = WORKFLOW_MODES[modeName];
49062
- console.log(chalk5.green.bold(`
49212
+ if (isModePersistenceEnabled()) {
49213
+ const saved = await saveModeState(modeName, {
49214
+ setBy: "cli",
49215
+ reason: `ax mode ${modeName}`
49216
+ });
49217
+ if (saved) {
49218
+ console.log(chalk5.green.bold(`
49063
49219
  \u2705 Workflow mode set to: ${modeName}
49064
49220
  `));
49065
- console.log(chalk5.gray(`Description: ${modeConfig.description}`));
49221
+ console.log(chalk5.gray(`Description: ${modeConfig.description}`));
49222
+ } else {
49223
+ console.log(chalk5.yellow.bold(`
49224
+ \u26A0\uFE0F Mode set to: ${modeName} (not persisted)
49225
+ `));
49226
+ console.log(chalk5.gray(`Description: ${modeConfig.description}`));
49227
+ }
49228
+ } else {
49229
+ console.log(chalk5.green.bold(`
49230
+ \u2705 Workflow mode set to: ${modeName}
49231
+ `));
49232
+ console.log(chalk5.gray(`Description: ${modeConfig.description}`));
49233
+ console.log(chalk5.gray("(Mode persistence disabled via AX_DISABLE_MODE_PERSISTENCE)"));
49234
+ }
49066
49235
  if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
49067
49236
  console.log(chalk5.yellow("\nRestricted tools in this mode:"));
49068
49237
  modeConfig.blockedTools.forEach((tool) => {
@@ -49076,9 +49245,14 @@ var modeCommand = {
49076
49245
  });
49077
49246
  }
49078
49247
  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 });
49248
+ if (modeName === "iterate") {
49249
+ console.log(chalk5.cyan('\u{1F4A1} Tip: Use `ax run <agent> "task"` and it will auto-use iterate mode'));
49250
+ } else if (modeName === "plan") {
49251
+ console.log(chalk5.cyan('\u{1F4A1} Tip: Use `ax run <agent> "task"` and it will auto-use plan mode'));
49252
+ console.log(chalk5.gray(" The mode will persist until you run `ax mode default`"));
49253
+ }
49254
+ console.log();
49255
+ logger.info("Workflow mode set", { mode: modeName, persisted: isModePersistenceEnabled() });
49082
49256
  } catch (error) {
49083
49257
  const err = error instanceof Error ? error : new Error(String(error));
49084
49258
  console.error(chalk5.red.bold(`
@@ -49108,15 +49282,30 @@ function displayModeList() {
49108
49282
  console.log(chalk5.gray("\nUsage: ax mode <mode-name>"));
49109
49283
  console.log(chalk5.gray("Example: ax mode plan\n"));
49110
49284
  }
49111
- function displayModeStatus() {
49112
- const currentMode = "default";
49285
+ async function displayModeStatus() {
49286
+ const modeState = await loadModeState();
49287
+ const currentMode = modeState?.mode ?? "default";
49113
49288
  const modeConfig = WORKFLOW_MODES[currentMode];
49114
49289
  console.log(chalk5.blue.bold("\n\u{1F4CA} Workflow Mode Status\n"));
49115
49290
  console.log(chalk5.dim("\u2500".repeat(50)));
49116
49291
  console.log(` Current mode: ${chalk5.cyan.bold(currentMode)}`);
49117
49292
  console.log(` Description: ${chalk5.gray(modeConfig.description)}`);
49293
+ if (modeState) {
49294
+ const setAt = new Date(modeState.setAt);
49295
+ const expiresAt = modeState.expiresAt ? new Date(modeState.expiresAt) : null;
49296
+ console.log(` Set at: ${chalk5.gray(setAt.toLocaleString())}`);
49297
+ if (expiresAt) {
49298
+ const remainingMs = expiresAt.getTime() - Date.now();
49299
+ const remainingMins = Math.round(remainingMs / 6e4);
49300
+ if (remainingMs > 0) {
49301
+ console.log(` Expires in: ${chalk5.gray(`${remainingMins} minutes`)}`);
49302
+ } else {
49303
+ console.log(` Status: ${chalk5.yellow("expired (will use default)")}`);
49304
+ }
49305
+ }
49306
+ }
49118
49307
  if (modeConfig.blockedTools && modeConfig.blockedTools.length > 0) {
49119
- console.log(` Blocked tools: ${chalk5.yellow(modeConfig.blockedTools.length)}`);
49308
+ console.log(` Blocked tools: ${chalk5.yellow(modeConfig.blockedTools.join(", "))}`);
49120
49309
  } else {
49121
49310
  console.log(` Blocked tools: ${chalk5.green("none")}`);
49122
49311
  }
@@ -49134,113 +49323,6 @@ init_logger();
49134
49323
  init_esm_shims();
49135
49324
  init_logger();
49136
49325
 
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
49326
  // src/core/orchestration/instruction-injector.ts
49245
49327
  init_esm_shims();
49246
49328
  init_logger();
@@ -49248,10 +49330,28 @@ init_logger();
49248
49330
  // src/core/orchestration/token-budget.ts
49249
49331
  init_esm_shims();
49250
49332
  init_logger();
49333
+ var PRIORITY_ORDER = {
49334
+ critical: 0,
49335
+ high: 1,
49336
+ normal: 2,
49337
+ low: 3
49338
+ };
49339
+ function createEmptyTypeUsage() {
49340
+ return {
49341
+ task: 0,
49342
+ memory: 0,
49343
+ session: 0,
49344
+ delegation: 0,
49345
+ mode: 0,
49346
+ context: 0
49347
+ };
49348
+ }
49251
49349
  var TokenBudgetManager = class _TokenBudgetManager {
49252
49350
  config;
49253
49351
  /** Characters per token estimate (conservative) */
49254
49352
  static CHARS_PER_TOKEN = 4;
49353
+ /** Overhead tokens for system-reminder XML tags and formatting */
49354
+ static FORMATTING_OVERHEAD_TOKENS = 50;
49255
49355
  constructor(config) {
49256
49356
  this.config = {
49257
49357
  ...DEFAULT_TOKEN_BUDGET,
@@ -49282,9 +49382,8 @@ var TokenBudgetManager = class _TokenBudgetManager {
49282
49382
  * Estimate tokens for an instruction (including formatting overhead)
49283
49383
  */
49284
49384
  estimateInstructionTokens(instruction) {
49285
- const overhead = 50;
49286
49385
  const contentTokens = this.estimateTokens(instruction.content).tokens;
49287
- return contentTokens + overhead;
49386
+ return contentTokens + _TokenBudgetManager.FORMATTING_OVERHEAD_TOKENS;
49288
49387
  }
49289
49388
  /**
49290
49389
  * Allocate budget for instructions
@@ -49298,24 +49397,12 @@ var TokenBudgetManager = class _TokenBudgetManager {
49298
49397
  allocateBudget(instructions) {
49299
49398
  const included = [];
49300
49399
  const excluded = [];
49301
- const perTypeUsage = {
49302
- task: 0,
49303
- memory: 0,
49304
- session: 0,
49305
- delegation: 0,
49306
- mode: 0
49307
- };
49400
+ const perTypeUsage = createEmptyTypeUsage();
49308
49401
  let tokensUsed = 0;
49309
49402
  const availableBudget = this.config.maxTotal;
49310
- const priorityOrder = {
49311
- critical: 0,
49312
- high: 1,
49313
- normal: 2,
49314
- low: 3
49315
- };
49316
49403
  const sorted = [...instructions].sort((a, b) => {
49317
- const aPriority = priorityOrder[a.priority] ?? 2;
49318
- const bPriority = priorityOrder[b.priority] ?? 2;
49404
+ const aPriority = PRIORITY_ORDER[a.priority];
49405
+ const bPriority = PRIORITY_ORDER[b.priority];
49319
49406
  const priorityDiff = aPriority - bPriority;
49320
49407
  if (priorityDiff !== 0) return priorityDiff;
49321
49408
  return a.createdAt - b.createdAt;
@@ -49427,12 +49514,12 @@ var TokenBudgetManager = class _TokenBudgetManager {
49427
49514
  };
49428
49515
 
49429
49516
  // src/core/orchestration/instruction-injector.ts
49517
+ var INSTRUCTION_TYPE_ORDER = ["mode", "task", "context", "memory", "session", "delegation"];
49430
49518
  var OrchestrationInstructionInjector = class {
49431
49519
  providers = /* @__PURE__ */ new Map();
49432
49520
  budgetManager;
49433
49521
  config;
49434
49522
  lastInjectionTime = 0;
49435
- instructionCache = /* @__PURE__ */ new Map();
49436
49523
  constructor(config) {
49437
49524
  this.config = {
49438
49525
  ...DEFAULT_ORCHESTRATION_CONFIG,
@@ -49555,8 +49642,7 @@ var OrchestrationInstructionInjector = class {
49555
49642
  grouped.set(instruction.type, existing);
49556
49643
  }
49557
49644
  const parts = [];
49558
- const typeOrder = ["mode", "task", "memory", "session", "delegation"];
49559
- for (const type of typeOrder) {
49645
+ for (const type of INSTRUCTION_TYPE_ORDER) {
49560
49646
  const typeInstructions = grouped.get(type);
49561
49647
  if (!typeInstructions || typeInstructions.length === 0) continue;
49562
49648
  for (const instruction of typeInstructions) {
@@ -49581,7 +49667,8 @@ ${instruction.content}
49581
49667
  if (instruction.expiresAfter === void 0) {
49582
49668
  return true;
49583
49669
  }
49584
- const turnsSinceCreation = currentTurn;
49670
+ const createdAtTurn = instruction.createdAtTurn ?? currentTurn;
49671
+ const turnsSinceCreation = currentTurn - createdAtTurn;
49585
49672
  return turnsSinceCreation < instruction.expiresAfter;
49586
49673
  });
49587
49674
  }
@@ -49589,16 +49676,10 @@ ${instruction.content}
49589
49676
  * Calculate per-type token usage
49590
49677
  */
49591
49678
  calculateTypeUsage(instructions) {
49592
- const usage = {
49593
- task: 0,
49594
- memory: 0,
49595
- session: 0,
49596
- delegation: 0,
49597
- mode: 0
49598
- };
49679
+ const usage = createEmptyTypeUsage();
49599
49680
  for (const instruction of instructions) {
49600
49681
  const tokens = this.budgetManager.estimateInstructionTokens(instruction);
49601
- usage[instruction.type] = (usage[instruction.type] || 0) + tokens;
49682
+ usage[instruction.type] += tokens;
49602
49683
  }
49603
49684
  return usage;
49604
49685
  }
@@ -49614,22 +49695,15 @@ ${instruction.content}
49614
49695
  excluded: [],
49615
49696
  tokensUsed: 0,
49616
49697
  remaining: this.budgetManager.getConfig().maxTotal,
49617
- perTypeUsage: {
49618
- task: 0,
49619
- memory: 0,
49620
- session: 0,
49621
- delegation: 0,
49622
- mode: 0
49623
- }
49698
+ perTypeUsage: createEmptyTypeUsage()
49624
49699
  },
49625
49700
  hasInstructions: false
49626
49701
  };
49627
49702
  }
49628
49703
  /**
49629
- * Clear instruction cache
49704
+ * Clear instruction cache (placeholder for future caching implementation)
49630
49705
  */
49631
49706
  clearCache() {
49632
- this.instructionCache.clear();
49633
49707
  logger.debug("Instruction cache cleared");
49634
49708
  }
49635
49709
  /**
@@ -49709,7 +49783,7 @@ var TodoInstructionProvider = class {
49709
49783
  if (!context.todos || context.todos.length === 0) {
49710
49784
  return false;
49711
49785
  }
49712
- const currentHash = this.computeStateHash(context.todos);
49786
+ const currentHash = computeTodoHash(context.todos);
49713
49787
  const stateChanged = currentHash !== this.lastStateHash;
49714
49788
  const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
49715
49789
  const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
@@ -49723,14 +49797,24 @@ var TodoInstructionProvider = class {
49723
49797
  if (!context.todos || context.todos.length === 0) {
49724
49798
  return instructions;
49725
49799
  }
49726
- const currentHash = this.computeStateHash(context.todos);
49800
+ const currentHash = computeTodoHash(context.todos);
49727
49801
  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");
49802
+ const inProgressTasks = [];
49803
+ const pendingTasks = [];
49804
+ const completedTasks = [];
49805
+ for (const todo of context.todos) {
49806
+ switch (todo.status) {
49807
+ case "in_progress":
49808
+ inProgressTasks.push(todo);
49809
+ break;
49810
+ case "pending":
49811
+ pendingTasks.push(todo);
49812
+ break;
49813
+ case "completed":
49814
+ completedTasks.push(todo);
49815
+ break;
49816
+ }
49817
+ }
49734
49818
  let content;
49735
49819
  let priority;
49736
49820
  if (stateChanged) {
@@ -49747,8 +49831,9 @@ var TodoInstructionProvider = class {
49747
49831
  type: "task",
49748
49832
  priority,
49749
49833
  content,
49750
- source: "automatosx",
49834
+ source: INSTRUCTION_SOURCE,
49751
49835
  createdAt: Date.now(),
49836
+ createdAtTurn: context.turnCount,
49752
49837
  expiresAfter: this.config.reminderFrequency + 1,
49753
49838
  id: `todo-${currentHash.substring(0, 8)}`
49754
49839
  });
@@ -49825,13 +49910,6 @@ var TodoInstructionProvider = class {
49825
49910
  }
49826
49911
  return parts.join(" | ");
49827
49912
  }
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
49913
  /**
49836
49914
  * Get current configuration
49837
49915
  */
@@ -49860,10 +49938,15 @@ var TodoInstructionProvider = class {
49860
49938
  logger.debug("TodoInstructionProvider state reset");
49861
49939
  }
49862
49940
  };
49941
+ function computeTodoHash(todos) {
49942
+ const stateString = todos.map((t) => `${t.id}:${t.status}:${t.content}`).sort().join("|");
49943
+ return crypto2.createHash("sha256").update(stateString).digest("hex").substring(0, 16);
49944
+ }
49863
49945
 
49864
49946
  // src/core/orchestration/memory-instruction-provider.ts
49865
49947
  init_esm_shims();
49866
49948
  init_logger();
49949
+ var DEFAULT_CONTENT_MAX_LENGTH = 500;
49867
49950
  var DEFAULT_MEMORY_CONFIG = {
49868
49951
  enabled: true,
49869
49952
  maxEntries: 5,
@@ -49872,8 +49955,9 @@ var DEFAULT_MEMORY_CONFIG = {
49872
49955
  maxAge: 0,
49873
49956
  // No limit by default
49874
49957
  includeMetadata: true,
49875
- cacheTTL: 6e4
49958
+ cacheTTL: 6e4,
49876
49959
  // 1 minute
49960
+ contentMaxLength: DEFAULT_CONTENT_MAX_LENGTH
49877
49961
  };
49878
49962
  var MemoryInstructionProvider = class {
49879
49963
  name = "memory";
@@ -49942,8 +50026,9 @@ var MemoryInstructionProvider = class {
49942
50026
  type: "memory",
49943
50027
  priority: "normal",
49944
50028
  content,
49945
- source: "automatosx",
50029
+ source: INSTRUCTION_SOURCE,
49946
50030
  createdAt: Date.now(),
50031
+ createdAtTurn: context.turnCount,
49947
50032
  expiresAfter: this.config.searchFrequency + 1,
49948
50033
  id: `memory-${Date.now()}`
49949
50034
  });
@@ -49966,9 +50051,12 @@ var MemoryInstructionProvider = class {
49966
50051
  if (context.currentTask) {
49967
50052
  parts.push(context.currentTask);
49968
50053
  }
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);
50054
+ let inProgressCount = 0;
50055
+ for (const todo of context.todos) {
50056
+ if (todo.status === "in_progress") {
50057
+ parts.push(todo.content);
50058
+ if (++inProgressCount >= 2) break;
50059
+ }
49972
50060
  }
49973
50061
  if (context.agentName) {
49974
50062
  parts.push(context.agentName);
@@ -50042,8 +50130,7 @@ var MemoryInstructionProvider = class {
50042
50130
  } else {
50043
50131
  lines.push(`### Memory ${i + 1} (${relevancePercent}% relevant)`);
50044
50132
  }
50045
- const maxLength = 500;
50046
- const content = memory.content.length > maxLength ? memory.content.substring(0, maxLength) + "..." : memory.content;
50133
+ const content = memory.content.length > this.config.contentMaxLength ? memory.content.substring(0, this.config.contentMaxLength) + "..." : memory.content;
50047
50134
  lines.push(content);
50048
50135
  lines.push("");
50049
50136
  }
@@ -50105,6 +50192,7 @@ var DEFAULT_SESSION_CONFIG = {
50105
50192
  reminderFrequency: 5,
50106
50193
  showHandoffContext: true
50107
50194
  };
50195
+ var SESSION_CACHE_TTL_MS = 3e4;
50108
50196
  var SessionInstructionProvider = class {
50109
50197
  name = "session";
50110
50198
  config;
@@ -50112,8 +50200,6 @@ var SessionInstructionProvider = class {
50112
50200
  lastReminderTurn = 0;
50113
50201
  cachedState;
50114
50202
  cacheExpiry = 0;
50115
- CACHE_TTL = 3e4;
50116
- // 30 seconds
50117
50203
  constructor(stateProvider, config) {
50118
50204
  this.config = {
50119
50205
  ...DEFAULT_SESSION_CONFIG,
@@ -50161,10 +50247,11 @@ var SessionInstructionProvider = class {
50161
50247
  type: "session",
50162
50248
  priority: "normal",
50163
50249
  content,
50164
- source: "automatosx",
50250
+ source: INSTRUCTION_SOURCE,
50165
50251
  createdAt: Date.now(),
50252
+ createdAtTurn: context.turnCount,
50166
50253
  expiresAfter: this.config.reminderFrequency,
50167
- id: `session-${context.sessionId || "default"}-${Date.now()}`
50254
+ id: `session-${context.sessionId ?? "default"}-${Date.now()}`
50168
50255
  });
50169
50256
  }
50170
50257
  this.lastReminderTurn = context.turnCount;
@@ -50191,7 +50278,7 @@ var SessionInstructionProvider = class {
50191
50278
  const state = await this.stateProvider.getSessionState(context.sessionId);
50192
50279
  if (state) {
50193
50280
  this.cachedState = state;
50194
- this.cacheExpiry = Date.now() + this.CACHE_TTL;
50281
+ this.cacheExpiry = Date.now() + SESSION_CACHE_TTL_MS;
50195
50282
  }
50196
50283
  return state;
50197
50284
  } catch (error) {
@@ -50635,22 +50722,42 @@ var STANDARD_TEMPLATE = {
50635
50722
  "Keep changes focused"
50636
50723
  ]
50637
50724
  };
50725
+ var FULLSTACK_TEMPLATE = {
50726
+ ...BACKEND_TEMPLATE,
50727
+ domain: "fullstack",
50728
+ displayName: "Fullstack Engineer"
50729
+ };
50730
+ var DATA_TEMPLATE = {
50731
+ ...BACKEND_TEMPLATE,
50732
+ domain: "data",
50733
+ displayName: "Data Engineer"
50734
+ };
50735
+ var MOBILE_TEMPLATE = {
50736
+ ...FRONTEND_TEMPLATE,
50737
+ domain: "mobile",
50738
+ displayName: "Mobile Engineer"
50739
+ };
50740
+ var RESEARCHER_TEMPLATE = {
50741
+ ...STANDARD_TEMPLATE,
50742
+ domain: "researcher",
50743
+ displayName: "Researcher"
50744
+ };
50638
50745
  var AGENT_TEMPLATES = {
50639
50746
  backend: BACKEND_TEMPLATE,
50640
50747
  frontend: FRONTEND_TEMPLATE,
50641
- fullstack: { ...BACKEND_TEMPLATE, domain: "fullstack", displayName: "Fullstack Engineer" },
50748
+ fullstack: FULLSTACK_TEMPLATE,
50642
50749
  security: SECURITY_TEMPLATE,
50643
50750
  quality: QUALITY_TEMPLATE,
50644
50751
  architecture: ARCHITECTURE_TEMPLATE,
50645
50752
  devops: DEVOPS_TEMPLATE,
50646
- data: { ...BACKEND_TEMPLATE, domain: "data", displayName: "Data Engineer" },
50647
- mobile: { ...FRONTEND_TEMPLATE, domain: "mobile", displayName: "Mobile Engineer" },
50753
+ data: DATA_TEMPLATE,
50754
+ mobile: MOBILE_TEMPLATE,
50648
50755
  writer: WRITER_TEMPLATE,
50649
- researcher: { ...STANDARD_TEMPLATE, domain: "researcher", displayName: "Researcher" },
50756
+ researcher: RESEARCHER_TEMPLATE,
50650
50757
  standard: STANDARD_TEMPLATE
50651
50758
  };
50652
50759
  function getAgentTemplate(domain) {
50653
- return AGENT_TEMPLATES[domain] || STANDARD_TEMPLATE;
50760
+ return AGENT_TEMPLATES[domain] ?? STANDARD_TEMPLATE;
50654
50761
  }
50655
50762
  function isValidAgentDomain(domain) {
50656
50763
  return domain in AGENT_TEMPLATES;
@@ -50682,8 +50789,95 @@ var DEFAULT_AGENT_CONFIG = {
50682
50789
  minDelegationKeywords: 1,
50683
50790
  includeQualityChecklist: true,
50684
50791
  qualityChecklistFrequency: 10,
50685
- includeAntiPatterns: true
50792
+ includeAntiPatterns: true,
50793
+ contextAwareBoosting: true
50686
50794
  };
50795
+ var CONTEXT_KEYWORD_CATEGORIES = [
50796
+ {
50797
+ name: "security",
50798
+ keywords: ["auth", "authentication", "authorization", "login", "password", "token", "jwt", "oauth", "session", "credential", "encrypt", "decrypt", "hash", "secret", "permission", "role", "access control", "csrf", "xss", "injection", "sanitize", "validate input"],
50799
+ boostDomains: ["security"],
50800
+ additionalChecklist: [
50801
+ "Validate all user input before processing",
50802
+ "Use parameterized queries to prevent injection",
50803
+ "Ensure sensitive data is not logged or exposed",
50804
+ "Implement proper session management",
50805
+ "Follow OWASP Top 10 guidelines"
50806
+ ]
50807
+ },
50808
+ {
50809
+ name: "database",
50810
+ keywords: ["database", "db", "sql", "query", "migration", "schema", "table", "index", "transaction", "orm", "prisma", "mongoose", "postgresql", "mysql", "sqlite", "redis", "cache"],
50811
+ boostDomains: ["backend"],
50812
+ additionalChecklist: [
50813
+ "Use transactions for multi-step operations",
50814
+ "Add appropriate indexes for query performance",
50815
+ "Handle connection pooling properly",
50816
+ "Avoid N+1 query patterns",
50817
+ "Use prepared statements for security"
50818
+ ]
50819
+ },
50820
+ {
50821
+ name: "api",
50822
+ keywords: ["api", "endpoint", "rest", "graphql", "request", "response", "http", "status code", "route", "middleware", "cors", "rate limit"],
50823
+ boostDomains: ["backend"],
50824
+ additionalChecklist: [
50825
+ "Use appropriate HTTP status codes",
50826
+ "Validate request body and parameters",
50827
+ "Document API with clear examples",
50828
+ "Implement proper error responses",
50829
+ "Consider rate limiting for public endpoints"
50830
+ ]
50831
+ },
50832
+ {
50833
+ name: "testing",
50834
+ keywords: ["test", "testing", "unit test", "integration test", "e2e", "mock", "stub", "fixture", "coverage", "assert", "expect", "vitest", "jest", "cypress"],
50835
+ boostDomains: ["quality"],
50836
+ additionalChecklist: [
50837
+ "Test behavior, not implementation details",
50838
+ "Include edge cases and error scenarios",
50839
+ "Keep tests isolated and independent",
50840
+ "Use meaningful test descriptions",
50841
+ "Aim for high coverage on critical paths"
50842
+ ]
50843
+ },
50844
+ {
50845
+ name: "performance",
50846
+ keywords: ["performance", "optimize", "slow", "fast", "latency", "memory", "cpu", "bottleneck", "profiling", "benchmark", "cache", "lazy load", "debounce", "throttle"],
50847
+ boostDomains: ["backend", "devops"],
50848
+ additionalChecklist: [
50849
+ "Profile before optimizing",
50850
+ "Consider caching for expensive operations",
50851
+ "Avoid premature optimization",
50852
+ "Measure impact of changes",
50853
+ "Watch for memory leaks"
50854
+ ]
50855
+ },
50856
+ {
50857
+ name: "deployment",
50858
+ keywords: ["deploy", "deployment", "ci", "cd", "pipeline", "docker", "kubernetes", "container", "production", "staging", "environment", "config", "secret", "infrastructure"],
50859
+ boostDomains: ["devops"],
50860
+ additionalChecklist: [
50861
+ "Never hardcode secrets or credentials",
50862
+ "Use environment variables for configuration",
50863
+ "Ensure rollback strategy exists",
50864
+ "Test in staging before production",
50865
+ "Monitor deployment health"
50866
+ ]
50867
+ },
50868
+ {
50869
+ name: "frontend",
50870
+ keywords: ["ui", "ux", "component", "react", "vue", "angular", "css", "style", "responsive", "accessibility", "a11y", "wcag", "form", "validation", "state", "render"],
50871
+ boostDomains: ["frontend"],
50872
+ additionalChecklist: [
50873
+ "Ensure accessibility (ARIA labels, keyboard nav)",
50874
+ "Handle loading and error states",
50875
+ "Optimize for performance (memo, lazy loading)",
50876
+ "Test across different screen sizes",
50877
+ "Validate forms with clear error messages"
50878
+ ]
50879
+ }
50880
+ ];
50687
50881
  var AgentInstructionInjector = class {
50688
50882
  name = "agent-template";
50689
50883
  config;
@@ -50730,11 +50924,12 @@ var AgentInstructionInjector = class {
50730
50924
  if (!domain) {
50731
50925
  return false;
50732
50926
  }
50927
+ const taskText = this.extractTaskText(context);
50733
50928
  const turnsSinceReminder = context.turnCount - this.lastReminderTurn;
50734
50929
  const reminderDue = turnsSinceReminder >= this.config.reminderFrequency;
50735
50930
  const turnsSinceQuality = context.turnCount - this.lastQualityCheckTurn;
50736
50931
  const qualityDue = this.config.includeQualityChecklist && turnsSinceQuality >= this.config.qualityChecklistFrequency;
50737
- const hasDelegationTriggers = this.config.delegationDetection && this.checkDelegationTriggers(context);
50932
+ const hasDelegationTriggers = this.config.delegationDetection && taskText !== this.recentTaskText && this.checkDelegationTriggers(context, domain, taskText);
50738
50933
  return reminderDue || qualityDue || hasDelegationTriggers;
50739
50934
  }
50740
50935
  /**
@@ -50755,8 +50950,9 @@ var AgentInstructionInjector = class {
50755
50950
  type: "delegation",
50756
50951
  priority: "normal",
50757
50952
  content: reminderContent,
50758
- source: "automatosx",
50953
+ source: INSTRUCTION_SOURCE,
50759
50954
  createdAt: Date.now(),
50955
+ createdAtTurn: context.turnCount,
50760
50956
  expiresAfter: this.config.reminderFrequency,
50761
50957
  id: `agent-reminder-${domain}-${Date.now()}`
50762
50958
  });
@@ -50768,15 +50964,16 @@ var AgentInstructionInjector = class {
50768
50964
  type: "delegation",
50769
50965
  priority: "normal",
50770
50966
  content: checklistContent,
50771
- source: "automatosx",
50967
+ source: INSTRUCTION_SOURCE,
50772
50968
  createdAt: Date.now(),
50969
+ createdAtTurn: context.turnCount,
50773
50970
  expiresAfter: this.config.qualityChecklistFrequency,
50774
50971
  id: `agent-quality-${domain}-${Date.now()}`
50775
50972
  });
50776
50973
  this.lastQualityCheckTurn = context.turnCount;
50777
50974
  }
50975
+ const taskText = this.extractTaskText(context);
50778
50976
  if (this.config.delegationDetection) {
50779
- const taskText = this.extractTaskText(context);
50780
50977
  if (taskText !== this.recentTaskText) {
50781
50978
  this.recentTaskText = taskText;
50782
50979
  const delegationContent = this.checkAndFormatDelegation(template, taskText);
@@ -50785,14 +50982,34 @@ var AgentInstructionInjector = class {
50785
50982
  type: "delegation",
50786
50983
  priority: "high",
50787
50984
  content: delegationContent,
50788
- source: "automatosx",
50985
+ source: INSTRUCTION_SOURCE,
50789
50986
  createdAt: Date.now(),
50987
+ createdAtTurn: context.turnCount,
50790
50988
  expiresAfter: 3,
50791
50989
  id: `agent-delegation-${Date.now()}`
50792
50990
  });
50793
50991
  }
50794
50992
  }
50795
50993
  }
50994
+ if (this.config.contextAwareBoosting && taskText) {
50995
+ const detectedCategories = this.detectContextCategories(taskText);
50996
+ const contextBoostContent = this.formatContextBoost(detectedCategories);
50997
+ if (contextBoostContent) {
50998
+ instructions.push({
50999
+ type: "context",
51000
+ priority: "normal",
51001
+ content: contextBoostContent,
51002
+ source: INSTRUCTION_SOURCE,
51003
+ createdAt: Date.now(),
51004
+ createdAtTurn: context.turnCount,
51005
+ expiresAfter: 5,
51006
+ id: `agent-context-boost-${Date.now()}`
51007
+ });
51008
+ logger.debug("Context-aware boost applied", {
51009
+ categories: detectedCategories.map((c) => c.name)
51010
+ });
51011
+ }
51012
+ }
50796
51013
  logger.debug("Agent instructions generated", {
50797
51014
  domain,
50798
51015
  instructionCount: instructions.length
@@ -50816,20 +51033,22 @@ var AgentInstructionInjector = class {
50816
51033
  if (context.currentTask) {
50817
51034
  parts.push(context.currentTask);
50818
51035
  }
50819
- for (const todo of context.todos.filter((t) => t.status === "in_progress")) {
50820
- parts.push(todo.content);
51036
+ for (const todo of context.todos) {
51037
+ if (todo.status === "in_progress") {
51038
+ parts.push(todo.content);
51039
+ }
50821
51040
  }
50822
51041
  return parts.join(" ");
50823
51042
  }
50824
51043
  /**
50825
51044
  * Check if delegation triggers are present
50826
51045
  */
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);
51046
+ checkDelegationTriggers(context, domain, taskText) {
51047
+ const resolvedDomain = domain ?? this.resolveDomain(context);
51048
+ if (!resolvedDomain) return false;
51049
+ const text = taskText ?? this.extractTaskText(context);
51050
+ if (!text) return false;
51051
+ const suggestions = getDelegationSuggestions(text, resolvedDomain);
50833
51052
  return suggestions.some((s) => s.keywords.length >= this.config.minDelegationKeywords);
50834
51053
  }
50835
51054
  /**
@@ -50890,6 +51109,54 @@ var AgentInstructionInjector = class {
50890
51109
  lines.push("Use `DELEGATE TO @agent: task` or `@agent task` syntax to delegate.");
50891
51110
  return lines.join("\n");
50892
51111
  }
51112
+ /**
51113
+ * Detect context categories from task text
51114
+ * @since v11.3.1
51115
+ */
51116
+ detectContextCategories(taskText) {
51117
+ if (!taskText || !this.config.contextAwareBoosting) {
51118
+ return [];
51119
+ }
51120
+ const textLower = taskText.toLowerCase();
51121
+ const matchedCategories = [];
51122
+ for (const category of CONTEXT_KEYWORD_CATEGORIES) {
51123
+ const matchCount = category.keywords.filter(
51124
+ (kw) => textLower.includes(kw.toLowerCase())
51125
+ ).length;
51126
+ if (matchCount > 0) {
51127
+ matchedCategories.push(category);
51128
+ }
51129
+ }
51130
+ return matchedCategories;
51131
+ }
51132
+ /**
51133
+ * Format context-aware boosted instructions
51134
+ * @since v11.3.1
51135
+ */
51136
+ formatContextBoost(categories) {
51137
+ if (categories.length === 0) {
51138
+ return null;
51139
+ }
51140
+ const lines = [];
51141
+ const allChecklistItems = /* @__PURE__ */ new Set();
51142
+ const categoryNames = [];
51143
+ for (const category of categories) {
51144
+ categoryNames.push(category.name);
51145
+ for (const item of category.additionalChecklist.slice(0, 3)) {
51146
+ allChecklistItems.add(item);
51147
+ }
51148
+ }
51149
+ if (allChecklistItems.size === 0) {
51150
+ return null;
51151
+ }
51152
+ lines.push(`## Context-Aware Reminders (${categoryNames.join(", ")})`);
51153
+ lines.push("");
51154
+ lines.push("Based on task keywords, ensure you:");
51155
+ for (const item of Array.from(allChecklistItems).slice(0, 5)) {
51156
+ lines.push(`- ${item}`);
51157
+ }
51158
+ return lines.join("\n");
51159
+ }
50893
51160
  /**
50894
51161
  * Get current configuration
50895
51162
  */
@@ -51032,8 +51299,13 @@ var OrchestrationService = class {
51032
51299
  }
51033
51300
  /**
51034
51301
  * Set the workflow mode
51302
+ *
51303
+ * @throws Error if mode is not a valid WorkflowMode
51035
51304
  */
51036
51305
  setWorkflowMode(mode) {
51306
+ if (!isValidWorkflowMode(mode)) {
51307
+ throw new Error(`Invalid workflow mode: ${mode}. Valid modes: default, plan, iterate, review`);
51308
+ }
51037
51309
  this.workflowModeManager.setMode(mode);
51038
51310
  logger.debug("Workflow mode set", { mode });
51039
51311
  }
@@ -51060,6 +51332,7 @@ var OrchestrationService = class {
51060
51332
  */
51061
51333
  incrementTurn() {
51062
51334
  this.turnCount++;
51335
+ this.workflowModeManager.updateTurnCount(this.turnCount);
51063
51336
  }
51064
51337
  /**
51065
51338
  * Get current turn count
@@ -51149,10 +51422,49 @@ ${content}
51149
51422
  updateConfig(updates) {
51150
51423
  this.config = {
51151
51424
  ...this.config,
51152
- ...updates
51425
+ ...updates,
51426
+ tokenBudget: updates.tokenBudget ? { ...this.config.tokenBudget, ...updates.tokenBudget } : this.config.tokenBudget,
51427
+ todoIntegration: updates.todoIntegration ? { ...this.config.todoIntegration, ...updates.todoIntegration } : this.config.todoIntegration,
51428
+ memoryIntegration: updates.memoryIntegration ? { ...this.config.memoryIntegration, ...updates.memoryIntegration } : this.config.memoryIntegration,
51429
+ sessionIntegration: updates.sessionIntegration ? { ...this.config.sessionIntegration, ...updates.sessionIntegration } : this.config.sessionIntegration,
51430
+ agentTemplates: updates.agentTemplates ? { ...this.config.agentTemplates, ...updates.agentTemplates } : this.config.agentTemplates
51153
51431
  };
51154
51432
  if (updates.tokenBudget) {
51155
- this.tokenBudgetManager = new TokenBudgetManager(updates.tokenBudget);
51433
+ this.tokenBudgetManager.updateConfig(this.config.tokenBudget);
51434
+ }
51435
+ this.injector.updateConfig(updates);
51436
+ if (updates.todoIntegration && this.todoProvider) {
51437
+ const current = this.todoProvider.getConfig();
51438
+ this.todoProvider.updateConfig({
51439
+ enabled: updates.todoIntegration.enabled ?? current.enabled,
51440
+ reminderFrequency: updates.todoIntegration.reminderFrequency ?? current.reminderFrequency,
51441
+ compactMode: updates.todoIntegration.compactMode ?? current.compactMode
51442
+ });
51443
+ }
51444
+ if (updates.memoryIntegration && this.memoryProvider) {
51445
+ const current = this.memoryProvider.getConfig();
51446
+ this.memoryProvider.updateConfig({
51447
+ enabled: updates.memoryIntegration.enabled ?? current.enabled,
51448
+ maxEntries: updates.memoryIntegration.maxEntries ?? current.maxEntries,
51449
+ minRelevance: updates.memoryIntegration.minRelevance ?? current.minRelevance
51450
+ });
51451
+ }
51452
+ if (updates.sessionIntegration && this.sessionProvider) {
51453
+ const current = this.sessionProvider.getConfig();
51454
+ this.sessionProvider.updateConfig({
51455
+ enabled: updates.sessionIntegration.enabled ?? current.enabled,
51456
+ showCollaboration: updates.sessionIntegration.showCollaboration ?? current.showCollaboration
51457
+ });
51458
+ }
51459
+ if (updates.agentTemplates) {
51460
+ const agentUpdates = {};
51461
+ if (updates.agentTemplates.enabled !== void 0) {
51462
+ agentUpdates.enabled = updates.agentTemplates.enabled;
51463
+ }
51464
+ if (updates.agentTemplates.reminderFrequency !== void 0) {
51465
+ agentUpdates.reminderFrequency = updates.agentTemplates.reminderFrequency;
51466
+ }
51467
+ this.agentInjector.updateConfig(agentUpdates);
51156
51468
  }
51157
51469
  logger.debug("OrchestrationService config updated", { updates });
51158
51470
  }
@@ -51271,17 +51583,18 @@ function displayTokenBudget(verbose) {
51271
51583
  console.log(` Critical reserve: ${chalk5.yellow(config.criticalReserve)} tokens`);
51272
51584
  console.log(` Available: ${chalk5.green(config.maxTotal - config.criticalReserve)} tokens`);
51273
51585
  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 }) => {
51586
+ const typeDescriptions = {
51587
+ task: "Todo/task reminders",
51588
+ memory: "Memory context",
51589
+ session: "Session state",
51590
+ delegation: "Agent delegation hints",
51591
+ mode: "Workflow mode instructions",
51592
+ context: "Context-aware boosted reminders"
51593
+ };
51594
+ Object.entries(config.perType).forEach(([type, budget]) => {
51282
51595
  console.log(` \u2022 ${chalk5.cyan(type)}: ${budget} tokens`);
51283
- if (verbose) {
51284
- console.log(chalk5.gray(` ${description}`));
51596
+ if (verbose && typeDescriptions[type]) {
51597
+ console.log(chalk5.gray(` ${typeDescriptions[type]}`));
51285
51598
  }
51286
51599
  });
51287
51600
  console.log(chalk5.cyan("\n Token Estimation:"));
@@ -51405,6 +51718,228 @@ function displayAgentTemplate(domain, verbose) {
51405
51718
  console.log();
51406
51719
  }
51407
51720
 
51721
+ // src/cli/commands/shortcuts.ts
51722
+ init_esm_shims();
51723
+ init_logger();
51724
+ async function runAxCommand(args) {
51725
+ return new Promise((resolve13, reject) => {
51726
+ const nodeExe = process.argv[0];
51727
+ const cliScript = process.argv[1];
51728
+ if (!nodeExe || !cliScript) {
51729
+ reject(new Error("Cannot determine CLI path"));
51730
+ return;
51731
+ }
51732
+ const child = spawn(nodeExe, [cliScript, ...args], {
51733
+ stdio: "inherit",
51734
+ env: process.env
51735
+ });
51736
+ child.on("close", (code) => {
51737
+ if (code === 0) {
51738
+ resolve13();
51739
+ } else {
51740
+ reject(new Error(`Command exited with code ${code}`));
51741
+ }
51742
+ });
51743
+ child.on("error", reject);
51744
+ });
51745
+ }
51746
+ var planCommand = {
51747
+ command: "plan [task]",
51748
+ describe: "Enter plan mode and explore/plan a task (shortcut for ax mode plan + ax run)",
51749
+ builder: (yargs2) => {
51750
+ return yargs2.positional("task", {
51751
+ describe: "Task to plan (optional - if not provided, just sets mode)",
51752
+ type: "string"
51753
+ }).option("agent", {
51754
+ alias: "a",
51755
+ describe: "Agent to use (auto-selects if not specified)",
51756
+ type: "string"
51757
+ }).option("provider", {
51758
+ alias: "p",
51759
+ describe: "Override provider",
51760
+ type: "string"
51761
+ }).option("verbose", {
51762
+ alias: "v",
51763
+ describe: "Verbose output",
51764
+ type: "boolean",
51765
+ default: false
51766
+ }).option("quiet", {
51767
+ alias: "q",
51768
+ describe: "Quiet output",
51769
+ type: "boolean",
51770
+ default: false
51771
+ }).example("$0 plan", "Enter plan mode").example('$0 plan "design auth system"', "Plan a task with auto-selected agent").example('$0 plan "design API" --agent architecture', "Plan with specific agent");
51772
+ },
51773
+ handler: async (argv) => {
51774
+ try {
51775
+ const saved = await saveModeState("plan", {
51776
+ setBy: "shortcut",
51777
+ reason: "ax plan command"
51778
+ });
51779
+ if (!saved) {
51780
+ logger.warn("Failed to persist mode state, continuing anyway");
51781
+ }
51782
+ if (!argv.quiet) {
51783
+ console.log(chalk5.cyan.bold("\n\u{1F4CB} Plan Mode Activated\n"));
51784
+ console.log(chalk5.gray("Read-only exploration mode - no file modifications allowed"));
51785
+ console.log(chalk5.gray("Use `ax mode default` to exit plan mode\n"));
51786
+ }
51787
+ if (argv.task) {
51788
+ const runArgs = ["run"];
51789
+ if (argv.agent) runArgs.push(argv.agent);
51790
+ runArgs.push(argv.task);
51791
+ if (argv.provider) runArgs.push("--provider", argv.provider);
51792
+ if (argv.verbose) runArgs.push("--verbose");
51793
+ if (argv.quiet) runArgs.push("--quiet");
51794
+ await runAxCommand(runArgs);
51795
+ } else {
51796
+ console.log(chalk5.gray('No task specified. Use `ax run <agent> "task"` to run in plan mode.'));
51797
+ }
51798
+ logger.info("Plan shortcut executed", { task: argv.task, agent: argv.agent });
51799
+ } catch (error) {
51800
+ const err = error instanceof Error ? error : new Error(String(error));
51801
+ console.error(chalk5.red.bold(`
51802
+ \u274C Error: ${err.message}
51803
+ `));
51804
+ process.exit(1);
51805
+ }
51806
+ }
51807
+ };
51808
+ var iterateCommand = {
51809
+ command: "iterate [task]",
51810
+ describe: "Enter iterate mode and run a task autonomously (shortcut for ax mode iterate + ax run --iterate)",
51811
+ builder: (yargs2) => {
51812
+ return yargs2.positional("task", {
51813
+ describe: "Task to execute (optional - if not provided, just sets mode)",
51814
+ type: "string"
51815
+ }).option("agent", {
51816
+ alias: "a",
51817
+ describe: "Agent to use (auto-selects if not specified)",
51818
+ type: "string"
51819
+ }).option("timeout", {
51820
+ alias: "t",
51821
+ describe: "Max duration in minutes",
51822
+ type: "number"
51823
+ }).option("max-tokens", {
51824
+ describe: "Max total tokens",
51825
+ type: "number"
51826
+ }).option("provider", {
51827
+ alias: "p",
51828
+ describe: "Override provider",
51829
+ type: "string"
51830
+ }).option("verbose", {
51831
+ alias: "v",
51832
+ describe: "Verbose output",
51833
+ type: "boolean",
51834
+ default: false
51835
+ }).option("quiet", {
51836
+ alias: "q",
51837
+ describe: "Quiet output",
51838
+ type: "boolean",
51839
+ default: false
51840
+ }).example("$0 iterate", "Enter iterate mode").example('$0 iterate "implement auth"', "Run task in iterate mode").example('$0 iterate "fix bug" --agent backend', "Iterate with specific agent");
51841
+ },
51842
+ handler: async (argv) => {
51843
+ try {
51844
+ const saved = await saveModeState("iterate", {
51845
+ setBy: "shortcut",
51846
+ reason: "ax iterate command"
51847
+ });
51848
+ if (!saved) {
51849
+ logger.warn("Failed to persist mode state, continuing anyway");
51850
+ }
51851
+ if (!argv.quiet) {
51852
+ console.log(chalk5.cyan.bold("\n\u{1F504} Iterate Mode Activated\n"));
51853
+ console.log(chalk5.gray("Autonomous execution mode - agent will work continuously"));
51854
+ console.log(chalk5.gray("Use `ax mode default` to exit iterate mode\n"));
51855
+ }
51856
+ if (argv.task) {
51857
+ const runArgs = ["run"];
51858
+ if (argv.agent) runArgs.push(argv.agent);
51859
+ runArgs.push(argv.task);
51860
+ runArgs.push("--iterate");
51861
+ if (argv.timeout) runArgs.push("--iterate-timeout", String(argv.timeout));
51862
+ if (argv.maxTokens) runArgs.push("--iterate-max-tokens", String(argv.maxTokens));
51863
+ if (argv.provider) runArgs.push("--provider", argv.provider);
51864
+ if (argv.verbose) runArgs.push("--verbose");
51865
+ if (argv.quiet) runArgs.push("--quiet");
51866
+ await runAxCommand(runArgs);
51867
+ } else {
51868
+ console.log(chalk5.gray('No task specified. Use `ax run <agent> "task"` to run in iterate mode.'));
51869
+ }
51870
+ logger.info("Iterate shortcut executed", { task: argv.task, agent: argv.agent });
51871
+ } catch (error) {
51872
+ const err = error instanceof Error ? error : new Error(String(error));
51873
+ console.error(chalk5.red.bold(`
51874
+ \u274C Error: ${err.message}
51875
+ `));
51876
+ process.exit(1);
51877
+ }
51878
+ }
51879
+ };
51880
+ var reviewCommand = {
51881
+ command: "review [path]",
51882
+ describe: "Enter review mode and analyze code (shortcut for ax mode review + ax run quality)",
51883
+ builder: (yargs2) => {
51884
+ return yargs2.positional("path", {
51885
+ describe: "Path to review (file or directory)",
51886
+ type: "string"
51887
+ }).option("agent", {
51888
+ alias: "a",
51889
+ describe: "Agent to use (defaults to quality)",
51890
+ type: "string",
51891
+ default: "quality"
51892
+ }).option("provider", {
51893
+ alias: "p",
51894
+ describe: "Override provider",
51895
+ type: "string"
51896
+ }).option("verbose", {
51897
+ alias: "v",
51898
+ describe: "Verbose output",
51899
+ type: "boolean",
51900
+ default: false
51901
+ }).option("quiet", {
51902
+ alias: "q",
51903
+ describe: "Quiet output",
51904
+ type: "boolean",
51905
+ default: false
51906
+ }).example("$0 review", "Enter review mode").example("$0 review src/core/", "Review a directory").example("$0 review src/api.ts", "Review a specific file");
51907
+ },
51908
+ handler: async (argv) => {
51909
+ try {
51910
+ const saved = await saveModeState("review", {
51911
+ setBy: "shortcut",
51912
+ reason: "ax review command"
51913
+ });
51914
+ if (!saved) {
51915
+ logger.warn("Failed to persist mode state, continuing anyway");
51916
+ }
51917
+ if (!argv.quiet) {
51918
+ console.log(chalk5.cyan.bold("\n\u{1F50D} Review Mode Activated\n"));
51919
+ console.log(chalk5.gray("Code review mode - analyzing for quality, security, and best practices"));
51920
+ console.log(chalk5.gray("Use `ax mode default` to exit review mode\n"));
51921
+ }
51922
+ if (argv.path) {
51923
+ const task = `Review the code at ${argv.path} for quality, security, and best practices`;
51924
+ const runArgs = ["run", argv.agent || "quality", task];
51925
+ if (argv.provider) runArgs.push("--provider", argv.provider);
51926
+ if (argv.verbose) runArgs.push("--verbose");
51927
+ if (argv.quiet) runArgs.push("--quiet");
51928
+ await runAxCommand(runArgs);
51929
+ } else {
51930
+ console.log(chalk5.gray('No path specified. Use `ax run quality "Review <path>"` to review code.'));
51931
+ }
51932
+ logger.info("Review shortcut executed", { path: argv.path, agent: argv.agent });
51933
+ } catch (error) {
51934
+ const err = error instanceof Error ? error : new Error(String(error));
51935
+ console.error(chalk5.red.bold(`
51936
+ \u274C Error: ${err.message}
51937
+ `));
51938
+ process.exit(1);
51939
+ }
51940
+ }
51941
+ };
51942
+
51408
51943
  // src/cli/index.ts
51409
51944
  installExitHandlers();
51410
51945
  var VERSION2 = getVersion();
@@ -51427,7 +51962,7 @@ globalTracker.mark("cli_start");
51427
51962
  type: "string",
51428
51963
  description: "Path to custom config file",
51429
51964
  global: true
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();
51965
+ }).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).command(planCommand).command(iterateCommand).command(reviewCommand).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();
51431
51966
  globalTracker.mark("yargs_parse_end");
51432
51967
  globalTracker.measure("yargs_parsing", "yargs_parse_start", "yargs_parse_end");
51433
51968
  globalTracker.mark("options_setup_start");