Add independent Cursor/Grok Bot marketplace plugins and host-observer install flow

Ship independent Cursor/Grok Bot marketplace plugins, host-observer probe, and Grok transcript discovery.

Fixes Greptile P1s: source-specific manual sessions, probe-before-persist host observer, occupied-port rejection, and Grok Bot agent-data root discovery.
This commit is contained in:
Copilot
2026-09-02 11:58:51 -07:00
committed by GitHub
parent e5b6719fb9
commit 1c7aaff38d
40 changed files with 1531 additions and 60 deletions
+22 -1
View File
@@ -12,6 +12,10 @@ const codexPluginPath = path.join(rootDir, '.codex-plugin', 'plugin.json');
const bundledCodexPluginPath = path.join(rootDir, 'plugin', '.codex-plugin', 'plugin.json');
const claudePluginPath = path.join(rootDir, '.claude-plugin', 'plugin.json');
const bundledClaudePluginPath = path.join(rootDir, 'plugin', '.claude-plugin', 'plugin.json');
const cursorPluginPaths = [
path.join(rootDir, 'claude-mem-cursor', '.cursor-plugin', 'plugin.json'),
path.join(rootDir, 'claude-mem-grok-bot', '.cursor-plugin', 'plugin.json'),
];
function readJson(filePath) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
@@ -69,6 +73,21 @@ function normalizeAuthorName(author) {
return '';
}
function syncCursorPlugin(plugin, pkg) {
return {
...plugin,
version: pkg.version,
description: pkg.description,
homepage: pkg.homepage,
repository: normalizeRepositoryUrl(pkg.repository),
license: pkg.license,
author: {
...(typeof plugin.author === 'object' && plugin.author ? plugin.author : {}),
name: normalizeAuthorName(pkg.author),
},
};
}
function normalizeRepositoryUrl(repository) {
if (typeof repository === 'string') return repository.replace(/\.git$/, '');
if (repository && typeof repository === 'object' && typeof repository.url === 'string')
@@ -77,7 +96,7 @@ function normalizeRepositoryUrl(repository) {
}
function main() {
for (const filePath of [packageJsonPath, codexPluginPath, bundledCodexPluginPath, claudePluginPath, bundledClaudePluginPath]) {
for (const filePath of [packageJsonPath, codexPluginPath, bundledCodexPluginPath, claudePluginPath, bundledClaudePluginPath, ...cursorPluginPaths]) {
if (!fs.existsSync(filePath)) {
console.error(`Missing required file: ${filePath}`);
process.exit(1);
@@ -89,11 +108,13 @@ function main() {
const bundledCodexPlugin = readJson(bundledCodexPluginPath);
const claudePlugin = readJson(claudePluginPath);
const bundledClaudePlugin = readJson(bundledClaudePluginPath);
const cursorPlugins = cursorPluginPaths.map(readJson);
writeJson(codexPluginPath, syncCodexPlugin(codexPlugin, pkg));
writeJson(bundledCodexPluginPath, syncCodexPlugin(bundledCodexPlugin, pkg));
writeJson(claudePluginPath, syncClaudePlugin(claudePlugin, pkg));
writeJson(bundledClaudePluginPath, syncClaudePlugin(bundledClaudePlugin, pkg));
cursorPluginPaths.forEach((filePath, index) => writeJson(filePath, syncCursorPlugin(cursorPlugins[index], pkg)));
console.log('✓ Synced plugin manifests from package.json');
}