byterover-cli 2.1.5 → 2.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/dist/oclif/commands/locations.d.ts +14 -0
- package/dist/oclif/commands/locations.js +68 -0
- package/dist/oclif/commands/status.js +3 -3
- package/dist/server/infra/daemon/brv-server.js +2 -0
- package/dist/server/infra/process/feature-handlers.d.ts +4 -1
- package/dist/server/infra/process/feature-handlers.js +9 -2
- package/dist/server/infra/transport/handlers/index.d.ts +2 -0
- package/dist/server/infra/transport/handlers/index.js +1 -0
- package/dist/server/infra/transport/handlers/locations-handler.d.ts +25 -0
- package/dist/server/infra/transport/handlers/locations-handler.js +64 -0
- package/dist/server/templates/skill/SKILL.md +19 -1
- package/dist/shared/transport/events/index.d.ts +3 -0
- package/dist/shared/transport/events/index.js +3 -0
- package/dist/shared/transport/events/locations-events.d.ts +7 -0
- package/dist/shared/transport/events/locations-events.js +3 -0
- package/dist/shared/transport/types/dto.d.ts +11 -0
- package/dist/tui/features/commands/definitions/index.js +2 -0
- package/dist/tui/features/commands/definitions/locations.d.ts +2 -0
- package/dist/tui/features/commands/definitions/locations.js +11 -0
- package/dist/tui/features/locations/api/get-locations.d.ts +16 -0
- package/dist/tui/features/locations/api/get-locations.js +17 -0
- package/dist/tui/features/locations/components/locations-view.d.ts +3 -0
- package/dist/tui/features/locations/components/locations-view.js +25 -0
- package/dist/tui/features/locations/utils/format-locations.d.ts +2 -0
- package/dist/tui/features/locations/utils/format-locations.js +26 -0
- package/oclif.manifest.json +155 -116
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import type { ProjectLocationDTO } from '../../shared/transport/types/dto.js';
|
|
3
|
+
import { type DaemonClientOptions } from '../lib/daemon-client.js';
|
|
4
|
+
export default class Locations extends Command {
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: {
|
|
8
|
+
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
protected fetchLocations(options?: DaemonClientOptions): Promise<ProjectLocationDTO[]>;
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
private formatLocationEntry;
|
|
13
|
+
private formatTextOutput;
|
|
14
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { LocationsEvents } from '../../shared/transport/events/locations-events.js';
|
|
4
|
+
import { formatConnectionError, withDaemonRetry } from '../lib/daemon-client.js';
|
|
5
|
+
import { writeJsonResponse } from '../lib/json-response.js';
|
|
6
|
+
export default class Locations extends Command {
|
|
7
|
+
static description = 'List all registered projects and their context tree status';
|
|
8
|
+
static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> --format json'];
|
|
9
|
+
static flags = {
|
|
10
|
+
format: Flags.string({
|
|
11
|
+
char: 'f',
|
|
12
|
+
default: 'text',
|
|
13
|
+
description: 'Output format',
|
|
14
|
+
options: ['text', 'json'],
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
async fetchLocations(options) {
|
|
18
|
+
return withDaemonRetry(async (client) => {
|
|
19
|
+
const response = await client.requestWithAck(LocationsEvents.GET);
|
|
20
|
+
return response.locations;
|
|
21
|
+
}, options);
|
|
22
|
+
}
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags } = await this.parse(Locations);
|
|
25
|
+
const isJson = flags.format === 'json';
|
|
26
|
+
try {
|
|
27
|
+
const locations = await this.fetchLocations();
|
|
28
|
+
if (isJson) {
|
|
29
|
+
writeJsonResponse({ command: 'locations', data: { locations }, success: true });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.formatTextOutput(locations);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (isJson) {
|
|
37
|
+
writeJsonResponse({ command: 'locations', data: { error: formatConnectionError(error) }, success: false });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.log(formatConnectionError(error));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
formatLocationEntry(loc) {
|
|
45
|
+
const label = loc.isCurrent ? ' ' + chalk.green('[current]') : loc.isActive ? ' ' + chalk.yellow('[active]') : '';
|
|
46
|
+
const path = loc.isCurrent || loc.isActive ? chalk.bold(loc.projectPath) : loc.projectPath;
|
|
47
|
+
this.log(` ${path}${label}`);
|
|
48
|
+
if (loc.isInitialized) {
|
|
49
|
+
this.log(chalk.dim(' └─ .brv/context-tree/'));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.log(chalk.dim(' └─ .brv/context-tree/ (not initialized)'));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
formatTextOutput(locations) {
|
|
56
|
+
if (locations.length > 0) {
|
|
57
|
+
this.log(`Registered Projects — ${locations.length} found`);
|
|
58
|
+
this.log(chalk.dim('──────────────────────────────────────────'));
|
|
59
|
+
for (const loc of locations) {
|
|
60
|
+
this.formatLocationEntry(loc);
|
|
61
|
+
this.log('');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.log('Registered Projects — none found');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -22,10 +22,10 @@ export default class Status extends Command {
|
|
|
22
22
|
}
|
|
23
23
|
async run() {
|
|
24
24
|
const { flags } = await this.parse(Status);
|
|
25
|
-
const
|
|
25
|
+
const isJson = flags.format === 'json';
|
|
26
26
|
try {
|
|
27
27
|
const status = await this.fetchStatus();
|
|
28
|
-
if (
|
|
28
|
+
if (isJson) {
|
|
29
29
|
writeJsonResponse({
|
|
30
30
|
command: 'status',
|
|
31
31
|
data: { ...status, cliVersion: this.config.version },
|
|
@@ -37,7 +37,7 @@ export default class Status extends Command {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
40
|
-
if (
|
|
40
|
+
if (isJson) {
|
|
41
41
|
writeJsonResponse({
|
|
42
42
|
command: 'status',
|
|
43
43
|
data: { error: formatConnectionError(error) },
|
|
@@ -352,7 +352,9 @@ async function main() {
|
|
|
352
352
|
broadcastToProject(projectPath, event, data) {
|
|
353
353
|
broadcastToProjectRoom(projectRegistry, projectRouter, projectPath, event, data);
|
|
354
354
|
},
|
|
355
|
+
getActiveProjectPaths: () => clientManager.getActiveProjects(),
|
|
355
356
|
log,
|
|
357
|
+
projectRegistry,
|
|
356
358
|
providerConfigStore,
|
|
357
359
|
providerKeychainStore,
|
|
358
360
|
resolveProjectPath: (clientId) => clientManager.getClient(clientId)?.projectPath,
|
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { IProviderConfigStore } from '../../core/interfaces/i-provider-config-store.js';
|
|
8
8
|
import type { IProviderKeychainStore } from '../../core/interfaces/i-provider-keychain-store.js';
|
|
9
|
+
import type { IProjectRegistry } from '../../core/interfaces/project/i-project-registry.js';
|
|
9
10
|
import type { IAuthStateStore } from '../../core/interfaces/state/i-auth-state-store.js';
|
|
10
11
|
import type { ITransportServer } from '../../core/interfaces/transport/i-transport-server.js';
|
|
11
12
|
import type { ProjectBroadcaster, ProjectPathResolver } from '../transport/handlers/handler-types.js';
|
|
12
13
|
export interface FeatureHandlersOptions {
|
|
13
14
|
authStateStore: IAuthStateStore;
|
|
14
15
|
broadcastToProject: ProjectBroadcaster;
|
|
16
|
+
getActiveProjectPaths: () => string[];
|
|
15
17
|
log: (msg: string) => void;
|
|
18
|
+
projectRegistry: IProjectRegistry;
|
|
16
19
|
providerConfigStore: IProviderConfigStore;
|
|
17
20
|
providerKeychainStore: IProviderKeychainStore;
|
|
18
21
|
resolveProjectPath: ProjectPathResolver;
|
|
@@ -22,4 +25,4 @@ export interface FeatureHandlersOptions {
|
|
|
22
25
|
* Setup all feature handlers on the transport server.
|
|
23
26
|
* These handlers implement the TUI ↔ Server event contract (auth:*, config:*, status:*, etc.).
|
|
24
27
|
*/
|
|
25
|
-
export declare function setupFeatureHandlers({ authStateStore, broadcastToProject, log, providerConfigStore, providerKeychainStore, resolveProjectPath, transport, }: FeatureHandlersOptions): Promise<void>;
|
|
28
|
+
export declare function setupFeatureHandlers({ authStateStore, broadcastToProject, getActiveProjectPaths, log, projectRegistry, providerConfigStore, providerKeychainStore, resolveProjectPath, transport, }: FeatureHandlersOptions): Promise<void>;
|
|
@@ -29,13 +29,13 @@ import { HttpSpaceService } from '../space/http-space-service.js';
|
|
|
29
29
|
import { createTokenStore } from '../storage/token-store.js';
|
|
30
30
|
import { HttpTeamService } from '../team/http-team-service.js';
|
|
31
31
|
import { FsTemplateLoader } from '../template/fs-template-loader.js';
|
|
32
|
-
import { AuthHandler, ConfigHandler, ConnectorsHandler, HubHandler, InitHandler, ModelHandler, ProviderHandler, PullHandler, PushHandler, ResetHandler, SpaceHandler, StatusHandler, } from '../transport/handlers/index.js';
|
|
32
|
+
import { AuthHandler, ConfigHandler, ConnectorsHandler, HubHandler, InitHandler, LocationsHandler, ModelHandler, ProviderHandler, PullHandler, PushHandler, ResetHandler, SpaceHandler, StatusHandler, } from '../transport/handlers/index.js';
|
|
33
33
|
import { HttpUserService } from '../user/http-user-service.js';
|
|
34
34
|
/**
|
|
35
35
|
* Setup all feature handlers on the transport server.
|
|
36
36
|
* These handlers implement the TUI ↔ Server event contract (auth:*, config:*, status:*, etc.).
|
|
37
37
|
*/
|
|
38
|
-
export async function setupFeatureHandlers({ authStateStore, broadcastToProject, log, providerConfigStore, providerKeychainStore, resolveProjectPath, transport, }) {
|
|
38
|
+
export async function setupFeatureHandlers({ authStateStore, broadcastToProject, getActiveProjectPaths, log, projectRegistry, providerConfigStore, providerKeychainStore, resolveProjectPath, transport, }) {
|
|
39
39
|
const envConfig = getCurrentConfig();
|
|
40
40
|
const tokenStore = createTokenStore();
|
|
41
41
|
const projectConfigStore = new ProjectConfigStore();
|
|
@@ -90,6 +90,13 @@ export async function setupFeatureHandlers({ authStateStore, broadcastToProject,
|
|
|
90
90
|
tokenStore,
|
|
91
91
|
transport,
|
|
92
92
|
}).setup();
|
|
93
|
+
new LocationsHandler({
|
|
94
|
+
contextTreeService,
|
|
95
|
+
getActiveProjectPaths,
|
|
96
|
+
projectRegistry,
|
|
97
|
+
resolveProjectPath,
|
|
98
|
+
transport,
|
|
99
|
+
}).setup();
|
|
93
100
|
new PushHandler({
|
|
94
101
|
broadcastToProject,
|
|
95
102
|
cogitPushService,
|
|
@@ -10,6 +10,8 @@ export { HubHandler } from './hub-handler.js';
|
|
|
10
10
|
export type { HubHandlerDeps } from './hub-handler.js';
|
|
11
11
|
export { InitHandler } from './init-handler.js';
|
|
12
12
|
export type { InitHandlerDeps } from './init-handler.js';
|
|
13
|
+
export { LocationsHandler } from './locations-handler.js';
|
|
14
|
+
export type { LocationsHandlerDeps } from './locations-handler.js';
|
|
13
15
|
export { ModelHandler } from './model-handler.js';
|
|
14
16
|
export type { ModelHandlerDeps } from './model-handler.js';
|
|
15
17
|
export { ProviderHandler } from './provider-handler.js';
|
|
@@ -4,6 +4,7 @@ export { ConnectorsHandler } from './connectors-handler.js';
|
|
|
4
4
|
export { resolveRequiredProjectPath } from './handler-types.js';
|
|
5
5
|
export { HubHandler } from './hub-handler.js';
|
|
6
6
|
export { InitHandler } from './init-handler.js';
|
|
7
|
+
export { LocationsHandler } from './locations-handler.js';
|
|
7
8
|
export { ModelHandler } from './model-handler.js';
|
|
8
9
|
export { ProviderHandler } from './provider-handler.js';
|
|
9
10
|
export { PullHandler } from './pull-handler.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IContextTreeService } from '../../../core/interfaces/context-tree/i-context-tree-service.js';
|
|
2
|
+
import type { IProjectRegistry } from '../../../core/interfaces/project/i-project-registry.js';
|
|
3
|
+
import type { ITransportServer } from '../../../core/interfaces/transport/i-transport-server.js';
|
|
4
|
+
import { type ProjectPathResolver } from './handler-types.js';
|
|
5
|
+
export interface LocationsHandlerDeps {
|
|
6
|
+
contextTreeService: IContextTreeService;
|
|
7
|
+
getActiveProjectPaths: () => string[];
|
|
8
|
+
projectRegistry: IProjectRegistry;
|
|
9
|
+
resolveProjectPath: ProjectPathResolver;
|
|
10
|
+
transport: ITransportServer;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Handles locations:get event.
|
|
14
|
+
* Returns all registered project locations with context tree status.
|
|
15
|
+
*/
|
|
16
|
+
export declare class LocationsHandler {
|
|
17
|
+
private readonly contextTreeService;
|
|
18
|
+
private readonly getActiveProjectPaths;
|
|
19
|
+
private readonly projectRegistry;
|
|
20
|
+
private readonly resolveProjectPath;
|
|
21
|
+
private readonly transport;
|
|
22
|
+
constructor(deps: LocationsHandlerDeps);
|
|
23
|
+
setup(): void;
|
|
24
|
+
private buildLocations;
|
|
25
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { LocationsEvents } from '../../../../shared/transport/events/locations-events.js';
|
|
3
|
+
import { BRV_DIR, CONTEXT_TREE_DIR } from '../../../constants.js';
|
|
4
|
+
import { resolveRequiredProjectPath } from './handler-types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Handles locations:get event.
|
|
7
|
+
* Returns all registered project locations with context tree status.
|
|
8
|
+
*/
|
|
9
|
+
export class LocationsHandler {
|
|
10
|
+
contextTreeService;
|
|
11
|
+
getActiveProjectPaths;
|
|
12
|
+
projectRegistry;
|
|
13
|
+
resolveProjectPath;
|
|
14
|
+
transport;
|
|
15
|
+
constructor(deps) {
|
|
16
|
+
this.contextTreeService = deps.contextTreeService;
|
|
17
|
+
this.getActiveProjectPaths = deps.getActiveProjectPaths;
|
|
18
|
+
this.projectRegistry = deps.projectRegistry;
|
|
19
|
+
this.resolveProjectPath = deps.resolveProjectPath;
|
|
20
|
+
this.transport = deps.transport;
|
|
21
|
+
}
|
|
22
|
+
setup() {
|
|
23
|
+
this.transport.onRequest(LocationsEvents.GET, async (_data, clientId) => {
|
|
24
|
+
const projectPath = resolveRequiredProjectPath(this.resolveProjectPath, clientId);
|
|
25
|
+
try {
|
|
26
|
+
const locations = await this.buildLocations(projectPath);
|
|
27
|
+
return { locations };
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return { locations: [] };
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async buildLocations(currentProjectPath) {
|
|
35
|
+
const all = this.projectRegistry.getAll();
|
|
36
|
+
const activeSet = new Set(this.getActiveProjectPaths());
|
|
37
|
+
const results = await Promise.all([...all.entries()].map(async ([path]) => {
|
|
38
|
+
let isInitialized = false;
|
|
39
|
+
try {
|
|
40
|
+
isInitialized = await this.contextTreeService.exists(path);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// FS error — treat as not initialized
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
contextTreePath: join(path, BRV_DIR, CONTEXT_TREE_DIR),
|
|
47
|
+
isActive: activeSet.has(path) || path === currentProjectPath,
|
|
48
|
+
isCurrent: path === currentProjectPath,
|
|
49
|
+
isInitialized,
|
|
50
|
+
projectPath: path,
|
|
51
|
+
};
|
|
52
|
+
}));
|
|
53
|
+
// Sort: current first → active (has clients) → initialized → rest, all by registeredAt desc
|
|
54
|
+
return results.sort((a, b) => {
|
|
55
|
+
if (a.isCurrent !== b.isCurrent)
|
|
56
|
+
return a.isCurrent ? -1 : 1;
|
|
57
|
+
if (a.isActive !== b.isActive)
|
|
58
|
+
return a.isActive ? -1 : 1;
|
|
59
|
+
if (a.isInitialized !== b.isInitialized)
|
|
60
|
+
return a.isInitialized ? -1 : 1;
|
|
61
|
+
return (all.get(b.projectPath)?.registeredAt ?? 0) - (all.get(a.projectPath)?.registeredAt ?? 0);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -93,7 +93,25 @@ brv providers list
|
|
|
93
93
|
brv providers connect openai --api-key sk-xxx --model gpt-4.1
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
### 4.
|
|
96
|
+
### 4. Project Locations
|
|
97
|
+
**Overview:** List registered projects and their context tree paths. Returns project metadata including initialization status and active state. Use `-f json` for machine-readable output.
|
|
98
|
+
|
|
99
|
+
**Use this when:**
|
|
100
|
+
- You need to find a project's context tree path
|
|
101
|
+
- You need to check which projects are registered
|
|
102
|
+
- You need to verify if a project is initialized
|
|
103
|
+
|
|
104
|
+
**Do NOT use this when:**
|
|
105
|
+
- You already know the project path from your current context
|
|
106
|
+
- You need project content rather than metadata — use `brv query` instead
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
brv locations -f json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
JSON fields: `projectPath`, `contextTreePath`, `isCurrent`, `isActive`, `isInitialized`.
|
|
113
|
+
|
|
114
|
+
### 5. Cloud Sync (Optional)
|
|
97
115
|
**Overview:** Sync your local knowledge with a team via ByteRover's cloud service. Requires ByteRover authentication.
|
|
98
116
|
|
|
99
117
|
**Setup steps:**
|
|
@@ -6,6 +6,7 @@ export * from './connector-events.js';
|
|
|
6
6
|
export * from './hub-events.js';
|
|
7
7
|
export * from './init-events.js';
|
|
8
8
|
export * from './llm-events.js';
|
|
9
|
+
export * from './locations-events.js';
|
|
9
10
|
export * from './model-events.js';
|
|
10
11
|
export * from './onboarding-events.js';
|
|
11
12
|
export * from './provider-events.js';
|
|
@@ -103,6 +104,8 @@ export declare const AllEventGroups: readonly [{
|
|
|
103
104
|
readonly EXECUTE: "reset:execute";
|
|
104
105
|
}, {
|
|
105
106
|
readonly SWITCHED: "session:switched";
|
|
107
|
+
}, {
|
|
108
|
+
readonly GET: "locations:get";
|
|
106
109
|
}, {
|
|
107
110
|
readonly LIST: "space:list";
|
|
108
111
|
readonly SWITCH: "space:switch";
|
|
@@ -8,6 +8,7 @@ export * from './connector-events.js';
|
|
|
8
8
|
export * from './hub-events.js';
|
|
9
9
|
export * from './init-events.js';
|
|
10
10
|
export * from './llm-events.js';
|
|
11
|
+
export * from './locations-events.js';
|
|
11
12
|
export * from './model-events.js';
|
|
12
13
|
export * from './onboarding-events.js';
|
|
13
14
|
export * from './provider-events.js';
|
|
@@ -26,6 +27,7 @@ import { ConnectorEvents } from './connector-events.js';
|
|
|
26
27
|
import { HubEvents } from './hub-events.js';
|
|
27
28
|
import { InitEvents } from './init-events.js';
|
|
28
29
|
import { LlmEvents } from './llm-events.js';
|
|
30
|
+
import { LocationsEvents } from './locations-events.js';
|
|
29
31
|
import { ModelEvents } from './model-events.js';
|
|
30
32
|
import { OnboardingEvents } from './onboarding-events.js';
|
|
31
33
|
import { ProviderEvents } from './provider-events.js';
|
|
@@ -55,6 +57,7 @@ export const AllEventGroups = [
|
|
|
55
57
|
PushEvents,
|
|
56
58
|
ResetEvents,
|
|
57
59
|
SessionEvents,
|
|
60
|
+
LocationsEvents,
|
|
58
61
|
SpaceEvents,
|
|
59
62
|
StatusEvents,
|
|
60
63
|
TaskEvents,
|
|
@@ -97,6 +97,17 @@ export interface HubEntryDTO {
|
|
|
97
97
|
type: 'agent-skill' | 'bundle';
|
|
98
98
|
version: string;
|
|
99
99
|
}
|
|
100
|
+
export interface ProjectLocationDTO {
|
|
101
|
+
/** Absolute path to the context tree directory (e.g., '/Users/foo/project/.brv/context-tree') */
|
|
102
|
+
contextTreePath: string;
|
|
103
|
+
/** True if this project has connected clients/agents or is the current project */
|
|
104
|
+
isActive: boolean;
|
|
105
|
+
/** True if this is the project the client is currently running from */
|
|
106
|
+
isCurrent: boolean;
|
|
107
|
+
/** True if .brv/context-tree exists */
|
|
108
|
+
isInitialized: boolean;
|
|
109
|
+
projectPath: string;
|
|
110
|
+
}
|
|
100
111
|
export interface StatusDTO {
|
|
101
112
|
authStatus: 'expired' | 'logged_in' | 'not_logged_in' | 'unknown';
|
|
102
113
|
contextTreeChanges?: ContextTreeChanges;
|
|
@@ -2,6 +2,7 @@ import { connectorsCommand } from './connectors.js';
|
|
|
2
2
|
import { curateCommand } from './curate.js';
|
|
3
3
|
import { exitCommand } from './exit.js';
|
|
4
4
|
import { hubCommand } from './hub.js';
|
|
5
|
+
import { locationsCommand } from './locations.js';
|
|
5
6
|
import { loginCommand } from './login.js';
|
|
6
7
|
import { logoutCommand } from './logout.js';
|
|
7
8
|
import { modelCommand } from './model.js';
|
|
@@ -22,6 +23,7 @@ import { statusCommand } from './status.js';
|
|
|
22
23
|
export const load = () => [
|
|
23
24
|
// Core workflow - most frequently used
|
|
24
25
|
statusCommand,
|
|
26
|
+
locationsCommand,
|
|
25
27
|
curateCommand,
|
|
26
28
|
queryCommand,
|
|
27
29
|
// Connectors management
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LocationsView } from '../../locations/components/locations-view.js';
|
|
3
|
+
export const locationsCommand = {
|
|
4
|
+
action() {
|
|
5
|
+
return {
|
|
6
|
+
render: ({ onCancel, onComplete }) => React.createElement(LocationsView, { onCancel, onComplete }),
|
|
7
|
+
};
|
|
8
|
+
},
|
|
9
|
+
description: 'List all registered projects and their context tree status',
|
|
10
|
+
name: 'locations',
|
|
11
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { QueryConfig } from '../../../lib/react-query.js';
|
|
2
|
+
import { type LocationsGetResponse } from '../../../../shared/transport/events/index.js';
|
|
3
|
+
export declare const getLocations: () => Promise<LocationsGetResponse>;
|
|
4
|
+
export declare const getLocationsQueryOptions: () => import("@tanstack/react-query").OmitKeyof<import("@tanstack/react-query").UseQueryOptions<LocationsGetResponse, Error, LocationsGetResponse, string[]>, "queryFn"> & {
|
|
5
|
+
queryFn?: import("@tanstack/react-query").QueryFunction<LocationsGetResponse, string[], never> | undefined;
|
|
6
|
+
} & {
|
|
7
|
+
queryKey: string[] & {
|
|
8
|
+
[dataTagSymbol]: LocationsGetResponse;
|
|
9
|
+
[dataTagErrorSymbol]: Error;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
type UseGetLocationsOptions = {
|
|
13
|
+
queryConfig?: QueryConfig<typeof getLocationsQueryOptions>;
|
|
14
|
+
};
|
|
15
|
+
export declare const useGetLocations: ({ queryConfig }?: UseGetLocationsOptions) => import("@tanstack/react-query").UseQueryResult<LocationsGetResponse, Error>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { queryOptions, useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { LocationsEvents } from '../../../../shared/transport/events/index.js';
|
|
3
|
+
import { useTransportStore } from '../../../stores/transport-store.js';
|
|
4
|
+
export const getLocations = () => {
|
|
5
|
+
const { apiClient } = useTransportStore.getState();
|
|
6
|
+
if (!apiClient)
|
|
7
|
+
return Promise.reject(new Error('Not connected'));
|
|
8
|
+
return apiClient.request(LocationsEvents.GET);
|
|
9
|
+
};
|
|
10
|
+
export const getLocationsQueryOptions = () => queryOptions({
|
|
11
|
+
queryFn: getLocations,
|
|
12
|
+
queryKey: ['locations'],
|
|
13
|
+
});
|
|
14
|
+
export const useGetLocations = ({ queryConfig } = {}) => useQuery({
|
|
15
|
+
...getLocationsQueryOptions(),
|
|
16
|
+
...queryConfig,
|
|
17
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text, useInput } from 'ink';
|
|
3
|
+
import Spinner from 'ink-spinner';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import { useGetLocations } from '../api/get-locations.js';
|
|
6
|
+
import { formatLocations } from '../utils/format-locations.js';
|
|
7
|
+
export function LocationsView({ onCancel, onComplete }) {
|
|
8
|
+
const { data, error, isLoading } = useGetLocations();
|
|
9
|
+
useInput((_input, key) => {
|
|
10
|
+
if (key.escape)
|
|
11
|
+
onCancel();
|
|
12
|
+
});
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (data) {
|
|
15
|
+
onComplete(formatLocations(data.locations));
|
|
16
|
+
}
|
|
17
|
+
if (error) {
|
|
18
|
+
onComplete(`Failed to get locations: ${error.message}`);
|
|
19
|
+
}
|
|
20
|
+
}, [data, error, onComplete]);
|
|
21
|
+
if (isLoading) {
|
|
22
|
+
return (_jsxs(Text, { children: [_jsx(Spinner, { type: "dots" }), " Loading locations..."] }));
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
function formatLocationEntry(loc) {
|
|
3
|
+
const label = loc.isCurrent ? ' ' + chalk.green('[current]') : loc.isActive ? ' ' + chalk.yellow('[active]') : '';
|
|
4
|
+
const path = loc.isCurrent || loc.isActive ? chalk.bold(loc.projectPath) : loc.projectPath;
|
|
5
|
+
const lines = [` ${path}${label}`];
|
|
6
|
+
if (loc.isInitialized) {
|
|
7
|
+
lines.push(chalk.dim(' └─ .brv/context-tree/'));
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
lines.push(chalk.dim(' └─ .brv/context-tree/ (not initialized)'));
|
|
11
|
+
}
|
|
12
|
+
return lines;
|
|
13
|
+
}
|
|
14
|
+
export function formatLocations(locations) {
|
|
15
|
+
const lines = [];
|
|
16
|
+
if (locations.length > 0) {
|
|
17
|
+
lines.push(`Registered Projects — ${locations.length} found`, chalk.dim('──────────────────────────────────────────'));
|
|
18
|
+
for (const loc of locations) {
|
|
19
|
+
lines.push(...formatLocationEntry(loc), '');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
lines.push('Registered Projects — none found');
|
|
24
|
+
}
|
|
25
|
+
return lines.join('\n');
|
|
26
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -75,6 +75,45 @@
|
|
|
75
75
|
"hook-prompt-submit.js"
|
|
76
76
|
]
|
|
77
77
|
},
|
|
78
|
+
"locations": {
|
|
79
|
+
"aliases": [],
|
|
80
|
+
"args": {},
|
|
81
|
+
"description": "List all registered projects and their context tree status",
|
|
82
|
+
"examples": [
|
|
83
|
+
"<%= config.bin %> <%= command.id %>",
|
|
84
|
+
"<%= config.bin %> <%= command.id %> --format json"
|
|
85
|
+
],
|
|
86
|
+
"flags": {
|
|
87
|
+
"format": {
|
|
88
|
+
"char": "f",
|
|
89
|
+
"description": "Output format",
|
|
90
|
+
"name": "format",
|
|
91
|
+
"default": "text",
|
|
92
|
+
"hasDynamicHelp": false,
|
|
93
|
+
"multiple": false,
|
|
94
|
+
"options": [
|
|
95
|
+
"text",
|
|
96
|
+
"json"
|
|
97
|
+
],
|
|
98
|
+
"type": "option"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"hasDynamicHelp": false,
|
|
102
|
+
"hiddenAliases": [],
|
|
103
|
+
"id": "locations",
|
|
104
|
+
"pluginAlias": "byterover-cli",
|
|
105
|
+
"pluginName": "byterover-cli",
|
|
106
|
+
"pluginType": "core",
|
|
107
|
+
"strict": true,
|
|
108
|
+
"enableJsonFlag": false,
|
|
109
|
+
"isESM": true,
|
|
110
|
+
"relativePath": [
|
|
111
|
+
"dist",
|
|
112
|
+
"oclif",
|
|
113
|
+
"commands",
|
|
114
|
+
"locations.js"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
78
117
|
"login": {
|
|
79
118
|
"aliases": [],
|
|
80
119
|
"args": {},
|
|
@@ -897,15 +936,40 @@
|
|
|
897
936
|
"list.js"
|
|
898
937
|
]
|
|
899
938
|
},
|
|
900
|
-
"
|
|
939
|
+
"providers:connect": {
|
|
901
940
|
"aliases": [],
|
|
902
|
-
"args": {
|
|
903
|
-
|
|
941
|
+
"args": {
|
|
942
|
+
"provider": {
|
|
943
|
+
"description": "Provider ID to connect (e.g., anthropic, openai, openrouter)",
|
|
944
|
+
"name": "provider",
|
|
945
|
+
"required": true
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
"description": "Connect or switch to an LLM provider",
|
|
904
949
|
"examples": [
|
|
905
|
-
"<%= config.bin %>
|
|
906
|
-
"<%= config.bin %>
|
|
950
|
+
"<%= config.bin %> providers connect anthropic --api-key sk-xxx",
|
|
951
|
+
"<%= config.bin %> providers connect openai --api-key sk-xxx --model gpt-4.1",
|
|
952
|
+
"<%= config.bin %> providers connect byterover",
|
|
953
|
+
"<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1",
|
|
954
|
+
"<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1 --api-key sk-xxx --model llama3"
|
|
907
955
|
],
|
|
908
956
|
"flags": {
|
|
957
|
+
"api-key": {
|
|
958
|
+
"char": "k",
|
|
959
|
+
"description": "API key for the provider",
|
|
960
|
+
"name": "api-key",
|
|
961
|
+
"hasDynamicHelp": false,
|
|
962
|
+
"multiple": false,
|
|
963
|
+
"type": "option"
|
|
964
|
+
},
|
|
965
|
+
"base-url": {
|
|
966
|
+
"char": "b",
|
|
967
|
+
"description": "Base URL for OpenAI-compatible providers (e.g., http://localhost:11434/v1)",
|
|
968
|
+
"name": "base-url",
|
|
969
|
+
"hasDynamicHelp": false,
|
|
970
|
+
"multiple": false,
|
|
971
|
+
"type": "option"
|
|
972
|
+
},
|
|
909
973
|
"format": {
|
|
910
974
|
"description": "Output format (text or json)",
|
|
911
975
|
"name": "format",
|
|
@@ -917,11 +981,19 @@
|
|
|
917
981
|
"json"
|
|
918
982
|
],
|
|
919
983
|
"type": "option"
|
|
984
|
+
},
|
|
985
|
+
"model": {
|
|
986
|
+
"char": "m",
|
|
987
|
+
"description": "Model to set as active after connecting",
|
|
988
|
+
"name": "model",
|
|
989
|
+
"hasDynamicHelp": false,
|
|
990
|
+
"multiple": false,
|
|
991
|
+
"type": "option"
|
|
920
992
|
}
|
|
921
993
|
},
|
|
922
994
|
"hasDynamicHelp": false,
|
|
923
995
|
"hiddenAliases": [],
|
|
924
|
-
"id": "
|
|
996
|
+
"id": "providers:connect",
|
|
925
997
|
"pluginAlias": "byterover-cli",
|
|
926
998
|
"pluginName": "byterover-cli",
|
|
927
999
|
"pluginType": "core",
|
|
@@ -932,17 +1004,23 @@
|
|
|
932
1004
|
"dist",
|
|
933
1005
|
"oclif",
|
|
934
1006
|
"commands",
|
|
935
|
-
"
|
|
936
|
-
"
|
|
1007
|
+
"providers",
|
|
1008
|
+
"connect.js"
|
|
937
1009
|
]
|
|
938
1010
|
},
|
|
939
|
-
"
|
|
1011
|
+
"providers:disconnect": {
|
|
940
1012
|
"aliases": [],
|
|
941
|
-
"args": {
|
|
942
|
-
|
|
1013
|
+
"args": {
|
|
1014
|
+
"provider": {
|
|
1015
|
+
"description": "Provider ID to disconnect",
|
|
1016
|
+
"name": "provider",
|
|
1017
|
+
"required": true
|
|
1018
|
+
}
|
|
1019
|
+
},
|
|
1020
|
+
"description": "Disconnect an LLM provider",
|
|
943
1021
|
"examples": [
|
|
944
|
-
"<%= config.bin %>
|
|
945
|
-
"<%= config.bin %>
|
|
1022
|
+
"<%= config.bin %> providers disconnect anthropic",
|
|
1023
|
+
"<%= config.bin %> providers disconnect openai --format json"
|
|
946
1024
|
],
|
|
947
1025
|
"flags": {
|
|
948
1026
|
"format": {
|
|
@@ -956,19 +1034,11 @@
|
|
|
956
1034
|
"json"
|
|
957
1035
|
],
|
|
958
1036
|
"type": "option"
|
|
959
|
-
},
|
|
960
|
-
"provider": {
|
|
961
|
-
"char": "p",
|
|
962
|
-
"description": "Only list models for a specific provider",
|
|
963
|
-
"name": "provider",
|
|
964
|
-
"hasDynamicHelp": false,
|
|
965
|
-
"multiple": false,
|
|
966
|
-
"type": "option"
|
|
967
1037
|
}
|
|
968
1038
|
},
|
|
969
1039
|
"hasDynamicHelp": false,
|
|
970
1040
|
"hiddenAliases": [],
|
|
971
|
-
"id": "
|
|
1041
|
+
"id": "providers:disconnect",
|
|
972
1042
|
"pluginAlias": "byterover-cli",
|
|
973
1043
|
"pluginName": "byterover-cli",
|
|
974
1044
|
"pluginType": "core",
|
|
@@ -979,24 +1049,17 @@
|
|
|
979
1049
|
"dist",
|
|
980
1050
|
"oclif",
|
|
981
1051
|
"commands",
|
|
982
|
-
"
|
|
983
|
-
"
|
|
1052
|
+
"providers",
|
|
1053
|
+
"disconnect.js"
|
|
984
1054
|
]
|
|
985
1055
|
},
|
|
986
|
-
"
|
|
1056
|
+
"providers": {
|
|
987
1057
|
"aliases": [],
|
|
988
|
-
"args": {
|
|
989
|
-
|
|
990
|
-
"description": "Model ID to switch to (e.g., claude-sonnet-4-5, gpt-4.1)",
|
|
991
|
-
"name": "model",
|
|
992
|
-
"required": true
|
|
993
|
-
}
|
|
994
|
-
},
|
|
995
|
-
"description": "Switch the active model",
|
|
1058
|
+
"args": {},
|
|
1059
|
+
"description": "Show active provider and model",
|
|
996
1060
|
"examples": [
|
|
997
|
-
"<%= config.bin %>
|
|
998
|
-
"<%= config.bin %>
|
|
999
|
-
"<%= config.bin %> model switch claude-sonnet-4-5 --format json"
|
|
1061
|
+
"<%= config.bin %> providers",
|
|
1062
|
+
"<%= config.bin %> providers --format json"
|
|
1000
1063
|
],
|
|
1001
1064
|
"flags": {
|
|
1002
1065
|
"format": {
|
|
@@ -1010,19 +1073,11 @@
|
|
|
1010
1073
|
"json"
|
|
1011
1074
|
],
|
|
1012
1075
|
"type": "option"
|
|
1013
|
-
},
|
|
1014
|
-
"provider": {
|
|
1015
|
-
"char": "p",
|
|
1016
|
-
"description": "Provider ID (defaults to active provider)",
|
|
1017
|
-
"name": "provider",
|
|
1018
|
-
"hasDynamicHelp": false,
|
|
1019
|
-
"multiple": false,
|
|
1020
|
-
"type": "option"
|
|
1021
1076
|
}
|
|
1022
1077
|
},
|
|
1023
1078
|
"hasDynamicHelp": false,
|
|
1024
1079
|
"hiddenAliases": [],
|
|
1025
|
-
"id": "
|
|
1080
|
+
"id": "providers",
|
|
1026
1081
|
"pluginAlias": "byterover-cli",
|
|
1027
1082
|
"pluginName": "byterover-cli",
|
|
1028
1083
|
"pluginType": "core",
|
|
@@ -1033,44 +1088,19 @@
|
|
|
1033
1088
|
"dist",
|
|
1034
1089
|
"oclif",
|
|
1035
1090
|
"commands",
|
|
1036
|
-
"
|
|
1037
|
-
"
|
|
1091
|
+
"providers",
|
|
1092
|
+
"index.js"
|
|
1038
1093
|
]
|
|
1039
1094
|
},
|
|
1040
|
-
"providers:
|
|
1095
|
+
"providers:list": {
|
|
1041
1096
|
"aliases": [],
|
|
1042
|
-
"args": {
|
|
1043
|
-
|
|
1044
|
-
"description": "Provider ID to connect (e.g., anthropic, openai, openrouter)",
|
|
1045
|
-
"name": "provider",
|
|
1046
|
-
"required": true
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
"description": "Connect or switch to an LLM provider",
|
|
1097
|
+
"args": {},
|
|
1098
|
+
"description": "List all available providers and their connection status",
|
|
1050
1099
|
"examples": [
|
|
1051
|
-
"<%= config.bin %> providers
|
|
1052
|
-
"<%= config.bin %> providers
|
|
1053
|
-
"<%= config.bin %> providers connect byterover",
|
|
1054
|
-
"<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1",
|
|
1055
|
-
"<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1 --api-key sk-xxx --model llama3"
|
|
1100
|
+
"<%= config.bin %> providers list",
|
|
1101
|
+
"<%= config.bin %> providers list --format json"
|
|
1056
1102
|
],
|
|
1057
1103
|
"flags": {
|
|
1058
|
-
"api-key": {
|
|
1059
|
-
"char": "k",
|
|
1060
|
-
"description": "API key for the provider",
|
|
1061
|
-
"name": "api-key",
|
|
1062
|
-
"hasDynamicHelp": false,
|
|
1063
|
-
"multiple": false,
|
|
1064
|
-
"type": "option"
|
|
1065
|
-
},
|
|
1066
|
-
"base-url": {
|
|
1067
|
-
"char": "b",
|
|
1068
|
-
"description": "Base URL for OpenAI-compatible providers (e.g., http://localhost:11434/v1)",
|
|
1069
|
-
"name": "base-url",
|
|
1070
|
-
"hasDynamicHelp": false,
|
|
1071
|
-
"multiple": false,
|
|
1072
|
-
"type": "option"
|
|
1073
|
-
},
|
|
1074
1104
|
"format": {
|
|
1075
1105
|
"description": "Output format (text or json)",
|
|
1076
1106
|
"name": "format",
|
|
@@ -1082,19 +1112,11 @@
|
|
|
1082
1112
|
"json"
|
|
1083
1113
|
],
|
|
1084
1114
|
"type": "option"
|
|
1085
|
-
},
|
|
1086
|
-
"model": {
|
|
1087
|
-
"char": "m",
|
|
1088
|
-
"description": "Model to set as active after connecting",
|
|
1089
|
-
"name": "model",
|
|
1090
|
-
"hasDynamicHelp": false,
|
|
1091
|
-
"multiple": false,
|
|
1092
|
-
"type": "option"
|
|
1093
1115
|
}
|
|
1094
1116
|
},
|
|
1095
1117
|
"hasDynamicHelp": false,
|
|
1096
1118
|
"hiddenAliases": [],
|
|
1097
|
-
"id": "providers:
|
|
1119
|
+
"id": "providers:list",
|
|
1098
1120
|
"pluginAlias": "byterover-cli",
|
|
1099
1121
|
"pluginName": "byterover-cli",
|
|
1100
1122
|
"pluginType": "core",
|
|
@@ -1106,22 +1128,22 @@
|
|
|
1106
1128
|
"oclif",
|
|
1107
1129
|
"commands",
|
|
1108
1130
|
"providers",
|
|
1109
|
-
"
|
|
1131
|
+
"list.js"
|
|
1110
1132
|
]
|
|
1111
1133
|
},
|
|
1112
|
-
"providers:
|
|
1134
|
+
"providers:switch": {
|
|
1113
1135
|
"aliases": [],
|
|
1114
1136
|
"args": {
|
|
1115
1137
|
"provider": {
|
|
1116
|
-
"description": "Provider ID to
|
|
1138
|
+
"description": "Provider ID to switch to (e.g., anthropic, openai)",
|
|
1117
1139
|
"name": "provider",
|
|
1118
1140
|
"required": true
|
|
1119
1141
|
}
|
|
1120
1142
|
},
|
|
1121
|
-
"description": "
|
|
1143
|
+
"description": "Switch the active provider",
|
|
1122
1144
|
"examples": [
|
|
1123
|
-
"<%= config.bin %> providers
|
|
1124
|
-
"<%= config.bin %> providers
|
|
1145
|
+
"<%= config.bin %> providers switch anthropic",
|
|
1146
|
+
"<%= config.bin %> providers switch openai --format json"
|
|
1125
1147
|
],
|
|
1126
1148
|
"flags": {
|
|
1127
1149
|
"format": {
|
|
@@ -1139,7 +1161,7 @@
|
|
|
1139
1161
|
},
|
|
1140
1162
|
"hasDynamicHelp": false,
|
|
1141
1163
|
"hiddenAliases": [],
|
|
1142
|
-
"id": "providers:
|
|
1164
|
+
"id": "providers:switch",
|
|
1143
1165
|
"pluginAlias": "byterover-cli",
|
|
1144
1166
|
"pluginName": "byterover-cli",
|
|
1145
1167
|
"pluginType": "core",
|
|
@@ -1151,16 +1173,16 @@
|
|
|
1151
1173
|
"oclif",
|
|
1152
1174
|
"commands",
|
|
1153
1175
|
"providers",
|
|
1154
|
-
"
|
|
1176
|
+
"switch.js"
|
|
1155
1177
|
]
|
|
1156
1178
|
},
|
|
1157
|
-
"
|
|
1179
|
+
"model": {
|
|
1158
1180
|
"aliases": [],
|
|
1159
1181
|
"args": {},
|
|
1160
|
-
"description": "Show active
|
|
1182
|
+
"description": "Show the active model",
|
|
1161
1183
|
"examples": [
|
|
1162
|
-
"<%= config.bin %>
|
|
1163
|
-
"<%= config.bin %>
|
|
1184
|
+
"<%= config.bin %> model",
|
|
1185
|
+
"<%= config.bin %> model --format json"
|
|
1164
1186
|
],
|
|
1165
1187
|
"flags": {
|
|
1166
1188
|
"format": {
|
|
@@ -1178,7 +1200,7 @@
|
|
|
1178
1200
|
},
|
|
1179
1201
|
"hasDynamicHelp": false,
|
|
1180
1202
|
"hiddenAliases": [],
|
|
1181
|
-
"id": "
|
|
1203
|
+
"id": "model",
|
|
1182
1204
|
"pluginAlias": "byterover-cli",
|
|
1183
1205
|
"pluginName": "byterover-cli",
|
|
1184
1206
|
"pluginType": "core",
|
|
@@ -1189,17 +1211,17 @@
|
|
|
1189
1211
|
"dist",
|
|
1190
1212
|
"oclif",
|
|
1191
1213
|
"commands",
|
|
1192
|
-
"
|
|
1214
|
+
"model",
|
|
1193
1215
|
"index.js"
|
|
1194
1216
|
]
|
|
1195
1217
|
},
|
|
1196
|
-
"
|
|
1218
|
+
"model:list": {
|
|
1197
1219
|
"aliases": [],
|
|
1198
1220
|
"args": {},
|
|
1199
|
-
"description": "List
|
|
1221
|
+
"description": "List available models from all connected providers",
|
|
1200
1222
|
"examples": [
|
|
1201
|
-
"<%= config.bin %>
|
|
1202
|
-
"<%= config.bin %>
|
|
1223
|
+
"<%= config.bin %> model list",
|
|
1224
|
+
"<%= config.bin %> model list --format json"
|
|
1203
1225
|
],
|
|
1204
1226
|
"flags": {
|
|
1205
1227
|
"format": {
|
|
@@ -1213,11 +1235,19 @@
|
|
|
1213
1235
|
"json"
|
|
1214
1236
|
],
|
|
1215
1237
|
"type": "option"
|
|
1238
|
+
},
|
|
1239
|
+
"provider": {
|
|
1240
|
+
"char": "p",
|
|
1241
|
+
"description": "Only list models for a specific provider",
|
|
1242
|
+
"name": "provider",
|
|
1243
|
+
"hasDynamicHelp": false,
|
|
1244
|
+
"multiple": false,
|
|
1245
|
+
"type": "option"
|
|
1216
1246
|
}
|
|
1217
1247
|
},
|
|
1218
1248
|
"hasDynamicHelp": false,
|
|
1219
1249
|
"hiddenAliases": [],
|
|
1220
|
-
"id": "
|
|
1250
|
+
"id": "model:list",
|
|
1221
1251
|
"pluginAlias": "byterover-cli",
|
|
1222
1252
|
"pluginName": "byterover-cli",
|
|
1223
1253
|
"pluginType": "core",
|
|
@@ -1228,23 +1258,24 @@
|
|
|
1228
1258
|
"dist",
|
|
1229
1259
|
"oclif",
|
|
1230
1260
|
"commands",
|
|
1231
|
-
"
|
|
1261
|
+
"model",
|
|
1232
1262
|
"list.js"
|
|
1233
1263
|
]
|
|
1234
1264
|
},
|
|
1235
|
-
"
|
|
1265
|
+
"model:switch": {
|
|
1236
1266
|
"aliases": [],
|
|
1237
1267
|
"args": {
|
|
1238
|
-
"
|
|
1239
|
-
"description": "
|
|
1240
|
-
"name": "
|
|
1268
|
+
"model": {
|
|
1269
|
+
"description": "Model ID to switch to (e.g., claude-sonnet-4-5, gpt-4.1)",
|
|
1270
|
+
"name": "model",
|
|
1241
1271
|
"required": true
|
|
1242
1272
|
}
|
|
1243
1273
|
},
|
|
1244
|
-
"description": "Switch the active
|
|
1274
|
+
"description": "Switch the active model",
|
|
1245
1275
|
"examples": [
|
|
1246
|
-
"<%= config.bin %>
|
|
1247
|
-
"<%= config.bin %>
|
|
1276
|
+
"<%= config.bin %> model switch claude-sonnet-4-5",
|
|
1277
|
+
"<%= config.bin %> model switch gpt-4.1 --provider openai",
|
|
1278
|
+
"<%= config.bin %> model switch claude-sonnet-4-5 --format json"
|
|
1248
1279
|
],
|
|
1249
1280
|
"flags": {
|
|
1250
1281
|
"format": {
|
|
@@ -1258,11 +1289,19 @@
|
|
|
1258
1289
|
"json"
|
|
1259
1290
|
],
|
|
1260
1291
|
"type": "option"
|
|
1292
|
+
},
|
|
1293
|
+
"provider": {
|
|
1294
|
+
"char": "p",
|
|
1295
|
+
"description": "Provider ID (defaults to active provider)",
|
|
1296
|
+
"name": "provider",
|
|
1297
|
+
"hasDynamicHelp": false,
|
|
1298
|
+
"multiple": false,
|
|
1299
|
+
"type": "option"
|
|
1261
1300
|
}
|
|
1262
1301
|
},
|
|
1263
1302
|
"hasDynamicHelp": false,
|
|
1264
1303
|
"hiddenAliases": [],
|
|
1265
|
-
"id": "
|
|
1304
|
+
"id": "model:switch",
|
|
1266
1305
|
"pluginAlias": "byterover-cli",
|
|
1267
1306
|
"pluginName": "byterover-cli",
|
|
1268
1307
|
"pluginType": "core",
|
|
@@ -1273,7 +1312,7 @@
|
|
|
1273
1312
|
"dist",
|
|
1274
1313
|
"oclif",
|
|
1275
1314
|
"commands",
|
|
1276
|
-
"
|
|
1315
|
+
"model",
|
|
1277
1316
|
"switch.js"
|
|
1278
1317
|
]
|
|
1279
1318
|
},
|
|
@@ -1574,5 +1613,5 @@
|
|
|
1574
1613
|
]
|
|
1575
1614
|
}
|
|
1576
1615
|
},
|
|
1577
|
-
"version": "2.
|
|
1616
|
+
"version": "2.2.0"
|
|
1578
1617
|
}
|