feat: update install CLI, ESM compat, and Gemini CLI docs

Fixes CursorHooksInstaller ESM compatibility, updates install command
with improved path resolution, and refreshes built plugin artifacts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-03 12:38:45 -07:00
parent 5621b67ccd
commit 76a880a3d6
11 changed files with 423 additions and 204 deletions
+2 -1
View File
@@ -109,7 +109,8 @@ export const geminiCliAdapter: PlatformAdapter = {
}
if (result.systemMessage) {
output.systemMessage = result.systemMessage;
// Strip ANSI escape codes — Gemini CLI renders them as raw text
output.systemMessage = result.systemMessage.replace(/\x1b\[[0-9;]*m/g, '');
}
// hookSpecificOutput is a first-class Gemini CLI field — pass through directly
+1 -1
View File
@@ -39,7 +39,7 @@ export const contextHandler: EventHandler = {
// Pass all projects (parent + worktree if applicable) for unified timeline
const projectsParam = context.allProjects.join(',');
const apiPath = `/api/context/inject?projects=${encodeURIComponent(projectsParam)}`;
const colorApiPath = `${apiPath}&colors=true`;
const colorApiPath = input.platform === 'claude-code' ? `${apiPath}&colors=true` : apiPath;
// Note: Removed AbortSignal.timeout due to Windows Bun cleanup issue (libuv assertion)
// Worker service has its own timeouts, so client-side timeout is redundant
+3 -1
View File
@@ -23,9 +23,11 @@ export const userMessageHandler: EventHandler = {
const project = basename(input.cwd ?? process.cwd());
// Fetch formatted context directly from worker API
// Only request ANSI colors for platforms that render them (claude-code)
const colorsParam = input.platform === 'claude-code' ? '&colors=true' : '';
try {
const response = await workerHttpRequest(
`/api/context/inject?project=${encodeURIComponent(project)}&colors=true`
`/api/context/inject?project=${encodeURIComponent(project)}${colorsParam}`
);
if (!response.ok) {
+27 -13
View File
@@ -230,22 +230,36 @@ async function promptForIDESelection(): Promise<string[]> {
function copyPluginToMarketplace(): void {
const marketplaceDir = marketplaceDirectory();
const packageRoot = npmPackageRootDirectory();
ensureDirectoryExists(marketplaceDir);
// Copy the entire npm package (not just plugin/) so that package.json,
// node_modules, and scripts are all present in the marketplace dir.
const packageRoot = npmPackageRootDirectory();
cpSync(packageRoot, marketplaceDir, {
recursive: true,
force: true,
filter: (source) => {
// Skip .git and other unnecessary directories
if (source.includes('.git') && !source.includes('.claude-plugin')) return false;
if (source.endsWith('.tgz')) return false;
return true;
},
});
// Only copy directories/files that are actually needed at runtime.
// The npm package ships plugin/, package.json, node_modules/, openclaw/, dist/.
// When running from a dev checkout, the root contains many extra dirs
// (.claude, .agents, src, docs, etc.) that must NOT be copied.
const allowedTopLevelEntries = [
'plugin',
'package.json',
'package-lock.json',
'node_modules',
'openclaw',
'dist',
'LICENSE',
'README.md',
'CHANGELOG.md',
];
for (const entry of allowedTopLevelEntries) {
const sourcePath = join(packageRoot, entry);
const destPath = join(marketplaceDir, entry);
if (!existsSync(sourcePath)) continue;
cpSync(sourcePath, destPath, {
recursive: true,
force: true,
});
}
}
function copyPluginToCache(version: string): void {
@@ -133,9 +133,7 @@ export function findMcpServerPath(): string | null {
const possiblePaths = [
// Marketplace install location
path.join(MARKETPLACE_ROOT, 'plugin', 'scripts', 'mcp-server.cjs'),
// Development/source location (relative to built worker-service.cjs in plugin/scripts/)
path.join(path.dirname(__filename), 'mcp-server.cjs'),
// Alternative dev location
// Development/source location
path.join(process.cwd(), 'plugin', 'scripts', 'mcp-server.cjs'),
];
@@ -155,9 +153,7 @@ export function findWorkerServicePath(): string | null {
const possiblePaths = [
// Marketplace install location
path.join(MARKETPLACE_ROOT, 'plugin', 'scripts', 'worker-service.cjs'),
// Development/source location (relative to built worker-service.cjs in plugin/scripts/)
path.join(path.dirname(__filename), 'worker-service.cjs'),
// Alternative dev location
// Development/source location
path.join(process.cwd(), 'plugin', 'scripts', 'worker-service.cjs'),
];