opencode-1password-auth 1.0.1 → 1.0.3

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 (4) hide show
  1. package/index.ts +48 -23
  2. package/package.json +1 -1
  3. package/setup.ps1 +196 -3
  4. package/setup.sh +205 -3
package/index.ts CHANGED
@@ -1,8 +1,5 @@
1
1
  import type { Plugin } from "@opencode-ai/plugin";
2
2
  import * as sdk from "@1password/sdk";
3
- import * as fs from "fs";
4
- import * as path from "path";
5
- import * as os from "os";
6
3
 
7
4
  interface MCPServerConfig {
8
5
  environment?: Record<string, string>;
@@ -21,13 +18,24 @@ interface AuthJson {
21
18
  [providerId: string]: ProviderAuth;
22
19
  }
23
20
 
24
- const AUTH_JSON_PATH = path.join(os.homedir(), ".local", "share", "opencode", "auth.json");
25
- const OPENCODE_JSON_PATH = path.join(os.homedir(), ".config", "opencode", "opencode.json");
26
-
27
- export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
21
+ export const OnePasswordAuthPlugin: Plugin = async ({ client, $ }) => {
28
22
  let opClient: Awaited<ReturnType<typeof sdk.createClient>> | null = null;
29
23
  let mcpsEnvId: string | undefined;
30
24
 
25
+ const getHomeDir = (): string => {
26
+ return process.env.HOME || process.env.USERPROFILE || "";
27
+ };
28
+
29
+ const getAuthJsonPath = (): string => {
30
+ const home = getHomeDir();
31
+ return `${home}/.local/share/opencode/auth.json`;
32
+ };
33
+
34
+ const getOpenCodeJsonPath = (): string => {
35
+ const home = getHomeDir();
36
+ return `${home}/.config/opencode/opencode.json`;
37
+ };
38
+
31
39
  const initClient = async () => {
32
40
  const token = process.env.OP_SERVICE_ACCOUNT_TOKEN;
33
41
  if (!token) {
@@ -71,14 +79,21 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
71
79
  };
72
80
 
73
81
  const updateAuthJson = async (providerEnvId: string): Promise<void> => {
74
- if (!fs.existsSync(AUTH_JSON_PATH)) {
75
- console.log("1Password: auth.json not found, skipping");
76
- return;
77
- }
82
+ const authJsonPath = getAuthJsonPath();
78
83
 
79
84
  try {
80
- const content = fs.readFileSync(AUTH_JSON_PATH, "utf-8");
81
- const auth: AuthJson = JSON.parse(content);
85
+ // Read current auth.json using cat
86
+ const catResult = await $`cat "${authJsonPath}"`;
87
+ const content = catResult.stdout;
88
+ let auth: AuthJson;
89
+
90
+ try {
91
+ auth = JSON.parse(content);
92
+ } catch {
93
+ console.log("1Password: auth.json is not valid JSON, skipping");
94
+ return;
95
+ }
96
+
82
97
  let modified = false;
83
98
 
84
99
  for (const [providerId, authConfig] of Object.entries(auth)) {
@@ -91,7 +106,10 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
91
106
  }
92
107
 
93
108
  if (modified) {
94
- fs.writeFileSync(AUTH_JSON_PATH, JSON.stringify(auth, null, 2));
109
+ // Write updated content using a temp file and mv
110
+ const newContent = JSON.stringify(auth, null, 2);
111
+ // Use node to write the file since $ heredocs can be tricky
112
+ await $`node -e "const fs=require('fs'); fs.writeFileSync('${authJsonPath}', JSON.stringify(${JSON.stringify(auth)}, null, 2));"`;
95
113
  console.log("1Password: auth.json updated to use environment variables");
96
114
  }
97
115
  } catch (err) {
@@ -100,14 +118,20 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
100
118
  };
101
119
 
102
120
  const updateOpenCodeJsonMCP = async (mcpEnvId: string): Promise<void> => {
103
- if (!fs.existsSync(OPENCODE_JSON_PATH)) {
104
- console.log("1Password: opencode.json not found, skipping");
105
- return;
106
- }
121
+ const openCodeJsonPath = getOpenCodeJsonPath();
107
122
 
108
123
  try {
109
- const content = fs.readFileSync(OPENCODE_JSON_PATH, "utf-8");
110
- const config = JSON.parse(content);
124
+ // Read current opencode.json using cat
125
+ const catResult = await $`cat "${openCodeJsonPath}"`;
126
+ const content = catResult.stdout;
127
+ let config: OpenCodeConfig;
128
+
129
+ try {
130
+ config = JSON.parse(content);
131
+ } catch {
132
+ console.log("1Password: opencode.json is not valid JSON, skipping");
133
+ return;
134
+ }
111
135
 
112
136
  if (!config.mcp) {
113
137
  console.log("1Password: No MCP configuration found, skipping");
@@ -130,7 +154,8 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
130
154
  }
131
155
 
132
156
  if (modified) {
133
- fs.writeFileSync(OPENCODE_JSON_PATH, JSON.stringify(config, null, 2));
157
+ // Write updated content
158
+ await $`node -e "const fs=require('fs'); fs.writeFileSync('${openCodeJsonPath}', JSON.stringify(${JSON.stringify(config)}, null, 2));"`;
134
159
  console.log("1Password: opencode.json MCP config updated to use environment variables");
135
160
  }
136
161
  } catch (err) {
@@ -147,7 +172,7 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
147
172
  if (!apiKey) continue;
148
173
 
149
174
  try {
150
- await ctx.client.auth.set({
175
+ await client.auth.set({
151
176
  path: { id: providerId },
152
177
  body: { type: "api", key: apiKey },
153
178
  });
@@ -162,7 +187,7 @@ export const OnePasswordAuthPlugin: Plugin = async (ctx) => {
162
187
  const vars = new Set<string>();
163
188
 
164
189
  try {
165
- const config = ctx.config as OpenCodeConfig;
190
+ const config = client.config as OpenCodeConfig;
166
191
  if (config?.mcp) {
167
192
  for (const [, serverConfig] of Object.entries(config.mcp)) {
168
193
  if (serverConfig?.environment) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-1password-auth",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "1Password integration for OpenCode - authenticate providers and inject MCP secrets from 1Password environments",
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/setup.ps1 CHANGED
@@ -3,7 +3,8 @@
3
3
 
4
4
  param(
5
5
  [switch]$Uninstall,
6
- [switch]$Audit
6
+ [switch]$Audit,
7
+ [switch]$UpdateConfig
7
8
  )
8
9
 
9
10
  # Colors for output
@@ -65,6 +66,137 @@ function Remove-RegistryValue {
65
66
  }
66
67
  }
67
68
 
69
+ function Get-OpenCodeAuthJsonPath {
70
+ $home = if ($env:USERPROFILE) { $env:USERPROFILE } else { $env:USERPROFILE }
71
+ return "$home/.local/share/opencode/auth.json"
72
+ }
73
+
74
+ function Get-OpenCodeConfigJsonPath {
75
+ $home = if ($env:USERPROFILE) { $env:USERPROFILE } else { $env:USERPROFILE }
76
+ return "$home/.config/opencode/opencode.json"
77
+ }
78
+
79
+ function Update-ConfigFiles {
80
+ param([string]$Token, [string]$ProvidersEnvId, [string]$McpsEnvId)
81
+
82
+ $nodeModulesPath = Get-OpenCodeNodeModulesPath
83
+ if (-not $nodeModulesPath) {
84
+ Write-Error "Could not find @1password/sdk in any node_modules directory"
85
+ return
86
+ }
87
+
88
+ $sdkPath = ($nodeModulesPath -replace '\\', '/') + "/@1password/sdk/dist/sdk.js"
89
+
90
+ # Get provider secrets from 1Password
91
+ Write-Info "Reading provider secrets from 1Password..."
92
+
93
+ $script = @"
94
+ const sdk = require('${sdkPath}');
95
+
96
+ async function getSecrets() {
97
+ const client = await sdk.createClient({
98
+ auth: '${Token}',
99
+ integrationName: 'opencode-1password-setup',
100
+ integrationVersion: '1.0.0'
101
+ });
102
+
103
+ const providers = {};
104
+ const { variables: providerVars } = await client.environments.getVariables('${ProvidersEnvId}');
105
+ for (const v of providerVars) {
106
+ if (v.value) providers[v.name] = v.value;
107
+ }
108
+
109
+ const mcps = {};
110
+ if ('${McpsEnvId}') {
111
+ const { variables: mcpVars } = await client.environments.getVariables('${McpsEnvId}');
112
+ for (const v of mcpVars) {
113
+ if (v.value) mcps[v.name] = v.value;
114
+ }
115
+ }
116
+
117
+ console.log(JSON.stringify({ providers, mcps }));
118
+ }
119
+
120
+ getSecrets().catch(err => { console.error('FAILED:', err.message); process.exit(1); });
121
+ "@
122
+
123
+ $tempScript = [System.IO.Path]::GetTempFileName() -replace '\.tmp$', '.js'
124
+ $script | Out-File -FilePath $tempScript -Encoding UTF8 -NoNewline
125
+
126
+ $result = & node $tempScript 2>&1 | Out-String
127
+ Remove-Item $tempScript -ErrorAction SilentlyContinue
128
+
129
+ if ($result -match "FAILED:") {
130
+ Write-Error "Failed to read secrets from 1Password: $($result -replace 'FAILED:', '')"
131
+ return
132
+ }
133
+
134
+ $secrets = $result | ConvertFrom-Json
135
+
136
+ # Update auth.json
137
+ $authJsonPath = Get-OpenCodeAuthJsonPath
138
+ Write-Info "Updating auth.json..."
139
+
140
+ if (Test-Path $authJsonPath) {
141
+ $authContent = Get-Content $authJsonPath -Raw -Encoding UTF8
142
+ $auth = $authContent | ConvertFrom-Json
143
+
144
+ $modified = $false
145
+ foreach ($providerId in $auth.PSObject.Properties.Name) {
146
+ $authConfig = $auth.$providerId
147
+ if ($authConfig.key -and -not $authConfig.key.StartsWith("{env:")) {
148
+ $authConfig.key = "{env:$providerId}"
149
+ $modified = $true
150
+ Write-Success "Updated $providerId -> {env:$providerId}"
151
+ }
152
+ }
153
+
154
+ if ($modified) {
155
+ $auth | ConvertTo-Json -Depth 10 | Set-Content $authJsonPath -Encoding UTF8 -NoNewline
156
+ Write-Success "auth.json updated"
157
+ } else {
158
+ Write-Info "auth.json already uses environment variable references"
159
+ }
160
+ } else {
161
+ Write-Info "auth.json not found at $authJsonPath"
162
+ }
163
+
164
+ # Update opencode.json MCP config
165
+ $configJsonPath = Get-OpenCodeConfigJsonPath
166
+ Write-Info "Updating opencode.json MCP config..."
167
+
168
+ if (Test-Path $configJsonPath) {
169
+ $configContent = Get-Content $configJsonPath -Raw -Encoding UTF8
170
+ $config = $configContent | ConvertFrom-Json
171
+
172
+ $modified = $false
173
+ if ($config.mcp) {
174
+ foreach ($serverName in $config.mcp.PSObject.Properties.Name) {
175
+ $serverConfig = $config.mcp.$serverName
176
+ if ($serverConfig.environment) {
177
+ foreach ($key in $serverConfig.environment.PSObject.Properties.Name) {
178
+ $value = $serverConfig.environment.$key
179
+ if ($value -and -not $value.StartsWith("{env:") -and -not $value.StartsWith("$")) {
180
+ $serverConfig.environment.$key = "{env:$key}"
181
+ $modified = $true
182
+ Write-Success "Updated $serverName.$key -> {env:$key}"
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ if ($modified) {
190
+ $config | ConvertTo-Json -Depth 10 | Set-Content $configJsonPath -Encoding UTF8 -NoNewline
191
+ Write-Success "opencode.json updated"
192
+ } else {
193
+ Write-Info "opencode.json already uses environment variable references"
194
+ }
195
+ } else {
196
+ Write-Info "opencode.json not found at $configJsonPath"
197
+ }
198
+ }
199
+
68
200
  function Get-OpenCodeNodeModulesPath {
69
201
  $paths = @(
70
202
  "$env:USERPROFILE\.cache\opencode\node_modules",
@@ -320,6 +452,66 @@ if ($Audit) {
320
452
  exit 0
321
453
  }
322
454
 
455
+ if ($UpdateConfig) {
456
+ # Update Config mode
457
+ Write-Host "Update Config Mode" -ForegroundColor Yellow
458
+ Write-Host "------------------" -ForegroundColor Yellow
459
+ Write-Host ""
460
+
461
+ $token = Get-RegistryValue -Name "OP_SERVICE_ACCOUNT_TOKEN" -Scope "Machine"
462
+ $configId = Get-RegistryValue -Name "OP_CONFIG_ENV_ID" -Scope "Machine"
463
+
464
+ if (-not $token) {
465
+ $token = Get-RegistryValue -Name "OP_SERVICE_ACCOUNT_TOKEN" -Scope "User"
466
+ $configId = Get-RegistryValue -Name "OP_CONFIG_ENV_ID" -Scope "User"
467
+ }
468
+
469
+ if (-not $token -or -not $configId) {
470
+ Write-Error "Environment variables not set. Run setup first."
471
+ exit 1
472
+ }
473
+
474
+ Write-Info "Testing 1Password connection..."
475
+
476
+ if (Test-1PasswordConnection -Token $token) {
477
+ Write-Success "1Password connection successful!"
478
+ } else {
479
+ Write-Error "Failed to connect to 1Password. Check your service account token."
480
+ exit 1
481
+ }
482
+
483
+ Write-Info "Reading configuration from 1Password..."
484
+
485
+ $envIds = Get-1PasswordAudit -Token $token -ConfigEnvId $configId
486
+
487
+ if ($envIds) {
488
+ $providersEnvId = $null
489
+ $mcpsEnvId = $null
490
+
491
+ foreach ($prop in $envIds.PSObject.Properties) {
492
+ if ($prop.Name -eq "OPENCODE_PROVIDERS_ENV_ID") {
493
+ $providersEnvId = $prop.Value
494
+ } elseif ($prop.Name -eq "OPENCODE_MCPS_ENV_ID") {
495
+ $mcpsEnvId = $prop.Value
496
+ }
497
+ }
498
+
499
+ if ($providersEnvId) {
500
+ Write-Info "Updating config files to use environment variables..."
501
+ Update-ConfigFiles -Token $token -ProvidersEnvId $providersEnvId -McpsEnvId $mcpsEnvId
502
+ Write-Success "Config update complete!"
503
+ } else {
504
+ Write-Error "Could not find OPENCODE_PROVIDERS_ENV_ID in bootstrap environment"
505
+ exit 1
506
+ }
507
+ } else {
508
+ Write-Error "Failed to read bootstrap environment."
509
+ exit 1
510
+ }
511
+
512
+ exit 0
513
+ }
514
+
323
515
  # Setup mode (default)
324
516
  Write-Host "Setup Mode" -ForegroundColor Yellow
325
517
  Write-Host "----------" -ForegroundColor Yellow
@@ -438,6 +630,7 @@ Write-Success "Setup complete!"
438
630
  Write-Info "Restart OpenCode to activate the plugin."
439
631
  Write-Host ""
440
632
  Write-Host "Usage:" -ForegroundColor White
441
- Write-Host " ./setup.ps1 -Audit Show current configuration"
442
- Write-Host " ./setup.ps1 -Uninstall Remove environment variables"
633
+ Write-Host " ./setup.ps1 -Audit Show current configuration"
634
+ Write-Host " ./setup.ps1 -UpdateConfig Update config files to use {env:VAR} references"
635
+ Write-Host " ./setup.ps1 -Uninstall Remove environment variables"
443
636
  Write-Host ""
package/setup.sh CHANGED
@@ -221,9 +221,161 @@ EOFINNER
221
221
  done
222
222
  }
223
223
 
224
+ update_config_files() {
225
+ local token="$1"
226
+ local providers_env_id="$2"
227
+ local mcps_env_id="$3"
228
+
229
+ log_info "Reading secrets from 1Password..."
230
+
231
+ # Get provider and MCP secrets
232
+ cat > /tmp/update_config_$$.js << 'EOF'
233
+ const sdk = require('@1password/sdk');
234
+
235
+ async function getSecrets() {
236
+ const token = process.argv[1];
237
+ const providersEnvId = process.argv[2];
238
+ const mcpsEnvId = process.argv[3];
239
+
240
+ const client = await sdk.createClient({
241
+ auth: token,
242
+ integrationName: 'opencode-1password-setup',
243
+ integrationVersion: '1.0.0'
244
+ });
245
+
246
+ const providers = {};
247
+ const { variables: providerVars } = await client.environments.getVariables(providersEnvId);
248
+ for (const v of providerVars) {
249
+ if (v.value) providers[v.name] = v.value;
250
+ }
251
+
252
+ const mcps = {};
253
+ if (mcpsEnvId) {
254
+ const { variables: mcpVars } = await client.environments.getVariables(mcpsEnvId);
255
+ for (const v of mcpVars) {
256
+ if (v.value) mcps[v.name] = v.value;
257
+ }
258
+ }
259
+
260
+ console.log(JSON.stringify({ providers, mcps }));
261
+ }
262
+
263
+ getSecrets().catch(err => {
264
+ console.error('FAILED:', err.message);
265
+ process.exit(1);
266
+ });
267
+ EOF
268
+
269
+ result=$(node /tmp/update_config_$$.js "$token" "$providers_env_id" "$mcps_env_id" 2>&1)
270
+ rm -f /tmp/update_config_$$.js
271
+
272
+ if [[ "$result" == "FAILED:"* ]]; then
273
+ log_error "Failed to read secrets from 1Password: $result"
274
+ return 1
275
+ fi
276
+
277
+ # Get home directory
278
+ home="${HOME:-}"
279
+ if [[ -z "$home" ]]; then
280
+ home=$(eval echo ~)
281
+ fi
282
+
283
+ # Update auth.json
284
+ auth_json_path="$home/.local/share/opencode/auth.json"
285
+ log_info "Updating auth.json..."
286
+
287
+ if [[ -f "$auth_json_path" ]]; then
288
+ # Read auth.json and update
289
+ auth_content=$(cat "$auth_json_path")
290
+ # Use node to parse and update JSON
291
+ cat > /tmp/update_auth_$$.js << 'EOFJ'
292
+ const fs = require('fs');
293
+ const authPath = process.argv[1];
294
+ const auth = JSON.parse(fs.readFileSync(authPath, 'utf8'));
295
+
296
+ let modified = false;
297
+ for (const [providerId, authConfig] of Object.entries(auth)) {
298
+ if (authConfig.key && !authConfig.key.startsWith('{env:')) {
299
+ authConfig.key = '{env:' + providerId + '}';
300
+ modified = true;
301
+ console.log('Updated ' + providerId + ' -> {env:' + providerId + '}');
302
+ }
303
+ }
304
+
305
+ if (modified) {
306
+ fs.writeFileSync(authPath, JSON.stringify(auth, null, 2));
307
+ console.log('auth.json updated');
308
+ } else {
309
+ console.log('auth.json already uses environment variable references');
310
+ }
311
+ EOFJ
312
+
313
+ update_result=$(node /tmp/update_auth_$$.js "$auth_json_path" 2>&1)
314
+ rm -f /tmp/update_auth_$$.js
315
+ echo "$update_result" | while read line; do
316
+ if [[ "$line" == Updated* ]] || [[ "$line" == *updated* ]]; then
317
+ log_success "$(echo "$line" | sed 's/Updated/Updated/')"
318
+ else
319
+ log_info "$line"
320
+ fi
321
+ done
322
+ else
323
+ log_info "auth.json not found at $auth_json_path"
324
+ fi
325
+
326
+ # Update opencode.json MCP config
327
+ config_json_path="$home/.config/opencode/opencode.json"
328
+ log_info "Updating opencode.json MCP config..."
329
+
330
+ if [[ -f "$config_json_path" ]]; then
331
+ cat > /tmp/update_mcp_$$.js << 'EOFMCP'
332
+ const fs = require('fs');
333
+ const configPath = process.argv[1];
334
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
335
+
336
+ let modified = false;
337
+ if (config.mcp) {
338
+ for (const [serverName, serverConfig] of Object.entries(config.mcp)) {
339
+ if (serverConfig && serverConfig.environment) {
340
+ for (const [key, value] of Object.entries(serverConfig.environment)) {
341
+ if (value && !value.startsWith('{env:') && !value.startsWith('$')) {
342
+ serverConfig.environment[key] = '{env:' + key + '}';
343
+ modified = true;
344
+ console.log('Updated ' + serverName + '.' + key + ' -> {env:' + key + '}');
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ if (modified) {
352
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
353
+ console.log('opencode.json updated');
354
+ } else {
355
+ console.log('opencode.json already uses environment variable references');
356
+ }
357
+ EOFMCP
358
+
359
+ update_result=$(node /tmp/update_mcp_$$.js "$config_json_path" 2>&1)
360
+ rm -f /tmp/update_mcp_$$.js
361
+ echo "$update_result" | while read line; do
362
+ if [[ "$line" == Updated* ]] || [[ "$line" == *updated* ]]; then
363
+ log_success "$(echo "$line" | sed 's/Updated/Updated/')"
364
+ else
365
+ log_info "$line"
366
+ fi
367
+ done
368
+ else
369
+ log_info "opencode.json not found at $config_json_path"
370
+ fi
371
+
372
+ log_success "Config update complete!"
373
+ }
374
+
224
375
  # Parse arguments
225
376
  UNINSTALL=false
226
377
  AUDIT=false
378
+ UPDATE_CONFIG=false
227
379
 
228
380
  while [[ $# -gt 0 ]]; do
229
381
  case $1 in
@@ -235,8 +387,12 @@ while [[ $# -gt 0 ]]; do
235
387
  AUDIT=true
236
388
  shift
237
389
  ;;
390
+ -c|--update-config)
391
+ UPDATE_CONFIG=true
392
+ shift
393
+ ;;
238
394
  *)
239
- echo "Usage: $0 [--uninstall|--audit]"
395
+ echo "Usage: $0 [--uninstall|--audit|--update-config]"
240
396
  exit 1
241
397
  ;;
242
398
  esac
@@ -325,6 +481,51 @@ if [[ "$AUDIT" == true ]]; then
325
481
  exit 0
326
482
  fi
327
483
 
484
+ if [[ "$UPDATE_CONFIG" == true ]]; then
485
+ echo -e "${YELLOW}Update Config Mode${NC}"
486
+ echo -e "${YELLOW}------------------${NC}"
487
+ echo ""
488
+
489
+ get_existing_values
490
+
491
+ if [[ -z "$OP_SERVICE_ACCOUNT_TOKEN" || -z "$OP_CONFIG_ENV_ID" ]]; then
492
+ log_error "Environment variables not set. Run setup first."
493
+ exit 1
494
+ fi
495
+
496
+ log_info "Testing 1Password connection..."
497
+
498
+ if test_connection "$OP_SERVICE_ACCOUNT_TOKEN"; then
499
+ log_success "1Password connection successful!"
500
+ else
501
+ log_error "Failed to connect to 1Password. Check your service account token."
502
+ exit 1
503
+ fi
504
+
505
+ log_info "Reading configuration from 1Password..."
506
+
507
+ env_ids_json=$(get_audit_data "$OP_SERVICE_ACCOUNT_TOKEN" "$OP_CONFIG_ENV_ID")
508
+
509
+ if [[ -n "$env_ids_json" && "$env_ids_json" != "FAILED:"* ]]; then
510
+ # Parse JSON to extract env IDs
511
+ providers_env_id=$(echo "$env_ids_json" | sed -n 's/.*"OPENCODE_PROVIDERS_ENV_ID":"\([^"]*\)".*/\1/p')
512
+ mcps_env_id=$(echo "$env_ids_json" | sed -n 's/.*"OPENCODE_MCPS_ENV_ID":"\([^"]*\)".*/\1/p')
513
+
514
+ if [[ -n "$providers_env_id" ]]; then
515
+ log_info "Updating config files to use environment variables..."
516
+ update_config_files "$OP_SERVICE_ACCOUNT_TOKEN" "$providers_env_id" "$mcps_env_id"
517
+ else
518
+ log_error "Could not find OPENCODE_PROVIDERS_ENV_ID in bootstrap environment"
519
+ exit 1
520
+ fi
521
+ else
522
+ log_error "Failed to read bootstrap environment."
523
+ exit 1
524
+ fi
525
+
526
+ exit 0
527
+ fi
528
+
328
529
  # Setup mode (default)
329
530
  echo -e "${YELLOW}Setup Mode${NC}"
330
531
  echo -e "${YELLOW}----------${NC}"
@@ -439,6 +640,7 @@ log_success "Setup complete!"
439
640
  log_info "Restart OpenCode to activate the plugin."
440
641
  echo ""
441
642
  echo "Usage:"
442
- echo " ./setup.sh --audit Show current configuration"
443
- echo " ./setup.sh --uninstall Remove environment variables"
643
+ echo " ./setup.sh --audit Show current configuration"
644
+ echo " ./setup.sh --update-config Update config files to use {env:VAR} references"
645
+ echo " ./setup.sh --uninstall Remove environment variables"
444
646
  echo ""