berget 2.2.7 → 2.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/.github/workflows/publish.yml +6 -6
  2. package/.github/workflows/test.yml +1 -1
  3. package/.prettierrc +5 -3
  4. package/dist/index.js +24 -25
  5. package/dist/package.json +7 -3
  6. package/dist/src/agents/app.js +8 -8
  7. package/dist/src/agents/backend.js +3 -3
  8. package/dist/src/agents/devops.js +8 -8
  9. package/dist/src/agents/frontend.js +3 -3
  10. package/dist/src/agents/fullstack.js +3 -3
  11. package/dist/src/agents/index.js +18 -18
  12. package/dist/src/agents/quality.js +8 -8
  13. package/dist/src/agents/security.js +8 -8
  14. package/dist/src/client.js +115 -127
  15. package/dist/src/commands/api-keys.js +181 -202
  16. package/dist/src/commands/auth.js +16 -25
  17. package/dist/src/commands/autocomplete.js +8 -8
  18. package/dist/src/commands/billing.js +10 -19
  19. package/dist/src/commands/chat.js +139 -170
  20. package/dist/src/commands/clusters.js +21 -30
  21. package/dist/src/commands/code/__tests__/auth-sync.test.js +189 -186
  22. package/dist/src/commands/code/__tests__/fake-api-key-service.js +3 -13
  23. package/dist/src/commands/code/__tests__/fake-auth-service.js +21 -29
  24. package/dist/src/commands/code/__tests__/fake-command-runner.js +22 -33
  25. package/dist/src/commands/code/__tests__/fake-file-store.js +19 -41
  26. package/dist/src/commands/code/__tests__/fake-prompter.js +81 -97
  27. package/dist/src/commands/code/__tests__/setup-flow.test.js +295 -295
  28. package/dist/src/commands/code/adapters/clack-prompter.js +15 -32
  29. package/dist/src/commands/code/adapters/fs-file-store.js +25 -44
  30. package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -41
  31. package/dist/src/commands/code/auth-sync.js +215 -228
  32. package/dist/src/commands/code/errors.js +15 -12
  33. package/dist/src/commands/code/setup.js +390 -425
  34. package/dist/src/commands/code.js +279 -294
  35. package/dist/src/commands/index.js +5 -5
  36. package/dist/src/commands/models.js +16 -25
  37. package/dist/src/commands/users.js +9 -18
  38. package/dist/src/constants/command-structure.js +138 -138
  39. package/dist/src/services/api-key-service.js +132 -152
  40. package/dist/src/services/auth-service.js +81 -95
  41. package/dist/src/services/browser-auth.js +121 -131
  42. package/dist/src/services/chat-service.js +369 -386
  43. package/dist/src/services/cluster-service.js +47 -62
  44. package/dist/src/services/collaborator-service.js +9 -21
  45. package/dist/src/services/flux-service.js +13 -25
  46. package/dist/src/services/helm-service.js +9 -21
  47. package/dist/src/services/kubectl-service.js +15 -29
  48. package/dist/src/utils/config-checker.js +8 -8
  49. package/dist/src/utils/config-loader.js +109 -109
  50. package/dist/src/utils/default-api-key.js +129 -139
  51. package/dist/src/utils/env-manager.js +55 -66
  52. package/dist/src/utils/error-handler.js +62 -62
  53. package/dist/src/utils/logger.js +74 -67
  54. package/dist/src/utils/markdown-renderer.js +28 -28
  55. package/dist/src/utils/opencode-validator.js +67 -69
  56. package/dist/src/utils/token-manager.js +67 -65
  57. package/dist/tests/commands/chat.test.js +30 -39
  58. package/dist/tests/commands/code.test.js +186 -195
  59. package/dist/tests/utils/config-loader.test.js +107 -107
  60. package/dist/tests/utils/env-manager.test.js +81 -90
  61. package/dist/tests/utils/opencode-validator.test.js +42 -41
  62. package/dist/vitest.config.js +1 -1
  63. package/eslint.config.mjs +65 -30
  64. package/index.ts +30 -31
  65. package/package.json +7 -3
  66. package/src/agents/app.ts +9 -9
  67. package/src/agents/backend.ts +4 -4
  68. package/src/agents/devops.ts +9 -9
  69. package/src/agents/frontend.ts +4 -4
  70. package/src/agents/fullstack.ts +4 -4
  71. package/src/agents/index.ts +27 -25
  72. package/src/agents/quality.ts +9 -9
  73. package/src/agents/security.ts +9 -9
  74. package/src/agents/types.ts +10 -10
  75. package/src/client.ts +85 -77
  76. package/src/commands/api-keys.ts +180 -185
  77. package/src/commands/auth.ts +15 -14
  78. package/src/commands/autocomplete.ts +10 -10
  79. package/src/commands/billing.ts +13 -12
  80. package/src/commands/chat.ts +145 -142
  81. package/src/commands/clusters.ts +20 -19
  82. package/src/commands/code/__tests__/auth-sync.test.ts +176 -175
  83. package/src/commands/code/__tests__/fake-api-key-service.ts +2 -2
  84. package/src/commands/code/__tests__/fake-auth-service.ts +18 -18
  85. package/src/commands/code/__tests__/fake-command-runner.ts +28 -22
  86. package/src/commands/code/__tests__/fake-file-store.ts +15 -15
  87. package/src/commands/code/__tests__/fake-prompter.ts +86 -85
  88. package/src/commands/code/__tests__/setup-flow.test.ts +253 -251
  89. package/src/commands/code/adapters/clack-prompter.ts +32 -30
  90. package/src/commands/code/adapters/fs-file-store.ts +18 -17
  91. package/src/commands/code/adapters/spawn-command-runner.ts +20 -15
  92. package/src/commands/code/auth-sync.ts +210 -210
  93. package/src/commands/code/errors.ts +11 -11
  94. package/src/commands/code/ports/auth-services.ts +7 -7
  95. package/src/commands/code/ports/command-runner.ts +2 -2
  96. package/src/commands/code/ports/file-store.ts +3 -3
  97. package/src/commands/code/ports/prompter.ts +13 -13
  98. package/src/commands/code/setup.ts +408 -406
  99. package/src/commands/code.ts +288 -287
  100. package/src/commands/index.ts +11 -10
  101. package/src/commands/models.ts +19 -18
  102. package/src/commands/users.ts +11 -10
  103. package/src/constants/command-structure.ts +159 -159
  104. package/src/services/api-key-service.ts +85 -85
  105. package/src/services/auth-service.ts +55 -54
  106. package/src/services/browser-auth.ts +62 -62
  107. package/src/services/chat-service.ts +170 -171
  108. package/src/services/cluster-service.ts +28 -28
  109. package/src/services/collaborator-service.ts +6 -6
  110. package/src/services/flux-service.ts +17 -17
  111. package/src/services/helm-service.ts +11 -11
  112. package/src/services/kubectl-service.ts +12 -12
  113. package/src/types/api.d.ts +1933 -1933
  114. package/src/types/json.d.ts +1 -1
  115. package/src/utils/config-checker.ts +7 -7
  116. package/src/utils/config-loader.ts +130 -129
  117. package/src/utils/default-api-key.ts +81 -80
  118. package/src/utils/env-manager.ts +37 -37
  119. package/src/utils/error-handler.ts +64 -64
  120. package/src/utils/logger.ts +72 -66
  121. package/src/utils/markdown-renderer.ts +28 -28
  122. package/src/utils/opencode-validator.ts +72 -71
  123. package/src/utils/token-manager.ts +69 -68
  124. package/tests/commands/chat.test.ts +32 -31
  125. package/tests/commands/code.test.ts +182 -181
  126. package/tests/utils/config-loader.test.ts +111 -110
  127. package/tests/utils/env-manager.test.ts +83 -79
  128. package/tests/utils/opencode-validator.test.ts +43 -42
  129. package/tsconfig.json +2 -1
  130. package/vitest.config.ts +2 -2
@@ -1,93 +1,92 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const node_fs_1 = require("node:fs");
3
4
  const vitest_1 = require("vitest");
4
5
  const opencode_validator_1 = require("../../src/utils/opencode-validator");
5
- const fs_1 = require("fs");
6
- (0, vitest_1.describe)("OpenCode Validator", () => {
7
- (0, vitest_1.it)("should validate a correct OpenCode configuration", () => {
6
+ (0, vitest_1.describe)('OpenCode Validator', () => {
7
+ (0, vitest_1.it)('should validate a correct OpenCode configuration', () => {
8
8
  const validConfig = {
9
- $schema: "https://opencode.ai/config.json",
10
- username: "test-user",
11
- model: "gpt-4",
9
+ $schema: 'https://opencode.ai/config.json',
12
10
  agent: {
13
11
  test: {
14
- model: "gpt-4",
15
- temperature: 0.7,
16
- prompt: "Test agent",
12
+ model: 'gpt-4',
17
13
  permission: {
18
- edit: "allow",
19
- bash: "allow",
20
- webfetch: "allow",
14
+ bash: 'allow',
15
+ edit: 'allow',
16
+ webfetch: 'allow',
21
17
  },
18
+ prompt: 'Test agent',
19
+ temperature: 0.7,
22
20
  },
23
21
  },
22
+ model: 'gpt-4',
23
+ username: 'test-user',
24
24
  };
25
25
  const result = (0, opencode_validator_1.validateOpenCodeConfig)(validConfig);
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)("should reject invalid configuration", () => {
29
+ (0, vitest_1.it)('should reject invalid configuration', () => {
30
30
  const invalidConfig = {
31
- username: 123, // Should be string
32
- model: "gpt-4",
33
31
  agent: {
34
32
  test: {
35
- model: "gpt-4",
36
- temperature: "high", // Should be number
37
- prompt: "Test agent",
33
+ model: 'gpt-4',
38
34
  permission: {
39
- edit: "invalid", // Should be enum value
40
- bash: "allow",
41
- webfetch: "allow",
35
+ bash: 'allow',
36
+ edit: 'invalid', // Should be enum value
37
+ webfetch: 'allow',
42
38
  },
39
+ prompt: 'Test agent',
40
+ temperature: 'high', // Should be number
43
41
  },
44
42
  },
43
+ model: 'gpt-4',
44
+ username: 123, // Should be string
45
45
  };
46
46
  const result = (0, opencode_validator_1.validateOpenCodeConfig)(invalidConfig);
47
47
  (0, vitest_1.expect)(result.valid).toBe(false);
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)("should fix common configuration issues", () => {
51
+ (0, vitest_1.it)('should fix common configuration issues', () => {
52
52
  const configWithIssues = {
53
- username: "test-user",
54
- model: "gpt-4",
55
- tools: {
56
- compact: { threshold: 80000 }, // Should be boolean
57
- },
58
53
  maxTokens: 4000, // Invalid property
54
+ model: 'gpt-4',
59
55
  provider: {
60
56
  berget: {
61
57
  models: {
62
- "test-model": {
63
- name: "Test Model",
64
- maxTokens: 4000, // Should be moved to limit.context
58
+ 'test-model': {
65
59
  contextWindow: 8000, // Should be moved to limit.context
60
+ maxTokens: 4000, // Should be moved to limit.context
61
+ name: 'Test Model',
66
62
  },
67
63
  },
68
64
  },
69
65
  },
66
+ tools: {
67
+ compact: { threshold: 80000 }, // Should be boolean
68
+ },
69
+ username: 'test-user',
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("boolean");
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["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();
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)("should validate the current opencode.json file", () => {
83
- var _a;
82
+ (0, vitest_1.it)('should validate the current opencode.json file', () => {
84
83
  let currentConfig;
85
84
  try {
86
- currentConfig = JSON.parse((0, fs_1.readFileSync)("opencode.json", "utf8"));
85
+ currentConfig = JSON.parse((0, node_fs_1.readFileSync)('opencode.json', 'utf8'));
87
86
  }
88
87
  catch (error) {
89
88
  // Skip when opencode.json is not present (e.g. in CI or clean checkouts)
90
- console.log("Skipping: opencode.json not found:", error);
89
+ console.log('Skipping: opencode.json not found:', error);
91
90
  return;
92
91
  }
93
92
  // Apply fixes to handle common issues
@@ -97,8 +96,10 @@ const fs_1 = require("fs");
97
96
  // The fixed config should be valid according to the JSON Schema
98
97
  (0, vitest_1.expect)(result.valid).toBe(true);
99
98
  if (!result.valid) {
100
- console.log("Fixed opencode.json validation errors:");
101
- (_a = result.errors) === null || _a === void 0 ? void 0 : _a.forEach(err => console.log(` - ${err}`));
99
+ console.log('Fixed opencode.json validation errors:');
100
+ if (result.errors)
101
+ for (const error of result.errors)
102
+ console.log(` - ${error}`);
102
103
  }
103
104
  });
104
105
  });
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_1 = require("vitest/config");
4
4
  exports.default = (0, config_1.defineConfig)({
5
5
  test: {
6
+ environment: 'node',
6
7
  globals: true,
7
- environment: "node",
8
8
  },
9
9
  });
package/eslint.config.mjs CHANGED
@@ -1,47 +1,82 @@
1
- import typescriptEslint from "@typescript-eslint/eslint-plugin";
2
- import typescriptParser from "@typescript-eslint/parser";
3
- import prettier from "eslint-plugin-prettier";
1
+ import vitest from '@vitest/eslint-plugin';
2
+ import perfectionist from 'eslint-plugin-perfectionist';
3
+ import prettier from 'eslint-plugin-prettier';
4
+ import promise from 'eslint-plugin-promise';
5
+ import sonarjs from 'eslint-plugin-sonarjs';
6
+ import tseslint from 'typescript-eslint';
4
7
 
5
- export default [
8
+ export default tseslint.config(
6
9
  {
7
10
  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/**",
11
+ 'node_modules/**',
12
+ 'dist/**',
13
+ 'build/**',
14
+ '*.lock',
15
+ '.husky/**',
16
+ 'coverage/**',
17
+ '.nyc_output/**',
18
+ 'test-results/**',
19
+ 'playwright-report/**',
20
+ '.pi/**',
21
+ 'src/types/api.d.ts',
18
22
  ],
19
23
  },
24
+ ...tseslint.configs.recommended,
25
+ ...tseslint.configs.strict,
26
+ sonarjs.configs.recommended,
27
+ promise.configs['flat/recommended'],
28
+ perfectionist.configs['recommended-natural'],
20
29
  {
21
- files: ["**/*.ts", "**/*.tsx"],
30
+ files: ['**/*.test.ts', '**/*.spec.ts', '**/*.test.tsx', '**/*.spec.tsx'],
22
31
  languageOptions: {
23
- parser: typescriptParser,
32
+ globals: {
33
+ ...vitest.environments.env.globals,
34
+ },
35
+ },
36
+ plugins: {
37
+ vitest,
38
+ },
39
+ rules: {
40
+ ...vitest.configs.recommended.rules,
41
+ '@typescript-eslint/no-explicit-any': 'off',
42
+ '@typescript-eslint/no-non-null-assertion': 'off',
43
+ },
44
+ },
45
+ {
46
+ files: ['**/*.ts', '**/*.tsx'],
47
+ languageOptions: {
48
+ ecmaVersion: 'latest',
24
49
  parserOptions: {
25
- ecmaVersion: "latest",
26
- sourceType: "commonjs",
27
- project: "./tsconfig.json",
50
+ project: './tsconfig.json',
28
51
  tsconfigRootDir: process.cwd(),
29
52
  },
30
- globals: {
31
- node: "readonly",
32
- es2022: "readonly",
33
- },
53
+ sourceType: 'commonjs',
34
54
  },
35
55
  plugins: {
36
- "@typescript-eslint": typescriptEslint,
37
- prettier: prettier,
56
+ prettier,
38
57
  },
39
58
  rules: {
40
59
  ...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",
60
+ '@typescript-eslint/no-dynamic-delete': 'off',
61
+ '@typescript-eslint/no-explicit-any': 'off',
62
+ '@typescript-eslint/no-non-null-assertion': 'off',
63
+ '@typescript-eslint/no-unused-vars': [
64
+ 'error',
65
+ { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
66
+ ],
67
+ 'sonarjs/cognitive-complexity': 'off',
68
+ 'sonarjs/different-types-comparison': 'off',
69
+ 'sonarjs/function-return-type': 'off',
70
+ 'sonarjs/no-duplicated-branches': 'off',
71
+ 'sonarjs/no-nested-conditional': 'off',
72
+ 'sonarjs/no-nested-functions': 'off',
73
+ 'sonarjs/no-nested-template-literals': 'off',
74
+ 'sonarjs/no-os-command-from-path': 'off',
75
+ 'sonarjs/no-unused-vars': 'off',
76
+ 'sonarjs/prefer-regexp-exec': 'off',
77
+ 'sonarjs/publicly-writable-directories': 'off',
78
+ 'sonarjs/redundant-type-aliases': 'off',
79
+ 'sonarjs/slow-regex': 'off',
45
80
  },
46
81
  },
47
- ];
82
+ );
package/index.ts CHANGED
@@ -1,16 +1,15 @@
1
- #!/usr/bin/env node
1
+ import chalk from 'chalk';
2
+ import { Option, program } from 'commander';
2
3
 
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";
4
+ import { version } from './package.json';
5
+ import { registerCommands } from './src/commands';
6
+ import { checkBergetConfig } from './src/utils/config-checker';
7
+ process.env.DOTENV_CONFIG_OVERRIDE = 'true';
8
+ import 'dotenv/config';
10
9
 
11
10
  // Set version and description
12
11
  program
13
- .name("berget")
12
+ .name('berget')
14
13
  .description(
15
14
  `______ _ ___ _____
16
15
  | ___ \\ | | / _ \\|_ _|
@@ -20,12 +19,12 @@ program
20
19
  \\____/ \\___|_| \\__, |\\___|\\_\\_ \\_| |_/\\___/
21
20
  __/ |
22
21
  |___/ AI on European terms
23
- Version: ${version}`
22
+ Version: ${version}`,
24
23
  )
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);
24
+ .version(version, '-v, --version')
25
+ .addOption(new Option('--local').default(false).hideHelp())
26
+ .addOption(new Option('--stage').default(false).hideHelp())
27
+ .option('--debug', 'Enable debug output', false);
29
28
 
30
29
  // Register all commands
31
30
  registerCommands(program);
@@ -41,42 +40,42 @@ if (process.argv.length <= 2) {
41
40
 
42
41
  // Add helpful suggestions for common command mistakes
43
42
  const commonMistakes: Record<string, string> = {
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",
43
+ 'create-key': 'api-keys create',
44
+ init: 'code init',
45
+ 'list-clusters': 'clusters list',
46
+ 'list-keys': 'api-keys list',
47
+ 'list-models': 'models list',
48
+ login: 'auth login',
49
+ logout: 'auth logout',
50
+ usage: 'billing usage',
51
+ whoami: 'auth whoami',
53
52
  };
54
53
 
55
54
  // Add error handler for unknown commands
56
- program.on("command:*", operands => {
55
+ program.on('command:*', (operands) => {
57
56
  const unknownCommand = operands[0] as string;
58
57
  console.error(chalk.red(`Error: unknown command '${unknownCommand}'`));
59
58
 
60
59
  // Check if this is a known mistake and suggest the correct command
61
60
  if (unknownCommand in commonMistakes) {
62
61
  console.log(
63
- chalk.yellow(`Did you mean? ${chalk.bold(`berget ${commonMistakes[unknownCommand]}`)}`)
62
+ chalk.yellow(`Did you mean? ${chalk.bold(`berget ${commonMistakes[unknownCommand]}`)}`),
64
63
  );
65
64
  } else {
66
65
  // Try to find similar commands
67
- const availableCommands = program.commands.map(cmd => cmd.name());
66
+ const availableCommands = program.commands.map((cmd) => cmd.name());
68
67
  const similarCommands = availableCommands.filter(
69
- cmd => cmd.includes(unknownCommand) || unknownCommand.includes(cmd)
68
+ (cmd) => cmd.includes(unknownCommand) || unknownCommand.includes(cmd),
70
69
  );
71
70
 
72
71
  if (similarCommands.length > 0) {
73
- console.log(chalk.yellow("Similar commands:"));
74
- similarCommands.forEach(cmd => {
72
+ console.log(chalk.yellow('Similar commands:'));
73
+ for (const cmd of similarCommands) {
75
74
  console.log(chalk.yellow(` ${chalk.bold(`berget ${cmd}`)}`));
76
- });
75
+ }
77
76
  }
78
77
 
79
- console.log(chalk.blue("\nRun `berget --help` for a list of available commands."));
78
+ console.log(chalk.blue('\nRun `berget --help` for a list of available commands.'));
80
79
  }
81
80
 
82
81
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "berget",
3
- "version": "2.2.7",
3
+ "version": "2.2.9",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "berget": "dist/index.js"
@@ -37,16 +37,19 @@
37
37
  "@types/marked": "^5.0.2",
38
38
  "@types/marked-terminal": "^6.1.1",
39
39
  "@types/node": "^20.11.20",
40
- "@typescript-eslint/eslint-plugin": "^8.59.3",
41
- "@typescript-eslint/parser": "^8.59.3",
40
+ "@vitest/eslint-plugin": "^1.6.17",
42
41
  "eslint": "^10.3.0",
43
42
  "eslint-config-prettier": "^10.1.8",
43
+ "eslint-plugin-perfectionist": "^5.9.0",
44
44
  "eslint-plugin-prettier": "^5.5.5",
45
+ "eslint-plugin-promise": "^7.3.0",
46
+ "eslint-plugin-sonarjs": "^3.0.2",
45
47
  "husky": "^9.1.7",
46
48
  "lint-staged": "^17.0.4",
47
49
  "prettier": "^3.8.3",
48
50
  "tsx": "^4.19.3",
49
51
  "typescript": "^5.3.3",
52
+ "typescript-eslint": "^8.59.3",
50
53
  "vitest": "^1.0.0"
51
54
  },
52
55
  "dependencies": {
@@ -57,6 +60,7 @@
57
60
  "commander": "^12.0.0",
58
61
  "dotenv": "^17.2.3",
59
62
  "fs-extra": "^11.3.0",
63
+ "globals": "^17.6.0",
60
64
  "jsonc-parser": "^3.3.1",
61
65
  "marked": "^9.1.6",
62
66
  "marked-terminal": "^6.2.0",
package/src/agents/app.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
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,
5
+ description: 'Expo + React Native apps; props-first, offline-aware, shared tokens.',
6
+ mode: 'primary',
7
+ name: 'app',
10
8
  permission: {
11
- edit: "allow",
12
- bash: "deny",
13
- webfetch: "allow",
9
+ bash: 'deny',
10
+ edit: 'allow',
11
+ webfetch: 'allow',
14
12
  },
13
+ temperature: 0.4,
14
+ top_p: 0.9,
15
15
  },
16
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
17
 
@@ -1,10 +1,10 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
4
  config: {
5
- name: "backend",
6
- description: "Functional, modular Koa + TypeScript services",
7
- mode: "primary",
5
+ description: 'Functional, modular Koa + TypeScript services',
6
+ mode: 'primary',
7
+ name: 'backend',
8
8
  },
9
9
  systemPrompt: `# Backend Agent
10
10
 
@@ -1,17 +1,17 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
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,
5
+ description: 'Declarative GitOps infra with FluxCD, Kustomize, Helm, operators.',
6
+ mode: 'primary',
7
+ name: 'devops',
10
8
  permission: {
11
- edit: "allow",
12
- bash: "allow",
13
- webfetch: "allow",
9
+ bash: 'allow',
10
+ edit: 'allow',
11
+ webfetch: 'allow',
14
12
  },
13
+ temperature: 0.3,
14
+ top_p: 0.8,
15
15
  },
16
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
17
 
@@ -1,10 +1,10 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
4
  config: {
5
- name: "frontend",
6
- description: "Scandinavian, type-safe UIs with React, Tailwind, and Shadcn",
7
- mode: "primary",
5
+ description: 'Scandinavian, type-safe UIs with React, Tailwind, and Shadcn',
6
+ mode: 'primary',
7
+ name: 'frontend',
8
8
  },
9
9
  systemPrompt: `# Frontend Agent
10
10
 
@@ -1,10 +1,10 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
4
  config: {
5
- name: "fullstack",
6
- description: "Router/coordinator agent for full-stack development",
7
- mode: "primary",
5
+ description: 'Router/coordinator agent for full-stack development',
6
+ mode: 'primary',
7
+ name: 'fullstack',
8
8
  },
9
9
  systemPrompt: `# Fullstack Agent
10
10
 
@@ -1,31 +1,43 @@
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";
1
+ import type { Agent } from './types.js';
2
+
3
+ import { agent as app } from './app.js';
4
+ import { agent as backend } from './backend.js';
5
+ import { agent as devops } from './devops.js';
6
+ import { agent as frontend } from './frontend.js';
7
+ import { agent as fullstack } from './fullstack.js';
8
+ import { agent as quality } from './quality.js';
9
+ import { agent as security } from './security.js';
9
10
 
10
11
  const agents: Record<string, Agent> = {
11
- fullstack,
12
- frontend,
12
+ app,
13
13
  backend,
14
14
  devops,
15
- app,
15
+ frontend,
16
+ fullstack,
16
17
  quality,
17
18
  security,
18
19
  };
19
20
 
20
21
  export { agents };
21
- export type { Agent, AgentConfig };
22
+
23
+ export function getAgent(name: string): Agent | undefined {
24
+ return agents[name];
25
+ }
22
26
 
23
27
  export function getAllAgents(): Agent[] {
24
28
  return Object.values(agents);
25
29
  }
26
30
 
27
- export function getAgent(name: string): Agent | undefined {
28
- return agents[name];
31
+ export function toAgentTemplate(agent: Agent): {
32
+ content: string;
33
+ description: string;
34
+ name: string;
35
+ } {
36
+ return {
37
+ content: agent.systemPrompt,
38
+ description: agent.config.description,
39
+ name: agent.config.name,
40
+ };
29
41
  }
30
42
 
31
43
  export function toMarkdown(agent: Agent): string {
@@ -58,14 +70,4 @@ export function toPiPrompt(agent: Agent): string {
58
70
  return agent.systemPrompt;
59
71
  }
60
72
 
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
- }
73
+ export { type Agent, type AgentConfig } from './types.js';
@@ -1,17 +1,17 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
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,
5
+ description: 'Quality assurance specialist for testing, building, and complete PR management.',
6
+ mode: 'subagent',
7
+ name: 'quality',
10
8
  permission: {
11
- edit: "allow",
12
- bash: "allow",
13
- webfetch: "allow",
9
+ bash: 'allow',
10
+ edit: 'allow',
11
+ webfetch: 'allow',
14
12
  },
13
+ temperature: 0.1,
14
+ top_p: 0.9,
15
15
  },
16
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
17
 
@@ -1,18 +1,18 @@
1
- import { Agent } from "./types.js";
1
+ import { Agent } from './types.js';
2
2
 
3
3
  export const agent: Agent = {
4
4
  config: {
5
- name: "security",
6
5
  description:
7
- "Security specialist for pentesting, OWASP compliance, and vulnerability assessments.",
8
- mode: "subagent",
9
- temperature: 0.2,
10
- top_p: 0.8,
6
+ 'Security specialist for pentesting, OWASP compliance, and vulnerability assessments.',
7
+ mode: 'subagent',
8
+ name: 'security',
11
9
  permission: {
12
- edit: "deny",
13
- bash: "allow",
14
- webfetch: "allow",
10
+ bash: 'allow',
11
+ edit: 'deny',
12
+ webfetch: 'allow',
15
13
  },
14
+ temperature: 0.2,
15
+ top_p: 0.8,
16
16
  },
17
17
  systemPrompt: `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.
18
18