byterover-cli 0.1.0 → 0.2.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 +108 -653
- package/bin/dev.cmd +1 -1
- package/bin/dev.js +1 -1
- package/bin/run.cmd +1 -1
- package/bin/run.js +1 -1
- package/dist/commands/add.d.ts +4 -15
- package/dist/commands/add.js +31 -69
- package/dist/commands/init.js +13 -8
- package/dist/commands/push.d.ts +6 -4
- package/dist/commands/push.js +39 -9
- package/dist/commands/retrieve.d.ts +2 -2
- package/dist/commands/retrieve.js +3 -3
- package/dist/commands/space/list.js +10 -5
- package/dist/commands/space/switch.js +8 -7
- package/dist/commands/status.js +5 -6
- package/dist/config/environment.d.ts +3 -2
- package/dist/config/environment.js +13 -11
- package/dist/constants.d.ts +8 -1
- package/dist/constants.js +8 -1
- package/dist/core/domain/entities/{br-config.d.ts → brv-config.d.ts} +5 -5
- package/dist/core/domain/entities/{br-config.js → brv-config.js} +5 -5
- package/dist/core/domain/entities/playbook.d.ts +4 -0
- package/dist/core/domain/entities/playbook.js +7 -0
- package/dist/core/interfaces/i-playbook-service.d.ts +1 -1
- package/dist/core/interfaces/i-project-config-store.d.ts +10 -10
- package/dist/hooks/init/welcome.d.ts +3 -0
- package/dist/hooks/init/welcome.js +31 -0
- package/dist/infra/ace/ace-file-utils.js +2 -2
- package/dist/infra/ace/file-bullet-content-store.d.ts +4 -4
- package/dist/infra/ace/file-bullet-content-store.js +7 -7
- package/dist/infra/ace/file-delta-store.d.ts +1 -1
- package/dist/infra/ace/file-delta-store.js +1 -1
- package/dist/infra/ace/file-executor-output-store.d.ts +1 -1
- package/dist/infra/ace/file-executor-output-store.js +1 -1
- package/dist/infra/ace/file-playbook-store.d.ts +3 -3
- package/dist/infra/ace/file-playbook-store.js +6 -6
- package/dist/infra/ace/file-reflection-store.d.ts +1 -1
- package/dist/infra/ace/file-reflection-store.js +1 -1
- package/dist/infra/config/file-config-store.d.ts +6 -8
- package/dist/infra/config/file-config-store.js +10 -11
- package/dist/infra/playbook/file-playbook-service.d.ts +0 -1
- package/dist/infra/playbook/file-playbook-service.js +7 -8
- package/dist/templates/README.md +5 -5
- package/dist/templates/sections/command-reference.md +23 -23
- package/dist/templates/sections/workflow.md +3 -4
- package/oclif.manifest.json +10 -3
- package/package.json +8 -5
package/bin/dev.cmd
CHANGED
package/bin/dev.js
CHANGED
package/bin/run.cmd
CHANGED
package/bin/run.js
CHANGED
package/dist/commands/add.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
-
import type { Bullet } from '../core/domain/entities/bullet.js';
|
|
3
2
|
import type { IPlaybookService } from '../core/interfaces/i-playbook-service.js';
|
|
4
3
|
import type { IPlaybookStore } from '../core/interfaces/i-playbook-store.js';
|
|
5
4
|
import type { ITrackingService } from '../core/interfaces/i-tracking-service.js';
|
|
6
|
-
type UserAction = 'add' | 'update';
|
|
7
5
|
interface SectionPromptOptions {
|
|
8
6
|
readonly existingSections: readonly string[];
|
|
9
7
|
readonly suggestedSections: readonly string[];
|
|
10
8
|
}
|
|
11
|
-
interface ContentPromptContext {
|
|
12
|
-
readonly action: UserAction;
|
|
13
|
-
readonly existingContent?: string;
|
|
14
|
-
readonly section: string;
|
|
15
|
-
}
|
|
16
9
|
export default class Add extends Command {
|
|
17
10
|
static description: string;
|
|
18
11
|
static examples: string[];
|
|
@@ -28,24 +21,20 @@ export default class Add extends Command {
|
|
|
28
21
|
trackingService: ITrackingService;
|
|
29
22
|
};
|
|
30
23
|
/**
|
|
31
|
-
* Prompt user to
|
|
32
|
-
*/
|
|
33
|
-
protected promptForAction(): Promise<UserAction>;
|
|
34
|
-
/**
|
|
35
|
-
* Prompt user to select a bullet to update
|
|
24
|
+
* Prompt user to confirm adding the bullet
|
|
36
25
|
*/
|
|
37
|
-
protected
|
|
26
|
+
protected promptForConfirmation(bulletId: string, section: string, content: string): Promise<boolean>;
|
|
38
27
|
/**
|
|
39
28
|
* Prompt user to enter bullet content
|
|
40
29
|
*/
|
|
41
|
-
protected promptForContent(
|
|
30
|
+
protected promptForContent(section: string): Promise<string>;
|
|
42
31
|
/**
|
|
43
32
|
* Prompt user to select or create a section name
|
|
44
33
|
*/
|
|
45
34
|
protected promptForSection(options: SectionPromptOptions): Promise<string>;
|
|
46
35
|
run(): Promise<void>;
|
|
47
36
|
/**
|
|
48
|
-
* Display success message after adding
|
|
37
|
+
* Display success message after adding a bullet
|
|
49
38
|
*/
|
|
50
39
|
private displaySuccess;
|
|
51
40
|
/**
|
package/dist/commands/add.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { input, search
|
|
1
|
+
import { confirm, input, search } from '@inquirer/prompts';
|
|
2
2
|
import { Command, Flags } from '@oclif/core';
|
|
3
3
|
import { Playbook } from '../core/domain/entities/playbook.js';
|
|
4
4
|
import { FilePlaybookStore } from '../infra/ace/file-playbook-store.js';
|
|
@@ -54,55 +54,27 @@ export default class Add extends Command {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* Prompt user to
|
|
57
|
+
* Prompt user to confirm adding the bullet
|
|
58
58
|
*/
|
|
59
|
-
async
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
async promptForConfirmation(bulletId, section, content) {
|
|
60
|
+
this.log('\nReview your bullet:');
|
|
61
|
+
this.log(` ID: ${bulletId}`);
|
|
62
|
+
this.log(` Section: ${section}`);
|
|
63
|
+
const contentDisplay = content.length > 200 ? `${content.slice(0, 200)}...` : content;
|
|
64
|
+
this.log(` Content: ${contentDisplay}`);
|
|
65
|
+
this.log('\nTip: Use `brv status` to view and update bullets later');
|
|
66
|
+
const confirmed = await confirm({
|
|
67
|
+
default: true,
|
|
68
|
+
message: 'Add this bullet?',
|
|
66
69
|
});
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Prompt user to select a bullet to update
|
|
71
|
-
*/
|
|
72
|
-
async promptForBullet(bullets) {
|
|
73
|
-
const displayBullets = bullets.map((bullet) => ({
|
|
74
|
-
contentPreview: bullet.content.length > 60 ? `${bullet.content.slice(0, 60)}...` : bullet.content,
|
|
75
|
-
id: bullet.id,
|
|
76
|
-
section: bullet.section,
|
|
77
|
-
tags: bullet.metadata.tags,
|
|
78
|
-
timestamp: new Date(bullet.metadata.timestamp).toLocaleDateString(),
|
|
79
|
-
}));
|
|
80
|
-
const bulletId = await search({
|
|
81
|
-
message: 'Select a bullet to update:',
|
|
82
|
-
async source(input) {
|
|
83
|
-
const filtered = input
|
|
84
|
-
? displayBullets.filter((b) => b.section.toLowerCase().includes(input.toLowerCase()) ||
|
|
85
|
-
b.contentPreview.toLowerCase().includes(input.toLowerCase()) ||
|
|
86
|
-
b.id.toLowerCase().includes(input.toLowerCase()))
|
|
87
|
-
: displayBullets;
|
|
88
|
-
return filtered.map((b) => ({
|
|
89
|
-
description: `Tags: ${b.tags.join(', ')} | Date: ${b.timestamp}`,
|
|
90
|
-
name: `[${b.id}] ${b.section}: ${b.contentPreview}`,
|
|
91
|
-
value: b.id,
|
|
92
|
-
}));
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
return bulletId;
|
|
70
|
+
return confirmed;
|
|
96
71
|
}
|
|
97
72
|
/**
|
|
98
73
|
* Prompt user to enter bullet content
|
|
99
74
|
*/
|
|
100
|
-
async promptForContent(
|
|
101
|
-
const message =
|
|
102
|
-
? `Enter new content for bullet in "${context.section}":`
|
|
103
|
-
: `Enter content for new bullet in "${context.section}":`;
|
|
75
|
+
async promptForContent(section) {
|
|
76
|
+
const message = `Enter content for new bullet in "${section}":`;
|
|
104
77
|
const content = await input({
|
|
105
|
-
default: context.existingContent,
|
|
106
78
|
message,
|
|
107
79
|
validate(value) {
|
|
108
80
|
if (!validateContent(value)) {
|
|
@@ -139,11 +111,10 @@ export default class Add extends Command {
|
|
|
139
111
|
return flags.interactive ? this.runInteractive() : this.runFlagBased(flags);
|
|
140
112
|
}
|
|
141
113
|
/**
|
|
142
|
-
* Display success message after adding
|
|
114
|
+
* Display success message after adding a bullet
|
|
143
115
|
*/
|
|
144
|
-
displaySuccess(bullet
|
|
145
|
-
|
|
146
|
-
this.log(`\n✓ ${actionText} bullet successfully!`);
|
|
116
|
+
displaySuccess(bullet) {
|
|
117
|
+
this.log(`\n✓ Added bullet successfully!`);
|
|
147
118
|
this.log(` ID: ${bullet.id}`);
|
|
148
119
|
this.log(` Section: ${bullet.section}`);
|
|
149
120
|
this.log(` Content: ${bullet.content}`);
|
|
@@ -173,7 +144,7 @@ export default class Add extends Command {
|
|
|
173
144
|
content: flags.content,
|
|
174
145
|
section: flags.section,
|
|
175
146
|
});
|
|
176
|
-
this.displaySuccess(bullet
|
|
147
|
+
this.displaySuccess(bullet);
|
|
177
148
|
}
|
|
178
149
|
catch (error) {
|
|
179
150
|
this.error(error instanceof Error ? error.message : 'Unexpected error occurred');
|
|
@@ -185,43 +156,34 @@ export default class Add extends Command {
|
|
|
185
156
|
async runInteractive() {
|
|
186
157
|
const { playbookService, playbookStore, trackingService } = this.createServices();
|
|
187
158
|
try {
|
|
159
|
+
// Display welcome message
|
|
160
|
+
this.log('Press Ctrl+C at any time to cancel the process\n');
|
|
188
161
|
// Load existing playbook or create new one
|
|
189
162
|
let playbook = await playbookStore.load();
|
|
190
163
|
if (!playbook) {
|
|
191
164
|
playbook = new Playbook();
|
|
192
165
|
}
|
|
193
|
-
const action = await this.promptForAction();
|
|
194
166
|
const sectionOptions = {
|
|
195
167
|
existingSections: playbook.getSections(),
|
|
196
168
|
suggestedSections: SUGGESTED_SECTIONS,
|
|
197
169
|
};
|
|
198
170
|
const section = await this.promptForSection(sectionOptions);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
bulletId = await this.promptForBullet(bullets);
|
|
208
|
-
const bullet = playbook.getBullet(bulletId);
|
|
209
|
-
existingContent = bullet?.content;
|
|
210
|
-
}
|
|
171
|
+
const content = await this.promptForContent(section);
|
|
172
|
+
// Get next bullet ID for confirmation
|
|
173
|
+
const nextId = playbook.getNextId();
|
|
174
|
+
// Prompt for confirmation
|
|
175
|
+
const confirmed = await this.promptForConfirmation(nextId, section, content);
|
|
176
|
+
if (!confirmed) {
|
|
177
|
+
this.log('\nBullet not added. Operation cancelled.');
|
|
178
|
+
return;
|
|
211
179
|
}
|
|
212
|
-
const contentContext = {
|
|
213
|
-
action: bulletId ? 'update' : 'add',
|
|
214
|
-
existingContent,
|
|
215
|
-
section,
|
|
216
|
-
};
|
|
217
|
-
const content = await this.promptForContent(contentContext);
|
|
218
180
|
const bullet = await playbookService.addOrUpdateBullet({
|
|
219
|
-
bulletId,
|
|
181
|
+
bulletId: undefined,
|
|
220
182
|
content,
|
|
221
183
|
section,
|
|
222
184
|
});
|
|
223
185
|
await trackingService.track('ace:add_bullet');
|
|
224
|
-
this.displaySuccess(bullet
|
|
186
|
+
this.displaySuccess(bullet);
|
|
225
187
|
}
|
|
226
188
|
catch (error) {
|
|
227
189
|
this.error(error instanceof Error ? error.message : 'Unexpected error occurred');
|
package/dist/commands/init.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { select } from '@inquirer/prompts';
|
|
2
2
|
import { Command, ux } from '@oclif/core';
|
|
3
3
|
import { getCurrentConfig } from '../config/environment.js';
|
|
4
|
-
import {
|
|
4
|
+
import { BRV_DIR, PROJECT_CONFIG_FILE } from '../constants.js';
|
|
5
|
+
import { BrvConfig } from '../core/domain/entities/brv-config.js';
|
|
5
6
|
import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
6
7
|
import { FilePlaybookService } from '../infra/playbook/file-playbook-service.js';
|
|
7
8
|
import { HttpSpaceService } from '../infra/space/http-space-service.js';
|
|
@@ -9,7 +10,7 @@ import { KeychainTokenStore } from '../infra/storage/keychain-token-store.js';
|
|
|
9
10
|
import { HttpTeamService } from '../infra/team/http-team-service.js';
|
|
10
11
|
import { MixpanelTrackingService } from '../infra/tracking/mixpanel-tracking-service.js';
|
|
11
12
|
export default class Init extends Command {
|
|
12
|
-
static description =
|
|
13
|
+
static description = `Initialize a project with ByteRover (creates ${BRV_DIR}/${PROJECT_CONFIG_FILE} with team/space selection and initializes ACE playbook)`;
|
|
13
14
|
static examples = [
|
|
14
15
|
'<%= config.bin %> <%= command.id %>',
|
|
15
16
|
'# Re-initialize if config exists (will show current config and exit):\n<%= config.bin %> <%= command.id %>',
|
|
@@ -75,10 +76,10 @@ export default class Init extends Command {
|
|
|
75
76
|
// 2. Load and validate authentication token
|
|
76
77
|
const token = await tokenStore.load();
|
|
77
78
|
if (token === undefined) {
|
|
78
|
-
this.error('Not authenticated. Please run "
|
|
79
|
+
this.error('Not authenticated. Please run "brv login" first.');
|
|
79
80
|
}
|
|
80
81
|
if (!token.isValid()) {
|
|
81
|
-
this.error('Authentication token expired. Please run "
|
|
82
|
+
this.error('Authentication token expired. Please run "brv login" again.');
|
|
82
83
|
}
|
|
83
84
|
// 3. Fetch all teams with spinner
|
|
84
85
|
ux.action.start('Fetching all teams');
|
|
@@ -86,7 +87,9 @@ export default class Init extends Command {
|
|
|
86
87
|
ux.action.stop();
|
|
87
88
|
const { teams } = teamResult;
|
|
88
89
|
if (teams.length === 0) {
|
|
89
|
-
this.
|
|
90
|
+
this.log('No teams found.');
|
|
91
|
+
this.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first team.`);
|
|
92
|
+
return;
|
|
90
93
|
}
|
|
91
94
|
// 4. Prompt for team selection
|
|
92
95
|
this.log();
|
|
@@ -99,13 +102,15 @@ export default class Init extends Command {
|
|
|
99
102
|
ux.action.stop();
|
|
100
103
|
const { spaces } = spaceResult;
|
|
101
104
|
if (spaces.length === 0) {
|
|
102
|
-
this.
|
|
105
|
+
this.log(`No spaces found in team "${selectedTeam.getDisplayName()}"`);
|
|
106
|
+
this.log(`Please visit ${getCurrentConfig().webAppUrl} to create your first space for ${selectedTeam.getDisplayName()}.`);
|
|
107
|
+
return;
|
|
103
108
|
}
|
|
104
109
|
// 6. Prompt for space selection
|
|
105
110
|
this.log();
|
|
106
111
|
const selectedSpace = await this.promptForSpaceSelection(spaces);
|
|
107
112
|
// 7. Create and save configuration
|
|
108
|
-
const config =
|
|
113
|
+
const config = BrvConfig.fromSpace(selectedSpace);
|
|
109
114
|
await projectConfigStore.write(config);
|
|
110
115
|
// 8. Initialize ACE playbook
|
|
111
116
|
this.log('\nInitializing ACE context...');
|
|
@@ -126,7 +131,7 @@ export default class Init extends Command {
|
|
|
126
131
|
// 10. Display success
|
|
127
132
|
this.log(`\n✓ Project initialized successfully!`);
|
|
128
133
|
this.log(`✓ Connected to space: ${selectedSpace.getDisplayName()}`);
|
|
129
|
-
this.log(`✓ Configuration saved to:
|
|
134
|
+
this.log(`✓ Configuration saved to: ${BRV_DIR}/${PROJECT_CONFIG_FILE}`);
|
|
130
135
|
}
|
|
131
136
|
catch (error) {
|
|
132
137
|
this.error(error instanceof Error ? error.message : 'Initialization failed');
|
package/dist/commands/push.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import type { AuthToken } from '../core/domain/entities/auth-token.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { BrvConfig } from '../core/domain/entities/brv-config.js';
|
|
4
4
|
import type { PresignedUrl } from '../core/domain/entities/presigned-url.js';
|
|
5
5
|
import type { PresignedUrlsResponse } from '../core/domain/entities/presigned-urls-response.js';
|
|
6
6
|
import type { IMemoryStorageService } from '../core/interfaces/i-memory-storage-service.js';
|
|
@@ -13,10 +13,12 @@ export default class Push extends Command {
|
|
|
13
13
|
static examples: string[];
|
|
14
14
|
static flags: {
|
|
15
15
|
branch: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
17
|
};
|
|
17
|
-
protected checkProjectInit(projectConfigStore: IProjectConfigStore): Promise<
|
|
18
|
+
protected checkProjectInit(projectConfigStore: IProjectConfigStore): Promise<BrvConfig>;
|
|
18
19
|
protected cleanUpLocalFiles(playbookStore: IPlaybookStore): Promise<void>;
|
|
19
|
-
protected
|
|
20
|
+
protected confirmPush(projectConfig: BrvConfig, branch: string, fileCount: number): Promise<boolean>;
|
|
21
|
+
protected confirmUpload(memoryService: IMemoryStorageService, token: AuthToken, projectConfig: BrvConfig, requestId: string): Promise<void>;
|
|
20
22
|
protected createServices(): {
|
|
21
23
|
memoryService: IMemoryStorageService;
|
|
22
24
|
playbookStore: IPlaybookStore;
|
|
@@ -24,7 +26,7 @@ export default class Push extends Command {
|
|
|
24
26
|
tokenStore: ITokenStore;
|
|
25
27
|
trackingService: ITrackingService;
|
|
26
28
|
};
|
|
27
|
-
protected getPresignedUrls(memoryService: IMemoryStorageService, token: AuthToken, projectConfig:
|
|
29
|
+
protected getPresignedUrls(memoryService: IMemoryStorageService, token: AuthToken, projectConfig: BrvConfig): Promise<PresignedUrlsResponse>;
|
|
28
30
|
protected loadPlaybookContent(playbookStore: IPlaybookStore): Promise<string>;
|
|
29
31
|
run(): Promise<void>;
|
|
30
32
|
protected uploadFiles(memoryService: IMemoryStorageService, presignedUrls: ReadonlyArray<PresignedUrl>, playbookContent: string): Promise<void>;
|
package/dist/commands/push.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
1
2
|
import { Command, Flags, ux } from '@oclif/core';
|
|
2
3
|
import { join } from 'node:path';
|
|
3
4
|
import { getCurrentConfig } from '../config/environment.js';
|
|
4
|
-
import { ACE_DIR,
|
|
5
|
+
import { ACE_DIR, BRV_DIR, BULLETS_DIR, DEFAULT_BRANCH, DELTAS_DIR, EXECUTOR_OUTPUTS_DIR, PLAYBOOK_FILE, REFLECTIONS_DIR, } from '../constants.js';
|
|
5
6
|
import { FilePlaybookStore } from '../infra/ace/file-playbook-store.js';
|
|
6
7
|
import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
7
8
|
import { HttpMemoryStorageService } from '../infra/memory/http-memory-storage-service.js';
|
|
@@ -22,23 +23,28 @@ export default class Push extends Command {
|
|
|
22
23
|
default: DEFAULT_BRANCH,
|
|
23
24
|
description: 'ByteRover branch name (not Git branch)',
|
|
24
25
|
}),
|
|
26
|
+
yes: Flags.boolean({
|
|
27
|
+
char: 'y',
|
|
28
|
+
default: false,
|
|
29
|
+
description: 'Skip confirmation prompt',
|
|
30
|
+
}),
|
|
25
31
|
};
|
|
26
32
|
async checkProjectInit(projectConfigStore) {
|
|
27
33
|
const projectConfig = await projectConfigStore.read();
|
|
28
34
|
if (projectConfig === undefined) {
|
|
29
|
-
this.error('Project not initialized. Run "
|
|
35
|
+
this.error('Project not initialized. Run "brv init" first.');
|
|
30
36
|
}
|
|
31
37
|
return projectConfig;
|
|
32
38
|
}
|
|
33
39
|
async cleanUpLocalFiles(playbookStore) {
|
|
34
40
|
this.log('\nCleaning up local files...');
|
|
35
|
-
// Clear playbook content
|
|
36
|
-
ux.action.start(' Clearing playbook');
|
|
41
|
+
// Clear playbook content and bullet files
|
|
42
|
+
ux.action.start(' Clearing playbook and bullet files');
|
|
37
43
|
await playbookStore.clear();
|
|
38
44
|
ux.action.stop('✓');
|
|
39
45
|
// Clean executor outputs
|
|
40
46
|
const baseDir = process.cwd();
|
|
41
|
-
const aceDir = join(baseDir,
|
|
47
|
+
const aceDir = join(baseDir, BRV_DIR, ACE_DIR);
|
|
42
48
|
const executorOutputsDir = join(aceDir, EXECUTOR_OUTPUTS_DIR);
|
|
43
49
|
const reflectionsDir = join(aceDir, REFLECTIONS_DIR);
|
|
44
50
|
const deltasDir = join(aceDir, DELTAS_DIR);
|
|
@@ -54,6 +60,22 @@ export default class Push extends Command {
|
|
|
54
60
|
const deltaCount = await clearDirectory(deltasDir);
|
|
55
61
|
ux.action.stop(`✓ (${deltaCount} files removed)`);
|
|
56
62
|
}
|
|
63
|
+
async confirmPush(projectConfig, branch, fileCount) {
|
|
64
|
+
this.log('\nYou are about to push to ByteRover memory storage:');
|
|
65
|
+
this.log(` Space: ${projectConfig.spaceName}`);
|
|
66
|
+
this.log(` Branch: ${branch}`);
|
|
67
|
+
this.log(` Files to upload: ${fileCount}`);
|
|
68
|
+
this.log('\nAfter successful push, these local files will be cleaned up:');
|
|
69
|
+
this.log(' - Playbook content');
|
|
70
|
+
this.log(` - Bullet files (${BRV_DIR}/${ACE_DIR}/${BULLETS_DIR}/)`);
|
|
71
|
+
this.log(` - Executor outputs (${BRV_DIR}/${ACE_DIR}/${EXECUTOR_OUTPUTS_DIR}/)`);
|
|
72
|
+
this.log(` - Reflections (${BRV_DIR}/${ACE_DIR}/${REFLECTIONS_DIR}/)`);
|
|
73
|
+
this.log(` - Deltas (${BRV_DIR}/${ACE_DIR}/${DELTAS_DIR}/)`);
|
|
74
|
+
return confirm({
|
|
75
|
+
default: false,
|
|
76
|
+
message: 'Push to ByteRover and clean up local files?',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
57
79
|
async confirmUpload(memoryService, token, projectConfig, requestId) {
|
|
58
80
|
ux.action.start('Confirming upload');
|
|
59
81
|
await memoryService.confirmUpload({
|
|
@@ -85,7 +107,7 @@ export default class Push extends Command {
|
|
|
85
107
|
const response = await memoryService.getPresignedUrls({
|
|
86
108
|
accessToken: token.accessToken,
|
|
87
109
|
branch: flags.branch,
|
|
88
|
-
fileNames: [
|
|
110
|
+
fileNames: [`${PLAYBOOK_FILE}`],
|
|
89
111
|
sessionKey: token.sessionKey,
|
|
90
112
|
spaceId: projectConfig.spaceId,
|
|
91
113
|
teamId: projectConfig.teamId,
|
|
@@ -111,6 +133,14 @@ export default class Push extends Command {
|
|
|
111
133
|
const token = await this.validateAuth(tokenStore);
|
|
112
134
|
const projectConfig = await this.checkProjectInit(projectConfigStore);
|
|
113
135
|
await this.verifyPlaybookExists(playbookStore);
|
|
136
|
+
// Prompt for confirmation unless --yes flag is provided
|
|
137
|
+
if (!flags.yes) {
|
|
138
|
+
const confirmed = await this.confirmPush(projectConfig, flags.branch, 1);
|
|
139
|
+
if (!confirmed) {
|
|
140
|
+
this.log('Push cancelled. No files were uploaded or cleaned.');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
114
144
|
const response = await this.getPresignedUrls(memoryService, token, projectConfig);
|
|
115
145
|
const playbookContent = await this.loadPlaybookContent(playbookStore);
|
|
116
146
|
await this.uploadFiles(memoryService, response.presignedUrls, playbookContent);
|
|
@@ -134,17 +164,17 @@ export default class Push extends Command {
|
|
|
134
164
|
async validateAuth(tokenStore) {
|
|
135
165
|
const token = await tokenStore.load();
|
|
136
166
|
if (token === undefined) {
|
|
137
|
-
this.error('Not authenticated. Run "
|
|
167
|
+
this.error('Not authenticated. Run "brv login" first.');
|
|
138
168
|
}
|
|
139
169
|
if (!token.isValid()) {
|
|
140
|
-
this.error('Authentication token expired. Run "
|
|
170
|
+
this.error('Authentication token expired. Run "brv login" again.');
|
|
141
171
|
}
|
|
142
172
|
return token;
|
|
143
173
|
}
|
|
144
174
|
async verifyPlaybookExists(playbookStore) {
|
|
145
175
|
const playbookExists = await playbookStore.exists();
|
|
146
176
|
if (!playbookExists) {
|
|
147
|
-
this.error('Playbook not found. Run "
|
|
177
|
+
this.error('Playbook not found. Run "brv init" to create one.');
|
|
148
178
|
}
|
|
149
179
|
}
|
|
150
180
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import type { AuthToken } from '../core/domain/entities/auth-token.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { BrvConfig } from '../core/domain/entities/brv-config.js';
|
|
4
4
|
import type { IMemoryRetrievalService } from '../core/interfaces/i-memory-retrieval-service.js';
|
|
5
5
|
import type { IProjectConfigStore } from '../core/interfaces/i-project-config-store.js';
|
|
6
6
|
import type { ITokenStore } from '../core/interfaces/i-token-store.js';
|
|
@@ -13,7 +13,7 @@ export default class Retrieve extends Command {
|
|
|
13
13
|
'node-keys': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
14
|
query: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
15
|
};
|
|
16
|
-
protected checkProjectInt(projectConfigStore: IProjectConfigStore): Promise<
|
|
16
|
+
protected checkProjectInt(projectConfigStore: IProjectConfigStore): Promise<BrvConfig>;
|
|
17
17
|
protected createServices(): {
|
|
18
18
|
memoryService: IMemoryRetrievalService;
|
|
19
19
|
projectConfigStore: IProjectConfigStore;
|
|
@@ -31,7 +31,7 @@ export default class Retrieve extends Command {
|
|
|
31
31
|
async checkProjectInt(projectConfigStore) {
|
|
32
32
|
const isInitialized = await projectConfigStore.exists();
|
|
33
33
|
if (!isInitialized) {
|
|
34
|
-
this.error('Project is not initialized. Please run "
|
|
34
|
+
this.error('Project is not initialized. Please run "brv init" first.');
|
|
35
35
|
}
|
|
36
36
|
const config = await projectConfigStore.read();
|
|
37
37
|
if (!config) {
|
|
@@ -82,10 +82,10 @@ export default class Retrieve extends Command {
|
|
|
82
82
|
async validateAuth(tokenStore) {
|
|
83
83
|
const token = await tokenStore.load();
|
|
84
84
|
if (token === undefined) {
|
|
85
|
-
this.error('Not authenticated. Please run "
|
|
85
|
+
this.error('Not authenticated. Please run "brv login" first.');
|
|
86
86
|
}
|
|
87
87
|
if (!token.isValid()) {
|
|
88
|
-
this.error('Authentication token expired. Please run "
|
|
88
|
+
this.error('Authentication token expired. Please run "brv login" again.');
|
|
89
89
|
}
|
|
90
90
|
return token;
|
|
91
91
|
}
|
|
@@ -51,13 +51,18 @@ export default class SpaceList extends Command {
|
|
|
51
51
|
// Check project initialization
|
|
52
52
|
const projectConfig = await projectConfigStore.read();
|
|
53
53
|
if (projectConfig === undefined) {
|
|
54
|
-
this.error('Project not initialized. Run "
|
|
54
|
+
this.error('Project not initialized. Run "brv init" first.');
|
|
55
55
|
}
|
|
56
56
|
const token = await this.validateAuth(tokenStore);
|
|
57
57
|
// Fetch spaces for the team from project config
|
|
58
58
|
ux.action.start(`Fetching spaces for ${projectConfig.teamName}`);
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
let result;
|
|
60
|
+
try {
|
|
61
|
+
result = await spaceService.getSpaces(token.accessToken, token.sessionKey, projectConfig.teamId, flags.all ? { fetchAll: true } : { limit: flags.limit, offset: flags.offset });
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
ux.action.stop();
|
|
65
|
+
}
|
|
61
66
|
// Handle empty results
|
|
62
67
|
if (result.spaces.length === 0) {
|
|
63
68
|
this.log(`No spaces found in team "${projectConfig.teamName}".`);
|
|
@@ -95,10 +100,10 @@ export default class SpaceList extends Command {
|
|
|
95
100
|
async validateAuth(tokenStore) {
|
|
96
101
|
const token = await tokenStore.load();
|
|
97
102
|
if (token === undefined) {
|
|
98
|
-
this.error('Not authenticated. Please run "
|
|
103
|
+
this.error('Not authenticated. Please run "brv login" first.');
|
|
99
104
|
}
|
|
100
105
|
if (!token.isValid()) {
|
|
101
|
-
this.error('Authentication token expired. Please run "
|
|
106
|
+
this.error('Authentication token expired. Please run "brv login" again.');
|
|
102
107
|
}
|
|
103
108
|
return token;
|
|
104
109
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { select } from '@inquirer/prompts';
|
|
2
2
|
import { Command, ux } from '@oclif/core';
|
|
3
3
|
import { getCurrentConfig } from '../../config/environment.js';
|
|
4
|
-
import {
|
|
4
|
+
import { BRV_DIR, PROJECT_CONFIG_FILE } from '../../constants.js';
|
|
5
|
+
import { BrvConfig } from '../../core/domain/entities/brv-config.js';
|
|
5
6
|
import { ProjectConfigStore } from '../../infra/config/file-config-store.js';
|
|
6
7
|
import { HttpSpaceService } from '../../infra/space/http-space-service.js';
|
|
7
8
|
import { KeychainTokenStore } from '../../infra/storage/keychain-token-store.js';
|
|
8
9
|
import { HttpTeamService } from '../../infra/team/http-team-service.js';
|
|
9
10
|
export default class SpaceSwitch extends Command {
|
|
10
|
-
static description =
|
|
11
|
+
static description = `Switch to a different team or space (updates ${BRV_DIR}/${PROJECT_CONFIG_FILE})`;
|
|
11
12
|
static examples = [
|
|
12
13
|
'<%= config.bin %> <%= command.id %>',
|
|
13
14
|
'# Shows current configuration, then prompts for new team/space selection',
|
|
@@ -59,7 +60,7 @@ export default class SpaceSwitch extends Command {
|
|
|
59
60
|
// Check project initialization (MUST exist for switch)
|
|
60
61
|
const currentConfig = await projectConfigStore.read();
|
|
61
62
|
if (currentConfig === undefined) {
|
|
62
|
-
this.error('Project not initialized. Run "
|
|
63
|
+
this.error('Project not initialized. Run "brv init" first.');
|
|
63
64
|
}
|
|
64
65
|
// Show current configuration
|
|
65
66
|
this.log('Current configuration:');
|
|
@@ -69,10 +70,10 @@ export default class SpaceSwitch extends Command {
|
|
|
69
70
|
// Validate authentication
|
|
70
71
|
const token = await tokenStore.load();
|
|
71
72
|
if (token === undefined) {
|
|
72
|
-
this.error('Not authenticated. Please run "
|
|
73
|
+
this.error('Not authenticated. Please run "brv login" first.');
|
|
73
74
|
}
|
|
74
75
|
if (!token.isValid()) {
|
|
75
|
-
this.error('Authentication token expired. Please run "
|
|
76
|
+
this.error('Authentication token expired. Please run "brv login" again.');
|
|
76
77
|
}
|
|
77
78
|
// Fetch all teams
|
|
78
79
|
ux.action.start('Fetching all teams');
|
|
@@ -97,11 +98,11 @@ export default class SpaceSwitch extends Command {
|
|
|
97
98
|
this.log();
|
|
98
99
|
const selectedSpace = await this.promptForSpaceSelection(spaceResult.spaces);
|
|
99
100
|
// Update configuration
|
|
100
|
-
const newConfig =
|
|
101
|
+
const newConfig = BrvConfig.fromSpace(selectedSpace);
|
|
101
102
|
await projectConfigStore.write(newConfig);
|
|
102
103
|
// Display success
|
|
103
104
|
this.log(`\n✓ Successfully switched to space: ${selectedSpace.getDisplayName()}`);
|
|
104
|
-
this.log(`✓ Configuration updated in:
|
|
105
|
+
this.log(`✓ Configuration updated in: ${BRV_DIR}/${PROJECT_CONFIG_FILE}`);
|
|
105
106
|
}
|
|
106
107
|
catch (error) {
|
|
107
108
|
this.error(error instanceof Error ? error.message : 'Switch failed');
|
package/dist/commands/status.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { ACE_DIR,
|
|
3
|
+
import { ACE_DIR, BRV_DIR, BULLETS_DIR } from '../constants.js';
|
|
4
4
|
import { FilePlaybookStore } from '../infra/ace/file-playbook-store.js';
|
|
5
5
|
import { ProjectConfigStore } from '../infra/config/file-config-store.js';
|
|
6
6
|
import { KeychainTokenStore } from '../infra/storage/keychain-token-store.js';
|
|
@@ -80,7 +80,7 @@ export default class Status extends Command {
|
|
|
80
80
|
try {
|
|
81
81
|
const playbook = await playbookStore.load(args.directory);
|
|
82
82
|
if (!playbook) {
|
|
83
|
-
this.error('Playbook not found. Run `
|
|
83
|
+
this.error('Playbook not found. Run `brv init` to initialize.');
|
|
84
84
|
}
|
|
85
85
|
// Display based on format
|
|
86
86
|
if (flags.format === 'json') {
|
|
@@ -90,7 +90,7 @@ export default class Status extends Command {
|
|
|
90
90
|
const bullets = playbook.getBullets();
|
|
91
91
|
const sections = playbook.getSections();
|
|
92
92
|
if (bullets.length === 0) {
|
|
93
|
-
this.log('Playbook is empty. Use "
|
|
93
|
+
this.log('Playbook is empty. Use "brv add" commands to add knowledge.');
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
96
|
this.log(`\nMemory not pushed to cloud:`);
|
|
@@ -101,13 +101,12 @@ export default class Status extends Command {
|
|
|
101
101
|
this.log(`# ${section}`);
|
|
102
102
|
const sectionBullets = playbook.getBulletsInSection(section);
|
|
103
103
|
for (const bullet of sectionBullets) {
|
|
104
|
-
const relativePath = `${
|
|
104
|
+
const relativePath = `${BRV_DIR}/${ACE_DIR}/${BULLETS_DIR}/${bullet.id}.md`;
|
|
105
105
|
// Display like git status: red path
|
|
106
106
|
this.log(` ${chalk.red(relativePath)}`);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
|
|
110
|
-
this.log(`Use "br push" to push memory to cloud.`);
|
|
109
|
+
this.log(`\nUse "brv push" to push playbook to ByteRover memory storage.`);
|
|
111
110
|
}
|
|
112
111
|
catch (error) {
|
|
113
112
|
this.error(error instanceof Error ? error.message : 'Failed to load playbook statistics');
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
type Environment = 'development' | 'production';
|
|
5
5
|
/**
|
|
6
6
|
* Current environment - set at runtime by the launcher scripts.
|
|
7
|
-
* - `./bin/dev.js` sets
|
|
8
|
-
* - `./bin/run.js` sets
|
|
7
|
+
* - `./bin/dev.js` sets BRV_ENV=development
|
|
8
|
+
* - `./bin/run.js` sets BRV_ENV=production
|
|
9
9
|
*/
|
|
10
10
|
export declare const ENVIRONMENT: Environment;
|
|
11
11
|
/**
|
|
@@ -21,6 +21,7 @@ type EnvironmentConfig = {
|
|
|
21
21
|
mixpanelToken: string;
|
|
22
22
|
scopes: string[];
|
|
23
23
|
tokenUrl: string;
|
|
24
|
+
webAppUrl: string;
|
|
24
25
|
};
|
|
25
26
|
/**
|
|
26
27
|
* Configuration for each environment.
|