@niroai/niro 0.3.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/README.md +291 -0
- package/bin/niro.js +2 -0
- package/package.json +41 -0
- package/src/commands/_resolveProject.js +142 -0
- package/src/commands/add-project.js +190 -0
- package/src/commands/add-repo.js +270 -0
- package/src/commands/build.js +118 -0
- package/src/commands/delete.js +66 -0
- package/src/commands/edit.js +601 -0
- package/src/commands/info.js +172 -0
- package/src/commands/init.js +1166 -0
- package/src/commands/login.js +214 -0
- package/src/commands/logout.js +33 -0
- package/src/commands/mcp.js +40 -0
- package/src/commands/projects.js +76 -0
- package/src/commands/release.js +175 -0
- package/src/commands/remove.js +95 -0
- package/src/commands/status.js +75 -0
- package/src/commands/takeover.js +204 -0
- package/src/commands/watch.js +498 -0
- package/src/commands/whoami.js +74 -0
- package/src/index.js +293 -0
- package/src/lib/agentApi.js +276 -0
- package/src/lib/api.js +230 -0
- package/src/lib/browser.js +30 -0
- package/src/lib/color.js +46 -0
- package/src/lib/config.js +38 -0
- package/src/lib/credentials.js +73 -0
- package/src/lib/folderSync.js +503 -0
- package/src/lib/git.js +190 -0
- package/src/lib/moduleExcludeSuggestions.js +57 -0
- package/src/lib/niroProjectFile.js +76 -0
- package/src/lib/pendingRequests.js +99 -0
- package/src/lib/prompt.js +118 -0
- package/src/lib/resolveContext.js +108 -0
- package/src/lib/secret.js +114 -0
- package/src/lib/service.js +221 -0
- package/src/lib/spinner.js +109 -0
- package/src/lib/watchDaemon.js +93 -0
- package/src/lib/watchState.js +217 -0
- package/src/mcp/server.js +764 -0
- package/src/mcp/setup.js +1976 -0
- package/src/mcp/teardown.js +673 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `niro info [path] [--json]` — report what Niro knows about the current
|
|
3
|
+
* working directory: is it a git repo, does it have an origin, and which Niro
|
|
4
|
+
* project(s) (if any) map to it, plus each project's build/doc status.
|
|
5
|
+
*
|
|
6
|
+
* Designed to be agent-friendly:
|
|
7
|
+
* - Not logged in -> {authed:false} (JSON) / human "not logged in", exit 0
|
|
8
|
+
* (mirrors `whoami --json` so an agent can branch instead of crash).
|
|
9
|
+
* - Not a git repo / no origin -> graceful {indexed:false, reason:...}, no throw.
|
|
10
|
+
* - resolveContext degrades gracefully (state "error") rather than throwing,
|
|
11
|
+
* so resolution failures don't crash the command.
|
|
12
|
+
*
|
|
13
|
+
* NEVER prints secrets: it only emits project ids, aliases and status fields —
|
|
14
|
+
* no env-var values, tokens or credentials are touched here.
|
|
15
|
+
*/
|
|
16
|
+
const api = require("../lib/api");
|
|
17
|
+
const credentials = require("../lib/credentials");
|
|
18
|
+
const color = require("../lib/color");
|
|
19
|
+
const { resolveContext } = require("../lib/resolveContext");
|
|
20
|
+
|
|
21
|
+
async function info(pathArg, opts = {}) {
|
|
22
|
+
const startPath = pathArg || process.cwd();
|
|
23
|
+
|
|
24
|
+
// Auth gate — mirror whoami: emit a branchable result and exit 0 when not
|
|
25
|
+
// logged in, instead of throwing ENOAUTH.
|
|
26
|
+
const creds = credentials.load();
|
|
27
|
+
const durable = creds && (creds.cliToken || creds.niroApiKey);
|
|
28
|
+
if (!creds || (!creds.token && !durable)) {
|
|
29
|
+
if (opts.json) {
|
|
30
|
+
console.log(JSON.stringify({ authed: false }));
|
|
31
|
+
} else {
|
|
32
|
+
console.log("Not logged in. Run `niro login` first.");
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const ctx = await resolveContext(startPath, { apiUrl: opts.apiUrl });
|
|
38
|
+
|
|
39
|
+
// Not a git repo / no origin: short, branchable result. No server projects.
|
|
40
|
+
if (ctx.state === "not_a_git_repo") {
|
|
41
|
+
return emit(opts, {
|
|
42
|
+
git_root: null,
|
|
43
|
+
repo_url: null,
|
|
44
|
+
branch: null,
|
|
45
|
+
indexed: false,
|
|
46
|
+
ambiguous: false,
|
|
47
|
+
reason: "not_a_git_repo",
|
|
48
|
+
projects: [],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (ctx.state === "no_origin") {
|
|
52
|
+
return emit(opts, {
|
|
53
|
+
git_root: ctx.gitRoot,
|
|
54
|
+
repo_url: null,
|
|
55
|
+
branch: ctx.branch,
|
|
56
|
+
indexed: false,
|
|
57
|
+
ambiguous: false,
|
|
58
|
+
reason: "no_origin",
|
|
59
|
+
projects: [],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Resolution failed (server/network) — report gracefully, don't throw.
|
|
64
|
+
if (ctx.state === "error") {
|
|
65
|
+
return emit(opts, {
|
|
66
|
+
git_root: ctx.gitRoot,
|
|
67
|
+
repo_url: ctx.repoUrl,
|
|
68
|
+
branch: ctx.branch,
|
|
69
|
+
indexed: false,
|
|
70
|
+
ambiguous: false,
|
|
71
|
+
reason: "resolve_error",
|
|
72
|
+
error: ctx.error || null,
|
|
73
|
+
projects: [],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Resolved or unresolved: fetch status for each matched project.
|
|
78
|
+
const projects = [];
|
|
79
|
+
for (const p of ctx.projects) {
|
|
80
|
+
let status = null;
|
|
81
|
+
let docGenStatus = null;
|
|
82
|
+
let updatedAt = null;
|
|
83
|
+
try {
|
|
84
|
+
const data = await api.get(`/api/graph/${encodeURIComponent(p.project_id)}/status`, {
|
|
85
|
+
apiUrl: opts.apiUrl,
|
|
86
|
+
});
|
|
87
|
+
status = data.status || null;
|
|
88
|
+
docGenStatus = data.doc_gen_status || data.docGenStatus || null;
|
|
89
|
+
updatedAt = data.updated_at || data.updatedAt || null;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
// A status fetch failure for one project must not abort the whole command.
|
|
92
|
+
status = null;
|
|
93
|
+
}
|
|
94
|
+
projects.push({
|
|
95
|
+
project_id: p.project_id,
|
|
96
|
+
alias: p.alias || null,
|
|
97
|
+
// Matched repo's registration kind (REMOTE_GIT / LOCAL_PATH / AGENT_UPLOAD),
|
|
98
|
+
// or null. Lets agents warn on remote-git projects (auto-build only on commits).
|
|
99
|
+
source_type: p.source_type || null,
|
|
100
|
+
status,
|
|
101
|
+
doc_gen_status: docGenStatus,
|
|
102
|
+
updated_at: updatedAt,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const indexed = projects.length > 0;
|
|
107
|
+
const ambiguous = projects.length > 1;
|
|
108
|
+
|
|
109
|
+
return emit(opts, {
|
|
110
|
+
git_root: ctx.gitRoot,
|
|
111
|
+
repo_url: ctx.repoUrl,
|
|
112
|
+
branch: ctx.branch, // null === detached HEAD
|
|
113
|
+
indexed,
|
|
114
|
+
ambiguous,
|
|
115
|
+
projects,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Emit either JSON (exact shape) or a plain-English human summary. */
|
|
120
|
+
function emit(opts, payload) {
|
|
121
|
+
if (opts.json) {
|
|
122
|
+
console.log(JSON.stringify(payload));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
printHuman(payload);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function printHuman(p) {
|
|
129
|
+
const label = (s) => color.dim(s.padEnd(11));
|
|
130
|
+
|
|
131
|
+
if (p.reason === "not_a_git_repo") {
|
|
132
|
+
console.log("This folder is not a git repository, so Niro can't index it.");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (p.reason === "no_origin") {
|
|
136
|
+
console.log(`${label("Git root:")} ${p.git_root}`);
|
|
137
|
+
console.log("No git remote (origin) is set, so Niro can't match this repo to a project.");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (p.reason === "resolve_error") {
|
|
141
|
+
console.log(`${label("Git root:")} ${p.git_root}`);
|
|
142
|
+
console.log(`${label("Repo URL:")} ${color.cyan(p.repo_url)}`);
|
|
143
|
+
console.log(color.yellow("Could not reach the server to check indexing status.") +
|
|
144
|
+
(p.error ? ` (${p.error})` : ""));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
console.log(`${label("Git root:")} ${p.git_root}`);
|
|
149
|
+
console.log(`${label("Repo URL:")} ${color.cyan(p.repo_url)}`);
|
|
150
|
+
console.log(`${label("Branch:")} ${p.branch || color.dim("(detached HEAD)")}`);
|
|
151
|
+
|
|
152
|
+
if (!p.indexed) {
|
|
153
|
+
console.log("This repo is " + color.yellow("not indexed") + " by Niro yet. Run `niro init` to onboard it.");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (p.ambiguous) {
|
|
158
|
+
console.log(color.yellow(`This repo maps to ${p.projects.length} Niro projects:`));
|
|
159
|
+
} else {
|
|
160
|
+
console.log(color.green("This repo is indexed by Niro."));
|
|
161
|
+
}
|
|
162
|
+
for (const proj of p.projects) {
|
|
163
|
+
const name = proj.alias ? `${color.bold(proj.alias)} (${color.dim(proj.project_id)})` : color.bold(proj.project_id);
|
|
164
|
+
const bits = [];
|
|
165
|
+
if (proj.status) bits.push(`status: ${proj.status}`);
|
|
166
|
+
if (proj.doc_gen_status) bits.push(`docs: ${proj.doc_gen_status}`);
|
|
167
|
+
if (proj.updated_at) bits.push(`updated: ${proj.updated_at}`);
|
|
168
|
+
console.log(` - ${name}${bits.length ? " — " + color.dim(bits.join(", ")) : ""}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
module.exports = { info };
|