@datalabrotterdam/nova-ai-cli 1.1.0 → 1.2.0-alpha.10

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +211 -100
  3. package/dist/browser-setup-7SWHUQEL.js +57 -0
  4. package/dist/chunk-FMHWW3E6.js +11 -0
  5. package/dist/chunk-KDAUUQBE.js +643 -0
  6. package/dist/chunk-L77KQRGZ.js +170 -0
  7. package/dist/headless-BQXK7TNC.js +550 -0
  8. package/dist/index.js +193 -17
  9. package/dist/tui-TJFV6NC6.js +5185 -0
  10. package/dist/update-check-G3PYCRWM.js +23 -0
  11. package/package.json +35 -33
  12. package/dist/acp/agent.d.ts +0 -13
  13. package/dist/acp/agent.js +0 -242
  14. package/dist/acp/auth-server.d.ts +0 -10
  15. package/dist/acp/auth-server.js +0 -67
  16. package/dist/acp/credentials.d.ts +0 -11
  17. package/dist/acp/credentials.js +0 -30
  18. package/dist/acp/index.d.ts +0 -2
  19. package/dist/acp/index.js +0 -21
  20. package/dist/acp/mcp.d.ts +0 -11
  21. package/dist/acp/mcp.js +0 -90
  22. package/dist/acp/sessions.d.ts +0 -20
  23. package/dist/acp/sessions.js +0 -91
  24. package/dist/acp/tools/index.d.ts +0 -6
  25. package/dist/acp/tools/index.js +0 -5
  26. package/dist/acp/tools/marker.d.ts +0 -17
  27. package/dist/acp/tools/marker.js +0 -43
  28. package/dist/acp/tools/permission.d.ts +0 -2
  29. package/dist/acp/tools/permission.js +0 -20
  30. package/dist/acp/tools/read-file.d.ts +0 -2
  31. package/dist/acp/tools/read-file.js +0 -20
  32. package/dist/acp/tools/registry.d.ts +0 -4
  33. package/dist/acp/tools/registry.js +0 -10
  34. package/dist/acp/tools/reporting.d.ts +0 -3
  35. package/dist/acp/tools/reporting.js +0 -26
  36. package/dist/acp/tools/run-command.d.ts +0 -2
  37. package/dist/acp/tools/run-command.js +0 -29
  38. package/dist/acp/tools/system-prompt.d.ts +0 -2
  39. package/dist/acp/tools/system-prompt.js +0 -23
  40. package/dist/acp/tools/types.d.ts +0 -18
  41. package/dist/acp/tools/types.js +0 -1
  42. package/dist/acp/tools/write-file.d.ts +0 -2
  43. package/dist/acp/tools/write-file.js +0 -20
  44. package/dist/index.d.ts +0 -2
  45. package/dist/tui/index.d.ts +0 -7
  46. package/dist/tui/index.js +0 -11
  47. package/dist/webui/index.d.ts +0 -6
  48. package/dist/webui/index.js +0 -9
  49. package/src/acp/web/dist/assets/index-CSccI7lJ.css +0 -1
  50. package/src/acp/web/dist/assets/index-D2Z0sfLR.js +0 -1
  51. package/src/acp/web/dist/favicon.svg +0 -46
  52. package/src/acp/web/dist/index.html +0 -32
package/dist/index.js CHANGED
@@ -1,25 +1,201 @@
1
1
  #!/usr/bin/env node
2
- import { runBrowserAuth } from "./acp/auth-server.js";
3
- import chat from "./tui/index.js";
4
- import web from "./webui/index.js";
5
- import acp from "./acp/index.js";
2
+ import {
3
+ cliVersion
4
+ } from "./chunk-FMHWW3E6.js";
5
+
6
+ // src/cli.ts
7
+ var SUBCOMMANDS = {
8
+ login: "login",
9
+ logout: "logout",
10
+ help: "help",
11
+ version: "version"
12
+ };
13
+ var MODE_FLAGS = {
14
+ "--acp": "acp",
15
+ "-p": "print",
16
+ "--print": "print",
17
+ "--headless": "print",
18
+ "--setup": "login",
19
+ "--version": "version",
20
+ "-v": "version"
21
+ };
22
+ function parseCli(argv) {
23
+ const first = argv[0];
24
+ if (first !== void 0 && SUBCOMMANDS[first]) {
25
+ return { mode: SUBCOMMANDS[first], args: argv.slice(1) };
26
+ }
27
+ const end = argv.indexOf("--");
28
+ const options = end >= 0 ? argv.slice(0, end) : argv;
29
+ const modes = new Set(options.flatMap((arg) => MODE_FLAGS[arg] ? [MODE_FLAGS[arg]] : []));
30
+ if (modes.size > 1) {
31
+ return { mode: "error", message: `Choose one mode, not ${[...modes].join(" and ")}.` };
32
+ }
33
+ const mode = [...modes][0];
34
+ const wantsHelp = options.includes("--help") || options.includes("-h");
35
+ if (!mode) return wantsHelp ? { mode: "help", args: [] } : { mode: "tui", args: argv };
36
+ const drop = /* @__PURE__ */ new Set(["--acp", "--headless", "--setup", "--version", "-v"]);
37
+ return { mode, args: argv.filter((arg, index) => !(drop.has(arg) && (end < 0 || index < end))) };
38
+ }
39
+ function versionText() {
40
+ return `nova-ai ${cliVersion() ?? "unknown"}`;
41
+ }
42
+ var MAIN_HELP = `Nova AI \u2014 agentic coding in your terminal, and an ACP agent for editors.
43
+
44
+ Usage:
45
+ nova-ai [options] Interactive terminal UI
46
+ nova-ai -p [options] [prompt] Run one request headless (see nova-ai -p --help)
47
+ nova-ai --acp Agent Client Protocol over stdio (for editors)
48
+ nova-ai login [--no-browser] Connect your Nova AI account
49
+ nova-ai logout Remove the stored API key
50
+
51
+ Interactive options:
52
+ --resume <session-id> Continue a saved session
53
+ -c, --continue Continue the most recent session in this folder
54
+ --model <id> Use this model
55
+
56
+ General:
57
+ -h, --help Show help
58
+ -v, --version Show the version
59
+
60
+ Environment:
61
+ NOVA_API_KEY, NOVA_MODEL Use this key / model instead of the stored ones
62
+ NOVA_BASE_URL Use another Nova gateway
63
+ NOVA_AI_HOME Settings folder (default ~/.nova-ai)
64
+ NOVA_TOOL_PROTOCOL Force "native" or "text" tool calling`;
65
+ function parseTuiArgs(args) {
66
+ const options = { resume: null, continueLast: false, model: null };
67
+ for (let index = 0; index < args.length; index++) {
68
+ const arg = args[index];
69
+ const value = (name) => {
70
+ const next = args[++index];
71
+ if (!next || next.startsWith("-")) throw new Error(`${name} requires a value.`);
72
+ return next;
73
+ };
74
+ if (arg === "--resume") options.resume = value(arg);
75
+ else if (arg.startsWith("--resume=")) options.resume = arg.slice("--resume=".length);
76
+ else if (arg === "--continue" || arg === "-c") options.continueLast = true;
77
+ else if (arg === "--model") options.model = value(arg);
78
+ else if (arg.startsWith("--model=")) options.model = arg.slice("--model=".length);
79
+ else throw new Error(`Unknown option for the interactive UI: ${arg}`);
80
+ }
81
+ if (options.resume && options.continueLast) {
82
+ throw new Error("Use either --continue or --resume, not both.");
83
+ }
84
+ return options;
85
+ }
86
+
87
+ // src/index.ts
88
+ function startUpdateCheck() {
89
+ if (!process.stderr.isTTY) return null;
90
+ const abort = new AbortController();
91
+ const result = import("./update-check-G3PYCRWM.js").then(({ checkForUpdate }) => checkForUpdate({ signal: abort.signal })).catch(() => null);
92
+ return { result, cancel: () => abort.abort() };
93
+ }
94
+ async function noticeUpdate(check, waitMs) {
95
+ let timer;
96
+ const update = await Promise.race([
97
+ check.result,
98
+ new Promise((resolve) => {
99
+ timer = setTimeout(() => resolve(null), waitMs);
100
+ })
101
+ ]);
102
+ clearTimeout(timer);
103
+ check.cancel();
104
+ if (!update) return;
105
+ const { formatUpdateNotice } = await import("./update-check-G3PYCRWM.js");
106
+ process.stderr.write(`
107
+ ${formatUpdateNotice(update)}
108
+ `);
109
+ }
110
+ var BROWSER_MODES = /* @__PURE__ */ new Set(["tui", "print", "acp", "web"]);
6
111
  async function main() {
7
- const args = process.argv.slice(2);
8
- if (args.includes("--setup")) {
9
- await runBrowserAuth();
10
- return;
112
+ const command = parseCli(process.argv.slice(2));
113
+ if (BROWSER_MODES.has(command.mode)) {
114
+ const { setUpBrowserInBackground } = await import("./browser-setup-7SWHUQEL.js");
115
+ setUpBrowserInBackground();
116
+ }
117
+ switch (command.mode) {
118
+ case "error":
119
+ process.stderr.write(`${command.message}
120
+
121
+ ${MAIN_HELP}
122
+ `);
123
+ return 2;
124
+ case "help":
125
+ process.stdout.write(`${MAIN_HELP}
126
+ `);
127
+ return 0;
128
+ case "version": {
129
+ const update = startUpdateCheck();
130
+ process.stdout.write(`${versionText()}
131
+ `);
132
+ if (update) await noticeUpdate(update, 800);
133
+ return 0;
134
+ }
135
+ case "acp": {
136
+ if (command.args.length) {
137
+ process.stderr.write(`--acp takes no other arguments (got ${command.args.join(" ")}).
138
+ `);
139
+ return 2;
140
+ }
141
+ const { default: runAcp } = await import("@datalabrotterdam/nova-ai-agent/acp/index.js");
142
+ await runAcp();
143
+ return 0;
144
+ }
145
+ case "print": {
146
+ const update = startUpdateCheck();
147
+ const { default: runHeadless } = await import("./headless-BQXK7TNC.js");
148
+ const code = await runHeadless(command.args);
149
+ if (update) await noticeUpdate(update, 500);
150
+ return code;
151
+ }
152
+ case "login": {
153
+ const { runLogin } = await import("@datalabrotterdam/nova-ai-agent/commands/login.js");
154
+ const code = await runLogin(command.args);
155
+ if (code === 0) {
156
+ const { browserSetupDisabled, describeBrowserSetup, setUpBrowser } = await import("./browser-setup-7SWHUQEL.js");
157
+ if (!browserSetupDisabled()) {
158
+ await setUpBrowser().then(
159
+ (result) => process.stderr.write(`${describeBrowserSetup(result)}
160
+ `),
161
+ () => void 0
162
+ );
163
+ }
164
+ }
165
+ return code;
11
166
  }
12
- if (args.includes("--acp")) {
13
- await acp(...args.slice(1));
14
- return;
167
+ case "logout": {
168
+ const { runLogout } = await import("@datalabrotterdam/nova-ai-agent/commands/login.js");
169
+ return runLogout();
15
170
  }
16
- if (args.includes("--web")) {
17
- await web(...args.slice(1));
18
- return;
171
+ case "tui": {
172
+ let options;
173
+ try {
174
+ options = parseTuiArgs(command.args);
175
+ } catch (error) {
176
+ process.stderr.write(`${error.message}
177
+
178
+ ${MAIN_HELP}
179
+ `);
180
+ return 2;
181
+ }
182
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
183
+ process.stderr.write(
184
+ 'nova-ai needs an interactive terminal. For scripts and pipes use `nova-ai -p "<prompt>"`, for editors `nova-ai --acp`.\n'
185
+ );
186
+ return 2;
187
+ }
188
+ const { default: runChat } = await import("./tui-TJFV6NC6.js");
189
+ return runChat(options);
19
190
  }
20
- await chat(...args.slice(1));
191
+ }
21
192
  }
22
- main().catch((err) => {
193
+ main().then(
194
+ (code) => {
195
+ process.exitCode = code;
196
+ },
197
+ (err) => {
23
198
  console.error(err);
24
199
  process.exit(1);
25
- });
200
+ }
201
+ );