@niroai/niro 0.10.1 → 0.11.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/CHANGELOG.md CHANGED
@@ -2,6 +2,123 @@
2
2
 
3
3
  Notable changes to `@niroai/niro`. Dates are release dates.
4
4
 
5
+ ## 0.11.0 — 2026-09-03
6
+
7
+ ### The watcher stops pausing and resuming your uploads over and over
8
+
9
+ The background watcher holds back uploads from a folder whose branch disagrees with the branch its
10
+ private copy is labelled with, so two branches cannot be written into one copy. One developer's log
11
+ carried 306 pauses against 286 resumes. Those counts being nearly equal is the whole story: it was
12
+ toggling, not failing 306 times.
13
+
14
+ Once a minute the watcher asks which branch the copy is on. A request that failed returned nothing,
15
+ which was read as "everything is fine again": it printed "resuming uploads" and cleared the pause, so
16
+ the next check paused and warned all over again. It also let a folder that genuinely should not be
17
+ uploading start writing again on any slow request. Now a question the server could not answer changes
18
+ nothing at all, in either direction. The same six alternating checks went from 3 warnings and 3 resumes
19
+ down to 1 and 0.
20
+
21
+ The message was wrong too. When it paused it looked for another folder on the same *project* and blamed
22
+ it. A project can hold several repositories and each folder can have its own, so it regularly named a
23
+ folder that was writing nowhere near yours and told you to discard it. It now matches on the repository
24
+ actually being written to, so it either names the folder that really shares your copy or tells you
25
+ plainly that you switched branch in that folder yourself.
26
+
27
+ **The pause itself is unchanged, deliberately.** While a folder's branch and its copy's label disagree,
28
+ your assistant's questions are not sent to that copy anyway, so uploading into it would only fill it
29
+ with the wrong branch's files. Run `niro new-temp-project` in that folder to put it back in step.
30
+
31
+ ### Servlet apps declare their endpoints in a file that was never sent
32
+
33
+ A Java web app written before Spring Boot lists its whole HTTP surface in `WEB-INF/web.xml` rather than
34
+ in annotations. That file was missing from the set the CLI offers, so such a project indexed as a
35
+ servlet application with no endpoints at all. Measured on one repository: 11 real endpoints, 0 detected,
36
+ against an otherwise complete and healthy index.
37
+
38
+
39
+ ### Stale pointers clean themselves up
40
+
41
+ Delete a project, or let an unused private copy expire, and your machine is never told. The folder
42
+ carries on naming something that is gone. That is what makes `niro new-temp-project` in another
43
+ worktree say the slot is taken, naming a copy that no longer exists.
44
+
45
+ That command never shipped: it went in under this same Unreleased section and has been renamed since,
46
+ so `niro doctor sync-registry` is its first public name. It also only helped if you remembered to run
47
+ it. Now the background watcher runs it every six hours by itself, and it covers two more cases:
48
+
49
+ - **Ordinary registrations**, not just private copies. A folder registered against a deleted project
50
+ used to sit there for ever: the daemon retried it on every start and nothing could clear it. One
51
+ developer asked whether they should edit `~/.niro/projects.json` by hand. They were right that there
52
+ was no supported way.
53
+ - **`.niro-project` files** naming something the server does not recognise. Nothing has ever surfaced
54
+ these, and they are not inert: that file is read before your git remote, so a stale one keeps
55
+ answering. They are REPORTED, never deleted — the file can hold a project's name rather than its id,
56
+ and a renamed project is indistinguishable from a deleted one from the client, so the right repair
57
+ (update it, or remove it) is yours to choose.
58
+
59
+ **What it refuses to do matters more than what it does.** A deleted project is not enough to
60
+ unregister a folder, because a project can be deleted while its repos are moved to another one and
61
+ that folder is still syncing fine, so the repo is checked too. On the machine this was built on that
62
+ took the count from 18 folders to 1. And a `.niro-project` may hold an *alias* rather than an id, which
63
+ the direct lookup reports as "not found" for a project that is perfectly alive; the account's project
64
+ list is now the authority. Both of those were caught by dry runs against real data after the unit tests
65
+ were green.
66
+
67
+ The watcher remembers when it last swept, so restarting it does not re-run the job, and a `niro watch`
68
+ left in a terminal cannot sweep at the same moment as the background one. It stays silent when there
69
+ was nothing to do.
70
+
71
+ ### When you run out of private copies, it says where they are
72
+
73
+ The server already tells you which branches are holding your copies. It cannot tell you where those
74
+ branches are checked out, because that is a fact about your machine. The CLI now adds the folder next
75
+ to each branch, so you can go straight to one and discard it.
76
+
77
+ ### Multi-line error messages are no longer cut off
78
+
79
+ Errors printed only their first line, so any message built over several lines lost the rest. Two were
80
+ affected: "Multiple projects match this repo — pass --project:" showed no projects, and the
81
+ working-copy-limit refusal showed no folders. The text was always correct and simply never reached the
82
+ screen. Found by running the real CLI against a real backend until it refused; no unit test could have
83
+ caught it, because both features assert on the message and the message was right.
84
+
85
+
86
+ ### `niro doctor sync-registry` tidies up copies the server deleted for you
87
+
88
+ A temporary project can go without this machine ever being told: somebody deletes it in the web
89
+ app, or the sweeper reaps it after two weeks. The folder keeps a registration pointing at an id
90
+ that resolves to nothing. That is not harmless, because it is exactly what makes
91
+ `niro new-temp-project` in a second worktree refuse with "already held by another folder".
92
+
93
+ `niro discard-temp-project` already repaired one folder in that state. What nothing did was find
94
+ them. On the machine this was built on, 13 of 14 registered copies had gone and every one of the
95
+ 14 folders was still pointing at a dead id.
96
+
97
+ ```bash
98
+ niro doctor sync-registry # check and repair
99
+ niro doctor sync-registry --dry-run # list, change nothing
100
+ ```
101
+
102
+ It asks the server once per copy and moves the folders whose copy has gone back onto their
103
+ original project. Three things it will not do. It never treats an unreachable server as an
104
+ answer: only a definitive "Project not found" counts, so a 500, a timeout, or a project you are
105
+ simply not allowed to see leaves every entry exactly as it was. It never unregisters a folder,
106
+ because the watch daemon still needs somewhere to sync it. And it never guesses: a copy that no
107
+ folder recorded a source project for is reported and left alone.
108
+
109
+ `--json` for scripts, `--dry-run` to look first, `-y` to skip the prompt. At a terminal, `--json`
110
+ asks for one of the last two rather than writing without a prompt it cannot show.
111
+
112
+ Two guards came out of review and apply to `niro discard-temp-project` as well, because both commands
113
+ now share one repair routine. A folder re-registered by another process while the command runs is
114
+ left alone and reported, instead of being overwritten by a stale snapshot. And within a copy that
115
+ covers several folders, the one holding the record of the original project is always written last, so
116
+ a run interrupted half way through can still be finished by running it again.
117
+
118
+ Folders that had no local registration before the copy was made are now listed separately from the
119
+ ones that keep syncing. They go back to not having one, which is where they started, but calling that
120
+ "repaired" and stopping there implied the daemon was still watching them.
121
+
5
122
  ## 0.10.0 — 2026-08-28
6
123
 
7
124
  One command to get started, and a way to check what Niro is worth.
package/README.md CHANGED
@@ -67,6 +67,13 @@ niro build
67
67
  ```
68
68
  Rebuild the index by hand and watch it finish.
69
69
 
70
+ ```bash
71
+ niro doctor
72
+ ```
73
+ Check this machine against the server and repair what is safe to repair. Today that is
74
+ `niro doctor sync-registry`, which fixes folders and `.niro-project` files left pointing at projects
75
+ that have gone or been renamed. The background watcher runs it for you every six hours.
76
+
70
77
  ---
71
78
 
72
79
  ## Working on a branch
@@ -85,10 +92,72 @@ niro discard-temp-project
85
92
  ```
86
93
  Run when the branch is merged. Forgotten copies are cleaned up after two weeks.
87
94
 
95
+ If a copy is deleted for you, or a project is renamed, your machine is not told and the folder keeps
96
+ pointing at something that is gone. `niro doctor sync-registry` sorts that out, and the background
97
+ watcher runs it every six hours — see [When a project is deleted](#when-a-project-is-deleted).
98
+
88
99
  Full guide: [docs/working-on-branches.md](https://unpkg.com/@niroai/niro/docs/working-on-branches.md)
89
100
 
90
101
  ---
91
102
 
103
+ ## When a project is deleted
104
+
105
+ Delete a project, or let an unused private copy expire, and your machine is not told. The folder
106
+ carries on pointing at something that is no longer there.
107
+
108
+ That is not just untidy. It is what makes `niro new-temp-project` in another folder say the slot is
109
+ already taken, naming a copy that no longer exists. And a `.niro-project` file left naming a deleted
110
+ project keeps answering, because it is read before your git remote.
111
+
112
+ The background watcher checks every six hours and sorts this out for you. `niro
113
+ doctor sync-registry` does the same thing on demand.
114
+
115
+ What it does depends on what went missing:
116
+
117
+ | What is gone | What happens to your folder |
118
+ |---|---|
119
+ | A private copy of a project | Goes back to the original project and carries on syncing |
120
+ | The project itself | Left alone if the repo still exists; unregistered only when both are gone |
121
+ | 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 |
122
+
123
+ It never deletes anything on the server, and it never touches a `.niro-project` file. Everything it
124
+ acts on has already gone. It only acts on what it can check, too: a folder git cannot read, or a
125
+ project it could not reach, is left exactly as it is and reported. A bad connection can never cost
126
+ you a working folder.
127
+
128
+ **How it decides what to do with a stale `.niro-project`.** That file can hold a project's name
129
+ rather than its id, so a renamed project looks exactly like a deleted one. Niro uses a second signal:
130
+ your folder's git remote. If the remote points at exactly one project, the pin is rewritten to that
131
+ project's id, which cannot be broken by a future rename. If the remote points at nothing either, the
132
+ pin identifies nothing and is removed.
133
+
134
+ **Unless the file is committed.** A `.niro-project` in git is shared with everyone who clones the
135
+ repo, and what looks like a dead project to you may be a colleague's. Niro never changes a committed
136
+ one for you. It tells you, and you decide.
137
+
138
+ `niro info` also mentions it when you are standing in an affected folder, so you do not have to go
139
+ looking.
140
+
141
+ ## When you run out of private copies
142
+
143
+ You get a limited number of private copies of each project. If you hit that limit, Niro tells you
144
+ which branches are holding them, and the CLI adds where each one is checked out:
145
+
146
+ ```
147
+ You already have 5 working copies of this project, which is the limit (5).
148
+ They are for: feature/a, feature/b, feature/c, feature/d, feature/e.
149
+
150
+ You have 5 working copies of this project on this machine:
151
+ feature/a /home/you/work/service
152
+ feature/b /home/you/work/service-wt2
153
+ ...
154
+ ```
155
+
156
+ Run `niro discard-temp-project` in one you have finished with, then try again. Copies nobody has
157
+ touched for a while are also cleared automatically.
158
+
159
+ ---
160
+
92
161
  ## Measure what Niro changes
93
162
 
94
163
  ```bash
@@ -181,7 +250,8 @@ Watch this folder in the foreground instead, for one session.
181
250
  ## Reference
182
251
 
183
252
  Add `--help` to any command for its flags. Add `--json` to `whoami`, `info`, `status`,
184
- `projects`, `build`, `ab report` and `edit --list-env` for machine-readable output.
253
+ `projects`, `build`, `ab report`, `edit --list-env` and `doctor sync-registry` for machine-readable
254
+ output.
185
255
 
186
256
  | File | What it holds |
187
257
  |---|---|
@@ -63,6 +63,61 @@ Run this in the repo folder:
63
63
  It deletes your private copy. Your local files are never touched.
64
64
  If you forget, Niro deletes unused copies by itself after two weeks.
65
65
 
66
+ ## Tidying up copies that were deleted for you
67
+
68
+ When a copy goes after two weeks, or somebody deletes it in the web app,
69
+ your machine is not told. The folder is left pointing at a copy that is
70
+ no longer there. Nothing breaks, but "niro new-temp-project" in another
71
+ worktree of the same repo will say the slot is already taken.
72
+
73
+ Run this from anywhere to sort it out:
74
+
75
+ niro doctor sync-registry
76
+
77
+ You will rarely need to type it. The background watcher runs the same
78
+ check every six hours by itself.
79
+
80
+ It sorts out three things, and treats them differently:
81
+
82
+ - A folder pointing at a private copy that has gone goes back to the
83
+ original project, and carries on syncing.
84
+ - A folder pointing at a project that has gone is only unregistered when
85
+ the repo has gone too. A project can be deleted while its repos are
86
+ moved somewhere else, and that folder is still syncing perfectly well.
87
+ - A ".niro-project" file naming something the server does not know is
88
+ repaired where possible. That file can hold a project's NAME rather
89
+ than its id, so a renamed project looks exactly like a deleted one.
90
+ Niro checks your folder's git remote instead: if that points at one
91
+ project, the file is rewritten to that project's id, which a future
92
+ rename cannot break. If the remote points at nothing either, the file
93
+ names nothing and is removed.
94
+
95
+ Not if the file is committed to git, though. Then it is shared with
96
+ everyone who clones the repo, and a project that means nothing to you
97
+ may be a colleague's. Niro tells you and leaves the choice to you.
98
+ "niro info" mentions it too, when you are standing in that folder.
99
+
100
+ Copies that are still there are left alone, and so is anything it could
101
+ not check, so a dropped connection never costs you a working folder. Add
102
+ "--dry-run" to see the list without changing anything.
103
+
104
+ ## When you run out of private copies
105
+
106
+ You get a limited number of private copies of each project. When you hit
107
+ the limit, Niro says which branches are holding them, and the CLI adds
108
+ where each one is checked out on this machine:
109
+
110
+ You already have 5 working copies of this project, which is
111
+ the limit (5). They are for: feature/a, feature/b, ...
112
+
113
+ You have 5 working copies of this project on this machine:
114
+ feature/a /home/you/work/service
115
+ feature/b /home/you/work/service-wt2
116
+
117
+ Run "niro discard-temp-project" in one you have finished with, then try
118
+ again. Copies nobody has touched for a while are cleared automatically,
119
+ so this usually sorts itself out.
120
+
66
121
  ## A feature that spans several repos
67
122
 
68
123
  Run "niro new-temp-project" in each repo folder you branch.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@niroai/niro",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Niro — one package: the niro CLI plus the Niro MCP server (code intelligence for AI coding assistants).",
5
5
  "keywords": [
6
6
  "niro",