byterover-cli 0.1.0

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 (193) hide show
  1. package/README.md +781 -0
  2. package/bin/dev.cmd +4 -0
  3. package/bin/dev.js +7 -0
  4. package/bin/run.cmd +4 -0
  5. package/bin/run.js +7 -0
  6. package/dist/commands/add.d.ts +60 -0
  7. package/dist/commands/add.js +230 -0
  8. package/dist/commands/clear.d.ts +13 -0
  9. package/dist/commands/clear.js +57 -0
  10. package/dist/commands/complete.d.ts +108 -0
  11. package/dist/commands/complete.js +340 -0
  12. package/dist/commands/gen-rules.d.ts +26 -0
  13. package/dist/commands/gen-rules.js +89 -0
  14. package/dist/commands/init.d.ts +24 -0
  15. package/dist/commands/init.js +135 -0
  16. package/dist/commands/login.d.ts +22 -0
  17. package/dist/commands/login.js +103 -0
  18. package/dist/commands/push.d.ts +33 -0
  19. package/dist/commands/push.js +150 -0
  20. package/dist/commands/retrieve.d.ts +26 -0
  21. package/dist/commands/retrieve.js +101 -0
  22. package/dist/commands/space/list.d.ts +22 -0
  23. package/dist/commands/space/list.js +105 -0
  24. package/dist/commands/space/switch.d.ts +20 -0
  25. package/dist/commands/space/switch.js +110 -0
  26. package/dist/commands/status.d.ts +22 -0
  27. package/dist/commands/status.js +116 -0
  28. package/dist/config/auth.config.d.ts +32 -0
  29. package/dist/config/auth.config.js +35 -0
  30. package/dist/config/environment.d.ts +35 -0
  31. package/dist/config/environment.js +39 -0
  32. package/dist/constants.d.ts +11 -0
  33. package/dist/constants.js +12 -0
  34. package/dist/core/domain/entities/agent.d.ts +5 -0
  35. package/dist/core/domain/entities/agent.js +23 -0
  36. package/dist/core/domain/entities/auth-token.d.ts +43 -0
  37. package/dist/core/domain/entities/auth-token.js +70 -0
  38. package/dist/core/domain/entities/br-config.d.ts +25 -0
  39. package/dist/core/domain/entities/br-config.js +58 -0
  40. package/dist/core/domain/entities/bullet.d.ts +51 -0
  41. package/dist/core/domain/entities/bullet.js +94 -0
  42. package/dist/core/domain/entities/curator-output.d.ts +14 -0
  43. package/dist/core/domain/entities/curator-output.js +23 -0
  44. package/dist/core/domain/entities/delta-batch.d.ts +30 -0
  45. package/dist/core/domain/entities/delta-batch.js +52 -0
  46. package/dist/core/domain/entities/delta-operation.d.ts +31 -0
  47. package/dist/core/domain/entities/delta-operation.js +50 -0
  48. package/dist/core/domain/entities/event.d.ts +8 -0
  49. package/dist/core/domain/entities/event.js +15 -0
  50. package/dist/core/domain/entities/executor-output.d.ts +27 -0
  51. package/dist/core/domain/entities/executor-output.js +33 -0
  52. package/dist/core/domain/entities/memory.d.ts +55 -0
  53. package/dist/core/domain/entities/memory.js +90 -0
  54. package/dist/core/domain/entities/oauth-token-data.d.ts +13 -0
  55. package/dist/core/domain/entities/oauth-token-data.js +20 -0
  56. package/dist/core/domain/entities/playbook.d.ts +97 -0
  57. package/dist/core/domain/entities/playbook.js +275 -0
  58. package/dist/core/domain/entities/presigned-url.d.ts +9 -0
  59. package/dist/core/domain/entities/presigned-url.js +18 -0
  60. package/dist/core/domain/entities/presigned-urls-response.d.ts +10 -0
  61. package/dist/core/domain/entities/presigned-urls-response.js +18 -0
  62. package/dist/core/domain/entities/reflector-output.d.ts +38 -0
  63. package/dist/core/domain/entities/reflector-output.js +44 -0
  64. package/dist/core/domain/entities/retrieve-result.d.ts +35 -0
  65. package/dist/core/domain/entities/retrieve-result.js +35 -0
  66. package/dist/core/domain/entities/space.d.ts +24 -0
  67. package/dist/core/domain/entities/space.js +52 -0
  68. package/dist/core/domain/entities/team.d.ts +42 -0
  69. package/dist/core/domain/entities/team.js +89 -0
  70. package/dist/core/domain/entities/user.d.ts +20 -0
  71. package/dist/core/domain/entities/user.js +32 -0
  72. package/dist/core/domain/errors/ace-error.d.ts +34 -0
  73. package/dist/core/domain/errors/ace-error.js +53 -0
  74. package/dist/core/domain/errors/auth-error.d.ts +10 -0
  75. package/dist/core/domain/errors/auth-error.js +20 -0
  76. package/dist/core/domain/errors/discovery-error.d.ts +21 -0
  77. package/dist/core/domain/errors/discovery-error.js +33 -0
  78. package/dist/core/domain/errors/rule-error.d.ts +6 -0
  79. package/dist/core/domain/errors/rule-error.js +12 -0
  80. package/dist/core/interfaces/i-ace-prompt-builder.d.ts +48 -0
  81. package/dist/core/interfaces/i-ace-prompt-builder.js +1 -0
  82. package/dist/core/interfaces/i-auth-service.d.ts +35 -0
  83. package/dist/core/interfaces/i-auth-service.js +1 -0
  84. package/dist/core/interfaces/i-browser-launcher.d.ts +11 -0
  85. package/dist/core/interfaces/i-browser-launcher.js +1 -0
  86. package/dist/core/interfaces/i-bullet-content-store.d.ts +36 -0
  87. package/dist/core/interfaces/i-bullet-content-store.js +1 -0
  88. package/dist/core/interfaces/i-callback-handler.d.ts +35 -0
  89. package/dist/core/interfaces/i-callback-handler.js +1 -0
  90. package/dist/core/interfaces/i-delta-store.d.ts +15 -0
  91. package/dist/core/interfaces/i-delta-store.js +1 -0
  92. package/dist/core/interfaces/i-executor-output-store.d.ts +14 -0
  93. package/dist/core/interfaces/i-executor-output-store.js +1 -0
  94. package/dist/core/interfaces/i-file-service.d.ts +34 -0
  95. package/dist/core/interfaces/i-file-service.js +1 -0
  96. package/dist/core/interfaces/i-http-client.d.ts +33 -0
  97. package/dist/core/interfaces/i-http-client.js +1 -0
  98. package/dist/core/interfaces/i-memory-retrieval-service.d.ts +40 -0
  99. package/dist/core/interfaces/i-memory-retrieval-service.js +1 -0
  100. package/dist/core/interfaces/i-memory-storage-service.d.ts +55 -0
  101. package/dist/core/interfaces/i-memory-storage-service.js +1 -0
  102. package/dist/core/interfaces/i-oidc-discovery-service.d.ts +20 -0
  103. package/dist/core/interfaces/i-oidc-discovery-service.js +1 -0
  104. package/dist/core/interfaces/i-playbook-service.d.ts +69 -0
  105. package/dist/core/interfaces/i-playbook-service.js +1 -0
  106. package/dist/core/interfaces/i-playbook-store.d.ts +38 -0
  107. package/dist/core/interfaces/i-playbook-store.js +1 -0
  108. package/dist/core/interfaces/i-project-config-store.d.ts +26 -0
  109. package/dist/core/interfaces/i-project-config-store.js +1 -0
  110. package/dist/core/interfaces/i-reflection-store.d.ts +21 -0
  111. package/dist/core/interfaces/i-reflection-store.js +1 -0
  112. package/dist/core/interfaces/i-rule-template-service.d.ts +17 -0
  113. package/dist/core/interfaces/i-rule-template-service.js +4 -0
  114. package/dist/core/interfaces/i-rule-writer-service.d.ts +13 -0
  115. package/dist/core/interfaces/i-rule-writer-service.js +1 -0
  116. package/dist/core/interfaces/i-space-service.d.ts +28 -0
  117. package/dist/core/interfaces/i-space-service.js +1 -0
  118. package/dist/core/interfaces/i-team-service.d.ts +29 -0
  119. package/dist/core/interfaces/i-team-service.js +1 -0
  120. package/dist/core/interfaces/i-template-loader.d.ts +29 -0
  121. package/dist/core/interfaces/i-template-loader.js +1 -0
  122. package/dist/core/interfaces/i-token-store.d.ts +22 -0
  123. package/dist/core/interfaces/i-token-store.js +1 -0
  124. package/dist/core/interfaces/i-tracking-service.d.ts +21 -0
  125. package/dist/core/interfaces/i-tracking-service.js +1 -0
  126. package/dist/core/interfaces/i-user-service.d.ts +14 -0
  127. package/dist/core/interfaces/i-user-service.js +1 -0
  128. package/dist/index.d.ts +1 -0
  129. package/dist/index.js +1 -0
  130. package/dist/infra/ace/ace-file-utils.d.ts +46 -0
  131. package/dist/infra/ace/ace-file-utils.js +83 -0
  132. package/dist/infra/ace/ace-prompt-templates.d.ts +13 -0
  133. package/dist/infra/ace/ace-prompt-templates.js +177 -0
  134. package/dist/infra/ace/file-bullet-content-store.d.ts +27 -0
  135. package/dist/infra/ace/file-bullet-content-store.js +89 -0
  136. package/dist/infra/ace/file-delta-store.d.ts +9 -0
  137. package/dist/infra/ace/file-delta-store.js +26 -0
  138. package/dist/infra/ace/file-executor-output-store.d.ts +9 -0
  139. package/dist/infra/ace/file-executor-output-store.js +26 -0
  140. package/dist/infra/ace/file-playbook-store.d.ts +29 -0
  141. package/dist/infra/ace/file-playbook-store.js +107 -0
  142. package/dist/infra/ace/file-reflection-store.d.ts +10 -0
  143. package/dist/infra/ace/file-reflection-store.js +55 -0
  144. package/dist/infra/auth/oauth-service.d.ts +49 -0
  145. package/dist/infra/auth/oauth-service.js +126 -0
  146. package/dist/infra/auth/oidc-discovery-service.d.ts +51 -0
  147. package/dist/infra/auth/oidc-discovery-service.js +145 -0
  148. package/dist/infra/browser/system-browser-launcher.d.ts +10 -0
  149. package/dist/infra/browser/system-browser-launcher.js +18 -0
  150. package/dist/infra/config/file-config-store.d.ts +21 -0
  151. package/dist/infra/config/file-config-store.js +57 -0
  152. package/dist/infra/file/fs-file-service.d.ts +28 -0
  153. package/dist/infra/file/fs-file-service.js +57 -0
  154. package/dist/infra/http/authenticated-http-client.d.ts +46 -0
  155. package/dist/infra/http/authenticated-http-client.js +99 -0
  156. package/dist/infra/http/callback-handler.d.ts +13 -0
  157. package/dist/infra/http/callback-handler.js +24 -0
  158. package/dist/infra/http/callback-server.d.ts +18 -0
  159. package/dist/infra/http/callback-server.js +93 -0
  160. package/dist/infra/memory/http-memory-retrieval-service.d.ts +18 -0
  161. package/dist/infra/memory/http-memory-retrieval-service.js +63 -0
  162. package/dist/infra/memory/http-memory-storage-service.d.ts +18 -0
  163. package/dist/infra/memory/http-memory-storage-service.js +67 -0
  164. package/dist/infra/memory/memory-to-playbook-mapper.d.ts +33 -0
  165. package/dist/infra/memory/memory-to-playbook-mapper.js +51 -0
  166. package/dist/infra/playbook/file-playbook-service.d.ts +43 -0
  167. package/dist/infra/playbook/file-playbook-service.js +133 -0
  168. package/dist/infra/rule/agent-rule-config.d.ts +19 -0
  169. package/dist/infra/rule/agent-rule-config.js +77 -0
  170. package/dist/infra/rule/rule-template-service.d.ts +18 -0
  171. package/dist/infra/rule/rule-template-service.js +80 -0
  172. package/dist/infra/rule/rule-writer-service.d.ts +19 -0
  173. package/dist/infra/rule/rule-writer-service.js +43 -0
  174. package/dist/infra/space/http-space-service.d.ts +20 -0
  175. package/dist/infra/space/http-space-service.js +67 -0
  176. package/dist/infra/storage/keychain-token-store.d.ts +10 -0
  177. package/dist/infra/storage/keychain-token-store.js +40 -0
  178. package/dist/infra/team/http-team-service.d.ts +21 -0
  179. package/dist/infra/team/http-team-service.js +71 -0
  180. package/dist/infra/template/fs-template-loader.d.ts +33 -0
  181. package/dist/infra/template/fs-template-loader.js +62 -0
  182. package/dist/infra/tracking/mixpanel-tracking-service.d.ts +14 -0
  183. package/dist/infra/tracking/mixpanel-tracking-service.js +44 -0
  184. package/dist/infra/user/http-user-service.d.ts +12 -0
  185. package/dist/infra/user/http-user-service.js +26 -0
  186. package/dist/templates/README.md +103 -0
  187. package/dist/templates/base.md +3 -0
  188. package/dist/templates/sections/command-reference.md +141 -0
  189. package/dist/templates/sections/workflow.md +46 -0
  190. package/dist/utils/file-helpers.d.ts +15 -0
  191. package/dist/utils/file-helpers.js +45 -0
  192. package/oclif.manifest.json +476 -0
  193. package/package.json +82 -0
@@ -0,0 +1,110 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { Command, ux } from '@oclif/core';
3
+ import { getCurrentConfig } from '../../config/environment.js';
4
+ import { BrConfig } from '../../core/domain/entities/br-config.js';
5
+ import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
6
+ import { HttpSpaceService } from '../../infra/space/http-space-service.js';
7
+ import { KeychainTokenStore } from '../../infra/storage/keychain-token-store.js';
8
+ import { HttpTeamService } from '../../infra/team/http-team-service.js';
9
+ export default class SpaceSwitch extends Command {
10
+ static description = 'Switch to a different team or space (updates .br/config.json)';
11
+ static examples = [
12
+ '<%= config.bin %> <%= command.id %>',
13
+ '# Shows current configuration, then prompts for new team/space selection',
14
+ ];
15
+ createServices() {
16
+ const envConfig = getCurrentConfig();
17
+ return {
18
+ projectConfigStore: new ProjectConfigStore(),
19
+ spaceService: new HttpSpaceService({
20
+ apiBaseUrl: envConfig.apiBaseUrl,
21
+ }),
22
+ teamService: new HttpTeamService({
23
+ apiBaseUrl: envConfig.apiBaseUrl,
24
+ }),
25
+ tokenStore: new KeychainTokenStore(),
26
+ };
27
+ }
28
+ async promptForSpaceSelection(spaces) {
29
+ const selectedSpaceId = await select({
30
+ choices: spaces.map((space) => ({
31
+ name: space.getDisplayName(),
32
+ value: space.id,
33
+ })),
34
+ message: 'Select a space',
35
+ });
36
+ const selectedSpace = spaces.find((space) => space.id === selectedSpaceId);
37
+ if (!selectedSpace) {
38
+ this.error('Space selection failed');
39
+ }
40
+ return selectedSpace;
41
+ }
42
+ async promptForTeamSelection(teams) {
43
+ const selectedTeamId = await select({
44
+ choices: teams.map((team) => ({
45
+ name: team.name,
46
+ value: team.id,
47
+ })),
48
+ message: 'Select a team',
49
+ });
50
+ const selectedTeam = teams.find((team) => team.id === selectedTeamId);
51
+ if (!selectedTeam) {
52
+ this.error('Team selection failed');
53
+ }
54
+ return selectedTeam;
55
+ }
56
+ async run() {
57
+ try {
58
+ const { projectConfigStore, spaceService, teamService, tokenStore } = this.createServices();
59
+ // Check project initialization (MUST exist for switch)
60
+ const currentConfig = await projectConfigStore.read();
61
+ if (currentConfig === undefined) {
62
+ this.error('Project not initialized. Run "br init" first.');
63
+ }
64
+ // Show current configuration
65
+ this.log('Current configuration:');
66
+ this.log(` Team: ${currentConfig.teamName}`);
67
+ this.log(` Space: ${currentConfig.spaceName}`);
68
+ this.log();
69
+ // Validate authentication
70
+ const token = await tokenStore.load();
71
+ if (token === undefined) {
72
+ this.error('Not authenticated. Please run "br login" first.');
73
+ }
74
+ if (!token.isValid()) {
75
+ this.error('Authentication token expired. Please run "br login" again.');
76
+ }
77
+ // Fetch all teams
78
+ ux.action.start('Fetching all teams');
79
+ const teamResult = await teamService.getTeams(token.accessToken, token.sessionKey, { fetchAll: true });
80
+ ux.action.stop();
81
+ if (teamResult.teams.length === 0) {
82
+ this.error('No teams found. Please create a team in the ByteRover dashboard first.');
83
+ }
84
+ // Prompt for team selection
85
+ this.log();
86
+ const selectedTeam = await this.promptForTeamSelection(teamResult.teams);
87
+ // Fetch spaces for selected team
88
+ ux.action.start('Fetching all spaces');
89
+ const spaceResult = await spaceService.getSpaces(token.accessToken, token.sessionKey, selectedTeam.id, {
90
+ fetchAll: true,
91
+ });
92
+ ux.action.stop();
93
+ if (spaceResult.spaces.length === 0) {
94
+ this.error(`No spaces found in team "${selectedTeam.getDisplayName()}". Please create a space in the ByteRover dashboard first.`);
95
+ }
96
+ // Prompt for space selection
97
+ this.log();
98
+ const selectedSpace = await this.promptForSpaceSelection(spaceResult.spaces);
99
+ // Update configuration
100
+ const newConfig = BrConfig.fromSpace(selectedSpace);
101
+ await projectConfigStore.write(newConfig);
102
+ // Display success
103
+ this.log(`\n✓ Successfully switched to space: ${selectedSpace.getDisplayName()}`);
104
+ this.log(`✓ Configuration updated in: .br/config.json`);
105
+ }
106
+ catch (error) {
107
+ this.error(error instanceof Error ? error.message : 'Switch failed');
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,22 @@
1
+ import { Command } from '@oclif/core';
2
+ import type { IPlaybookStore } from '../core/interfaces/i-playbook-store.js';
3
+ import type { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
4
+ import type { ITokenStore } from '../core/interfaces/i-token-store.js';
5
+ import { ITrackingService } from '../core/interfaces/i-tracking-service.js';
6
+ export default class Status extends Command {
7
+ static args: {
8
+ directory: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
9
+ };
10
+ static description: string;
11
+ static examples: string[];
12
+ static flags: {
13
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ };
15
+ protected createServices(): {
16
+ playbookStore: IPlaybookStore;
17
+ projectConfigStore: IProjectConfigStore;
18
+ tokenStore: ITokenStore;
19
+ trackingService: ITrackingService;
20
+ };
21
+ run(): Promise<void>;
22
+ }
@@ -0,0 +1,116 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { ACE_DIR, BR_DIR, BULLETS_DIR } from '../constants.js';
4
+ import { FilePlaybookStore } from '../infra/ace/file-playbook-store.js';
5
+ import { ProjectConfigStore } from '../infra/config/file-config-store.js';
6
+ import { KeychainTokenStore } from '../infra/storage/keychain-token-store.js';
7
+ import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
8
+ export default class Status extends Command {
9
+ static args = {
10
+ directory: Args.string({ description: 'Project directory (defaults to current directory)', required: false }),
11
+ };
12
+ static description = 'Show CLI status and project information. Display local ACE context (ACE playbook) managed by ByteRover CLI';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %>',
15
+ '# Check status after login:\n<%= config.bin %> login\n<%= config.bin %> <%= command.id %>',
16
+ '# Verify project initialization:\n<%= config.bin %> init\n<%= config.bin %> <%= command.id %>',
17
+ '<%= config.bin %> <%= command.id %>',
18
+ '<%= config.bin %> <%= command.id %> /path/to/project',
19
+ '<%= config.bin %> <%= command.id %> --format json',
20
+ ];
21
+ static flags = {
22
+ format: Flags.string({
23
+ char: 'f',
24
+ default: 'table',
25
+ description: 'Output format',
26
+ options: ['table', 'json'],
27
+ }),
28
+ };
29
+ createServices() {
30
+ const tokenStore = new KeychainTokenStore();
31
+ const trackingService = new MixpanelTrackingService(tokenStore);
32
+ return {
33
+ playbookStore: new FilePlaybookStore(),
34
+ projectConfigStore: new ProjectConfigStore(),
35
+ tokenStore,
36
+ trackingService,
37
+ };
38
+ }
39
+ async run() {
40
+ const { playbookStore, projectConfigStore, tokenStore } = this.createServices();
41
+ const { args, flags } = await this.parse(Status);
42
+ this.log(`CLI Version: ${this.config.version}`);
43
+ try {
44
+ const token = await tokenStore.load();
45
+ if (token !== undefined && token.isValid()) {
46
+ this.log(`Status: Logged in as ${token.userEmail}`);
47
+ }
48
+ else if (token === undefined) {
49
+ this.log('Status: Not logged in');
50
+ }
51
+ else {
52
+ this.log('Status: Session expired (login required)');
53
+ }
54
+ }
55
+ catch (error) {
56
+ this.log('Status: Unable to check authentication status');
57
+ this.warn(`Warning: ${error.message}`);
58
+ }
59
+ const cwd = process.cwd();
60
+ this.log(`Current Directory: ${cwd}`);
61
+ try {
62
+ const isInitialized = await projectConfigStore.exists();
63
+ if (isInitialized) {
64
+ const config = await projectConfigStore.read();
65
+ if (config) {
66
+ this.log(`Project Status: Connected to ${config.teamName}/${config.spaceName}`);
67
+ }
68
+ else {
69
+ this.log('Project Status: Configuration file exists but is invalid');
70
+ }
71
+ }
72
+ else {
73
+ this.log('Project Status: Not initialized');
74
+ }
75
+ }
76
+ catch (error) {
77
+ this.log('Project Status: Unable to read project configuration');
78
+ this.warn(`Warning: ${error.message}`);
79
+ }
80
+ try {
81
+ const playbook = await playbookStore.load(args.directory);
82
+ if (!playbook) {
83
+ this.error('Playbook not found. Run `br init` to initialize.');
84
+ }
85
+ // Display based on format
86
+ if (flags.format === 'json') {
87
+ return this.log(JSON.stringify(playbook.toJson(), null, 2));
88
+ }
89
+ // Display file URLs like git status
90
+ const bullets = playbook.getBullets();
91
+ const sections = playbook.getSections();
92
+ if (bullets.length === 0) {
93
+ this.log('Playbook is empty. Use "br add" commands to add knowledge.');
94
+ return;
95
+ }
96
+ this.log(`\nMemory not pushed to cloud:`);
97
+ for (const section of sections) {
98
+ // Space between sections
99
+ this.log(' ');
100
+ // Section title
101
+ this.log(`# ${section}`);
102
+ const sectionBullets = playbook.getBulletsInSection(section);
103
+ for (const bullet of sectionBullets) {
104
+ const relativePath = `${BR_DIR}/${ACE_DIR}/${BULLETS_DIR}/${bullet.id}.md`;
105
+ // Display like git status: red path
106
+ this.log(` ${chalk.red(relativePath)}`);
107
+ }
108
+ }
109
+ // Guide user to push memory to cloud
110
+ this.log(`Use "br push" to push memory to cloud.`);
111
+ }
112
+ catch (error) {
113
+ this.error(error instanceof Error ? error.message : 'Failed to load playbook statistics');
114
+ }
115
+ }
116
+ }
@@ -0,0 +1,32 @@
1
+ import { IOidcDiscoveryService } from '../core/interfaces/i-oidc-discovery-service.js';
2
+ /**
3
+ * OAuth/OIDC configuration for the application.
4
+ * This CLI uses PKCE flow (public client), so clientSecret is optional and typically undefined.
5
+ */
6
+ export type OAuthConfig = {
7
+ authorizationUrl: string;
8
+ clientId: string;
9
+ clientSecret?: string;
10
+ /**
11
+ * OAuth redirect URI for receiving authorization codes.
12
+ *
13
+ * For CLI flows with local callback servers, this is typically built dynamically
14
+ * after the server starts on a random port (e.g., `http://localhost:3456/callback`).
15
+ *
16
+ * For other flows (web apps, etc.), this can be provided as a static value in config.
17
+ *
18
+ * Optional - can be omitted if redirectUri is determined at runtime.
19
+ */
20
+ redirectUri?: string;
21
+ scopes: string[];
22
+ tokenUrl: string;
23
+ };
24
+ /**
25
+ * Get OAuth configuration using OIDC discovery.
26
+ * Configuration is built from environment-specific defaults with fallback
27
+ * to hardcoded URLs if discovery fails.
28
+ *
29
+ * @param discoveryService OIDC discovery service for fetching endpoints
30
+ * @returns OAuth configuration
31
+ */
32
+ export declare const getAuthConfig: (discoveryService: IOidcDiscoveryService) => Promise<OAuthConfig>;
@@ -0,0 +1,35 @@
1
+ import { ENVIRONMENT, getCurrentConfig } from './environment.js';
2
+ /**
3
+ * Get OAuth configuration using OIDC discovery.
4
+ * Configuration is built from environment-specific defaults with fallback
5
+ * to hardcoded URLs if discovery fails.
6
+ *
7
+ * @param discoveryService OIDC discovery service for fetching endpoints
8
+ * @returns OAuth configuration
9
+ */
10
+ export const getAuthConfig = async (discoveryService) => {
11
+ // Get environment config
12
+ const envConfig = getCurrentConfig();
13
+ // Discover OIDC endpoints
14
+ let authorizationUrl;
15
+ let tokenUrl;
16
+ try {
17
+ const metadata = await discoveryService.discover(envConfig.issuerUrl);
18
+ // Use discovered endpoints
19
+ authorizationUrl = metadata.authorizationEndpoint;
20
+ tokenUrl = metadata.tokenEndpoint;
21
+ }
22
+ catch (error) {
23
+ // Fallback to hardcoded environment-specific URLs
24
+ authorizationUrl = envConfig.authorizationUrl;
25
+ tokenUrl = envConfig.tokenUrl;
26
+ // Warn user about fallback
27
+ console.warn(`Warning: OIDC discovery failed, using fallback URLs for ${ENVIRONMENT} environment.`, error instanceof Error ? error.message : 'Unknown error');
28
+ }
29
+ return {
30
+ authorizationUrl,
31
+ clientId: envConfig.clientId,
32
+ scopes: envConfig.scopes,
33
+ tokenUrl,
34
+ };
35
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Environment types supported by the CLI.
3
+ */
4
+ type Environment = 'development' | 'production';
5
+ /**
6
+ * Current environment - set at runtime by the launcher scripts.
7
+ * - `./bin/dev.js` sets BR_ENV=development
8
+ * - `./bin/run.js` sets BR_ENV=production
9
+ */
10
+ export declare const ENVIRONMENT: Environment;
11
+ /**
12
+ * Environment-specific configuration.
13
+ */
14
+ type EnvironmentConfig = {
15
+ apiBaseUrl: string;
16
+ authorizationUrl: string;
17
+ clientId: string;
18
+ cogitApiBaseUrl: string;
19
+ issuerUrl: string;
20
+ memoraApiBaseUrl: string;
21
+ mixpanelToken: string;
22
+ scopes: string[];
23
+ tokenUrl: string;
24
+ };
25
+ /**
26
+ * Configuration for each environment.
27
+ * These values are bundled at build time.
28
+ */
29
+ export declare const ENV_CONFIG: Record<Environment, EnvironmentConfig>;
30
+ /**
31
+ * Get the configuration for the current environment.
32
+ * @returns The environment configuration.
33
+ */
34
+ export declare const getCurrentConfig: () => EnvironmentConfig;
35
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Current environment - set at runtime by the launcher scripts.
3
+ * - `./bin/dev.js` sets BR_ENV=development
4
+ * - `./bin/run.js` sets BR_ENV=production
5
+ */
6
+ export const ENVIRONMENT = process.env.BR_ENV ?? 'development';
7
+ /**
8
+ * Configuration for each environment.
9
+ * These values are bundled at build time.
10
+ */
11
+ export const ENV_CONFIG = {
12
+ development: {
13
+ apiBaseUrl: 'https://dev-beta-iam.byterover.dev/api/v1',
14
+ authorizationUrl: 'https://dev-beta-iam.byterover.dev/api/v1/oidc/authorize',
15
+ clientId: 'byterover-cli-client',
16
+ cogitApiBaseUrl: 'https://dev-beta-cogit.byterover.dev/api/v1',
17
+ issuerUrl: 'https://dev-beta-iam.byterover.dev/api/v1/oidc',
18
+ memoraApiBaseUrl: 'https://dev-beta-memora-retrieve.byterover.dev/api/v3',
19
+ mixpanelToken: '258e1a2b3d44cc634ef28964771b1da0',
20
+ scopes: ['read', 'write', 'debug'],
21
+ tokenUrl: 'https://dev-beta-iam.byterover.dev/api/v1/oidc/token',
22
+ },
23
+ production: {
24
+ apiBaseUrl: 'https://prod-beta-iam.byterover.dev/api/v1',
25
+ authorizationUrl: 'https://prod-beta-iam.byterover.dev/api/v1/oidc/authorize',
26
+ clientId: 'byterover-cli-prod',
27
+ cogitApiBaseUrl: 'https://prod-beta-cogit.byterover.dev/api/v1',
28
+ issuerUrl: 'https://prod-beta-iam.byterover.dev/api/v1/oidc',
29
+ memoraApiBaseUrl: 'https://prod-beta-memora-retrieve.byterover.dev/api/v3',
30
+ mixpanelToken: 'fac9051df8242c885a9e0eaf60f78b10',
31
+ scopes: ['read', 'write'],
32
+ tokenUrl: 'https://prod-beta-iam.byterover.dev/api/v1/oidc/token',
33
+ },
34
+ };
35
+ /**
36
+ * Get the configuration for the current environment.
37
+ * @returns The environment configuration.
38
+ */
39
+ export const getCurrentConfig = () => ENV_CONFIG[ENVIRONMENT];
@@ -0,0 +1,11 @@
1
+ export declare const BR_DIR = ".br";
2
+ export declare const ACE_DIR = "ace";
3
+ export declare const EXECUTOR_OUTPUTS_DIR = "executor-outputs";
4
+ export declare const REFLECTIONS_DIR = "reflections";
5
+ export declare const DELTAS_DIR = "deltas";
6
+ export declare const BULLETS_DIR = "bullets";
7
+ /**
8
+ * Default ByteRover branch name for memory storage.
9
+ * This is ByteRover's internal branching mechanism, not Git branches.
10
+ */
11
+ export declare const DEFAULT_BRANCH = "main";
@@ -0,0 +1,12 @@
1
+ // ACE directory structure constants
2
+ export const BR_DIR = '.br';
3
+ export const ACE_DIR = 'ace';
4
+ export const EXECUTOR_OUTPUTS_DIR = 'executor-outputs';
5
+ export const REFLECTIONS_DIR = 'reflections';
6
+ export const DELTAS_DIR = 'deltas';
7
+ export const BULLETS_DIR = 'bullets';
8
+ /**
9
+ * Default ByteRover branch name for memory storage.
10
+ * This is ByteRover's internal branching mechanism, not Git branches.
11
+ */
12
+ export const DEFAULT_BRANCH = 'main';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Array of all supported Agents.
3
+ */
4
+ export declare const AGENT_VALUES: readonly ["Amp", "Augment Code", "Claude Code", "Cline", "Codex", "Cursor", "Gemini CLI", "Github Copilot", "Junie", "Kilo Code", "Kiro", "Qoder", "Qwen Code", "Roo Code", "Trae.ai", "Warp", "Windsurf", "Zed"];
5
+ export type Agent = (typeof AGENT_VALUES)[number];
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Array of all supported Agents.
3
+ */
4
+ export const AGENT_VALUES = [
5
+ 'Amp',
6
+ 'Augment Code',
7
+ 'Claude Code',
8
+ 'Cline',
9
+ 'Codex',
10
+ 'Cursor',
11
+ 'Gemini CLI',
12
+ 'Github Copilot',
13
+ 'Junie',
14
+ 'Kilo Code',
15
+ 'Kiro',
16
+ 'Qoder',
17
+ 'Qwen Code',
18
+ 'Roo Code',
19
+ 'Trae.ai',
20
+ 'Warp',
21
+ 'Windsurf',
22
+ 'Zed',
23
+ ];
@@ -0,0 +1,43 @@
1
+ export type AuthTokenParams = {
2
+ accessToken: string;
3
+ expiresAt: Date;
4
+ refreshToken: string;
5
+ sessionKey: string;
6
+ tokenType?: string;
7
+ userEmail: string;
8
+ userId: string;
9
+ };
10
+ /**
11
+ * Represents an authentication token with access and refresh tokens, expiration, and type.
12
+ */
13
+ export declare class AuthToken {
14
+ readonly accessToken: string;
15
+ readonly expiresAt: Date;
16
+ readonly refreshToken: string;
17
+ readonly sessionKey: string;
18
+ readonly tokenType: string;
19
+ readonly userEmail: string;
20
+ readonly userId: string;
21
+ constructor(params: AuthTokenParams);
22
+ /**
23
+ * Create an AuthToken instance from a JSON object.
24
+ * @param json JSON object representing the AuthToken
25
+ * @returns An instance of AuthToken, or undefined if required fields are missing
26
+ */
27
+ static fromJson(json: Record<string, string>): AuthToken | undefined;
28
+ /**
29
+ * Check if the token is expired.
30
+ * @returns True if the token is expired, false otherwise.
31
+ */
32
+ isExpired(): boolean;
33
+ /**
34
+ * Check if the token is valid.
35
+ * @returns True if the token is valid, false otherwise.
36
+ */
37
+ isValid(): boolean;
38
+ /**
39
+ * Convert the AuthToken instance to a JSON object.
40
+ * @returns A JSON object representing the AuthToken
41
+ */
42
+ toJson(): Record<string, string>;
43
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Represents an authentication token with access and refresh tokens, expiration, and type.
3
+ */
4
+ export class AuthToken {
5
+ accessToken;
6
+ expiresAt;
7
+ refreshToken;
8
+ sessionKey;
9
+ tokenType;
10
+ userEmail;
11
+ userId;
12
+ constructor(params) {
13
+ this.accessToken = params.accessToken;
14
+ this.expiresAt = params.expiresAt;
15
+ this.refreshToken = params.refreshToken;
16
+ this.sessionKey = params.sessionKey;
17
+ this.tokenType = params.tokenType ?? 'Bearer';
18
+ this.userId = params.userId;
19
+ this.userEmail = params.userEmail;
20
+ }
21
+ /**
22
+ * Create an AuthToken instance from a JSON object.
23
+ * @param json JSON object representing the AuthToken
24
+ * @returns An instance of AuthToken, or undefined if required fields are missing
25
+ */
26
+ static fromJson(json) {
27
+ // Validate that new required fields exist (for backward compatibility with old tokens)
28
+ if (!json.userId || !json.userEmail) {
29
+ return undefined;
30
+ }
31
+ return new AuthToken({
32
+ accessToken: json.accessToken,
33
+ expiresAt: new Date(json.expiresAt),
34
+ refreshToken: json.refreshToken,
35
+ sessionKey: json.sessionKey,
36
+ tokenType: json.tokenType,
37
+ userEmail: json.userEmail,
38
+ userId: json.userId,
39
+ });
40
+ }
41
+ /**
42
+ * Check if the token is expired.
43
+ * @returns True if the token is expired, false otherwise.
44
+ */
45
+ isExpired() {
46
+ return this.expiresAt <= new Date();
47
+ }
48
+ /**
49
+ * Check if the token is valid.
50
+ * @returns True if the token is valid, false otherwise.
51
+ */
52
+ isValid() {
53
+ return Boolean(this.accessToken) && !this.isExpired();
54
+ }
55
+ /**
56
+ * Convert the AuthToken instance to a JSON object.
57
+ * @returns A JSON object representing the AuthToken
58
+ */
59
+ toJson() {
60
+ return {
61
+ accessToken: this.accessToken,
62
+ expiresAt: this.expiresAt.toISOString(),
63
+ refreshToken: this.refreshToken,
64
+ sessionKey: this.sessionKey,
65
+ tokenType: this.tokenType,
66
+ userEmail: this.userEmail,
67
+ userId: this.userId,
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,25 @@
1
+ import { Space } from './space.js';
2
+ /**
3
+ * Represents the configuration stored in .br/config.json
4
+ * This config links a project directory to a ByteRover space.
5
+ */
6
+ export declare class BrConfig {
7
+ readonly createdAt: string;
8
+ readonly spaceId: string;
9
+ readonly spaceName: string;
10
+ readonly teamId: string;
11
+ readonly teamName: string;
12
+ constructor(createdAt: string, spaceId: string, spaceName: string, teamId: string, teamName: string);
13
+ /**
14
+ * Deserializes config from JSON format
15
+ */
16
+ static fromJson(json: Record<string, string>): BrConfig;
17
+ /**
18
+ * Creates a BrConfig from a Space entity
19
+ */
20
+ static fromSpace(space: Space): BrConfig;
21
+ /**
22
+ * Serializes the config to JSON format
23
+ */
24
+ toJson(): Record<string, string>;
25
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Represents the configuration stored in .br/config.json
3
+ * This config links a project directory to a ByteRover space.
4
+ */
5
+ export class BrConfig {
6
+ createdAt;
7
+ spaceId;
8
+ spaceName;
9
+ teamId;
10
+ teamName;
11
+ // eslint-disable-next-line max-params
12
+ constructor(createdAt, spaceId, spaceName, teamId, teamName) {
13
+ if (createdAt.trim().length === 0) {
14
+ throw new Error('Created at cannot be empty');
15
+ }
16
+ if (spaceId.trim().length === 0) {
17
+ throw new Error('Space ID cannot be empty');
18
+ }
19
+ if (spaceName.trim().length === 0) {
20
+ throw new Error('Space name cannot be empty');
21
+ }
22
+ if (teamId.trim().length === 0) {
23
+ throw new Error('Team ID cannot be empty');
24
+ }
25
+ if (teamName.trim().length === 0) {
26
+ throw new Error('Team name cannot be empty');
27
+ }
28
+ this.createdAt = createdAt;
29
+ this.spaceId = spaceId;
30
+ this.spaceName = spaceName;
31
+ this.teamId = teamId;
32
+ this.teamName = teamName;
33
+ }
34
+ /**
35
+ * Deserializes config from JSON format
36
+ */
37
+ static fromJson(json) {
38
+ return new BrConfig(json.createdAt, json.spaceId, json.spaceName, json.teamId, json.teamName);
39
+ }
40
+ /**
41
+ * Creates a BrConfig from a Space entity
42
+ */
43
+ static fromSpace(space) {
44
+ return new BrConfig(new Date().toISOString(), space.id, space.name, space.teamId, space.teamName);
45
+ }
46
+ /**
47
+ * Serializes the config to JSON format
48
+ */
49
+ toJson() {
50
+ return {
51
+ createdAt: this.createdAt,
52
+ spaceId: this.spaceId,
53
+ spaceName: this.spaceName,
54
+ teamId: this.teamId,
55
+ teamName: this.teamName,
56
+ };
57
+ }
58
+ }