pantheon-opencode 1.4.2 → 1.5.0-beta.1

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.
Files changed (98) hide show
  1. package/.pantheon/code-mode/.gitkeep +0 -0
  2. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-1.json +8 -0
  3. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-10.json +8 -0
  4. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-11.json +8 -0
  5. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-2.json +8 -0
  6. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-3.json +8 -0
  7. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-4.json +8 -0
  8. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-5.json +8 -0
  9. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-6.json +8 -0
  10. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-7.json +8 -0
  11. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-8.json +8 -0
  12. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/checkpoint-9.json +8 -0
  13. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/heartbeat.json +8 -0
  14. package/.pantheon/code-mode/.pantheon/deepwork/initial-token-40k/session.json +11 -0
  15. package/.pantheon/code-mode/README.md +93 -0
  16. package/.pantheon/code-mode/checkpoint-session.py +7 -0
  17. package/.pantheon/code-mode/checkpoint-session.sh +11 -0
  18. package/.pantheon/code-mode/checkpoint_session.py +481 -0
  19. package/.pantheon/code-mode/compress-inline.py +450 -0
  20. package/.pantheon/code-mode/eval-llm-judge.py +255 -0
  21. package/.pantheon/code-mode/eval-monte-carlo.py +368 -0
  22. package/.pantheon/code-mode/eval-run.py +197 -0
  23. package/.pantheon/code-mode/eval-static.py +321 -0
  24. package/.pantheon/code-mode/example-sync.sh +5 -0
  25. package/.pantheon/code-mode/session-end-save.py +186 -0
  26. package/.pantheon/code-mode/session-end-save.sh +18 -0
  27. package/.pantheon/code-mode/test-allowed.sh +5 -0
  28. package/.pantheon/code-mode/test-auto-continue-checkpoint.sh +179 -0
  29. package/.pantheon/code-mode/test-env.sh +7 -0
  30. package/.pantheon/code-mode/test-prlimit.sh +9 -0
  31. package/.pantheon/code-mode/test-timeout.sh +6 -0
  32. package/README.md +158 -1189
  33. package/README.pt-BR.md +222 -0
  34. package/bin/pantheon-init.mjs +30 -11
  35. package/opencode.json +1 -0
  36. package/package.json +14 -3
  37. package/plugin.json +15 -0
  38. package/scripts/_pantheon_paths.py +48 -7
  39. package/scripts/ci-validate-yaml.py +7 -2
  40. package/scripts/code_mode_server.py +33 -2
  41. package/scripts/doctor.mjs +135 -127
  42. package/scripts/generate-preset-docs.mjs +127 -66
  43. package/scripts/generate-prompts.sh +2 -2
  44. package/scripts/install/cli-ui.mjs +8 -1
  45. package/scripts/install/config-migration.mjs +401 -0
  46. package/scripts/install/health-check.mjs +3 -3
  47. package/scripts/install/model-picker.mjs +72 -23
  48. package/scripts/install/opencode-version.mjs +47 -0
  49. package/scripts/install/opencode.mjs +261 -88
  50. package/scripts/install/plugin.mjs +112 -42
  51. package/scripts/install/shared.mjs +13 -158
  52. package/scripts/install-mcp.mjs +44 -232
  53. package/scripts/mcp_persistence_server.py +344 -15
  54. package/scripts/mcp_resources_server.py +144 -40
  55. package/scripts/memory_mcp_server.py +2 -2
  56. package/scripts/recover-zenodo-deposition.mjs +146 -0
  57. package/scripts/sync-tui.mjs +32 -7
  58. package/scripts/test-opencode-v1-v2-sandbox.sh +591 -0
  59. package/scripts/uninstall.mjs +298 -954
  60. package/scripts/validate-zenodo-release.mjs +154 -0
  61. package/scripts/zenodo-artifact.mjs +21 -0
  62. package/scripts/zenodo-release-state.mjs +53 -0
  63. package/src/mcp/_pantheon_paths.py +48 -7
  64. package/src/mcp/code_mode_server.py +33 -2
  65. package/src/mcp/eval_store.py +1 -1
  66. package/src/mcp/mcp_persistence_server.py +344 -15
  67. package/src/mcp/mcp_resources_server.py +144 -40
  68. package/src/mcp/pantheon_vision_server.py +1 -1
  69. package/src/mcp/toon_codec.py +491 -0
  70. package/src/pantheon/background-job-board.ts +67 -1
  71. package/src/pantheon/cost-command.ts +6 -2
  72. package/src/pantheon/delegate-manager.ts +384 -0
  73. package/src/pantheon/delegate-task-adapter.ts +444 -0
  74. package/src/pantheon/delegation-notify.ts +35 -20
  75. package/src/pantheon/model-command.ts +86 -32
  76. package/src/pantheon/token-opt.ts +555 -0
  77. package/src/pantheon/toon-codec.ts +481 -0
  78. package/src/pantheon/tui-version-check.ts +1 -3
  79. package/src/pantheon/v2-bridge.ts +129 -0
  80. package/src/pantheon/v2-events.ts +131 -0
  81. package/src/pantheon/v2-hooks.ts +287 -0
  82. package/src/pantheon/v2-tool-definitions.ts +331 -0
  83. package/src/plugin-v2/index.ts +21 -0
  84. package/src/plugin-v2.ts +836 -0
  85. package/src/plugin.ts +57 -10
  86. package/src/plugins/tui/dist/server.d.ts +1 -1
  87. package/src/plugins/tui/dist/server.d.ts.map +1 -1
  88. package/src/plugins/tui/dist/server.js +1 -1
  89. package/src/plugins/tui/dist/server.js.map +1 -1
  90. package/src/plugins/tui/dist/tui.d.ts +10 -7
  91. package/src/plugins/tui/dist/tui.d.ts.map +1 -1
  92. package/src/plugins/tui/dist/tui.js +11 -8
  93. package/src/plugins/tui/dist/tui.js.map +1 -1
  94. package/src/plugins/tui/dist/tui.tsx +22 -16
  95. package/src/plugins/tui/package-lock.json +51 -51
  96. package/src/plugins/tui/package.json +7 -7
  97. package/src/plugins/tui/src/index.tsx +22 -16
  98. package/src/skills/README.md +0 -2
@@ -1,14 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * install-mcp.mjs — Multi-platform MCP server installer for Pantheon
3
+ * install-mcp.mjs — OpenCode MCP server installer for Pantheon
4
4
  *
5
- * Detects the user's platform (OpenCode, VS Code, Cursor, Claude, Windsurf),
6
- * installs MCP servers (Essential Tier 1, optional Domain Tier 2), writes
7
- * platform-specific config files, and validates each MCP responds.
5
+ * Installs MCP servers (Essential Tier 1, optional Domain Tier 2) into
6
+ * OpenCode's configuration and validates each MCP responds.
8
7
  *
9
8
  * Usage:
10
9
  * node scripts/install-mcp.mjs
11
- * node scripts/install-mcp.mjs --platform opencode
12
10
  * node scripts/install-mcp.mjs --tier 2
13
11
  * node scripts/install-mcp.mjs --mcp context7
14
12
  * node scripts/install-mcp.mjs --list
@@ -89,7 +87,7 @@ const PANTHEON_VISION_SERVER = resolveServerScript('src/mcp/pantheon_vision_serv
89
87
  * tier - 1 (Essential), 2 (Domain), 3 (Project)
90
88
  * name - Human-readable label
91
89
  * description- Short description
92
- * platforms - Per-platform config; each entry has:
90
+ * platforms - OpenCode config; each entry has:
93
91
  * type - 'remote' | 'local' | 'stdio' | 'http'
94
92
  * url - (remote/http) endpoint URL
95
93
  * command - (local/stdio) executable
@@ -97,17 +95,13 @@ const PANTHEON_VISION_SERVER = resolveServerScript('src/mcp/pantheon_vision_serv
97
95
  * env - Required environment variable names
98
96
  * validate - Async function returning { ok, message }
99
97
  */
100
- const MCPS = {
98
+ export const MCPS = {
101
99
  github: {
102
100
  tier: 1,
103
101
  name: 'GitHub MCP',
104
102
  description: 'Repository access, PR/issue management via GitHub API',
105
103
  platforms: {
106
104
  opencode: { type: 'remote', url: 'https://api.githubcopilot.com/mcp/' },
107
- vscode: { type: 'http', url: 'https://api.githubcopilot.com/mcp/' },
108
- cursor: { type: 'http', url: 'https://api.githubcopilot.com/mcp/' },
109
- claude: { type: 'remote', url: 'https://api.githubcopilot.com/mcp/' },
110
- windsurf: { type: 'http', url: 'https://api.githubcopilot.com/mcp/' },
111
105
  },
112
106
  env: [],
113
107
  validate: async () => ({ ok: true, message: 'remote (OAuth handled by platform)' }),
@@ -118,10 +112,6 @@ const MCPS = {
118
112
  description: 'Up-to-date documentation for libraries and frameworks',
119
113
  platforms: {
120
114
  opencode: { type: 'local', command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
121
- vscode: { type: 'stdio', command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
122
- cursor: { type: 'local', command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
123
- claude: { type: 'local', command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
124
- windsurf: { type: 'local', command: 'npx', args: ['-y', '@upstash/context7-mcp'] },
125
115
  },
126
116
  env: [],
127
117
  validate: async () => {
@@ -142,10 +132,6 @@ const MCPS = {
142
132
  description: 'Browser automation and E2E testing via Playwright',
143
133
  platforms: {
144
134
  opencode: { type: 'local', command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
145
- vscode: { type: 'stdio', command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
146
- cursor: { type: 'local', command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
147
- claude: { type: 'local', command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
148
- windsurf: { type: 'local', command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
149
135
  },
150
136
  env: [],
151
137
  validate: async () => {
@@ -166,10 +152,6 @@ const MCPS = {
166
152
  description: 'Database schema exploration and SQL query execution',
167
153
  platforms: {
168
154
  opencode: { type: 'local', command: 'npx', args: ['-y', '@anthropic/postgres-mcp'] },
169
- vscode: { type: 'stdio', command: 'npx', args: ['-y', '@anthropic/postgres-mcp'] },
170
- cursor: { type: 'local', command: 'npx', args: ['-y', '@anthropic/postgres-mcp'] },
171
- claude: { type: 'local', command: 'npx', args: ['-y', '@anthropic/postgres-mcp'] },
172
- windsurf: { type: 'local', command: 'npx', args: ['-y', '@anthropic/postgres-mcp'] },
173
155
  },
174
156
  env: ['DATABASE_URL'],
175
157
  validate: async () => {
@@ -193,10 +175,6 @@ const MCPS = {
193
175
  description: 'Real-time web search via Brave Search API',
194
176
  platforms: {
195
177
  opencode: { type: 'local', command: 'npx', args: ['-y', '@anthropic/brave-search-mcp'] },
196
- vscode: { type: 'stdio', command: 'npx', args: ['-y', '@anthropic/brave-search-mcp'] },
197
- cursor: { type: 'local', command: 'npx', args: ['-y', '@anthropic/brave-search-mcp'] },
198
- claude: { type: 'local', command: 'npx', args: ['-y', '@anthropic/brave-search-mcp'] },
199
- windsurf: { type: 'local', command: 'npx', args: ['-y', '@anthropic/brave-search-mcp'] },
200
178
  },
201
179
  env: ['BRAVE_API_KEY'],
202
180
  validate: async () => {
@@ -218,34 +196,14 @@ const MCPS = {
218
196
  tier: 1,
219
197
  name: 'Pantheon Resources',
220
198
  description: 'Pantheon framework resources — agents, skills, routing, deepwork, memory bank',
199
+ env: [],
221
200
  platforms: {
222
201
  opencode: {
223
202
  type: 'local',
224
203
  command: VENV_PYTHON,
225
204
  args: [MCP_RESOURCES_SERVER],
226
205
  },
227
- vscode: {
228
- type: 'stdio',
229
- command: VENV_PYTHON,
230
- args: [MCP_RESOURCES_SERVER],
231
- },
232
- cursor: {
233
- type: 'local',
234
- command: VENV_PYTHON,
235
- args: [MCP_RESOURCES_SERVER],
236
- },
237
- claude: {
238
- type: 'local',
239
- command: VENV_PYTHON,
240
- args: [MCP_RESOURCES_SERVER],
241
- },
242
- windsurf: {
243
- type: 'local',
244
- command: VENV_PYTHON,
245
- args: [MCP_RESOURCES_SERVER],
246
- },
247
206
  },
248
- env: [],
249
207
  validate: async () => {
250
208
  const scriptPath = MCP_RESOURCES_SERVER
251
209
  if (existsSync(scriptPath)) {
@@ -264,26 +222,6 @@ const MCPS = {
264
222
  command: VENV_PYTHON,
265
223
  args: [CODE_MODE_SERVER],
266
224
  },
267
- vscode: {
268
- type: 'stdio',
269
- command: VENV_PYTHON,
270
- args: [CODE_MODE_SERVER],
271
- },
272
- cursor: {
273
- type: 'local',
274
- command: VENV_PYTHON,
275
- args: [CODE_MODE_SERVER],
276
- },
277
- claude: {
278
- type: 'local',
279
- command: VENV_PYTHON,
280
- args: [CODE_MODE_SERVER],
281
- },
282
- windsurf: {
283
- type: 'local',
284
- command: VENV_PYTHON,
285
- args: [CODE_MODE_SERVER],
286
- },
287
225
  },
288
226
  env: [],
289
227
  validate: async () => {
@@ -305,21 +243,6 @@ const MCPS = {
305
243
  command: VENV_PYTHON,
306
244
  args: [MEMORY_MCP_SERVER],
307
245
  },
308
- claude: {
309
- type: 'local',
310
- command: VENV_PYTHON,
311
- args: [MEMORY_MCP_SERVER],
312
- },
313
- cursor: {
314
- type: 'local',
315
- command: VENV_PYTHON,
316
- args: [MEMORY_MCP_SERVER],
317
- },
318
- windsurf: {
319
- type: 'local',
320
- command: VENV_PYTHON,
321
- args: [MEMORY_MCP_SERVER],
322
- },
323
246
  },
324
247
  env: [],
325
248
  validate: async () => {
@@ -335,29 +258,14 @@ const MCPS = {
335
258
  name: 'Pantheon Persistence',
336
259
  description:
337
260
  'Pantheon Persistence MCP Server — key-value store with FTS5 full-text search, TTL-based expiration, and namespace isolation',
261
+ env: [],
338
262
  platforms: {
339
263
  opencode: {
340
264
  type: 'local',
341
265
  command: VENV_PYTHON,
342
266
  args: [MCP_PERSISTENCE_SERVER],
343
267
  },
344
- claude: {
345
- type: 'local',
346
- command: VENV_PYTHON,
347
- args: [MCP_PERSISTENCE_SERVER],
348
- },
349
- cursor: {
350
- type: 'local',
351
- command: VENV_PYTHON,
352
- args: [MCP_PERSISTENCE_SERVER],
353
- },
354
- windsurf: {
355
- type: 'local',
356
- command: VENV_PYTHON,
357
- args: [MCP_PERSISTENCE_SERVER],
358
- },
359
268
  },
360
- env: [],
361
269
  validate: async () => {
362
270
  const scriptPath = MCP_PERSISTENCE_SERVER
363
271
  if (existsSync(scriptPath)) {
@@ -378,26 +286,6 @@ const MCPS = {
378
286
  command: VENV_PYTHON,
379
287
  args: [PANTHEON_VISION_SERVER],
380
288
  },
381
- vscode: {
382
- type: 'stdio',
383
- command: VENV_PYTHON,
384
- args: [PANTHEON_VISION_SERVER],
385
- },
386
- claude: {
387
- type: 'local',
388
- command: VENV_PYTHON,
389
- args: [PANTHEON_VISION_SERVER],
390
- },
391
- cursor: {
392
- type: 'local',
393
- command: VENV_PYTHON,
394
- args: [PANTHEON_VISION_SERVER],
395
- },
396
- windsurf: {
397
- type: 'local',
398
- command: VENV_PYTHON,
399
- args: [PANTHEON_VISION_SERVER],
400
- },
401
289
  },
402
290
  env: [],
403
291
  validate: async () => {
@@ -415,10 +303,6 @@ const MCPS = {
415
303
  description: 'Container lifecycle management via Docker CLI',
416
304
  platforms: {
417
305
  opencode: { type: 'local', command: 'docker' },
418
- vscode: { type: 'stdio', command: 'docker' },
419
- cursor: { type: 'local', command: 'docker' },
420
- claude: { type: 'local', command: 'docker' },
421
- windsurf: { type: 'local', command: 'docker' },
422
306
  },
423
307
  env: [],
424
308
  validate: async () => {
@@ -439,7 +323,7 @@ const MCPS = {
439
323
  // Platform Metadata
440
324
  // ---------------------------------------------------------------------------
441
325
 
442
- const PLATFORMS = {
326
+ export const PLATFORMS = {
443
327
  opencode: {
444
328
  label: 'OpenCode',
445
329
  configFile: 'opencode.json',
@@ -455,46 +339,6 @@ const PLATFORMS = {
455
339
  existsSync(join(process.cwd(), 'opencode.json')) ||
456
340
  existsSync(join(homedir(), '.config', 'opencode', 'opencode.json')),
457
341
  },
458
- vscode: {
459
- label: 'VS Code',
460
- configFile: '.vscode/mcp.json',
461
- configPaths: [join(ROOT, '.vscode', 'mcp.json'), join(process.cwd(), '.vscode', 'mcp.json')],
462
- // VS Code uses "servers" key
463
- configKey: 'servers',
464
- detect: () =>
465
- existsSync(join(ROOT, '.vscode', 'mcp.json')) ||
466
- existsSync(join(process.cwd(), '.vscode', 'mcp.json')),
467
- },
468
- cursor: {
469
- label: 'Cursor',
470
- configFile: '.cursor/mcp.json',
471
- configPaths: [join(ROOT, '.cursor', 'mcp.json'), join(process.cwd(), '.cursor', 'mcp.json')],
472
- configKey: 'mcpServers',
473
- detect: () =>
474
- existsSync(join(ROOT, '.cursor', 'mcp.json')) ||
475
- existsSync(join(process.cwd(), '.cursor', 'mcp.json')),
476
- },
477
- claude: {
478
- label: 'Claude',
479
- configFile: '.mcp.json',
480
- configPaths: [
481
- join(ROOT, '.mcp.json'),
482
- join(process.cwd(), '.mcp.json'),
483
- join(homedir(), '.claude', 'settings.json'),
484
- ],
485
- configKey: 'mcpServers',
486
- detect: () =>
487
- existsSync(join(ROOT, '.mcp.json')) ||
488
- existsSync(join(process.cwd(), '.mcp.json')) ||
489
- existsSync(join(homedir(), '.claude', 'settings.json')),
490
- },
491
- windsurf: {
492
- label: 'Windsurf',
493
- configFile: '~/.codeium/windsurf/mcp_config.json',
494
- configPaths: [join(homedir(), '.codeium', 'windsurf', 'mcp_config.json')],
495
- configKey: 'mcpServers',
496
- detect: () => existsSync(join(homedir(), '.codeium', 'windsurf', 'mcp_config.json')),
497
- },
498
342
  }
499
343
 
500
344
  // ---------------------------------------------------------------------------
@@ -502,22 +346,31 @@ const PLATFORMS = {
502
346
  // ---------------------------------------------------------------------------
503
347
 
504
348
  /**
505
- * Build the MCP server entry for a given platform.
506
- * Each platform has a slightly different JSON shape.
349
+ * Build the MCP server entry for OpenCode.
507
350
  *
508
351
  * @param {string} mcpKey - Canonical MCP key (e.g. 'github', 'context7')
509
- * @param {string} platformName - Platform key (e.g. 'opencode', 'vscode')
352
+ * @param {string} platformName - Must be `opencode`
353
+ * @param {object} [catalog=MCPS] - MCP catalog (injectable for transport fixtures)
510
354
  * @returns {object|null} - The config entry, or null if unsupported
511
355
  */
512
- function buildMcpEntry(mcpKey, platformName) {
513
- const mcp = MCPS[mcpKey]
356
+ export function buildMcpEntry(mcpKey, platformName, catalog = MCPS) {
357
+ const mcp = catalog[mcpKey]
514
358
  if (!mcp) return null
515
359
  const platform = mcp.platforms[platformName]
516
360
  if (!platform) return null
517
361
 
518
362
  // Collect env vars that are set for inclusion in config
519
363
  const env = {}
520
- for (const key of mcp.env) {
364
+ // PWD is a logical working-directory hint, not a general environment
365
+ // variable. It is valid only for the stdio transport of the two servers
366
+ // that consume it; never emit it for local or remote platform entries.
367
+ const environmentKeys = (platform.env ?? mcp.env).filter(
368
+ (key) =>
369
+ key !== 'PWD' ||
370
+ (platform.type === 'stdio' &&
371
+ (mcpKey === 'pantheon-resources' || mcpKey === 'pantheon-persistence')),
372
+ )
373
+ for (const key of environmentKeys) {
521
374
  const val = process.env[key]
522
375
  if (val) {
523
376
  env[key] = `\${${key}}`
@@ -535,19 +388,17 @@ function buildMcpEntry(mcpKey, platformName) {
535
388
  enabled: true,
536
389
  }
537
390
  }
538
- // VS Code http format: { type: "http", url }
539
- if (platformName === 'vscode') {
540
- return { type: 'http', url: platform.url }
541
- }
542
- // Cursor/Claude/Windsurf http format
543
- return { type: 'http', url: platform.url }
391
+ return null
544
392
  }
545
393
 
546
- case 'local': {
547
- // OpenCode uses "mcp" key with { type: "local", command: [...], enabled }
394
+ case 'local':
395
+ case 'stdio': {
396
+ // OpenCode uses { type, command: [...], enabled }. `stdio` is accepted
397
+ // for transport fixtures and integrations; production entries currently
398
+ // use OpenCode's `local` spelling.
548
399
  if (platformName === 'opencode') {
549
400
  const entry = {
550
- type: 'local',
401
+ type: platform.type,
551
402
  command: [platform.command, ...(platform.args || [])],
552
403
  enabled: true,
553
404
  }
@@ -556,24 +407,7 @@ function buildMcpEntry(mcpKey, platformName) {
556
407
  }
557
408
  return entry
558
409
  }
559
- // Cursor/Claude/Windsurf format: { command, args?, env? }
560
- const entry = {
561
- command: platform.command,
562
- ...(platform.args ? { args: platform.args } : {}),
563
- }
564
- if (Object.keys(env).length > 0) {
565
- entry.env = env
566
- }
567
- return entry
568
- }
569
-
570
- case 'stdio': {
571
- // VS Code stdio format: { type: "stdio", command, args? }
572
- return {
573
- type: 'stdio',
574
- command: platform.command,
575
- ...(platform.args ? { args: platform.args } : {}),
576
- }
410
+ return null
577
411
  }
578
412
 
579
413
  default:
@@ -689,7 +523,7 @@ function writeMcpConfig(platformName, mcpKey, dryRun, force) {
689
523
 
690
524
  function parseArgs(argv) {
691
525
  const args = {
692
- platforms: [],
526
+ platforms: ['opencode'],
693
527
  tier: 1,
694
528
  mcp: null,
695
529
  list: false,
@@ -728,30 +562,16 @@ function parseArgs(argv) {
728
562
  }
729
563
  }
730
564
 
731
- // If no platforms specified and not --list, auto-detect
732
- if (args.platforms.length === 0 && !args.list && !args.help) {
733
- const detected = detectPlatforms()
734
- if (detected.length > 0) {
735
- args.platforms = detected
736
- } else {
737
- // Default to all platforms if none detected
738
- args.platforms = Object.keys(PLATFORMS)
739
- }
565
+ const unsupported = args.platforms.filter((name) => name !== 'opencode')
566
+ if (unsupported.length > 0) {
567
+ throw new Error(
568
+ `Unsupported platform: ${unsupported.join(', ')}. This package supports OpenCode only.`,
569
+ )
740
570
  }
741
571
 
742
572
  return args
743
573
  }
744
574
 
745
- function detectPlatforms() {
746
- const detected = []
747
- for (const [name, platform] of Object.entries(PLATFORMS)) {
748
- if (platform.detect()) {
749
- detected.push(name)
750
- }
751
- }
752
- return detected
753
- }
754
-
755
575
  // ---------------------------------------------------------------------------
756
576
  // Interactive Prompt
757
577
  // ---------------------------------------------------------------------------
@@ -816,7 +636,7 @@ function listMcps() {
816
636
  console.log(` ${key.padEnd(16)} ${mcp.name.padEnd(20)} ${mcp.description}${envInfo}`)
817
637
  }
818
638
  }
819
- console.log(`\nPlatforms supported: ${Object.keys(PLATFORMS).join(', ')}`)
639
+ console.log(`\nPlatform supported: ${Object.keys(PLATFORMS).join(', ')}`)
820
640
  console.log('')
821
641
  }
822
642
 
@@ -826,11 +646,11 @@ function listMcps() {
826
646
 
827
647
  function showHelp() {
828
648
  console.log(`
829
- install-mcp.mjs — Multi-platform MCP server installer for Pantheon
649
+ install-mcp.mjs — OpenCode MCP server installer for Pantheon
830
650
 
831
651
  Usage:
832
- node scripts/install-mcp.mjs Auto-detect platform, install Tier 1
833
- node scripts/install-mcp.mjs --platform opencode Install for specific platform
652
+ node scripts/install-mcp.mjs Install OpenCode Tier 1 MCPs
653
+ node scripts/install-mcp.mjs --platform opencode Install OpenCode MCPs explicitly
834
654
  node scripts/install-mcp.mjs --tier 2 Install Tier 2 (interactive prompt)
835
655
  node scripts/install-mcp.mjs --mcp context7 Install a specific MCP only
836
656
  node scripts/install-mcp.mjs --list List available MCPs
@@ -839,8 +659,7 @@ Usage:
839
659
  node scripts/install-mcp.mjs --platform opencode --mcp github,context7
840
660
 
841
661
  Options:
842
- --platform <name> Target platform (opencode|vscode|cursor|claude|windsurf).
843
- Comma-separated for multiple. Auto-detects if omitted.
662
+ --platform <name> Target platform (opencode only).
844
663
  --tier <n> 1=Essential (default), 2=Domain, 3=Project
845
664
  --mcp <name> Install specific MCP(s) only. Comma-separated.
846
665
  --list List available MCPs and exit
@@ -848,12 +667,8 @@ Options:
848
667
  --force Overwrite existing MCP entries
849
668
  --help, -h Show this help
850
669
 
851
- Platforms:
670
+ Platform:
852
671
  opencode → opencode.json (mcp key)
853
- vscode → .vscode/mcp.json (servers key)
854
- cursor → .cursor/mcp.json (mcpServers key)
855
- claude → .mcp.json or ~/.claude/settings.json (mcpServers key)
856
- windsurf → ~/.codeium/windsurf/mcp_config.json (mcpServers key)
857
672
 
858
673
  Environment Variables:
859
674
  DATABASE_URL Required for PostgreSQL MCP (postgresql+ssl://...)
@@ -863,7 +678,6 @@ Examples:
863
678
  node scripts/install-mcp.mjs Auto-detect + install essentials
864
679
  node scripts/install-mcp.mjs --platform opencode --tier 2 OpenCode + interactive Tier 2
865
680
  node scripts/install-mcp.mjs --mcp docker Install only Docker MCP
866
- node scripts/install-mcp.mjs --platform vscode --dry-run Preview VS Code changes
867
681
  `)
868
682
  }
869
683
 
@@ -1041,9 +855,7 @@ export async function main() {
1041
855
  }
1042
856
  }
1043
857
 
1044
- console.log('\n⚠️ Reminder: Restart your editor/CLI tool for MCP changes to take effect.')
1045
- console.log(' For VS Code: Cmd+Shift+P → "Developer: Reload Window"')
1046
- console.log(' For OpenCode: Just restart the session')
858
+ console.log('\n⚠️ Reminder: Restart OpenCode for MCP changes to take effect.')
1047
859
  console.log('')
1048
860
 
1049
861
  process.exit(progress.errors.length > 0 ? 1 : 0)