@datalabrotterdam/nova-ai-cli 1.2.0-alpha.1 → 1.2.0-alpha.11
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 +172 -0
- package/README.md +76 -32
- package/dist/browser-setup-7SWHUQEL.js +57 -0
- package/dist/chunk-FMHWW3E6.js +11 -0
- package/dist/{chunk-ZKRZIF3S.js → chunk-KDAUUQBE.js} +49 -360
- package/dist/chunk-L77KQRGZ.js +170 -0
- package/dist/{headless-ZYUSTZDL.js → headless-BQXK7TNC.js} +29 -46
- package/dist/index.js +57 -19
- package/dist/{tui-XOKXPXN2.js → tui-TJFV6NC6.js} +719 -335
- package/dist/update-check-G3PYCRWM.js +23 -0
- package/package.json +25 -39
- package/dist/acp-ZYOQ6PON.js +0 -65
- package/dist/chunk-GZZ7PY3S.js +0 -8878
- package/dist/chunk-JAEXUFAS.js +0 -451
- package/dist/chunk-Q7WL3DXP.js +0 -19
- package/dist/index.d.ts +0 -1
- package/dist/login-6U7QS7EA.js +0 -118
- package/dist/webui-L4GGMXJ3.js +0 -9
- package/src/acp/web/dist/assets/index-CSccI7lJ.css +0 -1
- package/src/acp/web/dist/assets/index-DlCz3fmq.js +0 -1
- package/src/acp/web/dist/favicon.svg +0 -46
- package/src/acp/web/dist/index.html +0 -32
|
@@ -1,43 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TuiAcpClient,
|
|
3
3
|
choosePermissionOption,
|
|
4
|
-
createStore
|
|
5
|
-
|
|
6
|
-
startInProcessAgent
|
|
7
|
-
} from "./chunk-ZKRZIF3S.js";
|
|
8
|
-
import {
|
|
9
|
-
NOVA_NOTIFICATIONS,
|
|
10
|
-
NovaAgent,
|
|
11
|
-
listStoredSessions,
|
|
12
|
-
loadStoredSession
|
|
13
|
-
} from "./chunk-GZZ7PY3S.js";
|
|
14
|
-
import "./chunk-Q7WL3DXP.js";
|
|
15
|
-
import {
|
|
16
|
-
setWorkspaceTrusted
|
|
17
|
-
} from "./chunk-JAEXUFAS.js";
|
|
4
|
+
createStore
|
|
5
|
+
} from "./chunk-KDAUUQBE.js";
|
|
18
6
|
|
|
19
7
|
// src/headless/index.ts
|
|
20
8
|
import { resolve } from "path";
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
// src/client/context-client.ts
|
|
9
|
+
import { NOVA_NOTIFICATIONS } from "@datalabrotterdam/nova-ai-agent/acp/extensions.js";
|
|
24
10
|
import * as acp from "@agentclientprotocol/sdk";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
requestPermission: (params) => request(acp.methods.client.session.requestPermission, params),
|
|
30
|
-
readTextFile: (params) => request(acp.methods.client.fs.readTextFile, params),
|
|
31
|
-
writeTextFile: async (params) => await request(acp.methods.client.fs.writeTextFile, params) ?? {},
|
|
32
|
-
createTerminal: (params) => request(acp.methods.client.terminal.create, params),
|
|
33
|
-
terminalOutput: (params) => request(acp.methods.client.terminal.output, params),
|
|
34
|
-
waitForTerminalExit: (params) => request(acp.methods.client.terminal.waitForExit, params),
|
|
35
|
-
killTerminal: async (params) => await request(acp.methods.client.terminal.kill, params) ?? {},
|
|
36
|
-
releaseTerminal: async (params) => await request(acp.methods.client.terminal.release, params) ?? {},
|
|
37
|
-
unstable_createElicitation: (params) => request(acp.methods.client.elicitation.create, params),
|
|
38
|
-
extNotification: (method, params) => context.notify(method, params)
|
|
39
|
-
};
|
|
40
|
-
}
|
|
11
|
+
import { NovaAgent } from "@datalabrotterdam/nova-ai-agent/acp/agent.js";
|
|
12
|
+
import { clientFromContext } from "@datalabrotterdam/nova-ai-agent/client/context-client.js";
|
|
13
|
+
import { startInProcessAgent } from "@datalabrotterdam/nova-ai-agent/client/in-process.js";
|
|
14
|
+
import { listStoredSessions, loadStoredSession } from "@datalabrotterdam/nova-ai-agent/core/sessions.js";
|
|
41
15
|
|
|
42
16
|
// src/headless/client.ts
|
|
43
17
|
var HeadlessAcpClient = class {
|
|
@@ -215,15 +189,19 @@ ${HEADLESS_HELP}
|
|
|
215
189
|
dependencies.agent ?? new NovaAgent()
|
|
216
190
|
);
|
|
217
191
|
const agent = connection.client;
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
serverName
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
192
|
+
const sessionMeta = { "nova-ai-cli/workspaceMcp": options.mcp };
|
|
193
|
+
const reportMcpFailures = (meta) => {
|
|
194
|
+
const failures = toRecord(toRecord(meta)?.["nova-ai-cli/mcp"])?.failures;
|
|
195
|
+
for (const failure of Array.isArray(failures) ? failures : []) {
|
|
196
|
+
const item = toRecord(failure);
|
|
197
|
+
if (typeof item?.serverName !== "string" || typeof item.message !== "string") continue;
|
|
198
|
+
output.write({
|
|
199
|
+
type: "mcp.configuration_error",
|
|
200
|
+
serverName: item.serverName,
|
|
201
|
+
message: item.message
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
};
|
|
227
205
|
let sessionId = null;
|
|
228
206
|
let interrupted = false;
|
|
229
207
|
const onInterrupt = () => {
|
|
@@ -235,22 +213,27 @@ ${HEADLESS_HELP}
|
|
|
235
213
|
process.once("SIGINT", onInterrupt);
|
|
236
214
|
try {
|
|
237
215
|
await agent.initialize({
|
|
238
|
-
protocolVersion:
|
|
216
|
+
protocolVersion: acp.PROTOCOL_VERSION,
|
|
239
217
|
clientCapabilities: client.capabilities,
|
|
240
218
|
clientInfo: { name: "nova-ai-cli-headless", version: "1" }
|
|
241
219
|
});
|
|
220
|
+
if (options.trustWorkspace) await agent.workspaceTrust({ cwd: options.cwd, trusted: true });
|
|
242
221
|
if (options.resume) {
|
|
243
|
-
await agent.resumeSession({
|
|
222
|
+
const resumed = await agent.resumeSession({
|
|
244
223
|
sessionId: options.resume,
|
|
245
224
|
cwd: options.cwd,
|
|
246
|
-
mcpServers:
|
|
225
|
+
mcpServers: [],
|
|
226
|
+
_meta: sessionMeta
|
|
247
227
|
});
|
|
228
|
+
reportMcpFailures(resumed._meta);
|
|
248
229
|
sessionId = options.resume;
|
|
249
230
|
} else {
|
|
250
231
|
const created = await agent.newSession({
|
|
251
232
|
cwd: options.cwd,
|
|
252
|
-
mcpServers:
|
|
233
|
+
mcpServers: [],
|
|
234
|
+
_meta: sessionMeta
|
|
253
235
|
});
|
|
236
|
+
reportMcpFailures(created._meta);
|
|
254
237
|
sessionId = created.sessionId;
|
|
255
238
|
}
|
|
256
239
|
await agent.setSessionConfigOption({
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
cliVersion
|
|
4
|
+
} from "./chunk-FMHWW3E6.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
var SUBCOMMANDS = {
|
|
@@ -17,8 +17,7 @@ var MODE_FLAGS = {
|
|
|
17
17
|
"--headless": "print",
|
|
18
18
|
"--setup": "login",
|
|
19
19
|
"--version": "version",
|
|
20
|
-
"-v": "version"
|
|
21
|
-
"--web": "web"
|
|
20
|
+
"-v": "version"
|
|
22
21
|
};
|
|
23
22
|
function parseCli(argv) {
|
|
24
23
|
const first = argv[0];
|
|
@@ -34,11 +33,11 @@ function parseCli(argv) {
|
|
|
34
33
|
const mode = [...modes][0];
|
|
35
34
|
const wantsHelp = options.includes("--help") || options.includes("-h");
|
|
36
35
|
if (!mode) return wantsHelp ? { mode: "help", args: [] } : { mode: "tui", args: argv };
|
|
37
|
-
const drop = /* @__PURE__ */ new Set(["--acp", "--headless", "--setup", "--version", "-v"
|
|
36
|
+
const drop = /* @__PURE__ */ new Set(["--acp", "--headless", "--setup", "--version", "-v"]);
|
|
38
37
|
return { mode, args: argv.filter((arg, index) => !(drop.has(arg) && (end < 0 || index < end))) };
|
|
39
38
|
}
|
|
40
39
|
function versionText() {
|
|
41
|
-
return `nova-ai ${
|
|
40
|
+
return `nova-ai ${cliVersion() ?? "unknown"}`;
|
|
42
41
|
}
|
|
43
42
|
var MAIN_HELP = `Nova AI \u2014 agentic coding in your terminal, and an ACP agent for editors.
|
|
44
43
|
|
|
@@ -86,8 +85,35 @@ function parseTuiArgs(args) {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
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"]);
|
|
89
111
|
async function main() {
|
|
90
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
|
+
}
|
|
91
117
|
switch (command.mode) {
|
|
92
118
|
case "error":
|
|
93
119
|
process.stderr.write(`${command.message}
|
|
@@ -99,37 +125,49 @@ ${MAIN_HELP}
|
|
|
99
125
|
process.stdout.write(`${MAIN_HELP}
|
|
100
126
|
`);
|
|
101
127
|
return 0;
|
|
102
|
-
case "version":
|
|
128
|
+
case "version": {
|
|
129
|
+
const update = startUpdateCheck();
|
|
103
130
|
process.stdout.write(`${versionText()}
|
|
104
131
|
`);
|
|
132
|
+
if (update) await noticeUpdate(update, 800);
|
|
105
133
|
return 0;
|
|
134
|
+
}
|
|
106
135
|
case "acp": {
|
|
107
136
|
if (command.args.length) {
|
|
108
137
|
process.stderr.write(`--acp takes no other arguments (got ${command.args.join(" ")}).
|
|
109
138
|
`);
|
|
110
139
|
return 2;
|
|
111
140
|
}
|
|
112
|
-
const { default: runAcp } = await import("
|
|
141
|
+
const { default: runAcp } = await import("@datalabrotterdam/nova-ai-agent/acp/index.js");
|
|
113
142
|
await runAcp();
|
|
114
143
|
return 0;
|
|
115
144
|
}
|
|
116
145
|
case "print": {
|
|
117
|
-
const
|
|
118
|
-
|
|
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;
|
|
119
151
|
}
|
|
120
152
|
case "login": {
|
|
121
|
-
const { runLogin } = await import("
|
|
122
|
-
|
|
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;
|
|
123
166
|
}
|
|
124
167
|
case "logout": {
|
|
125
|
-
const { runLogout } = await import("
|
|
168
|
+
const { runLogout } = await import("@datalabrotterdam/nova-ai-agent/commands/login.js");
|
|
126
169
|
return runLogout();
|
|
127
170
|
}
|
|
128
|
-
case "web": {
|
|
129
|
-
const { default: runWebUi } = await import("./webui-L4GGMXJ3.js");
|
|
130
|
-
await runWebUi();
|
|
131
|
-
return 0;
|
|
132
|
-
}
|
|
133
171
|
case "tui": {
|
|
134
172
|
let options;
|
|
135
173
|
try {
|
|
@@ -147,7 +185,7 @@ ${MAIN_HELP}
|
|
|
147
185
|
);
|
|
148
186
|
return 2;
|
|
149
187
|
}
|
|
150
|
-
const { default: runChat } = await import("./tui-
|
|
188
|
+
const { default: runChat } = await import("./tui-TJFV6NC6.js");
|
|
151
189
|
return runChat(options);
|
|
152
190
|
}
|
|
153
191
|
}
|