mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-30 06:12:05 +00:00
chore: apply requested changes
This commit is contained in:
@@ -7,7 +7,8 @@ import {
|
||||
OAuthFlowOptions,
|
||||
AuthenticationError,
|
||||
AuthConfig,
|
||||
UserContext
|
||||
UserContext,
|
||||
UserContextWithBrief
|
||||
} from '../types.js';
|
||||
import { ContextStore } from '../services/context-store.js';
|
||||
import { OAuthService } from '../services/oauth-service.js';
|
||||
@@ -18,6 +19,10 @@ import {
|
||||
type Brief,
|
||||
type RemoteTask
|
||||
} from '../services/organization.service.js';
|
||||
import {
|
||||
ERROR_CODES,
|
||||
TaskMasterError
|
||||
} from '../../../common/errors/task-master-error.js';
|
||||
import { getLogger } from '../../../common/logger/index.js';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
@@ -430,4 +435,28 @@ export class AuthManager {
|
||||
const service = await this.getOrganizationService();
|
||||
return service.getTasks(briefId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a brief is selected in the current context
|
||||
* Throws a TaskMasterError if no brief is selected
|
||||
* @param operation - The operation name for error context
|
||||
* @returns The current user context with a guaranteed briefId
|
||||
*/
|
||||
ensureBriefSelected(operation: string): UserContextWithBrief {
|
||||
const context = this.getContext();
|
||||
|
||||
if (!context?.briefId) {
|
||||
throw new TaskMasterError(
|
||||
'No brief selected',
|
||||
ERROR_CODES.NO_BRIEF_SELECTED,
|
||||
{
|
||||
operation,
|
||||
userMessage:
|
||||
'No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return context as UserContextWithBrief;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ export interface UserContext {
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* User context with a guaranteed briefId
|
||||
*/
|
||||
export type UserContextWithBrief = UserContext & { briefId: string };
|
||||
|
||||
export interface OAuthFlowOptions {
|
||||
/** Callback to open the browser with the auth URL. If not provided, browser won't be opened */
|
||||
openBrowser?: (url: string) => Promise<void>;
|
||||
|
||||
@@ -53,13 +53,6 @@ export interface ExpandTaskOptions {
|
||||
force?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth context with a guaranteed briefId
|
||||
*/
|
||||
type ContextWithBrief = NonNullable<
|
||||
ReturnType<typeof AuthManager.prototype.getContext>
|
||||
> & { briefId: string };
|
||||
|
||||
/**
|
||||
* TaskExpansionService handles AI-powered task expansion
|
||||
*/
|
||||
@@ -93,7 +86,7 @@ export class TaskExpansionService {
|
||||
): Promise<ExpandTaskResult> {
|
||||
try {
|
||||
// Get brief context from AuthManager
|
||||
const context = this.ensureBriefSelected('expandTask');
|
||||
const context = this.authManager.ensureBriefSelected('expandTask');
|
||||
|
||||
// Get the task being expanded to extract existing subtasks
|
||||
const task = await this.repository.getTask(this.projectId, taskId);
|
||||
@@ -101,7 +94,7 @@ export class TaskExpansionService {
|
||||
if (!task) {
|
||||
throw new TaskMasterError(
|
||||
`Task ${taskId} not found`,
|
||||
ERROR_CODES.VALIDATION_ERROR,
|
||||
ERROR_CODES.TASK_NOT_FOUND,
|
||||
{
|
||||
operation: 'expandTask',
|
||||
taskId,
|
||||
@@ -230,26 +223,4 @@ export class TaskExpansionService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a brief is selected in the current context
|
||||
* @returns The current auth context with a valid briefId
|
||||
*/
|
||||
private ensureBriefSelected(operation: string): ContextWithBrief {
|
||||
const context = this.authManager.getContext();
|
||||
|
||||
if (!context?.briefId) {
|
||||
throw new TaskMasterError(
|
||||
'No brief selected',
|
||||
ERROR_CODES.NO_BRIEF_SELECTED,
|
||||
{
|
||||
operation,
|
||||
userMessage:
|
||||
'No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return context as ContextWithBrief;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,6 @@ interface GetTaskResponse {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth context with a guaranteed briefId
|
||||
*/
|
||||
type ContextWithBrief = NonNullable<
|
||||
ReturnType<typeof AuthManager.prototype.getContext>
|
||||
> & { briefId: string };
|
||||
|
||||
/**
|
||||
* TaskRetrievalService handles fetching tasks with enriched document content
|
||||
* Uses repository for task structure and API endpoint for document content
|
||||
@@ -65,14 +58,14 @@ export class TaskRetrievalService {
|
||||
*/
|
||||
async getTask(taskId: string): Promise<Task | null> {
|
||||
try {
|
||||
this.ensureBriefSelected('getTask');
|
||||
this.authManager.ensureBriefSelected('getTask');
|
||||
|
||||
const task = await this.repository.getTask(this.projectId, taskId);
|
||||
|
||||
if (!task) {
|
||||
throw new TaskMasterError(
|
||||
`Task ${taskId} not found`,
|
||||
ERROR_CODES.VALIDATION_ERROR,
|
||||
ERROR_CODES.TASK_NOT_FOUND,
|
||||
{
|
||||
operation: 'getTask',
|
||||
taskId,
|
||||
@@ -127,26 +120,4 @@ export class TaskRetrievalService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a brief is selected in the current context
|
||||
* @returns The current auth context with a valid briefId
|
||||
*/
|
||||
private ensureBriefSelected(operation: string): ContextWithBrief {
|
||||
const context = this.authManager.getContext();
|
||||
|
||||
if (!context?.briefId) {
|
||||
throw new TaskMasterError(
|
||||
'No brief selected',
|
||||
ERROR_CODES.NO_BRIEF_SELECTED,
|
||||
{
|
||||
operation,
|
||||
userMessage:
|
||||
'No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return context as ContextWithBrief;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,13 +47,6 @@ export interface ApiStorageConfig {
|
||||
maxRetries?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth context with a guaranteed briefId
|
||||
*/
|
||||
type ContextWithBrief = NonNullable<
|
||||
ReturnType<typeof AuthManager.prototype.getContext>
|
||||
> & { briefId: string };
|
||||
|
||||
/**
|
||||
* Response from the update task with prompt API endpoint
|
||||
*/
|
||||
@@ -205,7 +198,8 @@ export class ApiStorage implements IStorage {
|
||||
await this.ensureInitialized();
|
||||
|
||||
try {
|
||||
const context = this.ensureBriefSelected('loadTasks');
|
||||
const context =
|
||||
AuthManager.getInstance().ensureBriefSelected('loadTasks');
|
||||
|
||||
// Load tasks from the current brief context with filters pushed to repository
|
||||
const tasks = await this.retryOperation(() =>
|
||||
@@ -276,7 +270,7 @@ export class ApiStorage implements IStorage {
|
||||
|
||||
try {
|
||||
const retrievalService = this.getRetrievalService();
|
||||
return retrievalService.getTask(taskId);
|
||||
return await this.retryOperation(() => retrievalService.getTask(taskId));
|
||||
} catch (error) {
|
||||
this.wrapError(error, 'Failed to load task from API', {
|
||||
operation: 'loadTask',
|
||||
@@ -636,7 +630,7 @@ export class ApiStorage implements IStorage {
|
||||
await this.ensureInitialized();
|
||||
|
||||
try {
|
||||
this.ensureBriefSelected('updateTaskStatus');
|
||||
AuthManager.getInstance().ensureBriefSelected('updateTaskStatus');
|
||||
|
||||
const existingTask = await this.retryOperation(() =>
|
||||
this.repository.getTask(this.projectId, taskId)
|
||||
@@ -897,29 +891,6 @@ export class ApiStorage implements IStorage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a brief is selected in the current context
|
||||
* @returns The current auth context with a valid briefId
|
||||
*/
|
||||
private ensureBriefSelected(operation: string): ContextWithBrief {
|
||||
const authManager = AuthManager.getInstance();
|
||||
const context = authManager.getContext();
|
||||
|
||||
if (!context?.briefId) {
|
||||
throw new TaskMasterError(
|
||||
'No brief selected',
|
||||
ERROR_CODES.NO_BRIEF_SELECTED,
|
||||
{
|
||||
operation,
|
||||
userMessage:
|
||||
'No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return context as ContextWithBrief;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create API client instance with auth
|
||||
*/
|
||||
@@ -936,7 +907,8 @@ export class ApiStorage implements IStorage {
|
||||
);
|
||||
}
|
||||
|
||||
const context = this.ensureBriefSelected('getApiClient');
|
||||
const context =
|
||||
AuthManager.getInstance().ensureBriefSelected('getApiClient');
|
||||
const authManager = AuthManager.getInstance();
|
||||
|
||||
this.apiClient = new ApiClient({
|
||||
|
||||
Reference in New Issue
Block a user