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/README.ja.md +55 -29
- package/README.md +60 -30
- package/README.zh-cn.md +54 -29
- package/dist/agents/prometheus-prompt.d.ts +1 -1
- package/dist/cli/index.js +104 -109
- package/dist/cli/types.d.ts +3 -0
- package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
- package/dist/features/builtin-commands/templates/refactor.d.ts +1 -1
- package/dist/index.js +564 -718
- package/dist/shared/migration.d.ts +1 -0
- package/dist/tools/lsp/tools.d.ts +1 -5
- package/package.json +3 -3
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
20988
|
-
import { join as
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
21129
|
+
const userSkillsDir = join44(getClaudeConfigDir(), "skills");
|
|
21179
21130
|
return loadSkillsFromDir(userSkillsDir, "user");
|
|
21180
21131
|
}
|
|
21181
21132
|
async function discoverProjectClaudeSkills() {
|
|
21182
|
-
const projectSkillsDir =
|
|
21133
|
+
const projectSkillsDir = join44(process.cwd(), ".claude", "skills");
|
|
21183
21134
|
return loadSkillsFromDir(projectSkillsDir, "project");
|
|
21184
21135
|
}
|
|
21185
21136
|
async function discoverOpencodeGlobalSkills() {
|
|
21186
|
-
const opencodeSkillsDir =
|
|
21137
|
+
const opencodeSkillsDir = join44(homedir12(), ".config", "opencode", "skill");
|
|
21187
21138
|
return loadSkillsFromDir(opencodeSkillsDir, "opencode");
|
|
21188
21139
|
}
|
|
21189
21140
|
async function discoverOpencodeProjectSkills() {
|
|
21190
|
-
const opencodeProjectDir =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
22716
|
-
const projectCommandsDir =
|
|
22717
|
-
const opencodeGlobalDir =
|
|
22718
|
-
const opencodeProjectDir =
|
|
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
|
|
22896
|
-
import { join as
|
|
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
|
|
22892
|
+
function getMessageDir10(sessionID) {
|
|
22942
22893
|
if (!existsSync37(MESSAGE_STORAGE))
|
|
22943
22894
|
return null;
|
|
22944
|
-
const directPath =
|
|
22895
|
+
const directPath = join46(MESSAGE_STORAGE, sessionID);
|
|
22945
22896
|
if (existsSync37(directPath))
|
|
22946
22897
|
return directPath;
|
|
22947
|
-
for (const dir of
|
|
22948
|
-
const sessionPath =
|
|
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 =
|
|
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
|
|
23054
|
-
import { dirname as dirname9, join as
|
|
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
|
|
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 =
|
|
23047
|
+
const plansDir = join47(directory, PROMETHEUS_PLANS_DIR);
|
|
23097
23048
|
if (!existsSync38(plansDir)) {
|
|
23098
23049
|
return [];
|
|
23099
23050
|
}
|
|
23100
23051
|
try {
|
|
23101
|
-
const files =
|
|
23102
|
-
return files.filter((f) => f.endsWith(".md")).map((f) =>
|
|
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
|
|
23257
|
-
import { join as
|
|
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
|
|
23477
|
+
function getMessageDir11(sessionID) {
|
|
23527
23478
|
if (!existsSync39(MESSAGE_STORAGE))
|
|
23528
23479
|
return null;
|
|
23529
|
-
const directPath =
|
|
23480
|
+
const directPath = join48(MESSAGE_STORAGE, sessionID);
|
|
23530
23481
|
if (existsSync39(directPath))
|
|
23531
23482
|
return directPath;
|
|
23532
|
-
for (const dir of
|
|
23533
|
-
const sessionPath =
|
|
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 =
|
|
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
|
|
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:
|
|
24082
|
-
{ path:
|
|
24083
|
-
{ path:
|
|
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
|
|
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:
|
|
24553
|
-
user:
|
|
24554
|
-
opencode:
|
|
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(
|
|
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
|
-
|
|
24683
|
-
|
|
24684
|
-
|
|
24685
|
-
|
|
24686
|
-
|
|
24687
|
-
|
|
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
|
|
38040
|
-
description: "Get
|
|
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
|
|
38047
|
-
|
|
38048
|
-
|
|
38049
|
-
|
|
38050
|
-
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
|
|
38055
|
-
|
|
38056
|
-
|
|
38057
|
-
|
|
38058
|
-
|
|
38059
|
-
|
|
38060
|
-
|
|
38061
|
-
lines
|
|
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
|
-
|
|
38064
|
-
|
|
38065
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 ||
|
|
38316
|
-
return
|
|
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 ||
|
|
38320
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
38805
|
-
import { join as
|
|
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 =
|
|
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
|
|
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
|
|
38647
|
+
return join53(homeDir, ".cache", "oh-my-opencode", "bin");
|
|
38834
38648
|
}
|
|
38835
38649
|
function getRgPath() {
|
|
38836
38650
|
const isWindows2 = process.platform === "win32";
|
|
38837
|
-
return
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
38943
|
-
|
|
38944
|
-
|
|
38945
|
-
|
|
38946
|
-
|
|
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
|
|
39412
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
39452
|
-
const projectCommandsDir =
|
|
39453
|
-
const opencodeGlobalDir =
|
|
39454
|
-
const opencodeProjectDir =
|
|
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
|
|
39431
|
+
import { join as join56 } from "path";
|
|
39618
39432
|
var OPENCODE_STORAGE9 = getOpenCodeStorageDir();
|
|
39619
|
-
var MESSAGE_STORAGE4 =
|
|
39620
|
-
var PART_STORAGE4 =
|
|
39621
|
-
var SESSION_STORAGE =
|
|
39622
|
-
var TODO_DIR2 =
|
|
39623
|
-
var TRANSCRIPT_DIR2 =
|
|
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
|
|
39510
|
+
import { existsSync as existsSync49, readdirSync as readdirSync18 } from "fs";
|
|
39697
39511
|
import { readdir, readFile } from "fs/promises";
|
|
39698
|
-
import { join as
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
39570
|
+
function getMessageDir12(sessionID) {
|
|
39757
39571
|
if (!existsSync49(MESSAGE_STORAGE4))
|
|
39758
39572
|
return "";
|
|
39759
|
-
const directPath =
|
|
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
|
|
39765
|
-
const sessionPath =
|
|
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
|
|
39590
|
+
return getMessageDir12(sessionID) !== "";
|
|
39777
39591
|
}
|
|
39778
39592
|
async function readSessionMessages(sessionID) {
|
|
39779
|
-
const messageDir =
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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
|
|
40922
|
-
import { join as
|
|
40735
|
+
import { existsSync as existsSync50, readdirSync as readdirSync19 } from "fs";
|
|
40736
|
+
import { join as join58 } from "path";
|
|
40923
40737
|
init_logger();
|
|
40924
|
-
function
|
|
40738
|
+
function getMessageDir13(sessionID) {
|
|
40925
40739
|
if (!existsSync50(MESSAGE_STORAGE))
|
|
40926
40740
|
return null;
|
|
40927
|
-
const directPath =
|
|
40741
|
+
const directPath = join58(MESSAGE_STORAGE, sessionID);
|
|
40928
40742
|
if (existsSync50(directPath))
|
|
40929
40743
|
return directPath;
|
|
40930
|
-
for (const dir of
|
|
40931
|
-
const sessionPath =
|
|
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 =
|
|
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
|
-
|
|
41309
|
-
import { existsSync as existsSync51, readdirSync as
|
|
41310
|
-
import { join as
|
|
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
|
|
41275
|
+
function getMessageDir14(sessionID) {
|
|
41462
41276
|
if (!existsSync51(MESSAGE_STORAGE))
|
|
41463
41277
|
return null;
|
|
41464
|
-
const directPath =
|
|
41278
|
+
const directPath = join59(MESSAGE_STORAGE, sessionID);
|
|
41465
41279
|
if (existsSync51(directPath))
|
|
41466
41280
|
return directPath;
|
|
41467
|
-
for (const dir of
|
|
41468
|
-
const sessionPath =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
50146
|
-
|
|
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
|
-
|
|
50150
|
-
|
|
50151
|
-
|
|
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
|
-
|
|
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**: \`
|
|
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
|
|
51137
|
-
import { join as
|
|
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 (!
|
|
50990
|
+
if (!existsSync54(agentsDir)) {
|
|
51152
50991
|
return [];
|
|
51153
50992
|
}
|
|
51154
|
-
const entries =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
51057
|
+
return join64(homedir18(), ".claude", "plugins");
|
|
51219
51058
|
}
|
|
51220
51059
|
function getInstalledPluginsPath() {
|
|
51221
|
-
return
|
|
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 (!
|
|
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
|
|
51100
|
+
return join64(homedir18(), ".claude", "settings.json");
|
|
51262
51101
|
}
|
|
51263
51102
|
function loadClaudeSettings() {
|
|
51264
51103
|
const settingsPath = getClaudeSettingsPath();
|
|
51265
|
-
if (!
|
|
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 =
|
|
51278
|
-
if (!
|
|
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 (!
|
|
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 (
|
|
51348
|
-
loadedPlugin.commandsDir =
|
|
51186
|
+
if (existsSync55(join64(installPath, "commands"))) {
|
|
51187
|
+
loadedPlugin.commandsDir = join64(installPath, "commands");
|
|
51349
51188
|
}
|
|
51350
|
-
if (
|
|
51351
|
-
loadedPlugin.agentsDir =
|
|
51189
|
+
if (existsSync55(join64(installPath, "agents"))) {
|
|
51190
|
+
loadedPlugin.agentsDir = join64(installPath, "agents");
|
|
51352
51191
|
}
|
|
51353
|
-
if (
|
|
51354
|
-
loadedPlugin.skillsDir =
|
|
51192
|
+
if (existsSync55(join64(installPath, "skills"))) {
|
|
51193
|
+
loadedPlugin.skillsDir = join64(installPath, "skills");
|
|
51355
51194
|
}
|
|
51356
|
-
const hooksPath =
|
|
51357
|
-
if (
|
|
51195
|
+
const hooksPath = join64(installPath, "hooks", "hooks.json");
|
|
51196
|
+
if (existsSync55(hooksPath)) {
|
|
51358
51197
|
loadedPlugin.hooksPath = hooksPath;
|
|
51359
51198
|
}
|
|
51360
|
-
const mcpPath =
|
|
51361
|
-
if (
|
|
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 || !
|
|
51211
|
+
if (!plugin.commandsDir || !existsSync55(plugin.commandsDir))
|
|
51373
51212
|
continue;
|
|
51374
|
-
const entries =
|
|
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 =
|
|
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 || !
|
|
51253
|
+
if (!plugin.skillsDir || !existsSync55(plugin.skillsDir))
|
|
51415
51254
|
continue;
|
|
51416
|
-
const entries =
|
|
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 =
|
|
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 =
|
|
51425
|
-
if (!
|
|
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 || !
|
|
51314
|
+
if (!plugin.agentsDir || !existsSync55(plugin.agentsDir))
|
|
51476
51315
|
continue;
|
|
51477
|
-
const entries =
|
|
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 =
|
|
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 || !
|
|
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 || !
|
|
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
|
-
|
|
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"
|
|
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",
|