oh-my-opencode 3.0.0-beta.6 → 3.0.0-beta.7

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
@@ -3,7 +3,6 @@ var __create = Object.create;
3
3
  var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
7
  var __toESM = (mod, isNodeMode, target) => {
9
8
  target = mod != null ? __create(__getProtoOf(mod)) : {};
@@ -16,20 +15,6 @@ var __toESM = (mod, isNodeMode, target) => {
16
15
  });
17
16
  return to;
18
17
  };
19
- var __moduleCache = /* @__PURE__ */ new WeakMap;
20
- var __toCommonJS = (from) => {
21
- var entry = __moduleCache.get(from), desc;
22
- if (entry)
23
- return entry;
24
- entry = __defProp({}, "__esModule", { value: true });
25
- if (from && typeof from === "object" || typeof from === "function")
26
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
27
- get: () => from[key],
28
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
29
- }));
30
- __moduleCache.set(from, entry);
31
- return entry;
32
- };
33
18
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
19
  var __export = (target, all) => {
35
20
  for (var name in all)
@@ -4179,259 +4164,6 @@ var init_jsonc_parser = __esm(() => {
4179
4164
  init_main();
4180
4165
  });
4181
4166
 
4182
- // src/tools/sisyphus-task/constants.ts
4183
- var exports_constants = {};
4184
- __export(exports_constants, {
4185
- WRITING_CATEGORY_PROMPT_APPEND: () => WRITING_CATEGORY_PROMPT_APPEND,
4186
- VISUAL_CATEGORY_PROMPT_APPEND: () => VISUAL_CATEGORY_PROMPT_APPEND,
4187
- STRATEGIC_CATEGORY_PROMPT_APPEND: () => STRATEGIC_CATEGORY_PROMPT_APPEND,
4188
- SISYPHUS_TASK_DESCRIPTION: () => SISYPHUS_TASK_DESCRIPTION,
4189
- QUICK_CATEGORY_PROMPT_APPEND: () => QUICK_CATEGORY_PROMPT_APPEND,
4190
- MOST_CAPABLE_CATEGORY_PROMPT_APPEND: () => MOST_CAPABLE_CATEGORY_PROMPT_APPEND,
4191
- GENERAL_CATEGORY_PROMPT_APPEND: () => GENERAL_CATEGORY_PROMPT_APPEND,
4192
- DEFAULT_CATEGORIES: () => DEFAULT_CATEGORIES,
4193
- CATEGORY_PROMPT_APPENDS: () => CATEGORY_PROMPT_APPENDS,
4194
- CATEGORY_DESCRIPTIONS: () => CATEGORY_DESCRIPTIONS,
4195
- ARTISTRY_CATEGORY_PROMPT_APPEND: () => ARTISTRY_CATEGORY_PROMPT_APPEND
4196
- });
4197
- var VISUAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
4198
- You are working on VISUAL/UI tasks.
4199
-
4200
- Design-first mindset:
4201
- - Bold aesthetic choices over safe defaults
4202
- - Unexpected layouts, asymmetry, grid-breaking elements
4203
- - Distinctive typography (avoid: Arial, Inter, Roboto, Space Grotesk)
4204
- - Cohesive color palettes with sharp accents
4205
- - High-impact animations with staggered reveals
4206
- - Atmosphere: gradient meshes, noise textures, layered transparencies
4207
-
4208
- AVOID: Generic fonts, purple gradients on white, predictable layouts, cookie-cutter patterns.
4209
- </Category_Context>`, STRATEGIC_CATEGORY_PROMPT_APPEND = `<Category_Context>
4210
- You are working on BUSINESS LOGIC / ARCHITECTURE tasks.
4211
-
4212
- Strategic advisor mindset:
4213
- - Bias toward simplicity: least complex solution that fulfills requirements
4214
- - Leverage existing code/patterns over new components
4215
- - Prioritize developer experience and maintainability
4216
- - One clear recommendation with effort estimate (Quick/Short/Medium/Large)
4217
- - Signal when advanced approach warranted
4218
-
4219
- Response format:
4220
- - Bottom line (2-3 sentences)
4221
- - Action plan (numbered steps)
4222
- - Risks and mitigations (if relevant)
4223
- </Category_Context>`, ARTISTRY_CATEGORY_PROMPT_APPEND = `<Category_Context>
4224
- You are working on HIGHLY CREATIVE / ARTISTIC tasks.
4225
-
4226
- Artistic genius mindset:
4227
- - Push far beyond conventional boundaries
4228
- - Explore radical, unconventional directions
4229
- - Surprise and delight: unexpected twists, novel combinations
4230
- - Rich detail and vivid expression
4231
- - Break patterns deliberately when it serves the creative vision
4232
-
4233
- Approach:
4234
- - Generate diverse, bold options first
4235
- - Embrace ambiguity and wild experimentation
4236
- - Balance novelty with coherence
4237
- - This is for tasks requiring exceptional creativity
4238
- </Category_Context>`, QUICK_CATEGORY_PROMPT_APPEND = `<Category_Context>
4239
- You are working on SMALL / QUICK tasks.
4240
-
4241
- Efficient execution mindset:
4242
- - Fast, focused, minimal overhead
4243
- - Get to the point immediately
4244
- - No over-engineering
4245
- - Simple solutions for simple problems
4246
-
4247
- Approach:
4248
- - Minimal viable implementation
4249
- - Skip unnecessary abstractions
4250
- - Direct and concise
4251
- </Category_Context>
4252
-
4253
- <Caller_Warning>
4254
- \u26A0\uFE0F THIS CATEGORY USES A LESS CAPABLE MODEL (claude-haiku-4-5).
4255
-
4256
- The model executing this task has LIMITED reasoning capacity. Your prompt MUST be:
4257
-
4258
- **EXHAUSTIVELY EXPLICIT** - Leave NOTHING to interpretation:
4259
- 1. MUST DO: List every required action as atomic, numbered steps
4260
- 2. MUST NOT DO: Explicitly forbid likely mistakes and deviations
4261
- 3. EXPECTED OUTPUT: Describe exact success criteria with concrete examples
4262
-
4263
- **WHY THIS MATTERS:**
4264
- - Less capable models WILL deviate without explicit guardrails
4265
- - Vague instructions \u2192 unpredictable results
4266
- - Implicit expectations \u2192 missed requirements
4267
-
4268
- **PROMPT STRUCTURE (MANDATORY):**
4269
- \`\`\`
4270
- TASK: [One-sentence goal]
4271
-
4272
- MUST DO:
4273
- 1. [Specific action with exact details]
4274
- 2. [Another specific action]
4275
- ...
4276
-
4277
- MUST NOT DO:
4278
- - [Forbidden action + why]
4279
- - [Another forbidden action]
4280
- ...
4281
-
4282
- EXPECTED OUTPUT:
4283
- - [Exact deliverable description]
4284
- - [Success criteria / verification method]
4285
- \`\`\`
4286
-
4287
- If your prompt lacks this structure, REWRITE IT before delegating.
4288
- </Caller_Warning>`, MOST_CAPABLE_CATEGORY_PROMPT_APPEND = `<Category_Context>
4289
- You are working on COMPLEX / MOST-CAPABLE tasks.
4290
-
4291
- Maximum capability mindset:
4292
- - Bring full reasoning power to bear
4293
- - Consider all edge cases and implications
4294
- - Deep analysis before action
4295
- - Quality over speed
4296
-
4297
- Approach:
4298
- - Thorough understanding first
4299
- - Comprehensive solution design
4300
- - Meticulous execution
4301
- - This is for the most challenging problems
4302
- </Category_Context>`, WRITING_CATEGORY_PROMPT_APPEND = `<Category_Context>
4303
- You are working on WRITING / PROSE tasks.
4304
-
4305
- Wordsmith mindset:
4306
- - Clear, flowing prose
4307
- - Appropriate tone and voice
4308
- - Engaging and readable
4309
- - Proper structure and organization
4310
-
4311
- Approach:
4312
- - Understand the audience
4313
- - Draft with care
4314
- - Polish for clarity and impact
4315
- - Documentation, READMEs, articles, technical writing
4316
- </Category_Context>`, GENERAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
4317
- You are working on GENERAL tasks.
4318
-
4319
- Balanced execution mindset:
4320
- - Practical, straightforward approach
4321
- - Good enough is good enough
4322
- - Focus on getting things done
4323
-
4324
- Approach:
4325
- - Standard best practices
4326
- - Reasonable trade-offs
4327
- - Efficient completion
4328
- </Category_Context>
4329
-
4330
- <Caller_Warning>
4331
- \u26A0\uFE0F THIS CATEGORY USES A MID-TIER MODEL (claude-sonnet-4-5).
4332
-
4333
- While capable, this model benefits significantly from EXPLICIT instructions.
4334
-
4335
- **PROVIDE CLEAR STRUCTURE:**
4336
- 1. MUST DO: Enumerate required actions explicitly - don't assume inference
4337
- 2. MUST NOT DO: State forbidden actions to prevent scope creep or wrong approaches
4338
- 3. EXPECTED OUTPUT: Define concrete success criteria and deliverables
4339
-
4340
- **COMMON PITFALLS WITHOUT EXPLICIT INSTRUCTIONS:**
4341
- - Model may take shortcuts that miss edge cases
4342
- - Implicit requirements get overlooked
4343
- - Output format may not match expectations
4344
- - Scope may expand beyond intended boundaries
4345
-
4346
- **RECOMMENDED PROMPT PATTERN:**
4347
- \`\`\`
4348
- TASK: [Clear, single-purpose goal]
4349
-
4350
- CONTEXT: [Relevant background the model needs]
4351
-
4352
- MUST DO:
4353
- - [Explicit requirement 1]
4354
- - [Explicit requirement 2]
4355
-
4356
- MUST NOT DO:
4357
- - [Boundary/constraint 1]
4358
- - [Boundary/constraint 2]
4359
-
4360
- EXPECTED OUTPUT:
4361
- - [What success looks like]
4362
- - [How to verify completion]
4363
- \`\`\`
4364
-
4365
- The more explicit your prompt, the better the results.
4366
- </Caller_Warning>`, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, BUILTIN_CATEGORIES, SISYPHUS_TASK_DESCRIPTION;
4367
- var init_constants = __esm(() => {
4368
- DEFAULT_CATEGORIES = {
4369
- "visual-engineering": {
4370
- model: "google/gemini-3-pro-preview",
4371
- temperature: 0.7
4372
- },
4373
- ultrabrain: {
4374
- model: "openai/gpt-5.2",
4375
- temperature: 0.1
4376
- },
4377
- artistry: {
4378
- model: "google/gemini-3-pro-preview",
4379
- temperature: 0.9
4380
- },
4381
- quick: {
4382
- model: "anthropic/claude-haiku-4-5",
4383
- temperature: 0.3
4384
- },
4385
- "most-capable": {
4386
- model: "anthropic/claude-opus-4-5",
4387
- temperature: 0.1
4388
- },
4389
- writing: {
4390
- model: "google/gemini-3-flash-preview",
4391
- temperature: 0.5
4392
- },
4393
- general: {
4394
- model: "anthropic/claude-sonnet-4-5",
4395
- temperature: 0.3
4396
- }
4397
- };
4398
- CATEGORY_PROMPT_APPENDS = {
4399
- "visual-engineering": VISUAL_CATEGORY_PROMPT_APPEND,
4400
- ultrabrain: STRATEGIC_CATEGORY_PROMPT_APPEND,
4401
- artistry: ARTISTRY_CATEGORY_PROMPT_APPEND,
4402
- quick: QUICK_CATEGORY_PROMPT_APPEND,
4403
- "most-capable": MOST_CAPABLE_CATEGORY_PROMPT_APPEND,
4404
- writing: WRITING_CATEGORY_PROMPT_APPEND,
4405
- general: GENERAL_CATEGORY_PROMPT_APPEND
4406
- };
4407
- CATEGORY_DESCRIPTIONS = {
4408
- "visual-engineering": "Frontend, UI/UX, design, styling, animation",
4409
- ultrabrain: "Strict architecture design, very complex business logic",
4410
- artistry: "Highly creative/artistic tasks, novel ideas",
4411
- quick: "Cheap & fast - small tasks with minimal overhead, budget-friendly",
4412
- "most-capable": "Complex tasks requiring maximum capability",
4413
- writing: "Documentation, prose, technical writing",
4414
- general: "General purpose tasks"
4415
- };
4416
- BUILTIN_CATEGORIES = Object.keys(DEFAULT_CATEGORIES).join(", ");
4417
- SISYPHUS_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection.
4418
-
4419
- MUTUALLY EXCLUSIVE: Provide EITHER category OR agent, not both (unless resuming).
4420
-
4421
- - category: Use predefined category (${BUILTIN_CATEGORIES}) \u2192 Spawns Sisyphus-Junior with category config
4422
- - agent: Use specific agent directly (e.g., "oracle", "explore")
4423
- - background: true=async (returns task_id), false=sync (waits for result). Default: false. Use background=true ONLY for parallel exploration with 5+ independent queries.
4424
- - resume: Session ID to resume (from previous task output). Continues agent with FULL CONTEXT PRESERVED - saves tokens, maintains continuity.
4425
- - skills: Array of skill names to prepend to prompt (e.g., ["playwright", "frontend-ui-ux"]). Skills will be resolved and their content prepended with a separator. Empty array = no prepending.
4426
-
4427
- **WHEN TO USE resume:**
4428
- - Task failed/incomplete \u2192 resume with "fix: [specific issue]"
4429
- - Need follow-up on previous result \u2192 resume with additional question
4430
- - Multi-turn conversation with same agent \u2192 always resume instead of new task
4431
-
4432
- Prompts MUST be in English.`;
4433
- });
4434
-
4435
4167
  // src/shared/migration.ts
4436
4168
  import * as fs4 from "fs";
4437
4169
  function migrateAgentNames(agents) {
@@ -4458,35 +4190,6 @@ function migrateHookNames(hooks) {
4458
4190
  }
4459
4191
  return { migrated, changed };
4460
4192
  }
4461
- function migrateAgentConfigToCategory(config) {
4462
- const { model, ...rest } = config;
4463
- if (typeof model !== "string") {
4464
- return { migrated: config, changed: false };
4465
- }
4466
- const category = MODEL_TO_CATEGORY_MAP[model];
4467
- if (!category) {
4468
- return { migrated: config, changed: false };
4469
- }
4470
- return {
4471
- migrated: { category, ...rest },
4472
- changed: true
4473
- };
4474
- }
4475
- function shouldDeleteAgentConfig(config, category) {
4476
- const { DEFAULT_CATEGORIES: DEFAULT_CATEGORIES2 } = (init_constants(), __toCommonJS(exports_constants));
4477
- const defaults = DEFAULT_CATEGORIES2[category];
4478
- if (!defaults)
4479
- return false;
4480
- const keys = Object.keys(config).filter((k) => k !== "category");
4481
- if (keys.length === 0)
4482
- return true;
4483
- for (const key of keys) {
4484
- if (config[key] !== defaults[key]) {
4485
- return false;
4486
- }
4487
- }
4488
- return true;
4489
- }
4490
4193
  function migrateConfigFile(configPath, rawConfig) {
4491
4194
  let needsWrite = false;
4492
4195
  if (rawConfig.agents && typeof rawConfig.agents === "object") {
@@ -4496,21 +4199,6 @@ function migrateConfigFile(configPath, rawConfig) {
4496
4199
  needsWrite = true;
4497
4200
  }
4498
4201
  }
4499
- if (rawConfig.agents && typeof rawConfig.agents === "object") {
4500
- const agents = rawConfig.agents;
4501
- for (const [name, config] of Object.entries(agents)) {
4502
- const { migrated, changed } = migrateAgentConfigToCategory(config);
4503
- if (changed) {
4504
- const category = migrated.category;
4505
- if (shouldDeleteAgentConfig(migrated, category)) {
4506
- delete agents[name];
4507
- } else {
4508
- agents[name] = migrated;
4509
- }
4510
- needsWrite = true;
4511
- }
4512
- }
4513
- }
4514
4202
  if (rawConfig.omo_agent) {
4515
4203
  rawConfig.sisyphus_agent = rawConfig.omo_agent;
4516
4204
  delete rawConfig.omo_agent;
@@ -4537,7 +4225,7 @@ function migrateConfigFile(configPath, rawConfig) {
4537
4225
  }
4538
4226
  return needsWrite;
4539
4227
  }
4540
- var AGENT_NAME_MAP, HOOK_NAME_MAP, MODEL_TO_CATEGORY_MAP;
4228
+ var AGENT_NAME_MAP, BUILTIN_AGENT_NAMES, HOOK_NAME_MAP;
4541
4229
  var init_migration = __esm(() => {
4542
4230
  init_logger();
4543
4231
  AGENT_NAME_MAP = {
@@ -4559,16 +4247,23 @@ var init_migration = __esm(() => {
4559
4247
  "document-writer": "document-writer",
4560
4248
  "multimodal-looker": "multimodal-looker"
4561
4249
  };
4250
+ BUILTIN_AGENT_NAMES = new Set([
4251
+ "Sisyphus",
4252
+ "oracle",
4253
+ "librarian",
4254
+ "explore",
4255
+ "frontend-ui-ux-engineer",
4256
+ "document-writer",
4257
+ "multimodal-looker",
4258
+ "Metis (Plan Consultant)",
4259
+ "Momus (Plan Reviewer)",
4260
+ "Prometheus (Planner)",
4261
+ "orchestrator-sisyphus",
4262
+ "build"
4263
+ ]);
4562
4264
  HOOK_NAME_MAP = {
4563
4265
  "anthropic-auto-compact": "anthropic-context-window-limit-recovery"
4564
4266
  };
4565
- MODEL_TO_CATEGORY_MAP = {
4566
- "google/gemini-3-pro-preview": "visual-engineering",
4567
- "openai/gpt-5.2": "ultrabrain",
4568
- "anthropic/claude-haiku-4-5": "quick",
4569
- "anthropic/claude-opus-4-5": "most-capable",
4570
- "anthropic/claude-sonnet-4-5": "general"
4571
- };
4572
4267
  });
4573
4268
 
4574
4269
  // src/shared/opencode-config-dir.ts
@@ -6434,7 +6129,7 @@ function getWindowsAppdataDir2() {
6434
6129
  return process.env.APPDATA ?? path5.join(os5.homedir(), "AppData", "Roaming");
6435
6130
  }
6436
6131
  var PACKAGE_NAME = "oh-my-opencode", NPM_REGISTRY_URL, NPM_FETCH_TIMEOUT = 5000, CACHE_DIR, VERSION_FILE, INSTALLED_PACKAGE_JSON, USER_CONFIG_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC;
6437
- var init_constants2 = __esm(() => {
6132
+ var init_constants = __esm(() => {
6438
6133
  NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
6439
6134
  CACHE_DIR = getCacheDir2();
6440
6135
  VERSION_FILE = path5.join(CACHE_DIR, "version");
@@ -6644,7 +6339,7 @@ async function getLatestVersion(channel = "latest") {
6644
6339
  }
6645
6340
  }
6646
6341
  var init_checker = __esm(() => {
6647
- init_constants2();
6342
+ init_constants();
6648
6343
  init_logger();
6649
6344
  });
6650
6345
 
@@ -6713,7 +6408,7 @@ function invalidatePackage(packageName = PACKAGE_NAME) {
6713
6408
  }
6714
6409
  }
6715
6410
  var init_cache = __esm(() => {
6716
- init_constants2();
6411
+ init_constants();
6717
6412
  init_logger();
6718
6413
  });
6719
6414
 
@@ -6971,7 +6666,7 @@ var SISYPHUS_SPINNER;
6971
6666
  var init_auto_update_checker = __esm(() => {
6972
6667
  init_checker();
6973
6668
  init_cache();
6974
- init_constants2();
6669
+ init_constants();
6975
6670
  init_logger();
6976
6671
  init_config_errors();
6977
6672
  init_config_manager();
@@ -6980,6 +6675,245 @@ var init_auto_update_checker = __esm(() => {
6980
6675
  SISYPHUS_SPINNER = ["\xB7", "\u2022", "\u25CF", "\u25CB", "\u25CC", "\u25E6", " "];
6981
6676
  });
6982
6677
 
6678
+ // src/tools/sisyphus-task/constants.ts
6679
+ var VISUAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
6680
+ You are working on VISUAL/UI tasks.
6681
+
6682
+ Design-first mindset:
6683
+ - Bold aesthetic choices over safe defaults
6684
+ - Unexpected layouts, asymmetry, grid-breaking elements
6685
+ - Distinctive typography (avoid: Arial, Inter, Roboto, Space Grotesk)
6686
+ - Cohesive color palettes with sharp accents
6687
+ - High-impact animations with staggered reveals
6688
+ - Atmosphere: gradient meshes, noise textures, layered transparencies
6689
+
6690
+ AVOID: Generic fonts, purple gradients on white, predictable layouts, cookie-cutter patterns.
6691
+ </Category_Context>`, STRATEGIC_CATEGORY_PROMPT_APPEND = `<Category_Context>
6692
+ You are working on BUSINESS LOGIC / ARCHITECTURE tasks.
6693
+
6694
+ Strategic advisor mindset:
6695
+ - Bias toward simplicity: least complex solution that fulfills requirements
6696
+ - Leverage existing code/patterns over new components
6697
+ - Prioritize developer experience and maintainability
6698
+ - One clear recommendation with effort estimate (Quick/Short/Medium/Large)
6699
+ - Signal when advanced approach warranted
6700
+
6701
+ Response format:
6702
+ - Bottom line (2-3 sentences)
6703
+ - Action plan (numbered steps)
6704
+ - Risks and mitigations (if relevant)
6705
+ </Category_Context>`, ARTISTRY_CATEGORY_PROMPT_APPEND = `<Category_Context>
6706
+ You are working on HIGHLY CREATIVE / ARTISTIC tasks.
6707
+
6708
+ Artistic genius mindset:
6709
+ - Push far beyond conventional boundaries
6710
+ - Explore radical, unconventional directions
6711
+ - Surprise and delight: unexpected twists, novel combinations
6712
+ - Rich detail and vivid expression
6713
+ - Break patterns deliberately when it serves the creative vision
6714
+
6715
+ Approach:
6716
+ - Generate diverse, bold options first
6717
+ - Embrace ambiguity and wild experimentation
6718
+ - Balance novelty with coherence
6719
+ - This is for tasks requiring exceptional creativity
6720
+ </Category_Context>`, QUICK_CATEGORY_PROMPT_APPEND = `<Category_Context>
6721
+ You are working on SMALL / QUICK tasks.
6722
+
6723
+ Efficient execution mindset:
6724
+ - Fast, focused, minimal overhead
6725
+ - Get to the point immediately
6726
+ - No over-engineering
6727
+ - Simple solutions for simple problems
6728
+
6729
+ Approach:
6730
+ - Minimal viable implementation
6731
+ - Skip unnecessary abstractions
6732
+ - Direct and concise
6733
+ </Category_Context>
6734
+
6735
+ <Caller_Warning>
6736
+ \u26A0\uFE0F THIS CATEGORY USES A LESS CAPABLE MODEL (claude-haiku-4-5).
6737
+
6738
+ The model executing this task has LIMITED reasoning capacity. Your prompt MUST be:
6739
+
6740
+ **EXHAUSTIVELY EXPLICIT** - Leave NOTHING to interpretation:
6741
+ 1. MUST DO: List every required action as atomic, numbered steps
6742
+ 2. MUST NOT DO: Explicitly forbid likely mistakes and deviations
6743
+ 3. EXPECTED OUTPUT: Describe exact success criteria with concrete examples
6744
+
6745
+ **WHY THIS MATTERS:**
6746
+ - Less capable models WILL deviate without explicit guardrails
6747
+ - Vague instructions \u2192 unpredictable results
6748
+ - Implicit expectations \u2192 missed requirements
6749
+
6750
+ **PROMPT STRUCTURE (MANDATORY):**
6751
+ \`\`\`
6752
+ TASK: [One-sentence goal]
6753
+
6754
+ MUST DO:
6755
+ 1. [Specific action with exact details]
6756
+ 2. [Another specific action]
6757
+ ...
6758
+
6759
+ MUST NOT DO:
6760
+ - [Forbidden action + why]
6761
+ - [Another forbidden action]
6762
+ ...
6763
+
6764
+ EXPECTED OUTPUT:
6765
+ - [Exact deliverable description]
6766
+ - [Success criteria / verification method]
6767
+ \`\`\`
6768
+
6769
+ If your prompt lacks this structure, REWRITE IT before delegating.
6770
+ </Caller_Warning>`, MOST_CAPABLE_CATEGORY_PROMPT_APPEND = `<Category_Context>
6771
+ You are working on COMPLEX / MOST-CAPABLE tasks.
6772
+
6773
+ Maximum capability mindset:
6774
+ - Bring full reasoning power to bear
6775
+ - Consider all edge cases and implications
6776
+ - Deep analysis before action
6777
+ - Quality over speed
6778
+
6779
+ Approach:
6780
+ - Thorough understanding first
6781
+ - Comprehensive solution design
6782
+ - Meticulous execution
6783
+ - This is for the most challenging problems
6784
+ </Category_Context>`, WRITING_CATEGORY_PROMPT_APPEND = `<Category_Context>
6785
+ You are working on WRITING / PROSE tasks.
6786
+
6787
+ Wordsmith mindset:
6788
+ - Clear, flowing prose
6789
+ - Appropriate tone and voice
6790
+ - Engaging and readable
6791
+ - Proper structure and organization
6792
+
6793
+ Approach:
6794
+ - Understand the audience
6795
+ - Draft with care
6796
+ - Polish for clarity and impact
6797
+ - Documentation, READMEs, articles, technical writing
6798
+ </Category_Context>`, GENERAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
6799
+ You are working on GENERAL tasks.
6800
+
6801
+ Balanced execution mindset:
6802
+ - Practical, straightforward approach
6803
+ - Good enough is good enough
6804
+ - Focus on getting things done
6805
+
6806
+ Approach:
6807
+ - Standard best practices
6808
+ - Reasonable trade-offs
6809
+ - Efficient completion
6810
+ </Category_Context>
6811
+
6812
+ <Caller_Warning>
6813
+ \u26A0\uFE0F THIS CATEGORY USES A MID-TIER MODEL (claude-sonnet-4-5).
6814
+
6815
+ While capable, this model benefits significantly from EXPLICIT instructions.
6816
+
6817
+ **PROVIDE CLEAR STRUCTURE:**
6818
+ 1. MUST DO: Enumerate required actions explicitly - don't assume inference
6819
+ 2. MUST NOT DO: State forbidden actions to prevent scope creep or wrong approaches
6820
+ 3. EXPECTED OUTPUT: Define concrete success criteria and deliverables
6821
+
6822
+ **COMMON PITFALLS WITHOUT EXPLICIT INSTRUCTIONS:**
6823
+ - Model may take shortcuts that miss edge cases
6824
+ - Implicit requirements get overlooked
6825
+ - Output format may not match expectations
6826
+ - Scope may expand beyond intended boundaries
6827
+
6828
+ **RECOMMENDED PROMPT PATTERN:**
6829
+ \`\`\`
6830
+ TASK: [Clear, single-purpose goal]
6831
+
6832
+ CONTEXT: [Relevant background the model needs]
6833
+
6834
+ MUST DO:
6835
+ - [Explicit requirement 1]
6836
+ - [Explicit requirement 2]
6837
+
6838
+ MUST NOT DO:
6839
+ - [Boundary/constraint 1]
6840
+ - [Boundary/constraint 2]
6841
+
6842
+ EXPECTED OUTPUT:
6843
+ - [What success looks like]
6844
+ - [How to verify completion]
6845
+ \`\`\`
6846
+
6847
+ The more explicit your prompt, the better the results.
6848
+ </Caller_Warning>`, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, BUILTIN_CATEGORIES, SISYPHUS_TASK_DESCRIPTION;
6849
+ var init_constants2 = __esm(() => {
6850
+ DEFAULT_CATEGORIES = {
6851
+ "visual-engineering": {
6852
+ model: "google/gemini-3-pro-preview",
6853
+ temperature: 0.7
6854
+ },
6855
+ ultrabrain: {
6856
+ model: "openai/gpt-5.2",
6857
+ temperature: 0.1
6858
+ },
6859
+ artistry: {
6860
+ model: "google/gemini-3-pro-preview",
6861
+ temperature: 0.9
6862
+ },
6863
+ quick: {
6864
+ model: "anthropic/claude-haiku-4-5",
6865
+ temperature: 0.3
6866
+ },
6867
+ "most-capable": {
6868
+ model: "anthropic/claude-opus-4-5",
6869
+ temperature: 0.1
6870
+ },
6871
+ writing: {
6872
+ model: "google/gemini-3-flash-preview",
6873
+ temperature: 0.5
6874
+ },
6875
+ general: {
6876
+ model: "anthropic/claude-sonnet-4-5",
6877
+ temperature: 0.3
6878
+ }
6879
+ };
6880
+ CATEGORY_PROMPT_APPENDS = {
6881
+ "visual-engineering": VISUAL_CATEGORY_PROMPT_APPEND,
6882
+ ultrabrain: STRATEGIC_CATEGORY_PROMPT_APPEND,
6883
+ artistry: ARTISTRY_CATEGORY_PROMPT_APPEND,
6884
+ quick: QUICK_CATEGORY_PROMPT_APPEND,
6885
+ "most-capable": MOST_CAPABLE_CATEGORY_PROMPT_APPEND,
6886
+ writing: WRITING_CATEGORY_PROMPT_APPEND,
6887
+ general: GENERAL_CATEGORY_PROMPT_APPEND
6888
+ };
6889
+ CATEGORY_DESCRIPTIONS = {
6890
+ "visual-engineering": "Frontend, UI/UX, design, styling, animation",
6891
+ ultrabrain: "Strict architecture design, very complex business logic",
6892
+ artistry: "Highly creative/artistic tasks, novel ideas",
6893
+ quick: "Cheap & fast - small tasks with minimal overhead, budget-friendly",
6894
+ "most-capable": "Complex tasks requiring maximum capability",
6895
+ writing: "Documentation, prose, technical writing",
6896
+ general: "General purpose tasks"
6897
+ };
6898
+ BUILTIN_CATEGORIES = Object.keys(DEFAULT_CATEGORIES).join(", ");
6899
+ SISYPHUS_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection.
6900
+
6901
+ MUTUALLY EXCLUSIVE: Provide EITHER category OR agent, not both (unless resuming).
6902
+
6903
+ - category: Use predefined category (${BUILTIN_CATEGORIES}) \u2192 Spawns Sisyphus-Junior with category config
6904
+ - agent: Use specific agent directly (e.g., "oracle", "explore")
6905
+ - background: true=async (returns task_id), false=sync (waits for result). Default: false. Use background=true ONLY for parallel exploration with 5+ independent queries.
6906
+ - resume: Session ID to resume (from previous task output). Continues agent with FULL CONTEXT PRESERVED - saves tokens, maintains continuity.
6907
+ - skills: Array of skill names to prepend to prompt (e.g., ["playwright", "frontend-ui-ux"]). Skills will be resolved and their content prepended with a separator. Empty array = no prepending.
6908
+
6909
+ **WHEN TO USE resume:**
6910
+ - Task failed/incomplete \u2192 resume with "fix: [specific issue]"
6911
+ - Need follow-up on previous result \u2192 resume with additional question
6912
+ - Multi-turn conversation with same agent \u2192 always resume instead of new task
6913
+
6914
+ Prompts MUST be in English.`;
6915
+ });
6916
+
6983
6917
  // node_modules/ajv/dist/compile/codegen/code.js
6984
6918
  var require_code = __commonJS((exports) => {
6985
6919
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -15765,8 +15699,7 @@ var TRUNCATABLE_TOOLS = [
15765
15699
  "Glob",
15766
15700
  "safe_glob",
15767
15701
  "lsp_find_references",
15768
- "lsp_document_symbols",
15769
- "lsp_workspace_symbols",
15702
+ "lsp_symbols",
15770
15703
  "lsp_diagnostics",
15771
15704
  "ast_grep_search",
15772
15705
  "interactive_bash",
@@ -16853,7 +16786,6 @@ var DEFAULT_PROTECTED_TOOLS = new Set([
16853
16786
  "todowrite",
16854
16787
  "todoread",
16855
16788
  "lsp_rename",
16856
- "lsp_code_action_resolve",
16857
16789
  "session_read",
16858
16790
  "session_write",
16859
16791
  "session_search"
@@ -17256,8 +17188,7 @@ async function executeCompact(sessionID, msg, autoCompactState, client, director
17256
17188
  "task",
17257
17189
  "todowrite",
17258
17190
  "todoread",
17259
- "lsp_rename",
17260
- "lsp_code_action_resolve"
17191
+ "lsp_rename"
17261
17192
  ]
17262
17193
  };
17263
17194
  try {
@@ -20576,7 +20507,8 @@ function createThinkingBlockValidatorHook() {
20576
20507
  }
20577
20508
  // src/hooks/ralph-loop/index.ts
20578
20509
  init_logger();
20579
- import { existsSync as existsSync34, readFileSync as readFileSync22 } from "fs";
20510
+ import { existsSync as existsSync34, readFileSync as readFileSync22, readdirSync as readdirSync11 } from "fs";
20511
+ import { join as join43 } from "path";
20580
20512
 
20581
20513
  // src/hooks/ralph-loop/storage.ts
20582
20514
  init_frontmatter();
@@ -20675,6 +20607,19 @@ function incrementIteration(directory, customPath) {
20675
20607
  }
20676
20608
 
20677
20609
  // src/hooks/ralph-loop/index.ts
20610
+ function getMessageDir9(sessionID) {
20611
+ if (!existsSync34(MESSAGE_STORAGE))
20612
+ return null;
20613
+ const directPath = join43(MESSAGE_STORAGE, sessionID);
20614
+ if (existsSync34(directPath))
20615
+ return directPath;
20616
+ for (const dir of readdirSync11(MESSAGE_STORAGE)) {
20617
+ const sessionPath = join43(MESSAGE_STORAGE, dir, sessionID);
20618
+ if (existsSync34(sessionPath))
20619
+ return sessionPath;
20620
+ }
20621
+ return null;
20622
+ }
20678
20623
  var CONTINUATION_PROMPT2 = `[RALPH LOOP - ITERATION {{ITERATION}}/{{MAX}}]
20679
20624
 
20680
20625
  Your previous attempt did not output the completion promise. Continue working on the task.
@@ -20874,9 +20819,15 @@ function createRalphLoopHook(ctx, options) {
20874
20819
  }
20875
20820
  }).catch(() => {});
20876
20821
  try {
20822
+ const messageDir = getMessageDir9(sessionID);
20823
+ const currentMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
20824
+ const agent = currentMessage?.agent;
20825
+ const model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
20877
20826
  await ctx.client.session.prompt({
20878
20827
  path: { id: sessionID },
20879
20828
  body: {
20829
+ ...agent !== undefined ? { agent } : {},
20830
+ ...model !== undefined ? { model } : {},
20880
20831
  parts: [{ type: "text", text: continuationPrompt }]
20881
20832
  },
20882
20833
  query: { directory: ctx.directory }
@@ -20984,8 +20935,8 @@ function extractPromptText3(parts) {
20984
20935
  // src/hooks/auto-slash-command/executor.ts
20985
20936
  init_shared();
20986
20937
  init_file_utils();
20987
- import { existsSync as existsSync36, readdirSync as readdirSync11, readFileSync as readFileSync24 } from "fs";
20988
- import { join as join44, basename as basename2, dirname as dirname8 } from "path";
20938
+ import { existsSync as existsSync36, readdirSync as readdirSync12, readFileSync as readFileSync24 } from "fs";
20939
+ import { join as join45, basename as basename2, dirname as dirname8 } from "path";
20989
20940
  import { homedir as homedir14 } from "os";
20990
20941
  // src/features/opencode-skill-loader/loader.ts
20991
20942
  init_js_yaml();
@@ -20993,7 +20944,7 @@ init_frontmatter();
20993
20944
  init_file_utils();
20994
20945
  init_shared();
20995
20946
  import { promises as fs11 } from "fs";
20996
- import { join as join43, basename } from "path";
20947
+ import { join as join44, basename } from "path";
20997
20948
  import { homedir as homedir12 } from "os";
20998
20949
  function parseSkillMcpConfigFromFrontmatter(content) {
20999
20950
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -21010,7 +20961,7 @@ function parseSkillMcpConfigFromFrontmatter(content) {
21010
20961
  return;
21011
20962
  }
21012
20963
  async function loadMcpJsonFromDir(skillDir) {
21013
- const mcpJsonPath = join43(skillDir, "mcp.json");
20964
+ const mcpJsonPath = join44(skillDir, "mcp.json");
21014
20965
  try {
21015
20966
  const content = await fs11.readFile(mcpJsonPath, "utf-8");
21016
20967
  const parsed = JSON.parse(content);
@@ -21091,11 +21042,11 @@ async function loadSkillsFromDir(skillsDir, scope) {
21091
21042
  for (const entry of entries) {
21092
21043
  if (entry.name.startsWith("."))
21093
21044
  continue;
21094
- const entryPath = join43(skillsDir, entry.name);
21045
+ const entryPath = join44(skillsDir, entry.name);
21095
21046
  if (entry.isDirectory() || entry.isSymbolicLink()) {
21096
21047
  const resolvedPath = await resolveSymlinkAsync(entryPath);
21097
21048
  const dirName = entry.name;
21098
- const skillMdPath = join43(resolvedPath, "SKILL.md");
21049
+ const skillMdPath = join44(resolvedPath, "SKILL.md");
21099
21050
  try {
21100
21051
  await fs11.access(skillMdPath);
21101
21052
  const skill = await loadSkillFromPath(skillMdPath, resolvedPath, dirName, scope);
@@ -21103,7 +21054,7 @@ async function loadSkillsFromDir(skillsDir, scope) {
21103
21054
  skills.push(skill);
21104
21055
  continue;
21105
21056
  } catch {}
21106
- const namedSkillMdPath = join43(resolvedPath, `${dirName}.md`);
21057
+ const namedSkillMdPath = join44(resolvedPath, `${dirName}.md`);
21107
21058
  try {
21108
21059
  await fs11.access(namedSkillMdPath);
21109
21060
  const skill = await loadSkillFromPath(namedSkillMdPath, resolvedPath, dirName, scope);
@@ -21131,22 +21082,22 @@ function skillsToRecord(skills) {
21131
21082
  return result;
21132
21083
  }
21133
21084
  async function loadUserSkills() {
21134
- const userSkillsDir = join43(getClaudeConfigDir(), "skills");
21085
+ const userSkillsDir = join44(getClaudeConfigDir(), "skills");
21135
21086
  const skills = await loadSkillsFromDir(userSkillsDir, "user");
21136
21087
  return skillsToRecord(skills);
21137
21088
  }
21138
21089
  async function loadProjectSkills() {
21139
- const projectSkillsDir = join43(process.cwd(), ".claude", "skills");
21090
+ const projectSkillsDir = join44(process.cwd(), ".claude", "skills");
21140
21091
  const skills = await loadSkillsFromDir(projectSkillsDir, "project");
21141
21092
  return skillsToRecord(skills);
21142
21093
  }
21143
21094
  async function loadOpencodeGlobalSkills() {
21144
- const opencodeSkillsDir = join43(homedir12(), ".config", "opencode", "skill");
21095
+ const opencodeSkillsDir = join44(homedir12(), ".config", "opencode", "skill");
21145
21096
  const skills = await loadSkillsFromDir(opencodeSkillsDir, "opencode");
21146
21097
  return skillsToRecord(skills);
21147
21098
  }
21148
21099
  async function loadOpencodeProjectSkills() {
21149
- const opencodeProjectDir = join43(process.cwd(), ".opencode", "skill");
21100
+ const opencodeProjectDir = join44(process.cwd(), ".opencode", "skill");
21150
21101
  const skills = await loadSkillsFromDir(opencodeProjectDir, "opencode-project");
21151
21102
  return skillsToRecord(skills);
21152
21103
  }
@@ -21175,19 +21126,19 @@ async function discoverSkills(options = {}) {
21175
21126
  return [...opencodeProjectSkills, ...projectSkills, ...opencodeGlobalSkills, ...userSkills];
21176
21127
  }
21177
21128
  async function discoverUserClaudeSkills() {
21178
- const userSkillsDir = join43(getClaudeConfigDir(), "skills");
21129
+ const userSkillsDir = join44(getClaudeConfigDir(), "skills");
21179
21130
  return loadSkillsFromDir(userSkillsDir, "user");
21180
21131
  }
21181
21132
  async function discoverProjectClaudeSkills() {
21182
- const projectSkillsDir = join43(process.cwd(), ".claude", "skills");
21133
+ const projectSkillsDir = join44(process.cwd(), ".claude", "skills");
21183
21134
  return loadSkillsFromDir(projectSkillsDir, "project");
21184
21135
  }
21185
21136
  async function discoverOpencodeGlobalSkills() {
21186
- const opencodeSkillsDir = join43(homedir12(), ".config", "opencode", "skill");
21137
+ const opencodeSkillsDir = join44(homedir12(), ".config", "opencode", "skill");
21187
21138
  return loadSkillsFromDir(opencodeSkillsDir, "opencode");
21188
21139
  }
21189
21140
  async function discoverOpencodeProjectSkills() {
21190
- const opencodeProjectDir = join43(process.cwd(), ".opencode", "skill");
21141
+ const opencodeProjectDir = join44(process.cwd(), ".opencode", "skill");
21191
21142
  return loadSkillsFromDir(opencodeProjectDir, "opencode-project");
21192
21143
  }
21193
21144
  // src/features/opencode-skill-loader/merger.ts
@@ -22662,12 +22613,12 @@ function discoverCommandsFromDir(commandsDir, scope) {
22662
22613
  if (!existsSync36(commandsDir)) {
22663
22614
  return [];
22664
22615
  }
22665
- const entries = readdirSync11(commandsDir, { withFileTypes: true });
22616
+ const entries = readdirSync12(commandsDir, { withFileTypes: true });
22666
22617
  const commands = [];
22667
22618
  for (const entry of entries) {
22668
22619
  if (!isMarkdownFile(entry))
22669
22620
  continue;
22670
- const commandPath = join44(commandsDir, entry.name);
22621
+ const commandPath = join45(commandsDir, entry.name);
22671
22622
  const commandName = basename2(entry.name, ".md");
22672
22623
  try {
22673
22624
  const content = readFileSync24(commandPath, "utf-8");
@@ -22712,10 +22663,10 @@ function skillToCommandInfo(skill) {
22712
22663
  };
22713
22664
  }
22714
22665
  async function discoverAllCommands(options) {
22715
- const userCommandsDir = join44(getClaudeConfigDir(), "commands");
22716
- const projectCommandsDir = join44(process.cwd(), ".claude", "commands");
22717
- const opencodeGlobalDir = join44(homedir14(), ".config", "opencode", "command");
22718
- const opencodeProjectDir = join44(process.cwd(), ".opencode", "command");
22666
+ const userCommandsDir = join45(getClaudeConfigDir(), "commands");
22667
+ const projectCommandsDir = join45(process.cwd(), ".claude", "commands");
22668
+ const opencodeGlobalDir = join45(homedir14(), ".config", "opencode", "command");
22669
+ const opencodeProjectDir = join45(process.cwd(), ".opencode", "command");
22719
22670
  const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
22720
22671
  const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode");
22721
22672
  const projectCommands = discoverCommandsFromDir(projectCommandsDir, "project");
@@ -22892,8 +22843,8 @@ ${EDIT_ERROR_REMINDER}`;
22892
22843
  };
22893
22844
  }
22894
22845
  // src/hooks/prometheus-md-only/index.ts
22895
- import { existsSync as existsSync37, readdirSync as readdirSync12 } from "fs";
22896
- import { join as join45, resolve as resolve7, relative as relative4, isAbsolute as isAbsolute3 } from "path";
22846
+ import { existsSync as existsSync37, readdirSync as readdirSync13 } from "fs";
22847
+ import { join as join46, resolve as resolve7, relative as relative4, isAbsolute as isAbsolute3 } from "path";
22897
22848
 
22898
22849
  // src/hooks/prometheus-md-only/constants.ts
22899
22850
  var HOOK_NAME4 = "prometheus-md-only";
@@ -22938,14 +22889,14 @@ function isAllowedFile(filePath, workspaceRoot) {
22938
22889
  }
22939
22890
  return true;
22940
22891
  }
22941
- function getMessageDir9(sessionID) {
22892
+ function getMessageDir10(sessionID) {
22942
22893
  if (!existsSync37(MESSAGE_STORAGE))
22943
22894
  return null;
22944
- const directPath = join45(MESSAGE_STORAGE, sessionID);
22895
+ const directPath = join46(MESSAGE_STORAGE, sessionID);
22945
22896
  if (existsSync37(directPath))
22946
22897
  return directPath;
22947
- for (const dir of readdirSync12(MESSAGE_STORAGE)) {
22948
- const sessionPath = join45(MESSAGE_STORAGE, dir, sessionID);
22898
+ for (const dir of readdirSync13(MESSAGE_STORAGE)) {
22899
+ const sessionPath = join46(MESSAGE_STORAGE, dir, sessionID);
22949
22900
  if (existsSync37(sessionPath))
22950
22901
  return sessionPath;
22951
22902
  }
@@ -22953,7 +22904,7 @@ function getMessageDir9(sessionID) {
22953
22904
  }
22954
22905
  var TASK_TOOLS = ["sisyphus_task", "task", "call_omo_agent"];
22955
22906
  function getAgentFromMessageFiles(sessionID) {
22956
- const messageDir = getMessageDir9(sessionID);
22907
+ const messageDir = getMessageDir10(sessionID);
22957
22908
  if (!messageDir)
22958
22909
  return;
22959
22910
  return findFirstMessageWithAgent(messageDir) ?? findNearestMessageWithFields(messageDir)?.agent;
@@ -23050,10 +23001,10 @@ var NOTEPAD_DIR = "notepads";
23050
23001
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
23051
23002
  var PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
23052
23003
  // src/features/boulder-state/storage.ts
23053
- import { existsSync as existsSync38, readFileSync as readFileSync25, writeFileSync as writeFileSync15, mkdirSync as mkdirSync11, readdirSync as readdirSync13 } from "fs";
23054
- import { dirname as dirname9, join as join46, basename as basename3 } from "path";
23004
+ import { existsSync as existsSync38, readFileSync as readFileSync25, writeFileSync as writeFileSync15, mkdirSync as mkdirSync11, readdirSync as readdirSync14 } from "fs";
23005
+ import { dirname as dirname9, join as join47, basename as basename3 } from "path";
23055
23006
  function getBoulderFilePath(directory) {
23056
- return join46(directory, BOULDER_DIR, BOULDER_FILE);
23007
+ return join47(directory, BOULDER_DIR, BOULDER_FILE);
23057
23008
  }
23058
23009
  function readBoulderState(directory) {
23059
23010
  const filePath = getBoulderFilePath(directory);
@@ -23093,13 +23044,13 @@ function appendSessionId(directory, sessionId) {
23093
23044
  return state2;
23094
23045
  }
23095
23046
  function findPrometheusPlans(directory) {
23096
- const plansDir = join46(directory, PROMETHEUS_PLANS_DIR);
23047
+ const plansDir = join47(directory, PROMETHEUS_PLANS_DIR);
23097
23048
  if (!existsSync38(plansDir)) {
23098
23049
  return [];
23099
23050
  }
23100
23051
  try {
23101
- const files = readdirSync13(plansDir);
23102
- return files.filter((f) => f.endsWith(".md")).map((f) => join46(plansDir, f)).sort((a, b) => {
23052
+ const files = readdirSync14(plansDir);
23053
+ return files.filter((f) => f.endsWith(".md")).map((f) => join47(plansDir, f)).sort((a, b) => {
23103
23054
  const aStat = __require("fs").statSync(a);
23104
23055
  const bStat = __require("fs").statSync(b);
23105
23056
  return bStat.mtimeMs - aStat.mtimeMs;
@@ -23253,8 +23204,8 @@ ${contextInfo}`;
23253
23204
  }
23254
23205
  // src/hooks/sisyphus-orchestrator/index.ts
23255
23206
  import { execSync as execSync2 } from "child_process";
23256
- import { existsSync as existsSync39, readdirSync as readdirSync14 } from "fs";
23257
- import { join as join47 } from "path";
23207
+ import { existsSync as existsSync39, readdirSync as readdirSync15 } from "fs";
23208
+ import { join as join48 } from "path";
23258
23209
  init_logger();
23259
23210
  var HOOK_NAME6 = "sisyphus-orchestrator";
23260
23211
  function isSisyphusPath(filePath) {
@@ -23523,14 +23474,14 @@ No file changes detected.
23523
23474
  return lines.join(`
23524
23475
  `);
23525
23476
  }
23526
- function getMessageDir10(sessionID) {
23477
+ function getMessageDir11(sessionID) {
23527
23478
  if (!existsSync39(MESSAGE_STORAGE))
23528
23479
  return null;
23529
- const directPath = join47(MESSAGE_STORAGE, sessionID);
23480
+ const directPath = join48(MESSAGE_STORAGE, sessionID);
23530
23481
  if (existsSync39(directPath))
23531
23482
  return directPath;
23532
- for (const dir of readdirSync14(MESSAGE_STORAGE)) {
23533
- const sessionPath = join47(MESSAGE_STORAGE, dir, sessionID);
23483
+ for (const dir of readdirSync15(MESSAGE_STORAGE)) {
23484
+ const sessionPath = join48(MESSAGE_STORAGE, dir, sessionID);
23534
23485
  if (existsSync39(sessionPath))
23535
23486
  return sessionPath;
23536
23487
  }
@@ -23539,7 +23490,7 @@ function getMessageDir10(sessionID) {
23539
23490
  function isCallerOrchestrator(sessionID) {
23540
23491
  if (!sessionID)
23541
23492
  return false;
23542
- const messageDir = getMessageDir10(sessionID);
23493
+ const messageDir = getMessageDir11(sessionID);
23543
23494
  if (!messageDir)
23544
23495
  return false;
23545
23496
  const nearest = findNearestMessageWithFields(messageDir);
@@ -23588,10 +23539,14 @@ function createSisyphusOrchestratorHook(ctx, options) {
23588
23539
  [Status: ${total - remaining}/${total} completed, ${remaining} remaining]`;
23589
23540
  try {
23590
23541
  log(`[${HOOK_NAME6}] Injecting boulder continuation`, { sessionID, planName, remaining });
23542
+ const messageDir = getMessageDir11(sessionID);
23543
+ const currentMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
23544
+ const model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
23591
23545
  await ctx.client.session.prompt({
23592
23546
  path: { id: sessionID },
23593
23547
  body: {
23594
23548
  agent: "orchestrator-sisyphus",
23549
+ ...model !== undefined ? { model } : {},
23595
23550
  parts: [{ type: "text", text: prompt }]
23596
23551
  },
23597
23552
  query: { directory: ctx.directory }
@@ -24008,7 +23963,7 @@ function createFirstMessageVariantGate() {
24008
23963
  // src/features/claude-code-mcp-loader/loader.ts
24009
23964
  init_shared();
24010
23965
  import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
24011
- import { join as join48 } from "path";
23966
+ import { join as join49 } from "path";
24012
23967
 
24013
23968
  // src/features/claude-code-mcp-loader/env-expander.ts
24014
23969
  function expandEnvVars(value) {
@@ -24078,9 +24033,9 @@ function getMcpConfigPaths() {
24078
24033
  const claudeConfigDir = getClaudeConfigDir();
24079
24034
  const cwd = process.cwd();
24080
24035
  return [
24081
- { path: join48(claudeConfigDir, ".mcp.json"), scope: "user" },
24082
- { path: join48(cwd, ".mcp.json"), scope: "project" },
24083
- { path: join48(cwd, ".claude", ".mcp.json"), scope: "local" }
24036
+ { path: join49(claudeConfigDir, ".mcp.json"), scope: "user" },
24037
+ { path: join49(cwd, ".mcp.json"), scope: "project" },
24038
+ { path: join49(cwd, ".claude", ".mcp.json"), scope: "local" }
24084
24039
  ];
24085
24040
  }
24086
24041
  async function loadMcpConfigFile(filePath) {
@@ -24535,7 +24490,7 @@ var EXT_TO_LANG = {
24535
24490
  };
24536
24491
  // src/tools/lsp/config.ts
24537
24492
  import { existsSync as existsSync41, readFileSync as readFileSync27 } from "fs";
24538
- import { join as join49 } from "path";
24493
+ import { join as join50 } from "path";
24539
24494
  import { homedir as homedir15 } from "os";
24540
24495
  function loadJsonFile(path8) {
24541
24496
  if (!existsSync41(path8))
@@ -24549,9 +24504,9 @@ function loadJsonFile(path8) {
24549
24504
  function getConfigPaths3() {
24550
24505
  const cwd = process.cwd();
24551
24506
  return {
24552
- project: join49(cwd, ".opencode", "oh-my-opencode.json"),
24553
- user: join49(homedir15(), ".config", "opencode", "oh-my-opencode.json"),
24554
- opencode: join49(homedir15(), ".config", "opencode", "opencode.json")
24507
+ project: join50(cwd, ".opencode", "oh-my-opencode.json"),
24508
+ user: join50(homedir15(), ".config", "opencode", "oh-my-opencode.json"),
24509
+ opencode: join50(homedir15(), ".config", "opencode", "opencode.json")
24555
24510
  };
24556
24511
  }
24557
24512
  function loadAllConfigs() {
@@ -24673,18 +24628,18 @@ function isServerInstalled(command) {
24673
24628
  const pathSeparator = isWindows2 ? ";" : ":";
24674
24629
  const paths = pathEnv.split(pathSeparator);
24675
24630
  for (const p of paths) {
24676
- if (existsSync41(join49(p, cmd)) || existsSync41(join49(p, cmd + ext))) {
24631
+ if (existsSync41(join50(p, cmd)) || existsSync41(join50(p, cmd + ext))) {
24677
24632
  return true;
24678
24633
  }
24679
24634
  }
24680
24635
  const cwd = process.cwd();
24681
24636
  const additionalPaths = [
24682
- join49(cwd, "node_modules", ".bin", cmd),
24683
- join49(cwd, "node_modules", ".bin", cmd + ext),
24684
- join49(homedir15(), ".config", "opencode", "bin", cmd),
24685
- join49(homedir15(), ".config", "opencode", "bin", cmd + ext),
24686
- join49(homedir15(), ".config", "opencode", "node_modules", ".bin", cmd),
24687
- join49(homedir15(), ".config", "opencode", "node_modules", ".bin", cmd + ext)
24637
+ join50(cwd, "node_modules", ".bin", cmd),
24638
+ join50(cwd, "node_modules", ".bin", cmd + ext),
24639
+ join50(homedir15(), ".config", "opencode", "bin", cmd),
24640
+ join50(homedir15(), ".config", "opencode", "bin", cmd + ext),
24641
+ join50(homedir15(), ".config", "opencode", "node_modules", ".bin", cmd),
24642
+ join50(homedir15(), ".config", "opencode", "node_modules", ".bin", cmd + ext)
24688
24643
  ];
24689
24644
  for (const p of additionalPaths) {
24690
24645
  if (existsSync41(p)) {
@@ -25386,23 +25341,6 @@ async function withLspClient(filePath, fn) {
25386
25341
  lspManager.releaseClient(root, server.id);
25387
25342
  }
25388
25343
  }
25389
- function formatHoverResult(result) {
25390
- if (!result)
25391
- return "No hover information available";
25392
- const contents = result.contents;
25393
- if (typeof contents === "string") {
25394
- return contents;
25395
- }
25396
- if (Array.isArray(contents)) {
25397
- return contents.map((c) => typeof c === "string" ? c : c.value).filter(Boolean).join(`
25398
-
25399
- `);
25400
- }
25401
- if (typeof contents === "object" && "value" in contents) {
25402
- return contents.value;
25403
- }
25404
- return "No hover information available";
25405
- }
25406
25344
  function formatLocation(loc) {
25407
25345
  if ("targetUri" in loc) {
25408
25346
  const uri2 = uriToPath(loc.targetUri);
@@ -25486,31 +25424,6 @@ function formatPrepareRenameResult(result) {
25486
25424
  }
25487
25425
  return "Cannot rename at this position";
25488
25426
  }
25489
- function formatCodeAction(action) {
25490
- let result = `[${action.kind || "action"}] ${action.title}`;
25491
- if (action.isPreferred) {
25492
- result += " \u2B50";
25493
- }
25494
- if (action.disabled) {
25495
- result += ` (disabled: ${action.disabled.reason})`;
25496
- }
25497
- return result;
25498
- }
25499
- function formatCodeActions(actions) {
25500
- if (!actions || actions.length === 0)
25501
- return "No code actions available";
25502
- const lines = [];
25503
- for (let i2 = 0;i2 < actions.length; i2++) {
25504
- const action = actions[i2];
25505
- if ("command" in action && typeof action.command === "string" && !("kind" in action)) {
25506
- lines.push(`${i2 + 1}. [command] ${action.title}`);
25507
- } else {
25508
- lines.push(`${i2 + 1}. ${formatCodeAction(action)}`);
25509
- }
25510
- }
25511
- return lines.join(`
25512
- `);
25513
- }
25514
25427
  function applyTextEditsToFile(filePath, edits) {
25515
25428
  try {
25516
25429
  let content = readFileSync29(filePath, "utf-8");
@@ -37953,26 +37866,6 @@ function tool(input) {
37953
37866
  tool.schema = exports_external;
37954
37867
 
37955
37868
  // src/tools/lsp/tools.ts
37956
- var lsp_hover = tool({
37957
- description: "Get type info, docs, and signature for a symbol at position.",
37958
- args: {
37959
- filePath: tool.schema.string(),
37960
- line: tool.schema.number().min(1).describe("1-based"),
37961
- character: tool.schema.number().min(0).describe("0-based")
37962
- },
37963
- execute: async (args, context) => {
37964
- try {
37965
- const result = await withLspClient(args.filePath, async (client) => {
37966
- return await client.hover(args.filePath, args.line, args.character);
37967
- });
37968
- const output = formatHoverResult(result);
37969
- return output;
37970
- } catch (e) {
37971
- const output = `Error: ${e instanceof Error ? e.message : String(e)}`;
37972
- return output;
37973
- }
37974
- }
37975
- });
37976
37869
  var lsp_goto_definition = tool({
37977
37870
  description: "Jump to symbol definition. Find WHERE something is defined.",
37978
37871
  args: {
@@ -38036,70 +37929,62 @@ var lsp_find_references = tool({
38036
37929
  }
38037
37930
  }
38038
37931
  });
38039
- var lsp_document_symbols = tool({
38040
- description: "Get hierarchical outline of all symbols in a file.",
37932
+ var lsp_symbols = tool({
37933
+ description: "Get symbols from file (document) or search across workspace. Use scope='document' for file outline, scope='workspace' for project-wide symbol search.",
38041
37934
  args: {
38042
- filePath: tool.schema.string()
37935
+ filePath: tool.schema.string().describe("File path for LSP context"),
37936
+ scope: tool.schema.enum(["document", "workspace"]).default("document").describe("'document' for file symbols, 'workspace' for project-wide search"),
37937
+ query: tool.schema.string().optional().describe("Symbol name to search (required for workspace scope)"),
37938
+ limit: tool.schema.number().optional().describe("Max results (default 50)")
38043
37939
  },
38044
37940
  execute: async (args, context) => {
38045
37941
  try {
38046
- const result = await withLspClient(args.filePath, async (client) => {
38047
- return await client.documentSymbols(args.filePath);
38048
- });
38049
- if (!result || result.length === 0) {
38050
- const output = "No symbols found";
38051
- return output;
38052
- }
38053
- const total = result.length;
38054
- const truncated = total > DEFAULT_MAX_SYMBOLS;
38055
- const limited = truncated ? result.slice(0, DEFAULT_MAX_SYMBOLS) : result;
38056
- const lines = [];
38057
- if (truncated) {
38058
- lines.push(`Found ${total} symbols (showing first ${DEFAULT_MAX_SYMBOLS}):`);
38059
- }
38060
- if ("range" in limited[0]) {
38061
- lines.push(...limited.map((s) => formatDocumentSymbol(s)));
37942
+ const scope = args.scope ?? "document";
37943
+ if (scope === "workspace") {
37944
+ if (!args.query) {
37945
+ return "Error: 'query' is required for workspace scope";
37946
+ }
37947
+ const result = await withLspClient(args.filePath, async (client) => {
37948
+ return await client.workspaceSymbols(args.query);
37949
+ });
37950
+ if (!result || result.length === 0) {
37951
+ return "No symbols found";
37952
+ }
37953
+ const total = result.length;
37954
+ const limit = Math.min(args.limit ?? DEFAULT_MAX_SYMBOLS, DEFAULT_MAX_SYMBOLS);
37955
+ const truncated = total > limit;
37956
+ const limited = result.slice(0, limit);
37957
+ const lines = limited.map(formatSymbolInfo);
37958
+ if (truncated) {
37959
+ lines.unshift(`Found ${total} symbols (showing first ${limit}):`);
37960
+ }
37961
+ return lines.join(`
37962
+ `);
38062
37963
  } else {
38063
- lines.push(...limited.map(formatSymbolInfo));
38064
- }
38065
- return lines.join(`
37964
+ const result = await withLspClient(args.filePath, async (client) => {
37965
+ return await client.documentSymbols(args.filePath);
37966
+ });
37967
+ if (!result || result.length === 0) {
37968
+ return "No symbols found";
37969
+ }
37970
+ const total = result.length;
37971
+ const limit = Math.min(args.limit ?? DEFAULT_MAX_SYMBOLS, DEFAULT_MAX_SYMBOLS);
37972
+ const truncated = total > limit;
37973
+ const limited = truncated ? result.slice(0, limit) : result;
37974
+ const lines = [];
37975
+ if (truncated) {
37976
+ lines.push(`Found ${total} symbols (showing first ${limit}):`);
37977
+ }
37978
+ if ("range" in limited[0]) {
37979
+ lines.push(...limited.map((s) => formatDocumentSymbol(s)));
37980
+ } else {
37981
+ lines.push(...limited.map(formatSymbolInfo));
37982
+ }
37983
+ return lines.join(`
38066
37984
  `);
38067
- } catch (e) {
38068
- const output = `Error: ${e instanceof Error ? e.message : String(e)}`;
38069
- return output;
38070
- }
38071
- }
38072
- });
38073
- var lsp_workspace_symbols = tool({
38074
- description: "Search symbols by name across ENTIRE workspace.",
38075
- args: {
38076
- filePath: tool.schema.string(),
38077
- query: tool.schema.string().describe("Symbol name (fuzzy match)"),
38078
- limit: tool.schema.number().optional().describe("Max results")
38079
- },
38080
- execute: async (args, context) => {
38081
- try {
38082
- const result = await withLspClient(args.filePath, async (client) => {
38083
- return await client.workspaceSymbols(args.query);
38084
- });
38085
- if (!result || result.length === 0) {
38086
- const output2 = "No symbols found";
38087
- return output2;
38088
37985
  }
38089
- const total = result.length;
38090
- const limit = Math.min(args.limit ?? DEFAULT_MAX_SYMBOLS, DEFAULT_MAX_SYMBOLS);
38091
- const truncated = total > limit;
38092
- const limited = result.slice(0, limit);
38093
- const lines = limited.map(formatSymbolInfo);
38094
- if (truncated) {
38095
- lines.unshift(`Found ${total} symbols (showing first ${limit}):`);
38096
- }
38097
- const output = lines.join(`
38098
- `);
38099
- return output;
38100
37986
  } catch (e) {
38101
- const output = `Error: ${e instanceof Error ? e.message : String(e)}`;
38102
- return output;
37987
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
38103
37988
  }
38104
37989
  }
38105
37990
  });
@@ -38207,86 +38092,15 @@ var lsp_rename = tool({
38207
38092
  }
38208
38093
  }
38209
38094
  });
38210
- var lsp_code_actions = tool({
38211
- description: "Get available quick fixes, refactorings, and source actions (organize imports, fix all).",
38212
- args: {
38213
- filePath: tool.schema.string(),
38214
- startLine: tool.schema.number().min(1).describe("1-based"),
38215
- startCharacter: tool.schema.number().min(0).describe("0-based"),
38216
- endLine: tool.schema.number().min(1).describe("1-based"),
38217
- endCharacter: tool.schema.number().min(0).describe("0-based"),
38218
- kind: tool.schema.enum([
38219
- "quickfix",
38220
- "refactor",
38221
- "refactor.extract",
38222
- "refactor.inline",
38223
- "refactor.rewrite",
38224
- "source",
38225
- "source.organizeImports",
38226
- "source.fixAll"
38227
- ]).optional().describe("Filter by code action kind")
38228
- },
38229
- execute: async (args, context) => {
38230
- try {
38231
- const only = args.kind ? [args.kind] : undefined;
38232
- const result = await withLspClient(args.filePath, async (client) => {
38233
- return await client.codeAction(args.filePath, args.startLine, args.startCharacter, args.endLine, args.endCharacter, only);
38234
- });
38235
- const output = formatCodeActions(result);
38236
- return output;
38237
- } catch (e) {
38238
- const output = `Error: ${e instanceof Error ? e.message : String(e)}`;
38239
- return output;
38240
- }
38241
- }
38242
- });
38243
- var lsp_code_action_resolve = tool({
38244
- description: "Resolve and APPLY a code action from lsp_code_actions.",
38245
- args: {
38246
- filePath: tool.schema.string(),
38247
- codeAction: tool.schema.string().describe("Code action JSON from lsp_code_actions")
38248
- },
38249
- execute: async (args, context) => {
38250
- try {
38251
- const codeAction = JSON.parse(args.codeAction);
38252
- const resolved = await withLspClient(args.filePath, async (client) => {
38253
- return await client.codeActionResolve(codeAction);
38254
- });
38255
- if (!resolved) {
38256
- const output2 = "Failed to resolve code action";
38257
- return output2;
38258
- }
38259
- const lines = [];
38260
- lines.push(`Action: ${resolved.title}`);
38261
- if (resolved.kind)
38262
- lines.push(`Kind: ${resolved.kind}`);
38263
- if (resolved.edit) {
38264
- const result = applyWorkspaceEdit(resolved.edit);
38265
- lines.push(formatApplyResult(result));
38266
- } else {
38267
- lines.push("No edit to apply");
38268
- }
38269
- if (resolved.command) {
38270
- lines.push(`Command: ${resolved.command.title} (${resolved.command.command}) - not executed`);
38271
- }
38272
- const output = lines.join(`
38273
- `);
38274
- return output;
38275
- } catch (e) {
38276
- const output = `Error: ${e instanceof Error ? e.message : String(e)}`;
38277
- return output;
38278
- }
38279
- }
38280
- });
38281
38095
  // src/tools/ast-grep/constants.ts
38282
38096
  import { createRequire as createRequire4 } from "module";
38283
- import { dirname as dirname10, join as join51 } from "path";
38097
+ import { dirname as dirname10, join as join52 } from "path";
38284
38098
  import { existsSync as existsSync44, statSync as statSync4 } from "fs";
38285
38099
 
38286
38100
  // src/tools/ast-grep/downloader.ts
38287
38101
  init_shared();
38288
38102
  import { existsSync as existsSync43, mkdirSync as mkdirSync12, chmodSync as chmodSync2, unlinkSync as unlinkSync10 } from "fs";
38289
- import { join as join50 } from "path";
38103
+ import { join as join51 } from "path";
38290
38104
  import { homedir as homedir16 } from "os";
38291
38105
  import { createRequire as createRequire3 } from "module";
38292
38106
  var REPO2 = "ast-grep/ast-grep";
@@ -38312,18 +38126,18 @@ var PLATFORM_MAP2 = {
38312
38126
  function getCacheDir3() {
38313
38127
  if (process.platform === "win32") {
38314
38128
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
38315
- const base2 = localAppData || join50(homedir16(), "AppData", "Local");
38316
- return join50(base2, "oh-my-opencode", "bin");
38129
+ const base2 = localAppData || join51(homedir16(), "AppData", "Local");
38130
+ return join51(base2, "oh-my-opencode", "bin");
38317
38131
  }
38318
38132
  const xdgCache = process.env.XDG_CACHE_HOME;
38319
- const base = xdgCache || join50(homedir16(), ".cache");
38320
- return join50(base, "oh-my-opencode", "bin");
38133
+ const base = xdgCache || join51(homedir16(), ".cache");
38134
+ return join51(base, "oh-my-opencode", "bin");
38321
38135
  }
38322
38136
  function getBinaryName3() {
38323
38137
  return process.platform === "win32" ? "sg.exe" : "sg";
38324
38138
  }
38325
38139
  function getCachedBinaryPath2() {
38326
- const binaryPath = join50(getCacheDir3(), getBinaryName3());
38140
+ const binaryPath = join51(getCacheDir3(), getBinaryName3());
38327
38141
  return existsSync43(binaryPath) ? binaryPath : null;
38328
38142
  }
38329
38143
  async function downloadAstGrep(version2 = DEFAULT_VERSION) {
@@ -38335,7 +38149,7 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
38335
38149
  }
38336
38150
  const cacheDir = getCacheDir3();
38337
38151
  const binaryName = getBinaryName3();
38338
- const binaryPath = join50(cacheDir, binaryName);
38152
+ const binaryPath = join51(cacheDir, binaryName);
38339
38153
  if (existsSync43(binaryPath)) {
38340
38154
  return binaryPath;
38341
38155
  }
@@ -38351,7 +38165,7 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
38351
38165
  if (!response.ok) {
38352
38166
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
38353
38167
  }
38354
- const archivePath = join50(cacheDir, assetName);
38168
+ const archivePath = join51(cacheDir, assetName);
38355
38169
  const arrayBuffer = await response.arrayBuffer();
38356
38170
  await Bun.write(archivePath, arrayBuffer);
38357
38171
  await extractZip(archivePath, cacheDir);
@@ -38409,7 +38223,7 @@ function findSgCliPathSync() {
38409
38223
  const require2 = createRequire4(import.meta.url);
38410
38224
  const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
38411
38225
  const cliDir = dirname10(cliPkgPath);
38412
- const sgPath = join51(cliDir, binaryName);
38226
+ const sgPath = join52(cliDir, binaryName);
38413
38227
  if (existsSync44(sgPath) && isValidBinary(sgPath)) {
38414
38228
  return sgPath;
38415
38229
  }
@@ -38421,7 +38235,7 @@ function findSgCliPathSync() {
38421
38235
  const pkgPath = require2.resolve(`${platformPkg}/package.json`);
38422
38236
  const pkgDir = dirname10(pkgPath);
38423
38237
  const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
38424
- const binaryPath = join51(pkgDir, astGrepName);
38238
+ const binaryPath = join52(pkgDir, astGrepName);
38425
38239
  if (existsSync44(binaryPath) && isValidBinary(binaryPath)) {
38426
38240
  return binaryPath;
38427
38241
  }
@@ -38796,20 +38610,20 @@ var {spawn: spawn9 } = globalThis.Bun;
38796
38610
 
38797
38611
  // src/tools/grep/constants.ts
38798
38612
  import { existsSync as existsSync47 } from "fs";
38799
- import { join as join53, dirname as dirname11 } from "path";
38613
+ import { join as join54, dirname as dirname11 } from "path";
38800
38614
  import { spawnSync as spawnSync2 } from "child_process";
38801
38615
 
38802
38616
  // src/tools/grep/downloader.ts
38803
38617
  init_shared();
38804
- import { existsSync as existsSync46, mkdirSync as mkdirSync13, chmodSync as chmodSync3, unlinkSync as unlinkSync11, readdirSync as readdirSync15 } from "fs";
38805
- import { join as join52 } from "path";
38618
+ import { existsSync as existsSync46, mkdirSync as mkdirSync13, chmodSync as chmodSync3, unlinkSync as unlinkSync11, readdirSync as readdirSync16 } from "fs";
38619
+ import { join as join53 } from "path";
38806
38620
  var {spawn: spawn8 } = globalThis.Bun;
38807
38621
  function findFileRecursive(dir, filename) {
38808
38622
  try {
38809
- const entries = readdirSync15(dir, { withFileTypes: true, recursive: true });
38623
+ const entries = readdirSync16(dir, { withFileTypes: true, recursive: true });
38810
38624
  for (const entry of entries) {
38811
38625
  if (entry.isFile() && entry.name === filename) {
38812
- return join52(entry.parentPath ?? dir, entry.name);
38626
+ return join53(entry.parentPath ?? dir, entry.name);
38813
38627
  }
38814
38628
  }
38815
38629
  } catch {
@@ -38830,11 +38644,11 @@ function getPlatformKey() {
38830
38644
  }
38831
38645
  function getInstallDir() {
38832
38646
  const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
38833
- return join52(homeDir, ".cache", "oh-my-opencode", "bin");
38647
+ return join53(homeDir, ".cache", "oh-my-opencode", "bin");
38834
38648
  }
38835
38649
  function getRgPath() {
38836
38650
  const isWindows2 = process.platform === "win32";
38837
- return join52(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
38651
+ return join53(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
38838
38652
  }
38839
38653
  async function downloadFile(url2, destPath) {
38840
38654
  const response = await fetch(url2);
@@ -38868,7 +38682,7 @@ async function extractZip2(archivePath, destDir) {
38868
38682
  const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
38869
38683
  const foundPath = findFileRecursive(destDir, binaryName);
38870
38684
  if (foundPath) {
38871
- const destPath = join52(destDir, binaryName);
38685
+ const destPath = join53(destDir, binaryName);
38872
38686
  if (foundPath !== destPath) {
38873
38687
  const { renameSync } = await import("fs");
38874
38688
  renameSync(foundPath, destPath);
@@ -38889,7 +38703,7 @@ async function downloadAndInstallRipgrep() {
38889
38703
  mkdirSync13(installDir, { recursive: true });
38890
38704
  const filename = `ripgrep-${RG_VERSION}-${config3.platform}.${config3.extension}`;
38891
38705
  const url2 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
38892
- const archivePath = join52(installDir, filename);
38706
+ const archivePath = join53(installDir, filename);
38893
38707
  try {
38894
38708
  await downloadFile(url2, archivePath);
38895
38709
  if (config3.extension === "tar.gz") {
@@ -38939,11 +38753,11 @@ function getOpenCodeBundledRg() {
38939
38753
  const isWindows2 = process.platform === "win32";
38940
38754
  const rgName = isWindows2 ? "rg.exe" : "rg";
38941
38755
  const candidates = [
38942
- join53(getDataDir(), "opencode", "bin", rgName),
38943
- join53(execDir, rgName),
38944
- join53(execDir, "bin", rgName),
38945
- join53(execDir, "..", "bin", rgName),
38946
- join53(execDir, "..", "libexec", rgName)
38756
+ join54(getDataDir(), "opencode", "bin", rgName),
38757
+ join54(execDir, rgName),
38758
+ join54(execDir, "bin", rgName),
38759
+ join54(execDir, "..", "bin", rgName),
38760
+ join54(execDir, "..", "libexec", rgName)
38947
38761
  ];
38948
38762
  for (const candidate of candidates) {
38949
38763
  if (existsSync47(candidate)) {
@@ -39408,18 +39222,18 @@ var glob = tool({
39408
39222
  init_shared();
39409
39223
  init_file_utils();
39410
39224
  init_shared();
39411
- import { existsSync as existsSync48, readdirSync as readdirSync16, readFileSync as readFileSync30 } from "fs";
39412
- import { join as join54, basename as basename4, dirname as dirname12 } from "path";
39225
+ import { existsSync as existsSync48, readdirSync as readdirSync17, readFileSync as readFileSync30 } from "fs";
39226
+ import { join as join55, basename as basename4, dirname as dirname12 } from "path";
39413
39227
  function discoverCommandsFromDir2(commandsDir, scope) {
39414
39228
  if (!existsSync48(commandsDir)) {
39415
39229
  return [];
39416
39230
  }
39417
- const entries = readdirSync16(commandsDir, { withFileTypes: true });
39231
+ const entries = readdirSync17(commandsDir, { withFileTypes: true });
39418
39232
  const commands = [];
39419
39233
  for (const entry of entries) {
39420
39234
  if (!isMarkdownFile(entry))
39421
39235
  continue;
39422
- const commandPath = join54(commandsDir, entry.name);
39236
+ const commandPath = join55(commandsDir, entry.name);
39423
39237
  const commandName = basename4(entry.name, ".md");
39424
39238
  try {
39425
39239
  const content = readFileSync30(commandPath, "utf-8");
@@ -39448,10 +39262,10 @@ function discoverCommandsFromDir2(commandsDir, scope) {
39448
39262
  }
39449
39263
  function discoverCommandsSync() {
39450
39264
  const { homedir: homedir17 } = __require("os");
39451
- const userCommandsDir = join54(getClaudeConfigDir(), "commands");
39452
- const projectCommandsDir = join54(process.cwd(), ".claude", "commands");
39453
- const opencodeGlobalDir = join54(homedir17(), ".config", "opencode", "command");
39454
- const opencodeProjectDir = join54(process.cwd(), ".opencode", "command");
39265
+ const userCommandsDir = join55(getClaudeConfigDir(), "commands");
39266
+ const projectCommandsDir = join55(process.cwd(), ".claude", "commands");
39267
+ const opencodeGlobalDir = join55(homedir17(), ".config", "opencode", "command");
39268
+ const opencodeProjectDir = join55(process.cwd(), ".opencode", "command");
39455
39269
  const userCommands = discoverCommandsFromDir2(userCommandsDir, "user");
39456
39270
  const opencodeGlobalCommands = discoverCommandsFromDir2(opencodeGlobalDir, "opencode");
39457
39271
  const projectCommands = discoverCommandsFromDir2(projectCommandsDir, "project");
@@ -39614,13 +39428,13 @@ var slashcommand = createSlashcommandTool();
39614
39428
  // src/tools/session-manager/constants.ts
39615
39429
  init_data_path();
39616
39430
  init_shared();
39617
- import { join as join55 } from "path";
39431
+ import { join as join56 } from "path";
39618
39432
  var OPENCODE_STORAGE9 = getOpenCodeStorageDir();
39619
- var MESSAGE_STORAGE4 = join55(OPENCODE_STORAGE9, "message");
39620
- var PART_STORAGE4 = join55(OPENCODE_STORAGE9, "part");
39621
- var SESSION_STORAGE = join55(OPENCODE_STORAGE9, "session");
39622
- var TODO_DIR2 = join55(getClaudeConfigDir(), "todos");
39623
- var TRANSCRIPT_DIR2 = join55(getClaudeConfigDir(), "transcripts");
39433
+ var MESSAGE_STORAGE4 = join56(OPENCODE_STORAGE9, "message");
39434
+ var PART_STORAGE4 = join56(OPENCODE_STORAGE9, "part");
39435
+ var SESSION_STORAGE = join56(OPENCODE_STORAGE9, "session");
39436
+ var TODO_DIR2 = join56(getClaudeConfigDir(), "todos");
39437
+ var TRANSCRIPT_DIR2 = join56(getClaudeConfigDir(), "transcripts");
39624
39438
  var SESSION_LIST_DESCRIPTION = `List all OpenCode sessions with optional filtering.
39625
39439
 
39626
39440
  Returns a list of available session IDs with metadata including message count, date range, and agents used.
@@ -39693,9 +39507,9 @@ Has Todos: Yes (12 items, 8 completed)
39693
39507
  Has Transcript: Yes (234 entries)`;
39694
39508
 
39695
39509
  // src/tools/session-manager/storage.ts
39696
- import { existsSync as existsSync49, readdirSync as readdirSync17 } from "fs";
39510
+ import { existsSync as existsSync49, readdirSync as readdirSync18 } from "fs";
39697
39511
  import { readdir, readFile } from "fs/promises";
39698
- import { join as join56 } from "path";
39512
+ import { join as join57 } from "path";
39699
39513
  async function getMainSessions(options) {
39700
39514
  if (!existsSync49(SESSION_STORAGE))
39701
39515
  return [];
@@ -39705,13 +39519,13 @@ async function getMainSessions(options) {
39705
39519
  for (const projectDir of projectDirs) {
39706
39520
  if (!projectDir.isDirectory())
39707
39521
  continue;
39708
- const projectPath = join56(SESSION_STORAGE, projectDir.name);
39522
+ const projectPath = join57(SESSION_STORAGE, projectDir.name);
39709
39523
  const sessionFiles = await readdir(projectPath);
39710
39524
  for (const file2 of sessionFiles) {
39711
39525
  if (!file2.endsWith(".json"))
39712
39526
  continue;
39713
39527
  try {
39714
- const content = await readFile(join56(projectPath, file2), "utf-8");
39528
+ const content = await readFile(join57(projectPath, file2), "utf-8");
39715
39529
  const meta = JSON.parse(content);
39716
39530
  if (meta.parentID)
39717
39531
  continue;
@@ -39737,7 +39551,7 @@ async function getAllSessions() {
39737
39551
  const entries = await readdir(dir, { withFileTypes: true });
39738
39552
  for (const entry of entries) {
39739
39553
  if (entry.isDirectory()) {
39740
- const sessionPath = join56(dir, entry.name);
39554
+ const sessionPath = join57(dir, entry.name);
39741
39555
  const files = await readdir(sessionPath);
39742
39556
  if (files.some((f) => f.endsWith(".json"))) {
39743
39557
  sessions.push(entry.name);
@@ -39753,16 +39567,16 @@ async function getAllSessions() {
39753
39567
  await scanDirectory(MESSAGE_STORAGE4);
39754
39568
  return [...new Set(sessions)];
39755
39569
  }
39756
- function getMessageDir11(sessionID) {
39570
+ function getMessageDir12(sessionID) {
39757
39571
  if (!existsSync49(MESSAGE_STORAGE4))
39758
39572
  return "";
39759
- const directPath = join56(MESSAGE_STORAGE4, sessionID);
39573
+ const directPath = join57(MESSAGE_STORAGE4, sessionID);
39760
39574
  if (existsSync49(directPath)) {
39761
39575
  return directPath;
39762
39576
  }
39763
39577
  try {
39764
- for (const dir of readdirSync17(MESSAGE_STORAGE4)) {
39765
- const sessionPath = join56(MESSAGE_STORAGE4, dir, sessionID);
39578
+ for (const dir of readdirSync18(MESSAGE_STORAGE4)) {
39579
+ const sessionPath = join57(MESSAGE_STORAGE4, dir, sessionID);
39766
39580
  if (existsSync49(sessionPath)) {
39767
39581
  return sessionPath;
39768
39582
  }
@@ -39773,10 +39587,10 @@ function getMessageDir11(sessionID) {
39773
39587
  return "";
39774
39588
  }
39775
39589
  function sessionExists(sessionID) {
39776
- return getMessageDir11(sessionID) !== "";
39590
+ return getMessageDir12(sessionID) !== "";
39777
39591
  }
39778
39592
  async function readSessionMessages(sessionID) {
39779
- const messageDir = getMessageDir11(sessionID);
39593
+ const messageDir = getMessageDir12(sessionID);
39780
39594
  if (!messageDir || !existsSync49(messageDir))
39781
39595
  return [];
39782
39596
  const messages = [];
@@ -39786,7 +39600,7 @@ async function readSessionMessages(sessionID) {
39786
39600
  if (!file2.endsWith(".json"))
39787
39601
  continue;
39788
39602
  try {
39789
- const content = await readFile(join56(messageDir, file2), "utf-8");
39603
+ const content = await readFile(join57(messageDir, file2), "utf-8");
39790
39604
  const meta = JSON.parse(content);
39791
39605
  const parts = await readParts2(meta.id);
39792
39606
  messages.push({
@@ -39812,7 +39626,7 @@ async function readSessionMessages(sessionID) {
39812
39626
  });
39813
39627
  }
39814
39628
  async function readParts2(messageID) {
39815
- const partDir = join56(PART_STORAGE4, messageID);
39629
+ const partDir = join57(PART_STORAGE4, messageID);
39816
39630
  if (!existsSync49(partDir))
39817
39631
  return [];
39818
39632
  const parts = [];
@@ -39822,7 +39636,7 @@ async function readParts2(messageID) {
39822
39636
  if (!file2.endsWith(".json"))
39823
39637
  continue;
39824
39638
  try {
39825
- const content = await readFile(join56(partDir, file2), "utf-8");
39639
+ const content = await readFile(join57(partDir, file2), "utf-8");
39826
39640
  parts.push(JSON.parse(content));
39827
39641
  } catch {
39828
39642
  continue;
@@ -39841,7 +39655,7 @@ async function readSessionTodos(sessionID) {
39841
39655
  const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json"));
39842
39656
  for (const file2 of todoFiles) {
39843
39657
  try {
39844
- const content = await readFile(join56(TODO_DIR2, file2), "utf-8");
39658
+ const content = await readFile(join57(TODO_DIR2, file2), "utf-8");
39845
39659
  const data = JSON.parse(content);
39846
39660
  if (Array.isArray(data)) {
39847
39661
  return data.map((item) => ({
@@ -39863,7 +39677,7 @@ async function readSessionTodos(sessionID) {
39863
39677
  async function readSessionTranscript(sessionID) {
39864
39678
  if (!existsSync49(TRANSCRIPT_DIR2))
39865
39679
  return 0;
39866
- const transcriptFile = join56(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
39680
+ const transcriptFile = join57(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
39867
39681
  if (!existsSync49(transcriptFile))
39868
39682
  return 0;
39869
39683
  try {
@@ -40918,17 +40732,17 @@ Available: {agents}
40918
40732
 
40919
40733
  Pass \`resume=session_id\` to continue previous agent with full context. Prompts MUST be in English. Use \`background_output\` for async results.`;
40920
40734
  // src/tools/call-omo-agent/tools.ts
40921
- import { existsSync as existsSync50, readdirSync as readdirSync18 } from "fs";
40922
- import { join as join57 } from "path";
40735
+ import { existsSync as existsSync50, readdirSync as readdirSync19 } from "fs";
40736
+ import { join as join58 } from "path";
40923
40737
  init_logger();
40924
- function getMessageDir12(sessionID) {
40738
+ function getMessageDir13(sessionID) {
40925
40739
  if (!existsSync50(MESSAGE_STORAGE))
40926
40740
  return null;
40927
- const directPath = join57(MESSAGE_STORAGE, sessionID);
40741
+ const directPath = join58(MESSAGE_STORAGE, sessionID);
40928
40742
  if (existsSync50(directPath))
40929
40743
  return directPath;
40930
- for (const dir of readdirSync18(MESSAGE_STORAGE)) {
40931
- const sessionPath = join57(MESSAGE_STORAGE, dir, sessionID);
40744
+ for (const dir of readdirSync19(MESSAGE_STORAGE)) {
40745
+ const sessionPath = join58(MESSAGE_STORAGE, dir, sessionID);
40932
40746
  if (existsSync50(sessionPath))
40933
40747
  return sessionPath;
40934
40748
  }
@@ -40965,7 +40779,7 @@ function createCallOmoAgent(ctx, backgroundManager) {
40965
40779
  }
40966
40780
  async function executeBackground(args, toolContext, manager) {
40967
40781
  try {
40968
- const messageDir = getMessageDir12(toolContext.sessionID);
40782
+ const messageDir = getMessageDir13(toolContext.sessionID);
40969
40783
  const prevMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
40970
40784
  const firstMessageAgent = messageDir ? findFirstMessageWithAgent(messageDir) : null;
40971
40785
  const sessionAgent = getSessionAgent(toolContext.sessionID);
@@ -41305,9 +41119,9 @@ If the requested information is not found, clearly state what is missing.`;
41305
41119
  });
41306
41120
  }
41307
41121
  // src/tools/sisyphus-task/tools.ts
41308
- init_constants();
41309
- import { existsSync as existsSync51, readdirSync as readdirSync19 } from "fs";
41310
- import { join as join58 } from "path";
41122
+ init_constants2();
41123
+ import { existsSync as existsSync51, readdirSync as readdirSync20 } from "fs";
41124
+ import { join as join59 } from "path";
41311
41125
 
41312
41126
  // src/features/task-toast-manager/manager.ts
41313
41127
  class TaskToastManager {
@@ -41458,14 +41272,14 @@ function parseModelString(model) {
41458
41272
  }
41459
41273
  return;
41460
41274
  }
41461
- function getMessageDir13(sessionID) {
41275
+ function getMessageDir14(sessionID) {
41462
41276
  if (!existsSync51(MESSAGE_STORAGE))
41463
41277
  return null;
41464
- const directPath = join58(MESSAGE_STORAGE, sessionID);
41278
+ const directPath = join59(MESSAGE_STORAGE, sessionID);
41465
41279
  if (existsSync51(directPath))
41466
41280
  return directPath;
41467
- for (const dir of readdirSync19(MESSAGE_STORAGE)) {
41468
- const sessionPath = join58(MESSAGE_STORAGE, dir, sessionID);
41281
+ for (const dir of readdirSync20(MESSAGE_STORAGE)) {
41282
+ const sessionPath = join59(MESSAGE_STORAGE, dir, sessionID);
41469
41283
  if (existsSync51(sessionPath))
41470
41284
  return sessionPath;
41471
41285
  }
@@ -41547,7 +41361,7 @@ function createSisyphusTask(options) {
41547
41361
 
41548
41362
  `);
41549
41363
  }
41550
- const messageDir = getMessageDir13(ctx.sessionID);
41364
+ const messageDir = getMessageDir14(ctx.sessionID);
41551
41365
  const prevMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
41552
41366
  const firstMessageAgent = messageDir ? findFirstMessageWithAgent(messageDir) : null;
41553
41367
  const sessionAgent = getSessionAgent(ctx.sessionID);
@@ -41608,9 +41422,15 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`;
41608
41422
  metadata: { sessionId: args.resume, sync: true }
41609
41423
  });
41610
41424
  try {
41425
+ const resumeMessageDir = getMessageDir14(args.resume);
41426
+ const resumeMessage = resumeMessageDir ? findNearestMessageWithFields(resumeMessageDir) : null;
41427
+ const resumeAgent = resumeMessage?.agent;
41428
+ const resumeModel = resumeMessage?.model?.providerID && resumeMessage?.model?.modelID ? { providerID: resumeMessage.model.providerID, modelID: resumeMessage.model.modelID } : undefined;
41611
41429
  await client2.session.prompt({
41612
41430
  path: { id: args.resume },
41613
41431
  body: {
41432
+ ...resumeAgent !== undefined ? { agent: resumeAgent } : {},
41433
+ ...resumeModel !== undefined ? { model: resumeModel } : {},
41614
41434
  tools: {
41615
41435
  task: false,
41616
41436
  sisyphus_task: false,
@@ -41927,7 +41747,7 @@ ${textContent || "(No text output)"}`;
41927
41747
  }
41928
41748
 
41929
41749
  // src/tools/sisyphus-task/index.ts
41930
- init_constants();
41750
+ init_constants2();
41931
41751
  // src/tools/index.ts
41932
41752
  function createBackgroundTools(manager, client2) {
41933
41753
  return {
@@ -41936,17 +41756,13 @@ function createBackgroundTools(manager, client2) {
41936
41756
  };
41937
41757
  }
41938
41758
  var builtinTools = {
41939
- lsp_hover,
41940
41759
  lsp_goto_definition,
41941
41760
  lsp_find_references,
41942
- lsp_document_symbols,
41943
- lsp_workspace_symbols,
41761
+ lsp_symbols,
41944
41762
  lsp_diagnostics,
41945
41763
  lsp_servers,
41946
41764
  lsp_prepare_rename,
41947
41765
  lsp_rename,
41948
- lsp_code_actions,
41949
- lsp_code_action_resolve,
41950
41766
  ast_grep_search,
41951
41767
  ast_grep_replace,
41952
41768
  grep,
@@ -42019,6 +41835,8 @@ class ConcurrencyManager {
42019
41835
  }
42020
41836
 
42021
41837
  // src/features/background-agent/manager.ts
41838
+ import { existsSync as existsSync52, readdirSync as readdirSync21 } from "fs";
41839
+ import { join as join60 } from "path";
42022
41840
  var TASK_TTL_MS = 30 * 60 * 1000;
42023
41841
  var MIN_STABILITY_TIME_MS = 10 * 1000;
42024
41842
 
@@ -42487,12 +42305,25 @@ Do NOT poll - continue productive work.
42487
42305
  Use \`background_output(task_id="${task.id}")\` to retrieve this result when ready.
42488
42306
  </system-reminder>`;
42489
42307
  }
42308
+ const messageDir = getMessageDir15(task.parentSessionID);
42309
+ const currentMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
42310
+ const agent = currentMessage?.agent ?? task.parentAgent;
42311
+ const model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
42312
+ log("[background-agent] notifyParentSession context:", {
42313
+ taskId: task.id,
42314
+ messageDir: !!messageDir,
42315
+ currentAgent: currentMessage?.agent,
42316
+ currentModel: currentMessage?.model,
42317
+ resolvedAgent: agent,
42318
+ resolvedModel: model
42319
+ });
42490
42320
  try {
42491
42321
  await this.client.session.prompt({
42492
42322
  path: { id: task.parentSessionID },
42493
42323
  body: {
42494
42324
  noReply: !allComplete,
42495
- agent: task.parentAgent,
42325
+ ...agent !== undefined ? { agent } : {},
42326
+ ...model !== undefined ? { model } : {},
42496
42327
  parts: [{ type: "text", text: notification }]
42497
42328
  }
42498
42329
  });
@@ -42657,6 +42488,19 @@ Use \`background_output(task_id="${task.id}")\` to retrieve this result when rea
42657
42488
  }
42658
42489
  }
42659
42490
  }
42491
+ function getMessageDir15(sessionID) {
42492
+ if (!existsSync52(MESSAGE_STORAGE))
42493
+ return null;
42494
+ const directPath = join60(MESSAGE_STORAGE, sessionID);
42495
+ if (existsSync52(directPath))
42496
+ return directPath;
42497
+ for (const dir of readdirSync21(MESSAGE_STORAGE)) {
42498
+ const sessionPath = join60(MESSAGE_STORAGE, dir, sessionID);
42499
+ if (existsSync52(sessionPath))
42500
+ return sessionPath;
42501
+ }
42502
+ return null;
42503
+ }
42660
42504
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
42661
42505
  function isZ4Schema(s) {
42662
42506
  const schema2 = s;
@@ -45617,7 +45461,6 @@ var DynamicContextPruningConfigSchema = exports_external.object({
45617
45461
  "todowrite",
45618
45462
  "todoread",
45619
45463
  "lsp_rename",
45620
- "lsp_code_action_resolve",
45621
45464
  "session_read",
45622
45465
  "session_write",
45623
45466
  "session_search"
@@ -47868,7 +47711,7 @@ function createMetisAgent(model = DEFAULT_MODEL8) {
47868
47711
  var metisAgent = createMetisAgent();
47869
47712
 
47870
47713
  // src/agents/orchestrator-sisyphus.ts
47871
- init_constants();
47714
+ init_constants2();
47872
47715
  init_permission_compat();
47873
47716
  function buildAgentSelectionSection(agents) {
47874
47717
  if (agents.length === 0) {
@@ -49287,6 +49130,7 @@ function createOrchestratorSisyphusAgent(ctx) {
49287
49130
  temperature: 0.1,
49288
49131
  prompt: buildDynamicOrchestratorPrompt(ctx),
49289
49132
  thinking: { type: "enabled", budgetTokens: 32000 },
49133
+ color: "#10B981",
49290
49134
  ...restrictions
49291
49135
  };
49292
49136
  }
@@ -49646,7 +49490,7 @@ function createMomusAgent(model = DEFAULT_MODEL10) {
49646
49490
  var momusAgent = createMomusAgent();
49647
49491
  // src/agents/utils.ts
49648
49492
  init_shared();
49649
- init_constants();
49493
+ init_constants2();
49650
49494
  var agentSources = {
49651
49495
  Sisyphus: createSisyphusAgent,
49652
49496
  oracle: createOracleAgent,
@@ -49917,7 +49761,7 @@ init_file_utils();
49917
49761
  init_shared();
49918
49762
  init_logger();
49919
49763
  import { promises as fs13 } from "fs";
49920
- import { join as join60, basename as basename6 } from "path";
49764
+ import { join as join62, basename as basename6 } from "path";
49921
49765
  import { homedir as homedir17 } from "os";
49922
49766
  async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
49923
49767
  try {
@@ -49948,7 +49792,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
49948
49792
  if (entry.isDirectory()) {
49949
49793
  if (entry.name.startsWith("."))
49950
49794
  continue;
49951
- const subDirPath = join60(commandsDir, entry.name);
49795
+ const subDirPath = join62(commandsDir, entry.name);
49952
49796
  const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name;
49953
49797
  const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
49954
49798
  commands.push(...subCommands);
@@ -49956,7 +49800,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
49956
49800
  }
49957
49801
  if (!isMarkdownFile(entry))
49958
49802
  continue;
49959
- const commandPath = join60(commandsDir, entry.name);
49803
+ const commandPath = join62(commandsDir, entry.name);
49960
49804
  const baseCommandName = basename6(entry.name, ".md");
49961
49805
  const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName;
49962
49806
  try {
@@ -50003,22 +49847,22 @@ function commandsToRecord(commands) {
50003
49847
  return result;
50004
49848
  }
50005
49849
  async function loadUserCommands() {
50006
- const userCommandsDir = join60(getClaudeConfigDir(), "commands");
49850
+ const userCommandsDir = join62(getClaudeConfigDir(), "commands");
50007
49851
  const commands = await loadCommandsFromDir(userCommandsDir, "user");
50008
49852
  return commandsToRecord(commands);
50009
49853
  }
50010
49854
  async function loadProjectCommands() {
50011
- const projectCommandsDir = join60(process.cwd(), ".claude", "commands");
49855
+ const projectCommandsDir = join62(process.cwd(), ".claude", "commands");
50012
49856
  const commands = await loadCommandsFromDir(projectCommandsDir, "project");
50013
49857
  return commandsToRecord(commands);
50014
49858
  }
50015
49859
  async function loadOpencodeGlobalCommands() {
50016
- const opencodeCommandsDir = join60(homedir17(), ".config", "opencode", "command");
49860
+ const opencodeCommandsDir = join62(homedir17(), ".config", "opencode", "command");
50017
49861
  const commands = await loadCommandsFromDir(opencodeCommandsDir, "opencode");
50018
49862
  return commandsToRecord(commands);
50019
49863
  }
50020
49864
  async function loadOpencodeProjectCommands() {
50021
- const opencodeProjectDir = join60(process.cwd(), ".opencode", "command");
49865
+ const opencodeProjectDir = join62(process.cwd(), ".opencode", "command");
50022
49866
  const commands = await loadCommandsFromDir(opencodeProjectDir, "opencode-project");
50023
49867
  return commandsToRecord(commands);
50024
49868
  }
@@ -50142,13 +49986,13 @@ If \`--create-new\`: Read all existing first (preserve context) \u2192 then dele
50142
49986
  lsp_servers() # Check availability
50143
49987
 
50144
49988
  # Entry points (parallel)
50145
- lsp_document_symbols(filePath="src/index.ts")
50146
- lsp_document_symbols(filePath="main.py")
49989
+ lsp_symbols(filePath="src/index.ts", scope="document")
49990
+ lsp_symbols(filePath="main.py", scope="document")
50147
49991
 
50148
49992
  # Key symbols (parallel)
50149
- lsp_workspace_symbols(filePath=".", query="class")
50150
- lsp_workspace_symbols(filePath=".", query="interface")
50151
- lsp_workspace_symbols(filePath=".", query="function")
49993
+ lsp_symbols(filePath=".", scope="workspace", query="class")
49994
+ lsp_symbols(filePath=".", scope="workspace", query="interface")
49995
+ lsp_symbols(filePath=".", scope="workspace", query="function")
50152
49996
 
50153
49997
  # Centrality for top exports
50154
49998
  lsp_find_references(filePath="...", line=X, character=Y)
@@ -50514,20 +50358,15 @@ While background agents are running, use direct tools:
50514
50358
  ### LSP Tools for Precise Analysis:
50515
50359
 
50516
50360
  \`\`\`typescript
50517
- // Get symbol information at target location
50518
- lsp_hover(filePath, line, character) // Type info, docs, signatures
50519
-
50520
50361
  // Find definition(s)
50521
50362
  lsp_goto_definition(filePath, line, character) // Where is it defined?
50522
50363
 
50523
50364
  // Find ALL usages across workspace
50524
50365
  lsp_find_references(filePath, line, character, includeDeclaration=true)
50525
50366
 
50526
- // Get file structure
50527
- lsp_document_symbols(filePath) // Hierarchical outline
50528
-
50529
- // Search symbols by name
50530
- lsp_workspace_symbols(filePath, query="[target_symbol]")
50367
+ // Get file structure (scope='document') or search symbols (scope='workspace')
50368
+ lsp_symbols(filePath, scope="document") // Hierarchical outline
50369
+ lsp_symbols(filePath, scope="workspace", query="[target_symbol]") // Search by name
50531
50370
 
50532
50371
  // Get current diagnostics
50533
50372
  lsp_diagnostics(filePath) // Errors, warnings before we start
@@ -50959,7 +50798,7 @@ You already know these tools. Use them intelligently:
50959
50798
 
50960
50799
  ## LSP Tools
50961
50800
  Leverage the full LSP toolset (\`lsp_*\`) for precision analysis. Key patterns:
50962
- - **Understand before changing**: \`lsp_hover\`, \`lsp_goto_definition\` to grasp context
50801
+ - **Understand before changing**: \`lsp_goto_definition\` to grasp context
50963
50802
  - **Impact analysis**: \`lsp_find_references\` to map all usages before modification
50964
50803
  - **Safe refactoring**: \`lsp_prepare_rename\` \u2192 \`lsp_rename\` for symbol renames
50965
50804
  - **Continuous verification**: \`lsp_diagnostics\` after every change
@@ -51133,8 +50972,8 @@ function loadBuiltinCommands(disabledCommands) {
51133
50972
  init_frontmatter();
51134
50973
  init_file_utils();
51135
50974
  init_shared();
51136
- import { existsSync as existsSync53, readdirSync as readdirSync20, readFileSync as readFileSync33 } from "fs";
51137
- import { join as join61, basename as basename7 } from "path";
50975
+ import { existsSync as existsSync54, readdirSync as readdirSync22, readFileSync as readFileSync33 } from "fs";
50976
+ import { join as join63, basename as basename7 } from "path";
51138
50977
  function parseToolsConfig(toolsStr) {
51139
50978
  if (!toolsStr)
51140
50979
  return;
@@ -51148,15 +50987,15 @@ function parseToolsConfig(toolsStr) {
51148
50987
  return result;
51149
50988
  }
51150
50989
  function loadAgentsFromDir(agentsDir, scope) {
51151
- if (!existsSync53(agentsDir)) {
50990
+ if (!existsSync54(agentsDir)) {
51152
50991
  return [];
51153
50992
  }
51154
- const entries = readdirSync20(agentsDir, { withFileTypes: true });
50993
+ const entries = readdirSync22(agentsDir, { withFileTypes: true });
51155
50994
  const agents = [];
51156
50995
  for (const entry of entries) {
51157
50996
  if (!isMarkdownFile(entry))
51158
50997
  continue;
51159
- const agentPath = join61(agentsDir, entry.name);
50998
+ const agentPath = join63(agentsDir, entry.name);
51160
50999
  const agentName = basename7(entry.name, ".md");
51161
51000
  try {
51162
51001
  const content = readFileSync33(agentPath, "utf-8");
@@ -51186,7 +51025,7 @@ function loadAgentsFromDir(agentsDir, scope) {
51186
51025
  return agents;
51187
51026
  }
51188
51027
  function loadUserAgents() {
51189
- const userAgentsDir = join61(getClaudeConfigDir(), "agents");
51028
+ const userAgentsDir = join63(getClaudeConfigDir(), "agents");
51190
51029
  const agents = loadAgentsFromDir(userAgentsDir, "user");
51191
51030
  const result = {};
51192
51031
  for (const agent of agents) {
@@ -51195,7 +51034,7 @@ function loadUserAgents() {
51195
51034
  return result;
51196
51035
  }
51197
51036
  function loadProjectAgents() {
51198
- const projectAgentsDir = join61(process.cwd(), ".claude", "agents");
51037
+ const projectAgentsDir = join63(process.cwd(), ".claude", "agents");
51199
51038
  const agents = loadAgentsFromDir(projectAgentsDir, "project");
51200
51039
  const result = {};
51201
51040
  for (const agent of agents) {
@@ -51207,18 +51046,18 @@ function loadProjectAgents() {
51207
51046
  init_frontmatter();
51208
51047
  init_file_utils();
51209
51048
  init_logger();
51210
- import { existsSync as existsSync54, readdirSync as readdirSync21, readFileSync as readFileSync34 } from "fs";
51049
+ import { existsSync as existsSync55, readdirSync as readdirSync23, readFileSync as readFileSync34 } from "fs";
51211
51050
  import { homedir as homedir18 } from "os";
51212
- import { join as join62, basename as basename8 } from "path";
51051
+ import { join as join64, basename as basename8 } from "path";
51213
51052
  var CLAUDE_PLUGIN_ROOT_VAR = "${CLAUDE_PLUGIN_ROOT}";
51214
51053
  function getPluginsBaseDir() {
51215
51054
  if (process.env.CLAUDE_PLUGINS_HOME) {
51216
51055
  return process.env.CLAUDE_PLUGINS_HOME;
51217
51056
  }
51218
- return join62(homedir18(), ".claude", "plugins");
51057
+ return join64(homedir18(), ".claude", "plugins");
51219
51058
  }
51220
51059
  function getInstalledPluginsPath() {
51221
- return join62(getPluginsBaseDir(), "installed_plugins.json");
51060
+ return join64(getPluginsBaseDir(), "installed_plugins.json");
51222
51061
  }
51223
51062
  function resolvePluginPath(path9, pluginRoot) {
51224
51063
  return path9.replace(CLAUDE_PLUGIN_ROOT_VAR, pluginRoot);
@@ -51243,7 +51082,7 @@ function resolvePluginPaths(obj, pluginRoot) {
51243
51082
  }
51244
51083
  function loadInstalledPlugins() {
51245
51084
  const dbPath = getInstalledPluginsPath();
51246
- if (!existsSync54(dbPath)) {
51085
+ if (!existsSync55(dbPath)) {
51247
51086
  return null;
51248
51087
  }
51249
51088
  try {
@@ -51258,11 +51097,11 @@ function getClaudeSettingsPath() {
51258
51097
  if (process.env.CLAUDE_SETTINGS_PATH) {
51259
51098
  return process.env.CLAUDE_SETTINGS_PATH;
51260
51099
  }
51261
- return join62(homedir18(), ".claude", "settings.json");
51100
+ return join64(homedir18(), ".claude", "settings.json");
51262
51101
  }
51263
51102
  function loadClaudeSettings() {
51264
51103
  const settingsPath = getClaudeSettingsPath();
51265
- if (!existsSync54(settingsPath)) {
51104
+ if (!existsSync55(settingsPath)) {
51266
51105
  return null;
51267
51106
  }
51268
51107
  try {
@@ -51274,8 +51113,8 @@ function loadClaudeSettings() {
51274
51113
  }
51275
51114
  }
51276
51115
  function loadPluginManifest(installPath) {
51277
- const manifestPath = join62(installPath, ".claude-plugin", "plugin.json");
51278
- if (!existsSync54(manifestPath)) {
51116
+ const manifestPath = join64(installPath, ".claude-plugin", "plugin.json");
51117
+ if (!existsSync55(manifestPath)) {
51279
51118
  return null;
51280
51119
  }
51281
51120
  try {
@@ -51326,7 +51165,7 @@ function discoverInstalledPlugins(options) {
51326
51165
  continue;
51327
51166
  }
51328
51167
  const { installPath, scope, version: version2 } = installation;
51329
- if (!existsSync54(installPath)) {
51168
+ if (!existsSync55(installPath)) {
51330
51169
  errors3.push({
51331
51170
  pluginKey,
51332
51171
  installPath,
@@ -51344,21 +51183,21 @@ function discoverInstalledPlugins(options) {
51344
51183
  pluginKey,
51345
51184
  manifest: manifest ?? undefined
51346
51185
  };
51347
- if (existsSync54(join62(installPath, "commands"))) {
51348
- loadedPlugin.commandsDir = join62(installPath, "commands");
51186
+ if (existsSync55(join64(installPath, "commands"))) {
51187
+ loadedPlugin.commandsDir = join64(installPath, "commands");
51349
51188
  }
51350
- if (existsSync54(join62(installPath, "agents"))) {
51351
- loadedPlugin.agentsDir = join62(installPath, "agents");
51189
+ if (existsSync55(join64(installPath, "agents"))) {
51190
+ loadedPlugin.agentsDir = join64(installPath, "agents");
51352
51191
  }
51353
- if (existsSync54(join62(installPath, "skills"))) {
51354
- loadedPlugin.skillsDir = join62(installPath, "skills");
51192
+ if (existsSync55(join64(installPath, "skills"))) {
51193
+ loadedPlugin.skillsDir = join64(installPath, "skills");
51355
51194
  }
51356
- const hooksPath = join62(installPath, "hooks", "hooks.json");
51357
- if (existsSync54(hooksPath)) {
51195
+ const hooksPath = join64(installPath, "hooks", "hooks.json");
51196
+ if (existsSync55(hooksPath)) {
51358
51197
  loadedPlugin.hooksPath = hooksPath;
51359
51198
  }
51360
- const mcpPath = join62(installPath, ".mcp.json");
51361
- if (existsSync54(mcpPath)) {
51199
+ const mcpPath = join64(installPath, ".mcp.json");
51200
+ if (existsSync55(mcpPath)) {
51362
51201
  loadedPlugin.mcpPath = mcpPath;
51363
51202
  }
51364
51203
  plugins.push(loadedPlugin);
@@ -51369,13 +51208,13 @@ function discoverInstalledPlugins(options) {
51369
51208
  function loadPluginCommands(plugins) {
51370
51209
  const commands2 = {};
51371
51210
  for (const plugin of plugins) {
51372
- if (!plugin.commandsDir || !existsSync54(plugin.commandsDir))
51211
+ if (!plugin.commandsDir || !existsSync55(plugin.commandsDir))
51373
51212
  continue;
51374
- const entries = readdirSync21(plugin.commandsDir, { withFileTypes: true });
51213
+ const entries = readdirSync23(plugin.commandsDir, { withFileTypes: true });
51375
51214
  for (const entry of entries) {
51376
51215
  if (!isMarkdownFile(entry))
51377
51216
  continue;
51378
- const commandPath = join62(plugin.commandsDir, entry.name);
51217
+ const commandPath = join64(plugin.commandsDir, entry.name);
51379
51218
  const commandName = basename8(entry.name, ".md");
51380
51219
  const namespacedName = `${plugin.name}:${commandName}`;
51381
51220
  try {
@@ -51411,18 +51250,18 @@ $ARGUMENTS
51411
51250
  function loadPluginSkillsAsCommands(plugins) {
51412
51251
  const skills = {};
51413
51252
  for (const plugin of plugins) {
51414
- if (!plugin.skillsDir || !existsSync54(plugin.skillsDir))
51253
+ if (!plugin.skillsDir || !existsSync55(plugin.skillsDir))
51415
51254
  continue;
51416
- const entries = readdirSync21(plugin.skillsDir, { withFileTypes: true });
51255
+ const entries = readdirSync23(plugin.skillsDir, { withFileTypes: true });
51417
51256
  for (const entry of entries) {
51418
51257
  if (entry.name.startsWith("."))
51419
51258
  continue;
51420
- const skillPath = join62(plugin.skillsDir, entry.name);
51259
+ const skillPath = join64(plugin.skillsDir, entry.name);
51421
51260
  if (!entry.isDirectory() && !entry.isSymbolicLink())
51422
51261
  continue;
51423
51262
  const resolvedPath = resolveSymlink(skillPath);
51424
- const skillMdPath = join62(resolvedPath, "SKILL.md");
51425
- if (!existsSync54(skillMdPath))
51263
+ const skillMdPath = join64(resolvedPath, "SKILL.md");
51264
+ if (!existsSync55(skillMdPath))
51426
51265
  continue;
51427
51266
  try {
51428
51267
  const content = readFileSync34(skillMdPath, "utf-8");
@@ -51472,13 +51311,13 @@ function parseToolsConfig2(toolsStr) {
51472
51311
  function loadPluginAgents(plugins) {
51473
51312
  const agents = {};
51474
51313
  for (const plugin of plugins) {
51475
- if (!plugin.agentsDir || !existsSync54(plugin.agentsDir))
51314
+ if (!plugin.agentsDir || !existsSync55(plugin.agentsDir))
51476
51315
  continue;
51477
- const entries = readdirSync21(plugin.agentsDir, { withFileTypes: true });
51316
+ const entries = readdirSync23(plugin.agentsDir, { withFileTypes: true });
51478
51317
  for (const entry of entries) {
51479
51318
  if (!isMarkdownFile(entry))
51480
51319
  continue;
51481
- const agentPath = join62(plugin.agentsDir, entry.name);
51320
+ const agentPath = join64(plugin.agentsDir, entry.name);
51482
51321
  const agentName = basename8(entry.name, ".md");
51483
51322
  const namespacedName = `${plugin.name}:${agentName}`;
51484
51323
  try {
@@ -51508,7 +51347,7 @@ function loadPluginAgents(plugins) {
51508
51347
  async function loadPluginMcpServers(plugins) {
51509
51348
  const servers = {};
51510
51349
  for (const plugin of plugins) {
51511
- if (!plugin.mcpPath || !existsSync54(plugin.mcpPath))
51350
+ if (!plugin.mcpPath || !existsSync55(plugin.mcpPath))
51512
51351
  continue;
51513
51352
  try {
51514
51353
  const content = await Bun.file(plugin.mcpPath).text();
@@ -51540,7 +51379,7 @@ async function loadPluginMcpServers(plugins) {
51540
51379
  function loadPluginHooksConfigs(plugins) {
51541
51380
  const configs = [];
51542
51381
  for (const plugin of plugins) {
51543
- if (!plugin.hooksPath || !existsSync54(plugin.hooksPath))
51382
+ if (!plugin.hooksPath || !existsSync55(plugin.hooksPath))
51544
51383
  continue;
51545
51384
  try {
51546
51385
  const content = readFileSync34(plugin.hooksPath, "utf-8");
@@ -52080,6 +51919,7 @@ sisyphus_task(agent="librarian", prompt="Find open source implementations of [fe
52080
51919
  - Maintain conversational tone
52081
51920
  - Use gathered evidence to inform suggestions
52082
51921
  - Ask questions that help user articulate needs
51922
+ - **Use the \`Question\` tool when presenting multiple options** (structured UI for selection)
52083
51923
  - Confirm understanding before proceeding
52084
51924
  - **Update draft file after EVERY meaningful exchange** (see Rule 6)
52085
51925
 
@@ -52585,7 +52425,7 @@ var PROMETHEUS_PERMISSION = {
52585
52425
  };
52586
52426
 
52587
52427
  // src/plugin-handlers/config-handler.ts
52588
- init_constants();
52428
+ init_constants2();
52589
52429
  function resolveCategoryConfig2(categoryName, userCategories) {
52590
52430
  return userCategories?.[categoryName] ?? DEFAULT_CATEGORIES[categoryName];
52591
52431
  }
@@ -52690,7 +52530,7 @@ function createConfigHandler(deps) {
52690
52530
  value ? migrateAgentConfig(value) : value
52691
52531
  ])) : {};
52692
52532
  const migratedBuild = configAgent?.build ? migrateAgentConfig(configAgent.build) : {};
52693
- const planDemoteConfig = replacePlan ? { mode: "subagent", hidden: true } : undefined;
52533
+ const planDemoteConfig = replacePlan ? { mode: "subagent" } : undefined;
52694
52534
  config3.agent = {
52695
52535
  ...agentConfig,
52696
52536
  ...Object.fromEntries(Object.entries(builtinAgents).filter(([k]) => k !== "Sisyphus")),
@@ -52735,6 +52575,12 @@ function createConfigHandler(deps) {
52735
52575
  call_omo_agent: false
52736
52576
  };
52737
52577
  }
52578
+ if (agentResult["Prometheus (Planner)"]) {
52579
+ agentResult["Prometheus (Planner)"].tools = {
52580
+ ...agentResult["Prometheus (Planner)"].tools,
52581
+ call_omo_agent: false
52582
+ };
52583
+ }
52738
52584
  config3.permission = {
52739
52585
  ...config3.permission,
52740
52586
  webfetch: "allow",