@datalabrotterdam/nova-ai-cli 1.2.0-alpha.1 → 1.2.0-alpha.2
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 +70 -0
- package/README.md +13 -23
- package/dist/{chunk-ZKRZIF3S.js → chunk-NHGIUEIR.js} +15 -215
- package/dist/chunk-SKAW2KXC.js +10 -0
- package/dist/{headless-ZYUSTZDL.js → headless-OFJFVJ3O.js} +9 -33
- package/dist/index.js +8 -8
- package/dist/{tui-XOKXPXN2.js → tui-NJWDD5X7.js} +40 -31
- package/package.json +22 -38
- 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/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
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# [@datalabrotterdam/nova-ai-cli-v1.2.0-alpha.2](https://github.com/Datalab-Rotterdam/nova-ai-cli/compare/@datalabrotterdam/nova-ai-cli@1.2.0-alpha.1...@datalabrotterdam/nova-ai-cli@1.2.0-alpha.2) (2026-10-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* release the agent separately as @datalabrotterdam/nova-ai-agent ([32ecfc0](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/32ecfc0faa99bd5bb80cb2eaf2363abc050978f0))
|
|
7
|
+
|
|
8
|
+
# [1.2.0-alpha.1](https://github.com/Datalab-Rotterdam/nova-ai-cli/compare/v1.1.0...v1.2.0-alpha.1) (2026-10-03)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **acp:** bounded, cancellable client terminals in the workspace ([81f7099](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/81f70996d9dfc8d78e12282def1582ea859f2784))
|
|
14
|
+
* **acp:** isolate background prompt jobs from live session history ([8328a8b](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/8328a8bfa1f22871ef36ec38247987e6effcd044))
|
|
15
|
+
* **acp:** replay loaded sessions faithfully; page session/list ([d576171](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/d5761710890f7b2f5d1b340cdce7faafcd2e3561))
|
|
16
|
+
* **env:** no shells or Docker probes when a session starts ([dc3a449](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/dc3a4495f394c1a16e48e282efd76b765af09999))
|
|
17
|
+
* **mcp:** connect servers in parallel with timeouts and diagnostics ([db4c62c](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/db4c62cd9c8ec0f197ea1ae1ce76adcf9d397ed5))
|
|
18
|
+
* **models:** offer and default to chat models only ([5d3ade2](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/5d3ade2727110ca7555bfdfa5b174c9e75b151f9))
|
|
19
|
+
* **security:** harden sessions, setup auth, credentials, processes and file access ([7f02a1d](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/7f02a1d203128555c4d00e5ab4dc4786329b6225))
|
|
20
|
+
* **tui:** keep printed lines inside the terminal width ([dd5cd0a](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/dd5cd0a40592af392eca797399ce56c0e672110e))
|
|
21
|
+
* **tui:** redraw cleanly after the terminal width changes ([f0b2ec6](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/f0b2ec6d01b0bd8ebcf087330c8bfd82072aa08d))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
* **acp:** agentInfo and env_var authentication in initialize ([b736e11](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/b736e115542b8fef083f9fc75514586327d3ac49))
|
|
27
|
+
* **acp:** namespace Nova extensions under _nova/ ([bf56cb9](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/bf56cb9e093dc90fc43b44008f1ddd86446a8cd0))
|
|
28
|
+
* **acp:** serialized turns, cancel, shutdown and proper error codes ([6688470](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/66884701af129ff2c1e9ad78b9e572d7ec64cc4b))
|
|
29
|
+
* **acp:** the agent owns permissions; clients only answer its questions ([7db651d](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/7db651d8d4883da2c170a831aeaa2952dc4444ac))
|
|
30
|
+
* **acp:** usage, session info, commands and model options as updates ([21d0816](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/21d08160c558ca9431deff8f8ead25e89a93d21c))
|
|
31
|
+
* added alpha stage on TUI ([3415411](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/3415411986ef4aefc2aa94dbb66fc73710fb6a5d))
|
|
32
|
+
* **cli:** proper entry point, -p/--print, login/logout, help and version ([73c8f94](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/73c8f9472099fa7c3cedccdd3c6a315d809e6a00))
|
|
33
|
+
* **core:** allow multiple tool calls per round ([f6a2171](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/f6a217145efac0722fddc49995808a7ad7bb2508))
|
|
34
|
+
* **core:** compact proactively at 80% of the model context window ([96afcbb](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/96afcbb7b68f4686a9b769bb80a73b00eebfe4a4))
|
|
35
|
+
* **core:** native tool calling with learned per-model text fallback ([6d71193](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/6d7119395b39a45026d676813ad3596382e2611a))
|
|
36
|
+
* **core:** share the ~/.nova-ai project layout with the VS Code extension ([aa75dde](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/aa75dde65218fdbd16b9f329bd849cc9ec608a28))
|
|
37
|
+
* **core:** validate tool args centrally before dispatch ([0a88e3e](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/0a88e3efb0d7c32611979e408b95e659873ec1e5))
|
|
38
|
+
* expand ACP runtime and terminal workflows ([bfbae15](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/bfbae157c301fbc1b7e88f5e267d25c8da126008))
|
|
39
|
+
* **mcp:** surface tool schemas, respect readOnlyHint, hint cwd args ([2b22be3](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/2b22be327b052788936e4badb010844f7ca3d057))
|
|
40
|
+
* **memory:** shared MEMORY.md index + typed notes, compatible with VS Code ([474c916](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/474c91694f4da58400426f39c290ac6888f4aa19))
|
|
41
|
+
* **modes:** plan mode can read, ask and keep the task list ([e253eaa](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/e253eaa66fd02478d61f34e734a27883068bf357))
|
|
42
|
+
* **policy:** agent-side permission policy with trust-gated rule sources ([234cd3a](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/234cd3adf06423c973c52497e5e31f6868d6b19a))
|
|
43
|
+
* **policy:** rule subjects for the extension's tool names ([5c188b6](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/5c188b610ff6e4ba8a715cc2ee10960736493b86))
|
|
44
|
+
* **tools:** add JSON schema validator for tool args ([24764ef](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/24764ef5100c14404f1923f89cc87c3d64de510d))
|
|
45
|
+
* **tools:** declare args schemas on every built-in tool ([79f6283](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/79f62833144f1a6aba9aaa65a2a19f18eb8793ca))
|
|
46
|
+
* **tools:** whitespace-tolerant edit_file with self-correction hints ([a350e14](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/a350e140e92c8469249d4c6297aad8f8161a217f))
|
|
47
|
+
* **tui:** Ink TUI with inline scrollback replaces pi-tui ([0725bae](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/0725bae27790829fd756afbdb5dd20574a1e0f00))
|
|
48
|
+
* **tui:** Shift+Enter inserts a new line where the terminal can report it ([b9c0b70](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/b9c0b7041057e2bdeb1675bbfa33a12fc3a664b9))
|
|
49
|
+
|
|
50
|
+
# [1.1.0](https://github.com/Datalab-Rotterdam/nova-ai-cli/compare/v1.0.1...v1.1.0) (2026-06-23)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Features
|
|
54
|
+
|
|
55
|
+
* **acp-web:** theme support, favicon, font, and dep bumps ([0576402](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/0576402b6888a2cf6bc93123d733c4163358c63f))
|
|
56
|
+
* **acp:** add MCP server support (stdio/http/sse) ([ba98b0c](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/ba98b0c0b2e2461e8553331cafa1985e7673ee43))
|
|
57
|
+
|
|
58
|
+
## [1.0.1](https://github.com/Datalab-Rotterdam/nova-ai-cli/compare/v1.0.0...v1.0.1) (2026-06-22)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Bug Fixes
|
|
62
|
+
|
|
63
|
+
* correct npm scope to [@datalabrotterdam](https://github.com/datalabrotterdam) ([6ab6bf8](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/6ab6bf88506cc1d4b778c1a30b123cd532a0a8de))
|
|
64
|
+
|
|
65
|
+
# 1.0.0 (2026-06-22)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Features
|
|
69
|
+
|
|
70
|
+
* add ACP agent, tool calling, and alpha release channel ([15d19a7](https://github.com/Datalab-Rotterdam/nova-ai-cli/commit/15d19a7998b4651ba9ad279fc2607006ea14ed49))
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="
|
|
3
|
+
<img src="https://raw.githubusercontent.com/Datalab-Rotterdam/nova-ai-cli/main/assets/logo.png" width="96" height="96" alt="Nova logo" />
|
|
4
4
|
|
|
5
5
|
# @datalabrotterdam/nova-ai-cli
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://agentclientprotocol.com)
|
|
13
13
|
[](https://github.com/Datalab-Rotterdam/nova-ai-cli/issues)
|
|
14
14
|
|
|
15
|
-
[npm](https://www.npmjs.com/package/@datalabrotterdam/nova-ai-cli) · [Issues](https://github.com/Datalab-Rotterdam/nova-ai-cli/issues) · [ACP reference](
|
|
15
|
+
[npm](https://www.npmjs.com/package/@datalabrotterdam/nova-ai-cli) · [Issues](https://github.com/Datalab-Rotterdam/nova-ai-cli/issues) · [ACP reference](https://github.com/Datalab-Rotterdam/nova-ai-cli/blob/main/docs/ACP.md) · [Settings and memory](https://github.com/Datalab-Rotterdam/nova-ai-cli/blob/main/docs/NOVA_HOME.md)
|
|
16
16
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
@@ -90,7 +90,7 @@ Slash commands: `/help`, `/model`, `/mode`, `/permission`, `/session`,
|
|
|
90
90
|
`/resume`, `/clear`, `/compact`, `/rewind [n]`, `/queue`, `/steer`, `/usage`,
|
|
91
91
|
`/tools`, `/mcp`, `/skills`, `/shell` and `/agent` (background jobs), `/trust`
|
|
92
92
|
and `/exit`. Details:
|
|
93
|
-
[`src/tui/README.md`](
|
|
93
|
+
[`src/tui/README.md`](https://github.com/Datalab-Rotterdam/nova-ai-cli/blob/main/packages/cli/src/tui/README.md).
|
|
94
94
|
|
|
95
95
|
## Headless
|
|
96
96
|
|
|
@@ -131,8 +131,12 @@ always options, client file system and terminals, form questions, plans, usage
|
|
|
131
131
|
and title updates, MCP servers (stdio, HTTP, SSE), image prompts, and three
|
|
132
132
|
login methods (browser, `NOVA_API_KEY`, or `nova-ai login` in a terminal).
|
|
133
133
|
Nova-specific features (prompt queue, rewind, compaction, context usage,
|
|
134
|
-
background jobs) are `_nova/…` extension methods.
|
|
135
|
-
|
|
134
|
+
background jobs) are `_nova/…` extension methods. The agent is also published
|
|
135
|
+
on its own as
|
|
136
|
+
[`@datalabrotterdam/nova-ai-agent`](https://www.npmjs.com/package/@datalabrotterdam/nova-ai-agent)
|
|
137
|
+
(command `nova-ai-agent`), without the terminal UI, for integrations that only
|
|
138
|
+
need ACP. Everything is documented in
|
|
139
|
+
[docs/ACP.md](https://github.com/Datalab-Rotterdam/nova-ai-cli/blob/main/docs/ACP.md).
|
|
136
140
|
|
|
137
141
|
## Security model
|
|
138
142
|
|
|
@@ -172,7 +176,7 @@ VS Code extension: settings, per-project trust, sessions and memory.
|
|
|
172
176
|
`.codex/skills`, in the workspace or your home folder.
|
|
173
177
|
- **MCP servers**: `.mcp.json` or `mcpServers` in `.nova-ai/settings.json`.
|
|
174
178
|
|
|
175
|
-
The complete layout and rule syntax: [docs/NOVA_HOME.md](
|
|
179
|
+
The complete layout and rule syntax: [docs/NOVA_HOME.md](https://github.com/Datalab-Rotterdam/nova-ai-cli/blob/main/docs/NOVA_HOME.md).
|
|
176
180
|
|
|
177
181
|
## Models
|
|
178
182
|
|
|
@@ -194,23 +198,9 @@ hand).
|
|
|
194
198
|
|
|
195
199
|
## Development
|
|
196
200
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
npm run build # the login page and the CLI bundle in dist/
|
|
201
|
-
npm run dev # run from source with tsx
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
Tests never touch your `~/.nova-ai` or the real Nova API: they run with a
|
|
205
|
-
throwaway home folder and point the client at a local port. The ACP
|
|
206
|
-
conformance test starts the real `--acp` process against a fake gateway. CI
|
|
207
|
-
runs the suite on Linux, macOS and Windows with Node 22 and 24 (the PTY
|
|
208
|
-
scenario on Linux and macOS). Releases are cut by `semantic-release` from
|
|
209
|
-
`main` and `alpha`.
|
|
210
|
-
|
|
211
|
-
Planned: OIDC login against the Nova platform instead of a pasted API key,
|
|
212
|
-
and Remote Control (driving a running session from the Nova web UI or mobile
|
|
213
|
-
app). The standalone browser UI (`--web`) is experimental.
|
|
201
|
+
This package lives in the [nova-ai-cli repository](https://github.com/Datalab-Rotterdam/nova-ai-cli)
|
|
202
|
+
next to the agent package it depends on; see the repository README for
|
|
203
|
+
building and testing.
|
|
214
204
|
|
|
215
205
|
## License
|
|
216
206
|
|
|
@@ -1,135 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
NOVA_METHODS,
|
|
3
|
-
NOVA_NOTIFICATIONS,
|
|
4
|
-
NovaAgent,
|
|
5
|
-
createAgentApp,
|
|
6
|
-
fromElicitationRequest,
|
|
7
|
-
isInteractionMode,
|
|
8
|
-
readSettings,
|
|
9
|
-
resolveWorkspaceFile,
|
|
10
|
-
toElicitationResponse
|
|
11
|
-
} from "./chunk-GZZ7PY3S.js";
|
|
12
|
-
import {
|
|
13
|
-
isWorkspaceTrusted
|
|
14
|
-
} from "./chunk-JAEXUFAS.js";
|
|
15
|
-
|
|
16
|
-
// src/client/in-process.ts
|
|
17
|
-
import * as acp from "@agentclientprotocol/sdk";
|
|
18
|
-
|
|
19
|
-
// src/client/nova-agent-client.ts
|
|
20
|
-
var NovaAgentClient = class {
|
|
21
|
-
constructor(connection) {
|
|
22
|
-
this.connection = connection;
|
|
23
|
-
}
|
|
24
|
-
connection;
|
|
25
|
-
initialize(params) {
|
|
26
|
-
return this.connection.initialize(params);
|
|
27
|
-
}
|
|
28
|
-
newSession(params) {
|
|
29
|
-
return this.connection.newSession(params);
|
|
30
|
-
}
|
|
31
|
-
loadSession(params) {
|
|
32
|
-
return this.connection.loadSession(params);
|
|
33
|
-
}
|
|
34
|
-
resumeSession(params) {
|
|
35
|
-
return this.connection.resumeSession(params);
|
|
36
|
-
}
|
|
37
|
-
closeSession(params) {
|
|
38
|
-
return this.connection.closeSession(params);
|
|
39
|
-
}
|
|
40
|
-
prompt(params) {
|
|
41
|
-
return this.connection.prompt(params);
|
|
42
|
-
}
|
|
43
|
-
cancel(params) {
|
|
44
|
-
return this.connection.cancel(params);
|
|
45
|
-
}
|
|
46
|
-
setSessionMode(params) {
|
|
47
|
-
return this.connection.setSessionMode(params);
|
|
48
|
-
}
|
|
49
|
-
setSessionConfigOption(params) {
|
|
50
|
-
return this.connection.setSessionConfigOption(params);
|
|
51
|
-
}
|
|
52
|
-
queueEnqueue(params) {
|
|
53
|
-
return this.ext(NOVA_METHODS.queueEnqueue, params);
|
|
54
|
-
}
|
|
55
|
-
queueList(params) {
|
|
56
|
-
return this.ext(NOVA_METHODS.queueList, params);
|
|
57
|
-
}
|
|
58
|
-
queueEditBegin(params) {
|
|
59
|
-
return this.ext(NOVA_METHODS.queueEditBegin, params);
|
|
60
|
-
}
|
|
61
|
-
queueUpdate(params) {
|
|
62
|
-
return this.ext(NOVA_METHODS.queueUpdate, params);
|
|
63
|
-
}
|
|
64
|
-
queueRemove(params) {
|
|
65
|
-
return this.ext(NOVA_METHODS.queueRemove, params);
|
|
66
|
-
}
|
|
67
|
-
queueClear(params) {
|
|
68
|
-
return this.ext(NOVA_METHODS.queueClear, params);
|
|
69
|
-
}
|
|
70
|
-
queueTakeNext(params) {
|
|
71
|
-
return this.ext(NOVA_METHODS.queueTakeNext, params);
|
|
72
|
-
}
|
|
73
|
-
sessionCompact(params) {
|
|
74
|
-
return this.ext(
|
|
75
|
-
NOVA_METHODS.sessionCompact,
|
|
76
|
-
params
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
sessionContextUsage(params) {
|
|
80
|
-
return this.ext(NOVA_METHODS.sessionContextUsage, params);
|
|
81
|
-
}
|
|
82
|
-
sessionRewind(params) {
|
|
83
|
-
return this.ext(NOVA_METHODS.sessionRewind, params);
|
|
84
|
-
}
|
|
85
|
-
backgroundStartTerminal(params) {
|
|
86
|
-
return this.ext(NOVA_METHODS.backgroundStartTerminal, params);
|
|
87
|
-
}
|
|
88
|
-
backgroundStartPrompt(params) {
|
|
89
|
-
return this.ext(NOVA_METHODS.backgroundStartPrompt, params);
|
|
90
|
-
}
|
|
91
|
-
backgroundList(params) {
|
|
92
|
-
return this.ext(NOVA_METHODS.backgroundList, params);
|
|
93
|
-
}
|
|
94
|
-
backgroundOutput(params) {
|
|
95
|
-
return this.ext(NOVA_METHODS.backgroundOutput, params);
|
|
96
|
-
}
|
|
97
|
-
backgroundKill(params) {
|
|
98
|
-
return this.ext(NOVA_METHODS.backgroundKill, params);
|
|
99
|
-
}
|
|
100
|
-
backgroundRelease(params) {
|
|
101
|
-
return this.ext(NOVA_METHODS.backgroundRelease, params);
|
|
102
|
-
}
|
|
103
|
-
async ext(method, params) {
|
|
104
|
-
return await this.connection.extMethod(method, params);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// src/client/in-process.ts
|
|
109
|
-
function startInProcessAgent(toClient, agent = new NovaAgent()) {
|
|
110
|
-
const toAgent = new TransformStream();
|
|
111
|
-
const toClientStream = new TransformStream();
|
|
112
|
-
const agentConnection = createAgentApp(agent).connect(
|
|
113
|
-
acp.ndJsonStream(toClientStream.writable, toAgent.readable)
|
|
114
|
-
);
|
|
115
|
-
const connection = new acp.ClientSideConnection(
|
|
116
|
-
toClient,
|
|
117
|
-
acp.ndJsonStream(toAgent.writable, toClientStream.readable)
|
|
118
|
-
);
|
|
119
|
-
return {
|
|
120
|
-
agent,
|
|
121
|
-
client: new NovaAgentClient(connection),
|
|
122
|
-
async close() {
|
|
123
|
-
await agent.shutdown().catch(() => {
|
|
124
|
-
});
|
|
125
|
-
agentConnection.close();
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
1
|
// src/tui/settings/workspace-mcp.ts
|
|
131
2
|
import { readFileSync as readFileSync2 } from "fs";
|
|
132
3
|
import { join as join2 } from "path";
|
|
4
|
+
import { isWorkspaceTrusted } from "@datalabrotterdam/nova-ai-agent/core/nova-home.js";
|
|
5
|
+
import { readSettings } from "@datalabrotterdam/nova-ai-agent/core/policy/settings.js";
|
|
133
6
|
|
|
134
7
|
// src/tui/settings/workspace-settings.ts
|
|
135
8
|
import { readFileSync } from "fs";
|
|
@@ -270,93 +143,21 @@ function errorMessage(error, fallback) {
|
|
|
270
143
|
}
|
|
271
144
|
|
|
272
145
|
// src/tui/session/tui-acp-client.ts
|
|
146
|
+
import { NOVA_NOTIFICATIONS } from "@datalabrotterdam/nova-ai-agent/acp/extensions.js";
|
|
273
147
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
274
148
|
import { dirname } from "path";
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
windowsHide: true,
|
|
288
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
289
|
-
};
|
|
290
|
-
const child = options.args?.length ? spawn(command, options.args, common) : spawn(command, { ...common, shell: true });
|
|
291
|
-
liveChildren.add(child);
|
|
292
|
-
const forget = () => liveChildren.delete(child);
|
|
293
|
-
child.once("exit", forget);
|
|
294
|
-
child.once("error", forget);
|
|
295
|
-
return child;
|
|
296
|
-
}
|
|
297
|
-
function killProcessTree(child, signal = "SIGTERM") {
|
|
298
|
-
if (child.pid === void 0) return;
|
|
299
|
-
try {
|
|
300
|
-
if (process.platform === "win32") {
|
|
301
|
-
spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
302
|
-
stdio: "ignore",
|
|
303
|
-
windowsHide: true
|
|
304
|
-
}).on("error", () => {
|
|
305
|
-
});
|
|
306
|
-
} else {
|
|
307
|
-
process.kill(-child.pid, signal);
|
|
308
|
-
}
|
|
309
|
-
} catch {
|
|
310
|
-
try {
|
|
311
|
-
child.kill(signal);
|
|
312
|
-
} catch {
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
function terminateProcessTree(child, graceMs = KILL_GRACE_MS) {
|
|
317
|
-
if (hasExited(child)) return Promise.resolve();
|
|
318
|
-
return new Promise((resolve) => {
|
|
319
|
-
let forceTimer;
|
|
320
|
-
let giveUpTimer;
|
|
321
|
-
const done = () => {
|
|
322
|
-
clearTimeout(forceTimer);
|
|
323
|
-
clearTimeout(giveUpTimer);
|
|
324
|
-
resolve();
|
|
325
|
-
};
|
|
326
|
-
child.once("exit", done);
|
|
327
|
-
killProcessTree(child, "SIGTERM");
|
|
328
|
-
forceTimer = setTimeout(() => {
|
|
329
|
-
killProcessTree(child, "SIGKILL");
|
|
330
|
-
giveUpTimer = setTimeout(done, graceMs);
|
|
331
|
-
}, graceMs);
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
function hasExited(child) {
|
|
335
|
-
return child.exitCode !== null || child.signalCode !== null;
|
|
336
|
-
}
|
|
337
|
-
function installExitHook() {
|
|
338
|
-
if (exitHookInstalled) return;
|
|
339
|
-
exitHookInstalled = true;
|
|
340
|
-
process.once("exit", () => {
|
|
341
|
-
for (const child of liveChildren) {
|
|
342
|
-
if (process.platform === "win32" && child.pid !== void 0) {
|
|
343
|
-
try {
|
|
344
|
-
spawnSync("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
345
|
-
stdio: "ignore",
|
|
346
|
-
windowsHide: true,
|
|
347
|
-
timeout: 2e3
|
|
348
|
-
});
|
|
349
|
-
} catch {
|
|
350
|
-
}
|
|
351
|
-
} else {
|
|
352
|
-
killProcessTree(child, "SIGKILL");
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
liveChildren.clear();
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// src/tui/session/tui-acp-client.ts
|
|
149
|
+
import {
|
|
150
|
+
spawnCommand,
|
|
151
|
+
terminateProcessTree
|
|
152
|
+
} from "@datalabrotterdam/nova-ai-agent/core/process-tree.js";
|
|
153
|
+
import { resolveWorkspaceFile } from "@datalabrotterdam/nova-ai-agent/core/tools/workspace-paths.js";
|
|
154
|
+
import {
|
|
155
|
+
isInteractionMode
|
|
156
|
+
} from "@datalabrotterdam/nova-ai-agent/core/interaction-modes.js";
|
|
157
|
+
import {
|
|
158
|
+
fromElicitationRequest,
|
|
159
|
+
toElicitationResponse
|
|
160
|
+
} from "@datalabrotterdam/nova-ai-agent/acp/user-questions.js";
|
|
360
161
|
var DEFAULT_OUTPUT_LIMIT = 1e5;
|
|
361
162
|
var nextMessageId = 0;
|
|
362
163
|
function uid() {
|
|
@@ -945,7 +746,6 @@ function createStore(initial) {
|
|
|
945
746
|
}
|
|
946
747
|
|
|
947
748
|
export {
|
|
948
|
-
startInProcessAgent,
|
|
949
749
|
readWorkspaceMcpConfiguration,
|
|
950
750
|
workspaceNeedsTrust,
|
|
951
751
|
TuiAcpClient,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/version.ts
|
|
2
|
+
import { readPackageVersion } from "@datalabrotterdam/nova-ai-agent/core/version.js";
|
|
3
|
+
var CLI_PACKAGE_NAME = "@datalabrotterdam/nova-ai-cli";
|
|
4
|
+
function cliVersion() {
|
|
5
|
+
return readPackageVersion(CLI_PACKAGE_NAME, import.meta.url);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
cliVersion
|
|
10
|
+
};
|
|
@@ -2,42 +2,18 @@ import {
|
|
|
2
2
|
TuiAcpClient,
|
|
3
3
|
choosePermissionOption,
|
|
4
4
|
createStore,
|
|
5
|
-
readWorkspaceMcpConfiguration
|
|
6
|
-
|
|
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";
|
|
5
|
+
readWorkspaceMcpConfiguration
|
|
6
|
+
} from "./chunk-NHGIUEIR.js";
|
|
18
7
|
|
|
19
8
|
// src/headless/index.ts
|
|
20
9
|
import { resolve } from "path";
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
// src/client/context-client.ts
|
|
10
|
+
import { NOVA_NOTIFICATIONS } from "@datalabrotterdam/nova-ai-agent/acp/extensions.js";
|
|
24
11
|
import * as acp from "@agentclientprotocol/sdk";
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
}
|
|
12
|
+
import { NovaAgent } from "@datalabrotterdam/nova-ai-agent/acp/agent.js";
|
|
13
|
+
import { clientFromContext } from "@datalabrotterdam/nova-ai-agent/client/context-client.js";
|
|
14
|
+
import { startInProcessAgent } from "@datalabrotterdam/nova-ai-agent/client/in-process.js";
|
|
15
|
+
import { setWorkspaceTrusted } from "@datalabrotterdam/nova-ai-agent/core/nova-home.js";
|
|
16
|
+
import { listStoredSessions, loadStoredSession } from "@datalabrotterdam/nova-ai-agent/core/sessions.js";
|
|
41
17
|
|
|
42
18
|
// src/headless/client.ts
|
|
43
19
|
var HeadlessAcpClient = class {
|
|
@@ -235,7 +211,7 @@ ${HEADLESS_HELP}
|
|
|
235
211
|
process.once("SIGINT", onInterrupt);
|
|
236
212
|
try {
|
|
237
213
|
await agent.initialize({
|
|
238
|
-
protocolVersion:
|
|
214
|
+
protocolVersion: acp.PROTOCOL_VERSION,
|
|
239
215
|
clientCapabilities: client.capabilities,
|
|
240
216
|
clientInfo: { name: "nova-ai-cli-headless", version: "1" }
|
|
241
217
|
});
|
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-SKAW2KXC.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
var SUBCOMMANDS = {
|
|
@@ -38,7 +38,7 @@ function parseCli(argv) {
|
|
|
38
38
|
return { mode, args: argv.filter((arg, index) => !(drop.has(arg) && (end < 0 || index < end))) };
|
|
39
39
|
}
|
|
40
40
|
function versionText() {
|
|
41
|
-
return `nova-ai ${
|
|
41
|
+
return `nova-ai ${cliVersion() ?? "unknown"}`;
|
|
42
42
|
}
|
|
43
43
|
var MAIN_HELP = `Nova AI \u2014 agentic coding in your terminal, and an ACP agent for editors.
|
|
44
44
|
|
|
@@ -109,20 +109,20 @@ ${MAIN_HELP}
|
|
|
109
109
|
`);
|
|
110
110
|
return 2;
|
|
111
111
|
}
|
|
112
|
-
const { default: runAcp } = await import("
|
|
112
|
+
const { default: runAcp } = await import("@datalabrotterdam/nova-ai-agent/acp/index.js");
|
|
113
113
|
await runAcp();
|
|
114
114
|
return 0;
|
|
115
115
|
}
|
|
116
116
|
case "print": {
|
|
117
|
-
const { default: runHeadless } = await import("./headless-
|
|
117
|
+
const { default: runHeadless } = await import("./headless-OFJFVJ3O.js");
|
|
118
118
|
return runHeadless(command.args);
|
|
119
119
|
}
|
|
120
120
|
case "login": {
|
|
121
|
-
const { runLogin } = await import("
|
|
121
|
+
const { runLogin } = await import("@datalabrotterdam/nova-ai-agent/commands/login.js");
|
|
122
122
|
return runLogin(command.args);
|
|
123
123
|
}
|
|
124
124
|
case "logout": {
|
|
125
|
-
const { runLogout } = await import("
|
|
125
|
+
const { runLogout } = await import("@datalabrotterdam/nova-ai-agent/commands/login.js");
|
|
126
126
|
return runLogout();
|
|
127
127
|
}
|
|
128
128
|
case "web": {
|
|
@@ -147,7 +147,7 @@ ${MAIN_HELP}
|
|
|
147
147
|
);
|
|
148
148
|
return 2;
|
|
149
149
|
}
|
|
150
|
-
const { default: runChat } = await import("./tui-
|
|
150
|
+
const { default: runChat } = await import("./tui-NJWDD5X7.js");
|
|
151
151
|
return runChat(options);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
@@ -1,48 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cliVersion
|
|
3
|
+
} from "./chunk-SKAW2KXC.js";
|
|
1
4
|
import {
|
|
2
5
|
TuiAcpClient,
|
|
3
6
|
createStore,
|
|
4
7
|
readWorkspaceMcpConfiguration,
|
|
5
|
-
startInProcessAgent,
|
|
6
8
|
workspaceNeedsTrust
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
INTERACTION_MODES,
|
|
10
|
-
NovaAgent,
|
|
11
|
-
OTHER_OPTION_ID,
|
|
12
|
-
discoverSkills,
|
|
13
|
-
isInteractionMode,
|
|
14
|
-
listStoredSessions,
|
|
15
|
-
loadStoredSession,
|
|
16
|
-
replayHistory,
|
|
17
|
-
resolveModelContextWindow,
|
|
18
|
-
savePermissionMode,
|
|
19
|
-
savedPermissionMode
|
|
20
|
-
} from "./chunk-GZZ7PY3S.js";
|
|
21
|
-
import {
|
|
22
|
-
readPackageVersion
|
|
23
|
-
} from "./chunk-Q7WL3DXP.js";
|
|
24
|
-
import {
|
|
25
|
-
chatModels,
|
|
26
|
-
createNovaClient,
|
|
27
|
-
readCredentials,
|
|
28
|
-
resolveDefaultModel,
|
|
29
|
-
resolveModelSupportsImageInput,
|
|
30
|
-
saveDefaultModel,
|
|
31
|
-
setWorkspaceTrusted
|
|
32
|
-
} from "./chunk-JAEXUFAS.js";
|
|
9
|
+
} from "./chunk-NHGIUEIR.js";
|
|
33
10
|
|
|
34
11
|
// src/tui/index.ts
|
|
35
12
|
import { createInterface } from "readline/promises";
|
|
13
|
+
import { readCredentials } from "@datalabrotterdam/nova-ai-agent/core/credentials.js";
|
|
14
|
+
import { listStoredSessions as listStoredSessions2 } from "@datalabrotterdam/nova-ai-agent/core/sessions.js";
|
|
15
|
+
import { setWorkspaceTrusted as setWorkspaceTrusted2 } from "@datalabrotterdam/nova-ai-agent/core/nova-home.js";
|
|
36
16
|
|
|
37
17
|
// src/tui/ink/app.tsx
|
|
38
18
|
import { Box as Box6, render, Static, Text as Text6, useBoxMetrics, useWindowSize } from "ink";
|
|
39
19
|
import { useEffect, useRef, useState as useState2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
20
|
+
import { savedPermissionMode } from "@datalabrotterdam/nova-ai-agent/core/policy/settings.js";
|
|
40
21
|
|
|
41
22
|
// src/tui/session/session-runner.ts
|
|
42
23
|
import * as acp from "@agentclientprotocol/sdk";
|
|
43
24
|
import {
|
|
44
25
|
NovaAIError
|
|
45
26
|
} from "@datalabrotterdam/nova-sdk";
|
|
27
|
+
import { createNovaClient } from "@datalabrotterdam/nova-ai-agent/core/nova-client.js";
|
|
28
|
+
import { NovaAgent } from "@datalabrotterdam/nova-ai-agent/acp/agent.js";
|
|
29
|
+
import { startInProcessAgent } from "@datalabrotterdam/nova-ai-agent/client/in-process.js";
|
|
30
|
+
import { replayHistory } from "@datalabrotterdam/nova-ai-agent/core/history.js";
|
|
31
|
+
import { saveDefaultModel } from "@datalabrotterdam/nova-ai-agent/core/credentials.js";
|
|
32
|
+
import {
|
|
33
|
+
savePermissionMode
|
|
34
|
+
} from "@datalabrotterdam/nova-ai-agent/core/policy/settings.js";
|
|
35
|
+
import { loadStoredSession } from "@datalabrotterdam/nova-ai-agent/core/sessions.js";
|
|
36
|
+
import { discoverSkills } from "@datalabrotterdam/nova-ai-agent/core/skills.js";
|
|
37
|
+
import {
|
|
38
|
+
resolveModelContextWindow
|
|
39
|
+
} from "@datalabrotterdam/nova-ai-agent/core/context-compaction.js";
|
|
40
|
+
import {
|
|
41
|
+
chatModels,
|
|
42
|
+
resolveDefaultModel,
|
|
43
|
+
resolveModelSupportsImageInput
|
|
44
|
+
} from "@datalabrotterdam/nova-ai-agent/core/model-capabilities.js";
|
|
46
45
|
|
|
47
46
|
// src/tui/files/file-mentions.ts
|
|
48
47
|
import { statSync } from "fs";
|
|
@@ -1040,7 +1039,7 @@ async function checkForUpdate(options = {}) {
|
|
|
1040
1039
|
}
|
|
1041
1040
|
}
|
|
1042
1041
|
function readInstalledVersion() {
|
|
1043
|
-
return
|
|
1042
|
+
return cliVersion();
|
|
1044
1043
|
}
|
|
1045
1044
|
function isNewerVersion(candidate, current) {
|
|
1046
1045
|
const next = parseVersion(candidate);
|
|
@@ -1807,7 +1806,12 @@ function PlanView({
|
|
|
1807
1806
|
] });
|
|
1808
1807
|
}
|
|
1809
1808
|
|
|
1809
|
+
// src/tui/ink/controller.ts
|
|
1810
|
+
import { setWorkspaceTrusted } from "@datalabrotterdam/nova-ai-agent/core/nova-home.js";
|
|
1811
|
+
import { INTERACTION_MODES } from "@datalabrotterdam/nova-ai-agent/core/interaction-modes.js";
|
|
1812
|
+
|
|
1810
1813
|
// src/tui/commands/builtins.ts
|
|
1814
|
+
import { isInteractionMode } from "@datalabrotterdam/nova-ai-agent/core/interaction-modes.js";
|
|
1811
1815
|
var permissionModes = ["ask", "acceptEdits", "bypassAll"];
|
|
1812
1816
|
var builtinCommands = [
|
|
1813
1817
|
{
|
|
@@ -2561,6 +2565,7 @@ function walkWithFd(cwd, fdPath, query, signal) {
|
|
|
2561
2565
|
}
|
|
2562
2566
|
|
|
2563
2567
|
// src/tui/session/session-picker.ts
|
|
2568
|
+
import { listStoredSessions } from "@datalabrotterdam/nova-ai-agent/core/sessions.js";
|
|
2564
2569
|
function listSessionsForCwd(cwd) {
|
|
2565
2570
|
return listStoredSessions(cwd);
|
|
2566
2571
|
}
|
|
@@ -2609,6 +2614,9 @@ function formatDateTime(updatedAt) {
|
|
|
2609
2614
|
return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : "unknown";
|
|
2610
2615
|
}
|
|
2611
2616
|
|
|
2617
|
+
// src/tui/ink/dialogs/state.ts
|
|
2618
|
+
import { OTHER_OPTION_ID } from "@datalabrotterdam/nova-ai-agent/core/user-questions.js";
|
|
2619
|
+
|
|
2612
2620
|
// src/tui/ink/editor/buffer.ts
|
|
2613
2621
|
var segmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2614
2622
|
function boundaries(text) {
|
|
@@ -4308,6 +4316,7 @@ function errorMessage(error, fallback) {
|
|
|
4308
4316
|
import { Box as Box5, Text as Text5, useInput as useInput2, usePaste as usePaste2 } from "ink";
|
|
4309
4317
|
import stringWidth2 from "string-width";
|
|
4310
4318
|
import { useMemo, useState } from "react";
|
|
4319
|
+
import { OTHER_OPTION_ID as OTHER_OPTION_ID2 } from "@datalabrotterdam/nova-ai-agent/core/user-questions.js";
|
|
4311
4320
|
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4312
4321
|
function useDialogInput(handle, isActive) {
|
|
4313
4322
|
const [, setTick] = useState(0);
|
|
@@ -4520,7 +4529,7 @@ function QuestionDialog({
|
|
|
4520
4529
|
/* @__PURE__ */ jsxs5(Text5, { wrap: "truncate-end", children: [
|
|
4521
4530
|
/* @__PURE__ */ jsx5(Text5, { color: palette.primary, children: state.selected === otherIndex ? ">" : " " }),
|
|
4522
4531
|
" ",
|
|
4523
|
-
state.isSelected(question.id,
|
|
4532
|
+
state.isSelected(question.id, OTHER_OPTION_ID2) ? /* @__PURE__ */ jsx5(Text5, { color: palette.success, children: "[x]" }) : "[ ]",
|
|
4524
4533
|
" ",
|
|
4525
4534
|
otherAnswer ? `Other: ${otherAnswer}` : "Other... (write your own answer)"
|
|
4526
4535
|
] }),
|
|
@@ -4766,7 +4775,7 @@ async function runChat(options) {
|
|
|
4766
4775
|
const cwd = process.cwd();
|
|
4767
4776
|
let resume = options.resume;
|
|
4768
4777
|
if (options.continueLast) {
|
|
4769
|
-
resume =
|
|
4778
|
+
resume = listStoredSessions2(cwd)[0]?.sessionId ?? null;
|
|
4770
4779
|
if (!resume) {
|
|
4771
4780
|
console.error(`No earlier session in ${cwd} to continue.`);
|
|
4772
4781
|
return 1;
|
|
@@ -4786,7 +4795,7 @@ ${cwd}`);
|
|
|
4786
4795
|
console.log("Trusting it starts those servers and applies those rules. Only trust code you know.");
|
|
4787
4796
|
const answer = (await prompt.question("Trust this workspace? [y/N] ")).trim().toLowerCase();
|
|
4788
4797
|
if (answer === "y" || answer === "yes") {
|
|
4789
|
-
|
|
4798
|
+
setWorkspaceTrusted2(cwd, true);
|
|
4790
4799
|
} else {
|
|
4791
4800
|
console.log("Not trusted: its MCP servers stay off and its allow rules are ignored. Use /trust later to change this.");
|
|
4792
4801
|
}
|