Client2Door is built for small business owners who run recurring delivery or subscription services in Singapore — such as meal kit boxes, pastry subscriptions, or monthly packages — and who prefer the speed of a Command Line Interface (CLI) over clicking through menus.
If you find yourself juggling a growing list of subscribers, tracking which boxes need to go out, and coordinating drivers for dispatch, Client2Door is designed to make that faster and less error-prone.
This guide assumes you:
Managing recurring orders in a spreadsheet gets messy fast — you lose track of who has which box, when subscriptions expire, and who is delivering to whom. Client2Door gives you a single, fast interface to:
helpaddaddboxlistediteditboxremarkfinddeletedeleteboxmarkfilterassignexportimportclearexitEnsure you have Java 17 installed on your computer. Follow the guide for your operating system:
Download the latest Client2Door.jar file from here.
Create a folder anywhere on your computer (e.g. C:\MyBusiness\Client2Door on Windows, or ~/Client2Door on Mac) and move the .jar file into it. This folder will store all your data.
Open a terminal:
Win + R, type cmd, press EnterCmd + Space), type Terminal, press EnterNavigate to your folder using cd. For example:
cd C:\MyBusiness\Client2Door
Run the app:
java -jar Client2Door.jar
The app window should appear within a few seconds, preloaded with sample data.
The app window has three main areas:
| Area | Location | Purpose |
|---|---|---|
| Command Box | Top | Where you type commands and press Enter to run them |
| Output Display | Middle | Shows feedback from your last command: success confirmations or error messages |
| Result Panel | Bottom (scrollable) | Displays the results of your command: your subscriber list, search results, or filtered views |
If you have never used a CLI before, follow these steps to get familiar with Client2Door before managing your real data.
Step 1 — Add a subscriber
Type the following into the command box at the top and press Enter:
add n/Tom Baker p/91234567 e/tombaker@email.com a/123 Orchard Rd Singapore 238888 b/box-1:2
The middle output panel will confirm the subscriber was added. Tom Baker will appear at the bottom of the result panel with a Pending delivery status and one box.
Step 2 — View your full subscriber list
list
The result panel shows all subscribers. Each subscriber has an index number on the left — the subscriber at the top is always index 1, the next is 2, and so on down the list. Since Tom was just added, he will appear at the bottom with the highest index number.
Note: Index numbers are positional and update with every command refresh — they reflect the current position in the result panel, not a fixed ID.
Step 3 — Find a subscriber
find Bernice
The result panel filters to show only subscribers whose names contain "Bernice". The output panel confirms how many results were found. Run list to return to the full view.
Step 4 — Mark a delivery
Run list to see all subscribers and note Tom Baker's index number at the bottom. Then mark his delivery using that index — for example, if Tom is index 9:
mark 9 delivered
Tom's status updates to Delivered in the result panel. The output panel confirms the change.
Step 5 — Delete the test entry
Run list to see all subscribers and note Tom Baker's index number at the bottom. Then delete him using that index — for example, if Tom is index 9:
delete 9
Tom Baker is removed. The output panel confirms the deletion. You are now ready to manage your real subscribers.
Before using Client2Door, it helps to understand three core ideas:
Subscriber: A subscriber is a customer who receives regular deliveries from your business. Each subscriber has:
Note:
Namecan only have alphabetic characters, hyphens, apostrophes and spaces. (Excluded slashes to prevent incorrect parsing)
Addressis validated by finding a 6-digit postal code, with the Singapore context kept in mind!
Box:
A box represents a single recurring delivery package assigned to a subscriber. Each subscriber must have at least one box. Boxes have a name in the format [type]-[number] where the type uses underscores for multi-word names (e.g. box-1, pastry-2, meal_kit-1) and an expiry date — after which the subscription is considered lapsed. A subscriber can hold multiple boxes if they have ordered more than one package.
Note:
Orders are fulfilled starting the following month of a box's addition. Therefore, a one-month subscription made in the current month will be delivered the following month and expire at the end of the month.
Delivery Status: Every subscriber has a delivery status that reflects where their order is in the fulfilment process:
Pending — order received, not yet packedPacked — box is packed and ready for dispatchDelivered — box has been delivered to the subscriber
Words in
UPPER_CASEare the parameters to be supplied by you.
e.g. inadd n/NAME,NAMEis a parameter which can be used asadd n/John Doe.Items in square brackets are optional.
e.g.n/NAME [t/TAG]can be used asn/John Doe t/friendor asn/John Doe.Items with
…after them can be used multiple times including zero times.
e.g.[t/TAG]…can be used as(i.e. 0 times),t/friend,t/friend t/familyetc.Parameters can be in any order.
e.g. if the command specifiesn/NAME p/PHONE,p/PHONE n/NAMEis also acceptable.Extraneous parameters for commands that do not take in parameters (such as
help,list,exitandclear) will be ignored.
e.g. if the command specifieshelp 123, it will be interpreted ashelp.If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application.
| Prefix | Parameter | Description |
|---|---|---|
n/ | NAME | Full name of the subscriber |
p/ | PHONE | Contact number — digits only, at least 3 digits, must not start with 0 |
e/ | EMAIL | Email address |
a/ | ADDRESS | Delivery address |
b/ | BOX_NAMEMONTHS_SUBSCRIBED | Box name and number of months until subscription ends; At least 1 box subscription required |
nb/ | BOX_NAME | New box name — only used in the editbox command |
r/ | REMARK | Optional delivery note — defaults to No remark if omitted |
t/ | TAG | Optional tag(s) — can be repeated |
helpShows a link to this user guide.
Format: help
Expected output: A help window appears with a link to the online user guide.
addAdds a new subscriber to Client2Door.
Format: add n/NAME p/PHONE e/EMAIL a/ADDRESS b/BOX_NAME:MONTHS_SUBSCRIBED [r/REMARK] [t/TAG]…
Tip: Add multiple boxes in one command by repeating
b/. You can always add more boxes later withaddbox.
Note: The subscriber's delivery status is automatically set to
Pendingwhen first added.
Examples:
add n/Sarah Tan p/91234567 e/sarah@email.com a/Blk 10 Ang Mo Kio Ave 4 #05-03 Singapore 560010 b/box-1:2add n/Wei Ming p/87654321 e/weiming@email.com a/12 Toa Payoh Lor 6 Singapore 310012 b/box-1:2 b/box-2:3 r/Leave at door and ring bell t/VIPExpected output: The subscriber appears in the result panel at the bottom, and the output panel confirms:
listShows all subscribers currently in Client2Door.
Format: list
Tip: Run
listafter usingfindorfilterto return to the full subscriber view.
Expected output: All subscribers appear in the result panel. The output panel shows: Listed all persons.
editEdits the details of an existing subscriber.
Format: edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [r/REMARK] [t/TAG]…
INDEX refers to the number shown next to the subscriber's name in the current list. It must be a positive integer (1, 2, 3, …).t/ with nothing after it.r/ with nothing after it.remark command.editbox to change box names or expiry dates.Examples:
edit 1 p/98887777 e/sarah_new@email.com — updates the phone and email of subscriber 1.edit 2 a/50 Jurong West Ave 1 Singapore 649520 r/prefers afternoon delivery t/ — updates address and remark for subscriber 2 and removes all tags.Expected output: The output panel confirms the edit and shows the subscriber's updated details. The subscriber list resets to show all subscribers.
remarkUpdates the delivery remark for a subscriber.
Format: remark INDEX r/REMARK
INDEX refers to the number shown next to the subscriber in the current list. It must be a positive integer (1, 2, 3, …).r/ prefix is allowed — providing multiple r/ prefixes in the same command is an error.edit using the r/ prefix.Tip: Use remarks for delivery-specific notes like "ring doorbell", "leave at guardhouse", or "call before arriving".
Examples:
remark 1 r/leave at door and no need to ring bellremark 2 r/allergic to nutsExpected output: The output panel confirms the remark has been updated. The subscriber list resets to show all subscribers.
findFilters the subscriber list to show only subscribers whose names match the given keywords.
Format: find KEYWORD [MORE_KEYWORDS]…
sarah matches Sarah.Tan Sarah matches Sarah Tan.Sar will not match Sarah.Tip: Use
findbeforedeleteoreditto locate the right subscriber and confirm their index number before making changes.
Examples:
find Sarah — returns all subscribers named Sarah.find Sarah Wei — returns subscribers named Sarah or Wei.Expected output: The list filters to matching subscribers. The output panel shows how many were found.
Run list to return to the full subscriber view.
deletePermanently removes a subscriber from Client2Door.
Format: delete INDEX
INDEX refers to the number shown next to the subscriber's name in the current list. It must be a positive integer (1, 2, 3, …).Warning: Deletion is permanent and cannot be undone. Use
findto confirm you have the right subscriber before deleting. Consider runningexportbefore bulk deletions to save a copy of your data.
Warning: Deleting a subscriber clears all driver assignments for every subscriber. Re-run
assignafter deleting if driver assignments are needed.
Examples:
list then delete 2 — deletes the 2nd subscriber in the full list.find Sarah then delete 1 — deletes the first result from the search.Expected output: The subscriber is removed from the list. The output panel confirms the deletion.
markUpdates the delivery status of a subscriber. Delivery status tracks where a subscriber's order is in the fulfilment cycle:
Pending — order received but not yet preparedPacked — boxes have been packed and are ready for dispatchDelivered — order has been delivered to the subscriberStatus does not reset automatically — it must be updated manually using this command.
Format: mark INDEX STATUS
INDEX refers to the number shown next to the subscriber in the current list. It must be a positive integer (1, 2, 3, …).STATUS must be one of: pending, packed, or delivered (not case-sensitive).Tip: Use
markas you progress through your fulfilment workflow — mark aspackedonce boxes are ready, thendeliveredafter drop-off. This keeps your list up to date for driver coordination.
Examples:
mark 1 packed — marks subscriber 1 as Packed.mark 2 delivered — marks subscriber 2 as Delivered.mark 3 pending — resets subscriber 3 back to Pending.Expected output: The subscriber's status updates in the list. The output panel confirms the change. The subscriber list resets to show all subscribers.
filterNarrows the result panel to show only subscribers matching a box type or an assigned driver.
Format: filter BOX_NAME [MORE_BOX_NAMES]… OR filter d/DRIVER_NAME [d/MORE_DRIVER_NAMES]…
BOX_NAME or d/DRIVER_NAME must be provided.BOX_NAME filters by the box type subscribers have (e.g. box-1).d/DRIVER_NAME filters by the driver assigned to subscribers. Subscribers are assigned to drivers using the assign command.list to return to the full subscriber view.Tip: Use
filter d/DRIVER_NAMEafter runningassignto review exactly which subscribers each driver is responsible for before exporting.
Examples:
filter box-1 — shows all subscribers who have a box-1 box.filter d/David Lim — shows all subscribers assigned to driver David Lim.Expected output — filtering by box type:
Before filtering, all subscribers are shown:
After running filter box-1, only matching subscribers remain:
Expected output — filtering by driver:
Before filtering by driver:
After running filter d/David, only that driver's subscribers are shown:
addboxAdds one or more boxes to an existing subscriber.
Format: addbox n/NAME b/BOX_NAME:MONTHS_SUBSCRIBED [b/MORE_BOX_NAME:MONTHS_SUBSCRIBED]…
NAME from the currently displayed list. Run list first if the subscriber is not visible.add to add boxes when first creating a subscriber.Tip: Use this command when a subscriber renews or upgrades their order mid-cycle without changing their other details.
Examples:
Suppose the current date is 8 April 2026,
addbox n/Sarah Tan b/box-3:4 — adds one new box to Sarah Tan, expiring 4 months later, hence with an expiry date of 2026-08-31.addbox n/Wei Ming b/box-3:5 b/box-4:5 — adds two boxes to Wei Ming, both expiring 5 months later at 2026-09-30.Expected output: The output panel confirms the boxes have been added and shows the subscriber's updated details.
editboxEdits the name or expiry date of an existing box belonging to a subscriber.
Format: editbox n/NAME b/OLD_BOX_NAME [nb/NEW_BOX_NAME] [ex/MONTHS_SUBSCRIBED]
NAME from the currently displayed list. Run list first if the subscriber is not visible.b/OLD_BOX_NAME identifies which box to edit.nb/ or ex/ must be provided.addbox to add new boxes, deletebox to remove boxes.Examples:
editbox n/Sarah Tan b/box-1 nb/box-2 — renames the box.editbox n/Sarah Tan b/box-2 ex/3 — sets the expiry date to 3 months after the present date.editbox n/Wei Ming b/box-1 nb/box-3 ex/4 — renames box AND updates expiry to 4 months after the present date.Note: Present date here refers to the present date in our time, not the previous expiry date before the edit.
Expected output: The output panel confirms the update and shows the box's new details. The subscriber list resets to show all subscribers.
deleteboxRemoves one or more boxes from a subscriber.
Format: deletebox n/NAME b/BOX_NAME [b/BOX_NAME]…
NAME from the currently displayed list. Run list first if the subscriber is not visible.addbox to add boxes.Warning: If you delete all boxes belonging to a subscriber, the subscriber will also be permanently deleted from Client2Door.
Examples:
deletebox n/Sarah Tan b/box-1 — removes one box from Sarah Tan.deletebox n/Wei Ming b/box-1 b/box-2 — removes two boxes. If these are Wei Ming's only boxes, Wei Ming will also be deleted.deletebox n/Wei Ming b/box-1 b/box-1 — removes only one box, box-1. The second box-1 will be ignored.Expected output: The output panel confirms which boxes were removed. The subscriber list resets to show all subscribers.
assignSplits all subscribers in Client2Door into groups and assigns a driver to each group, regardless of what is currently shown in the result panel.
Format: assign n/NAME p/PHONE [n/NAME p/PHONE]…
Delivered. This is intentional so that completed deliveries remain attributed to the driver who fulfilled them.n/… p/… pairs determines how many groups are created. Subscribers are divided roughly equally.export to generate a shareable delivery schedule after assigning.Tip: Run
assignat the start of each delivery cycle to redistribute all subscribers across your available drivers for that day.
Examples:
assign n/David Lim p/91234567 — assigns all subscribers to David Lim.assign n/David Lim p/91234567 n/Priya Nair p/98765432 — splits all subscribers between two drivers.assign n/David Lim p/91234567 n/Priya Nair p/98765432 n/Ali Hassan p/81234567 — splits all subscribers across three drivers.Note: Running the commands that change the number of subscribers (such as
addanddelete) oredit(when address is changed) will clear drivers assignment to ensure the clustering algorithm applies to the full list of subscribers and there is efficient distribution of workload to drivers
Expected output: Every subscriber in Client2Door is tagged with their assigned driver. The output panel confirms how many subscribers were assigned and to which drivers. The subscriber list resets to show all subscribers.
exportGenerates a shareable HTML file listing all drivers and their assigned subscribers.
The HTML file is stored in the data/ folder.
Format: export [FILE_NAME.html]
FILE_NAME.html is provided, the exported HTML will be saved as delivery_assignments.html by default.export april-deliveries.html, not export data/april-deliveries.html.FILE_NAME.html must end with .html.assign first.Tip: Open the exported
.htmlfile in any web browser to view a clean, printable summary. You can share it with your drivers directly.
Warning: If any subscriber is missing an assigned driver, the export will fail with an error message. Run
assignfirst.
Examples:
export — saves to data/delivery_assignments.html.export march-delivery.html — saves to data/march-delivery.html.Expected output: The output panel confirms the file has been saved and shows the file path.
importImports subscribers from a CSV file in the data/ folder into Client2Door.
Format: import FILE_NAME.csv
FILE_NAME.csv must be the name of a CSV file located in the data/ folder of your Client2Door folder.import april-subscribers.csv, not import data/april-subscribers.csv..csv.Pending.Warning: The imported CSV file must be generated using this google form template
Tip: Running
importclears all existing driver assignments. Re-runassignafter importing if driver assignments are needed.
Note: Each subscriber can only subscribe to 1 of each type of box to prevent scalping.
CSV format:
Each data row must have at least 9 columns in this order:
| Column | Field | Notes |
|---|---|---|
| 1 | Row index | Any value — not imported |
| 2 | Name | |
| 3 | Phone | |
| 4 | ||
| 5 | Address | Wrap in quotes if it contains commas |
| 6 | Box 1 name | |
| 7 | Box 1 months subscribed | Integer |
| … | Additional box pairs | Repeat columns 6–7 for each extra box (leave blank to skip) |
| 2nd to last | Remark | |
| Last | Trailing column | Any value — not imported |
Example row (one box):
0,Sarah Tan,91234567,sarah@email.com,Blk 10 Ang Mo Kio Ave 4,box-1,2,leave at door,extra
Example row (two boxes):
0,Wei Ming,98765432,wei@email.com,456 Jurong West Ave 1,box-1,3,box-2,6,no remark,extra
Tip: Place the CSV file in the
data/folder before runningimport. This command reads only from that folder.
Warning: The
importcommand only accepts CSV files. Files generated byexportare HTML summaries and cannot be imported back into Client2Door.
Examples:
import april-subscribers.csv — imports subscribers from data/april-subscribers.csv.import backup_2026_04.csv — imports another CSV file stored in the same folder.Expected output: The output panel shows how many subscribers were imported successfully. If any rows are skipped, the output also lists the failed rows and the reason.
clearRemoves all subscribers from Client2Door.
Format: clear
Warning: This permanently deletes all subscriber data and cannot be undone. Run
exportbefore clearing if you may need the data again.
Expected output: The subscriber list becomes empty. The output panel shows: Address book has been cleared!
exitCloses Client2Door.
Format: exit
Expected output: The application window closes. All data has already been saved automatically.
Client2Door saves all data automatically to the hard disk after every command that changes data. There is no need to save manually.
Q: How do I transfer my data to another computer?
A: Copy the addressbook.json file located in the data/ directory (in the same directory the Client2Door.jar file) over to the other computer in the same directory structure
Example: Client2Door.jar in now in the tp directory, the data directory in the same tp directory and addressbook.json should be in the tp/data/ folder.
Q: What happens if I accidentally run clear?
A: All data is permanently deleted and cannot be recovered from within the app. Use export regularly to keep a saved copy of your delivery data.
Q: Can two subscribers share the same box name?
A: Yes — box names are unique per subscriber, not across all of Client2Door. Two different subscribers can each have a box named box-1.
Q: Why is my export failing?
A: The export command requires at least one driver to have been assigned via assign first. Run assign and then retry export.
Q: What happens to driver assignments if I run assign again?
A: All previous driver assignments for every subscriber are replaced. The assign command always acts on all subscribers in Client2Door, regardless of the current view.
preferences.json file in your Client2Door folder and relaunch the app.help again, no new window will appear. Restore the minimised window manually.| Action | Format | Example |
|---|---|---|
| Add | add n/NAME p/PHONE e/EMAIL a/ADDRESS b/BOX_NAME:MONTHS_SUBSCRIBED [r/REMARK] [t/TAG]… | add n/Sarah Tan p/91234567 e/sarah@email.com a/Blk 10 AMK Ave 4 b/box-1:2 |
| Edit | edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [r/REMARK] [t/TAG]… | edit 2 p/98887777 r/prefers afternoon delivery |
| Delete | delete INDEX | delete 3 |
| Find | find KEYWORD [MORE_KEYWORDS]… | find Sarah Wei |
| List | list | list |
| Mark | mark INDEX STATUS | mark 1 delivered |
| Filter | filter BOX_NAME [MORE_BOX_NAMES]… or filter d/DRIVER_NAME [d/MORE_DRIVER_NAMES]… | filter box-1 or filter d/David Lim |
| Remark | remark INDEX r/REMARK | remark 2 r/leave at door |
| Add Box | addbox n/NAME b/BOX_NAME:MONTHS_SUBSCRIBED [b/BOX_NAME:MONTHS_SUBSCRIBED]… | addbox n/Sarah Tan b/box-3:4 |
| Edit Box | editbox n/NAME b/OLD_BOX_NAME [nb/NEW_BOX_NAME] [ex/MONTHS_SUBSCRIBED] | editbox n/Sarah Tan b/box-1 nb/box-2 ex/3 |
| Delete Box | deletebox n/NAME b/BOX_NAME [b/BOX_NAME]… | deletebox n/Sarah Tan b/box-1 |
| Assign | assign n/NAME p/PHONE [n/NAME p/PHONE]… | assign n/David Lim p/91234567 n/Priya Nair p/98765432 |
| Export | export [FILE_NAME.html] | export march-delivery.html |
| Import | import FILE_NAME.csv | import april-subscribers.csv |
| Clear | clear | clear |
| Help | help | help |
| Exit | exit | exit |
This appendix walks you through installing Java and launching Client2Door for the first time, with step-by-step instructions for Windows, Mac, and Linux.
Client2Door requires Java 17. Follow the guide for your operating system below.
.exe file).Win + R, type cmd, press Enter) and run:java -version
You should see output like: java version "17.x.x".Cmd + Space, type Terminal, press Enter) and run:java -version
You should see output like: java version "17.x.x".java -version
You should see output like: java version "17.x.x".Client2Door.jar file.Create a dedicated folder for Client2Door and place the .jar file inside it. This folder will also store your subscriber data automatically.
| OS | Example folder path |
|---|---|
| Windows | C:\MyBusiness\Client2Door\ |
| Mac | ~/Client2Door/ |
| Linux | ~/Client2Door/ |
Open a terminal and navigate to your folder using the cd command, then run the app.
Windows (Command Prompt):
cd C:\MyBusiness\Client2Door
java -jar Client2Door.jar
Mac / Linux (Terminal):
cd ~/Client2Door
java -jar Client2Door.jar
The Client2Door window will appear within a few seconds, preloaded with sample data so you can explore the interface before adding your own subscribers.
Tip: You can create a simple script or shortcut to run these two commands automatically each time you want to launch the app.