berget 2.2.0 → 2.2.2
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/.github/workflows/publish.yml +20 -6
- package/dist/index.js +2 -2
- package/dist/package.json +1 -1
- package/dist/src/commands/code.js +33 -455
- package/index.ts +3 -3
- package/package.json +1 -1
- package/src/commands/code.ts +34 -546
package/src/commands/code.ts
CHANGED
|
@@ -2,22 +2,12 @@ import { Command } from 'commander'
|
|
|
2
2
|
import chalk from 'chalk'
|
|
3
3
|
import readline from 'readline'
|
|
4
4
|
import { COMMAND_GROUPS, SUBCOMMANDS } from '../constants/command-structure'
|
|
5
|
-
import { ApiKeyService, CreateApiKeyOptions } from '../services/api-key-service'
|
|
6
|
-
import { AuthService } from '../services/auth-service'
|
|
7
5
|
import { handleError } from '../utils/error-handler'
|
|
8
6
|
import * as fs from 'fs'
|
|
9
7
|
import { readFile, writeFile } from 'fs/promises'
|
|
10
8
|
import path from 'path'
|
|
11
9
|
import { spawn } from 'child_process'
|
|
12
|
-
import {
|
|
13
|
-
import { createAuthenticatedClient, getAuthToken } from '../client'
|
|
14
|
-
import {
|
|
15
|
-
getConfigLoader,
|
|
16
|
-
getModelConfig,
|
|
17
|
-
getProviderModels,
|
|
18
|
-
type OpenCodeConfig,
|
|
19
|
-
type AgentConfig,
|
|
20
|
-
} from '../utils/config-loader'
|
|
10
|
+
import { createAuthenticatedClient } from '../client'
|
|
21
11
|
|
|
22
12
|
/**
|
|
23
13
|
* Check if current directory has git
|
|
@@ -40,18 +30,6 @@ async function mergeConfigurations(
|
|
|
40
30
|
try {
|
|
41
31
|
const client = createAuthenticatedClient()
|
|
42
32
|
|
|
43
|
-
// Get model config with fallback for init scenario
|
|
44
|
-
let modelConfig: { primary: string; small: string }
|
|
45
|
-
try {
|
|
46
|
-
modelConfig = getModelConfig()
|
|
47
|
-
} catch (error) {
|
|
48
|
-
// Fallback to defaults when no config exists (init scenario)
|
|
49
|
-
modelConfig = {
|
|
50
|
-
primary: 'berget/glm-4.7',
|
|
51
|
-
small: 'berget/gpt-oss',
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
33
|
console.log(chalk.blue('🤖 Using AI to merge configurations...'))
|
|
56
34
|
|
|
57
35
|
const mergePrompt = `You are a configuration merge specialist. Merge these two OpenCode configurations:
|
|
@@ -73,7 +51,7 @@ Return ONLY the merged JSON configuration, no explanations.`
|
|
|
73
51
|
|
|
74
52
|
const response = await client.POST('/v1/chat/completions', {
|
|
75
53
|
body: {
|
|
76
|
-
model:
|
|
54
|
+
model: 'glm-4.7',
|
|
77
55
|
messages: [
|
|
78
56
|
{
|
|
79
57
|
role: 'user',
|
|
@@ -290,7 +268,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
290
268
|
// Return the latest agent configuration directly - no file reading needed
|
|
291
269
|
return {
|
|
292
270
|
fullstack: {
|
|
293
|
-
model: 'berget/glm-4.7',
|
|
294
271
|
temperature: 0.3,
|
|
295
272
|
top_p: 0.9,
|
|
296
273
|
mode: 'primary',
|
|
@@ -301,7 +278,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
301
278
|
"Voice: Scandinavian calm—precise, concise, confident; no fluff. You are Berget Code Fullstack agent. Act as a router and coordinator in a monorepo. Bottom-up schema: database → OpenAPI → generated types. Top-down types: API → UI → components. Use openapi-fetch and Zod at every boundary; compile-time errors are desired when contracts change. Routing rules: if task/paths match /apps/frontend or React (.tsx) → use frontend; if /apps/app or Expo/React Native → app; if /infra, /k8s, flux-system, kustomization.yaml, Helm values → devops; if /services, Koa routers, services/adapters/domain → backend. If ambiguous, remain fullstack and outline the end-to-end plan, then delegate subtasks to the right persona. Security: validate inputs; secrets via FluxCD SOPS/Sealed Secrets. Documentation is generated from code—never duplicated.\n\nGIT WORKFLOW RULES (CRITICAL):\n- NEVER push directly to main branch - ALWAYS use pull requests\n- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'\n- ALWAYS clean up test files, documentation files, and temporary artifacts before committing\n- ALWAYS ensure git history maintains production quality - no test commits, no debugging code\n- ALWAYS create descriptive commit messages following project conventions\n- ALWAYS run tests and build before creating PR\n\nCRITICAL: When all implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.",
|
|
302
279
|
},
|
|
303
280
|
frontend: {
|
|
304
|
-
model: 'berget/glm-4.7',
|
|
305
281
|
temperature: 0.4,
|
|
306
282
|
top_p: 0.9,
|
|
307
283
|
mode: 'primary',
|
|
@@ -313,7 +289,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
313
289
|
'You are Berget Code Frontend agent. Voice: Scandinavian calm—precise, concise, confident. React 18 + TypeScript. Tailwind + Shadcn UI only via the design system (index.css, tailwind.config.ts). Use semantic tokens for color/spacing/typography/motion; never ad-hoc classes or inline colors. Components are pure and responsive; props-first data; minimal global state (Zustand/Jotai). Accessibility and keyboard navigation mandatory. Mock data only at init under /data via typed hooks (e.g., useProducts() reading /data/products.json). Design: minimal, balanced, quiet motion.\n\nIMPORTANT: You have NO bash access and cannot run git commands. When your frontend implementation tasks are complete, inform the user that changes are ready and suggest using /pr command to create a pull request with proper testing and quality checks.\n\nCODE QUALITY RULES:\n- Write clean, production-ready code\n- Follow React and TypeScript best practices\n- Ensure accessibility and responsive design\n- Use semantic tokens from design system\n- Test your components manually when possible\n- Document any complex logic with comments\n\nCRITICAL: When frontend implementation is complete, ALWAYS inform the user to use "/pr" command to handle testing, building, and pull request creation.',
|
|
314
290
|
},
|
|
315
291
|
backend: {
|
|
316
|
-
model: 'berget/glm-4.7',
|
|
317
292
|
temperature: 0.3,
|
|
318
293
|
top_p: 0.9,
|
|
319
294
|
mode: 'primary',
|
|
@@ -324,7 +299,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
324
299
|
"You are Berget Code Backend agent. Voice: Scandinavian calm—precise, concise, confident. TypeScript + Koa. Prefer many small pure functions; avoid big try/catch blocks. Routes thin; logic in services/adapters/domain. Validate with Zod; auto-generate OpenAPI. Adapters isolate external systems; domain never depends on framework. Test with supertest; idempotent and stateless by default. Each microservice emits an OpenAPI contract; changes propagate upward to types. Code Quality & Refactoring Principles: Apply Single Responsibility Principle, fail fast with explicit errors, eliminate code duplication, remove nested complexity, use descriptive error codes, keep functions under 30 lines. Always leave code cleaner and more readable than you found it.\n\nGIT WORKFLOW RULES (CRITICAL):\n- NEVER push directly to main branch - ALWAYS use pull requests\n- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'\n- ALWAYS clean up test files, documentation files, and temporary artifacts before committing\n- ALWAYS ensure git history maintains production quality - no test commits, no debugging code\n- ALWAYS create descriptive commit messages following project conventions\n- ALWAYS run tests and build before creating PR\n\nCRITICAL: When all backend implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.",
|
|
325
300
|
},
|
|
326
301
|
devops: {
|
|
327
|
-
model: 'berget/glm-4.7',
|
|
328
302
|
temperature: 0.3,
|
|
329
303
|
top_p: 0.8,
|
|
330
304
|
mode: 'primary',
|
|
@@ -335,7 +309,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
335
309
|
"You are Berget Code DevOps agent. Voice: Scandinavian calm—precise, concise, confident. Start simple: k8s/{deployment,service,ingress}. Add FluxCD sync to repo and image automation. Use Kustomize bases/overlays (staging, production). Add dependencies via Helm from upstream sources; prefer native operators when available (CloudNativePG, cert-manager, external-dns). SemVer with -rc tags keeps CI environments current. Observability with Prometheus/Grafana. No manual kubectl in production—Git is the source of truth.\n\nGIT WORKFLOW RULES (CRITICAL):\n- NEVER push directly to main branch - ALWAYS use pull requests\n- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'\n- ALWAYS clean up test files, documentation files, and temporary artifacts before committing\n- ALWAYS ensure git history maintains production quality - no test commits, no debugging code\n- ALWAYS create descriptive commit messages following project conventions\n- ALWAYS run tests and build before creating PR\n\nHelm Values Configuration Process:\n1. Documentation First Approach: Always fetch official documentation from Artifact Hub/GitHub for the specific chart version before writing values. Search Artifact Hub for exact chart version documentation, check the chart's GitHub repository for official docs and examples, verify the exact version being used in the deployment.\n2. Validation Requirements: Check for available validation schemas before committing YAML files. Use Helm's built-in validation tools (helm lint, helm template). Validate against JSON schema if available for the chart. Ensure YAML syntax correctness with linters.\n3. Standard Workflow: Identify chart name and exact version. Fetch official documentation from Artifact Hub/GitHub. Check for available schemas and validation tools. Write values according to official documentation. Validate against schema (if available). Test with helm template or helm lint. Commit validated YAML files.\n4. Quality Assurance: Never commit unvalidated Helm values. Use helm dependency update when adding new charts. Test rendering with helm template --dry-run before deployment. Document any custom values with comments referencing official docs.",
|
|
336
310
|
},
|
|
337
311
|
app: {
|
|
338
|
-
model: 'berget/glm-4.7',
|
|
339
312
|
temperature: 0.4,
|
|
340
313
|
top_p: 0.9,
|
|
341
314
|
mode: 'primary',
|
|
@@ -347,7 +320,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
347
320
|
"You are Berget Code App agent. Voice: Scandinavian calm—precise, concise, confident. Expo + React Native + TypeScript. Structure by components/hooks/services/navigation. Components are pure; data via props; refactor shared logic into hooks/stores. Share tokens with frontend. Mock data in /data via typed hooks; later replace with live APIs. Offline via SQLite/MMKV; notifications via Expo. Request permissions only when needed. Subtle, meaningful motion; light/dark parity.\n\nGIT WORKFLOW RULES (CRITICAL):\n- NEVER push directly to main branch - ALWAYS use pull requests\n- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'\n- ALWAYS clean up test files, documentation files, and temporary artifacts before committing\n- ALWAYS ensure git history maintains production quality - no test commits, no debugging code\n- ALWAYS create descriptive commit messages following project conventions\n- ALWAYS run tests and build before creating PR\n\nCRITICAL: When all app implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.",
|
|
348
321
|
},
|
|
349
322
|
security: {
|
|
350
|
-
model: 'berget/glm-4.7',
|
|
351
323
|
temperature: 0.2,
|
|
352
324
|
top_p: 0.8,
|
|
353
325
|
mode: 'subagent',
|
|
@@ -358,7 +330,6 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
358
330
|
"Voice: Scandinavian calm—precise, concise, confident. You are Berget Code Security agent. Expert in application security, penetration testing, and OWASP standards. Core responsibilities: Conduct security assessments and penetration tests, Validate OWASP Top 10 compliance, Review code for security vulnerabilities, Implement security headers and Content Security Policy (CSP), Audit API security, Check for sensitive data exposure, Validate input sanitization and output encoding, Assess dependency security and supply chain risks. Tools and techniques: OWASP ZAP, Burp Suite, security linters, dependency scanners, manual code review. Always provide specific, actionable security recommendations with priority levels.\n\nGIT WORKFLOW RULES (CRITICAL):\n- NEVER push directly to main branch - ALWAYS use pull requests\n- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'\n- ALWAYS clean up test files, documentation files, and temporary artifacts before committing\n- ALWAYS ensure git history maintains production quality - no test commits, no debugging code\n- ALWAYS create descriptive commit messages following project conventions\n- ALWAYS run tests and build before creating PR",
|
|
359
331
|
},
|
|
360
332
|
quality: {
|
|
361
|
-
model: 'berget/glm-4.7',
|
|
362
333
|
temperature: 0.1,
|
|
363
334
|
top_p: 0.9,
|
|
364
335
|
mode: 'subagent',
|
|
@@ -398,7 +369,7 @@ async function installOpencode(): Promise<boolean> {
|
|
|
398
369
|
|
|
399
370
|
try {
|
|
400
371
|
await new Promise<void>((resolve, reject) => {
|
|
401
|
-
const install = spawn('npm', ['install', '-g', 'opencode-ai'], {
|
|
372
|
+
const install = spawn('npm', ['install', '-g', 'opencode-ai@1.2.27'], {
|
|
402
373
|
stdio: 'inherit',
|
|
403
374
|
})
|
|
404
375
|
|
|
@@ -520,188 +491,24 @@ export function registerCodeCommands(program: Command): void {
|
|
|
520
491
|
return
|
|
521
492
|
}
|
|
522
493
|
|
|
523
|
-
// Check if we have an API key in environment first
|
|
524
|
-
if (process.env.BERGET_API_KEY) {
|
|
525
|
-
console.log(
|
|
526
|
-
chalk.blue(
|
|
527
|
-
'🔑 Using BERGET_API_KEY from environment - no authentication required'
|
|
528
|
-
)
|
|
529
|
-
)
|
|
530
|
-
} else {
|
|
531
|
-
// Only require authentication if we don't have an API key
|
|
532
|
-
const authService = AuthService.getInstance()
|
|
533
|
-
const profile = await authService.whoami()
|
|
534
|
-
|
|
535
|
-
if (!profile) {
|
|
536
|
-
console.log(chalk.red('❌ Not authenticated with Berget AI.'))
|
|
537
|
-
console.log(chalk.blue('To get started, you have two options:'))
|
|
538
|
-
console.log('')
|
|
539
|
-
console.log(
|
|
540
|
-
chalk.yellow('Option 1: Use an existing API key (recommended)')
|
|
541
|
-
)
|
|
542
|
-
console.log(
|
|
543
|
-
chalk.cyan(' Set BERGET_API_KEY environment variable:')
|
|
544
|
-
)
|
|
545
|
-
console.log(
|
|
546
|
-
chalk.dim(' export BERGET_API_KEY=your_api_key_here')
|
|
547
|
-
)
|
|
548
|
-
console.log(chalk.cyan(' Or create a .env file in your project:'))
|
|
549
|
-
console.log(
|
|
550
|
-
chalk.dim(' echo "BERGET_API_KEY=your_api_key_here" > .env')
|
|
551
|
-
)
|
|
552
|
-
console.log('')
|
|
553
|
-
console.log(
|
|
554
|
-
chalk.yellow('Option 2: Login and create a new API key')
|
|
555
|
-
)
|
|
556
|
-
console.log(chalk.cyan(' berget auth login'))
|
|
557
|
-
console.log(
|
|
558
|
-
chalk.cyan(
|
|
559
|
-
` berget ${COMMAND_GROUPS.CODE} ${SUBCOMMANDS.CODE.INIT}`
|
|
560
|
-
)
|
|
561
|
-
)
|
|
562
|
-
console.log('')
|
|
563
|
-
console.log(chalk.blue('Then try again.'))
|
|
564
|
-
return
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
494
|
console.log(
|
|
569
495
|
chalk.cyan(`Initializing OpenCode for project: ${projectName}`)
|
|
570
496
|
)
|
|
571
497
|
|
|
572
|
-
// Handle API key selection or creation
|
|
573
|
-
let apiKey: string
|
|
574
|
-
let keyName: string
|
|
575
|
-
|
|
576
|
-
try {
|
|
577
|
-
const apiKeyService = ApiKeyService.getInstance()
|
|
578
|
-
|
|
579
|
-
if (process.env.BERGET_API_KEY) {
|
|
580
|
-
if (options.yes) {
|
|
581
|
-
console.log(chalk.blue('🔑 Using BERGET_API_KEY from environment'))
|
|
582
|
-
apiKey = process.env.BERGET_API_KEY
|
|
583
|
-
keyName = `env-key-${projectName}`
|
|
584
|
-
} else {
|
|
585
|
-
console.log(chalk.blue('\n📋 API key setup:'))
|
|
586
|
-
console.log(chalk.dim('─'.repeat(60)))
|
|
587
|
-
console.log(
|
|
588
|
-
`${chalk.cyan('1')} ${chalk.bold('Use existing API key')}`
|
|
589
|
-
)
|
|
590
|
-
console.log(chalk.dim(' Uses BERGET_API_KEY from environment'))
|
|
591
|
-
console.log(
|
|
592
|
-
`${chalk.cyan('2')} ${chalk.bold('Create a new API key')}`
|
|
593
|
-
)
|
|
594
|
-
console.log(chalk.dim('─'.repeat(60)))
|
|
595
|
-
|
|
596
|
-
const choice = await new Promise<string>((resolve) => {
|
|
597
|
-
const rl = readline.createInterface({
|
|
598
|
-
input: process.stdin,
|
|
599
|
-
output: process.stdout,
|
|
600
|
-
})
|
|
601
|
-
rl.question(chalk.blue('\nSelect an option (1-2, default: 1): '), (answer) => {
|
|
602
|
-
rl.close()
|
|
603
|
-
resolve(answer.trim() || '1')
|
|
604
|
-
})
|
|
605
|
-
})
|
|
606
|
-
|
|
607
|
-
if (choice === '1') {
|
|
608
|
-
console.log(chalk.blue('🔑 Using BERGET_API_KEY from environment'))
|
|
609
|
-
apiKey = process.env.BERGET_API_KEY
|
|
610
|
-
keyName = `env-key-${projectName}`
|
|
611
|
-
} else if (choice === '2') {
|
|
612
|
-
console.log(chalk.blue('\n🔑 Creating new API key...'))
|
|
613
|
-
|
|
614
|
-
const defaultKeyName = `opencode-${projectName}-${Date.now()}`
|
|
615
|
-
const customName = await getInput(
|
|
616
|
-
chalk.blue(`Enter key name (default: ${defaultKeyName}): `),
|
|
617
|
-
defaultKeyName,
|
|
618
|
-
options.yes
|
|
619
|
-
)
|
|
620
|
-
|
|
621
|
-
keyName = customName
|
|
622
|
-
const createOptions: CreateApiKeyOptions = { name: keyName }
|
|
623
|
-
const keyData = await apiKeyService.create(createOptions)
|
|
624
|
-
apiKey = keyData.key
|
|
625
|
-
console.log(chalk.green(`✓ Created new API key: ${keyName}`))
|
|
626
|
-
} else {
|
|
627
|
-
console.log(chalk.red('Invalid selection.'))
|
|
628
|
-
return
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
} else {
|
|
632
|
-
if (!options.yes) {
|
|
633
|
-
console.log(chalk.yellow('No BERGET_API_KEY environment variable found.'))
|
|
634
|
-
console.log(chalk.blue('Creating a new API key...'))
|
|
635
|
-
console.log(chalk.dim('\n💡 Tip: Set BERGET_API_KEY environment variable to reuse an existing key:'))
|
|
636
|
-
console.log(chalk.dim(' export BERGET_API_KEY=your_api_key_here'))
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
const defaultKeyName = `opencode-${projectName}-${Date.now()}`
|
|
640
|
-
const customName = await getInput(
|
|
641
|
-
chalk.blue(`Enter key name (default: ${defaultKeyName}): `),
|
|
642
|
-
defaultKeyName,
|
|
643
|
-
options.yes
|
|
644
|
-
)
|
|
645
|
-
|
|
646
|
-
keyName = customName
|
|
647
|
-
const createOptions: CreateApiKeyOptions = { name: keyName }
|
|
648
|
-
const keyData = await apiKeyService.create(createOptions)
|
|
649
|
-
apiKey = keyData.key
|
|
650
|
-
console.log(chalk.green(`✓ Created new API key: ${keyName}`))
|
|
651
|
-
}
|
|
652
|
-
} catch (error) {
|
|
653
|
-
if (process.env.BERGET_API_KEY) {
|
|
654
|
-
console.log(
|
|
655
|
-
chalk.yellow(
|
|
656
|
-
'⚠️ Could not verify API key with Berget API, but continuing with environment key'
|
|
657
|
-
)
|
|
658
|
-
)
|
|
659
|
-
console.log(
|
|
660
|
-
chalk.dim('This might be due to network issues or an invalid key')
|
|
661
|
-
)
|
|
662
|
-
} else {
|
|
663
|
-
console.error(chalk.red('❌ Failed to handle API keys:'))
|
|
664
|
-
console.log(chalk.blue('This could be due to:'))
|
|
665
|
-
console.log(chalk.dim(' • Network connectivity issues'))
|
|
666
|
-
console.log(chalk.dim(' • Invalid authentication credentials'))
|
|
667
|
-
console.log(chalk.dim(' • API service temporarily unavailable'))
|
|
668
|
-
console.log('')
|
|
669
|
-
console.log(chalk.blue('Try using an API key directly:'))
|
|
670
|
-
console.log(chalk.cyan(' export BERGET_API_KEY=your_api_key_here'))
|
|
671
|
-
console.log(
|
|
672
|
-
chalk.cyan(
|
|
673
|
-
` berget ${COMMAND_GROUPS.CODE} ${SUBCOMMANDS.CODE.INIT} --yes`
|
|
674
|
-
)
|
|
675
|
-
)
|
|
676
|
-
handleError('API key operation failed', error)
|
|
677
|
-
}
|
|
678
|
-
return
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// Prepare .env file path for safe update
|
|
682
|
-
const envPath = path.join(process.cwd(), '.env')
|
|
683
|
-
|
|
684
498
|
// Load latest agent configuration from our own codebase
|
|
685
499
|
const latestAgentConfig = await loadLatestAgentConfig()
|
|
686
500
|
|
|
687
501
|
// Use hardcoded defaults for init - never try to load from project
|
|
688
|
-
|
|
689
|
-
primary: 'berget/glm-4.7',
|
|
690
|
-
small: 'berget/gpt-oss',
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// Create opencode.json config with optimized agent-based format
|
|
502
|
+
// Create opencode.json config — plugin handles auth, models, and provider
|
|
694
503
|
const config = {
|
|
695
504
|
$schema: 'https://opencode.ai/config.json',
|
|
505
|
+
plugin: ['@bergetai/opencode-auth@1.0.9'],
|
|
696
506
|
username: 'berget-code',
|
|
697
507
|
theme: 'berget-dark',
|
|
698
508
|
share: 'manual',
|
|
699
509
|
autoupdate: true,
|
|
700
|
-
model: modelConfig.primary,
|
|
701
|
-
small_model: modelConfig.small,
|
|
702
510
|
agent: {
|
|
703
511
|
fullstack: {
|
|
704
|
-
model: modelConfig.primary,
|
|
705
512
|
temperature: 0.3,
|
|
706
513
|
top_p: 0.9,
|
|
707
514
|
mode: 'primary',
|
|
@@ -712,7 +519,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
712
519
|
'Voice: Scandinavian calm—precise, concise, confident; no fluff. You are Berget Code Fullstack agent. Act as a router and coordinator in a monorepo. Bottom-up schema: database → OpenAPI → generated types. Top-down types: API → UI → components. Use openapi-fetch and Zod at every boundary; compile-time errors are desired when contracts change. Routing rules: if task/paths match /apps/frontend or React (.tsx) → use frontend; if /apps/app or Expo/React Native → app; if /infra, /k8s, flux-system, kustomization.yaml, Helm values → devops; if /services, Koa routers, services/adapters/domain → backend. If ambiguous, remain fullstack and outline the end-to-end plan, then delegate subtasks to the right persona. Security: validate inputs; secrets via FluxCD SOPS/Sealed Secrets. Documentation is generated from code—never duplicated. CRITICAL: When all implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.',
|
|
713
520
|
},
|
|
714
521
|
frontend: {
|
|
715
|
-
model: modelConfig.primary,
|
|
716
522
|
temperature: 0.4,
|
|
717
523
|
top_p: 0.9,
|
|
718
524
|
mode: 'primary',
|
|
@@ -724,7 +530,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
724
530
|
'You are Berget Code Frontend agent. Voice: Scandinavian calm—precise, concise, confident. React 18 + TypeScript. Tailwind + Shadcn UI only via the design system (index.css, tailwind.config.ts). Use semantic tokens for color/spacing/typography/motion; never ad-hoc classes or inline colors. Components are pure and responsive; props-first data; minimal global state (Zustand/Jotai). Accessibility and keyboard navigation mandatory. Mock data only at init under /data via typed hooks (e.g., useProducts() reading /data/products.json). Design: minimal, balanced, quiet motion. CRITICAL: When all frontend implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.',
|
|
725
531
|
},
|
|
726
532
|
backend: {
|
|
727
|
-
model: modelConfig.primary,
|
|
728
533
|
temperature: 0.3,
|
|
729
534
|
top_p: 0.9,
|
|
730
535
|
mode: 'primary',
|
|
@@ -736,7 +541,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
736
541
|
},
|
|
737
542
|
// Use centralized devops configuration with Helm guidelines
|
|
738
543
|
devops: latestAgentConfig.devops || {
|
|
739
|
-
model: modelConfig.primary,
|
|
740
544
|
temperature: 0.3,
|
|
741
545
|
top_p: 0.8,
|
|
742
546
|
mode: 'primary',
|
|
@@ -747,7 +551,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
747
551
|
'You are Berget Code DevOps agent. Voice: Scandinavian calm—precise, concise, confident. Start simple: k8s/{deployment,service,ingress}. Add FluxCD sync to repo and image automation. Use Kustomize bases/overlays (staging, production). Add dependencies via Helm from upstream sources; prefer native operators when available (CloudNativePG, cert-manager, external-dns). SemVer with -rc tags keeps CI environments current. Observability with Prometheus/Grafana. No manual kubectl in production—Git is the source of truth.',
|
|
748
552
|
},
|
|
749
553
|
app: {
|
|
750
|
-
model: modelConfig.primary,
|
|
751
554
|
temperature: 0.4,
|
|
752
555
|
top_p: 0.9,
|
|
753
556
|
mode: 'primary',
|
|
@@ -759,7 +562,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
759
562
|
'You are Berget Code App agent. Voice: Scandinavian calm—precise, concise, confident. Expo + React Native + TypeScript. Structure by components/hooks/services/navigation. Components are pure; data via props; refactor shared logic into hooks/stores. Share tokens with frontend. Mock data in /data via typed hooks; later replace with live APIs. Offline via SQLite/MMKV; notifications via Expo. Request permissions only when needed. Subtle, meaningful motion; light/dark parity.',
|
|
760
563
|
},
|
|
761
564
|
security: {
|
|
762
|
-
model: modelConfig.primary,
|
|
763
565
|
temperature: 0.2,
|
|
764
566
|
top_p: 0.8,
|
|
765
567
|
mode: 'subagent',
|
|
@@ -770,7 +572,6 @@ export function registerCodeCommands(program: Command): void {
|
|
|
770
572
|
'Voice: Scandinavian calm—precise, concise, confident. You are Berget Code Security agent. Expert in application security, penetration testing, and OWASP standards. Core responsibilities: Conduct security assessments and penetration tests, Validate OWASP Top 10 compliance, Review code for security vulnerabilities, Implement security headers and Content Security Policy (CSP), Audit API security, Check for sensitive data exposure, Validate input sanitization and output encoding, Assess dependency security and supply chain risks. Tools and techniques: OWASP ZAP, Burp Suite, security linters, dependency scanners, manual code review. Always provide specific, actionable security recommendations with priority levels.',
|
|
771
573
|
},
|
|
772
574
|
quality: {
|
|
773
|
-
model: modelConfig.primary,
|
|
774
575
|
temperature: 0.1,
|
|
775
576
|
top_p: 0.9,
|
|
776
577
|
mode: 'subagent',
|
|
@@ -824,71 +625,14 @@ export function registerCodeCommands(program: Command): void {
|
|
|
824
625
|
watcher: {
|
|
825
626
|
ignore: ['node_modules', 'dist', '.git', 'coverage'],
|
|
826
627
|
},
|
|
827
|
-
provider: {
|
|
828
|
-
berget: {
|
|
829
|
-
npm: '@ai-sdk/openai-compatible',
|
|
830
|
-
name: 'Berget AI',
|
|
831
|
-
options: {
|
|
832
|
-
baseURL: '{env:BERGET_API_URL}',
|
|
833
|
-
apiKey: '{env:BERGET_API_KEY}',
|
|
834
|
-
},
|
|
835
|
-
models: {
|
|
836
|
-
'glm-4.7': {
|
|
837
|
-
name: 'GLM-4.7',
|
|
838
|
-
limit: { output: 4000, context: 200000 },
|
|
839
|
-
modalities: { input: ['text'], output: ['text'] },
|
|
840
|
-
},
|
|
841
|
-
'gpt-oss': {
|
|
842
|
-
name: 'GPT-OSS',
|
|
843
|
-
limit: { output: 4000, context: 128000 },
|
|
844
|
-
modalities: { input: ['text', 'image'], output: ['text'] },
|
|
845
|
-
},
|
|
846
|
-
'llama-8b': {
|
|
847
|
-
name: 'llama-3.1-8b',
|
|
848
|
-
limit: { output: 4000, context: 128000 },
|
|
849
|
-
},
|
|
850
|
-
},
|
|
851
|
-
},
|
|
852
|
-
},
|
|
853
628
|
}
|
|
854
629
|
|
|
855
630
|
// Ask for permission to create config files
|
|
856
631
|
if (!options.yes) {
|
|
857
632
|
console.log(chalk.blue('\nAbout to create configuration files:'))
|
|
858
633
|
console.log(chalk.dim(`Config: ${configPath}`))
|
|
859
|
-
console.log(chalk.dim(`Environment: ${envPath}`))
|
|
860
|
-
console.log(
|
|
861
|
-
chalk.dim(
|
|
862
|
-
`Documentation: ${path.join(
|
|
863
|
-
process.cwd(),
|
|
864
|
-
'AGENTS.md'
|
|
865
|
-
)} (if not exists)`
|
|
866
|
-
)
|
|
867
|
-
)
|
|
868
634
|
console.log(
|
|
869
|
-
chalk.dim(
|
|
870
|
-
`Environment: ${path.join(process.cwd(), '.env')} will be updated`
|
|
871
|
-
)
|
|
872
|
-
)
|
|
873
|
-
console.log(
|
|
874
|
-
chalk.dim('This will configure OpenCode to use Berget AI models.')
|
|
875
|
-
)
|
|
876
|
-
console.log(chalk.cyan('\n💡 Benefits:'))
|
|
877
|
-
console.log(
|
|
878
|
-
chalk.cyan(
|
|
879
|
-
' • API key stored separately in .env file (not committed to Git)'
|
|
880
|
-
)
|
|
881
|
-
)
|
|
882
|
-
console.log(
|
|
883
|
-
chalk.cyan(' • Easy cost separation per project/customer')
|
|
884
|
-
)
|
|
885
|
-
console.log(
|
|
886
|
-
chalk.cyan(' • Secure key management with environment variables')
|
|
887
|
-
)
|
|
888
|
-
console.log(
|
|
889
|
-
chalk.cyan(
|
|
890
|
-
" • Project-specific agent documentation (won't overwrite existing)"
|
|
891
|
-
)
|
|
635
|
+
chalk.dim('This will configure OpenCode with the Berget auth plugin.')
|
|
892
636
|
)
|
|
893
637
|
}
|
|
894
638
|
|
|
@@ -896,217 +640,11 @@ export function registerCodeCommands(program: Command): void {
|
|
|
896
640
|
await confirm('\nCreate configuration files? (Y/n): ', options.yes)
|
|
897
641
|
) {
|
|
898
642
|
try {
|
|
899
|
-
// Safely update .env file using dotenv
|
|
900
|
-
await updateEnvFile({
|
|
901
|
-
envPath,
|
|
902
|
-
key: 'BERGET_API_KEY',
|
|
903
|
-
value: apiKey,
|
|
904
|
-
comment: `Berget AI Configuration for ${projectName} - Generated by berget code init - Do not commit to version control`,
|
|
905
|
-
})
|
|
906
|
-
|
|
907
643
|
// Create opencode.json
|
|
908
644
|
await writeFile(configPath, JSON.stringify(config, null, 2))
|
|
909
645
|
console.log(chalk.green(`✓ Created opencode.json`))
|
|
910
|
-
console.log(chalk.dim(`
|
|
911
|
-
console.log(chalk.dim(` Small Model: ${config.small_model}`))
|
|
646
|
+
console.log(chalk.dim(` Plugin: @bergetai/opencode-auth`))
|
|
912
647
|
console.log(chalk.dim(` Theme: ${config.theme}`))
|
|
913
|
-
console.log(
|
|
914
|
-
chalk.dim(` API Key: Stored in .env as BERGET_API_KEY`)
|
|
915
|
-
)
|
|
916
|
-
|
|
917
|
-
// Create AGENTS.md documentation only if it doesn't exist
|
|
918
|
-
const agentsMdPath = path.join(process.cwd(), 'AGENTS.md')
|
|
919
|
-
if (!fs.existsSync(agentsMdPath)) {
|
|
920
|
-
const agentsMdContent = `# Berget Code Agents
|
|
921
|
-
|
|
922
|
-
This document describes the specialized agents available in this project for use with OpenCode.
|
|
923
|
-
|
|
924
|
-
## Available Agents
|
|
925
|
-
|
|
926
|
-
### Primary Agents
|
|
927
|
-
|
|
928
|
-
#### fullstack
|
|
929
|
-
Router/coordinator agent for full-stack development with schema-driven architecture. Handles routing between different personas based on file paths and task requirements.
|
|
930
|
-
|
|
931
|
-
**Use when:**
|
|
932
|
-
- Working across multiple parts of a monorepo
|
|
933
|
-
- Need to coordinate between frontend, backend, devops, and app
|
|
934
|
-
- Starting new projects and need to determine tech stack
|
|
935
|
-
|
|
936
|
-
**Key features:**
|
|
937
|
-
- Schema-driven development (database → OpenAPI → types)
|
|
938
|
-
- Automatic routing to appropriate persona
|
|
939
|
-
- Tech stack discovery and recommendations
|
|
940
|
-
|
|
941
|
-
#### frontend
|
|
942
|
-
Builds Scandinavian, type-safe UIs with React, Tailwind, and Shadcn.
|
|
943
|
-
|
|
944
|
-
**Use when:**
|
|
945
|
-
- Working with React components (.tsx files)
|
|
946
|
-
- Frontend development in /apps/frontend
|
|
947
|
-
- UI/UX implementation
|
|
948
|
-
|
|
949
|
-
**Key features:**
|
|
950
|
-
- Design system integration
|
|
951
|
-
- Semantic tokens and accessibility
|
|
952
|
-
- Props-first component architecture
|
|
953
|
-
|
|
954
|
-
#### backend
|
|
955
|
-
Functional, modular Koa + TypeScript services with schema-first approach and code quality focus.
|
|
956
|
-
|
|
957
|
-
**Use when:**
|
|
958
|
-
- Working with Koa routers and services
|
|
959
|
-
- Backend development in /services
|
|
960
|
-
- API development and database work
|
|
961
|
-
|
|
962
|
-
**Key features:**
|
|
963
|
-
- Zod validation and OpenAPI generation
|
|
964
|
-
- Code quality and refactoring principles
|
|
965
|
-
- PR workflow integration
|
|
966
|
-
|
|
967
|
-
#### devops
|
|
968
|
-
Declarative GitOps infrastructure with FluxCD, Kustomize, Helm, and operators.
|
|
969
|
-
|
|
970
|
-
**Use when:**
|
|
971
|
-
- Working with Kubernetes manifests
|
|
972
|
-
- Infrastructure in /infra or /k8s
|
|
973
|
-
- CI/CD and deployment configurations
|
|
974
|
-
|
|
975
|
-
**Key features:**
|
|
976
|
-
- GitOps workflows
|
|
977
|
-
- Operator-first approach
|
|
978
|
-
- SemVer with release candidates
|
|
979
|
-
|
|
980
|
-
**Helm Values Configuration Process:**
|
|
981
|
-
1. Documentation First Approach: Always fetch official documentation from Artifact Hub/GitHub for the specific chart version before writing values. Search Artifact Hub for exact chart version documentation, check the chart's GitHub repository for official docs and examples, verify the exact version being used in the deployment.
|
|
982
|
-
2. Validation Requirements: Check for available validation schemas before committing YAML files. Use Helm's built-in validation tools (helm lint, helm template). Validate against JSON schema if available for the chart. Ensure YAML syntax correctness with linters.
|
|
983
|
-
3. Standard Workflow: Identify chart name and exact version. Fetch official documentation from Artifact Hub/GitHub. Check for available schemas and validation tools. Write values according to official documentation. Validate against schema (if available). Test with helm template or helm lint. Commit validated YAML files.
|
|
984
|
-
4. Quality Assurance: Never commit unvalidated Helm values. Use helm dependency update when adding new charts. Test rendering with helm template --dry-run before deployment. Document any custom values with comments referencing official docs.
|
|
985
|
-
|
|
986
|
-
#### app
|
|
987
|
-
Expo + React Native applications with props-first architecture and offline awareness.
|
|
988
|
-
|
|
989
|
-
**Use when:**
|
|
990
|
-
- Mobile app development with Expo
|
|
991
|
-
- React Native projects in /apps/app
|
|
992
|
-
- Cross-platform mobile development
|
|
993
|
-
|
|
994
|
-
**Key features:**
|
|
995
|
-
- Shared design tokens with frontend
|
|
996
|
-
- Offline-first architecture
|
|
997
|
-
- Expo integration
|
|
998
|
-
|
|
999
|
-
### Subagents
|
|
1000
|
-
|
|
1001
|
-
#### security
|
|
1002
|
-
Security specialist for penetration testing, OWASP compliance, and vulnerability assessments.
|
|
1003
|
-
|
|
1004
|
-
**Use when:**
|
|
1005
|
-
- Need security review of code changes
|
|
1006
|
-
- OWASP Top 10 compliance checks
|
|
1007
|
-
- Vulnerability assessments
|
|
1008
|
-
|
|
1009
|
-
**Key features:**
|
|
1010
|
-
- OWASP standards compliance
|
|
1011
|
-
- Security best practices
|
|
1012
|
-
- Actionable remediation strategies
|
|
1013
|
-
|
|
1014
|
-
#### quality
|
|
1015
|
-
Quality assurance specialist for testing, building, and PR management.
|
|
1016
|
-
|
|
1017
|
-
**Use when:**
|
|
1018
|
-
- Need to run test suites and build processes
|
|
1019
|
-
- Creating or updating pull requests
|
|
1020
|
-
- Monitoring GitHub for reviewer comments
|
|
1021
|
-
- Ensuring code quality standards
|
|
1022
|
-
|
|
1023
|
-
**Key features:**
|
|
1024
|
-
- Comprehensive testing and building workflows
|
|
1025
|
-
- PR creation and management
|
|
1026
|
-
- GitHub integration for reviewer feedback
|
|
1027
|
-
- CLI command expertise for quality assurance
|
|
1028
|
-
|
|
1029
|
-
## Usage
|
|
1030
|
-
|
|
1031
|
-
### Switching Agents
|
|
1032
|
-
Use the \`<tab>\` key to cycle through primary agents during a session.
|
|
1033
|
-
|
|
1034
|
-
### Manual Agent Selection
|
|
1035
|
-
Use commands to switch to specific agents:
|
|
1036
|
-
- \`/fullstack\` - Switch to Fullstack agent
|
|
1037
|
-
- \`/frontend\` - Switch to Frontend agent
|
|
1038
|
-
- \`/backend\` - Switch to Backend agent
|
|
1039
|
-
- \`/devops\` - Switch to DevOps agent
|
|
1040
|
-
- \`/app\` - Switch to App agent
|
|
1041
|
-
- \`/quality\` - Switch to Quality agent for testing and PR management
|
|
1042
|
-
|
|
1043
|
-
### Using Subagents
|
|
1044
|
-
Mention subagents with \`@\` symbol:
|
|
1045
|
-
- \`@security review this authentication implementation\`
|
|
1046
|
-
- \`@quality run tests and create PR for these changes\`
|
|
1047
|
-
|
|
1048
|
-
## Routing Rules
|
|
1049
|
-
|
|
1050
|
-
The fullstack agent automatically routes tasks based on file patterns:
|
|
1051
|
-
|
|
1052
|
-
- \`/apps/frontend\` or \`.tsx\` files → frontend
|
|
1053
|
-
- \`/apps/app\` or Expo/React Native → app
|
|
1054
|
-
- \`/infra\`, \`/k8s\`, FluxCD, Helm → devops
|
|
1055
|
-
- \`/services\`, Koa routers → backend
|
|
1056
|
-
|
|
1057
|
-
## Configuration
|
|
1058
|
-
|
|
1059
|
-
All agents are configured in \`opencode.json\` with:
|
|
1060
|
-
- Specialized prompts and temperature settings
|
|
1061
|
-
- Appropriate tool permissions
|
|
1062
|
-
- Model optimizations for their specific tasks
|
|
1063
|
-
|
|
1064
|
-
## Environment Setup
|
|
1065
|
-
|
|
1066
|
-
Configure \`.env\` with your API key:
|
|
1067
|
-
\`\`\`
|
|
1068
|
-
BERGET_API_KEY=your_api_key_here
|
|
1069
|
-
\`\`\`
|
|
1070
|
-
|
|
1071
|
-
## Workflow
|
|
1072
|
-
|
|
1073
|
-
All agents follow these principles:
|
|
1074
|
-
- Never work directly in main branch
|
|
1075
|
-
- Follow branch strategy and commit conventions
|
|
1076
|
-
- Create PRs for new functionality
|
|
1077
|
-
- Run tests before committing
|
|
1078
|
-
- Address reviewer feedback promptly
|
|
1079
|
-
|
|
1080
|
-
---
|
|
1081
|
-
|
|
1082
|
-
*Generated by berget code init for ${projectName}*
|
|
1083
|
-
`
|
|
1084
|
-
|
|
1085
|
-
await writeFile(agentsMdPath, agentsMdContent)
|
|
1086
|
-
console.log(chalk.green(`✓ Created AGENTS.md`))
|
|
1087
|
-
console.log(
|
|
1088
|
-
chalk.dim(` Documentation for available agents and usage`)
|
|
1089
|
-
)
|
|
1090
|
-
} else {
|
|
1091
|
-
console.log(
|
|
1092
|
-
chalk.yellow(`⚠ AGENTS.md already exists, skipping creation`)
|
|
1093
|
-
)
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
// Check if .gitignore exists and add .env if not already there
|
|
1097
|
-
const gitignorePath = path.join(process.cwd(), '.gitignore')
|
|
1098
|
-
let gitignoreContent = ''
|
|
1099
|
-
|
|
1100
|
-
if (fs.existsSync(gitignorePath)) {
|
|
1101
|
-
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8')
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
if (!gitignoreContent.includes('.env')) {
|
|
1105
|
-
gitignoreContent +=
|
|
1106
|
-
(gitignoreContent.endsWith('\n') ? '' : '\n') + '.env\n'
|
|
1107
|
-
await writeFile(gitignorePath, gitignoreContent)
|
|
1108
|
-
console.log(chalk.green(`✓ Added .env to .gitignore`))
|
|
1109
|
-
}
|
|
1110
648
|
} catch (error) {
|
|
1111
649
|
console.error(chalk.red('Failed to create config files:'))
|
|
1112
650
|
handleError('Config file creation failed', error)
|
|
@@ -1118,11 +656,12 @@ All agents follow these principles:
|
|
|
1118
656
|
}
|
|
1119
657
|
|
|
1120
658
|
console.log(chalk.green('\n✅ Project initialized successfully!'))
|
|
1121
|
-
console.log(chalk.blue('
|
|
1122
|
-
console.log(
|
|
1123
|
-
|
|
1124
|
-
)
|
|
1125
|
-
console.log(chalk.
|
|
659
|
+
console.log(chalk.blue('\nNext steps:'))
|
|
660
|
+
console.log(chalk.cyan(' 1. Run: opencode'))
|
|
661
|
+
console.log(chalk.cyan(' 2. Type: /connect'))
|
|
662
|
+
console.log(chalk.cyan(' 3. Choose your auth method:'))
|
|
663
|
+
console.log(chalk.dim(' • "Login with Berget" — Berget Code team members (SSO)'))
|
|
664
|
+
console.log(chalk.dim(' • "Enter API Key" — API key users (console.berget.ai)'))
|
|
1126
665
|
} catch (error) {
|
|
1127
666
|
handleError('Failed to initialize project', error)
|
|
1128
667
|
}
|
|
@@ -1178,38 +717,25 @@ All agents follow these principles:
|
|
|
1178
717
|
return
|
|
1179
718
|
}
|
|
1180
719
|
|
|
1181
|
-
//
|
|
720
|
+
// Prepare opencode command
|
|
1182
721
|
const env = { ...process.env }
|
|
722
|
+
const opencodeArgs: string[] = []
|
|
1183
723
|
|
|
1184
|
-
//
|
|
1185
|
-
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
env.BERGET_API_URL = 'https://api.stage.berget.ai
|
|
1192
|
-
|
|
1193
|
-
} else {
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
// Auth resolution: JWT first (if valid), then API-key
|
|
1198
|
-
// This ensures seat-based users get proper tracking
|
|
1199
|
-
const jwtToken = getAuthToken()
|
|
1200
|
-
if (jwtToken) {
|
|
1201
|
-
env.BERGET_API_KEY = jwtToken
|
|
1202
|
-
console.log(chalk.dim('Using JWT token for authentication'))
|
|
1203
|
-
} else if (env.BERGET_API_KEY) {
|
|
1204
|
-
console.log(chalk.dim('Using API key for authentication'))
|
|
1205
|
-
} else {
|
|
1206
|
-
console.log(chalk.yellow('Warning: No authentication found'))
|
|
1207
|
-
console.log(chalk.dim(' Run `berget auth login` or set BERGET_API_KEY'))
|
|
724
|
+
// Read --stage and --local from root program options
|
|
725
|
+
// (these flags are registered at program level, not subcommand level)
|
|
726
|
+
const isStage = process.argv.includes('--stage')
|
|
727
|
+
const isLocal = process.argv.includes('--local')
|
|
728
|
+
|
|
729
|
+
if (isStage) {
|
|
730
|
+
console.log(chalk.cyan('Using Berget stage environment'))
|
|
731
|
+
env.BERGET_API_URL = 'https://api.stage.berget.ai'
|
|
732
|
+
env.BERGET_INFERENCE_URL = 'https://api.stage.berget.ai/v1'
|
|
733
|
+
} else if (isLocal) {
|
|
734
|
+
console.log(chalk.cyan('Using local development environment'))
|
|
735
|
+
env.BERGET_API_URL = 'http://localhost:3000'
|
|
736
|
+
env.BERGET_INFERENCE_URL = 'http://localhost:3000/v1'
|
|
1208
737
|
}
|
|
1209
738
|
|
|
1210
|
-
// Prepare opencode command
|
|
1211
|
-
const opencodeArgs: string[] = []
|
|
1212
|
-
|
|
1213
739
|
if (prompt) {
|
|
1214
740
|
opencodeArgs.push('run', prompt)
|
|
1215
741
|
}
|
|
@@ -1356,30 +882,16 @@ All agents follow these principles:
|
|
|
1356
882
|
// Load latest agent configuration to ensure consistency
|
|
1357
883
|
const latestAgentConfig = await loadLatestAgentConfig()
|
|
1358
884
|
|
|
1359
|
-
//
|
|
1360
|
-
let modelConfig: { primary: string; small: string }
|
|
1361
|
-
try {
|
|
1362
|
-
modelConfig = getModelConfig()
|
|
1363
|
-
} catch (error) {
|
|
1364
|
-
// Fallback to defaults when no config exists (init scenario)
|
|
1365
|
-
modelConfig = {
|
|
1366
|
-
primary: 'berget/glm-4.7',
|
|
1367
|
-
small: 'berget/gpt-oss',
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
// Create latest configuration with all improvements
|
|
885
|
+
// Create latest configuration — plugin handles auth, models, and provider
|
|
1372
886
|
const latestConfig = {
|
|
1373
887
|
$schema: 'https://opencode.ai/config.json',
|
|
888
|
+
plugin: ['@bergetai/opencode-auth@1.0.9'],
|
|
1374
889
|
username: 'berget-code',
|
|
1375
890
|
theme: 'berget-dark',
|
|
1376
891
|
share: 'manual',
|
|
1377
892
|
autoupdate: true,
|
|
1378
|
-
model: modelConfig.primary,
|
|
1379
|
-
small_model: modelConfig.small,
|
|
1380
893
|
agent: {
|
|
1381
894
|
fullstack: {
|
|
1382
|
-
model: modelConfig.primary,
|
|
1383
895
|
temperature: 0.3,
|
|
1384
896
|
top_p: 0.9,
|
|
1385
897
|
mode: 'primary',
|
|
@@ -1390,7 +902,6 @@ All agents follow these principles:
|
|
|
1390
902
|
'Voice: Scandinavian calm—precise, concise, confident; no fluff. You are Berget Code Fullstack agent. Act as a router and coordinator in a monorepo. Bottom-up schema: database → OpenAPI → generated types. Top-down types: API → UI → components. Use openapi-fetch and Zod at every boundary; compile-time errors are desired when contracts change. Routing rules: if task/paths match /apps/frontend or React (.tsx) → use frontend; if /apps/app or Expo/React Native → app; if /infra, /k8s, flux-system, kustomization.yaml, Helm values → devops; if /services, Koa routers, services/adapters/domain → backend. If ambiguous, remain fullstack and outline the end-to-end plan, then delegate subtasks to the right persona. Security: validate inputs; secrets via FluxCD SOPS/Sealed Secrets. Documentation is generated from code—never duplicated. CRITICAL: When all implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.',
|
|
1391
903
|
},
|
|
1392
904
|
frontend: {
|
|
1393
|
-
model: modelConfig.primary,
|
|
1394
905
|
temperature: 0.4,
|
|
1395
906
|
top_p: 0.9,
|
|
1396
907
|
mode: 'primary',
|
|
@@ -1402,7 +913,6 @@ All agents follow these principles:
|
|
|
1402
913
|
'You are Berget Code Frontend agent. Voice: Scandinavian calm—precise, concise, confident. React 18 + TypeScript. Tailwind + Shadcn UI only via the design system (index.css, tailwind.config.ts). Use semantic tokens for color/spacing/typography/motion; never ad-hoc classes or inline colors. Components are pure and responsive; props-first data; minimal global state (Zustand/Jotai). Accessibility and keyboard navigation mandatory. Mock data only at init under /data via typed hooks (e.g., useProducts() reading /data/products.json). Design: minimal, balanced, quiet motion. CRITICAL: When all frontend implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.',
|
|
1403
914
|
},
|
|
1404
915
|
backend: {
|
|
1405
|
-
model: modelConfig.primary,
|
|
1406
916
|
temperature: 0.3,
|
|
1407
917
|
top_p: 0.9,
|
|
1408
918
|
mode: 'primary',
|
|
@@ -1414,7 +924,6 @@ All agents follow these principles:
|
|
|
1414
924
|
},
|
|
1415
925
|
// Use centralized devops configuration with Helm guidelines
|
|
1416
926
|
devops: latestAgentConfig.devops || {
|
|
1417
|
-
model: modelConfig.primary,
|
|
1418
927
|
temperature: 0.3,
|
|
1419
928
|
top_p: 0.8,
|
|
1420
929
|
mode: 'primary',
|
|
@@ -1425,7 +934,6 @@ All agents follow these principles:
|
|
|
1425
934
|
'You are Berget Code DevOps agent. Voice: Scandinavian calm—precise, concise, confident. Start simple: k8s/{deployment,service,ingress}. Add FluxCD sync to repo and image automation. Use Kustomize bases/overlays (staging, production). Add dependencies via Helm from upstream sources; prefer native operators when available (CloudNativePG, cert-manager, external-dns). SemVer with -rc tags keeps CI environments current. Observability with Prometheus/Grafana. No manual kubectl in production—Git is the source of truth. For testing, building, and PR management, use @quality subagent.',
|
|
1426
935
|
},
|
|
1427
936
|
app: {
|
|
1428
|
-
model: modelConfig.primary,
|
|
1429
937
|
temperature: 0.4,
|
|
1430
938
|
top_p: 0.9,
|
|
1431
939
|
mode: 'primary',
|
|
@@ -1437,7 +945,6 @@ All agents follow these principles:
|
|
|
1437
945
|
'You are Berget Code App agent. Voice: Scandinavian calm—precise, concise, confident. Expo + React Native + TypeScript. Structure by components/hooks/services/navigation. Components are pure; data via props; refactor shared logic into hooks/stores. Share tokens with frontend. Mock data in /data via typed hooks; later replace with live APIs. Offline via SQLite/MMKV; notifications via Expo. Request permissions only when needed. Subtle, meaningful motion; light/dark parity. For testing, building, and PR management, use @quality subagent.',
|
|
1438
946
|
},
|
|
1439
947
|
security: {
|
|
1440
|
-
model: modelConfig.primary,
|
|
1441
948
|
temperature: 0.2,
|
|
1442
949
|
top_p: 0.8,
|
|
1443
950
|
mode: 'subagent',
|
|
@@ -1448,7 +955,6 @@ All agents follow these principles:
|
|
|
1448
955
|
'Voice: Scandinavian calm—precise, concise, confident. You are Berget Code Security agent. Expert in application security, penetration testing, and OWASP standards. Core responsibilities: Conduct security assessments and penetration tests, Validate OWASP Top 10 compliance, Review code for security vulnerabilities, Implement security headers and Content Security Policy (CSP), Audit API security, Check for sensitive data exposure, Validate input sanitization and output encoding, Assess dependency security and supply chain risks. Tools and techniques: OWASP ZAP, Burp Suite, security linters, dependency scanners, manual code review. Always provide specific, actionable security recommendations with priority levels. Workflow: Always follow branch_strategy and commit_convention from workflow section. Never work directly in main. Agent awareness: Review code from all personas (frontend, backend, app, devops). If implementation changes are needed, suggest <tab> to switch to appropriate persona after security assessment.',
|
|
1449
956
|
},
|
|
1450
957
|
quality: {
|
|
1451
|
-
model: modelConfig.primary,
|
|
1452
958
|
temperature: 0.1,
|
|
1453
959
|
top_p: 0.9,
|
|
1454
960
|
mode: 'subagent',
|
|
@@ -1508,17 +1014,6 @@ All agents follow these principles:
|
|
|
1508
1014
|
watcher: {
|
|
1509
1015
|
ignore: ['node_modules', 'dist', '.git', 'coverage'],
|
|
1510
1016
|
},
|
|
1511
|
-
provider: {
|
|
1512
|
-
berget: {
|
|
1513
|
-
npm: '@ai-sdk/openai-compatible',
|
|
1514
|
-
name: 'Berget AI',
|
|
1515
|
-
options: {
|
|
1516
|
-
baseURL: '{env:BERGET_API_URL}',
|
|
1517
|
-
apiKey: '{env:BERGET_API_KEY}',
|
|
1518
|
-
},
|
|
1519
|
-
models: getProviderModels(),
|
|
1520
|
-
},
|
|
1521
|
-
},
|
|
1522
1017
|
}
|
|
1523
1018
|
|
|
1524
1019
|
// Check if update is needed
|
|
@@ -1558,14 +1053,10 @@ All agents follow these principles:
|
|
|
1558
1053
|
)
|
|
1559
1054
|
}
|
|
1560
1055
|
|
|
1561
|
-
// Check for
|
|
1562
|
-
if (
|
|
1563
|
-
!currentConfig.provider?.berget?.models?.[
|
|
1564
|
-
modelConfig.primary.replace('berget/', '')
|
|
1565
|
-
]?.limit?.context
|
|
1566
|
-
) {
|
|
1056
|
+
// Check for plugin migration
|
|
1057
|
+
if (!currentConfig.plugin) {
|
|
1567
1058
|
console.log(
|
|
1568
|
-
chalk.cyan(' •
|
|
1059
|
+
chalk.cyan(' • Plugin-first auth (automatic token refresh + model discovery)')
|
|
1569
1060
|
)
|
|
1570
1061
|
}
|
|
1571
1062
|
|
|
@@ -1815,10 +1306,7 @@ All agents are configured in \`opencode.json\` with:
|
|
|
1815
1306
|
|
|
1816
1307
|
## Environment Setup
|
|
1817
1308
|
|
|
1818
|
-
|
|
1819
|
-
\`\`\`
|
|
1820
|
-
BERGET_API_KEY=your_api_key_here
|
|
1821
|
-
\`\`\`
|
|
1309
|
+
Authentication is handled by the Berget plugin. Run \`/connect\` in OpenCode to authenticate.
|
|
1822
1310
|
|
|
1823
1311
|
## Workflow
|
|
1824
1312
|
|