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