berget 2.2.6 → 2.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +6 -6
- package/.github/workflows/test.yml +11 -5
- package/.husky/pre-commit +1 -0
- package/.prettierignore +15 -0
- package/.prettierrc +5 -3
- package/CONTRIBUTING.md +38 -0
- package/README.md +2 -148
- package/dist/index.js +21 -21
- package/dist/package.json +28 -2
- package/dist/src/agents/app.js +28 -0
- package/dist/src/agents/backend.js +25 -0
- package/dist/src/agents/devops.js +34 -0
- package/dist/src/agents/frontend.js +25 -0
- package/dist/src/agents/fullstack.js +25 -0
- package/dist/src/agents/index.js +61 -0
- package/dist/src/agents/quality.js +70 -0
- package/dist/src/agents/security.js +26 -0
- package/dist/src/agents/types.js +2 -0
- package/dist/src/client.js +54 -62
- package/dist/src/commands/api-keys.js +132 -140
- package/dist/src/commands/auth.js +9 -9
- package/dist/src/commands/autocomplete.js +9 -9
- package/dist/src/commands/billing.js +7 -9
- package/dist/src/commands/chat.js +90 -92
- package/dist/src/commands/clusters.js +12 -12
- package/dist/src/commands/code/__tests__/auth-sync.test.js +348 -0
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +23 -0
- package/dist/src/commands/code/__tests__/fake-auth-service.js +55 -0
- package/dist/src/commands/code/__tests__/fake-command-runner.js +5 -7
- package/dist/src/commands/code/__tests__/fake-file-store.js +9 -0
- package/dist/src/commands/code/__tests__/fake-prompter.js +60 -18
- package/dist/src/commands/code/__tests__/setup-flow.test.js +374 -107
- package/dist/src/commands/code/adapters/clack-prompter.js +10 -0
- package/dist/src/commands/code/adapters/fs-file-store.js +8 -3
- package/dist/src/commands/code/adapters/spawn-command-runner.js +15 -11
- package/dist/src/commands/code/auth-sync.js +283 -0
- package/dist/src/commands/code/errors.js +4 -4
- package/dist/src/commands/code/ports/auth-services.js +2 -0
- package/dist/src/commands/code/setup.js +234 -93
- package/dist/src/commands/code.js +139 -251
- package/dist/src/commands/models.js +13 -15
- package/dist/src/commands/users.js +6 -8
- package/dist/src/constants/command-structure.js +116 -116
- package/dist/src/services/api-key-service.js +43 -48
- package/dist/src/services/auth-service.js +60 -299
- package/dist/src/services/browser-auth.js +278 -0
- package/dist/src/services/chat-service.js +78 -91
- package/dist/src/services/cluster-service.js +6 -6
- package/dist/src/services/collaborator-service.js +5 -8
- package/dist/src/services/flux-service.js +5 -8
- package/dist/src/services/helm-service.js +5 -8
- package/dist/src/services/kubectl-service.js +7 -10
- package/dist/src/utils/config-checker.js +5 -5
- package/dist/src/utils/config-loader.js +25 -25
- package/dist/src/utils/default-api-key.js +23 -23
- package/dist/src/utils/env-manager.js +7 -7
- package/dist/src/utils/error-handler.js +60 -61
- package/dist/src/utils/logger.js +7 -7
- package/dist/src/utils/markdown-renderer.js +2 -2
- package/dist/src/utils/opencode-validator.js +17 -20
- package/dist/src/utils/token-manager.js +38 -11
- package/dist/tests/commands/chat.test.js +24 -24
- package/dist/tests/commands/code.test.js +147 -147
- package/dist/tests/utils/config-loader.test.js +114 -114
- package/dist/tests/utils/env-manager.test.js +57 -57
- package/dist/tests/utils/opencode-validator.test.js +33 -33
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +47 -0
- package/index.ts +42 -48
- package/package.json +28 -2
- package/src/agents/app.ts +27 -0
- package/src/agents/backend.ts +24 -0
- package/src/agents/devops.ts +33 -0
- package/src/agents/frontend.ts +24 -0
- package/src/agents/fullstack.ts +24 -0
- package/src/agents/index.ts +71 -0
- package/src/agents/quality.ts +69 -0
- package/src/agents/security.ts +26 -0
- package/src/agents/types.ts +17 -0
- package/src/client.ts +125 -167
- package/src/commands/api-keys.ts +261 -358
- package/src/commands/auth.ts +24 -30
- package/src/commands/autocomplete.ts +12 -12
- package/src/commands/billing.ts +22 -27
- package/src/commands/chat.ts +230 -323
- package/src/commands/clusters.ts +33 -33
- package/src/commands/code/__tests__/auth-sync.test.ts +481 -0
- package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
- package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
- package/src/commands/code/__tests__/fake-command-runner.ts +39 -42
- package/src/commands/code/__tests__/fake-file-store.ts +32 -23
- package/src/commands/code/__tests__/fake-prompter.ts +107 -69
- package/src/commands/code/__tests__/setup-flow.test.ts +624 -270
- package/src/commands/code/adapters/clack-prompter.ts +50 -38
- package/src/commands/code/adapters/fs-file-store.ts +31 -27
- package/src/commands/code/adapters/spawn-command-runner.ts +33 -29
- package/src/commands/code/auth-sync.ts +329 -0
- package/src/commands/code/errors.ts +15 -15
- package/src/commands/code/ports/auth-services.ts +14 -0
- package/src/commands/code/ports/command-runner.ts +8 -4
- package/src/commands/code/ports/file-store.ts +5 -4
- package/src/commands/code/ports/prompter.ts +24 -18
- package/src/commands/code/setup.ts +545 -317
- package/src/commands/code.ts +271 -473
- package/src/commands/index.ts +19 -19
- package/src/commands/models.ts +32 -37
- package/src/commands/users.ts +15 -22
- package/src/constants/command-structure.ts +119 -142
- package/src/services/api-key-service.ts +96 -113
- package/src/services/auth-service.ts +92 -339
- package/src/services/browser-auth.ts +296 -0
- package/src/services/chat-service.ts +246 -279
- package/src/services/cluster-service.ts +29 -32
- package/src/services/collaborator-service.ts +13 -18
- package/src/services/flux-service.ts +16 -18
- package/src/services/helm-service.ts +16 -18
- package/src/services/kubectl-service.ts +12 -14
- package/src/types/api.d.ts +924 -926
- package/src/types/json.d.ts +3 -3
- package/src/utils/config-checker.ts +10 -10
- package/src/utils/config-loader.ts +110 -127
- package/src/utils/default-api-key.ts +81 -93
- package/src/utils/env-manager.ts +36 -40
- package/src/utils/error-handler.ts +83 -78
- package/src/utils/logger.ts +41 -41
- package/src/utils/markdown-renderer.ts +11 -11
- package/src/utils/opencode-validator.ts +51 -56
- package/src/utils/token-manager.ts +84 -64
- package/templates/agents/app.md +1 -0
- package/templates/agents/backend.md +1 -0
- package/templates/agents/devops.md +2 -0
- package/templates/agents/frontend.md +1 -0
- package/templates/agents/fullstack.md +1 -0
- package/templates/agents/quality.md +45 -40
- package/templates/agents/security.md +1 -0
- package/tests/commands/chat.test.ts +60 -70
- package/tests/commands/code.test.ts +330 -376
- package/tests/utils/config-loader.test.ts +260 -260
- package/tests/utils/env-manager.test.ts +127 -134
- package/tests/utils/opencode-validator.test.ts +58 -63
- package/tsconfig.json +2 -2
- package/vitest.config.ts +3 -3
- package/AGENTS.md +0 -374
- package/TODO.md +0 -19
|
@@ -3,21 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const vitest_1 = require("vitest");
|
|
4
4
|
const opencode_validator_1 = require("../../src/utils/opencode-validator");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
|
-
(0, vitest_1.describe)(
|
|
7
|
-
(0, vitest_1.it)(
|
|
6
|
+
(0, vitest_1.describe)("OpenCode Validator", () => {
|
|
7
|
+
(0, vitest_1.it)("should validate a correct OpenCode configuration", () => {
|
|
8
8
|
const validConfig = {
|
|
9
|
-
$schema:
|
|
10
|
-
username:
|
|
11
|
-
model:
|
|
9
|
+
$schema: "https://opencode.ai/config.json",
|
|
10
|
+
username: "test-user",
|
|
11
|
+
model: "gpt-4",
|
|
12
12
|
agent: {
|
|
13
13
|
test: {
|
|
14
|
-
model:
|
|
14
|
+
model: "gpt-4",
|
|
15
15
|
temperature: 0.7,
|
|
16
|
-
prompt:
|
|
16
|
+
prompt: "Test agent",
|
|
17
17
|
permission: {
|
|
18
|
-
edit:
|
|
19
|
-
bash:
|
|
20
|
-
webfetch:
|
|
18
|
+
edit: "allow",
|
|
19
|
+
bash: "allow",
|
|
20
|
+
webfetch: "allow",
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
23
|
},
|
|
@@ -26,19 +26,19 @@ const fs_1 = require("fs");
|
|
|
26
26
|
(0, vitest_1.expect)(result.valid).toBe(true);
|
|
27
27
|
(0, vitest_1.expect)(result.errors).toBeUndefined();
|
|
28
28
|
});
|
|
29
|
-
(0, vitest_1.it)(
|
|
29
|
+
(0, vitest_1.it)("should reject invalid configuration", () => {
|
|
30
30
|
const invalidConfig = {
|
|
31
31
|
username: 123, // Should be string
|
|
32
|
-
model:
|
|
32
|
+
model: "gpt-4",
|
|
33
33
|
agent: {
|
|
34
34
|
test: {
|
|
35
|
-
model:
|
|
36
|
-
temperature:
|
|
37
|
-
prompt:
|
|
35
|
+
model: "gpt-4",
|
|
36
|
+
temperature: "high", // Should be number
|
|
37
|
+
prompt: "Test agent",
|
|
38
38
|
permission: {
|
|
39
|
-
edit:
|
|
40
|
-
bash:
|
|
41
|
-
webfetch:
|
|
39
|
+
edit: "invalid", // Should be enum value
|
|
40
|
+
bash: "allow",
|
|
41
|
+
webfetch: "allow",
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
44
|
},
|
|
@@ -48,10 +48,10 @@ const fs_1 = require("fs");
|
|
|
48
48
|
(0, vitest_1.expect)(result.errors).toBeDefined();
|
|
49
49
|
(0, vitest_1.expect)(result.errors.length).toBeGreaterThan(0);
|
|
50
50
|
});
|
|
51
|
-
(0, vitest_1.it)(
|
|
51
|
+
(0, vitest_1.it)("should fix common configuration issues", () => {
|
|
52
52
|
const configWithIssues = {
|
|
53
|
-
username:
|
|
54
|
-
model:
|
|
53
|
+
username: "test-user",
|
|
54
|
+
model: "gpt-4",
|
|
55
55
|
tools: {
|
|
56
56
|
compact: { threshold: 80000 }, // Should be boolean
|
|
57
57
|
},
|
|
@@ -59,8 +59,8 @@ const fs_1 = require("fs");
|
|
|
59
59
|
provider: {
|
|
60
60
|
berget: {
|
|
61
61
|
models: {
|
|
62
|
-
|
|
63
|
-
name:
|
|
62
|
+
"test-model": {
|
|
63
|
+
name: "Test Model",
|
|
64
64
|
maxTokens: 4000, // Should be moved to limit.context
|
|
65
65
|
contextWindow: 8000, // Should be moved to limit.context
|
|
66
66
|
},
|
|
@@ -70,24 +70,24 @@ const fs_1 = require("fs");
|
|
|
70
70
|
};
|
|
71
71
|
const fixed = (0, opencode_validator_1.fixOpenCodeConfig)(configWithIssues);
|
|
72
72
|
// tools.compact should be boolean
|
|
73
|
-
(0, vitest_1.expect)(typeof fixed.tools.compact).toBe(
|
|
73
|
+
(0, vitest_1.expect)(typeof fixed.tools.compact).toBe("boolean");
|
|
74
74
|
// maxTokens should be removed
|
|
75
75
|
(0, vitest_1.expect)(fixed.maxTokens).toBeUndefined();
|
|
76
76
|
// maxTokens and contextWindow should be moved to limit.context
|
|
77
|
-
(0, vitest_1.expect)(fixed.provider.berget.models[
|
|
78
|
-
(0, vitest_1.expect)(fixed.provider.berget.models[
|
|
79
|
-
(0, vitest_1.expect)(fixed.provider.berget.models[
|
|
80
|
-
(0, vitest_1.expect)(fixed.provider.berget.models[
|
|
77
|
+
(0, vitest_1.expect)(fixed.provider.berget.models["test-model"].limit).toBeDefined();
|
|
78
|
+
(0, vitest_1.expect)(fixed.provider.berget.models["test-model"].limit.context).toBe(8000);
|
|
79
|
+
(0, vitest_1.expect)(fixed.provider.berget.models["test-model"].maxTokens).toBeUndefined();
|
|
80
|
+
(0, vitest_1.expect)(fixed.provider.berget.models["test-model"].contextWindow).toBeUndefined();
|
|
81
81
|
});
|
|
82
|
-
(0, vitest_1.it)(
|
|
82
|
+
(0, vitest_1.it)("should validate the current opencode.json file", () => {
|
|
83
83
|
var _a;
|
|
84
84
|
let currentConfig;
|
|
85
85
|
try {
|
|
86
|
-
currentConfig = JSON.parse((0, fs_1.readFileSync)(
|
|
86
|
+
currentConfig = JSON.parse((0, fs_1.readFileSync)("opencode.json", "utf8"));
|
|
87
87
|
}
|
|
88
88
|
catch (error) {
|
|
89
89
|
// Skip when opencode.json is not present (e.g. in CI or clean checkouts)
|
|
90
|
-
console.log(
|
|
90
|
+
console.log("Skipping: opencode.json not found:", error);
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
// Apply fixes to handle common issues
|
|
@@ -97,8 +97,8 @@ const fs_1 = require("fs");
|
|
|
97
97
|
// The fixed config should be valid according to the JSON Schema
|
|
98
98
|
(0, vitest_1.expect)(result.valid).toBe(true);
|
|
99
99
|
if (!result.valid) {
|
|
100
|
-
console.log(
|
|
101
|
-
(_a = result.errors) === null || _a === void 0 ? void 0 : _a.forEach(
|
|
100
|
+
console.log("Fixed opencode.json validation errors:");
|
|
101
|
+
(_a = result.errors) === null || _a === void 0 ? void 0 : _a.forEach(err => console.log(` - ${err}`));
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
104
|
});
|
package/dist/vitest.config.js
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
|
2
|
+
import typescriptParser from "@typescript-eslint/parser";
|
|
3
|
+
import prettier from "eslint-plugin-prettier";
|
|
4
|
+
|
|
5
|
+
export default [
|
|
6
|
+
{
|
|
7
|
+
ignores: [
|
|
8
|
+
"node_modules/**",
|
|
9
|
+
"dist/**",
|
|
10
|
+
"build/**",
|
|
11
|
+
"*.lock",
|
|
12
|
+
".husky/**",
|
|
13
|
+
"coverage/**",
|
|
14
|
+
".nyc_output/**",
|
|
15
|
+
"test-results/**",
|
|
16
|
+
"playwright-report/**",
|
|
17
|
+
".pi/**",
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
files: ["**/*.ts", "**/*.tsx"],
|
|
22
|
+
languageOptions: {
|
|
23
|
+
parser: typescriptParser,
|
|
24
|
+
parserOptions: {
|
|
25
|
+
ecmaVersion: "latest",
|
|
26
|
+
sourceType: "commonjs",
|
|
27
|
+
project: "./tsconfig.json",
|
|
28
|
+
tsconfigRootDir: process.cwd(),
|
|
29
|
+
},
|
|
30
|
+
globals: {
|
|
31
|
+
node: "readonly",
|
|
32
|
+
es2022: "readonly",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
plugins: {
|
|
36
|
+
"@typescript-eslint": typescriptEslint,
|
|
37
|
+
prettier: prettier,
|
|
38
|
+
},
|
|
39
|
+
rules: {
|
|
40
|
+
...prettier.configs.recommended.rules,
|
|
41
|
+
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
|
42
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
43
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
44
|
+
"@typescript-eslint/no-floating-promises": "off",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
];
|
package/index.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { program, Option } from
|
|
4
|
-
import { registerCommands } from
|
|
5
|
-
import { checkBergetConfig } from
|
|
6
|
-
import chalk from
|
|
7
|
-
import { version } from
|
|
8
|
-
process.env.DOTENV_CONFIG_OVERRIDE =
|
|
9
|
-
import
|
|
3
|
+
import { program, Option } from "commander";
|
|
4
|
+
import { registerCommands } from "./src/commands";
|
|
5
|
+
import { checkBergetConfig } from "./src/utils/config-checker";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { version } from "./package.json";
|
|
8
|
+
process.env.DOTENV_CONFIG_OVERRIDE = "true";
|
|
9
|
+
import "dotenv/config";
|
|
10
10
|
|
|
11
11
|
// Set version and description
|
|
12
12
|
program
|
|
13
|
-
.name(
|
|
13
|
+
.name("berget")
|
|
14
14
|
.description(
|
|
15
15
|
`______ _ ___ _____
|
|
16
16
|
| ___ \\ | | / _ \\|_ _|
|
|
@@ -22,70 +22,64 @@ program
|
|
|
22
22
|
|___/ AI on European terms
|
|
23
23
|
Version: ${version}`
|
|
24
24
|
)
|
|
25
|
-
.version(version,
|
|
26
|
-
.addOption(new Option(
|
|
27
|
-
.addOption(new Option(
|
|
28
|
-
.option(
|
|
25
|
+
.version(version, "-v, --version")
|
|
26
|
+
.addOption(new Option("--local").default(false).hideHelp())
|
|
27
|
+
.addOption(new Option("--stage").default(false).hideHelp())
|
|
28
|
+
.option("--debug", "Enable debug output", false);
|
|
29
29
|
|
|
30
30
|
// Register all commands
|
|
31
|
-
registerCommands(program)
|
|
31
|
+
registerCommands(program);
|
|
32
32
|
|
|
33
33
|
// Check for .bergetconfig if not running a command
|
|
34
34
|
if (process.argv.length <= 2) {
|
|
35
|
-
checkBergetConfig()
|
|
35
|
+
checkBergetConfig();
|
|
36
36
|
|
|
37
37
|
// Show the full help (including logo and commands)
|
|
38
|
-
program.outputHelp()
|
|
39
|
-
process.exit(0)
|
|
38
|
+
program.outputHelp();
|
|
39
|
+
process.exit(0);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// Add helpful suggestions for common command mistakes
|
|
43
43
|
const commonMistakes: Record<string, string> = {
|
|
44
|
-
login:
|
|
45
|
-
logout:
|
|
46
|
-
whoami:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
usage:
|
|
52
|
-
init:
|
|
53
|
-
}
|
|
44
|
+
login: "auth login",
|
|
45
|
+
logout: "auth logout",
|
|
46
|
+
whoami: "auth whoami",
|
|
47
|
+
"list-models": "models list",
|
|
48
|
+
"list-keys": "api-keys list",
|
|
49
|
+
"create-key": "api-keys create",
|
|
50
|
+
"list-clusters": "clusters list",
|
|
51
|
+
usage: "billing usage",
|
|
52
|
+
init: "code init",
|
|
53
|
+
};
|
|
54
54
|
|
|
55
55
|
// Add error handler for unknown commands
|
|
56
|
-
program.on(
|
|
57
|
-
const unknownCommand = operands[0] as string
|
|
58
|
-
console.error(chalk.red(`Error: unknown command '${unknownCommand}'`))
|
|
56
|
+
program.on("command:*", operands => {
|
|
57
|
+
const unknownCommand = operands[0] as string;
|
|
58
|
+
console.error(chalk.red(`Error: unknown command '${unknownCommand}'`));
|
|
59
59
|
|
|
60
60
|
// Check if this is a known mistake and suggest the correct command
|
|
61
61
|
if (unknownCommand in commonMistakes) {
|
|
62
62
|
console.log(
|
|
63
|
-
chalk.yellow(
|
|
64
|
-
|
|
65
|
-
`berget ${commonMistakes[unknownCommand]}`
|
|
66
|
-
)}`
|
|
67
|
-
)
|
|
68
|
-
)
|
|
63
|
+
chalk.yellow(`Did you mean? ${chalk.bold(`berget ${commonMistakes[unknownCommand]}`)}`)
|
|
64
|
+
);
|
|
69
65
|
} else {
|
|
70
66
|
// Try to find similar commands
|
|
71
|
-
const availableCommands = program.commands.map(
|
|
67
|
+
const availableCommands = program.commands.map(cmd => cmd.name());
|
|
72
68
|
const similarCommands = availableCommands.filter(
|
|
73
|
-
|
|
74
|
-
)
|
|
69
|
+
cmd => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
|
|
70
|
+
);
|
|
75
71
|
|
|
76
72
|
if (similarCommands.length > 0) {
|
|
77
|
-
console.log(chalk.yellow(
|
|
78
|
-
similarCommands.forEach(
|
|
79
|
-
console.log(chalk.yellow(` ${chalk.bold(`berget ${cmd}`)}`))
|
|
80
|
-
})
|
|
73
|
+
console.log(chalk.yellow("Similar commands:"));
|
|
74
|
+
similarCommands.forEach(cmd => {
|
|
75
|
+
console.log(chalk.yellow(` ${chalk.bold(`berget ${cmd}`)}`));
|
|
76
|
+
});
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
console.log(
|
|
84
|
-
chalk.blue('\nRun `berget --help` for a list of available commands.')
|
|
85
|
-
)
|
|
79
|
+
console.log(chalk.blue("\nRun `berget --help` for a list of available commands."));
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
process.exit(1)
|
|
89
|
-
})
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
90
84
|
|
|
91
|
-
program.parse(process.argv)
|
|
85
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "berget",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.7",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"berget": "dist/index.js"
|
|
7
7
|
},
|
|
8
8
|
"private": false,
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=20.0.0"
|
|
11
|
+
},
|
|
9
12
|
"publishConfig": {
|
|
10
13
|
"access": "public"
|
|
11
14
|
},
|
|
@@ -17,8 +20,14 @@
|
|
|
17
20
|
"build": "tsc",
|
|
18
21
|
"test": "vitest",
|
|
19
22
|
"test:run": "vitest run",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"lint": "eslint . --ext .ts,.tsx,.js",
|
|
25
|
+
"lint:fix": "eslint . --ext .ts,.tsx,.js --fix",
|
|
26
|
+
"format": "prettier --write .",
|
|
27
|
+
"format:check": "prettier --check .",
|
|
20
28
|
"prepublishOnly": "npm run build",
|
|
21
|
-
"generate-types": "openapi-typescript https://api.berget.ai/openapi.json -o src/types/api.d.ts"
|
|
29
|
+
"generate-types": "openapi-typescript https://api.berget.ai/openapi.json -o src/types/api.d.ts",
|
|
30
|
+
"prepare": "husky"
|
|
22
31
|
},
|
|
23
32
|
"author": "Berget AI AB",
|
|
24
33
|
"license": "MIT",
|
|
@@ -28,6 +37,14 @@
|
|
|
28
37
|
"@types/marked": "^5.0.2",
|
|
29
38
|
"@types/marked-terminal": "^6.1.1",
|
|
30
39
|
"@types/node": "^20.11.20",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
41
|
+
"@typescript-eslint/parser": "^8.59.3",
|
|
42
|
+
"eslint": "^10.3.0",
|
|
43
|
+
"eslint-config-prettier": "^10.1.8",
|
|
44
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
45
|
+
"husky": "^9.1.7",
|
|
46
|
+
"lint-staged": "^17.0.4",
|
|
47
|
+
"prettier": "^3.8.3",
|
|
31
48
|
"tsx": "^4.19.3",
|
|
32
49
|
"typescript": "^5.3.3",
|
|
33
50
|
"vitest": "^1.0.0"
|
|
@@ -48,5 +65,14 @@
|
|
|
48
65
|
"openapi-typescript": "^6.7.4",
|
|
49
66
|
"readline": "^1.3.0",
|
|
50
67
|
"zod": "^4.1.12"
|
|
68
|
+
},
|
|
69
|
+
"lint-staged": {
|
|
70
|
+
"*.{ts,tsx}": [
|
|
71
|
+
"eslint --fix",
|
|
72
|
+
"prettier --write"
|
|
73
|
+
],
|
|
74
|
+
"*.{json,yml,yaml,md}": [
|
|
75
|
+
"prettier --write"
|
|
76
|
+
]
|
|
51
77
|
}
|
|
52
78
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "app",
|
|
6
|
+
description: "Expo + React Native apps; props-first, offline-aware, shared tokens.",
|
|
7
|
+
mode: "primary",
|
|
8
|
+
temperature: 0.4,
|
|
9
|
+
top_p: 0.9,
|
|
10
|
+
permission: {
|
|
11
|
+
edit: "allow",
|
|
12
|
+
bash: "deny",
|
|
13
|
+
webfetch: "allow",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
systemPrompt: `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.
|
|
17
|
+
|
|
18
|
+
GIT WORKFLOW RULES (CRITICAL):
|
|
19
|
+
- NEVER push directly to main branch - ALWAYS use pull requests
|
|
20
|
+
- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'
|
|
21
|
+
- ALWAYS clean up test files, documentation files, and temporary artifacts before committing
|
|
22
|
+
- ALWAYS ensure git history maintains production quality - no test commits, no debugging code
|
|
23
|
+
- ALWAYS create descriptive commit messages following project conventions
|
|
24
|
+
- ALWAYS run tests and build before creating PR
|
|
25
|
+
|
|
26
|
+
CRITICAL: 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.`,
|
|
27
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "backend",
|
|
6
|
+
description: "Functional, modular Koa + TypeScript services",
|
|
7
|
+
mode: "primary",
|
|
8
|
+
},
|
|
9
|
+
systemPrompt: `# Backend Agent
|
|
10
|
+
|
|
11
|
+
Functional, modular Koa + TypeScript services with schema-first approach and code quality focus.
|
|
12
|
+
|
|
13
|
+
**Use when:**
|
|
14
|
+
|
|
15
|
+
- Working with Koa routers and services
|
|
16
|
+
- Backend development in /services
|
|
17
|
+
- API development and database work
|
|
18
|
+
|
|
19
|
+
**Key features:**
|
|
20
|
+
|
|
21
|
+
- Zod validation and OpenAPI generation
|
|
22
|
+
- Code quality and refactoring principles
|
|
23
|
+
- PR workflow integration`,
|
|
24
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "devops",
|
|
6
|
+
description: "Declarative GitOps infra with FluxCD, Kustomize, Helm, operators.",
|
|
7
|
+
mode: "primary",
|
|
8
|
+
temperature: 0.3,
|
|
9
|
+
top_p: 0.8,
|
|
10
|
+
permission: {
|
|
11
|
+
edit: "allow",
|
|
12
|
+
bash: "allow",
|
|
13
|
+
webfetch: "allow",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
systemPrompt: `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.
|
|
17
|
+
|
|
18
|
+
GIT WORKFLOW RULES (CRITICAL):
|
|
19
|
+
- NEVER push directly to main branch - ALWAYS use pull requests
|
|
20
|
+
- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'
|
|
21
|
+
- ALWAYS clean up test files, documentation files, and temporary artifacts before committing
|
|
22
|
+
- ALWAYS ensure git history maintains production quality - no test commits, no debugging code
|
|
23
|
+
- ALWAYS create descriptive commit messages following project conventions
|
|
24
|
+
- ALWAYS run tests and build before creating PR
|
|
25
|
+
|
|
26
|
+
Helm Values Configuration Process:
|
|
27
|
+
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.
|
|
28
|
+
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.
|
|
29
|
+
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.
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
CRITICAL: When all devops implementation tasks are complete and ready for merge, ALWAYS invoke @quality subagent to handle testing, building, and complete PR management including URL provision.`,
|
|
33
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "frontend",
|
|
6
|
+
description: "Scandinavian, type-safe UIs with React, Tailwind, and Shadcn",
|
|
7
|
+
mode: "primary",
|
|
8
|
+
},
|
|
9
|
+
systemPrompt: `# Frontend Agent
|
|
10
|
+
|
|
11
|
+
Builds Scandinavian, type-safe UIs with React, Tailwind, and Shadcn.
|
|
12
|
+
|
|
13
|
+
**Use when:**
|
|
14
|
+
|
|
15
|
+
- Working with React components (.tsx files)
|
|
16
|
+
- Frontend development in /apps/frontend
|
|
17
|
+
- UI/UX implementation
|
|
18
|
+
|
|
19
|
+
**Key features:**
|
|
20
|
+
|
|
21
|
+
- Design system integration
|
|
22
|
+
- Semantic tokens and accessibility
|
|
23
|
+
- Props-first component architecture`,
|
|
24
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "fullstack",
|
|
6
|
+
description: "Router/coordinator agent for full-stack development",
|
|
7
|
+
mode: "primary",
|
|
8
|
+
},
|
|
9
|
+
systemPrompt: `# Fullstack Agent
|
|
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
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Agent, AgentConfig } from "./types.js";
|
|
2
|
+
import { agent as fullstack } from "./fullstack.js";
|
|
3
|
+
import { agent as frontend } from "./frontend.js";
|
|
4
|
+
import { agent as backend } from "./backend.js";
|
|
5
|
+
import { agent as devops } from "./devops.js";
|
|
6
|
+
import { agent as app } from "./app.js";
|
|
7
|
+
import { agent as quality } from "./quality.js";
|
|
8
|
+
import { agent as security } from "./security.js";
|
|
9
|
+
|
|
10
|
+
const agents: Record<string, Agent> = {
|
|
11
|
+
fullstack,
|
|
12
|
+
frontend,
|
|
13
|
+
backend,
|
|
14
|
+
devops,
|
|
15
|
+
app,
|
|
16
|
+
quality,
|
|
17
|
+
security,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { agents };
|
|
21
|
+
export type { Agent, AgentConfig };
|
|
22
|
+
|
|
23
|
+
export function getAllAgents(): Agent[] {
|
|
24
|
+
return Object.values(agents);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getAgent(name: string): Agent | undefined {
|
|
28
|
+
return agents[name];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function toMarkdown(agent: Agent): string {
|
|
32
|
+
const { config, systemPrompt } = agent;
|
|
33
|
+
let frontmatter = `---\nname: ${config.name}\ndescription: ${config.description}\n`;
|
|
34
|
+
|
|
35
|
+
if (config.mode) {
|
|
36
|
+
frontmatter += `mode: ${config.mode}\n`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (config.temperature) {
|
|
40
|
+
frontmatter += `temperature: ${config.temperature}\n`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (config.top_p) {
|
|
44
|
+
frontmatter += `top_p: ${config.top_p}\n`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (config.permission) {
|
|
48
|
+
frontmatter += `permission:\n`;
|
|
49
|
+
for (const [key, value] of Object.entries(config.permission)) {
|
|
50
|
+
frontmatter += ` ${key}: ${value}\n`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return `${frontmatter}---\n\n${systemPrompt}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function toPiPrompt(agent: Agent): string {
|
|
58
|
+
return agent.systemPrompt;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function toAgentTemplate(agent: Agent): {
|
|
62
|
+
name: string;
|
|
63
|
+
content: string;
|
|
64
|
+
description: string;
|
|
65
|
+
} {
|
|
66
|
+
return {
|
|
67
|
+
name: agent.config.name,
|
|
68
|
+
description: agent.config.description,
|
|
69
|
+
content: agent.systemPrompt,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Agent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const agent: Agent = {
|
|
4
|
+
config: {
|
|
5
|
+
name: "quality",
|
|
6
|
+
description: "Quality assurance specialist for testing, building, and complete PR management.",
|
|
7
|
+
mode: "subagent",
|
|
8
|
+
temperature: 0.1,
|
|
9
|
+
top_p: 0.9,
|
|
10
|
+
permission: {
|
|
11
|
+
edit: "allow",
|
|
12
|
+
bash: "allow",
|
|
13
|
+
webfetch: "allow",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
systemPrompt: `Voice: Scandinavian calm—precise, concise, confident. You are Berget Code Quality agent. Specialist in code quality assurance, testing, building, and pull request lifecycle management.
|
|
17
|
+
|
|
18
|
+
Core responsibilities:
|
|
19
|
+
- Run comprehensive test suites (npm test, npm run test, jest, vitest)
|
|
20
|
+
- Execute build processes (npm run build, webpack, vite, tsc)
|
|
21
|
+
- Create and manage pull requests with proper descriptions
|
|
22
|
+
- Handle merge conflicts and keep main updated
|
|
23
|
+
- Monitor GitHub for reviewer comments and address them
|
|
24
|
+
- Ensure code quality standards are met
|
|
25
|
+
- Validate linting and formatting (npm run lint, prettier)
|
|
26
|
+
- Check test coverage and performance benchmarks
|
|
27
|
+
- Handle CI/CD pipeline validation
|
|
28
|
+
|
|
29
|
+
Complete PR Workflow:
|
|
30
|
+
1. Ensure all tests pass: npm test
|
|
31
|
+
2. Build successfully: npm run build
|
|
32
|
+
3. Commit all changes with proper message
|
|
33
|
+
4. Push to feature branch
|
|
34
|
+
5. Update main branch and handle merge conflicts
|
|
35
|
+
6. Create or update PR with comprehensive description
|
|
36
|
+
7. Monitor for reviewer comments
|
|
37
|
+
8. Address feedback and push updates
|
|
38
|
+
9. Always provide PR URL for user review
|
|
39
|
+
|
|
40
|
+
Essential CLI commands:
|
|
41
|
+
- npm test or npm run test (run test suite)
|
|
42
|
+
- npm run build (build project)
|
|
43
|
+
- npm run lint (run linting)
|
|
44
|
+
- npm run format (format code)
|
|
45
|
+
- npm run test:coverage (check coverage)
|
|
46
|
+
- git add <specific-files> && git commit -m "message" && git push (commit and push)
|
|
47
|
+
- git checkout main && git pull origin main (update main)
|
|
48
|
+
- git checkout feature-branch && git merge main (handle conflicts)
|
|
49
|
+
- gh pr create --title "title" --body "body" (create PR)
|
|
50
|
+
- gh pr view --comments (check PR comments)
|
|
51
|
+
- gh pr edit --title "title" --body "body" (update PR)
|
|
52
|
+
|
|
53
|
+
PR Creation Process:
|
|
54
|
+
- Always include clear summary of changes
|
|
55
|
+
- List technical details and improvements
|
|
56
|
+
- Include testing and validation results
|
|
57
|
+
- Add any breaking changes or migration notes
|
|
58
|
+
- Provide PR URL immediately after creation
|
|
59
|
+
|
|
60
|
+
GIT WORKFLOW RULES (CRITICAL - ENFORCE STRICTLY):
|
|
61
|
+
- NEVER push directly to main branch - ALWAYS use pull requests
|
|
62
|
+
- NEVER use 'git add .' - ALWAYS add specific files with 'git add path/to/file'
|
|
63
|
+
- ALWAYS clean up test files, documentation files, and temporary artifacts before committing
|
|
64
|
+
- ALWAYS ensure git history maintains production quality - no test commits, no debugging code
|
|
65
|
+
- ALWAYS create descriptive commit messages following project conventions
|
|
66
|
+
- ALWAYS run tests and build before creating PR
|
|
67
|
+
|
|
68
|
+
Always provide specific command examples and wait for processes to complete before proceeding.`,
|
|
69
|
+
};
|