@niroai/niro 0.9.0 → 0.10.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 +69 -0
- package/README.md +55 -1
- package/package.json +1 -1
- package/src/commands/ab.js +198 -0
- package/src/commands/add-project.js +11 -11
- package/src/commands/add-repo.js +23 -23
- package/src/commands/build.js +5 -5
- package/src/commands/delete.js +3 -3
- package/src/commands/edit.js +11 -11
- package/src/commands/info.js +2 -2
- package/src/commands/init.js +108 -87
- package/src/commands/login.js +25 -5
- package/src/commands/projects.js +1 -1
- package/src/commands/release.js +7 -7
- package/src/commands/remove.js +5 -5
- package/src/commands/start.js +567 -0
- package/src/commands/takeover.js +19 -19
- package/src/commands/watch.js +35 -35
- package/src/index.js +57 -3
- package/src/lib/folderSync.js +13 -8
- package/src/lib/moduleExcludeSuggestions.js +5 -5
- package/src/lib/nestedOutput.js +49 -0
- package/src/lib/onboardTarget.js +5 -5
- package/src/lib/prompt.js +3 -0
- package/src/lib/service.js +20 -12
- package/src/lib/spinner.js +28 -7
- package/src/lib/watchDaemon.js +9 -9
- package/src/mcp/setup.js +198 -160
- package/src/mcp/teardown.js +53 -53
package/src/commands/login.js
CHANGED
|
@@ -55,7 +55,7 @@ async function loginWithApiKey({ apiUrl }) {
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const sp = spinner.start("Authenticating...");
|
|
58
|
+
const sp = spinner.start(" Authenticating...");
|
|
59
59
|
try {
|
|
60
60
|
const data = await api.post(
|
|
61
61
|
"/api/public/auth/api-key-login",
|
|
@@ -157,11 +157,16 @@ async function loginWithDeviceFlow({ apiUrl }) {
|
|
|
157
157
|
throw new Error("Server did not return a complete device-code payload.");
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
// The verification URI is the web app's own address, chosen by whichever server we are
|
|
161
|
+
// talking to. Recording it is the only way the CLI can later link someone to their project
|
|
162
|
+
// without hardcoding a host that is wrong for UAT and wrong for every self-hosted install.
|
|
163
|
+
rememberAppUrl(verificationUri);
|
|
164
|
+
|
|
165
|
+
console.log(`\n Your one-time code: ${color.bold(color.cyan(userCode))}`);
|
|
166
|
+
console.log(` Open: ${color.cyan(verificationUri)}\n`);
|
|
162
167
|
browser.open(verificationUri);
|
|
163
168
|
|
|
164
|
-
const sp = spinner.start("Waiting for browser approval...");
|
|
169
|
+
const sp = spinner.start(" Waiting for browser approval...");
|
|
165
170
|
const deadline = Date.now() + expiresIn * 1000;
|
|
166
171
|
try {
|
|
167
172
|
while (Date.now() < deadline) {
|
|
@@ -199,6 +204,21 @@ async function loginWithDeviceFlow({ apiUrl }) {
|
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Store the web app's origin, taken from the device-flow verification URI.
|
|
209
|
+
*
|
|
210
|
+
* Best-effort by design: a malformed or missing URI must never fail a login that is otherwise
|
|
211
|
+
* fine. The only cost of not recording it is that `niro start` ends without a browser link.
|
|
212
|
+
*/
|
|
213
|
+
function rememberAppUrl(verificationUri) {
|
|
214
|
+
try {
|
|
215
|
+
const origin = new URL(verificationUri).origin;
|
|
216
|
+
require("../lib/config").save({ appUrl: origin });
|
|
217
|
+
} catch {
|
|
218
|
+
// Not a URL we can parse. Leave the previous value alone rather than storing a guess.
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
202
222
|
function isPending(err) {
|
|
203
223
|
const body = err.body;
|
|
204
224
|
if (!body) return false;
|
|
@@ -211,4 +231,4 @@ function sleep(ms) {
|
|
|
211
231
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
212
232
|
}
|
|
213
233
|
|
|
214
|
-
module.exports = { login };
|
|
234
|
+
module.exports = { login, rememberAppUrl };
|
package/src/commands/projects.js
CHANGED
|
@@ -69,7 +69,7 @@ async function projects(opts = {}) {
|
|
|
69
69
|
const repos = `${r.repo_count} repo${r.repo_count === 1 ? "" : "s"}`;
|
|
70
70
|
const created = fmtDate(r.created_at);
|
|
71
71
|
const meta = [repos, created].filter(Boolean).join(", ");
|
|
72
|
-
console.log(`
|
|
72
|
+
console.log(` ${name} ${color.dim(r.project_id)} ${color.dim("— " + meta)}`);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
package/src/commands/release.js
CHANGED
|
@@ -141,11 +141,11 @@ async function release(pathArg, opts = {}) {
|
|
|
141
141
|
} catch { /* can't inspect — don't block on it */ }
|
|
142
142
|
}
|
|
143
143
|
if (stillDiverged.length) {
|
|
144
|
-
console.log(warn(`\n
|
|
144
|
+
console.log(warn(`\n ⚠ This temporary project still covers in-flight work:`));
|
|
145
145
|
for (const d of stillDiverged) {
|
|
146
146
|
console.log(warn(` ${d.folder} is on \`${d.branch}\` (source: \`${d.sourceBranch}\`)`));
|
|
147
147
|
}
|
|
148
|
-
console.log(warn("
|
|
148
|
+
console.log(warn(" Discarding deletes the WHOLE temporary project — those repos lose their coverage" +
|
|
149
149
|
" until you run `niro new-temp-project` there again (local code is untouched)."));
|
|
150
150
|
if (!opts.yes) {
|
|
151
151
|
if (!process.stdout.isTTY || prompt.isNonInteractive()) {
|
|
@@ -233,25 +233,25 @@ async function release(pathArg, opts = {}) {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
if (alreadyGone) {
|
|
236
|
-
console.log(`\n
|
|
236
|
+
console.log(`\n ${ok("✓")} Temporary project ${color.bold(tempProjectId)} was already gone from the server` +
|
|
237
237
|
color.dim(" (deleted from the UI, or reaped after sitting idle)."));
|
|
238
238
|
console.log(repinned.length
|
|
239
239
|
? ` ${ok("✓")} Cleaned up ${repinned.length} local registration(s) that still pointed at it. ` +
|
|
240
240
|
"Niro routes back to the original project automatically."
|
|
241
241
|
: ` ${ok("✓")} Nothing left to clean up locally.`);
|
|
242
242
|
} else {
|
|
243
|
-
console.log(`\n
|
|
243
|
+
console.log(`\n ${ok("✓")} Temporary project discarded. Niro routes back to the original project automatically.`);
|
|
244
244
|
}
|
|
245
245
|
if (healed.length) {
|
|
246
|
-
console.log(color.dim("
|
|
246
|
+
console.log(color.dim(" Healed old-style pins:"));
|
|
247
247
|
for (const h of healed) console.log(color.dim(` ${h.folder} → ${h.to}`));
|
|
248
248
|
}
|
|
249
249
|
if (failed.length) {
|
|
250
|
-
console.log(warn(`\n
|
|
250
|
+
console.log(warn(`\n ⚠ ${failed.length} folder(s) could not be restored locally (the temporary project` +
|
|
251
251
|
" is already gone server-side):"));
|
|
252
252
|
for (const f of failed) console.log(color.dim(` ${f.folder} — ${f.error}`));
|
|
253
253
|
}
|
|
254
|
-
console.log(color.dim("
|
|
254
|
+
console.log(color.dim(" The original project picks up your merged commits via its normal remote polling."));
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
module.exports = { release };
|
package/src/commands/remove.js
CHANGED
|
@@ -71,9 +71,9 @@ async function remove(opts = {}) {
|
|
|
71
71
|
const expected = alias ? `"${alias}" or ${projectId}` : projectId;
|
|
72
72
|
console.error(`${color.red("✗")} Refusing to delete: --confirm-name must equal the project's name (${expected}).`);
|
|
73
73
|
if (confirm == null) {
|
|
74
|
-
console.error(color.dim("
|
|
74
|
+
console.error(color.dim(" Pass --confirm-name <name> to confirm this destructive delete."));
|
|
75
75
|
} else {
|
|
76
|
-
console.error(color.dim(`
|
|
76
|
+
console.error(color.dim(` You passed --confirm-name "${confirm}", which does not match.`));
|
|
77
77
|
}
|
|
78
78
|
process.exitCode = 1;
|
|
79
79
|
return;
|
|
@@ -86,9 +86,9 @@ async function remove(opts = {}) {
|
|
|
86
86
|
|
|
87
87
|
function printUsage() {
|
|
88
88
|
console.error("niro remove — remove a project or a repo mapping. Exactly one mode required:");
|
|
89
|
-
console.error("
|
|
90
|
-
console.error("
|
|
91
|
-
console.error("
|
|
89
|
+
console.error(" --project delete the whole project (DESTRUCTIVE)");
|
|
90
|
+
console.error(" requires --confirm-name <project alias or id>");
|
|
91
|
+
console.error(" --unmap-repo <gitId> remove one repo from the project (non-destructive)");
|
|
92
92
|
console.error("Target project: --target <alias|id>, or a .niro-project pin in this folder.");
|
|
93
93
|
}
|
|
94
94
|
|