berget 1.4.0 → 2.0.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.
- package/.env.example +5 -0
- package/AGENTS.md +184 -0
- package/TODO.md +2 -0
- package/blog-post.md +176 -0
- package/dist/index.js +11 -8
- package/dist/package.json +7 -2
- package/dist/src/commands/api-keys.js +4 -2
- package/dist/src/commands/chat.js +21 -11
- package/dist/src/commands/code.js +1424 -0
- package/dist/src/commands/index.js +2 -0
- package/dist/src/constants/command-structure.js +12 -0
- package/dist/src/schemas/opencode-schema.json +1121 -0
- package/dist/src/services/cluster-service.js +1 -1
- package/dist/src/utils/default-api-key.js +2 -2
- package/dist/src/utils/env-manager.js +86 -0
- package/dist/src/utils/error-handler.js +10 -3
- package/dist/src/utils/markdown-renderer.js +4 -4
- package/dist/src/utils/opencode-validator.js +122 -0
- package/dist/src/utils/token-manager.js +2 -2
- package/dist/tests/commands/chat.test.js +20 -18
- package/dist/tests/commands/code.test.js +414 -0
- package/dist/tests/utils/env-manager.test.js +148 -0
- package/dist/tests/utils/opencode-validator.test.js +103 -0
- package/index.ts +67 -32
- package/opencode.json +182 -0
- package/package.json +7 -2
- package/src/client.ts +20 -20
- package/src/commands/api-keys.ts +93 -60
- package/src/commands/auth.ts +4 -2
- package/src/commands/billing.ts +6 -3
- package/src/commands/chat.ts +149 -107
- package/src/commands/clusters.ts +2 -2
- package/src/commands/code.ts +1696 -0
- package/src/commands/index.ts +2 -0
- package/src/commands/models.ts +3 -3
- package/src/commands/users.ts +2 -2
- package/src/constants/command-structure.ts +112 -58
- package/src/schemas/opencode-schema.json +991 -0
- package/src/services/api-key-service.ts +1 -1
- package/src/services/auth-service.ts +27 -25
- package/src/services/chat-service.ts +26 -23
- package/src/services/cluster-service.ts +5 -5
- package/src/services/collaborator-service.ts +3 -3
- package/src/services/flux-service.ts +2 -2
- package/src/services/helm-service.ts +2 -2
- package/src/services/kubectl-service.ts +3 -6
- package/src/types/api.d.ts +1032 -1010
- package/src/types/json.d.ts +3 -3
- package/src/utils/default-api-key.ts +54 -42
- package/src/utils/env-manager.ts +98 -0
- package/src/utils/error-handler.ts +24 -15
- package/src/utils/logger.ts +12 -12
- package/src/utils/markdown-renderer.ts +18 -18
- package/src/utils/opencode-validator.ts +134 -0
- package/src/utils/token-manager.ts +35 -23
- package/tests/commands/chat.test.ts +43 -31
- package/tests/commands/code.test.ts +505 -0
- package/tests/utils/env-manager.test.ts +199 -0
- package/tests/utils/opencode-validator.test.ts +118 -0
- package/tsconfig.json +8 -8
- package/-27b-it +0 -0
- package/examples/README.md +0 -95
- package/examples/ai-review.sh +0 -30
- package/examples/install-global-security-hook.sh +0 -170
- package/examples/security-check.sh +0 -102
- package/examples/smart-commit.sh +0 -26
package/.env.example
ADDED
package/AGENTS.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Berget Code Agents
|
|
2
|
+
|
|
3
|
+
This document describes the specialized agents available in this project for use with OpenCode.
|
|
4
|
+
|
|
5
|
+
## Available Agents
|
|
6
|
+
|
|
7
|
+
### Primary Agents
|
|
8
|
+
|
|
9
|
+
#### fullstack
|
|
10
|
+
|
|
11
|
+
Router/coordinator agent for full-stack development with schema-driven architecture. Handles routing between different personas based on file paths and task requirements.
|
|
12
|
+
|
|
13
|
+
**Use when:**
|
|
14
|
+
|
|
15
|
+
- Working across multiple parts of a monorepo
|
|
16
|
+
- Need to coordinate between frontend, backend, devops, and app
|
|
17
|
+
- Starting new projects and need to determine tech stack
|
|
18
|
+
|
|
19
|
+
**Key features:**
|
|
20
|
+
|
|
21
|
+
- Schema-driven development (database → OpenAPI → types)
|
|
22
|
+
- Automatic routing to appropriate persona
|
|
23
|
+
- Tech stack discovery and recommendations
|
|
24
|
+
|
|
25
|
+
#### frontend
|
|
26
|
+
|
|
27
|
+
Builds Scandinavian, type-safe UIs with React, Tailwind, and Shadcn.
|
|
28
|
+
|
|
29
|
+
**Use when:**
|
|
30
|
+
|
|
31
|
+
- Working with React components (.tsx files)
|
|
32
|
+
- Frontend development in /apps/frontend
|
|
33
|
+
- UI/UX implementation
|
|
34
|
+
|
|
35
|
+
**Key features:**
|
|
36
|
+
|
|
37
|
+
- Design system integration
|
|
38
|
+
- Semantic tokens and accessibility
|
|
39
|
+
- Props-first component architecture
|
|
40
|
+
|
|
41
|
+
#### backend
|
|
42
|
+
|
|
43
|
+
Functional, modular Koa + TypeScript services with schema-first approach and code quality focus.
|
|
44
|
+
|
|
45
|
+
**Use when:**
|
|
46
|
+
|
|
47
|
+
- Working with Koa routers and services
|
|
48
|
+
- Backend development in /services
|
|
49
|
+
- API development and database work
|
|
50
|
+
|
|
51
|
+
**Key features:**
|
|
52
|
+
|
|
53
|
+
- Zod validation and OpenAPI generation
|
|
54
|
+
- Code quality and refactoring principles
|
|
55
|
+
- PR workflow integration
|
|
56
|
+
|
|
57
|
+
#### devops
|
|
58
|
+
|
|
59
|
+
Declarative GitOps infrastructure with FluxCD, Kustomize, Helm, and operators.
|
|
60
|
+
|
|
61
|
+
**Use when:**
|
|
62
|
+
|
|
63
|
+
- Working with Kubernetes manifests
|
|
64
|
+
- Infrastructure in /infra or /k8s
|
|
65
|
+
- CI/CD and deployment configurations
|
|
66
|
+
|
|
67
|
+
**Key features:**
|
|
68
|
+
|
|
69
|
+
- GitOps workflows
|
|
70
|
+
- Operator-first approach
|
|
71
|
+
- SemVer with release candidates
|
|
72
|
+
|
|
73
|
+
#### app
|
|
74
|
+
|
|
75
|
+
Expo + React Native applications with props-first architecture and offline awareness.
|
|
76
|
+
|
|
77
|
+
**Use when:**
|
|
78
|
+
|
|
79
|
+
- Mobile app development with Expo
|
|
80
|
+
- React Native projects in /apps/app
|
|
81
|
+
- Cross-platform mobile development
|
|
82
|
+
|
|
83
|
+
**Key features:**
|
|
84
|
+
|
|
85
|
+
- Shared design tokens with frontend
|
|
86
|
+
- Offline-first architecture
|
|
87
|
+
- Expo integration
|
|
88
|
+
|
|
89
|
+
### Subagents
|
|
90
|
+
|
|
91
|
+
#### security
|
|
92
|
+
|
|
93
|
+
Security specialist for penetration testing, OWASP compliance, and vulnerability assessments.
|
|
94
|
+
|
|
95
|
+
**Use when:**
|
|
96
|
+
|
|
97
|
+
- Need security review of code changes
|
|
98
|
+
- OWASP Top 10 compliance checks
|
|
99
|
+
- Vulnerability assessments
|
|
100
|
+
|
|
101
|
+
**Key features:**
|
|
102
|
+
|
|
103
|
+
- OWASP standards compliance
|
|
104
|
+
- Security best practices
|
|
105
|
+
- Actionable remediation strategies
|
|
106
|
+
|
|
107
|
+
#### quality
|
|
108
|
+
|
|
109
|
+
Quality assurance specialist for testing, building, and PR management.
|
|
110
|
+
|
|
111
|
+
**Use when:**
|
|
112
|
+
|
|
113
|
+
- Need to run test suites and build processes
|
|
114
|
+
- Creating or updating pull requests
|
|
115
|
+
- Monitoring GitHub for reviewer comments
|
|
116
|
+
- Ensuring code quality standards
|
|
117
|
+
|
|
118
|
+
**Key features:**
|
|
119
|
+
|
|
120
|
+
- Comprehensive testing and building workflows
|
|
121
|
+
- PR creation and management
|
|
122
|
+
- GitHub integration for reviewer feedback
|
|
123
|
+
- CLI command expertise for quality assurance
|
|
124
|
+
|
|
125
|
+
## Usage
|
|
126
|
+
|
|
127
|
+
### Switching Agents
|
|
128
|
+
|
|
129
|
+
Use the `<tab>` key to cycle through primary agents during a session.
|
|
130
|
+
|
|
131
|
+
### Manual Agent Selection
|
|
132
|
+
|
|
133
|
+
Use commands to switch to specific agents:
|
|
134
|
+
|
|
135
|
+
- `/fullstack` - Switch to Fullstack agent
|
|
136
|
+
- `/frontend` - Switch to Frontend agent
|
|
137
|
+
- `/backend` - Switch to Backend agent
|
|
138
|
+
- `/devops` - Switch to DevOps agent
|
|
139
|
+
- `/app` - Switch to App agent
|
|
140
|
+
- `/quality` - Switch to Quality agent for testing and PR management
|
|
141
|
+
|
|
142
|
+
### Using Subagents
|
|
143
|
+
|
|
144
|
+
Mention subagents with `@` symbol:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
@security review this authentication implementation
|
|
148
|
+
@quality run tests and create PR for these changes
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Routing Rules
|
|
152
|
+
|
|
153
|
+
The fullstack agent automatically routes tasks based on file patterns:
|
|
154
|
+
|
|
155
|
+
- `/apps/frontend` or `.tsx` files → frontend
|
|
156
|
+
- `/apps/app` or Expo/React Native → app
|
|
157
|
+
- `/infra`, `/k8s`, FluxCD, Helm → devops
|
|
158
|
+
- `/services`, Koa routers → backend
|
|
159
|
+
|
|
160
|
+
## Configuration
|
|
161
|
+
|
|
162
|
+
All agents are configured in `opencode.json` with:
|
|
163
|
+
|
|
164
|
+
- Specialized prompts and temperature settings
|
|
165
|
+
- Appropriate tool permissions
|
|
166
|
+
- Model optimizations for their specific tasks
|
|
167
|
+
|
|
168
|
+
## Environment Setup
|
|
169
|
+
|
|
170
|
+
Copy `.env.example` to `.env` and configure:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
BERGET_API_KEY=your_api_key_here
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Workflow
|
|
177
|
+
|
|
178
|
+
All agents follow these principles:
|
|
179
|
+
|
|
180
|
+
- Never work directly in main branch
|
|
181
|
+
- Follow branch strategy and commit conventions
|
|
182
|
+
- Create PRs for new functionality
|
|
183
|
+
- Run tests before committing
|
|
184
|
+
- Address reviewer feedback promptly
|
package/TODO.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Berget CLI - TODO
|
|
2
2
|
|
|
3
3
|
## Implementerade funktioner
|
|
4
|
+
|
|
4
5
|
- [x] Inloggning med BankID
|
|
5
6
|
- [x] Skapa och hantera API-nycklar
|
|
6
7
|
|
|
7
8
|
## Kommande funktioner
|
|
9
|
+
|
|
8
10
|
- [ ] Implementera riktiga API-anrop för klusterhantering
|
|
9
11
|
- [ ] Implementera riktiga API-anrop för Flux-integration
|
|
10
12
|
- [ ] Implementera riktiga API-anrop för Helm-kommandon
|
package/blog-post.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# OpenCode + Berget AI: Den ultimata AI-kodassistensen för svenska företag
|
|
2
|
+
|
|
3
|
+
I en värld där AI-drivna kodassistenter blir standard, står svenska företag inför ett kritiskt val: hur man balanserar produktivitetsvinster med data-suveränitet och efterlevnad. Med integrationen mellan OpenCode och Berget AI får du nu det bästa av två världar – en kraftfull, open source AI-kodassistent med svensk datainfrastruktur.
|
|
4
|
+
|
|
5
|
+
## Vad är OpenCode?
|
|
6
|
+
|
|
7
|
+
OpenCode är en open source AI-kodassistent byggd för terminalen. Till skillnad från många kommersiella alternativ ger OpenCode dig full kontroll över din kod och dina data. Med över 26 000 GitHub-stjärnor och 200 000+ aktiva utvecklare varje månad har det blivit ett av de mest populära verktygen för AI-assisterad programmering.
|
|
8
|
+
|
|
9
|
+
**Nödvändiga funktioner i OpenCode:**
|
|
10
|
+
|
|
11
|
+
- 🎯 **Native TUI** – Responsivt terminalgränssnitt som fungerar i din befintliga workflow
|
|
12
|
+
- 🔄 **Multi-session** – Köra flera agenter parallellt på samma projekt
|
|
13
|
+
- 🔗 **Share links** – Dela sessioner för kodgranskning och felsökning
|
|
14
|
+
- 🤖 **Any model** – Stöd för 75+ LLM-providers via Models.dev
|
|
15
|
+
- 🛠️ **LSP enabled** – Automatisk laddning av rätt Language Servers för LLM:en
|
|
16
|
+
|
|
17
|
+
## Berget AI: Svensk datainfrastruktur
|
|
18
|
+
|
|
19
|
+
Berget AI är en svensk AI-infrastrukturleverantör som säkerställer att din data aldrig lämnar Sverige. Detta är särskilt viktigt för företag som hanterar känslig information, personuppgifter eller skyddad kod.
|
|
20
|
+
|
|
21
|
+
**Fördelar med Berget AI:**
|
|
22
|
+
|
|
23
|
+
- 🇸🇪 **Data-suveränitet** – All data bearbetas inom Sverige
|
|
24
|
+
- ⚖️ **GDPR-kompatibilitet** – Full efterlevnad med EU:s dataskyddslagar
|
|
25
|
+
- 🔒 **Säkerhet** – Industriell säkerhet med kryptering och isolering
|
|
26
|
+
- 🏛️ **Reglering** – Enklare efterlevnad av svenska och EU-regleringar
|
|
27
|
+
- 🚀 **Prestanda** – Låg latens med svensk infrastruktur
|
|
28
|
+
|
|
29
|
+
## Varför kombinationen är oslagbar
|
|
30
|
+
|
|
31
|
+
### 1. Data som aldrig lämnar Sverige
|
|
32
|
+
|
|
33
|
+
När du använder OpenCode med Berget AI förblir all din kod – inklusive API-nycklar, konfigurationer och känslig affärslogik – inom Sveriges gränser. Detta eliminerar risken för dataexponering som kan uppstå med internationella molntjänster.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Initiera ditt projekt med AI-assistent
|
|
37
|
+
berget code init
|
|
38
|
+
|
|
39
|
+
# Din kod och data förblir alltid i Sverige ✅
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Förenklad reglering och efterlevnad
|
|
43
|
+
|
|
44
|
+
För svenska företag, särskilt inom finans, vård och offentlig sektor, är efterlevnad avgörande. Med Berget AI får du:
|
|
45
|
+
|
|
46
|
+
- **GDPR-säker hantering** av personuppgifter i koden
|
|
47
|
+
- **Klassificerad information** hanteras säkert
|
|
48
|
+
- **Revisionsbara spår** av all AI-interaktion
|
|
49
|
+
- **Lokal lagring** av konfigurationer och API-nycklar
|
|
50
|
+
|
|
51
|
+
### 3. Säker hantering av känslig kod
|
|
52
|
+
|
|
53
|
+
Många företag arbetar med kod som innehåller:
|
|
54
|
+
|
|
55
|
+
- API-nycklar och hemligheter
|
|
56
|
+
- Affärskritisk algoritmlogik
|
|
57
|
+
- Känslig kunddata
|
|
58
|
+
- Proprietära systemintegrationer
|
|
59
|
+
|
|
60
|
+
Med OpenCode + Berget AI kan du använda AI-assistens för:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Refaktorera känslig kod utan att lämna Sverige
|
|
64
|
+
berget code run "Refaktorera denna autentiseringsmodul"
|
|
65
|
+
|
|
66
|
+
# Få hjälp med API-integrationer säkert
|
|
67
|
+
berget code run "Optimera denna databasanslutning"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Projektspecifika API-nycklar
|
|
71
|
+
|
|
72
|
+
Varje projekt får sin egen unika API-nyckel som skapas automatiskt:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"model": "berget/deepseek-r1",
|
|
77
|
+
"apiKey": "projekt-specifik-nyckel",
|
|
78
|
+
"projectName": "mitt-svenska-projekt",
|
|
79
|
+
"provider": "berget",
|
|
80
|
+
"created": "2025-01-01T00:00:00.000Z",
|
|
81
|
+
"version": "1.0.0"
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Detta ger:
|
|
86
|
+
|
|
87
|
+
- 🔐 **Isolering** mellan projekt
|
|
88
|
+
- 📊 **Spårbarhet** av användning
|
|
89
|
+
- 🔄 **Enkel rotation** av nycklar
|
|
90
|
+
- 🎯 **Granulär kontroll** av åtkomst
|
|
91
|
+
|
|
92
|
+
## Kom igång på 2 minuter
|
|
93
|
+
|
|
94
|
+
### Steg 1: Installera OpenCode
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -fsSL https://opencode.ai/install | bash
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Steg 2: Initiera ditt projekt
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cd ditt-projekt
|
|
104
|
+
berget code init
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Steg 3: Starta AI-assistenen
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
berget code run
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Det var allt! Du har nu en fullfjädrad AI-kodassistent med svensk datainfrastruktur.
|
|
114
|
+
|
|
115
|
+
## Användningsfall för svenska företag
|
|
116
|
+
|
|
117
|
+
### Finans & Försäkring
|
|
118
|
+
|
|
119
|
+
- Refaktorera transaktionslogik med full säkerhet
|
|
120
|
+
- Hjälp med compliance-kod (KYC, AML)
|
|
121
|
+
- Optimera riskberäkningsalgoritmer
|
|
122
|
+
|
|
123
|
+
### Vård & Hälsa
|
|
124
|
+
|
|
125
|
+
- Utveckla patientdata-system med GDPR-säkerhet
|
|
126
|
+
- Hjälp med medicinsk kod och integrationer
|
|
127
|
+
- Säker hantering av journalsystem
|
|
128
|
+
|
|
129
|
+
### Offentlig Sektor
|
|
130
|
+
|
|
131
|
+
- Utveckla e-tjänster med svensk data
|
|
132
|
+
- Hjälp med myndighetsintegrationer
|
|
133
|
+
- Säker hantering av medborgardata
|
|
134
|
+
|
|
135
|
+
### Industri & Tillverkning
|
|
136
|
+
|
|
137
|
+
- Optimera PLC-kod och styrsystem
|
|
138
|
+
- Hjälp med IoT-integrationer
|
|
139
|
+
- Säker utveckling av produktionssystem
|
|
140
|
+
|
|
141
|
+
## Teknisk integration
|
|
142
|
+
|
|
143
|
+
OpenCode + Berget AI använder den kraftfulla **GLM-4.6** modellen (för närvarande deepseek-r1) som är optimerad för kodning:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Se vilka modeller som finns tillgängliga
|
|
147
|
+
berget models list
|
|
148
|
+
|
|
149
|
+
# Använd specifik modell
|
|
150
|
+
berget code run --model berget/glm-4-6 "Hjälp mig optimera denna funktion"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Framtiden för svensk AI-utveckling
|
|
154
|
+
|
|
155
|
+
Kombinationen av OpenCode och Berget AI representerar nästa generations AI-utveckling för svenska företag:
|
|
156
|
+
|
|
157
|
+
1. **Produktivitet** – AI-assisterad kodning utan kompromisser
|
|
158
|
+
2. **Säkerhet** – Full kontroll över din data och kod
|
|
159
|
+
3. **Efterlevnad** – Inbyggt stöd för svenska och EU-regleringar
|
|
160
|
+
4. **Flexibilitet** – Open source med frihet att välja modeller och verktyg
|
|
161
|
+
5. **Skalbarhet** – Från små projekt till enterprise-nivå
|
|
162
|
+
|
|
163
|
+
## Sammanfattning
|
|
164
|
+
|
|
165
|
+
OpenCode + Berget AI är inte bara ett verktyg – det är en strategisk lösning för svenska företag som vill leda inom AI-driven utveckling utan att kompromissa med säkerhet och efterlevnad.
|
|
166
|
+
|
|
167
|
+
Med svensk datainfrastruktur, projektspecifika API-nycklar och en open source AI-assistent får du det bästa av två världar: global AI-kompetens med lokal dataskydd.
|
|
168
|
+
|
|
169
|
+
**Redo att transformera din kodning med svensk AI?**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Börja idag
|
|
173
|
+
berget code init
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
_Din kod, din data, ditt land – nu med AI-superkrafter._
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,8 @@ commander_1.program
|
|
|
19
19
|
| |_/ / __/ | | (_| | __/ |_ | | | |_| |_
|
|
20
20
|
\\____/ \\___|_| \\__, |\\___|\\_\\_ \\_| |_/\\___/
|
|
21
21
|
__/ |
|
|
22
|
-
|___/ AI on European terms
|
|
22
|
+
|___/ AI on European terms
|
|
23
|
+
Version: ${package_json_1.version}`)
|
|
23
24
|
.version(package_json_1.version, '-v, --version')
|
|
24
25
|
.option('--local', 'Use local API endpoint (hidden)', false)
|
|
25
26
|
.option('--debug', 'Enable debug output', false);
|
|
@@ -34,19 +35,21 @@ if (process.argv.length <= 2) {
|
|
|
34
35
|
console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget auth login')} - Log in to Berget`));
|
|
35
36
|
console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget models list')} - List available AI models`));
|
|
36
37
|
console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget chat run')} - Start a chat session`));
|
|
38
|
+
console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget code init')} - Initialize AI coding assistant`));
|
|
37
39
|
console.log(chalk_1.default.blue(` ${chalk_1.default.bold('berget api-keys list')} - List your API keys`));
|
|
38
40
|
console.log(chalk_1.default.blue(`\nRun ${chalk_1.default.bold('berget --help')} for a complete list of commands.`));
|
|
39
41
|
}
|
|
40
42
|
// Add helpful suggestions for common command mistakes
|
|
41
43
|
const commonMistakes = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
login: 'auth login',
|
|
45
|
+
logout: 'auth logout',
|
|
46
|
+
whoami: 'auth whoami',
|
|
45
47
|
'list-models': 'models list',
|
|
46
48
|
'list-keys': 'api-keys list',
|
|
47
49
|
'create-key': 'api-keys create',
|
|
48
50
|
'list-clusters': 'clusters list',
|
|
49
|
-
|
|
51
|
+
usage: 'billing usage',
|
|
52
|
+
init: 'code init',
|
|
50
53
|
};
|
|
51
54
|
// Add error handler for unknown commands
|
|
52
55
|
commander_1.program.on('command:*', (operands) => {
|
|
@@ -58,11 +61,11 @@ commander_1.program.on('command:*', (operands) => {
|
|
|
58
61
|
}
|
|
59
62
|
else {
|
|
60
63
|
// Try to find similar commands
|
|
61
|
-
const availableCommands = commander_1.program.commands.map(cmd => cmd.name());
|
|
62
|
-
const similarCommands = availableCommands.filter(cmd => cmd.includes(unknownCommand) || unknownCommand.includes(cmd));
|
|
64
|
+
const availableCommands = commander_1.program.commands.map((cmd) => cmd.name());
|
|
65
|
+
const similarCommands = availableCommands.filter((cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd));
|
|
63
66
|
if (similarCommands.length > 0) {
|
|
64
67
|
console.log(chalk_1.default.yellow('Similar commands:'));
|
|
65
|
-
similarCommands.forEach(cmd => {
|
|
68
|
+
similarCommands.forEach((cmd) => {
|
|
66
69
|
console.log(chalk_1.default.yellow(` ${chalk_1.default.bold(`berget ${cmd}`)}`));
|
|
67
70
|
});
|
|
68
71
|
}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "berget",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"berget": "dist/index.js"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"description": "This is a cli command for interacting with the AI infrastructure provider Berget",
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@types/dotenv": "^6.1.1",
|
|
27
28
|
"@types/marked": "^5.0.2",
|
|
28
29
|
"@types/marked-terminal": "^6.1.1",
|
|
29
30
|
"@types/node": "^20.11.20",
|
|
@@ -32,14 +33,18 @@
|
|
|
32
33
|
"vitest": "^1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
36
|
+
"ajv": "^8.17.1",
|
|
37
|
+
"ajv-formats": "^3.0.1",
|
|
35
38
|
"chalk": "^4.1.2",
|
|
36
39
|
"commander": "^12.0.0",
|
|
40
|
+
"dotenv": "^17.2.3",
|
|
37
41
|
"fs-extra": "^11.3.0",
|
|
38
42
|
"marked": "^9.1.6",
|
|
39
43
|
"marked-terminal": "^6.2.0",
|
|
40
44
|
"open": "^9.1.0",
|
|
41
45
|
"openapi-fetch": "^0.9.1",
|
|
42
46
|
"openapi-typescript": "^6.7.4",
|
|
43
|
-
"readline": "^1.3.0"
|
|
47
|
+
"readline": "^1.3.0",
|
|
48
|
+
"zod": "^4.1.12"
|
|
44
49
|
}
|
|
45
50
|
}
|
|
@@ -46,7 +46,9 @@ function registerApiKeyCommands(program) {
|
|
|
46
46
|
chalk_1.default.dim('LAST USED'));
|
|
47
47
|
console.log(chalk_1.default.dim('─'.repeat(85)));
|
|
48
48
|
keys.forEach((key) => {
|
|
49
|
-
const lastUsed = key.lastUsed
|
|
49
|
+
const lastUsed = key.lastUsed
|
|
50
|
+
? key.lastUsed.substring(0, 10)
|
|
51
|
+
: 'Never';
|
|
50
52
|
const status = key.active
|
|
51
53
|
? chalk_1.default.green('● Active')
|
|
52
54
|
: chalk_1.default.red('● Inactive');
|
|
@@ -227,7 +229,7 @@ function registerApiKeyCommands(program) {
|
|
|
227
229
|
try {
|
|
228
230
|
const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
|
|
229
231
|
const keys = yield apiKeyService.list();
|
|
230
|
-
const selectedKey = keys.find(key => key.id.toString() === id);
|
|
232
|
+
const selectedKey = keys.find((key) => key.id.toString() === id);
|
|
231
233
|
if (!selectedKey) {
|
|
232
234
|
console.error(chalk_1.default.red(`Error: API key with ID ${id} not found`));
|
|
233
235
|
return;
|
|
@@ -230,7 +230,7 @@ function registerChatCommands(program) {
|
|
|
230
230
|
messages: messages,
|
|
231
231
|
temperature: options.temperature !== undefined ? options.temperature : 0.7,
|
|
232
232
|
max_tokens: options.maxTokens || 4096,
|
|
233
|
-
stream: options.stream !== false
|
|
233
|
+
stream: options.stream !== false,
|
|
234
234
|
};
|
|
235
235
|
// Only add apiKey if it actually exists
|
|
236
236
|
if (apiKey) {
|
|
@@ -241,7 +241,10 @@ function registerChatCommands(program) {
|
|
|
241
241
|
let assistantResponse = '';
|
|
242
242
|
// Stream the response in real-time
|
|
243
243
|
completionOptions.onChunk = (chunk) => {
|
|
244
|
-
if (chunk.choices &&
|
|
244
|
+
if (chunk.choices &&
|
|
245
|
+
chunk.choices[0] &&
|
|
246
|
+
chunk.choices[0].delta &&
|
|
247
|
+
chunk.choices[0].delta.content) {
|
|
245
248
|
const content = chunk.choices[0].delta.content;
|
|
246
249
|
try {
|
|
247
250
|
process.stdout.write(content);
|
|
@@ -267,7 +270,10 @@ function registerChatCommands(program) {
|
|
|
267
270
|
completionOptions.stream = false;
|
|
268
271
|
delete completionOptions.onChunk;
|
|
269
272
|
const response = yield chatService.createCompletion(completionOptions);
|
|
270
|
-
if (response &&
|
|
273
|
+
if (response &&
|
|
274
|
+
response.choices &&
|
|
275
|
+
response.choices[0] &&
|
|
276
|
+
response.choices[0].message) {
|
|
271
277
|
assistantResponse = response.choices[0].message.content;
|
|
272
278
|
console.log(assistantResponse);
|
|
273
279
|
}
|
|
@@ -332,7 +338,7 @@ function registerChatCommands(program) {
|
|
|
332
338
|
messages: messages,
|
|
333
339
|
temperature: options.temperature !== undefined ? options.temperature : 0.7,
|
|
334
340
|
max_tokens: options.maxTokens || 4096,
|
|
335
|
-
stream: options.stream !== false
|
|
341
|
+
stream: options.stream !== false,
|
|
336
342
|
};
|
|
337
343
|
// Only add apiKey if it actually exists
|
|
338
344
|
if (apiKey) {
|
|
@@ -344,7 +350,10 @@ function registerChatCommands(program) {
|
|
|
344
350
|
console.log(chalk_1.default.blue('Assistant: '));
|
|
345
351
|
// Stream the response in real-time
|
|
346
352
|
completionOptions.onChunk = (chunk) => {
|
|
347
|
-
if (chunk.choices &&
|
|
353
|
+
if (chunk.choices &&
|
|
354
|
+
chunk.choices[0] &&
|
|
355
|
+
chunk.choices[0].delta &&
|
|
356
|
+
chunk.choices[0].delta.content) {
|
|
348
357
|
const content = chunk.choices[0].delta.content;
|
|
349
358
|
try {
|
|
350
359
|
process.stdout.write(content);
|
|
@@ -370,7 +379,10 @@ function registerChatCommands(program) {
|
|
|
370
379
|
completionOptions.stream = false;
|
|
371
380
|
delete completionOptions.onChunk;
|
|
372
381
|
const response = yield chatService.createCompletion(completionOptions);
|
|
373
|
-
if (response &&
|
|
382
|
+
if (response &&
|
|
383
|
+
response.choices &&
|
|
384
|
+
response.choices[0] &&
|
|
385
|
+
response.choices[0].message) {
|
|
374
386
|
assistantResponse = response.choices[0].message.content;
|
|
375
387
|
console.log(assistantResponse);
|
|
376
388
|
}
|
|
@@ -379,7 +391,7 @@ function registerChatCommands(program) {
|
|
|
379
391
|
// Add assistant response to messages
|
|
380
392
|
messages.push({
|
|
381
393
|
role: 'assistant',
|
|
382
|
-
content: assistantResponse
|
|
394
|
+
content: assistantResponse,
|
|
383
395
|
});
|
|
384
396
|
// Continue the conversation
|
|
385
397
|
askQuestion();
|
|
@@ -492,8 +504,7 @@ function registerChatCommands(program) {
|
|
|
492
504
|
}
|
|
493
505
|
console.log(chalk_1.default.bold('Available Chat Models:'));
|
|
494
506
|
console.log(chalk_1.default.dim('─'.repeat(70)));
|
|
495
|
-
console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) +
|
|
496
|
-
chalk_1.default.dim('CAPABILITIES'));
|
|
507
|
+
console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) + chalk_1.default.dim('CAPABILITIES'));
|
|
497
508
|
console.log(chalk_1.default.dim('─'.repeat(70)));
|
|
498
509
|
// Filter to only show active models
|
|
499
510
|
const activeModels = models.data.filter((model) => model.active === true);
|
|
@@ -507,8 +518,7 @@ function registerChatCommands(program) {
|
|
|
507
518
|
capabilities.push('json_mode');
|
|
508
519
|
// Format model ID in Huggingface compatible format (owner/model)
|
|
509
520
|
const modelId = `${model.owned_by.toLowerCase()}/${model.id}`.padEnd(40);
|
|
510
|
-
console.log(modelId +
|
|
511
|
-
capabilities.join(', '));
|
|
521
|
+
console.log(modelId + capabilities.join(', '));
|
|
512
522
|
});
|
|
513
523
|
}
|
|
514
524
|
catch (error) {
|