fix(factory-plugin): wire marketplace so droid installs the Factory plugin

Add .factory-plugin/marketplace.json sourcing ./gitnexus-factory-plugin.
Droid reads it before .claude-plugin/marketplace.json, so
`droid plugin install` now delivers the Factory plugin (Execute matcher,
pinned mcp.json) instead of the translated Claude plugin (Bash matcher,
gitnexus@latest). Register the surface in the version-sync script and
cover the wiring in the factory and sync test suites.
This commit is contained in:
joseph02 2026-08-22 20:41:17 -07:00
parent 6649ce109e
commit 54870b41c7
4 changed files with 46 additions and 0 deletions

View file

@ -0,0 +1,19 @@
{
"name": "gitnexus-marketplace",
"owner": {
"name": "GitNexus",
"email": "nico@gitnexus.dev"
},
"metadata": {
"description": "Code intelligence powered by a knowledge graph — execution flows, blast radius, and semantic search",
"homepage": "https://github.com/nicosxt/gitnexus"
},
"plugins": [
{
"name": "gitnexus",
"version": "1.6.9",
"source": "./gitnexus-factory-plugin",
"description": "Code intelligence powered by a knowledge graph. Provides execution flow tracing, blast radius analysis, and augmented search across your codebase."
}
]
}

View file

@ -15,6 +15,7 @@
* - gitnexus-claude-plugin/skills/<skill>/mcp.json (gitnexus@<version> launch arg, x10)
* - gitnexus-factory-plugin/.factory-plugin/plugin.json (top-level version)
* - gitnexus-factory-plugin/mcp.json (gitnexus@<version> launch arg)
* - .factory-plugin/marketplace.json (plugins[gitnexus])
*
* Modes:
* node scripts/sync-plugin-manifests.mjs rewrite stale surfaces
@ -62,6 +63,10 @@ const MANIFEST_SURFACES = [
// released CLI.
{ file: 'gitnexus-factory-plugin/.factory-plugin/plugin.json', kind: 'plugin' },
{ file: 'gitnexus-factory-plugin/mcp.json', kind: 'mcp' },
// Droid reads .factory-plugin/marketplace.json before .claude-plugin's, so
// this entry is what makes `droid plugin install` deliver the Factory plugin
// (Execute matcher, pinned mcp.json) instead of the translated Claude one.
{ file: '.factory-plugin/marketplace.json', kind: 'marketplace' },
];
const PLUGIN_NAME = 'gitnexus';

View file

@ -64,6 +64,23 @@ describe('Factory plugin files', () => {
});
});
// ─── Marketplace wiring ─────────────────────────────────────────────
// Droid reads .factory-plugin/marketplace.json before .claude-plugin's, so this
// is what makes `droid plugin install` deliver this Factory plugin instead of
// the translated Claude one (Bash matcher, gitnexus@latest MCP).
describe('Factory marketplace wiring', () => {
const marketplace = JSON.parse(
fs.readFileSync(path.join(REPO_ROOT, '.factory-plugin', 'marketplace.json'), 'utf-8'),
);
it('exposes a single gitnexus plugin sourced from ./gitnexus-factory-plugin', () => {
const entries = marketplace.plugins.filter((p: { name: string }) => p.name === 'gitnexus');
expect(entries).toHaveLength(1);
expect(entries[0].source).toBe('./gitnexus-factory-plugin');
});
});
// ─── Drift guard: bundled guards === canonical Claude copies ─────────
describe('Factory plugin bundled guards stay in lockstep with the Claude adapter', () => {

View file

@ -10,6 +10,7 @@ const SURFACES = [
'gitnexus-claude-plugin/.codex-plugin/plugin.json',
'.agents/plugins/marketplace.json',
'gitnexus-factory-plugin/.factory-plugin/plugin.json',
'.factory-plugin/marketplace.json',
] as const;
const FACTORY_MCP = 'gitnexus-factory-plugin/mcp.json';
@ -60,6 +61,10 @@ function makeRoot(packageVersion: string, manifestVersion: string): string {
plugins: [{ name: 'gitnexus', version: manifestVersion, category: 'Developer Tools' }],
});
writeJson(root, SURFACES[4], { name: 'gitnexus', version: manifestVersion });
writeJson(root, SURFACES[5], {
name: 'gitnexus-marketplace',
plugins: [{ name: 'gitnexus', version: manifestVersion, source: './gitnexus-factory-plugin' }],
});
for (const dir of [...MCP_SKILL_DIRS.map(mcpPath), FACTORY_MCP]) {
writeJson(root, dir, {
mcpServers: {