@slenderbuilds/niti 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shubhadeep Datta
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # niti
2
+
3
+ **A terminal CLI that runs multiple AI coding agents — from different LLM providers — concurrently on one project.**
4
+
5
+ Assign models to custom roles (Gemini = Frontend, Claude = Backend, GPT = Reviewer...), pick one as the **orchestrator** to plan the work into a task DAG, and watch the team build together, **talking to each other directly** to stay aligned — live in your terminal, or in an optional web dashboard.
6
+
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](#license)
8
+ [![Bun](https://img.shields.io/badge/core-Bun%20%2F%20TypeScript-f9f1e1)](#two-front-ends-one-core)
9
+ [![Go](https://img.shields.io/badge/TUI-Go%20%2F%20Bubbletea-00add8)](#two-front-ends-one-core)
10
+
11
+ <img src="readme_images/CLI.png" alt="niti's terminal UI — team of 4 agents, live context/token sidebar" width="100%">
12
+
13
+ ## Quickstart
14
+
15
+ ```sh
16
+ npm install -g @slenderbuilds/niti # prebuilt binaries — no Bun, no Go, no build step
17
+ niti # pick your team, then start building
18
+ ```
19
+
20
+ > Published as **`@slenderbuilds/niti`** — the unscoped `niti` was rejected by npm's own
21
+ > anti-squatting check (too similar to `jiti`/`vite`/others), and it suggested this scope. The
22
+ > commands are still `niti` (TUI) and `niti-core` (headless engine); project state still lives
23
+ > in `.niti/` — only the install name changed.
24
+
25
+ On first launch, `niti` opens a picker: how many teammates (1–6), then per teammate — provider,
26
+ model, name, and a one-line job description. **29 providers / 152 models** from the
27
+ [Models.dev](https://models.dev) catalog, plus local (Ollama/LM Studio) and **Custom** for any
28
+ OpenAI-compatible endpoint. Keys live in `~/.config/niti/auth.json` (0600) and your OS keychain —
29
+ never a server.
30
+
31
+ Type `/` for the full command list:
32
+
33
+ <img src="readme_images/commands.png" alt="the / command palette, listing every slash command" width="100%">
34
+
35
+ ## Watch it from the browser too
36
+
37
+ `/dashboard` opens a live control center — agent avatars, message graph, task board, and per-agent
38
+ usage, all pushed over SSE as the team works:
39
+
40
+ <img src="readme_images/dashboardniti.png" alt="the web dashboard — live agent graph with task/message/usage panels" width="100%">
41
+
42
+ `/graph` opens an interactive force-graph — your project's file/import structure, or (toggle to
43
+ **Models**) the live agent-to-agent conversation as it happens:
44
+
45
+ <table>
46
+ <tr>
47
+ <td width="50%"><img src="readme_images/graph1.png" alt="project mode: 137-file dependency graph"></td>
48
+ <td width="50%"><img src="readme_images/graph2.png" alt="models mode: live pixel-art agent avatars, message-colored edges"></td>
49
+ </tr>
50
+ <tr>
51
+ <td>Project mode — every file, colored by directory</td>
52
+ <td>Models mode — your team, colored by status, talking in real time</td>
53
+ </tr>
54
+ </table>
55
+
56
+ Both pages retheme live with whatever theme (`ctrl+t` / `/theme`) the TUI has active.
57
+
58
+ ## Everything, at a glance
59
+
60
+ `/settings` (or `tab`) opens Status, Config, Usage, and Stats panes without leaving the session:
61
+
62
+ <table>
63
+ <tr>
64
+ <td width="33%"><img src="readme_images/status.png" alt="Status tab — version, team, mode, theme, models"></td>
65
+ <td width="33%"><img src="readme_images/usage.png" alt="Usage tab — session cost, tokens, per-agent breakdown"></td>
66
+ <td width="34%"><img src="readme_images/stats_models.png" alt="Stats tab — tokens per day, tokens by model"></td>
67
+ </tr>
68
+ </table>
69
+
70
+ ## What's actually happening under the hood
71
+
72
+ - **Orchestrator DAG** — the lead agent turns your goal into a validated task graph (dependencies +
73
+ hand-offs), not a flat queue; independent tasks run concurrently and the lead reviews at the end.
74
+ - **Agent-to-agent messaging** — any teammate can `ask_agent`/`send_message` another mid-task (e.g.
75
+ frontend asking backend about an API shape), rate-capped per pair as the loop guard.
76
+ - **Sandboxed tools** — `read_file` / `write_file` / `edit` / `shell`, gated per-agent by
77
+ `allowedTools` and a wildcard permission policy; every path is jailed to the project root.
78
+ - **Approval gates** — agents pause for `[y] approve · [n] deny · [a] always` before risky actions,
79
+ answered from the TUI or the web dashboard; dangerous shell patterns always prompt.
80
+ - **Persistence** — every turn checkpoints to SQLite (`.niti/niti.db`); `niti-core resume` picks up
81
+ unfinished tasks with history intact. `/undo` and `/rewind` revert file writes.
82
+ - **MCP + LSP** — declare `mcpServers`/`lsp` in `agents.yaml`; both merge into the same tool loop,
83
+ gated the same way as everything else.
84
+ - **Failover** — a 429/overload/context-limit requeues the task instead of failing it; another agent
85
+ picks it up.
86
+
87
+ See [`project_context.md`](./project_context.md) for the full architecture record, the verification
88
+ history, and the deliberate ceilings (what's intentionally out of scope, and why).
89
+
90
+ ## Configuring agents
91
+
92
+ `niti` rewrites only the `agents:` block on each team pick — everything else survives a relaunch.
93
+ Edit `.niti/agents.yaml` directly for anything the picker doesn't cover:
94
+
95
+ ```yaml
96
+ agents:
97
+ - id: architect
98
+ provider: anthropic
99
+ model: claude-opus-4-8
100
+ role: Architect
101
+ lead: true
102
+ systemPrompt: You are a software architect. Decompose work into independent subtasks.
103
+ - id: engineer
104
+ provider: openai
105
+ model: gpt-4o
106
+ role: Backend Engineer
107
+ systemPrompt: You are a backend engineer. Implement the assigned task.
108
+ allowedTools: [read_file, write_file, edit, shell, mcp]
109
+
110
+ permissions:
111
+ shell: { "git *": allow, "git commit *": ask, "rm -rf*": deny }
112
+ write_file: { "src/**": allow, "*": ask }
113
+
114
+ mcpServers:
115
+ - name: code-review
116
+ command: code-review-graph
117
+ args: [--stdio]
118
+
119
+ theme: niti # ctrl+t / /theme opens a live carousel, synced to any open dashboard/graph tab
120
+ auto: false # approve anything not explicitly denied
121
+ maxAgents: 6
122
+ ```
123
+
124
+ Full config reference — permissions resolution order, environment variables, LSP setup — lives in
125
+ [`project_context.md`](./project_context.md).
126
+
127
+ ## From source
128
+
129
+ Requires [Bun](https://bun.sh) ≥ 1.3 and [Go](https://go.dev) ≥ 1.22.
130
+
131
+ ```sh
132
+ bun install
133
+ bun run build:tui # builds ./niti (the Go TUI)
134
+ ./niti
135
+ ```
136
+
137
+ Headless / scripting, no interactive terminal needed:
138
+
139
+ ```sh
140
+ bun run src/cli.ts "Build a clothing website for gen-z." # one-shot
141
+ bun run src/cli.ts --web "..." # + live web dashboard
142
+ bun run src/server/main.ts # headless server, prints its own handshake URL
143
+ ```
144
+
145
+ ## Development
146
+
147
+ ```sh
148
+ bun test # TypeScript unit + integration tests
149
+ bunx tsc --noEmit # typecheck
150
+ cd tui && go build ./... && go vet ./... && go test ./... # Go TUI: build, vet, unit tests
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ // The headless engine/scripting CLI (`niti-core "task"`, `serve`, `auth`, …). Same handover as
3
+ // bin/niti.js — the TUI spawns this binary directly as a sibling, without going through Node.
4
+ import { spawnSync } from "node:child_process";
5
+ import { binPath } from "./resolve.js";
6
+
7
+ process.exit(spawnSync(binPath("niti-core"), process.argv.slice(2), { stdio: "inherit" }).status ?? 1);
package/bin/niti.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ // The interactive TUI. Node runs this shim; everything after the handover is Go and Bun.
3
+ import { spawnSync } from "node:child_process";
4
+ import { binPath } from "./resolve.js";
5
+
6
+ process.exit(spawnSync(binPath("niti"), process.argv.slice(2), { stdio: "inherit" }).status ?? 1);
package/bin/resolve.js ADDED
@@ -0,0 +1,32 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const require = createRequire(import.meta.url);
4
+
5
+ // This package ships no binaries. The real executables live in per-platform packages
6
+ // (`niti-darwin-arm64`, …) declared as optionalDependencies with `os`/`cpu` set, so npm installs
7
+ // exactly the one that matches and skips the other four.
8
+ //
9
+ // PLATFORM_BASE is deliberately NOT derived from this package's own `name`: the root wrapper is
10
+ // published as a scoped package (`@slenderbuilds/niti`, npm's own suggestion — the unscoped `niti`
11
+ // collided with its squatting-prevention check against jiti/vite/nib/…), but the five platform
12
+ // packages are unscoped (`niti-darwin-arm64`, …) and were already published under that name before
13
+ // the scope existed. `${name}-${platform}` would have produced `@slenderbuilds/niti-darwin-arm64`,
14
+ // which is not a real package — see scripts/build-release.ts, which publishes under this same
15
+ // hardcoded base.
16
+ const PLATFORM_BASE = "niti";
17
+
18
+ export function binPath(exe) {
19
+ const platformPkg = `${PLATFORM_BASE}-${process.platform}-${process.arch}`;
20
+ const ext = process.platform === "win32" ? ".exe" : "";
21
+ try {
22
+ return require.resolve(`${platformPkg}/bin/${exe}${ext}`);
23
+ } catch {
24
+ console.error(
25
+ `niti: no prebuilt binary for ${process.platform}-${process.arch} (looked for ${platformPkg}).\n` +
26
+ `Supported: darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64.\n` +
27
+ `If your platform is on that list, reinstall — npm sometimes skips optional dependencies ` +
28
+ `(https://github.com/npm/cli/issues/4828).`,
29
+ );
30
+ process.exit(1);
31
+ }
32
+ }
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@slenderbuilds/niti",
3
+ "version": "0.1.0",
4
+ "description": "A terminal CLI that runs multiple AI coding agents from different LLM providers concurrently on one project.",
5
+ "type": "module",
6
+ "bin": {
7
+ "niti": "bin/niti.js",
8
+ "niti-core": "bin/niti-core.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "dev": "bun run src/cli.ts",
17
+ "serve": "bun run src/server/main.ts",
18
+ "build": "bun build --compile ./src/cli.ts --outfile niti-core",
19
+ "build:tui": "cd tui && go mod tidy && go build -o ../niti ./cmd/niti",
20
+ "build:all": "bun run build:tui && bun run build",
21
+ "build:release": "bun run scripts/build-release.ts",
22
+ "test": "bun test src web",
23
+ "typecheck": "tsc --noEmit",
24
+ "gen:catalog": "bun run scripts/gen-catalog.ts"
25
+ },
26
+ "engines": {
27
+ "node": ">=18"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/slenderongithub/niti.git"
32
+ },
33
+ "homepage": "https://github.com/slenderongithub/niti#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/slenderongithub/niti/issues"
36
+ },
37
+ "keywords": [
38
+ "ai",
39
+ "agents",
40
+ "cli",
41
+ "tui",
42
+ "llm",
43
+ "coding-agent",
44
+ "multi-agent",
45
+ "anthropic",
46
+ "openai",
47
+ "gemini"
48
+ ],
49
+ "author": "Shubhadeep Datta <slenderisincollege@gmail.com>",
50
+ "license": "MIT",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "optionalDependencies": {
55
+ "niti-darwin-arm64": "0.1.0",
56
+ "niti-darwin-x64": "0.1.0",
57
+ "niti-linux-arm64": "0.1.0",
58
+ "niti-linux-x64": "0.1.0",
59
+ "niti-win32-x64": "0.1.0"
60
+ },
61
+ "devDependencies": {
62
+ "@anthropic-ai/sdk": "^0.115.0",
63
+ "@google/genai": "^2.13.0",
64
+ "@modelcontextprotocol/sdk": "^1.30.0",
65
+ "@napi-rs/keyring": "^1.3.0",
66
+ "@types/bun": "^1.3.14",
67
+ "openai": "^7.0.0",
68
+ "typescript": "^7.0.2",
69
+ "yaml": "^2.9.0",
70
+ "zod": "^4.4.3"
71
+ }
72
+ }