A fast, minimal CLI project task manager for efficient task and project management

This project is based on AddressBook-Level3 (AB3) from the SE-EDU initiative. We adapted its architecture, parser logic, and command execution framework.
We also acknowledge:
FlowCLI follows a layered architecture with clear separation of concerns:

Component Relationships:
The diagram shows the main components and their relationships:
Note: The multiplicity notation “1” → “” indicates a one-to-many relationship in UML. For example, one ProjectList can contain zero or more Projects, and one Project can contain zero or more Tasks.*
Key Design Principles:
The command processing infrastructure forms the foundation of FlowCLI, handling all user input parsing, validation, and command execution. It consists of three key components that work together to transform user input into executable commands.
Key Components:

Implementation Details:
Note: The sequence diagram shows constructor calls only for objects created during the command processing flow (Command and ArgumentParser). Pre-existing components (FlowCLI, CommandHandler, CommandParser, CommandFactory, ConsoleUi) are created during application initialization and persist throughout the session.
Design Rationale:
Example Flow:
User input: "add-task 1 Fix bug --priority high"
↓
CommandParser: type=ADD_TASK, args="1 Fix bug --priority high"
↓
ArgumentParser: projectIndex=1 → resolves to Project("CS2113T"), remaining="Fix bug --priority high"
↓
AddCommand: validates and adds task to project
↓
ConsoleUi: displays confirmation
Input validation is centralized to ensure consistent rules, clear error messages, and early failure before any state mutation.
Key Components:
CommandValidator - Static utility methods for validating command parameters (priorities, dates, filter/sort options, command syntax)ValidationConstants - Canonical constants for valid values (priorities, filter types, sort fields/orders, keywords)CommandValidator Methods:
validatePriority(String) - Validates and normalizes priority (low, medium, high, case-insensitive), throws InvalidArgumentException on failurepriorityToInt(String) - Converts validated priority string to integer (1=low, 2=medium, 3=high); use after validatePriority()validateAndParseDate(String) - Validates date format (yyyy-MM-dd) and returns LocalDate, throws InvalidDateException on failurevalidateFilterType(String) - Validates filter type (currently only priority), throws InvalidArgumentException on failurevalidateSortField(String) - Validates sort field (deadline or priority), throws InvalidArgumentException on failurevalidateSortOrder(String) - Validates sort order (ascending or descending), throws InvalidArgumentException on failurevalidateFilterCommand(String[], int) - Validates filter command syntax completeness, throws InvalidCommandSyntaxException on failurevalidateSortCommand(String[], int) - Validates sort command syntax completeness, throws InvalidCommandSyntaxException on failureValidationConstants Values:
PRIORITY_LOW, PRIORITY_MEDIUM, PRIORITY_HIGH (string values)PRIORITY_LOW_VALUE = 1, PRIORITY_MEDIUM_VALUE = 2, PRIORITY_HIGH_VALUE = 3FILTER_TYPE_PRIORITYSORT_FIELD_DEADLINE, SORT_FIELD_PRIORITYSORT_ORDER_ASCENDING, SORT_ORDER_DESCENDINGKEYWORD_BY, KEYWORD_FILTER, KEYWORD_SORTParser Integration:
CommandParser.parseIndexOrNull(String indexText, int maxIndex)
MissingIndexException (if indexText is null), InvalidIndexFormatException (if not numeric), IndexOutOfRangeException (if out of range)ArgumentParser.validateProjectIndex()
ArgumentParser construction to validate parsed project indexMissingArgumentException, InvalidIndexFormatException, IndexOutOfRangeException, InvalidArgumentExceptionUsage Example:
// Typical validation pattern in commands (e.g., AddCommand, UpdateCommand)
ArgumentParser parsedArgument = new ArgumentParser(arguments, context.getProjects());
parsedArgument.validateProjectIndex(); // Validate project index first
Project targetProject = parsedArgument.getTargetProject();
String remaining = parsedArgument.getRemainingArgument();
if (remaining == null || remaining.trim().isEmpty()) {
throw new MissingDescriptionException(); // Validate required fields
}
// Validate and convert priority
String validatedPriority = CommandValidator.validatePriority(priorityStr);
int priority = CommandValidator.priorityToInt(validatedPriority);
// Validate and parse date
LocalDate deadline = CommandValidator.validateAndParseDate(dateStr);
Extra Parameter Validation:
Commands that don’t accept parameters (e.g., bye, help, status, list) check for extra arguments using ArgumentParser.getRemainingArgument() and throw ExtraArgumentException:
String remaining = parsedArgument.getRemainingArgument();
if (remaining != null && !remaining.trim().isEmpty()) {
throw new ExtraArgumentException("Unexpected extra parameters: " + remaining);
}
Exception Types:
MissingArgumentException - Required argument is missingExtraArgumentException - Unexpected extra parameters providedMissingIndexException - Required index argument is missingMissingDescriptionException - Required description/field is missing or emptyInvalidIndexFormatException - Index cannot be parsed as integerIndexOutOfRangeException - Index is out of valid rangeInvalidArgumentException - Argument format/value is invalid (e.g., invalid priority, filter type, sort field)InvalidDateException - Date format is invalid (expects yyyy-MM-dd)InvalidFilenameException - Filename format is invalidInvalidCommandSyntaxException - Command syntax is malformed or incompleteValidation Flow:
The following sequence diagram illustrates the validation process, showing both success and exception paths:

The validation flow operates in 3 main layers:
ArgumentParser.validateProjectIndex() validates project index format and range (throws MissingArgumentException, IndexOutOfRangeException, InvalidIndexFormatException) - always executed firstCommandParser.parseIndexOrNull() validates task index format and range (throws MissingIndexException, InvalidIndexFormatException, IndexOutOfRangeException) - only for commands that need task indices (Mark, Update, DeleteTask, Unmark)CommandValidator methods for domain-specific validation (priorities, dates, filters, sort options) which reference ValidationConstants for valid valuesAll exceptions propagate to CommandHandler, which catches FlowCLIException and displays user-friendly messages via ConsoleUi.
Pre-execution validation: All validation occurs before model mutation to preserve data integrity.
Best Practices:
ArgumentParser.validateProjectIndex() before accessing project datavalidatePriority() followed by priorityToInt() to normalize and convert prioritiesThe task management system forms the core of FlowCLI, allowing users to create, track, and manage their work within different projects. The implementation follows the command pattern, where each user action is encapsulated in a dedicated command class.
add-task commandThe add-task command allows users to add a new task to a specified project. Users can provide a task description, an optional deadline, and an optional priority.
Command format: add-task <projectIndex> <description> [--priority <level>] [--deadline <YYYY-MM-DD>]
Example: add-task 2 "Draft project charter" --priority high --deadline 2025-02-15
Typical use cases:
The following sequence diagram illustrates the process of adding a task:

Implementation Details:
CommandParser identifies the add-task command and creates an AddCommand object.AddCommand#execute() is called.Project object and calls project.addTask() to create and add the new task.ConsoleUi then displays a confirmation message to the user.delete-task commandThe delete-task command is used to remove a task from a project. It requires the project index and the 1-based index of the task to be deleted.
Command format: delete-task <projectIndex> <taskIndex>
Example: delete-task 3 5
Typical use cases:
The sequence diagram below shows the workflow:

Implementation Details:
CommandParser creates a DeleteTaskCommand object.DeleteTaskCommand#execute() validates the presence of the project index and task index.project.deleteTask() to remove the task from the project’s TaskList.mark and unmark commandsThese commands allow users to change the completion status of a task.
mark: Marks a task as done.unmark: Marks a task as not done.Command format:
mark <projectIndex> <taskIndex>unmark <projectIndex> <taskIndex>Examples:
mark 1 4 — mark the fourth task in project 1 as completed once QA signs off.unmark 2 1 — reopen the first task in project 2 when new changes are requested.Typical use cases:
The process is illustrated in the following diagram:

Implementation Details:
MarkCommand or UnmarkCommand is instantiated by the parser.execute() method validates the project and task index.Task object and calls its mark() or unmark() method.update-task commandThe update-task command modifies the attributes of an existing task, such as its description, deadline, or priority.
Command format: update-task <projectIndex> <taskIndex> [--description <desc>] [--deadline <YYYY-MM-DD|none>] [--priority <level>]
Examples:
update-task 1 3 --deadline 2025-03-10 --priority mediumupdate-task 4 2 --description "Align scope with Design team"Typical use cases:
The update process is shown below:

Implementation Details:
UpdateCommand is responsible for parsing the various optional flags that specify which fields to update.project.updateTask(), passing the new values. The updateTask method handles the logic of only changing the fields that were provided in the command.list commandThe list command displays tasks. It can either list all tasks in all projects or list the tasks of a specific project.
Command format: list --all or list <projectIndex>
Examples:
list --all — review every project before the weekly sync.list 2 — focus on outstanding work for project 2 while planning the day.Typical use cases:
The diagram below illustrates the listing process:

Implementation Details:
ListCommand checks if a project index or --all flag was provided.MissingArgumentException)--all flag, validates project list is not empty (throws EmptyProjectListException)list 1 extra throws exception)ConsoleUi to display only the tasks for that project.--all flag is given, it iterates through the entire ProjectList and instructs the ConsoleUi to display all projects and their associated tasks.The Create-project command is facilitated by ProjectListand it is accessed by CommandContext. It extends Command with the feature of reading the user’s project name input and creating a project entity.
Additionally , it implements the following operations:
ProjectList#getProject(String name) - returns the project if it exists, or null if not found.ProjectList#addProject(String name) - adds a new project with the given name.ConsoleUi#showAddedProject() - notifies the user after successful creation.CommandContext#getProjects() - returns all the projects currently in the ProjectListGiven below is an example usage scenario and how the create-project feature behaves at each step
User Input: The user enters the create-project command with the project name (e.g., create-project Alpha).
Parsing: The CommandParser identifies the command as create-project and constructs a CreateCommand with the raw arguments.
Execution: The FlowCLI main loop invokes CreateCommand#execute(CommandContext). (Note: CreateCommand extends Command.)
Argument Parsing: Inside execute, CreateCommand extracts the project name from the arguments
Validation: The command validates that the name is non-blank; if blank, it throws MissingArgumentException. It then checks duplicates via context.getProjects().getProject(name) if present, it throws ProjectAlreadyExistsException.
Creating the Project: On success, the command calls context.getProjects().addProject(name) to persist the new project in the model.
UI Feedback: The command obtains the UI via context.getUi() and calls showAddedProject() (or the equivalent success method) to confirm creation to the user.
Return/Logging: The command returns true to signal success and logs at info/fine levels; failures log at warning and do not mutate the model.
Here is a sequence diagram illustrating the process:

The core data model of FlowCLI consists of four fundamental classes that represent the domain entities and their relationships. These classes form the foundation upon which all features are built.

Class Relationships:
This hierarchical structure allows for organized task management within distinct projects, with clear ownership and encapsulation of responsibilities.
Represents a single project and encapsulates its name and task collection TaskList. Allows for adding/updatig/deleting tasks within a project without directly coordinating multiple lower-level classes.
projectName is non null and should be non-blank when constructed
projectTasks is non null after construction
TaskList and Task (for managing per-project tasks).-ProjectList (container) creates and returns Project instances.
Project(String projectName) — Constructor that constructs an empty project with the given name.String getProjectName() — returns the name of the project.TaskList getProjectTasks() — returns the tasks in that projectvoid addTask(String description) — adds a task.void addTask(String description, LocalDate deadline, int priority) — add a task with deadline and priorityTask deleteTask(int index) — remove and return the task at index.Task updateTask(int index, String newDescription, boolean updateDescription, LocalDate newDeadline, boolean updateDeadline, Integer newPriority, boolean updatePriority) — Updates the task description , deadline and priorityString showAllTasks() — render the project’s tasks to a printable string (delegates to TaskList.render()).String toString() — printable representation of the project header + rendered tasks.An ArrayList container of Project instances offering indexed access, name-lookup, and simple rendering. This is the central point for commands to manipuate the collection of projects (e.g., create-project, delete-project, list-projects).
projects is non null after construction
Project - element sotred in the list.void addProject(String projectName) — appends a new Project.Project delete(int zeroBasedIndex) — delete by index, return the removed Project for confirmation.Project deleteProject(Project project) — remove by identity and returns the removed projectProject getProjectByIndex(int zeroBasedIndex) — indexed accessor.List<Project> getProjectList() — list the projects by name currently in the listint getProjectListSize() — returns the number of projects.Project getProject(String projectName) — returns the project via name-based lookupString render() — concatenate each project’s toString() into a printable block.The sorting algorithm supports sorting tasks by deadline or priority in ascending/descending order:

Algorithm Details:
The filtering algorithm supports filtering tasks by priority level and/or project name:

Algorithm Details:
The export algorithm supports saving project and task data to text files with filtering and sorting capabilities:

Key Components:
Design Principles:
The following sequence diagram illustrates the export workflow:

Utility class providing static methods to collect tasks from projects while preserving project association:
getAllTasksWithProjects(ProjectList projects) - Returns List<TaskWithProject> of all tasks from all projects (O(n) time/space)getTasksFromProject(Project project) - Returns List<TaskWithProject> of tasks from a specific project (O(m) time/space)Each task is wrapped in TaskWithProject, which formats as "ProjectName: [X] Task Description (Due: YYYY-MM-DD) [priority]". The class is reusable across filtering, sorting, and listing operations.
Utility class that writes tasks to text files with comprehensive error handling:
Method: exportTasksToFile(List<TaskWithProject> tasks, String filename, String header) throws FileWriteException
File Format:
<Header Text>
================
ProjectName: [X] Task Description (Due: YYYY-MM-DD) [priority]
ProjectName: [ ] Another Task [priority]
Uses try-with-resources for automatic cleanup. All I/O exceptions are translated to FileWriteException with user-friendly messages covering: permission denied, directory not found, disk space issues, file locking, path length limits, read-only filesystem, and security policy violations. Error messages follow the pattern "'<filename>': <description>" with actionable suggestions.
The export workflow consists of 5 steps:
Task Collection - Uses TaskCollector based on parameters with 4 strategies:
if (params.forceAll) {
tasks = TaskCollector.getAllTasksWithProjects(projects);
} else if (params.projectIndex != null) {
tasks = TaskCollector.getTasksFromProject(projects.getProjectByIndex(params.projectIndex));
} else if (!params.hasFilterOrSort() && lastViewType != ViewType.NONE && !lastDisplayedTasks.isEmpty()) {
tasks = new ArrayList<>(lastDisplayedTasks); // Export last cached view (from sort/filter)
} else {
tasks = TaskCollector.getAllTasksWithProjects(projects); // Default: all tasks
}
Last View Caching: View state is stored in ExportCommandHandler instance fields (lastDisplayedTasks, lastViewType, lastViewMetadata). The sort-tasks and filter-tasks commands update this state via updateViewState(). When exporting without parameters, it automatically exports the cached view if available.
TaskFilter and TaskSorter if specified in export commandTaskExporter.exportTasksToFile() with headerConsoleUi.showExportSuccess()Design Benefits: Separation of concerns, reusability across operations, error isolation, independent testability, and seamless integration with view commands (sort/filter) through view state tracking.
The storage system provides persistent data storage for FlowCLI, automatically saving and loading all projects and tasks between sessions. It implements robust error handling, data validation, and atomic write operations to ensure data integrity.
Key Components:
Architecture Overview:

The Storage class acts as the central persistence manager, coordinating file I/O operations and data validation. It maintains relationships with the domain model (ProjectList, Project, TaskList, Task) for serialization and handles exceptional cases through specialized exception types.
Storage Location:
Data is saved to ./data/flowcli-data.txt (relative to where the JAR is executed).
Data Format:
The storage uses a custom delimiter-based format optimized for parsing and validation:
PROJECT|Project Name
TASK|isDone|description|deadline|priority
Where:
PROJECT|<name> - Project header lineTASK|<0/1>|<description>|<YYYY-MM-DD or null>|<1-3> - Task entry (0=not done, 1=done; 1=low, 2=medium, 3=high priority)|, newlines) are escaped using <PIPE> and <NEWLINE> markersImplementation Details:
On Startup (FlowCLI constructor):
load() is called to read data from file.backup file, shows warning, starts with empty ProjectListOn Exit (ByeCommand execution):
save() is called with current ProjectListflowcli-data.tmp)flowcli-data.txt (prevents corruption if interrupted)Data Validation During Load:
isDone must be 0 or 1Special Character Handling:
| in user input are escaped to <PIPE><NEWLINE><PIPE> becomes <PIPE><PIPE>)Error Handling:
| Error Type | Handling | User Impact |
|---|---|---|
| File not found (first run) | Silent, start with empty list | None |
| Empty file | Silent, start with empty list | None |
| Corrupted data | Backup to .backup, show warning, start with empty list |
Warning message |
| I/O error (read) | Show warning, start with empty list | Warning message |
| I/O error (write) | Prompt for retry (3 attempts), allow exit without saving | Error message + retry prompt |
| Permission denied | Show specific error, prompt for retry or exit | Error message |
| Disk full | Show specific error, prompt for retry or exit | Error message |
Example Storage File:
PROJECT|CS2113T Project
TASK|1|Complete assignment|2025-12-31|3
TASK|0|Study for exam|null|2
PROJECT|Personal Tasks
TASK|0|Buy groceries|2025-11-10|1
TASK|1|Call dentist|null|2
Edge Cases Handled:

The interactive mode transforms single-word commands into guided conversations. When a user types “add” without arguments, the system prompts for project selection, task details, and optional fields.
The overall command processing workflow shows how user input flows through the system components:

Architecture Flow: User input → CommandHandler → InteractivePromptHandler (if needed) → CommandFactory → Command execution → Result display.

The CommandHandler.shouldUseInteractiveMode() method determines when to trigger interactive mode:
private boolean shouldUseInteractiveMode(CommandParser.ParsedCommand parsed) {
switch (parsed.getType()) {
case ADD_TASK:
return parsed.getArguments().trim().isEmpty();
case CREATE_PROJECT:
return parsed.getArguments().trim().isEmpty();
case LIST:
return parsed.getArguments().trim().isEmpty();
case MARK:
return parsed.getArguments().trim().isEmpty();
case UNMARK:
return parsed.getArguments().trim().isEmpty();
case DELETE:
return parsed.getArguments().trim().isEmpty();
case UPDATE:
return parsed.getArguments().trim().isEmpty();
case SORT:
return parsed.getArguments().trim().isEmpty();
case FILTER:
return parsed.getArguments().trim().isEmpty();
case EXPORT:
return parsed.getArguments().trim().isEmpty();
case STATUS:
return parsed.getArguments().trim().isEmpty();
default:
return false;
}
}
Decision Rationale: Interactive mode is triggered for main commands with empty arguments, preserving backward compatibility.
The status display system provides users with visual feedback on project progress through completion tracking, progress bars, and motivational messages. It separates analysis logic from presentation concerns for maintainability.

Key Components:
Design Principles:

The above diagram shows the execution flow for displaying a specific project’s status (e.g., status 1). The diagram focuses on the main success path for clarity.
Execution Flow:
Command Parsing:
Argument Processing:
Status Analysis:
isDone() == true)UI Rendering:
formatStatusSummary(): Creates summary text (e.g., “3/5 tasks completed, 60%”)generateProgressBar(): Creates visual progress bar [=========> ] 60%getMotivationalMessage(): Selects message based on completion percentageCleanup:
Note: The command also supports displaying all projects with status --all, which follows a similar flow but iterates through all projects in the ProjectList.
Task Status Markers:
Individual tasks display completion status using visual markers in list views:
public String marker() {
return isDone ? "[X]" : "[ ]";
}
Display Example:
CS2113T Project - Project Status
3/5 tasks completed, 60%
[========================> ] 60%
We are on the right track, keep completing your tasks!
Motivational Messages:
The system provides contextual encouragement based on progress:
Status Types:
status <projectIndex>): Shows detailed status for one projectstatus --all): Shows summary status for all projects in a compact formatThe add command guides users through project selection, task description, priority, and optional deadline:

Key Features:

Optional Fields: Priority and deadline can be skipped, defaulting to “medium” and no deadline respectively.
Mark and unmark commands share similar logic but with different validation:
public String handleMarkCommand() {
Integer projectSelection = promptForProjectIndex();
if (projectSelection == null) return null;
// Display tasks with status markers
System.out.println("Hmph, which tasks do you want to mark as done in " + projectName + ":");
for (int i = 0; i < project.size(); i++) {
var task = project.getProjectTasks().get(i);
String status = task.isDone() ? "x" : " ";
System.out.println((i + 1) + ". [" + status + "] " + task.getDescription());
}
// Multiple task selection with comma separation
String input = scanner.nextLine().trim();
String[] indices = input.split(",");
// ... validation and construction
}
Mark vs Unmark Validation:
Delete command uses a two-stage approach: type selection then specific item selection with confirmation:

Safety Features:
Update command implements recursive field updates allowing multiple changes in one session:

Recursive Design: Users can update multiple fields without restarting the flow, with options to reselect tasks/projects or exit at any point.
The export command provides comprehensive data export capabilities with multiple filtering and sorting options. Users can export their project and task data in various formats and configurations.
Key Features:
Export Options:

Create command prompts for a new project name with validation:

Validation: Checks for empty names and duplicate project names.
Mark and unmark commands follow identical selection flow with different validation:

Shared Logic: Both commands use identical project/task selection but different validation rules.
Sort command offers field and order selection:

Simple Flow: Two sequential choices with no complex validation.
Filter command offers priority level selection:

Single Choice: Simple selection from three priority options.

Display Logic: Shows numbered project list, then either displays tasks for selected project or all projects with all tasks.

Status Types: Shows either project-level statistics or task completion summaries.
Individual student developers working on their own coursework, capstones, hackathons, or any other related projects that require task management to streamline their workflow.
FlowCLI addresses the challenge of managing complex academic or personal projects by providing a streamlined, command-line interface for task and project organization. It helps student developers maintain focus, track progress, and efficiently handle multiple assignments or project phases without the overhead of graphical user interfaces. By offering quick task creation, flexible filtering, and clear status overviews, FlowCLI ensures that users can dedicate more time to coding and less to administrative overhead, ultimately boosting productivity and reducing stress.
| Version | As a … | I want to … | So that I can … |
|---|---|---|---|
| v1.0 | new user | see usage instructions | refer to them when I forget how to use the application |
| v1.0 | user | find a to-do item by name | locate a to-do without having to go through the entire list |
| v1.0 | user | create and manage projects and tasks | organize my work and track progress efficiently |
| v1.0 | user | add, mark, unmark, delete, and update tasks | keep my task list accurate and up-to-date |
| v1.0 | user | view, filter, and sort tasks | focus on relevant tasks and prioritize my workload |
| v1.0 | user | export my tasks | backup my data or share it with others |
| v2.0 | user | use interactive prompting for commands | be guided through complex commands easily |
| v2.0 | user | check the status of my projects and tasks | get a quick overview of my progress and workload |
Performance
Usability
Reliability
Portability
Maintainability
Scalability
Security
Compatibility
These instructions will guide you through comprehensive manual testing of FlowCLI, including both inline command usage and interactive mode functionality.
Build the application:
./gradlew build
Locate the JAR file:
build\libs\flowcli.jarRun the application:
java -jar <full-path-to-flowcli.jar>
Load sample data: Copy and paste the following commands to populate the application with sample data: (no need to copy paste one at a time)
create-project "CS2113T Project"
create-project "Internship Hunt"
create-project "Household Chores"
create-project "Fitness Plan"
create-project "Side Project - Website"
add-task 1 "Finalize DG" --priority high --deadline 2025-11-10
add-task 1 "Implement UI" --priority high --deadline 2025-11-20
add-task 1 "Write UG" --priority medium --deadline 2025-11-25
add-task 1 "Prepare for Demo" --priority medium
add-task 1 "Review teammate PR" --priority low
add-task 2 "Update Resume" --priority high
add-task 2 "Apply to 5 companies" --priority medium --deadline 2025-11-15
add-task 2 "Research company A" --priority low
add-task 2 "Practice LeetCode" --priority medium
add-task 3 "Buy groceries" --priority medium --deadline 2025-10-29
add-task 3 "Clean room" --priority low
add-task 3 "Pay utility bill" --priority high --deadline 2025-11-01
add-task 4 "Go for run" --priority medium
add-task 4 "Meal prep for week" --priority low
add-task 4 "Go to gym" --priority medium
add-task 5 "Design homepage" --priority medium
add-task 5 "Set up database" --priority high --deadline 2025-12-01
add-task 5 "Draft 'About Me' page" --priority low
mark 1 1
mark 2 1
mark 3 3
mark 4 1
Alternatively, you may create your own test data using the commands above as a reference.
View help:
help
Test interactive mode: Follow the help output and try all one-word command triggers for interactive mode:
add (triggers interactive task addition)create (triggers interactive project creation)list (triggers interactive project/task listing)mark (triggers interactive task marking)unmark (triggers interactive task unmarking)update (triggers interactive task updating)delete (triggers interactive item deletion)sort (triggers interactive sorting)filter (triggers interactive filtering)export (triggers interactive data export)Exit the application:
bye