c09ee32fe9
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
157 lines
4.7 KiB
TypeScript
157 lines
4.7 KiB
TypeScript
import { initConfigContext } from "./cli/config-manager/config-context"
|
|
import type { Plugin } from "@opencode-ai/plugin"
|
|
|
|
import type { HookName } from "./config"
|
|
|
|
import { createHooks } from "./create-hooks"
|
|
import { createManagers } from "./create-managers"
|
|
import { createRuntimeTmuxConfig, isTmuxIntegrationEnabled } from "./create-runtime-tmux-config"
|
|
import { createTools } from "./create-tools"
|
|
import { initializeOpenClaw } from "./openclaw"
|
|
import { createPluginInterface } from "./plugin-interface"
|
|
import { createPluginDispose, type PluginDispose } from "./plugin-dispose"
|
|
|
|
import { loadPluginConfig } from "./plugin-config"
|
|
import { createModelCacheState } from "./plugin-state"
|
|
import { createFirstMessageVariantGate } from "./shared/first-message-variant"
|
|
import { injectServerAuthIntoClient, log, logLegacyPluginStartupWarning } from "./shared"
|
|
import { detectExternalSkillPlugin, getSkillPluginConflictWarning } from "./shared/external-plugin-detector"
|
|
import { startBackgroundCheck as startTmuxCheck } from "./tools/interactive-bash"
|
|
import { lspManager } from "./tools/lsp/client"
|
|
import { createPluginPostHog, getPostHogDistinctId } from "./shared/posthog"
|
|
|
|
let activePluginDispose: PluginDispose | null = null
|
|
|
|
const OhMyOpenCodePlugin: Plugin = async (ctx) => {
|
|
initConfigContext("opencode", null)
|
|
log("[OhMyOpenCodePlugin] ENTRY - plugin loading", {
|
|
directory: ctx.directory,
|
|
})
|
|
logLegacyPluginStartupWarning()
|
|
|
|
const skillPluginCheck = detectExternalSkillPlugin(ctx.directory)
|
|
if (skillPluginCheck.detected && skillPluginCheck.pluginName) {
|
|
console.warn(getSkillPluginConflictWarning(skillPluginCheck.pluginName))
|
|
}
|
|
|
|
injectServerAuthIntoClient(ctx.client)
|
|
await activePluginDispose?.()
|
|
|
|
const pluginConfig = loadPluginConfig(ctx.directory, ctx)
|
|
|
|
const posthog = createPluginPostHog()
|
|
const distinctId = getPostHogDistinctId()
|
|
try {
|
|
posthog.trackActive(distinctId, "plugin_loaded")
|
|
} catch {
|
|
// telemetry failure is non-fatal, silently ignore
|
|
}
|
|
try {
|
|
posthog.capture({
|
|
distinctId,
|
|
event: "plugin_loaded",
|
|
properties: {
|
|
entry_point: "plugin",
|
|
has_openclaw: !!pluginConfig.openclaw,
|
|
tmux_enabled: isTmuxIntegrationEnabled(pluginConfig),
|
|
},
|
|
})
|
|
} catch {
|
|
// telemetry failure is non-fatal, silently ignore
|
|
}
|
|
if (pluginConfig.openclaw) {
|
|
await initializeOpenClaw(pluginConfig.openclaw)
|
|
}
|
|
const tmuxIntegrationEnabled = isTmuxIntegrationEnabled(pluginConfig)
|
|
if (tmuxIntegrationEnabled) {
|
|
startTmuxCheck()
|
|
}
|
|
const disabledHooks = new Set(pluginConfig.disabled_hooks ?? [])
|
|
|
|
const isHookEnabled = (hookName: HookName): boolean => !disabledHooks.has(hookName)
|
|
const safeHookEnabled = pluginConfig.experimental?.safe_hook_creation ?? true
|
|
|
|
const firstMessageVariantGate = createFirstMessageVariantGate()
|
|
|
|
const tmuxConfig = createRuntimeTmuxConfig(pluginConfig)
|
|
|
|
const modelCacheState = createModelCacheState()
|
|
|
|
const managers = createManagers({
|
|
ctx,
|
|
pluginConfig,
|
|
tmuxConfig,
|
|
modelCacheState,
|
|
backgroundNotificationHookEnabled: isHookEnabled("background-notification"),
|
|
})
|
|
|
|
const toolsResult = await createTools({
|
|
ctx,
|
|
pluginConfig,
|
|
managers,
|
|
})
|
|
|
|
const hooks = createHooks({
|
|
ctx,
|
|
pluginConfig,
|
|
modelCacheState,
|
|
backgroundManager: managers.backgroundManager,
|
|
isHookEnabled,
|
|
safeHookEnabled,
|
|
mergedSkills: toolsResult.mergedSkills,
|
|
availableSkills: toolsResult.availableSkills,
|
|
})
|
|
|
|
const dispose = createPluginDispose({
|
|
backgroundManager: managers.backgroundManager,
|
|
skillMcpManager: managers.skillMcpManager,
|
|
lspManager,
|
|
disposeHooks: hooks.disposeHooks,
|
|
})
|
|
|
|
const pluginInterface = createPluginInterface({
|
|
ctx,
|
|
pluginConfig,
|
|
firstMessageVariantGate,
|
|
managers,
|
|
hooks,
|
|
tools: toolsResult.filteredTools,
|
|
})
|
|
|
|
activePluginDispose = dispose
|
|
|
|
return {
|
|
name: "oh-my-openagent",
|
|
...pluginInterface,
|
|
|
|
"experimental.session.compacting": async (
|
|
_input: { sessionID: string },
|
|
output: { context: string[] },
|
|
): Promise<void> => {
|
|
await hooks.compactionContextInjector?.capture(_input.sessionID)
|
|
await hooks.compactionTodoPreserver?.capture(_input.sessionID)
|
|
await hooks.claudeCodeHooks?.["experimental.session.compacting"]?.(
|
|
_input,
|
|
output,
|
|
)
|
|
if (hooks.compactionContextInjector) {
|
|
output.context.push(hooks.compactionContextInjector.inject(_input.sessionID))
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
export default OhMyOpenCodePlugin
|
|
|
|
export type {
|
|
OhMyOpenCodeConfig,
|
|
AgentName,
|
|
AgentOverrideConfig,
|
|
AgentOverrides,
|
|
McpName,
|
|
HookName,
|
|
BuiltinCommandName,
|
|
} from "./config"
|
|
|
|
export type { ConfigLoadError } from "./shared/config-errors"
|