@niroai/niro 0.16.0 → 0.17.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
@@ -4,6 +4,19 @@ Notable changes to `@niroai/niro`. Dates are release dates.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.17.0 — 2026-09-23
8
+
9
+ ### `niro init --defaults` still asks which project
10
+
11
+ `--defaults` accepts default values: env vars, indexing scope, the project name. It also used to
12
+ skip the "new project, or add to an existing one?" question and always create a new project, which
13
+ put repos in the wrong place for anyone who already had a project for them. Which project is not a
14
+ default value, so in a terminal the question is now asked with `--defaults` too.
15
+
16
+ Unattended runs are unchanged. With no terminal (CI, a piped script, an agent's shell) there is no
17
+ question and a new project is created, as before. A script that wants an existing project passes
18
+ `--add-to <alias|id>`; `--project-name <name>` still skips the question everywhere.
19
+
7
20
  ## 0.16.0 — 2026-09-22
8
21
 
9
22
  ### A reverse proxy's routing table is offered for upload
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@niroai/niro",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Niro \u2014 one package: the niro CLI plus the Niro MCP server (code intelligence for AI coding assistants).",
5
5
  "keywords": [
6
6
  "niro",
@@ -946,10 +946,11 @@ async function scanIndexedChildren(targetDir, opts, resolve = resolveContext) {
946
946
  * Decide the TARGET of this onboarding up front, before any repo registration:
947
947
  * - --add-to <alias|id> -> EXISTING: resolve to a real projectId (throws on
948
948
  * ambiguity/not-found via resolveProjectId), attach the new repo to it later.
949
- * - --project-name / --defaults / non-interactive -> NEW: derive a free name
950
- * exactly as before (unchanged behaviour for scripts and the default path).
949
+ * - --project-name / non-interactive -> NEW: derive a free name exactly as
950
+ * before (unchanged behaviour for scripts).
951
951
  * - INTERACTIVE with >=1 existing project -> show a numbered menu (new vs each
952
952
  * existing project) so the user can attach instead of always creating new.
953
+ * This holds with --defaults too.
953
954
  *
954
955
  * Returns { projectId, isExisting } or null when the user/flags didn't yield a
955
956
  * usable target (caller sets exitCode=1).
@@ -966,10 +967,14 @@ async function resolveTarget({ defaultName, opts }) {
966
967
  return { projectId, isExisting: true };
967
968
  }
968
969
 
969
- // Explicit name, --defaults, or a non-interactive shell -> NEW (current path).
970
+ // Explicit name or a non-interactive shell -> NEW (current path).
970
971
  // We only offer the existing-project menu in an interactive shell with at
971
- // least one project to pick.
972
- if (!opts.projectName && !opts.defaults && !prompt.isNonInteractive()) {
972
+ // least one project to pick. --defaults does NOT skip it: that flag accepts
973
+ // default VALUES (env vars, scope, name), and "which project" has no safe
974
+ // default, so creating a new one silently put repos in the wrong place.
975
+ // Unattended runs have no terminal, so they still go straight to NEW; a
976
+ // script that wants an existing project passes --add-to.
977
+ if (!opts.projectName && !prompt.isNonInteractive()) {
973
978
  const existing = await fetchExistingProjects(opts);
974
979
  if (existing.length > 0) {
975
980
  const chosen = await chooseTarget(existing);