@girardmedia/bootspring 2.5.6 → 2.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +17111 -5348
- package/dist/cli-launcher.js +43 -11
- package/dist/core/index.d.ts +153 -172
- package/dist/core.js +3735 -3463
- package/dist/mcp/index.d.ts +168 -1
- package/dist/mcp-server.js +1448 -1157
- package/package.json +1 -1
- package/scripts/postinstall.cjs +127 -2
package/package.json
CHANGED
package/scripts/postinstall.cjs
CHANGED
|
@@ -7,10 +7,13 @@ const path = require('path');
|
|
|
7
7
|
const c = {
|
|
8
8
|
reset: '\x1b[0m',
|
|
9
9
|
green: '\x1b[32m',
|
|
10
|
+
yellow: '\x1b[33m',
|
|
10
11
|
cyan: '\x1b[36m',
|
|
11
12
|
dim: '\x1b[2m'
|
|
12
13
|
};
|
|
13
14
|
|
|
15
|
+
const HOME = os.homedir();
|
|
16
|
+
|
|
14
17
|
function resolveCommandsSource() {
|
|
15
18
|
const fromEnv = process.env.BOOTSPRING_COMMANDS_SOURCE;
|
|
16
19
|
const candidates = [
|
|
@@ -108,6 +111,102 @@ function installBootspringSkill(skillsDir) {
|
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
|
|
114
|
+
// ── MCP Server Registration ───────────────────────────────────────────
|
|
115
|
+
//
|
|
116
|
+
// Each assistant has its own MCP config file format. We register the
|
|
117
|
+
// `bootspring` MCP server so that bootspring_build, bootspring_context,
|
|
118
|
+
// bootspring_quality, etc. are exposed as tools in every project — no
|
|
119
|
+
// per-project .mcp.json required.
|
|
120
|
+
//
|
|
121
|
+
// All registrations are idempotent (skip if already configured) and
|
|
122
|
+
// failure-tolerant (silently skip on permission/IO errors so a broken
|
|
123
|
+
// assistant config never blocks `npm install`).
|
|
124
|
+
|
|
125
|
+
function registerClaudeMcp() {
|
|
126
|
+
// Claude Code v2.x reads user-scope MCP servers from ~/.claude.json
|
|
127
|
+
// (the file at home root, NOT inside the ~/.claude/ directory).
|
|
128
|
+
const configPath = path.join(HOME, '.claude.json');
|
|
129
|
+
try {
|
|
130
|
+
let config = {};
|
|
131
|
+
if (fs.existsSync(configPath)) {
|
|
132
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
133
|
+
config = raw.trim() ? JSON.parse(raw) : {};
|
|
134
|
+
}
|
|
135
|
+
if (!config.mcpServers || typeof config.mcpServers !== 'object') {
|
|
136
|
+
config.mcpServers = {};
|
|
137
|
+
}
|
|
138
|
+
// Skip if ANY bootspring entry exists — never clobber user customizations.
|
|
139
|
+
if (config.mcpServers.bootspring) {
|
|
140
|
+
return { name: 'Claude Code', status: 'unchanged', path: configPath };
|
|
141
|
+
}
|
|
142
|
+
config.mcpServers.bootspring = {
|
|
143
|
+
type: 'stdio',
|
|
144
|
+
command: 'bootspring',
|
|
145
|
+
args: ['mcp'],
|
|
146
|
+
env: { BOOTSPRING_ASSISTANT: 'claude' }
|
|
147
|
+
};
|
|
148
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
149
|
+
return { name: 'Claude Code', status: 'updated', path: configPath };
|
|
150
|
+
} catch (err) {
|
|
151
|
+
return { name: 'Claude Code', status: 'skipped', path: configPath, reason: err.message };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function registerCodexMcp() {
|
|
156
|
+
// Codex reads MCP servers from ~/.codex/config.toml under [mcp_servers.<name>]
|
|
157
|
+
const configPath = path.join(HOME, '.codex', 'config.toml');
|
|
158
|
+
try {
|
|
159
|
+
const dir = path.dirname(configPath);
|
|
160
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
161
|
+
|
|
162
|
+
const existing = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf8') : '';
|
|
163
|
+
if (existing.includes('[mcp_servers.bootspring]')) {
|
|
164
|
+
return { name: 'Codex', status: 'unchanged', path: configPath };
|
|
165
|
+
}
|
|
166
|
+
const block = '[mcp_servers.bootspring]\ncommand = "bootspring"\nargs = ["mcp"]\nenv = { BOOTSPRING_ASSISTANT = "codex" }\n';
|
|
167
|
+
const content = existing.length > 0 ? `${existing.trimEnd()}\n\n${block}` : block;
|
|
168
|
+
fs.writeFileSync(configPath, content, 'utf8');
|
|
169
|
+
return { name: 'Codex', status: 'updated', path: configPath };
|
|
170
|
+
} catch (err) {
|
|
171
|
+
return { name: 'Codex', status: 'skipped', path: configPath, reason: err.message };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function registerGeminiMcp() {
|
|
176
|
+
// Gemini CLI reads MCP servers from ~/.gemini/settings.json under "mcpServers"
|
|
177
|
+
const configPath = path.join(HOME, '.gemini', 'settings.json');
|
|
178
|
+
try {
|
|
179
|
+
const dir = path.dirname(configPath);
|
|
180
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
181
|
+
|
|
182
|
+
let settings = {};
|
|
183
|
+
if (fs.existsSync(configPath)) {
|
|
184
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
185
|
+
settings = raw.trim() ? JSON.parse(raw) : {};
|
|
186
|
+
}
|
|
187
|
+
if (!settings.mcpServers || typeof settings.mcpServers !== 'object') {
|
|
188
|
+
settings.mcpServers = {};
|
|
189
|
+
}
|
|
190
|
+
// Skip if ANY bootspring entry exists — never clobber user customizations.
|
|
191
|
+
if (settings.mcpServers.bootspring) {
|
|
192
|
+
return { name: 'Gemini CLI', status: 'unchanged', path: configPath };
|
|
193
|
+
}
|
|
194
|
+
settings.mcpServers.bootspring = {
|
|
195
|
+
command: 'bootspring',
|
|
196
|
+
args: ['mcp'],
|
|
197
|
+
env: { BOOTSPRING_ASSISTANT: 'gemini' }
|
|
198
|
+
};
|
|
199
|
+
fs.writeFileSync(configPath, `${JSON.stringify(settings, null, 2)}\n`, 'utf8');
|
|
200
|
+
return { name: 'Gemini CLI', status: 'updated', path: configPath };
|
|
201
|
+
} catch (err) {
|
|
202
|
+
return { name: 'Gemini CLI', status: 'skipped', path: configPath, reason: err.message };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function registerAllMcp() {
|
|
207
|
+
return [registerClaudeMcp(), registerCodexMcp(), registerGeminiMcp()];
|
|
208
|
+
}
|
|
209
|
+
|
|
111
210
|
function main() {
|
|
112
211
|
if (process.env.CI || process.env.BOOTSPRING_SKIP_POSTINSTALL) {
|
|
113
212
|
return;
|
|
@@ -128,15 +227,41 @@ function main() {
|
|
|
128
227
|
}
|
|
129
228
|
}
|
|
130
229
|
|
|
131
|
-
|
|
230
|
+
// Register the Bootspring MCP server with each assistant so its tools
|
|
231
|
+
// (bootspring_build, bootspring_context, bootspring_quality, etc.) are
|
|
232
|
+
// available everywhere — no per-project .mcp.json needed.
|
|
233
|
+
const mcpResults = registerAllMcp();
|
|
234
|
+
const mcpUpdated = mcpResults.filter((r) => r.status === 'updated');
|
|
235
|
+
const mcpUnchanged = mcpResults.filter((r) => r.status === 'unchanged');
|
|
236
|
+
const mcpSkipped = mcpResults.filter((r) => r.status === 'skipped');
|
|
237
|
+
|
|
238
|
+
const didAnything =
|
|
239
|
+
totalCommandsInstalled > 0 ||
|
|
240
|
+
totalSkillsInstalled > 0 ||
|
|
241
|
+
mcpUpdated.length > 0;
|
|
242
|
+
|
|
243
|
+
if (didAnything) {
|
|
132
244
|
console.log(`
|
|
133
245
|
${c.cyan}⚡ Bootspring${c.reset} assistant integrations installed!
|
|
134
246
|
|
|
135
247
|
${c.dim}Installed:${c.reset}
|
|
136
248
|
${c.green}${totalCommandsInstalled}${c.reset} slash command templates
|
|
137
249
|
${c.green}${totalSkillsInstalled}${c.reset} Bootspring base skills
|
|
250
|
+
${c.green}${mcpUpdated.length}${c.reset} MCP server registrations${mcpUnchanged.length > 0 ? ` ${c.dim}(${mcpUnchanged.length} already configured)${c.reset}` : ''}
|
|
251
|
+
`);
|
|
252
|
+
|
|
253
|
+
if (mcpUpdated.length > 0) {
|
|
254
|
+
console.log(`${c.dim}MCP registered for:${c.reset} ${mcpUpdated.map((r) => r.name).join(', ')}`);
|
|
255
|
+
}
|
|
256
|
+
if (installedTo.length > 0) {
|
|
257
|
+
console.log(`${c.dim}Commands & skills installed to:${c.reset} ${installedTo.join(', ')}`);
|
|
258
|
+
}
|
|
259
|
+
if (mcpSkipped.length > 0) {
|
|
260
|
+
console.log(`${c.yellow}Note:${c.reset} ${c.dim}MCP registration skipped for ${mcpSkipped.map((r) => r.name).join(', ')} — run \`bootspring setup\` to retry.${c.reset}`);
|
|
261
|
+
}
|
|
138
262
|
|
|
139
|
-
|
|
263
|
+
console.log(`
|
|
264
|
+
${c.dim}Restart your assistant (Claude Code, Codex, or Gemini CLI) to load the bootspring MCP tools.${c.reset}
|
|
140
265
|
`);
|
|
141
266
|
}
|
|
142
267
|
}
|