@niroai/niro 0.10.0 → 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 +117 -0
- package/README.md +185 -249
- package/docs/working-on-branches.md +55 -0
- package/package.json +1 -1
- package/src/commands/cleanup.js +689 -0
- package/src/commands/info.js +51 -2
- package/src/commands/release.js +13 -60
- package/src/commands/takeover.js +52 -2
- package/src/commands/watch.js +93 -25
- package/src/index.js +23 -3
- package/src/lib/folderSync.js +6 -0
- package/src/lib/periodicClaim.js +100 -0
- package/src/lib/printError.js +46 -0
- package/src/lib/takeoverRestore.js +156 -0
- package/src/mcp/setup.js +178 -13
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.
|