oh-my-opencode/src/shared/command-executor/resolve-commands-in-text.ts
YeonGyu-Kim 119e18c810 refactor: wave 2 - split atlas, auto-update-checker, session-recovery, todo-enforcer, background-task hooks
- Extract atlas/ into 15 focused modules (hook, event handler, tool policies, types, etc.)
- Split auto-update-checker into checker/ and hook/ subdirectories with single-purpose files
- Decompose session-recovery into separate recovery strategy files per error type
- Extract todo-continuation-enforcer from monolith to directory with dedicated modules
- Split background-task/tools.ts into individual tool creator files
- Extract command-executor, tmux-utils into focused sub-modules
- Split config/schema.ts into domain-specific schema files
- Decompose cli/config-manager.ts into focused modules
- Rollback skill-mcp-manager, model-availability, index.ts splits that broke tests
- Fix all import path depths for moved files (../../ -> ../../../)
- Add explicit type annotations to resolve TS7006 implicit any errors

Typecheck: 0 errors
Tests: 2359 pass, 5 fail (all pre-existing)
2026-02-08 15:01:42 +09:00

50 lines
1.1 KiB
TypeScript

import { executeCommand } from "./execute-command"
import { findEmbeddedCommands } from "./embedded-commands"
export async function resolveCommandsInText(
text: string,
depth: number = 0,
maxDepth: number = 3,
): Promise<string> {
if (depth >= maxDepth) {
return text
}
const matches = findEmbeddedCommands(text)
if (matches.length === 0) {
return text
}
const tasks = matches.map((m) => executeCommand(m.command))
const results = await Promise.allSettled(tasks)
const replacements = new Map<string, string>()
matches.forEach((match, idx) => {
const result = results[idx]
if (result.status === "rejected") {
replacements.set(
match.fullMatch,
`[error: ${
result.reason instanceof Error
? result.reason.message
: String(result.reason)
}]`,
)
} else {
replacements.set(match.fullMatch, result.value)
}
})
let resolved = text
for (const [pattern, replacement] of replacements.entries()) {
resolved = resolved.split(pattern).join(replacement)
}
if (findEmbeddedCommands(resolved).length > 0) {
return resolveCommandsInText(resolved, depth + 1, maxDepth)
}
return resolved
}