fix: remove all hardcoded user paths from plugins — dynamic SDK resolution
- plugins/macp/src/index.ts: use createRequire + dynamic import() for OC SDK - plugins/macp/src/acp-runtime-types.ts: local ACP runtime type definitions - plugins/macp/src/macp-runtime.ts: DEFAULT_REPO_ROOT and PI_RUNNER_PATH use os.homedir() instead of hardcoded /home/user/ - plugins/mosaic-framework/src/index.ts: removed hardcoded SDK import - No hardcoded /home/ paths remain in any plugin source file - Plugin works on any machine with openclaw installed globally
This commit is contained in:
68
plugins/macp/src/acp-runtime-types.ts
Normal file
68
plugins/macp/src/acp-runtime-types.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
* ACP Runtime type definitions.
|
||||||
|
*
|
||||||
|
* These mirror the OpenClaw plugin SDK AcpRuntime types.
|
||||||
|
* Defined locally so the plugin compiles without hardcoded SDK paths.
|
||||||
|
* The OC plugin loader provides the actual SDK at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface AcpRuntimeCapabilities {
|
||||||
|
controls: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeEnsureInput {
|
||||||
|
sessionKey: string;
|
||||||
|
agent: string;
|
||||||
|
mode: 'oneshot' | 'session';
|
||||||
|
cwd?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeHandle {
|
||||||
|
sessionKey: string;
|
||||||
|
backend: string;
|
||||||
|
runtimeSessionName: string;
|
||||||
|
cwd: string;
|
||||||
|
backendSessionId: string;
|
||||||
|
agentSessionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeEvent {
|
||||||
|
type: 'text_delta' | 'status' | 'done' | 'error';
|
||||||
|
text?: string;
|
||||||
|
stream?: string;
|
||||||
|
tag?: string;
|
||||||
|
stopReason?: string;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeTurnInput {
|
||||||
|
handle: AcpRuntimeHandle;
|
||||||
|
text: string;
|
||||||
|
requestId: string;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeStatus {
|
||||||
|
summary: string;
|
||||||
|
backendSessionId: string;
|
||||||
|
agentSessionId: string;
|
||||||
|
details?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntimeDoctorReport {
|
||||||
|
ok: boolean;
|
||||||
|
code?: string;
|
||||||
|
message: string;
|
||||||
|
details?: string[];
|
||||||
|
installCommand?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AcpRuntime {
|
||||||
|
ensureSession(input: AcpRuntimeEnsureInput): Promise<AcpRuntimeHandle>;
|
||||||
|
runTurn(input: AcpRuntimeTurnInput): AsyncIterable<AcpRuntimeEvent>;
|
||||||
|
getCapabilities(): AcpRuntimeCapabilities;
|
||||||
|
getStatus(input: { handle: AcpRuntimeHandle }): Promise<AcpRuntimeStatus>;
|
||||||
|
doctor(): Promise<AcpRuntimeDoctorReport>;
|
||||||
|
cancel(input: { handle: AcpRuntimeHandle; reason?: string }): Promise<void>;
|
||||||
|
close(input: { handle: AcpRuntimeHandle; reason: string }): Promise<void>;
|
||||||
|
}
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
|
import { createRequire } from 'node:module';
|
||||||
import * as os from 'node:os';
|
import * as os from 'node:os';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
|
||||||
import {
|
|
||||||
registerAcpRuntimeBackend,
|
|
||||||
unregisterAcpRuntimeBackend,
|
|
||||||
} from '/home/woltjejason/.npm-global/lib/node_modules/openclaw/dist/plugin-sdk/acp-runtime.js';
|
|
||||||
import type { OpenClawPluginApi } from '/home/woltjejason/.npm-global/lib/node_modules/openclaw/dist/plugin-sdk/index.js';
|
|
||||||
import type {
|
|
||||||
OpenClawPluginService,
|
|
||||||
OpenClawPluginServiceContext,
|
|
||||||
} from '/home/woltjejason/.npm-global/lib/node_modules/openclaw/dist/plugin-sdk/src/plugins/types.js';
|
|
||||||
|
|
||||||
import { MacpRuntime } from './macp-runtime.js';
|
import { MacpRuntime } from './macp-runtime.js';
|
||||||
|
|
||||||
|
// Resolve OC plugin SDK dynamically — works on any machine with openclaw installed globally
|
||||||
|
const ocRequire = createRequire(import.meta.url);
|
||||||
|
const sdkRoot = path.dirname(ocRequire.resolve('openclaw/dist/plugin-sdk/index.js'));
|
||||||
|
|
||||||
|
// Dynamic imports for runtime SDK functions
|
||||||
|
const { registerAcpRuntimeBackend, unregisterAcpRuntimeBackend } = await import(
|
||||||
|
`${sdkRoot}/acp-runtime.js`
|
||||||
|
) as {
|
||||||
|
registerAcpRuntimeBackend: (backend: { id: string; runtime: any; healthy: () => boolean }) => void;
|
||||||
|
unregisterAcpRuntimeBackend: (id: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
defaultModel?: string;
|
defaultModel?: string;
|
||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
@@ -38,7 +41,7 @@ function resolveConfig(pluginConfig?: Record<string, unknown>, stateDir?: string
|
|||||||
const config = (pluginConfig ?? {}) as PluginConfig;
|
const config = (pluginConfig ?? {}) as PluginConfig;
|
||||||
const repoRoot = config.repoRoot?.trim()
|
const repoRoot = config.repoRoot?.trim()
|
||||||
? path.resolve(expandHome(config.repoRoot))
|
? path.resolve(expandHome(config.repoRoot))
|
||||||
: path.resolve('/home/woltjejason/src/mosaic-stack-new');
|
: path.resolve(os.homedir(), 'src', 'mosaic-stack');
|
||||||
return {
|
return {
|
||||||
defaultModel: config.defaultModel?.trim() || 'openai/gpt-5-mini',
|
defaultModel: config.defaultModel?.trim() || 'openai/gpt-5-mini',
|
||||||
systemPrompt: config.systemPrompt ?? '',
|
systemPrompt: config.systemPrompt ?? '',
|
||||||
@@ -60,12 +63,12 @@ function resolveConfig(pluginConfig?: Record<string, unknown>, stateDir?: string
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMacpRuntimeService(pluginConfig?: Record<string, unknown>): OpenClawPluginService {
|
function createMacpRuntimeService(pluginConfig?: Record<string, unknown>) {
|
||||||
let runtime: MacpRuntime | null = null;
|
let runtime: MacpRuntime | null = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: 'macp-runtime',
|
id: 'macp-runtime',
|
||||||
async start(ctx: OpenClawPluginServiceContext) {
|
async start(ctx: { stateDir: string; logger: { info: (msg: string) => void } }) {
|
||||||
const resolved = resolveConfig(pluginConfig, ctx.stateDir);
|
const resolved = resolveConfig(pluginConfig, ctx.stateDir);
|
||||||
runtime = new MacpRuntime({
|
runtime = new MacpRuntime({
|
||||||
...resolved,
|
...resolved,
|
||||||
@@ -80,21 +83,16 @@ function createMacpRuntimeService(pluginConfig?: Record<string, unknown>): OpenC
|
|||||||
`macp runtime backend registered (defaultRuntime: ${resolved.defaultRuntime}, defaultDispatch: ${resolved.defaultDispatch}, timeoutMs: ${resolved.timeoutMs})`,
|
`macp runtime backend registered (defaultRuntime: ${resolved.defaultRuntime}, defaultDispatch: ${resolved.defaultDispatch}, timeoutMs: ${resolved.timeoutMs})`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
async stop(_ctx: OpenClawPluginServiceContext) {
|
async stop() {
|
||||||
unregisterAcpRuntimeBackend('macp');
|
if (runtime) {
|
||||||
runtime = null;
|
unregisterAcpRuntimeBackend('macp');
|
||||||
|
runtime = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const plugin = {
|
export default function register(api: any) {
|
||||||
id: 'macp',
|
const service = createMacpRuntimeService(api.pluginConfig);
|
||||||
name: 'MACP Runtime',
|
api.registerService(service);
|
||||||
description:
|
}
|
||||||
'ACP runtime backend that dispatches OpenClaw oneshot sessions through the MACP controller queue.',
|
|
||||||
register(api: OpenClawPluginApi) {
|
|
||||||
api.registerService(createMacpRuntimeService(api.pluginConfig));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default plugin;
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import type {
|
|||||||
AcpRuntimeHandle,
|
AcpRuntimeHandle,
|
||||||
AcpRuntimeStatus,
|
AcpRuntimeStatus,
|
||||||
AcpRuntimeTurnInput,
|
AcpRuntimeTurnInput,
|
||||||
} from '/home/woltjejason/.npm-global/lib/node_modules/openclaw/dist/plugin-sdk/acp-runtime.js';
|
} from './acp-runtime-types.js';
|
||||||
|
|
||||||
export interface MacpRuntimeConfig {
|
export interface MacpRuntimeConfig {
|
||||||
defaultModel: string;
|
defaultModel: string;
|
||||||
@@ -80,9 +80,9 @@ const MACP_CAPABILITIES: AcpRuntimeCapabilities = {
|
|||||||
controls: [],
|
controls: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_REPO_ROOT = '~/src/mosaic-stack-new';
|
const DEFAULT_REPO_ROOT = '~/src/mosaic-stack';
|
||||||
const ORCHESTRATOR_RUN_PATH = '~/.config/mosaic/bin/mosaic-orchestrator-run';
|
const ORCHESTRATOR_RUN_PATH = '~/.config/mosaic/bin/mosaic-orchestrator-run';
|
||||||
const PI_RUNNER_PATH = '/home/woltjejason/src/mosaic-stack-new/tools/macp/dispatcher/pi_runner.ts';
|
const PI_RUNNER_PATH = path.join(os.homedir(), 'src', 'mosaic-stack', 'tools', 'macp', 'dispatcher', 'pi_runner.ts');
|
||||||
|
|
||||||
function expandHome(rawPath: string): string {
|
function expandHome(rawPath: string): string {
|
||||||
if (rawPath === '~') {
|
if (rawPath === '~') {
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
||||||
import type { OpenClawPluginApi } from '/home/woltjejason/.npm-global/lib/node_modules/openclaw/dist/plugin-sdk/index.js';
|
// OpenClawPluginApi type — the OC plugin loader provides the actual api object at runtime
|
||||||
|
type OpenClawPluginApi = any;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Config types
|
// Config types
|
||||||
|
|||||||
Reference in New Issue
Block a user