README.md

nasin pali (the way of work)

REUSE status Go Report Card

This README is aspirational! None of the code exists yet, I'm just getting my ideas down. I previously wrote a planning-mcp-server that I'll keep some ideas from, and the overall workflow is about the same. I'm trying a CLI over MCP because MCP seems quite protocol-heavy for what could just be a few simple CLI invocations. Maybe connecting arbitrary data sources warrants a whole protocol like MCP, but I don't think something as basic as this does. Just some thoughtful design and prompting.


Overview

nasin pali, installed as np, is a CLI tool that encourages LLMs in agentic coding tools (specifically coding, I don't think we want to support generic workflows) to do a bit more planning before going off and making a bunch of changes. It is both meant for humans and LLMs; there are subcommands that produce output for the model and subcommands for the human to inspect the model's progress. There's a section on the name if you're curious about it.

The todo systems built into agentic coding tools are often just that: todo and nothing else. I think (backed by no evidence) that they do better when they can also set a goal. If I understand the coding tools correctly, they also have the LLM reproduce the entire task list with each todo_write invocation, which just seems wasteful and careless to me. What if it decides it doesn't want to do a task because it's "too hard" and it just omits that task next time it writes the list? nasin pali helps force the model into a different overall flow.

Expected workflow

This is what I like, I'd be happy to hear of other workflows that lead to better/different success and to consider whether nasin-pali can support them

The operator is expected to load the prompt up with relevant text. Type the issue in the prompt, paste the bug report, tell it how to fetch the issue from your issue tracker, whatever you like. If the issue content is too sparse, make sure to add more context. The more context you give and the higher its quality and relevancy, the better results you'll have. Include paths to as many files you know will be relevant as possible. Mention particular symbols, paste snippets of code, etc. Once your prompt looks good, send it off.

In the np section of the model's rules, we'll have instructions to immediately run np s, which outputs some LLM-oriented instructions for use. It first tells the model to set an overarching goal with np g s -t title -d description that captures the operator's request, combining the information from the ticket and any extra operator-provided context. Then it should go off and look at the provided references and thoroughly consider how to go about resolving the goal. After gathering that context, it adds tasks with np t a -t title -d description -t title2 -d description2 and gets started on them.

As it works through the tasks, it's expected to update statuses by ID with something like np t u -i id -s status. Commands that modify the model's plan output the revision so it can immediately see the result of its invocation without running another command (obviating patterns like running git status after every git commit). Format the list something like this, using individual unicode symbols to represent task statuses using one token per status instead of more verbose checkboxes - [x] or words completed that might use more tokens. The failed icon () and cancelled icon () are only shown in the legend if there are actually failed or cancelled tasks in the list.

Create a comprehensive MCP server for task planning and management

Legend: ☐ pending  ⟳ in progress  ☑ completed
☑ Set up project structure [a1b2c3d4]
  Create Go module, directories, and basic files
⟳ Implement core planning logic [e5f6g7h8]
  Create Goal and Task data structures with deterministic IDs
☐ Build MCP server integration [i9j0k1l2]

I'm unsure how to handle session archival (mentioned in random thoughts). We could tell the model how to archive sessions in the rules, but I don't know that the model even needs to know about sessions; maybe archival should require human interaction. If the model can't archive sessions, and the agentic coding tool doesn't have a way for the operator to execute shell commands, they'd have to quit or open a new shell to run that command before the model can create a new session. Maybe telling it about the archival command, but to never run it without operator interaction, would be sufficient.

Every LLM-oriented sub-command is tracked as an event in a global SQLite database in $XDG_CONFIG_HOME/nasin-pona/. Sub-commands that do anything to modify either created tasks or set goals require a reason ("operator said so" is insufficiently detailed, but otherwise acceptable).

The interactive, human-focused sub-commands are for watching these events and the resulting list as they change in realtime, and for exporting a session with all of its events as Markdown. The goal and description and tasks and their descriptions are rendered at the top of the UI and updated based on database events using some Charm libraries. Change events are underneath the rendered state, sorted most recent (top) to least recent (bottom).

Each session is working-directory-scoped so the model doesn't have to provide a session ID or something for each invocation. This is why there are np s and np a commands for starting and archiving a session. Worktrees allow for parallel sessions.

The name

Is toki pona. nasin occupies the semantic space of "method, doctrine, tradition; path, road, way" while pali covers "work, activity; create, build, design; put effort toward, take action on". Together and in this context, nasin pali could be translated as "the way of work", "the doctrine of design", etc.

Random thoughts

  • When providing multiple lines for the body, use

    np goal set "Sentence case title" "$(cat <<'EOF'
    Multi-line
    - Body
    - Here
    
    EOF
    )"
    
  • Start a new session with np s. It adds details to the global sqlite database and produces output to guide the LLM through its next steps. Instead of telling the model up-front about everything it can do with nasin pali though AGENTS.md or tool definitions or something, we only reveal the sub-commands and flags it might actually need once it needs them. It shouldn't ever use the interactive commands, so we never tell them model about them.

    • There can be one active session per working directory and the previous session must be archived before starting a new one. This is so the model doesn't have to provide a session ID or something for each invocation.
  • np s tells the model about the goal and task sub-commands and their flags and to begin the session by turning the user's request, bug report, issue contents, spec, etc. into a concise overarching goal with a thorough description.

  • np g s accepts title and description arguments and tells the model to, if necessary, look around at additional relevant files before adding some tasks with np t a. How to provide/require/validate for pairs of -t and -d flags?

  • Have the model update task statuses by ID and render the goal, the updated task, and the remaining tasks in the same format as planning-mcp-server. By default, planning-mcp-server returned all tasks, but I think it would be better to just return the modified one, so the model can see its previous command worked, and the still-open ones. Include a flag or something so it can look at all tasks including the completed ones.