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.
- package/README.md +781 -0
- package/bin/dev.cmd +4 -0
- package/bin/dev.js +7 -0
- package/bin/run.cmd +4 -0
- package/bin/run.js +7 -0
- package/dist/commands/add.d.ts +60 -0
- package/dist/commands/add.js +230 -0
- package/dist/commands/clear.d.ts +13 -0
- package/dist/commands/clear.js +57 -0
- package/dist/commands/complete.d.ts +108 -0
- package/dist/commands/complete.js +340 -0
- package/dist/commands/gen-rules.d.ts +26 -0
- package/dist/commands/gen-rules.js +89 -0
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.js +135 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +103 -0
- package/dist/commands/push.d.ts +33 -0
- package/dist/commands/push.js +150 -0
- package/dist/commands/retrieve.d.ts +26 -0
- package/dist/commands/retrieve.js +101 -0
- package/dist/commands/space/list.d.ts +22 -0
- package/dist/commands/space/list.js +105 -0
- package/dist/commands/space/switch.d.ts +20 -0
- package/dist/commands/space/switch.js +110 -0
- package/dist/commands/status.d.ts +22 -0
- package/dist/commands/status.js +116 -0
- package/dist/config/auth.config.d.ts +32 -0
- package/dist/config/auth.config.js +35 -0
- package/dist/config/environment.d.ts +35 -0
- package/dist/config/environment.js +39 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +12 -0
- package/dist/core/domain/entities/agent.d.ts +5 -0
- package/dist/core/domain/entities/agent.js +23 -0
- package/dist/core/domain/entities/auth-token.d.ts +43 -0
- package/dist/core/domain/entities/auth-token.js +70 -0
- package/dist/core/domain/entities/br-config.d.ts +25 -0
- package/dist/core/domain/entities/br-config.js +58 -0
- package/dist/core/domain/entities/bullet.d.ts +51 -0
- package/dist/core/domain/entities/bullet.js +94 -0
- package/dist/core/domain/entities/curator-output.d.ts +14 -0
- package/dist/core/domain/entities/curator-output.js +23 -0
- package/dist/core/domain/entities/delta-batch.d.ts +30 -0
- package/dist/core/domain/entities/delta-batch.js +52 -0
- package/dist/core/domain/entities/delta-operation.d.ts +31 -0
- package/dist/core/domain/entities/delta-operation.js +50 -0
- package/dist/core/domain/entities/event.d.ts +8 -0
- package/dist/core/domain/entities/event.js +15 -0
- package/dist/core/domain/entities/executor-output.d.ts +27 -0
- package/dist/core/domain/entities/executor-output.js +33 -0
- package/dist/core/domain/entities/memory.d.ts +55 -0
- package/dist/core/domain/entities/memory.js +90 -0
- package/dist/core/domain/entities/oauth-token-data.d.ts +13 -0
- package/dist/core/domain/entities/oauth-token-data.js +20 -0
- package/dist/core/domain/entities/playbook.d.ts +97 -0
- package/dist/core/domain/entities/playbook.js +275 -0
- package/dist/core/domain/entities/presigned-url.d.ts +9 -0
- package/dist/core/domain/entities/presigned-url.js +18 -0
- package/dist/core/domain/entities/presigned-urls-response.d.ts +10 -0
- package/dist/core/domain/entities/presigned-urls-response.js +18 -0
- package/dist/core/domain/entities/reflector-output.d.ts +38 -0
- package/dist/core/domain/entities/reflector-output.js +44 -0
- package/dist/core/domain/entities/retrieve-result.d.ts +35 -0
- package/dist/core/domain/entities/retrieve-result.js +35 -0
- package/dist/core/domain/entities/space.d.ts +24 -0
- package/dist/core/domain/entities/space.js +52 -0
- package/dist/core/domain/entities/team.d.ts +42 -0
- package/dist/core/domain/entities/team.js +89 -0
- package/dist/core/domain/entities/user.d.ts +20 -0
- package/dist/core/domain/entities/user.js +32 -0
- package/dist/core/domain/errors/ace-error.d.ts +34 -0
- package/dist/core/domain/errors/ace-error.js +53 -0
- package/dist/core/domain/errors/auth-error.d.ts +10 -0
- package/dist/core/domain/errors/auth-error.js +20 -0
- package/dist/core/domain/errors/discovery-error.d.ts +21 -0
- package/dist/core/domain/errors/discovery-error.js +33 -0
- package/dist/core/domain/errors/rule-error.d.ts +6 -0
- package/dist/core/domain/errors/rule-error.js +12 -0
- package/dist/core/interfaces/i-ace-prompt-builder.d.ts +48 -0
- package/dist/core/interfaces/i-ace-prompt-builder.js +1 -0
- package/dist/core/interfaces/i-auth-service.d.ts +35 -0
- package/dist/core/interfaces/i-auth-service.js +1 -0
- package/dist/core/interfaces/i-browser-launcher.d.ts +11 -0
- package/dist/core/interfaces/i-browser-launcher.js +1 -0
- package/dist/core/interfaces/i-bullet-content-store.d.ts +36 -0
- package/dist/core/interfaces/i-bullet-content-store.js +1 -0
- package/dist/core/interfaces/i-callback-handler.d.ts +35 -0
- package/dist/core/interfaces/i-callback-handler.js +1 -0
- package/dist/core/interfaces/i-delta-store.d.ts +15 -0
- package/dist/core/interfaces/i-delta-store.js +1 -0
- package/dist/core/interfaces/i-executor-output-store.d.ts +14 -0
- package/dist/core/interfaces/i-executor-output-store.js +1 -0
- package/dist/core/interfaces/i-file-service.d.ts +34 -0
- package/dist/core/interfaces/i-file-service.js +1 -0
- package/dist/core/interfaces/i-http-client.d.ts +33 -0
- package/dist/core/interfaces/i-http-client.js +1 -0
- package/dist/core/interfaces/i-memory-retrieval-service.d.ts +40 -0
- package/dist/core/interfaces/i-memory-retrieval-service.js +1 -0
- package/dist/core/interfaces/i-memory-storage-service.d.ts +55 -0
- package/dist/core/interfaces/i-memory-storage-service.js +1 -0
- package/dist/core/interfaces/i-oidc-discovery-service.d.ts +20 -0
- package/dist/core/interfaces/i-oidc-discovery-service.js +1 -0
- package/dist/core/interfaces/i-playbook-service.d.ts +69 -0
- package/dist/core/interfaces/i-playbook-service.js +1 -0
- package/dist/core/interfaces/i-playbook-store.d.ts +38 -0
- package/dist/core/interfaces/i-playbook-store.js +1 -0
- package/dist/core/interfaces/i-project-config-store.d.ts +26 -0
- package/dist/core/interfaces/i-project-config-store.js +1 -0
- package/dist/core/interfaces/i-reflection-store.d.ts +21 -0
- package/dist/core/interfaces/i-reflection-store.js +1 -0
- package/dist/core/interfaces/i-rule-template-service.d.ts +17 -0
- package/dist/core/interfaces/i-rule-template-service.js +4 -0
- package/dist/core/interfaces/i-rule-writer-service.d.ts +13 -0
- package/dist/core/interfaces/i-rule-writer-service.js +1 -0
- package/dist/core/interfaces/i-space-service.d.ts +28 -0
- package/dist/core/interfaces/i-space-service.js +1 -0
- package/dist/core/interfaces/i-team-service.d.ts +29 -0
- package/dist/core/interfaces/i-team-service.js +1 -0
- package/dist/core/interfaces/i-template-loader.d.ts +29 -0
- package/dist/core/interfaces/i-template-loader.js +1 -0
- package/dist/core/interfaces/i-token-store.d.ts +22 -0
- package/dist/core/interfaces/i-token-store.js +1 -0
- package/dist/core/interfaces/i-tracking-service.d.ts +21 -0
- package/dist/core/interfaces/i-tracking-service.js +1 -0
- package/dist/core/interfaces/i-user-service.d.ts +14 -0
- package/dist/core/interfaces/i-user-service.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/ace/ace-file-utils.d.ts +46 -0
- package/dist/infra/ace/ace-file-utils.js +83 -0
- package/dist/infra/ace/ace-prompt-templates.d.ts +13 -0
- package/dist/infra/ace/ace-prompt-templates.js +177 -0
- package/dist/infra/ace/file-bullet-content-store.d.ts +27 -0
- package/dist/infra/ace/file-bullet-content-store.js +89 -0
- package/dist/infra/ace/file-delta-store.d.ts +9 -0
- package/dist/infra/ace/file-delta-store.js +26 -0
- package/dist/infra/ace/file-executor-output-store.d.ts +9 -0
- package/dist/infra/ace/file-executor-output-store.js +26 -0
- package/dist/infra/ace/file-playbook-store.d.ts +29 -0
- package/dist/infra/ace/file-playbook-store.js +107 -0
- package/dist/infra/ace/file-reflection-store.d.ts +10 -0
- package/dist/infra/ace/file-reflection-store.js +55 -0
- package/dist/infra/auth/oauth-service.d.ts +49 -0
- package/dist/infra/auth/oauth-service.js +126 -0
- package/dist/infra/auth/oidc-discovery-service.d.ts +51 -0
- package/dist/infra/auth/oidc-discovery-service.js +145 -0
- package/dist/infra/browser/system-browser-launcher.d.ts +10 -0
- package/dist/infra/browser/system-browser-launcher.js +18 -0
- package/dist/infra/config/file-config-store.d.ts +21 -0
- package/dist/infra/config/file-config-store.js +57 -0
- package/dist/infra/file/fs-file-service.d.ts +28 -0
- package/dist/infra/file/fs-file-service.js +57 -0
- package/dist/infra/http/authenticated-http-client.d.ts +46 -0
- package/dist/infra/http/authenticated-http-client.js +99 -0
- package/dist/infra/http/callback-handler.d.ts +13 -0
- package/dist/infra/http/callback-handler.js +24 -0
- package/dist/infra/http/callback-server.d.ts +18 -0
- package/dist/infra/http/callback-server.js +93 -0
- package/dist/infra/memory/http-memory-retrieval-service.d.ts +18 -0
- package/dist/infra/memory/http-memory-retrieval-service.js +63 -0
- package/dist/infra/memory/http-memory-storage-service.d.ts +18 -0
- package/dist/infra/memory/http-memory-storage-service.js +67 -0
- package/dist/infra/memory/memory-to-playbook-mapper.d.ts +33 -0
- package/dist/infra/memory/memory-to-playbook-mapper.js +51 -0
- package/dist/infra/playbook/file-playbook-service.d.ts +43 -0
- package/dist/infra/playbook/file-playbook-service.js +133 -0
- package/dist/infra/rule/agent-rule-config.d.ts +19 -0
- package/dist/infra/rule/agent-rule-config.js +77 -0
- package/dist/infra/rule/rule-template-service.d.ts +18 -0
- package/dist/infra/rule/rule-template-service.js +80 -0
- package/dist/infra/rule/rule-writer-service.d.ts +19 -0
- package/dist/infra/rule/rule-writer-service.js +43 -0
- package/dist/infra/space/http-space-service.d.ts +20 -0
- package/dist/infra/space/http-space-service.js +67 -0
- package/dist/infra/storage/keychain-token-store.d.ts +10 -0
- package/dist/infra/storage/keychain-token-store.js +40 -0
- package/dist/infra/team/http-team-service.d.ts +21 -0
- package/dist/infra/team/http-team-service.js +71 -0
- package/dist/infra/template/fs-template-loader.d.ts +33 -0
- package/dist/infra/template/fs-template-loader.js +62 -0
- package/dist/infra/tracking/mixpanel-tracking-service.d.ts +14 -0
- package/dist/infra/tracking/mixpanel-tracking-service.js +44 -0
- package/dist/infra/user/http-user-service.d.ts +12 -0
- package/dist/infra/user/http-user-service.js +26 -0
- package/dist/templates/README.md +103 -0
- package/dist/templates/base.md +3 -0
- package/dist/templates/sections/command-reference.md +141 -0
- package/dist/templates/sections/workflow.md +46 -0
- package/dist/utils/file-helpers.d.ts +15 -0
- package/dist/utils/file-helpers.js +45 -0
- package/oclif.manifest.json +476 -0
- package/package.json +82 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
/**
|
|
4
|
+
* File system-based template loader.
|
|
5
|
+
* Loads templates from src/templates/ directory and performs variable substitution.
|
|
6
|
+
*/
|
|
7
|
+
export class FsTemplateLoader {
|
|
8
|
+
fileService;
|
|
9
|
+
templatesDir;
|
|
10
|
+
constructor(fileService) {
|
|
11
|
+
this.fileService = fileService;
|
|
12
|
+
// Get the directory of this file
|
|
13
|
+
const currentFileUrl = import.meta.url;
|
|
14
|
+
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
15
|
+
const currentDir = path.dirname(currentFilePath);
|
|
16
|
+
// Navigate from src/infra/template/ to src/templates/
|
|
17
|
+
this.templatesDir = path.join(currentDir, '..', '..', 'templates');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Loads a section template from the sections/ directory.
|
|
21
|
+
* @param sectionName - Name of the section (e.g., 'workflow', 'command-reference')
|
|
22
|
+
* @returns Promise resolving to section content
|
|
23
|
+
* @throws Error if section file cannot be read
|
|
24
|
+
*/
|
|
25
|
+
async loadSection(sectionName) {
|
|
26
|
+
const sectionPath = `sections/${sectionName}.md`;
|
|
27
|
+
return this.loadTemplate(sectionPath);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Loads a template file from the templates directory.
|
|
31
|
+
* @param templatePath - Relative path to template (e.g., 'base.md', 'sections/workflow.md')
|
|
32
|
+
* @returns Promise resolving to template content
|
|
33
|
+
* @throws Error if template file cannot be read
|
|
34
|
+
*/
|
|
35
|
+
async loadTemplate(templatePath) {
|
|
36
|
+
const fullPath = path.join(this.templatesDir, templatePath);
|
|
37
|
+
try {
|
|
38
|
+
const content = await this.fileService.read(fullPath);
|
|
39
|
+
return content;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new Error(`Failed to load template '${templatePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Substitutes variables in a template string.
|
|
47
|
+
* Replaces {{variable_name}} with corresponding values from context.
|
|
48
|
+
* @param template - Template string with {{variable}} placeholders
|
|
49
|
+
* @param context - Object mapping variable names to values
|
|
50
|
+
* @returns Template with variables replaced
|
|
51
|
+
*/
|
|
52
|
+
substituteVariables(template, context) {
|
|
53
|
+
let result = template;
|
|
54
|
+
// Replace each variable in the context
|
|
55
|
+
for (const [key, value] of Object.entries(context)) {
|
|
56
|
+
const placeholder = `{{${key}}}`;
|
|
57
|
+
// Use global replace to handle multiple occurrences
|
|
58
|
+
result = result.replaceAll(placeholder, value);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Mixpanel } from 'mixpanel';
|
|
2
|
+
import { EventName, PropertyDict } from '../../core/domain/entities/event.js';
|
|
3
|
+
import { ITokenStore } from '../../core/interfaces/i-token-store.js';
|
|
4
|
+
import { ITrackingService } from '../../core/interfaces/i-tracking-service.js';
|
|
5
|
+
/**
|
|
6
|
+
* Tracking service implementation using the Mixpanel library.
|
|
7
|
+
*/
|
|
8
|
+
export declare class MixpanelTrackingService implements ITrackingService {
|
|
9
|
+
private readonly mp;
|
|
10
|
+
private readonly tokenStore;
|
|
11
|
+
constructor(tokenStore: ITokenStore, mp?: Mixpanel);
|
|
12
|
+
track(eventName: EventName, properties?: PropertyDict): Promise<void>;
|
|
13
|
+
private getIdentificationProperties;
|
|
14
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import mixpanel from 'mixpanel';
|
|
2
|
+
import { getCurrentConfig } from '../../config/environment.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tracking service implementation using the Mixpanel library.
|
|
5
|
+
*/
|
|
6
|
+
export class MixpanelTrackingService {
|
|
7
|
+
mp;
|
|
8
|
+
tokenStore;
|
|
9
|
+
constructor(tokenStore, mp) {
|
|
10
|
+
this.tokenStore = tokenStore;
|
|
11
|
+
if (mp) {
|
|
12
|
+
// Injected dependencies for testing
|
|
13
|
+
this.mp = mp;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
// Initialize with real implementations for production
|
|
17
|
+
const envConfig = getCurrentConfig();
|
|
18
|
+
this.mp = mixpanel.init(envConfig.mixpanelToken);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async track(eventName, properties) {
|
|
22
|
+
try {
|
|
23
|
+
const identificationProps = await this.getIdentificationProperties();
|
|
24
|
+
this.mp.track(`cli:${eventName}`, {
|
|
25
|
+
...identificationProps,
|
|
26
|
+
...properties,
|
|
27
|
+
beta: true,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error(`Failed to track event ${eventName}:`, error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async getIdentificationProperties() {
|
|
35
|
+
// 2. Load and validate authentication token
|
|
36
|
+
const token = await this.tokenStore.load();
|
|
37
|
+
if (token) {
|
|
38
|
+
return {
|
|
39
|
+
$user_id: token.userId, // eslint-disable-line camelcase
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IUserService } from '../../core/interfaces/i-user-service.js';
|
|
2
|
+
import { User } from '../../core/domain/entities/user.js';
|
|
3
|
+
export type UserServiceConfig = {
|
|
4
|
+
apiBaseUrl: string;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare class HttpUserService implements IUserService {
|
|
8
|
+
private readonly config;
|
|
9
|
+
constructor(config: UserServiceConfig);
|
|
10
|
+
getCurrentUser(accessToken: string, sessionKey: string): Promise<User>;
|
|
11
|
+
private mapToUser;
|
|
12
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { User } from '../../core/domain/entities/user.js';
|
|
2
|
+
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
3
|
+
export class HttpUserService {
|
|
4
|
+
config;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = {
|
|
7
|
+
...config,
|
|
8
|
+
timeout: config.timeout ?? 10_000, // Default 10 seconds timeout
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async getCurrentUser(accessToken, sessionKey) {
|
|
12
|
+
try {
|
|
13
|
+
const httpClient = new AuthenticatedHttpClient(accessToken, sessionKey);
|
|
14
|
+
const response = await httpClient.get(`${this.config.apiBaseUrl}/user/me`, {
|
|
15
|
+
timeout: this.config.timeout,
|
|
16
|
+
});
|
|
17
|
+
return this.mapToUser(response.data);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
throw new Error(`Failed to fetch user information: ${error.message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
mapToUser(userData) {
|
|
24
|
+
return new User(userData.email, userData.id, userData.name);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# ByteRover CLI Template System
|
|
2
|
+
|
|
3
|
+
This directory contains template files used to generate agent instructions via the `br gen-rules` command.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/templates/
|
|
9
|
+
├── base.md # Main template structure
|
|
10
|
+
├── sections/ # Reusable content sections
|
|
11
|
+
│ ├── workflow.md # workflow guide
|
|
12
|
+
│ └── command-reference.md # All BR CLI commands documentation
|
|
13
|
+
└── README.md # This file
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Template Files
|
|
17
|
+
|
|
18
|
+
### `base.md`
|
|
19
|
+
The main template structure that combines all sections into the final output.
|
|
20
|
+
|
|
21
|
+
**Variables:**
|
|
22
|
+
- `{{agent_name}}` - Name of the agent (e.g., "Claude Code", "Cursor")
|
|
23
|
+
- `{{workflow}}` - Content from `sections/workflow.md`
|
|
24
|
+
- `{{command_reference}}` - Content from `sections/command-reference.md`
|
|
25
|
+
|
|
26
|
+
### `sections/workflow.md`
|
|
27
|
+
Complete guide to the ACE (Agentic Context Engineering) workflow:
|
|
28
|
+
- Quick start examples
|
|
29
|
+
- Command reference for ACE commands
|
|
30
|
+
- ADD vs UPDATE modes explanation
|
|
31
|
+
- Best practices for using ACE
|
|
32
|
+
- Examples with real use cases
|
|
33
|
+
|
|
34
|
+
### `sections/command-reference.md`
|
|
35
|
+
Comprehensive documentation of all BR CLI commands:
|
|
36
|
+
- Root commands (login, init, status, add, gen-rules, ace, push, retrieve, show, clear)
|
|
37
|
+
- Space commands (list, switch)
|
|
38
|
+
|
|
39
|
+
Each command includes:
|
|
40
|
+
- Description
|
|
41
|
+
- Arguments (if any)
|
|
42
|
+
- Flags with defaults
|
|
43
|
+
- Examples
|
|
44
|
+
|
|
45
|
+
## How It Works
|
|
46
|
+
|
|
47
|
+
1. User runs `br gen-rules`
|
|
48
|
+
2. User selects an agent (e.g., "Claude Code")
|
|
49
|
+
3. `RuleTemplateService` loads templates via `FsTemplateLoader`
|
|
50
|
+
4. Templates are assembled:
|
|
51
|
+
- Load section templates (workflow, command-reference)
|
|
52
|
+
- Substitute variables in base template
|
|
53
|
+
- Combine all content
|
|
54
|
+
5. Output written to `.clinerules/byterover-rules.md`
|
|
55
|
+
|
|
56
|
+
## Variable Substitution
|
|
57
|
+
|
|
58
|
+
The template system supports simple variable substitution using `{{variable_name}}` syntax.
|
|
59
|
+
|
|
60
|
+
**Available Variables:**
|
|
61
|
+
- `{{agent_name}}` - Agent name selected by user
|
|
62
|
+
## Updating Templates
|
|
63
|
+
|
|
64
|
+
### To Update Command Documentation:
|
|
65
|
+
Edit `sections/command-reference.md` - changes will be reflected next time `br gen-rules` runs.
|
|
66
|
+
|
|
67
|
+
### To Update ACE Workflow Guide:
|
|
68
|
+
Edit `sections/workflow.md` - changes will be reflected next time `br gen-rules` runs.
|
|
69
|
+
|
|
70
|
+
### To Change Output Structure:
|
|
71
|
+
Edit `base.md` - modify how sections are combined.
|
|
72
|
+
|
|
73
|
+
## Best Practices
|
|
74
|
+
|
|
75
|
+
1. **Keep templates in sync with code**: When adding/modifying commands, update `command-reference.md`
|
|
76
|
+
2. **Use clear examples**: Show realistic use cases in examples
|
|
77
|
+
3. **Maintain markdown formatting**: Ensure proper headers, code blocks, and lists
|
|
78
|
+
4. **Test after changes**: Run `br gen-rules` and verify output in `.clinerules/byterover-rules.md`
|
|
79
|
+
|
|
80
|
+
## Future Enhancements
|
|
81
|
+
|
|
82
|
+
This template system is designed to support future improvements:
|
|
83
|
+
- Context-aware content (show different sections based on project state)
|
|
84
|
+
- Agent-specific customizations (per-agent template overrides)
|
|
85
|
+
- Conditional sections (e.g., show memory commands only if authenticated)
|
|
86
|
+
- Dynamic variable injection (project status, playbook stats, etc.)
|
|
87
|
+
|
|
88
|
+
## Technical Details
|
|
89
|
+
|
|
90
|
+
**Template Loader:** `src/infra/template/fs-template-loader.ts`
|
|
91
|
+
- Loads templates from filesystem
|
|
92
|
+
- Performs variable substitution
|
|
93
|
+
- Returns assembled content
|
|
94
|
+
|
|
95
|
+
**Template Service:** `src/infra/rule/rule-template-service.ts`
|
|
96
|
+
- Orchestrates template loading
|
|
97
|
+
- Builds final instruction content
|
|
98
|
+
- Injects agent-specific values
|
|
99
|
+
|
|
100
|
+
**Command:** `src/commands/gen-rules.ts`
|
|
101
|
+
- User-facing command
|
|
102
|
+
- Prompts for agent selection
|
|
103
|
+
- Writes output to `.clinerules/byterover-rules.md`
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# ByteRover CLI Command Reference
|
|
2
|
+
|
|
3
|
+
## Memory Commands
|
|
4
|
+
|
|
5
|
+
### `br add`
|
|
6
|
+
|
|
7
|
+
**Description:** Add or update a bullet in the playbook (bypasses ACE workflow for direct agent usage)
|
|
8
|
+
|
|
9
|
+
**Flags:**
|
|
10
|
+
|
|
11
|
+
- `-s, --section <string>`: Section name for the bullet (required)
|
|
12
|
+
- `-c, --content <string>`: Content of the bullet (required)
|
|
13
|
+
- `-b, --bullet-id <string>`: Bullet ID to update (optional, creates new if omitted)
|
|
14
|
+
|
|
15
|
+
**Examples:**
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
br add --section "Common Errors" --content "Authentication fails when token expires"
|
|
19
|
+
br add --section "Common Errors" --bullet-id "common-00001" --content "Updated: Auth fails when token expires"
|
|
20
|
+
br add -s "Best Practices" -c "Always validate user input before processing"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Suggested Sections:** Common Errors, Best Practices, Strategies, Lessons Learned, Project Structure and Dependencies, Testing, Code Style and Quality, Styling and Design
|
|
24
|
+
|
|
25
|
+
**Behavior:**
|
|
26
|
+
|
|
27
|
+
- Warns if using non-standard section name
|
|
28
|
+
- Creates new bullet with auto-generated ID if `--bullet-id` not provided
|
|
29
|
+
- Updates existing bullet if `--bullet-id` matches existing bullet
|
|
30
|
+
- Displays bullet ID, section, content, and tags after operation
|
|
31
|
+
|
|
32
|
+
**Requirements:** Playbook must exist (run `br init` first)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### `br retrieve`
|
|
37
|
+
|
|
38
|
+
**Description:** Retrieve memories from ByteRover Memora service and save to local ACE playbook
|
|
39
|
+
|
|
40
|
+
**Flags:**
|
|
41
|
+
|
|
42
|
+
- `-q, --query <string>`: Search query string (required)
|
|
43
|
+
- `-n, --node-keys <string>`: Comma-separated list of node keys (file paths) to filter results
|
|
44
|
+
|
|
45
|
+
**Examples:**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
br retrieve --query "authentication best practices"
|
|
49
|
+
br retrieve -q "error handling" -n "src/auth/login.ts,src/auth/oauth.ts"
|
|
50
|
+
br retrieve -q "database connection issues"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Behavior:**
|
|
54
|
+
|
|
55
|
+
- **Clears existing playbook first** (destructive operation)
|
|
56
|
+
- Retrieves memories and related memories from Memora service
|
|
57
|
+
- Combines both result sets into playbook
|
|
58
|
+
- Maps memory fields: `bulletId` → `id`, `tags` → `metadata.tags`, `nodeKeys` → `metadata.relatedFiles`
|
|
59
|
+
- Displays results with score, content preview (200 chars), and related file paths
|
|
60
|
+
- Fail-safe: warns on save error but still displays results
|
|
61
|
+
|
|
62
|
+
**Output:** Shows count of memories and related memories, displays each with score and content
|
|
63
|
+
|
|
64
|
+
**Requirements:** Must be authenticated and project initialized
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### `br push`
|
|
69
|
+
|
|
70
|
+
**Description:** Push playbook to ByteRover memory storage and clean up local ACE files
|
|
71
|
+
|
|
72
|
+
**Flags:**
|
|
73
|
+
|
|
74
|
+
- `-b, --branch <string>`: ByteRover branch name (default: "main", NOT git branch)
|
|
75
|
+
|
|
76
|
+
**Examples:**
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
br push
|
|
80
|
+
br push --branch develop
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### `br complete`
|
|
86
|
+
|
|
87
|
+
**Description:** Complete ACE workflow: save executor output, generate reflection, and update playbook in one command
|
|
88
|
+
|
|
89
|
+
**Arguments:**
|
|
90
|
+
|
|
91
|
+
- `hint`: Short hint for naming output files (e.g., "user-auth", "bug-fix")
|
|
92
|
+
- `reasoning`: Detailed reasoning and approach for completing the task
|
|
93
|
+
- `finalAnswer`: The final answer/solution to the task
|
|
94
|
+
|
|
95
|
+
**Flags:**
|
|
96
|
+
|
|
97
|
+
- `-t, --tool-usage <string>`: Comma-separated list of tool calls with arguments (format: "ToolName:argument", required)
|
|
98
|
+
- `-f, --feedback <string>`: Environment feedback about task execution (e.g., "Tests passed", "Build failed", required)
|
|
99
|
+
- `-b, --bullet-ids <string>`: Comma-separated list of playbook bullet IDs referenced (optional)
|
|
100
|
+
- `-u, --update-bullet <string>`: Bullet ID to update with new knowledge (if not provided, adds new bullet)
|
|
101
|
+
|
|
102
|
+
**Examples:**
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
br complete "user-auth" "Implemented OAuth2 flow" "Auth works" --tool-usage "Read:src/auth.ts,Edit:src/auth.ts,Bash:npm test" --feedback "All tests passed"
|
|
106
|
+
br complete "validation-fix" "Analyzed validator" "Fixed bug" --tool-usage "Grep:pattern:\"validate\",Read:src/validator.ts" --bullet-ids "bullet-123" --feedback "Tests passed"
|
|
107
|
+
br complete "auth-update" "Improved error handling" "Better errors" --tool-usage "Edit:src/auth.ts" --feedback "Tests passed" --update-bullet "bullet-5"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Behavior:**
|
|
111
|
+
|
|
112
|
+
- **Phase 1 (Executor):** Saves executor output with hint, reasoning, answer, tool usage, and bullet IDs
|
|
113
|
+
- **Phase 2 (Reflector):** Auto-generates reflection based on feedback and applies tags to playbook
|
|
114
|
+
- **Phase 3 (Curator):** Creates delta operation (ADD or UPDATE) and applies to playbook
|
|
115
|
+
- Adds new bullet to "Lessons Learned" section with tag `['auto-generated']`
|
|
116
|
+
- If `--update-bullet` provided, updates existing bullet instead of adding new one
|
|
117
|
+
- Extracts file paths from tool usage and adds to bullet metadata as `relatedFiles`
|
|
118
|
+
|
|
119
|
+
**Output:** Shows summary with file paths, tags applied count, and delta operations breakdown
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### `br show`
|
|
124
|
+
|
|
125
|
+
## Best Practices
|
|
126
|
+
|
|
127
|
+
### Efficient Workflow
|
|
128
|
+
|
|
129
|
+
1. **Retrieve wisely:** Use `br retrieve` with specific queries and `--node-keys` to filter
|
|
130
|
+
2. **Read only what's needed:** Check playbook with `br status` to see statistics before reading full content
|
|
131
|
+
3. **Update precisely:** Use `br add` to add/update specific bullets or `br complete` for complete workflow
|
|
132
|
+
4. **Push when appropriate:** Prompt user to run `br push` after completing significant work
|
|
133
|
+
|
|
134
|
+
### Memory Management
|
|
135
|
+
|
|
136
|
+
**Retrieve pattern:**
|
|
137
|
+
|
|
138
|
+
- Use `br add` to directly add/update bullets
|
|
139
|
+
- `br retrieve` **clears existing playbook** - use carefully
|
|
140
|
+
- Retrieved memories use actual Memora tags (not "auto-generated")
|
|
141
|
+
- Both memories and related memories are saved to playbook
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Workflow Instruction
|
|
2
|
+
|
|
3
|
+
You are a coding agent focused on one codebase. Use the br CLI to manage working context.
|
|
4
|
+
Core Rules:
|
|
5
|
+
|
|
6
|
+
- Start from memory. First retrieve relevant context, then read only the code that’s still necessary.
|
|
7
|
+
- Keep a local playbook. playbook.json is your local memory store—update it with what you learn.
|
|
8
|
+
|
|
9
|
+
## user-centric
|
|
10
|
+
|
|
11
|
+
Before running any `br` command, ask the user to choose:
|
|
12
|
+
|
|
13
|
+
1. **Accept** - Review the command, then run if approved
|
|
14
|
+
2. **Auto-run** - Execute immediately (remember this preference for the session)
|
|
15
|
+
3. **No** - Cancel the command and continue without alternative
|
|
16
|
+
4. **Custom** - Skip the command and provide different instruction
|
|
17
|
+
|
|
18
|
+
Once the user chooses "Auto-run", apply that preference to all subsequent `br` commands in this conversation without asking again.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Daily Flow
|
|
22
|
+
|
|
23
|
+
1.Retrieve context
|
|
24
|
+
|
|
25
|
+
2.Do the work with minimal code reads
|
|
26
|
+
|
|
27
|
+
3.Record new or refined knowledge in the playbook
|
|
28
|
+
|
|
29
|
+
- Add only specific, actionable, contextual items; avoid secrets. Redact when in doubt.
|
|
30
|
+
|
|
31
|
+
4.Sync policy (manual by default)
|
|
32
|
+
|
|
33
|
+
- Do not auto-push.
|
|
34
|
+
- When the playbook has meaningful updates, prompt the user to run the command
|
|
35
|
+
- If the user has explicitly allowed auto-push, proceed non-interactively.
|
|
36
|
+
|
|
37
|
+
## Playbook Guideline
|
|
38
|
+
|
|
39
|
+
- Be specific (“Use React Query for data fetching in web modules”).
|
|
40
|
+
- Be actionable (clear instruction a future agent/dev can apply).
|
|
41
|
+
- Be contextual (mention module/service, constraints, links to source).
|
|
42
|
+
- Include source (file + lines or commit) when possible.
|
|
43
|
+
|
|
44
|
+
## CLI Usage Notes
|
|
45
|
+
|
|
46
|
+
- Use --help on any command to discover flags. Provide exact arguments for the scenario.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the most recent file in a directory by modification time.
|
|
3
|
+
* @param directory - Absolute path to directory to search
|
|
4
|
+
* @returns Absolute path to the most recent file
|
|
5
|
+
* @throws Error if directory is empty or doesn't exist
|
|
6
|
+
*/
|
|
7
|
+
export declare function findLatestFile(directory: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Removes all files from a directory while preserving the directory itself.
|
|
10
|
+
* Returns the number of files removed.
|
|
11
|
+
* Silently succeeds if directory doesn't exist.
|
|
12
|
+
* @param dirPath - Absolute path to directory to clear
|
|
13
|
+
* @returns Number of files removed
|
|
14
|
+
*/
|
|
15
|
+
export declare function clearDirectory(dirPath: string): Promise<number>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readdir, unlink } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Finds the most recent file in a directory by modification time.
|
|
5
|
+
* @param directory - Absolute path to directory to search
|
|
6
|
+
* @returns Absolute path to the most recent file
|
|
7
|
+
* @throws Error if directory is empty or doesn't exist
|
|
8
|
+
*/
|
|
9
|
+
export async function findLatestFile(directory) {
|
|
10
|
+
const files = await readdir(directory, { withFileTypes: true });
|
|
11
|
+
const fileNames = files.filter((f) => f.isFile()).map((f) => f.name);
|
|
12
|
+
if (fileNames.length === 0) {
|
|
13
|
+
throw new Error(`No files found in directory: ${directory}`);
|
|
14
|
+
}
|
|
15
|
+
// Sort files by name (timestamp-based naming ensures latest is last)
|
|
16
|
+
// Assuming filenames follow pattern: prefix-{timestamp}.json
|
|
17
|
+
fileNames.sort();
|
|
18
|
+
const latestFile = fileNames.at(-1);
|
|
19
|
+
return join(directory, latestFile);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Removes all files from a directory while preserving the directory itself.
|
|
23
|
+
* Returns the number of files removed.
|
|
24
|
+
* Silently succeeds if directory doesn't exist.
|
|
25
|
+
* @param dirPath - Absolute path to directory to clear
|
|
26
|
+
* @returns Number of files removed
|
|
27
|
+
*/
|
|
28
|
+
export async function clearDirectory(dirPath) {
|
|
29
|
+
try {
|
|
30
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
31
|
+
// Filter to only get files (not subdirectories)
|
|
32
|
+
const files = entries.filter((entry) => entry.isFile());
|
|
33
|
+
// Remove each file
|
|
34
|
+
await Promise.all(files.map((file) => unlink(join(dirPath, file.name))));
|
|
35
|
+
return files.length;
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// If directory doesn't exist (ENOENT), return 0
|
|
39
|
+
if (error.code === 'ENOENT') {
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
// Re-throw other errors
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|