sayanarijit / mind

A productive mind has an empty stack
https://mind.cli.rs
MIT License
47 stars 1 forks source link

Write a design for the possible solution #50

Closed sayanarijit closed 2 years ago

sayanarijit commented 2 years ago

Write a design for the possible solution we came up with in #49.

Ref: #46

sayanarijit commented 2 years ago

Step 1: Capture

Capturing information will be mind's primary focus (as currently is), because it's the most crucial part, since I can only process information when I capture them.

When I encounter some information that I want to capture, I don't want to lose my focus from the current task at hand. Hence, I want the experience to be as effortless, distraction-free and efficient as possible.

UI/UX

I think mind's current UI design and input mechanism is capable enough.

However, an even cleaner version is possible where I don't see the previously submitted information. Rather, I only see an input box where I can submit a paragraph (with details if required) and when I do submit, I get some feedback.

Which means, it's possible to further improve the UI/UX for an even better experience. So, it might come in handy to allow hacking the UI/UX via some configuration (and maybe plugin) system.

So, at the core, mind will only provide an interface via which an input reader can submit information. And a renderer that can render the captured information.

The input reader and the renderer should be able to receive and acknowledge live updates asynchronously.

Input reading should have the highest priority and rendering should be optional.

The information will be submitted in plain text format to keep things simple. The first line will be considered as the title (required, unique) and the following lines will be considered as the body (optional).

The input (both title and body) will be raw i.e. no special format, syntax, metadata or anything that contain some meaning for a tool or algorithm, will be supported. But I should be free to use my preferred format, syntax or attach metadata to the information to help me when I visit it later.

The mind CLI tool will come with a default implementation of the input reader and UI renderer for the terminal, but should be able to run in headless mode, only exposing the API via different channels, so that other tools can do the job too.

Sometimes I might want to skip the capture step and go directly to the next step. For this, there should be easy ways to move the current input to the next step at every opportunity.

Availability

When I need to capture information,

The preferred method of sync/communication will be using websocket because it has to be real-time.

The information will be captured (queued) as .txt files in a specific directory like /.mind/inbasket, waiting to be processed in the next step. To add some new information to the queue, go to the inbasket directory and enter vim info-$(date -u "+%s").txt.

sayanarijit commented 2 years ago

Step 2: Clarify

Once I capture enough information that might have some meaning for me, when I get some free time, I want to go through them and analyze what they really are.

I can delete the information that has no meaning for me. Others are actionable.

For each actionable item, if it's something trivial, I need to finish it right away. Else, I need to convert them to "Task"s.

I need to prepare well so that I can skip the turning into task step for as many items as possible.

The tasks could be stored as task-$(date -u "+%s").yml files in the ~/.mind/tasks directory.

UI/UX

The UI will display the information one by one, each for max 2 minutes. I can either finish it right then or turn it into a "Task".

In any case, I need to mark it as "Done" before the timeout, else it will get re-stacked and the next item will appear.

In order to turn some information into a "Task" I need to define the following:

The information should get auto-attached to the task.

There will be customizable shortcuts to perform actions like making API calls, auto generate tasks etc.

When the in basket is empty, it will remind me to check other sources like mobile, notebook etc. whatever I have defined as my in-basket, and provide me an interface to add adhoc tasks.

sayanarijit commented 2 years ago

Step 3: Organize

Once I know what to do and how to do, I need to decide if I should and when to do it. Basically, I need to put the tasks in different baskets. For e.g.

These can be actual folders inside ~/.mind/tasks.

UI/UX

A bunch of folders. Some will be there by default but can be deleted. Others can be created. The folders can be ordered by using a prefix numbers. Tasks can be dragged and dropped from one folder to another folder easily. No sub folders will be supported. Each folder can contain meta configuration as a config.yml file inside them. The meta configuration can define properties like color, tags etc.

sayanarijit commented 2 years ago

Step 4: Reflect

This is where tasks get priorities based on the 6 horizons of focus:

The horizons can be defined in different folders like ~/.mind/horizons_of_focus/${num}-${title}.

UI/UX

This step requires maximum visibility to all the tasks that need to be done. It's basically a dashboard where I can zoom in and zoom out into different horizons. Every horizon will have a priority set by me. Each item in every horizon will have a priority set. The dashboard will allow me to define how critical is the task for each item in each horizon. Then, I'll get the final priority calculated by an algorithm, also defined by me. Ofcource, I can add bias points to the task depending on my mood.

sayanarijit commented 2 years ago

Step 5: Engage

Now that the priorities are defined, it's time to engage and start doing. At this point I'm sure that whatever I'm doing is the best things I could be doing right now. There's no pending task or might-be-critical information hiding in my mind and making me anxious. All I need is the list of tasks to be done.

UI/UX

This is a list of TODOs auto arranged by the calculated priority. All I need to do is, finish each task and tick it off from the list.

sayanarijit commented 2 years ago

Let's iterate on the design and try looking from another angle.

sayanarijit commented 2 years ago

What if we generalise the process and make it implementation independent?

I think we can reduce the whole thing into a simple concept of a version controlled information-label system.

Let's see how.

Core

The core is the storage that stores information, labels, properties and revisions, as simple as that.

So, at minimum the core exposes api to:

Information

Information is something we capture, often not knowing what it really is, or what exactly to do with it. It's just some text data with mime type and revision. After capturing we will update it, attach and detach labels and properties, until we have dealt with it and are ready to delete it. That's all the core allows us to do with it.

Label

As per the core, labels are unique entities (defined as string). The core doesn't know what or how many labels are there, what they look like or what they mean. It can only attach and detach labels to information from the given string.

Property

A property is also something that can be attached to an information. But unlike labels, which carry only 2 possible states (attached/detached), properties allow us to attach extra metadata as key-value pairs.

Revision

Each change to the information will contain a revision (basically a UTC timestamp), so that sync works. Deleted information will have only the id and revision fields remaining in the DB.

Responsibilities

That's all the core does, i.e. store data. The actual logic will be implemented by the platform and the user.

Platform

A platform lets the user interact with the storage. But it does a lot more than that.

Information

The platform knows the format of the information. It also formats the information before storing. The platform gets to decide what types of data it will support, and what to do with unsupported data.

Labels & Properties

The platform can define what some labels and properties mean, how they behave and how they look like. Based on the type of information and the labels and properties attached to it, the platform can define how to display them and how users interact with them.

For e.g. A platform can define a label called Pinned, and tell the users that any information with this label attached will be displayed at the top of the page with a pin symbol. Or define a property called reminder and tell the user that information with this property set will behave like a reminder.

Platforms can also let the users define custom labels and properties, and define how they look and behave.

Revision

The platform can utilise the revision fields to sync data between multiple devices.

Responsibilities

The platform takes most of the responsibility to allow interaction between the user and the storage.

The platform can also define or allow the users to define what happens when some event occurs (e.g. new information, assigned a certain label, deleted a property) etc.

The platform can also implement support for calender, project management tools and frameworks etc. but these are not requirements.

The only requirements expected from a platform is to utilise the core storage system and define everything in terms of information, labels and properties (except uploaded files if any). And also to standardize the platform specific meanings of labels and properties so that migration between platforms are possible without going beyond what the core system allows.

User

Depending on what the platform enables, the user can also utilize the system to organize and automate organization steps using the platform supported scripting (code or nocode).

However, it'd be great if the platform allows the users to collaborate and share their labels, properties and automation scripts to help each other out, and the users actually do so. Not required, but highly recommended.

sayanarijit commented 2 years ago

Benefits of the setting explained above:

Drawback:

Most are related.

sayanarijit commented 2 years ago

Example storage using plain files and folders (git optimized):

/wrksp1/information/123/rev1/data /wrksp1/information/123/rev1/labels/label1 /wrksp1/information/123/rev1/properties/prop1

sayanarijit commented 2 years ago

The simplest way is to dump everything in a yaml file like mind already does.

sayanarijit commented 2 years ago

Standard for labels

A label should confirm to the format: definition::label-parent:label-child.

e.g. plt::pinned, plt::reminder:repeating, plt::pinned:sidebar, usr::work.

The definition:: part denotes where the meaning of the label is defined. Is it defined by the platform (plt::)? Or is it defined by the user (usr::)? If no definition is provided, it will default to usr::.

Now, the actual label can be defined using lower-case, hyphen (-) separated words. Nested labels can be defined using a colon (:) separator.

Standard for properties

Similar to labels, properties also confirm to the definition::property-parent:property-child format and follows the same logic.


This separation of platform and user defined labels is necessary to avoid conflict, where the user means one thing and the platform understands another. For e.g. the word wip might mean that the task is "work in progress" to the platform, but might also mean it's a "wise individual's principle" (something I made up) to the user. Both shouldn't be mixed up.

This also makes it easy to migrate from one platform to another without losing functionality, because it will be easy for the migration tools to rename the plt:: labels to the destination platform's equivalent platform defined labels to keep the functionality intact.


We could also introduce std:: to define a standard set of labels that every platform should support, but I think that might be asking too much of the platforms. Also, there will be extra headache to support different versions of the standard.

A better alternative would be to introduce cmm::{community}::{user}::label, where {community} is the name/domain of a community and {user} is the user ID of a member in the community who contributed the meaning of the label. It'd be up to the platforms to support community contributed labels.

sayanarijit commented 2 years ago

Next: https://github.com/sayanarijit/mind/issues/51