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