@niroai/niro 0.17.0 → 1.0.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.
Files changed (177) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +123 -302
  3. package/bin/niro.js +12 -1
  4. package/docs/agent-antigravity.md +37 -0
  5. package/docs/agent-claude-code.md +48 -0
  6. package/docs/agent-claude-desktop.md +47 -0
  7. package/docs/agent-cline.md +42 -0
  8. package/docs/agent-codex.md +45 -0
  9. package/docs/agent-copilot-cli.md +42 -0
  10. package/docs/agent-cursor.md +44 -0
  11. package/docs/agent-factory.md +42 -0
  12. package/docs/agent-gemini-cli.md +42 -0
  13. package/docs/agent-goose.md +42 -0
  14. package/docs/agent-kiro.md +37 -0
  15. package/docs/agent-opencode.md +37 -0
  16. package/docs/agent-vscode.md +45 -0
  17. package/docs/agent-windsurf.md +38 -0
  18. package/docs/answer-shapes.md +69 -0
  19. package/docs/builds-and-updates.md +68 -0
  20. package/docs/cloud-README.md +372 -0
  21. package/docs/configuring-a-folder.md +51 -0
  22. package/docs/connect-ci.md +24 -0
  23. package/docs/connect-overview.md +20 -0
  24. package/docs/connect-review-bots.md +17 -0
  25. package/docs/connect-team-server.md +12 -0
  26. package/docs/connect-terminal.md +49 -0
  27. package/docs/connect-web-agents.md +9 -0
  28. package/docs/connect-your-ai-assistant.md +59 -175
  29. package/docs/coverage-audit-and-consent.md +51 -0
  30. package/docs/evaluate-what-niro-did.md +271 -0
  31. package/docs/faq-assistants-and-mcp.md +122 -0
  32. package/docs/faq-feedback-and-receipts.md +33 -0
  33. package/docs/faq-indexing.md +127 -0
  34. package/docs/faq-install-and-setup.md +103 -0
  35. package/docs/faq-licence-and-plans.md +86 -0
  36. package/docs/faq-login-and-account.md +69 -0
  37. package/docs/faq-offline.md +34 -0
  38. package/docs/faq-performance.md +33 -0
  39. package/docs/faq-privacy-and-security.md +113 -0
  40. package/docs/faq-uninstall.md +47 -0
  41. package/docs/faq-updates.md +59 -0
  42. package/docs/faq-worktrees-and-branches.md +59 -0
  43. package/docs/faq-wrong-or-missing-answers.md +275 -0
  44. package/docs/hosted-only.md +33 -0
  45. package/docs/how-the-graph-works.md +47 -0
  46. package/docs/index.md +157 -0
  47. package/docs/licence-and-plans.md +72 -0
  48. package/docs/lifecycle-debug.md +48 -0
  49. package/docs/lifecycle-onboarding.md +32 -0
  50. package/docs/lifecycle-overview.md +77 -0
  51. package/docs/lifecycle-plan-and-design.md +44 -0
  52. package/docs/lifecycle-review.md +30 -0
  53. package/docs/lifecycle-security-and-privacy.md +35 -0
  54. package/docs/lifecycle-test.md +28 -0
  55. package/docs/lifecycle-write-code.md +35 -0
  56. package/docs/llms-full.txt +8015 -0
  57. package/docs/llms.txt +126 -0
  58. package/docs/playbook-add-a-feature.md +108 -0
  59. package/docs/playbook-change-safely.md +93 -0
  60. package/docs/playbook-data-and-events.md +107 -0
  61. package/docs/playbook-debug-after-a-change.md +96 -0
  62. package/docs/playbook-debug-config.md +95 -0
  63. package/docs/playbook-debug-exception.md +124 -0
  64. package/docs/playbook-debug-failing-service-call.md +119 -0
  65. package/docs/playbook-debug-slow-path.md +80 -0
  66. package/docs/playbook-debug-wrong-value.md +137 -0
  67. package/docs/playbook-onboard.md +95 -0
  68. package/docs/playbook-review-a-change.md +72 -0
  69. package/docs/playbook-test-a-change.md +73 -0
  70. package/docs/reference-cli.md +113 -0
  71. package/docs/reference-config-files.md +42 -0
  72. package/docs/reference-engine-commands.md +56 -0
  73. package/docs/reference-environment-variables.md +89 -0
  74. package/docs/reference-exit-codes.md +67 -0
  75. package/docs/reference-limits.md +75 -0
  76. package/docs/reference-mcp-tools.md +326 -0
  77. package/docs/reference-messages.md +180 -0
  78. package/docs/secrets-and-masking.md +48 -0
  79. package/docs/supported-c.md +130 -0
  80. package/docs/supported-cpp.md +157 -0
  81. package/docs/supported-csharp.md +211 -0
  82. package/docs/supported-go.md +258 -0
  83. package/docs/supported-java.md +226 -0
  84. package/docs/supported-javascript.md +223 -0
  85. package/docs/supported-kotlin.md +124 -0
  86. package/docs/supported-overview.md +89 -0
  87. package/docs/supported-php.md +157 -0
  88. package/docs/supported-python.md +224 -0
  89. package/docs/supported-ruby.md +162 -0
  90. package/docs/supported-rust.md +150 -0
  91. package/docs/supported-swift.md +133 -0
  92. package/docs/supported-typescript.md +220 -0
  93. package/docs/tokens-speed-and-accuracy.md +99 -0
  94. package/docs/troubleshooting.md +42 -0
  95. package/docs/uninstall.md +74 -0
  96. package/docs/what-leaves-your-machine.md +71 -0
  97. package/docs/where-things-are-stored.md +59 -0
  98. package/docs/worktrees-and-branches.md +55 -0
  99. package/package.json +5 -3
  100. package/src/commands/add-repo.js +5 -0
  101. package/src/commands/auditSend.js +67 -0
  102. package/src/commands/build.js +6 -0
  103. package/src/commands/docsSend.js +73 -0
  104. package/src/commands/engine.js +120 -0
  105. package/src/commands/engineRoutes.js +105 -0
  106. package/src/commands/guide.js +254 -0
  107. package/src/commands/init.js +6 -2
  108. package/src/commands/initLocal.js +96 -0
  109. package/src/commands/journalSend.js +47 -0
  110. package/src/commands/login.js +89 -12
  111. package/src/commands/mcp.js +22 -6
  112. package/src/commands/plan.js +99 -0
  113. package/src/commands/repoPush.js +33 -0
  114. package/src/commands/requestIntegration.js +38 -0
  115. package/src/commands/share.js +56 -0
  116. package/src/commands/start.js +451 -371
  117. package/src/commands/status.js +57 -0
  118. package/src/commands/takeover.js +6 -0
  119. package/src/commands/uninstall.js +180 -0
  120. package/src/commands/upgrade.js +38 -8
  121. package/src/commands/watch.js +420 -6
  122. package/src/index.js +174 -3
  123. package/src/lib/agentApi.js +32 -1
  124. package/src/lib/api.js +20 -6
  125. package/src/lib/auditUpload.js +293 -0
  126. package/src/lib/branchDrift.js +149 -0
  127. package/src/lib/choose.js +116 -0
  128. package/src/lib/cloudGuard.js +74 -0
  129. package/src/lib/credentials.js +2 -2
  130. package/src/lib/docsMarked.js +55 -0
  131. package/src/lib/docsState.js +213 -0
  132. package/src/lib/docsUpload.js +481 -0
  133. package/src/lib/engine.js +619 -0
  134. package/src/lib/folderSync.js +2 -1
  135. package/src/lib/graphCheck.js +40 -0
  136. package/src/lib/guide.js +293 -0
  137. package/src/lib/guideSearch.js +252 -0
  138. package/src/lib/integrationRequest.js +89 -0
  139. package/src/lib/journalUpload.js +147 -0
  140. package/src/lib/languages.js +129 -0
  141. package/src/lib/lease.js +375 -0
  142. package/src/lib/localBuild.js +285 -0
  143. package/src/lib/localEngine.js +210 -0
  144. package/src/lib/localOnboard.js +124 -0
  145. package/src/lib/localWorktrees.js +243 -0
  146. package/src/lib/machineCheck.js +58 -0
  147. package/src/lib/mcpClients.js +10 -1
  148. package/src/lib/migrationNotice.js +118 -0
  149. package/src/lib/modelFetch.js +153 -0
  150. package/src/lib/nestedOutput.js +23 -9
  151. package/src/lib/onboardingLog.js +34 -0
  152. package/src/lib/planUsage.js +165 -0
  153. package/src/lib/progressBar.js +46 -0
  154. package/src/lib/prompt.js +1 -1
  155. package/src/lib/redact.js +155 -0
  156. package/src/lib/release.js +33 -0
  157. package/src/lib/repoPush.js +495 -0
  158. package/src/lib/secret.js +1 -1
  159. package/src/lib/service.js +372 -63
  160. package/src/lib/shareCode.js +367 -0
  161. package/src/lib/shareExclusions.js +114 -0
  162. package/src/lib/shareFiles.js +129 -0
  163. package/src/lib/spinner.js +9 -5
  164. package/src/lib/watchDaemon.js +33 -10
  165. package/src/lib/watchState.js +12 -1
  166. package/src/lib/windowsPaths.js +67 -0
  167. package/src/mcp/lineCheck.js +382 -0
  168. package/src/mcp/lineName.js +92 -0
  169. package/src/mcp/localBackend.js +751 -0
  170. package/src/mcp/localMode.js +383 -0
  171. package/src/mcp/localSkill.js +189 -0
  172. package/src/mcp/server.js +610 -79
  173. package/src/mcp/setup.js +519 -131
  174. package/src/mcp/shellSearchHook.js +509 -0
  175. package/src/mcp/teardown.js +173 -91
  176. package/src/mcp/usingNiro.js +39 -0
  177. package/docs/working-on-branches.md +0 -162
@@ -0,0 +1,69 @@
1
+ # Ask for less: the `answer` input
2
+
3
+ **Most questions need only part of an answer.** An agent often wants to know whether something exists, how many there are, or where they are. The full answer also carries signatures, notes and sometimes code. The `answer` input asks a tool for a short form of the same list.
4
+ <!-- source: niro-local docs/usecases/answer-shapes.md "What it is" (43cce717) -->
5
+
6
+ **An everyday comparison:** asking a librarian "how many books do you have on this?" instead of "bring me every book on this".
7
+
8
+ ## Which tools take it
9
+
10
+ `code_grep`, `get_call_chain`, `get_reverse_call_chain`, `get_blast_radius`, `get_impact_analysis` and `get_class_structure`.
11
+ <!-- source: niro-local src/niro_local/mcp/shapes.py:24-45 (VALUES and the three descriptions); docs/reference-mcp-tools.md (generated from 43cce717, the `answer` rows) -->
12
+
13
+ | Value | What comes back | Use it when |
14
+ |---|---|---|
15
+ | `exists` | yes or no, with the total | you only need to know whether there is any |
16
+ | `count` | the numbers only | you need "how many" (callers, affected methods, matches, members) |
17
+ | `locations` | one line per entry: `file:line` and the exact id to pass to the next call | you will open a few of them, or ask about one next |
18
+ | `names` | one name per line | you need a list to read, not places |
19
+ | `match` (only `code_grep`) | only the text the pattern matched, at its place | you want the value, not the whole line |
20
+ <!-- source: niro-local src/niro_local/mcp/shapes.py:30-45 -->
21
+
22
+ ## What stays true in a short answer
23
+
24
+ - **The numbers are the full answer's numbers.** They come from the same code. For `code_grep`, the count covers every file searched, not only the page shown.
25
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 4 -->
26
+ - **Notes that change what the numbers mean are kept:** "confidence: partial", the "Not listed" note about calls Niro could not place, and `code_grep`'s PARTIAL and SKIPPED lines.
27
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 6 -->
28
+ - **Every short answer ends with one line in square brackets** saying what was left out and how to get it. For example: `[shown 39 of 100 callers; offset=39 shows the next callers]`.
29
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 7; real answer in the Keycloak run of 2026-11-10 (scratchpad niro-cli-task-playbooks/runs/eval-01-loc.txt) -->
30
+ - **A short answer never carries code.** If you also ask for source (`include_source_code`, or `purpose=DEBUG`), the footer says the code was left out.
31
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 3 -->
32
+ - **A short name that matches several methods is answered once per match,** up to 5. For example, `ErrorResponse.error` in Keycloak has two overloads (methods with the same name and different parameters), and `answer=count` gives a count for each: 100 callers and 3 callers.
33
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 9; `niro-local ask get_reverse_call_chain method_fqn=ErrorResponse.error answer=count` on Keycloak 968726fe66, 2026-11-10 (runs/chg-20-overloads.txt) -->
34
+ - **Without `answer`, every answer is exactly what it was before.**
35
+ <!-- source: niro-local docs/usecases/answer-shapes.md "What must not change"; merge commit 43cce717 ("476 of 476 calls without answer identical") -->
36
+
37
+ ## `purpose` and `answer` together
38
+
39
+ `purpose` chooses which list you get, and `answer` shortens that list. So `answer=count` with `purpose=ASSESS_RISK` gives the same number as the ASSESS_RISK answer would.
40
+ <!-- source: niro-local docs/usecases/answer-shapes.md rule 2 -->
41
+
42
+ ## A real example
43
+
44
+ A search of the Keycloak source (a public Java project) for an error message, asking only how many places hold it:
45
+
46
+ ```
47
+ niro ask code_grep pattern="User exists with same" answer=count
48
+ 10 matching lines in 4 files in the files searched so far
49
+ PARTIAL: the search stopped at its 1.5 s limit after 9793 of 11045 file(s) ...
50
+ [counts only; ask without answer= for the list]
51
+ ```
52
+ <!-- source: runs/exc-01-grep-count.txt (Keycloak 968726fe66, niro-local 43cce717, 2026-11-10; `niro ask` passes its words to the same engine command, src/commands/engineRoutes.js:28) -->
53
+
54
+ The PARTIAL line is kept, because it changes what "10" means: it is a floor. `code_grep` stops after a time limit (1.5 seconds a call), so on a busy machine the same search can count fewer, even "0 matching lines" with PARTIAL. A count with PARTIAL never means "none". Call again with the `continue_from` it gives, or pass a folder as `path_pattern` to search less; on a busy machine even one folder can stop early, and the PARTIAL line says so.
55
+ <!-- source: runs/exc-01-grep-count.txt ("Call again with continue_from=9793"); niro-local docs/NIRO-LOCAL-ISSUES.md entry "2026-11-10: code_grep counts change with machine load, and a busy machine can give '0 matching lines ... PARTIAL'" (OPEN, committed f1a9fe59); scratchpad niro-cli-task-playbooks-check/reruns (claim check round 1: 59 of 59 graph-tool reruns byte-identical, 7 code_grep reruns differed under load 17 to 30) -->
56
+
57
+ The graph tools have no such limit: the same question on the same graph gives the same answer.
58
+ <!-- source: niro-local docs/NIRO-LOCAL-ISSUES.md entry "2026-11-10: code_grep counts change with machine load, and a busy machine can give '0 matching lines ... PARTIAL'" (OPEN, committed f1a9fe59); scratchpad niro-cli-task-playbooks-check/reruns (claim check round 1: 59 of 59 graph-tool reruns byte-identical, 7 code_grep reruns differed under load 17 to 30) -->
59
+ <!-- source: runs/exc-01-grep-count.txt; runs/exc-03-grep-full.txt (path_pattern=services/, no PARTIAL line) -->
60
+
61
+ ## How much it saves
62
+
63
+ It depends on the question and on your code: a count is a line or two, while a full list names every entry. The shapes were chosen by reading recorded calls from real sessions with what the agent did next, and checking which short form still held what the agent then used. How that was measured is in [tokens-speed-and-accuracy.md](tokens-speed-and-accuracy.md).
64
+ <!-- source: scratchpad niro-local-answer-shapes/page-data.json and BRIEF.md (the trial); niro-local docs/usecases/answer-shapes.md "What the replay showed" -->
65
+
66
+ ## Not in this release
67
+
68
+ Line filters (keep only lines matching a pattern, or the first N lines) were planned and not built.
69
+ <!-- source: niro-local docs/usecases/answer-shapes.md "Not in this change" (parked by Niraj, D6) -->
@@ -0,0 +1,68 @@
1
+ # Builds and updates
2
+
3
+ **Niro keeps the graph in step with your files by rebuilding it in the background.** You rarely need to run a build yourself.
4
+
5
+ ## The first build
6
+
7
+ `niro start` builds the folder you are in. `niro init <folder>` adds and builds another folder.
8
+ <!-- source: src/commands/start.js:61; src/index.js:490-502 -->
9
+
10
+ The measured time for a full build of a repository of about 9,000 files is about 103 seconds.
11
+ <!-- source: niro-local TODO.md:189 -->
12
+
13
+ ## Keeping it current
14
+
15
+ - **Who does it.** `niro start` installs a background watcher called `niro-watch`. It is run by PM2, a tool that keeps programs running in the background.
16
+ <!-- source: src/commands/start.js:390-411; src/lib/watchDaemon.js:34-79 -->
17
+ - **When it starts.** Where it can, the watcher starts again every time you log in.
18
+ <!-- source: src/lib/watchDaemon.js:75-79 -->
19
+ - **When it rebuilds.** About 3 seconds after a folder stops changing. Only one build runs at a time. If files change during a build, one more build is queued.
20
+ <!-- source: src/lib/localBuild.js:16-21, :36 (NIRO_LOCAL_BUILD_SETTLE_MS, default 3000) -->
21
+ - **Missed changes.** Every 5 minutes it also checks for changes it may have missed.
22
+ <!-- source: src/lib/localBuild.js:46 (NIRO_LOCAL_RECHECK_MS, default 300000) -->
23
+ - **On start.** When the watcher starts, it builds every folder once.
24
+ <!-- source: src/commands/watch.js:578 -->
25
+ - **Folders that go away.** A folder deleted from disk stops being watched.
26
+ <!-- source: src/commands/watch.js:594-596 -->
27
+
28
+ `niro status` shows whether the watcher is running. If it is not, run `niro service install`.
29
+ <!-- source: src/commands/status.js:35-40 -->
30
+
31
+ ## A rebuild does only what is needed
32
+
33
+ **A rebuild processes the files that changed, and everything connected to them.** The result is the same graph a full build would give. To parse every file again anyway, run:
34
+
35
+ ```
36
+ niro build --full
37
+ ```
38
+ <!-- source: niro-local CLAUDE.md ("An incremental build processes what changed and everything connected to it, and must equal a full build"); src/index.js:517-527 (--full) -->
39
+
40
+ ## How Niro notices changes
41
+
42
+ Niro reads your files to see what changed. **It never runs git, and never reads your history.** It reads three small git files:
43
+
44
+ - `.git/HEAD`, to know your branch;
45
+ - `.git/index`, to know which files git tracks, so that it applies `.gitignore` the way git does;
46
+ - `.git/config`, to tell two copies of one repository apart.
47
+ <!-- source: niro-local CLAUDE.md amendments 2026-11-03, 2026-11-04, 2026-11-07; src/niro_local/repository_identity.py:1-24; src/niro_local/gitindex.py -->
48
+
49
+ ## While a build runs
50
+
51
+ During a full build, the graph is being rewritten. Most tools then say so instead of answering, and suggest searching files for that request. `get_index_status`, `code_grep` and `get_source_code` keep answering. During a smaller rebuild, answers carry a note listing the files being updated.
52
+ <!-- source: niro-local src/niro_local/mcp/freshness.py:309-334, :598 -->
53
+
54
+ ## Files left out
55
+
56
+ | Left out | Default limit | Change it with |
57
+ |---|---|---|
58
+ | A source file larger than | 2 MB | `NIRO_LOCAL_MAX_FILE_BYTES` |
59
+ | A file over 256 KB that takes longer to read than | 20 seconds | `NIRO_LOCAL_PARSE_TIMEOUT_SECONDS` |
60
+ <!-- source: niro-local src/niro_local/walk.py:79; src/niro_local/build/parse_time_limit.py:44-57 -->
61
+
62
+ Answers name the files left out (the first 5), with a line starting "SKIPPED". Files that git ignores, editor scratch files and links to other places on disk (symlinks) are not read either.
63
+ <!-- source: niro-local src/niro_local/too_large.py:41, :164-182; src/niro_local/mcp/source_tools.py:825-850 -->
64
+
65
+ ## Using several processor cores
66
+
67
+ A build with 200 or more files to read uses several worker processes: by default one per processor core, up to 8. Change the number with `NIRO_LOCAL_PARSE_WORKERS`.
68
+ <!-- source: niro-local src/niro_local/build/parallel_parse.py:59-61, :197-198 -->
@@ -0,0 +1,372 @@
1
+ # niro: CLI + MCP server (`@niroai/niro`)
2
+
3
+ Command-line tool and MCP server for [Niro](https://niroai.dev). Niro reads your code and builds
4
+ a map of how it fits together, so your AI assistant answers from that map instead of guessing.
5
+
6
+ One package installs three things: the `niro` command, the MCP server your assistant talks to,
7
+ and two agent skills so you can ask for Niro tasks in plain English.
8
+
9
+ Requires Node.js 18 or newer. Niro is in private beta: you need an access code, which you get
10
+ from the **Request Access** button at [www.niro.ai](https://www.niro.ai).
11
+
12
+ ---
13
+
14
+ ## Get started
15
+
16
+ ```bash
17
+ cd ~/code/my-service
18
+ npx @niroai/niro start
19
+ ```
20
+
21
+ Signs you in, installs itself, shows you what it is about to index and asks first, builds the
22
+ graph, and connects your assistant. Run it again in any other repo; it skips what is done.
23
+
24
+ Then restart your assistant and ask it something:
25
+
26
+ ```
27
+ "What breaks if I change PaymentService.refund?"
28
+ ```
29
+
30
+ ---
31
+
32
+ ## What you can ask for
33
+
34
+ | | |
35
+ |---|---|
36
+ | Anything about your code | call chains, structure, entry points, API endpoints |
37
+ | What breaks if you change something | blast radius across services, including callers a search cannot find |
38
+ | A standing review | issues already in the code, by severity, in the browser |
39
+ | Root causes from your alerts | connect Sentry, Slack, Jira, Linear or CloudWatch and an alert arrives as a bug with the analysis done |
40
+
41
+ ---
42
+
43
+ ## Everyday commands
44
+
45
+ ```bash
46
+ niro status
47
+ ```
48
+ Is my index up to date? It answers about the project this folder is synced to **on the branch you
49
+ are on**, so once you have run `niro new-temp-project` it reports that copy rather than the shared
50
+ project. Name one explicitly to ask about a different project: `niro status <project-id>`.
51
+
52
+ ```bash
53
+ niro start
54
+ ```
55
+ Index another repo. Cross-service answers need more than one.
56
+
57
+ ```bash
58
+ niro info
59
+ ```
60
+ What does Niro know about this folder: repo, branch, which project it maps to.
61
+
62
+ ```bash
63
+ niro projects
64
+ ```
65
+ Every project in your account.
66
+
67
+ ```bash
68
+ niro build
69
+ ```
70
+ Rebuild the index by hand and watch it finish. Like `niro status`, it picks the project for the
71
+ branch you are on, so on a branch with a temporary project it rebuilds that one. Name a project to
72
+ rebuild a different one.
73
+
74
+ ```bash
75
+ niro upgrade
76
+ ```
77
+ Get the latest version, and bring your hooks, skills and watcher with it. See
78
+ [Upgrading](#upgrading).
79
+
80
+ ```bash
81
+ niro doctor
82
+ ```
83
+ Check this machine against the server and repair what is safe to repair. Today that is
84
+ `niro doctor sync-registry`, which fixes folders and `.niro-project` files left pointing at projects
85
+ that have gone or been renamed. The background watcher runs it for you every six hours.
86
+
87
+ ---
88
+
89
+ ## Working on a branch
90
+
91
+ Your index covers the branches you chose to build. On a branch nothing covers, Niro says so
92
+ rather than answering from stale code.
93
+
94
+ ```bash
95
+ niro new-temp-project
96
+ ```
97
+ Run once in the repo folder. Makes a private copy that follows your branch and uncommitted
98
+ edits. Your shared project is untouched.
99
+
100
+ ```bash
101
+ niro discard-temp-project
102
+ ```
103
+ Run when the branch is merged. Forgotten copies are cleaned up after two weeks.
104
+
105
+ If a copy is deleted for you, or a project is renamed, your machine is not told and the folder keeps
106
+ pointing at something that is gone. `niro doctor sync-registry` sorts that out, and the background
107
+ watcher runs it every six hours — see [When a project is deleted](#when-a-project-is-deleted).
108
+
109
+ The full guide to working on branches with hosted Niro is not shipped in this package. For branches with the local graph, see [worktrees-and-branches.md](worktrees-and-branches.md).
110
+
111
+ ---
112
+
113
+ ## When a project is deleted
114
+
115
+ Delete a project, or let an unused private copy expire, and your machine is not told. The folder
116
+ carries on pointing at something that is no longer there.
117
+
118
+ That is not just untidy. It is what makes `niro new-temp-project` in another folder say the slot is
119
+ already taken, naming a copy that no longer exists. And a `.niro-project` file left naming a deleted
120
+ project keeps answering, because it is read before your git remote.
121
+
122
+ The background watcher checks every six hours and sorts this out for you. `niro
123
+ doctor sync-registry` does the same thing on demand.
124
+
125
+ What it does depends on what went missing:
126
+
127
+ | What is gone | What happens to your folder |
128
+ |---|---|
129
+ | A private copy of a project | Goes back to the original project and carries on syncing |
130
+ | The project itself | Left alone if the repo still exists; unregistered only when both are gone |
131
+ | Neither, just a stale `.niro-project` | Repaired if your git remote says which project it should name; removed if it names nothing and is not shared; otherwise you are told |
132
+
133
+ It never deletes anything on the server, and it never touches a `.niro-project` file. Everything it
134
+ acts on has already gone. It only acts on what it can check, too: a folder git cannot read, or a
135
+ project it could not reach, is left exactly as it is and reported. A bad connection can never cost
136
+ you a working folder.
137
+
138
+ **How it decides what to do with a stale `.niro-project`.** That file can hold a project's name
139
+ rather than its id, so a renamed project looks exactly like a deleted one. Niro uses a second signal:
140
+ your folder's git remote. If the remote points at exactly one project, the pin is rewritten to that
141
+ project's id, which cannot be broken by a future rename. If the remote points at nothing either, the
142
+ pin identifies nothing and is removed.
143
+
144
+ **Unless the file is committed.** A `.niro-project` in git is shared with everyone who clones the
145
+ repo, and what looks like a dead project to you may be a colleague's. Niro never changes a committed
146
+ one for you. It tells you, and you decide.
147
+
148
+ `niro info` also mentions it when you are standing in an affected folder, so you do not have to go
149
+ looking.
150
+
151
+ ## When you run out of private copies
152
+
153
+ You get a limited number of private copies of each project. If you hit that limit, Niro tells you
154
+ which branches are holding them, and the CLI adds where each one is checked out:
155
+
156
+ ```
157
+ You already have 5 working copies of this project, which is the limit (5).
158
+ They are for: feature/a, feature/b, feature/c, feature/d, feature/e.
159
+
160
+ You have 5 working copies of this project on this machine:
161
+ feature/a /home/you/work/service
162
+ feature/b /home/you/work/service-wt2
163
+ ...
164
+ ```
165
+
166
+ Run `niro discard-temp-project` in one you have finished with, then try again. Copies nobody has
167
+ touched for a while are also cleared automatically.
168
+
169
+ ---
170
+
171
+ ## Measure what Niro changes
172
+
173
+ ```bash
174
+ niro ab enable
175
+ ```
176
+ Runs Niro **off** for half your sessions for 14 days, so you can compare. Applies to your whole
177
+ account, and asks before it starts.
178
+
179
+ ```bash
180
+ niro ab report
181
+ ```
182
+ The with-Niro and without-Niro comparison.
183
+
184
+ ```bash
185
+ niro ab disable
186
+ ```
187
+ Stop early. Every session uses Niro again.
188
+
189
+ ---
190
+
191
+ ## Connect another assistant
192
+
193
+ ```bash
194
+ niro mcp install
195
+ ```
196
+ Pick from the list, or `--client <id>` to skip the prompt. Restart the assistant afterwards.
197
+
198
+ ```bash
199
+ niro mcp install --list
200
+ ```
201
+ All 14 supported clients and the file each one is configured through.
202
+
203
+ ```bash
204
+ niro mcp uninstall --all -y
205
+ ```
206
+ Removes everything install added: MCP config, hooks and skills. Leaves you logged in.
207
+
208
+ Per-client details: [docs/connect-your-ai-assistant.md](https://unpkg.com/@niroai/niro/docs/connect-your-ai-assistant.md)
209
+
210
+ ---
211
+
212
+ ## Managing projects
213
+
214
+ ```bash
215
+ niro edit --list-env
216
+ ```
217
+ Environment variables Niro found, with secret values masked.
218
+
219
+ ```bash
220
+ niro edit --set-env KEY=VALUE
221
+ ```
222
+ Set one. The value is never printed or logged.
223
+
224
+ ```bash
225
+ niro edit --alias new-name
226
+ ```
227
+ Rename a project.
228
+
229
+ ```bash
230
+ niro remove --unmap-repo <gitId>
231
+ ```
232
+ Detach a repo from a project. Nothing is deleted.
233
+
234
+ ```bash
235
+ niro remove --project --confirm-name <name>
236
+ ```
237
+ Delete a whole project. Destructive, hence the confirmation. It refuses on a temporary project and
238
+ sends you to `niro discard-temp-project` instead, because that removes the copy **and** points this
239
+ folder back at the shared project; deleting it here would leave the folder aimed at a project that
240
+ no longer exists. `niro delete` refuses for the same reason.
241
+
242
+ ---
243
+
244
+ ## Keeping in sync
245
+
246
+ ```bash
247
+ niro service status
248
+ ```
249
+ Is the background watcher running? It syncs your indexed folders as you edit.
250
+
251
+ ```bash
252
+ niro service install
253
+ ```
254
+ Start it and have it come back on login. Needs PM2 (`npm install -g pm2`).
255
+
256
+ ```bash
257
+ niro watch
258
+ ```
259
+ Watch this folder in the foreground instead, for one session.
260
+
261
+ ---
262
+
263
+ ## Upgrading
264
+
265
+ **Check which you are on first:**
266
+
267
+ ```bash
268
+ niro --version
269
+ ```
270
+
271
+ **On 0.13.0 or newer**, one command:
272
+
273
+ ```bash
274
+ niro upgrade
275
+ ```
276
+
277
+ Replaces the package with the latest published version, then puts back the two things replacing the
278
+ package cannot reach: it re-runs the installer for every assistant you have configured, and
279
+ restarts the background watcher. Restart your assistant afterwards.
280
+
281
+ **On anything older than 0.13.0**, you do not have `niro upgrade` yet, so it is two commands, once:
282
+
283
+ ```bash
284
+ npm install -g @niroai/niro@latest
285
+ niro upgrade --finish
286
+ ```
287
+
288
+ The first gets the package. The second does the half npm cannot: your hooks, skills and the
289
+ watcher. After that, `niro upgrade` on its own is enough. Do not stop after the first command:
290
+ that leaves you on the new version running the old version's hooks, skills and instruction files,
291
+ which is the problem `niro upgrade` exists to solve.
292
+
293
+ **Why it is more than an npm install.** The hooks, skills and instruction files are written into
294
+ your home folder as fixed text when you install, not read out of the package as it runs, so a newer
295
+ package does not change them. The watcher is a long-running process still holding the code it
296
+ started with. The MCP config is the one part that needs nothing done to it: it runs plain `niro`
297
+ from your `PATH` with no version pinned in it, so the new server is picked up on its own.
298
+
299
+ **Restart your assistant last.** Skills and hooks are read when it starts, so nothing above reaches
300
+ a session that is already open.
301
+
302
+ Fully by hand, if you would rather:
303
+
304
+ ```bash
305
+ npm install -g @niroai/niro@latest
306
+ niro mcp install # once per assistant you use
307
+ niro service install # only if you run the watcher
308
+ ```
309
+
310
+ `niro start` upgrades nothing. On a machine that has connected an assistant once it skips the
311
+ connect step, so the old hooks and skills stay where they are.
312
+
313
+ ---
314
+
315
+ ## Reference
316
+
317
+ Add `--help` to any command for its flags. Add `--json` to `whoami`, `info`, `status`,
318
+ `projects`, `build`, `ab report`, `edit --list-env` and `doctor sync-registry` for machine-readable
319
+ output.
320
+
321
+ | File | What it holds |
322
+ |---|---|
323
+ | `~/.niro/credentials.json` | Your login, mode `0600` |
324
+ | `~/.niro/config.json` | Backend URLs saved during setup |
325
+ | `~/.niro/projects.json` | Per-folder sync state |
326
+ | `.niro-project` | Pins a repo folder to a Niro project |
327
+
328
+ | Variable | What it sets | Default |
329
+ |---|---|---|
330
+ | `NIRO_API_URL` | Backend the CLI talks to | `https://aiorchestrator.niroai.dev` |
331
+ | `NIRO_MCP_SERVER_URL` | Backend the MCP server talks to | `https://aiassistant.niroai.dev` |
332
+ | `NIRO_API_KEY` | Read by the MCP server when running headless. For CI, prefer `niro login --api-key` | none |
333
+ | `NIRO_UPLOAD_CONCURRENCY` / `_TIMEOUT_MS` / `_MAX_TOTAL_BYTES` / `_MAX_FILES` | Tune the first upload | 4 / 60000 / 1 GiB / 50000 |
334
+
335
+ Running your own instance? Set `NIRO_API_URL` before `niro login`, and pass `--url <url>` to
336
+ `niro mcp install`.
337
+
338
+ ---
339
+
340
+ ## What leaves your machine
341
+
342
+ Source and config files from the folder you confirmed, and nothing else. `.gitignore` is
343
+ honoured, so a gitignored `.env` is never sent. Raw `.env` and `*.properties` files are not in
344
+ the upload set; committed files like `application.yml` and `.env.example` are, because they hold
345
+ defaults rather than secrets.
346
+
347
+ Secret values are never printed: `--set-env` does not echo them, and `--list-env` masks anything
348
+ that looks like a secret by name or by content.
349
+
350
+ ---
351
+
352
+ ## If something is wrong
353
+
354
+ **The assistant ignores Niro.** Restart it. Skills load at startup, so a fresh `niro mcp install`
355
+ does nothing until you do.
356
+
357
+ **`niro: command not found`.** Your global npm bin is not on `PATH`. Check with `npm bin -g`.
358
+
359
+ **This folder maps to several projects.** Pass `--project <alias|id>`, or pick one when asked.
360
+
361
+ **Auto-sync is not running.** `npm install -g pm2`, then `niro service install`.
362
+
363
+ **A command or feature in the changelog is missing.** You are on an older version. Check with
364
+ `niro --version`, then see [Upgrading](#upgrading): before 0.13.0 it takes two commands, after it
365
+ one. Plain `npm install -g` on its own always leaves your hooks and skills on the old version.
366
+
367
+ **A folder was refused.** Niro will not index your home folder, or a folder with no build file
368
+ in it. Point it at the repo you meant.
369
+
370
+ ---
371
+
372
+ MIT
@@ -0,0 +1,51 @@
1
+ # Telling Niro what it cannot work out
2
+
3
+ **Sometimes the code alone does not say where a call goes.** For example, a service calls `ORDERS_URL + "/orders"`, and the value of `ORDERS_URL` is only set when the program is deployed. Niro then cannot link that call to the orders service's route. These commands let you fill in what is missing, for one folder. Run each one inside the folder.
4
+
5
+ ## Which folders are services
6
+
7
+ ```
8
+ niro modules
9
+ ```
10
+
11
+ Lists the folders inside this one that Niro treats as separate services (deployables).
12
+ <!-- source: src/commands/engineRoutes.js:34; niro-local src/niro_local/cli.py:373 -->
13
+
14
+ ## The settings your code reads
15
+
16
+ ```
17
+ niro env scan # find the settings the code reads
18
+ niro env list # show them
19
+ niro env set ORDERS_URL=http://orders:8080
20
+ niro env set-from ORDERS_URL=deploy/orders.env
21
+ niro env unset ORDERS_URL
22
+ niro env files add deploy/staging.env
23
+ ```
24
+
25
+ Niro reads the template files `.env.example`, `.env.sample` and `.env.template` by itself. A real env file is read only if you name it with `niro env files add`, and then only its address values. **Passwords and tokens are refused and never stored.**
26
+ <!-- source: niro-local src/niro_local/env_args.py:30-73, :34, :65-69; docs/usecases/env-settings.md -->
27
+
28
+ ## The address a service answers on
29
+
30
+ ```
31
+ niro base-url # show it
32
+ niro base-url http://orders:8080 # set it
33
+ niro base-url "" # go back to the address Niro worked out
34
+ ```
35
+
36
+ You can also give it when adding the folder: `niro init --base-url <url>`.
37
+ <!-- source: niro-local src/niro_local/cli.py:232; src/index.js:490-502 -->
38
+
39
+ ## Where a path goes, when the project does not say
40
+
41
+ ```
42
+ niro route-rule unconnected # calls Niro could not link
43
+ niro route-rule add "/api/orders/*" --to orders
44
+ niro route-rule list
45
+ niro route-rule remove <id>
46
+ ```
47
+
48
+ A rule says that calls to a path go to a given service. You can have up to 200 rules. Rules are copied to temporary projects for new branches.
49
+ <!-- source: niro-local src/niro_local/route_rules_cli.py:33-54; src/niro_local/route_rules.py:34-36; src/niro_local/temporary.py:187-240 -->
50
+
51
+ Niro uses the new values at the next build. To build now, run `niro build`.
@@ -0,0 +1,24 @@
1
+ # Niro in CI
2
+
3
+ **CI is a build machine with no person at it.** Niro's setup is built for a person at a terminal, so CI support is partial.
4
+
5
+ ## What does not work without a person
6
+
7
+ - **`niro start` needs a terminal.** Without one it stops with "`niro start` is interactive and there is no terminal to prompt on."
8
+ <!-- source: src/commands/start.js:97-104 -->
9
+ - **Connecting agents needs a browser sign-in.** `niro mcp install` accepts only the browser sign-in that `niro start` does. After `niro login --api-key` it refuses with "Not signed in. Run niro login".
10
+ <!-- source: src/mcp/setup.js:574-583, :2950-2955 -->
11
+
12
+ - **Sending the coverage audit.** The audit reads your plan through your `niro login` sign-in before it sends anything, so on a machine with no sign-in nothing is sent. Setting `NIRO_AUDIT_API_KEY` does not change that: the key only replaces the upload's own sign-in header. When the sign-in is missing, `niro audit-send` says so: "Nothing sent: not signed in. The audit reads your plan through your `niro login` sign-in, so run `niro login` first."
13
+ <!-- source: src/lib/auditUpload.js:83-86, :168-177, :183-187; src/commands/auditSend.js:19-20; src/lib/lease.js:339-343; src/lib/api.js:140 -->
14
+
15
+ ## What works
16
+
17
+ - **Confirming without a prompt.** `niro uninstall --yes` and `niro audit-push-repo --yes` skip their question. Without a terminal they need `--yes`, and refuse without it.
18
+ <!-- source: src/index.js:60-67, :117-125; src/commands/uninstall.js:108; src/lib/repoPush.js:350 -->
19
+ - **Signing in with a key from a pipe.** `niro login --api-key` reads the key from a pipe when there is no terminal. This way of signing in is due to be removed.
20
+ <!-- source: src/commands/login.js:44-52; src/lib/prompt.js:47-61; TODO.md:51-62 -->
21
+
22
+ ## Not yet established
23
+
24
+ Whether a key-based sign-in lets `niro build` and `niro ask` run on a build machine has not been tested. Treat Niro in CI as not supported until this page says otherwise.
@@ -0,0 +1,20 @@
1
+ # Every way into Niro
2
+
3
+ **There are several ways to reach the graph, and not all of them work in this version.** This table says which do. Each "yes" comes from the code, and each "no" says why.
4
+
5
+ | Way in | Works today? | Page |
6
+ |---|---|---|
7
+ | The terminal: `niro ask`, `niro ui`, `niro status`, `niro plan` | **Yes** | [connect-terminal.md](connect-terminal.md) |
8
+ | 14 coding agents, connected over MCP | **Yes.** How much help each agent gets differs (see its page) | [connect-your-ai-assistant.md](connect-your-ai-assistant.md) |
9
+ | Any other MCP client | **Yes, by hand:** the installer prints a block to paste | [connect-your-ai-assistant.md](connect-your-ai-assistant.md#other-mcp-clients) |
10
+ | Review bots (Cursor Bugbot, CodeRabbit, Copilot review) | **No** | [connect-review-bots.md](connect-review-bots.md) |
11
+ | Agents in a web browser (Claude, ChatGPT) | **Not in a release yet.** Use hosted Niro | [connect-web-agents.md](connect-web-agents.md) |
12
+ | CI (a build machine with no person at it) | **Partly** | [connect-ci.md](connect-ci.md) |
13
+ | One shared server for a team | **Not in a release yet** | [connect-team-server.md](connect-team-server.md) |
14
+ <!-- source: src/commands/engineRoutes.js:27-46 (terminal commands); src/mcp/setup.js:279-414 (CLIENTS, 14), :658-667, :3000 ("Other (print the config)"); niro-local src/niro_local/cli.py:2622-2694 (HTTP serving: licence and no authentication) -->
15
+
16
+ **MCP** (the Model Context Protocol) is the standard way a coding agent uses an outside tool. Niro's MCP server runs on your computer, and your agent starts it when the agent starts. It talks to the agent through the agent's standard input and output, not over the network.
17
+ <!-- source: src/mcp/setup.js:241-247 (every client runs `niro mcp serve` over stdio) -->
18
+
19
+ **Computers:** Niro runs on macOS and Linux, on Intel and ARM. Windows is supported, and the details are coming.
20
+ <!-- source: src/lib/engine.js:79-90 (macOS, Linux; x64, arm64); Windows: Niraj, 2026-11-10 -->
@@ -0,0 +1,17 @@
1
+ # Review bots and Niro
2
+
3
+ **Review bots cannot use the local graph in this version.** Review bots are tools such as Cursor Bugbot, CodeRabbit or GitHub Copilot's pull request review, which comment on pull requests by themselves. niro-cli has no setup for them.
4
+ <!-- source: no review-bot code in src/ (searched for Bugbot, CodeRabbit and Copilot review; the only Copilot entries are the VS Code and Copilot CLI agents, src/mcp/setup.js:314-338) -->
5
+
6
+ **Why:**
7
+
8
+ - These bots run on their makers' servers.
9
+ - The local engine runs on your computer, and talks only to an agent your computer starts.
10
+ - So a bot on someone else's server has no way to reach it.
11
+ <!-- source: src/mcp/setup.js:241-247 (stdio only) -->
12
+
13
+ **What you can do instead:**
14
+
15
+ 1. **Review with your own agent.** Check out the branch, and let your coding agent ask Niro what the change reaches. See [lifecycle-review.md](lifecycle-review.md).
16
+ 2. **Use hosted Niro for pull request review.** It reviews pull requests on Niro's servers. See [hosted-only.md](hosted-only.md).
17
+ <!-- source: src/lib/cloudGuard.js:66-69 -->
@@ -0,0 +1,12 @@
1
+ # One shared server for a team
2
+
3
+ **A shared Niro server for a team is not supported in a release yet.** A shared server would be one computer that builds the graph and answers everyone's agents.
4
+
5
+ **Why:**
6
+
7
+ - **No licence.** A released engine gets its licence only from niro-cli, through a channel that exists only when niro-cli starts it, so an engine serving over the network refuses.
8
+ - **No password or key.** The network mode has no authentication, so anyone who can reach it could read the structure of the code.
9
+ - **One folder per process.** One running engine answers for one folder only.
10
+ <!-- source: niro-local src/niro_local/cli.py:2622-2637 (docstring: points 1 to 3), :2687-2693 -->
11
+
12
+ For now, each developer runs Niro on their own computer. For a shared view of a team's code, use hosted Niro (see [hosted-only.md](hosted-only.md)).