README.md

  1<!--
  2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  3
  4SPDX-License-Identifier: CC0-1.0
  5-->
  6
  7# nasin pali (the way of work)
  8
  9[![REUSE status](https://api.reuse.software/badge/git.secluded.site/np)](https://api.reuse.software/info/git.secluded.site/np)
 10[![Go Report Card](https://goreportcard.com/badge/git.secluded.site/np)](https://goreportcard.com/report/git.secluded.site/np)
 11
 12The code for this README exists, but requires some testing before release. I
 13previously wrote a
 14[planning-mcp-server](https://git.secluded.site/planning-mcp-server) that I've
 15kept some ideas from, and the overall workflow is about the same. I'm trying a
 16CLI over MCP because MCP seems quite protocol-heavy for what _could_ just be a
 17few simple CLI invocations. Maybe connecting arbitrary data sources warrants a
 18whole protocol like MCP, but I don't think something as basic as this does. Just
 19some thoughtful design and prompting.
 20
 21## Usage
 22
 23This section is first to entice you with _nasin pali_'s simplicity; after
 24installing the binary and prompt, having your coding tool using a better
 25planning system just requires typing six (or fewer!) characters.
 26
 27- When asking the model to do something a bit more complex, just append the
 28  phrase `use np`
 29  - If you want the model to `use np` _all_ the time, adjust the prompt after
 30    pasting to say something like _always use `np` instead of any other todo
 31    tools_.
 32- Once implemented, the `monitor` subcommand will show the model's plan and its
 33  realtime progress and the `export` subcommand will export the rendered plan
 34  and event log as Markdown. Should the model mark tasks failed/cancelled or
 35  change the goal/task content, it's required to provide a reason.
 36
 37## Installation
 38
 39You need both the binary and the prompt.
 40
 41### The binary
 42
 43- Using [bin](https://github.com/marcosnils/bin) (highly recommended
 44  because of centralised management/updates for statically-linked CLI tools like
 45  this)
 46  ```bash
 47  bin install goinstall://git.secluded.site/np@latest
 48  ```
 49- Using the [go toolchain](https://go.dev/dl) (requires
 50  tracking updates manually)
 51  ```bash
 52  go install git.secluded.site/np@latest
 53  ```
 54
 55### The prompt
 56
 57Paste this into some section of your `~/.config/AGENTS.md` or
 58`~/.claude/CLAUDE.md` or whatever titled something like `## nasin pali (the way
 59of work)`.
 60
 61- Using `bin`
 62  ```markdown
 63  IMPORTANT: If I ask you to `use np` or `use nasin pali` or some variation, you must completely ignore your built-in TODO tools and exclusively use what `np` provides. Try to use it, but if it's not in my PATH, ask me to install it with `bin install goinstall://git.secluded.site/np@latest`. If I've ask you to use it, start a session with `np s` and it'll guide you from there. If I haven't asked you to use it, proceed normally.
 64  ```
 65- Using `go install`
 66  ```markdown
 67  IMPORTANT: If I ask you to `use np` or `use nasin pali` or some variation, you must completely ignore your built-in TODO tools and exclusively use what `np` provides. Try to use it, but if it's not in my PATH, ask me to install it with `go install git.secluded.site/np@latest`. If I've ask you to use it, start a session with `np s` and it'll guide you from there. If I haven't asked you to use it, proceed normally.
 68  ```
 69
 70---
 71
 72## Overview
 73
 74_nasin pali_, pronounced _NAH-sin PAH-lee_ and installed as `np`, is a CLI tool
 75that encourages LLMs in agentic coding tools (specifically coding, I don't think
 76we want to support generic workflows) to do a bit more planning before going off
 77and making a bunch of changes. It is _both_ meant for humans and LLMs; there are
 78subcommands that produce output for the model and subcommands for the human to
 79inspect the model's progress. There's a section on [the name](#the-name) if
 80you're curious about it.
 81
 82The todo systems built into agentic coding tools are often just that: todo and
 83nothing else. I think (backed by no evidence) that they do better when they can
 84also set a goal. If I understand the coding tools correctly, they also have the
 85LLM reproduce the entire task list with each `todo_write` invocation, which just
 86seems wasteful and careless to me. What if it decides it doesn't want to do a
 87task because it's "too hard" and it just omits that task next time it writes the
 88list? _nasin pali_ helps force the model into a different overall flow.
 89
 90## Expected workflow
 91
 92_This is what I like, I'd be happy to hear of other workflows that lead to
 93better/different success and to consider whether nasin pali can support them_
 94
 95The operator is expected to load the prompt up with relevant text. Type the
 96issue in the prompt, paste the bug report, tell it how to fetch the issue from
 97your issue tracker, whatever you like. If the issue content is too sparse, make
 98sure to add more context. The more context you give and the higher its quality
 99and relevancy, the better results you'll have. Include paths to as many files
100you know will be relevant as possible. Mention particular symbols, paste
101snippets of code, etc. Once your prompt looks good, send it off.
102
103In the `np` section of the model's rules, we'll have instructions to
104_immediately_ run start a session if the operator says to `use np` or something
105similar. Each command further in the flow reveals the next step as instructions.
106`np s` tells the model to set an overarching goal with `np g s -t title -d
107description` that captures the operator's request, combining the information
108from the ticket and any extra operator-provided context. If there's a ticket ID,
109that goes in the goal description. The output of `np g s` says to look at the
110provided references, thoroughly consider how to go about resolving the goal, and
111gather additional context from other files if necessary. Once it has a good idea
112how to resolve the goal, it should add some tasks with `np t a -t title -d
113description -t title2 -d description2`. The descriptions are good places to
114reference files and symbols. The output of `np t a` tells it to update tasks as
115it works on them with something like `np t u -i task-id -s status`.
116
117Commands that modify the model's goal or list output the full changed plan
118(formatted [like so](#the-format-the-model-sees)) so it doesn't have to run
119another command to check, obviating patterns like `git status` after every `git
120commit`. It can use `np p` to check the plan (goal, desc, remaining tasks,
121descs) and use `np t -s status` to filter to `pending`, `in progress`,
122`completed`, `all`, etc. tasks, but usually doesn't need to because we
123immediately show it after every modification.
124
125Resume an interrupted session in a _new_ context window by telling the model to
126run `np r`. This outputs the full plan, provides relevant usage instructions,
127and tells the model to "check above" for a bug/issue/ticket ID in the goal
128description. If present, read that. Then read the files/symbols referenced in
129the pending tasks to get a good idea of what work is left.
130
131Once finished, the operator or model (I'm not sure which yet, see next section)
132archives the session with `np a`.
133
134## Details
135
136### Session scoping
137
138Each session is working-directory-scoped so neither the model nor the human
139_have_ to provide a session ID or something for each invocation like `np s -s
140session-id -t title -d description`. This is why there are `np s` and `np a`
141commands for `s`tarting and `a`rchiving a session. There can only be one session
142in progress per directory, so worktrees allow for parallel sessions.
143
144I'm unsure who should archive the session. I like the idea of requiring the
145operator to, meaning we can leave that bit out of the model's rules, but maybe
146the coding tool has no way for the operator to execute shell commands. In that
147case, they'd have to type the whole thing to the model or quit/open a new shell
148to archive themselves before the model can start a new session. Maybe telling
149the model about the archival command, but to never run it without explicit
150instruction from the operator, would be sufficient.
151
152### Global database with events
153
154Sessions, plans, goals, tasks, everything is stored in a shared
155[Badger](github.com/hypermodeinc/badger) database in
156`$XDG_CONFIG_HOME/nasin-pali/`.
157
158Every LLM-oriented sub-command is tracked as an event. Sub-commands that do
159anything to modify either created tasks or set goals require a reason ("operator
160said so" is insufficiently detailed, but otherwise acceptable) to go with those
161events.
162
163### Event rendering
164
165The interactive, human-focused sub-commands (for now, just `m` for `m`onitor),
166are for watching the events and the resulting list as they change in
167real-time-ish. The goal and description and tasks and their descriptions are
168rendered at the top of the UI and updated based on database events using some
169Charm libraries. Change events are underneath the rendered state, sorted most
170recent (top) to least recent (bottom).
171
172This will probably be implemented later, once the LLM-oriented planning commands
173are solid and I see regular success with them.
174
175### The format the model sees
176
177It uses individual unicode symbols to represent task statuses. This costs one
178token per status where more verbose checkboxes `- [x]` or words `completed`
179might use more. The failed icon (``) and cancelled icon (``) are only shown in
180the legend if there are actually failed or cancelled tasks in the list.
181
182```
183Create a comprehensive MCP server for task planning and management
184
185Legend: ☐ pending  ⟳ in progress  ☑ completed
186☑ Set up project structure [a1b2c3d4]
187  Create Go module, directories, and basic files
188⟳ Implement core planning logic [e5f6g7h8]
189  Create Goal and Task data structures with deterministic IDs
190☐ Build MCP server integration [i9j0k1l2]
191```
192
193## The name
194
195Is from [toki pona](https://tokipona.org/), _a simple language_, and pronounced
196_NAH-sin PAH-lee_. [_nasin_](https://nimi.li/nasin) occupies the semantic space
197of "method, doctrine, tradition; path, road, way" while
198[_pali_](https://nimi.li/pali) covers "work, activity; create, build, design;
199put effort toward, take action on". Together and in this context, _nasin pali_
200could be translated as "the way of work", "the doctrine of design", etc.
201
202## Random thoughts
203
204- When providing multiple lines for the body, use
205
206  ```bash
207  np g s -t "Sentence case title" -d "$(cat <<'EOF'
208  Multi-line
209  - Body
210  - Here
211
212  EOF
213  )"
214  ```