@niroai/niro 0.16.0 → 0.18.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 +149 -0
- package/README.md +123 -302
- package/bin/niro.js +12 -1
- package/docs/agent-antigravity.md +37 -0
- package/docs/agent-claude-code.md +48 -0
- package/docs/agent-claude-desktop.md +47 -0
- package/docs/agent-cline.md +42 -0
- package/docs/agent-codex.md +45 -0
- package/docs/agent-copilot-cli.md +42 -0
- package/docs/agent-cursor.md +44 -0
- package/docs/agent-factory.md +42 -0
- package/docs/agent-gemini-cli.md +42 -0
- package/docs/agent-goose.md +42 -0
- package/docs/agent-kiro.md +37 -0
- package/docs/agent-opencode.md +37 -0
- package/docs/agent-vscode.md +45 -0
- package/docs/agent-windsurf.md +38 -0
- package/docs/answer-shapes.md +69 -0
- package/docs/builds-and-updates.md +68 -0
- package/docs/cloud-README.md +372 -0
- package/docs/configuring-a-folder.md +51 -0
- package/docs/connect-ci.md +24 -0
- package/docs/connect-overview.md +20 -0
- package/docs/connect-review-bots.md +17 -0
- package/docs/connect-team-server.md +12 -0
- package/docs/connect-terminal.md +49 -0
- package/docs/connect-web-agents.md +9 -0
- package/docs/connect-your-ai-assistant.md +59 -175
- package/docs/coverage-audit-and-consent.md +51 -0
- package/docs/evaluate-what-niro-did.md +271 -0
- package/docs/faq-assistants-and-mcp.md +122 -0
- package/docs/faq-feedback-and-receipts.md +33 -0
- package/docs/faq-indexing.md +127 -0
- package/docs/faq-install-and-setup.md +103 -0
- package/docs/faq-licence-and-plans.md +86 -0
- package/docs/faq-login-and-account.md +69 -0
- package/docs/faq-offline.md +34 -0
- package/docs/faq-performance.md +33 -0
- package/docs/faq-privacy-and-security.md +113 -0
- package/docs/faq-uninstall.md +47 -0
- package/docs/faq-updates.md +59 -0
- package/docs/faq-worktrees-and-branches.md +59 -0
- package/docs/faq-wrong-or-missing-answers.md +275 -0
- package/docs/hosted-only.md +33 -0
- package/docs/how-the-graph-works.md +47 -0
- package/docs/index.md +157 -0
- package/docs/licence-and-plans.md +72 -0
- package/docs/lifecycle-debug.md +48 -0
- package/docs/lifecycle-onboarding.md +32 -0
- package/docs/lifecycle-overview.md +77 -0
- package/docs/lifecycle-plan-and-design.md +44 -0
- package/docs/lifecycle-review.md +30 -0
- package/docs/lifecycle-security-and-privacy.md +35 -0
- package/docs/lifecycle-test.md +28 -0
- package/docs/lifecycle-write-code.md +35 -0
- package/docs/llms-full.txt +8015 -0
- package/docs/llms.txt +126 -0
- package/docs/playbook-add-a-feature.md +108 -0
- package/docs/playbook-change-safely.md +93 -0
- package/docs/playbook-data-and-events.md +107 -0
- package/docs/playbook-debug-after-a-change.md +96 -0
- package/docs/playbook-debug-config.md +95 -0
- package/docs/playbook-debug-exception.md +124 -0
- package/docs/playbook-debug-failing-service-call.md +119 -0
- package/docs/playbook-debug-slow-path.md +80 -0
- package/docs/playbook-debug-wrong-value.md +137 -0
- package/docs/playbook-onboard.md +95 -0
- package/docs/playbook-review-a-change.md +72 -0
- package/docs/playbook-test-a-change.md +73 -0
- package/docs/reference-cli.md +113 -0
- package/docs/reference-config-files.md +42 -0
- package/docs/reference-engine-commands.md +56 -0
- package/docs/reference-environment-variables.md +89 -0
- package/docs/reference-exit-codes.md +67 -0
- package/docs/reference-limits.md +75 -0
- package/docs/reference-mcp-tools.md +326 -0
- package/docs/reference-messages.md +180 -0
- package/docs/secrets-and-masking.md +48 -0
- package/docs/supported-c.md +130 -0
- package/docs/supported-cpp.md +157 -0
- package/docs/supported-csharp.md +211 -0
- package/docs/supported-go.md +258 -0
- package/docs/supported-java.md +226 -0
- package/docs/supported-javascript.md +223 -0
- package/docs/supported-kotlin.md +124 -0
- package/docs/supported-overview.md +89 -0
- package/docs/supported-php.md +157 -0
- package/docs/supported-python.md +224 -0
- package/docs/supported-ruby.md +162 -0
- package/docs/supported-rust.md +150 -0
- package/docs/supported-swift.md +133 -0
- package/docs/supported-typescript.md +220 -0
- package/docs/tokens-speed-and-accuracy.md +99 -0
- package/docs/troubleshooting.md +42 -0
- package/docs/uninstall.md +74 -0
- package/docs/what-leaves-your-machine.md +71 -0
- package/docs/where-things-are-stored.md +59 -0
- package/docs/worktrees-and-branches.md +55 -0
- package/package.json +5 -3
- package/src/commands/add-repo.js +5 -0
- package/src/commands/auditSend.js +67 -0
- package/src/commands/build.js +6 -0
- package/src/commands/docsSend.js +73 -0
- package/src/commands/engine.js +120 -0
- package/src/commands/engineRoutes.js +105 -0
- package/src/commands/guide.js +254 -0
- package/src/commands/init.js +16 -7
- package/src/commands/initLocal.js +96 -0
- package/src/commands/journalSend.js +47 -0
- package/src/commands/login.js +89 -12
- package/src/commands/mcp.js +22 -6
- package/src/commands/plan.js +99 -0
- package/src/commands/repoPush.js +33 -0
- package/src/commands/requestIntegration.js +38 -0
- package/src/commands/share.js +56 -0
- package/src/commands/start.js +451 -371
- package/src/commands/status.js +57 -0
- package/src/commands/takeover.js +6 -0
- package/src/commands/uninstall.js +180 -0
- package/src/commands/upgrade.js +38 -8
- package/src/commands/watch.js +420 -6
- package/src/index.js +174 -3
- package/src/lib/agentApi.js +32 -1
- package/src/lib/api.js +20 -6
- package/src/lib/auditUpload.js +293 -0
- package/src/lib/branchDrift.js +149 -0
- package/src/lib/choose.js +116 -0
- package/src/lib/cloudGuard.js +74 -0
- package/src/lib/credentials.js +2 -2
- package/src/lib/docsMarked.js +55 -0
- package/src/lib/docsState.js +213 -0
- package/src/lib/docsUpload.js +481 -0
- package/src/lib/engine.js +619 -0
- package/src/lib/folderSync.js +2 -1
- package/src/lib/graphCheck.js +40 -0
- package/src/lib/guide.js +293 -0
- package/src/lib/guideSearch.js +252 -0
- package/src/lib/integrationRequest.js +89 -0
- package/src/lib/journalUpload.js +147 -0
- package/src/lib/languages.js +129 -0
- package/src/lib/lease.js +375 -0
- package/src/lib/localBuild.js +285 -0
- package/src/lib/localEngine.js +210 -0
- package/src/lib/localOnboard.js +124 -0
- package/src/lib/localWorktrees.js +243 -0
- package/src/lib/machineCheck.js +58 -0
- package/src/lib/mcpClients.js +10 -1
- package/src/lib/migrationNotice.js +118 -0
- package/src/lib/modelFetch.js +153 -0
- package/src/lib/nestedOutput.js +23 -9
- package/src/lib/onboardingLog.js +34 -0
- package/src/lib/planUsage.js +165 -0
- package/src/lib/progressBar.js +46 -0
- package/src/lib/prompt.js +1 -1
- package/src/lib/redact.js +155 -0
- package/src/lib/release.js +33 -0
- package/src/lib/repoPush.js +495 -0
- package/src/lib/secret.js +1 -1
- package/src/lib/service.js +372 -63
- package/src/lib/shareCode.js +367 -0
- package/src/lib/shareExclusions.js +114 -0
- package/src/lib/shareFiles.js +129 -0
- package/src/lib/spinner.js +9 -5
- package/src/lib/watchDaemon.js +33 -10
- package/src/lib/watchState.js +12 -1
- package/src/lib/windowsPaths.js +67 -0
- package/src/mcp/lineCheck.js +382 -0
- package/src/mcp/lineName.js +92 -0
- package/src/mcp/localBackend.js +751 -0
- package/src/mcp/localMode.js +383 -0
- package/src/mcp/localSkill.js +189 -0
- package/src/mcp/server.js +610 -79
- package/src/mcp/setup.js +519 -131
- package/src/mcp/shellSearchHook.js +509 -0
- package/src/mcp/teardown.js +173 -91
- package/src/mcp/usingNiro.js +39 -0
- package/docs/working-on-branches.md +0 -162
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `niro plan` — the plan, its line usage on this machine, and what to do near the limit.
|
|
3
|
+
*
|
|
4
|
+
* The plan comes from a fresh lease (the same claims the engine enforces) and usage from the
|
|
5
|
+
* engine's own count, so this says exactly what the next build will be held to.
|
|
6
|
+
*/
|
|
7
|
+
const color = require("../lib/color");
|
|
8
|
+
const credentials = require("../lib/credentials");
|
|
9
|
+
const lease = require("../lib/lease");
|
|
10
|
+
const planUsage = require("../lib/planUsage");
|
|
11
|
+
const shareExclusions = require("../lib/shareExclusions");
|
|
12
|
+
const localEngine = require("../lib/localEngine");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
|
|
15
|
+
async function plan({ currentClaims = lease.currentClaims, linesUsed = planUsage.linesUsed, folders = planUsage.folders, excluded = shareExclusions.list, json = false } = {}) {
|
|
16
|
+
credentials.requireCreds();
|
|
17
|
+
const claims = await currentClaims().catch(() => null);
|
|
18
|
+
if (json) {
|
|
19
|
+
// For the niro-local skill: the same facts as the text below, in fields.
|
|
20
|
+
if (!claims) {
|
|
21
|
+
console.log(JSON.stringify({ ok: false, reason: "plan_unreachable" }));
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const used = await linesUsed();
|
|
26
|
+
const limit = claims.max_lines === undefined ? null : claims.max_lines;
|
|
27
|
+
console.log(JSON.stringify({
|
|
28
|
+
ok: true,
|
|
29
|
+
plan: claims.plan_name || null,
|
|
30
|
+
plan_id: claims.plan_id || null,
|
|
31
|
+
share_code: !!claims.share_code,
|
|
32
|
+
max_lines: limit,
|
|
33
|
+
lines_used: used,
|
|
34
|
+
over_by: limit !== null && used !== null ? Math.max(0, used - limit) : 0,
|
|
35
|
+
no_room: !!planUsage.noRoomNote(claims, used),
|
|
36
|
+
limit_url: limit !== null && used !== null ? planUsage.limitUrl(used, limit) : null,
|
|
37
|
+
folders: await folders(),
|
|
38
|
+
share_excluded: excluded(),
|
|
39
|
+
}));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!claims) {
|
|
43
|
+
console.error(color.red("Could not read your plan from Niro.") + ` Check your connection, then run ${color.cyan("niro plan")} again.`);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const used = await linesUsed();
|
|
48
|
+
const LABEL = 19;
|
|
49
|
+
const label = (s) => color.dim(s.padEnd(LABEL));
|
|
50
|
+
console.log(`${label("Plan")}${color.bold(planUsage.describe(claims, used))}`);
|
|
51
|
+
const [first, ...rows] = planUsage.sharingBlock(!!claims.share_code, LABEL);
|
|
52
|
+
console.log(`${label("Help improve Niro")}${first}`);
|
|
53
|
+
for (const row of rows) console.log(row);
|
|
54
|
+
const notShared = excluded();
|
|
55
|
+
if (notShared.length) {
|
|
56
|
+
console.log(` Not shared (${color.cyan("niro share include <folder>")} to share again):`);
|
|
57
|
+
for (const folder of notShared) console.log(` ${folder}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const limited = claims.max_lines !== undefined && claims.max_lines !== null;
|
|
61
|
+
if (!limited) return;
|
|
62
|
+
const noRoom = planUsage.noRoomNote(claims, used);
|
|
63
|
+
if (noRoom) {
|
|
64
|
+
console.log(color.yellow(`\n${noRoom}`));
|
|
65
|
+
console.log(`Choose how to continue: ${color.cyan(planUsage.limitUrl(used, claims.max_lines))}`);
|
|
66
|
+
}
|
|
67
|
+
const list = await planUsage.folders();
|
|
68
|
+
if (list.length) {
|
|
69
|
+
console.log(`\n${color.bold("Indexed on this machine")}, largest first`);
|
|
70
|
+
for (const f of list) console.log(` ${f.lines.toLocaleString("en-US").padStart(9)} ${f.path}`);
|
|
71
|
+
console.log(color.dim(" Each repository counts once, by its largest checkout; a folder inside another indexed folder is not counted again."));
|
|
72
|
+
}
|
|
73
|
+
console.log(`\n${color.bold("Options")}`);
|
|
74
|
+
if (claims.plan_id === "plan-free") {
|
|
75
|
+
console.log(` No line limit turn on "Share redacted code" at ${color.cyan(`${planUsage.consoleUrl()}/settings?tab=privacy`)}`);
|
|
76
|
+
}
|
|
77
|
+
console.log(` Pro free trial request it at ${color.cyan(`${planUsage.consoleUrl()}/request?plan=pro`)}`);
|
|
78
|
+
console.log(` Stay under it stop indexing a folder: ${color.cyan("niro plan remove <folder>")} (the same as ${color.cyan("niro remove --path <folder>")})`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* `niro plan remove <folder>`: stop indexing a folder, which frees its lines. The folder and its
|
|
83
|
+
* code are untouched; only what was indexed goes (the engine's own `remove`).
|
|
84
|
+
*/
|
|
85
|
+
async function remove(folder, { run = localEngine.run } = {}) {
|
|
86
|
+
if (!folder) throw new Error("Name the folder to stop indexing: niro plan remove <folder>");
|
|
87
|
+
const abs = path.resolve(folder);
|
|
88
|
+
let out;
|
|
89
|
+
try {
|
|
90
|
+
out = await run(["remove", "--path", abs]);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
// The engine says why on its own output ("... is not indexed"); show that, not our wrapper.
|
|
93
|
+
throw new Error((err && (err.stdout || err.stderr)) || `Could not stop indexing ${abs}.`);
|
|
94
|
+
}
|
|
95
|
+
if (out && out.trim()) console.log(out.trim());
|
|
96
|
+
console.log(`Stopped indexing ${abs}. Run ${color.cyan("niro plan")} to see your lines, or ${color.cyan("niro start")} to build.`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = { plan, remove };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `niro audit-push-repo` — send this folder's whole source to Niro, when the plan includes it.
|
|
3
|
+
*
|
|
4
|
+
* Explicit on purpose: nothing calls this as a side effect, no watcher runs it, and it is not
|
|
5
|
+
* part of `audit-send`, which sends only the files the audit flagged. The reasoning and every
|
|
6
|
+
* refusal live in `src/lib/repoPush.js`.
|
|
7
|
+
*/
|
|
8
|
+
const color = require("../lib/color");
|
|
9
|
+
const repoPush = require("../lib/repoPush");
|
|
10
|
+
|
|
11
|
+
async function pushRepo(pathArg, opts = {}) {
|
|
12
|
+
const folder = pathArg || process.cwd();
|
|
13
|
+
const result = await repoPush.pushFolder(folder, {
|
|
14
|
+
force: opts.force === true,
|
|
15
|
+
yes: opts.yes === true,
|
|
16
|
+
});
|
|
17
|
+
if (result.sent) {
|
|
18
|
+
console.log(` ${color.green("✓")} Sent ${result.files} files to Niro.`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (result.alreadySent) {
|
|
22
|
+
console.log(` Nothing sent: ${result.reason}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.error(color.red(` Nothing was sent: ${result.reason}`));
|
|
26
|
+
if (result.gateRefused) {
|
|
27
|
+
console.error(" `--force` on this command means \"send it again\", not \"ignore that\":");
|
|
28
|
+
console.error(" run it inside the one repository you meant instead.");
|
|
29
|
+
}
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = { pushRepo };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `niro request-integration <name>`: ask Niro's team to support a language, framework or tool. Asks
|
|
3
|
+
* first (unless --yes), then sends it with the signed-in account; the orchestrator stores it. The same
|
|
4
|
+
* request an assistant makes through the request_integration tool (src/lib/integrationRequest.js).
|
|
5
|
+
*/
|
|
6
|
+
const color = require("../lib/color");
|
|
7
|
+
const prompt = require("../lib/prompt");
|
|
8
|
+
const integration = require("../lib/integrationRequest");
|
|
9
|
+
|
|
10
|
+
async function requestIntegration(name, opts = {}, { send = integration.post, confirm = prompt.confirm } = {}) {
|
|
11
|
+
const { request, problem } = integration.check({ kind: opts.kind || "language", name, reason: opts.reason });
|
|
12
|
+
if (problem) {
|
|
13
|
+
console.error(color.red(`Not sent: ${problem}.`));
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const who = integration.account();
|
|
18
|
+
if (!who) {
|
|
19
|
+
console.error(color.red("Not signed in.") + ` Run ${color.cyan("niro start")} first.`);
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const what = `${request.name} (${request.kind})`;
|
|
24
|
+
if (!opts.yes && !(await confirm(`Send a request for ${what} support to Niro, as ${who}?`, true))) {
|
|
25
|
+
console.log("Not sent.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
await send({ ...request, source: "cli" });
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error(color.red(`Could not send the request: ${err.message}`));
|
|
32
|
+
process.exitCode = 1;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log(`${color.green("✓")} Sent. Niro's team will see your request for ${what}.`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = { requestIntegration };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `niro share` — which folders are kept out of code sharing.
|
|
3
|
+
*
|
|
4
|
+
* niro share list the folders not shared
|
|
5
|
+
* niro share exclude <folder> never share this folder (and every folder inside it)
|
|
6
|
+
* niro share include <folder> share it again
|
|
7
|
+
*
|
|
8
|
+
* Only matters while "Help improve Niro" is on: then the watcher shares every indexed folder that
|
|
9
|
+
* is not excluded (src/lib/shareCode.js), and `niro audit-push-repo` asks before sending an excluded one.
|
|
10
|
+
* Niraj, 2026-11-11: a user may exclude a folder while sharing stays on.
|
|
11
|
+
*/
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
|
|
15
|
+
const color = require("../lib/color");
|
|
16
|
+
const shareExclusions = require("../lib/shareExclusions");
|
|
17
|
+
|
|
18
|
+
function show({ log = console.log } = {}) {
|
|
19
|
+
const folders = shareExclusions.read();
|
|
20
|
+
if (folders === null) {
|
|
21
|
+
log(color.yellow(`The list of folders not shared (${shareExclusions.file()}) cannot be read, so no folder is shared until it is fixed or deleted.`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (folders.length === 0) {
|
|
25
|
+
log(`No folder is excluded from code sharing. To keep one out: ${color.cyan("niro share exclude <folder>")}`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
log(color.bold("Not shared") + " (each folder and every folder inside it)");
|
|
29
|
+
for (const folder of folders) log(` ${folder}`);
|
|
30
|
+
log(color.dim(`Share one again with ${"niro share include <folder>"}.`));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function exclude(folder, { log = console.log } = {}) {
|
|
34
|
+
if (!folder) throw new Error("Name the folder to keep out of code sharing: niro share exclude <folder>");
|
|
35
|
+
const resolved = path.resolve(folder);
|
|
36
|
+
// A typo must not leave the folder the person meant being shared, so only a real folder is taken.
|
|
37
|
+
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) {
|
|
38
|
+
throw new Error(`Not a folder: ${resolved}`);
|
|
39
|
+
}
|
|
40
|
+
const added = shareExclusions.exclude(resolved);
|
|
41
|
+
const name = shareExclusions.canonical(resolved);
|
|
42
|
+
log(added ? `${name} is not shared from now on, nor any folder inside it.` : `${name} was already excluded.`);
|
|
43
|
+
log(color.dim("Code already sent stays until it is processed and deleted. Another checkout of the same repository elsewhere is not excluded by this."));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function include(folder, { log = console.log } = {}) {
|
|
47
|
+
if (!folder) throw new Error("Name the folder to share again: niro share include <folder>");
|
|
48
|
+
const name = shareExclusions.canonical(folder);
|
|
49
|
+
if (shareExclusions.include(folder)) {
|
|
50
|
+
log(`${name} is shared again while Help improve Niro is on.`);
|
|
51
|
+
} else {
|
|
52
|
+
log(`${name} was not excluded by that name. Run ${color.cyan("niro share")} to see the list.`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = { show, exclude, include };
|