@asathinkeroops/nova-code 0.1.0-beta.5 → 0.1.0-beta.6
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 +10 -4
- package/dist/index.js +46 -5
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
<img src="https://static-1453154645.cos.ap-guangzhou.myqcloud.com/logo.svg" alt="NOVA-CODE" width="600">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
+
<p align="center">
|
|
6
|
+
<b>为 DeepSeek 量身打造的编程代理 — 95%+ 缓存命中 · OS 级沙箱 · 工具齐全 · 开箱即用</b>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
5
9
|

|
|
6
10
|
|
|
7
11
|
> 为 DeepSeek 量身打造的编程代理 — 95%+ 缓存命中 · OS 级沙箱 · 工具齐全 · 开箱即用。
|
|
8
12
|
|
|
9
|
-
Nova 读代码、跑命令、改文件——通过工具调用把任务推到完成。模型层围绕 **DeepSeek** 构建:thinking 映射到 effort(而非 `budget_tokens
|
|
13
|
+
Nova 读代码、跑命令、改文件——通过工具调用把任务推到完成。模型层围绕 **DeepSeek** 构建:thinking 映射到 effort(而非 `budget_tokens`)、错误码翻译成人话、余额与定价内建,整个请求管线为 DeepSeek 的自动上下文缓存做了调优,让缓存持续命中。各家 provider 都走 Anthropic 兼容协议,差异(thinking 形状、错误码、余额探针)由 provider profile(按 `settings.provider` 选择)吸收——DeepSeek 是第一优先级,Kimi(Moonshot)有专用适配(beta),其余端点走通用 `other` 档。
|
|
10
14
|
|
|
11
15
|
## 为什么选 Nova
|
|
12
16
|
|
|
@@ -36,7 +40,9 @@ nova -p "解释这段代码" # headless 模式:只跑一轮,输
|
|
|
36
40
|
nova upgrade # 更新到最新版本(启动时也会自动检查并提示)
|
|
37
41
|
```
|
|
38
42
|
|
|
39
|
-
首次启动进入交互式配置向导,写入 `~/.nova/nova.config.json`(API key、模型、session 目录等)。模型按 `lite` / `pro` / `max`
|
|
43
|
+
首次启动进入交互式配置向导,写入 `~/.nova/nova.config.json`(API key、模型、session 目录等)。模型按 `lite` / `pro` / `max` 三档配置,每档可单独设定 thinking 等级与定价(`models.<档>.pricing`,支持 USD / CNY);`/model`、`--model` 切换的是档位而非裸 provider id。默认 provider 为 `deepseek`,`settings.provider` 可切到 `moonshot`(Kimi,beta)或通用 `other`。
|
|
44
|
+
|
|
45
|
+
`nova` 还带子命令:`nova doctor`(体检全局配置)、`nova mcp`(管理 MCP 服务器)、`nova plugin`(安装 / 启停插件)、`nova upgrade`(升级 CLI)。
|
|
40
46
|
|
|
41
47
|
## 功能概览
|
|
42
48
|
|
|
@@ -69,7 +75,7 @@ nova upgrade # 更新到最新版本(启动时也会自
|
|
|
69
75
|
| `/rename` | 给当前会话起个名字(显示在输入框边框上) |
|
|
70
76
|
| `/plan` | 只读调研出实现方案,不动手 |
|
|
71
77
|
| `/goal` | 设定成功条件后自动推进直到达成 |
|
|
72
|
-
| `/diff` · `/review` |
|
|
78
|
+
| `/diff` · `/review` | 浏览、评审未提交改动;`/review <PR#\|#PR\|github-pr-url>` 经 `gh` 只读评审指定 GitHub PR |
|
|
73
79
|
| `/init` | 分析代码库生成 `NOVA.md` |
|
|
74
80
|
| `/agents` · `/agent` | 查看子 agent 类型、委派任务 |
|
|
75
81
|
| `/nova-code-guide` · `/nova-code-guide-update` | 就 Nova 自身答疑的只读 Q&A agent;后者拉取最新源码 |
|
|
@@ -94,7 +100,7 @@ nova upgrade # 更新到最新版本(启动时也会自
|
|
|
94
100
|
| Markdown 扩展 | 自定义 slash 命令、子 agent、生命周期 hooks,丢 `.md` 进 `.nova/`、frontmatter 配置,免改代码 |
|
|
95
101
|
| 插件 | `nova plugin` 从本地路径 / GitHub / git url / marketplace 安装、启停插件;一个插件可贡献命令、agent、skill、hooks、MCP / LSP server 与 `bin/` 可执行文件,兼容 Claude Code 插件格式 |
|
|
96
102
|
| 三层记忆 | 全局 → 用户 → 项目,按 `NOVA.md` > `CLAUDE.md` > `AGENTS.md` 优先级加载 |
|
|
97
|
-
| 交互体验 | 全屏 Ink/React REPL,流式输出 + 鼠标;`@path` / `/` 补全、`↑` `↓` 翻历史;实时状态行显示 token 用量、缓存命中、花费、DeepSeek
|
|
103
|
+
| 交互体验 | 全屏 Ink/React REPL,流式输出 + 鼠标;`@path` / `/` 补全、`↑` `↓` 翻历史;实时状态行显示 token 用量、缓存命中、花费、provider 余额(DeepSeek / Kimi)、git 分支、上下文占用 |
|
|
98
104
|
|
|
99
105
|
## 架构
|
|
100
106
|
|
package/dist/index.js
CHANGED
|
@@ -1220,8 +1220,10 @@ var DEFAULT_SANDBOX_ALLOW_WRITE = [
|
|
|
1220
1220
|
// pnpm store/bin (Linux)
|
|
1221
1221
|
"~/Library/pnpm",
|
|
1222
1222
|
// pnpm store/bin (macOS)
|
|
1223
|
-
"~/.yarn"
|
|
1223
|
+
"~/.yarn",
|
|
1224
1224
|
// yarn global
|
|
1225
|
+
"~/.config/gh"
|
|
1226
|
+
// gh CLI auth/token refresh (git/PR workflow)
|
|
1225
1227
|
];
|
|
1226
1228
|
var modelPricingSchema = z2.object({
|
|
1227
1229
|
input: z2.number().nonnegative().describe("Price per 1M uncached (cache-miss) input tokens."),
|
|
@@ -2424,6 +2426,11 @@ When I ask you to commit, follow the repo's own version-control conventions:
|
|
|
2424
2426
|
- Default to Conventional Commits (\`type(scope): summary\` \u2014 imperative subject \u226472 chars, a short body explaining the *why* when the change is non-trivial), but defer to the repo's own convention where it differs.
|
|
2425
2427
|
- Never push, and never add co-author or tool-attribution trailers, unless I ask.
|
|
2426
2428
|
|
|
2429
|
+
When I ask you to open a pull request, use the \`gh\` CLI (it is already authenticated \u2014 don't build a GitHub API client):
|
|
2430
|
+
- Gather context first: \`git status\` / \`git diff\`, \`git log <base>..HEAD\` for the commits, and the default branch (\`gh repo view --json defaultBranchRef\`) for the PR base.
|
|
2431
|
+
- Push the branch if it has no upstream (never straight to main/master), then run \`gh pr create\`. Pass the body via a quoted HEREDOC so its markdown survives: \`gh pr create --title "\u2026" --body "$(cat <<'EOF' \u2026 EOF)"\`.
|
|
2432
|
+
- Structure the body as \`## Summary\` (1\u20133 bullets on what changed and why) and \`## Test plan\` (a checklist of how to verify) \u2014 keep it to what the diff actually supports.
|
|
2433
|
+
|
|
2427
2434
|
Act, don't explain.
|
|
2428
2435
|
|
|
2429
2436
|
<identity name="Nova"></identity>
|
|
@@ -9238,6 +9245,9 @@ var DENY_RULES = [
|
|
|
9238
9245
|
{ re: /\bgit\s+clean\s+-[a-z]*f/i, reason: "git clean -f (deletes untracked files)" },
|
|
9239
9246
|
{ re: /\bgit\s+stash\s+(?:drop|clear)\b/i, reason: "git stash drop/clear (loses stashed work)" },
|
|
9240
9247
|
{ re: /\bgit\s+commit\b[^|&;]*--amend\b/i, reason: "git commit --amend (rewrites history)" },
|
|
9248
|
+
// Irreversible GitHub (gh) operations — merging or deleting.
|
|
9249
|
+
{ re: /\bgh\s+pr\s+merge\b/i, reason: "gh pr merge (merges a pull request)" },
|
|
9250
|
+
{ re: /\bgh\s+repo\s+delete\b/i, reason: "gh repo delete" },
|
|
9241
9251
|
// Infrastructure-as-code teardown.
|
|
9242
9252
|
{ re: /\b(?:terraform|terragrunt|pulumi|cdk|cdktf)\s+destroy\b/i, reason: "infrastructure destroy" },
|
|
9243
9253
|
// Mass cloud deletion.
|
|
@@ -9298,6 +9308,18 @@ var READ_ONLY_GIT_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
9298
9308
|
"tag",
|
|
9299
9309
|
"config"
|
|
9300
9310
|
]);
|
|
9311
|
+
var READ_ONLY_GH_SIGNATURES = /* @__PURE__ */ new Set([
|
|
9312
|
+
"pr view",
|
|
9313
|
+
"pr diff",
|
|
9314
|
+
"pr list",
|
|
9315
|
+
"pr checks",
|
|
9316
|
+
"pr status",
|
|
9317
|
+
"issue view",
|
|
9318
|
+
"issue list",
|
|
9319
|
+
"repo view",
|
|
9320
|
+
"run view",
|
|
9321
|
+
"run list"
|
|
9322
|
+
]);
|
|
9301
9323
|
var COMPOUND_RE = /[|&;<>`]|\$\(|\bxargs\b|\beval\b|\bexec\b/;
|
|
9302
9324
|
function effectiveTokens(command) {
|
|
9303
9325
|
const tokens = command.trim().split(/\s+/);
|
|
@@ -9316,9 +9338,10 @@ function classifyCommandStatic(command) {
|
|
|
9316
9338
|
if (re.test(cmd)) return "deny";
|
|
9317
9339
|
}
|
|
9318
9340
|
if (!COMPOUND_RE.test(cmd)) {
|
|
9319
|
-
const [verb, sub] = effectiveTokens(cmd);
|
|
9341
|
+
const [verb, sub, action] = effectiveTokens(cmd);
|
|
9320
9342
|
if (verb && READ_ONLY_COMMANDS.has(verb)) return "allow";
|
|
9321
9343
|
if (verb === "git" && sub && READ_ONLY_GIT_SUBCOMMANDS.has(sub)) return "allow";
|
|
9344
|
+
if (verb === "gh" && sub && action && READ_ONLY_GH_SIGNATURES.has(`${sub} ${action}`)) return "allow";
|
|
9322
9345
|
}
|
|
9323
9346
|
return "unknown";
|
|
9324
9347
|
}
|
|
@@ -18323,8 +18346,17 @@ async function handleResume(ctx, arg) {
|
|
|
18323
18346
|
}
|
|
18324
18347
|
|
|
18325
18348
|
// src/commands/review.ts
|
|
18349
|
+
var DEFAULT_FOCUS = "correctness and regressions in adjacent code";
|
|
18350
|
+
var PR_REF_RE = /^(?:#?(\d+)|https?:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/(\d+))\b\s*/;
|
|
18326
18351
|
function handleReview(args) {
|
|
18327
|
-
const
|
|
18352
|
+
const trimmed = args.trim();
|
|
18353
|
+
const pr = trimmed.match(PR_REF_RE);
|
|
18354
|
+
if (pr) {
|
|
18355
|
+
const number = pr[1] ?? pr[2] ?? "";
|
|
18356
|
+
const focus2 = trimmed.slice(pr[0].length).trim() || DEFAULT_FOCUS;
|
|
18357
|
+
return { kind: "prompt", text: prReviewText(number, focus2) };
|
|
18358
|
+
}
|
|
18359
|
+
const focus = trimmed || DEFAULT_FOCUS;
|
|
18328
18360
|
const text = `Review the repository's uncommitted changes. Do NOT edit anything \u2014 this is a review only.
|
|
18329
18361
|
|
|
18330
18362
|
1. Run \`git status\` and \`git diff\` (include \`git diff --staged\`) to see every pending change.
|
|
@@ -18334,6 +18366,15 @@ function handleReview(args) {
|
|
|
18334
18366
|
Write your review in the same language and script as this request.`;
|
|
18335
18367
|
return { kind: "prompt", text };
|
|
18336
18368
|
}
|
|
18369
|
+
function prReviewText(pr, focus) {
|
|
18370
|
+
return `Review GitHub pull request #${pr}. Do NOT edit anything and do NOT post any comment to GitHub \u2014 this is a read-only review.
|
|
18371
|
+
|
|
18372
|
+
1. Fetch it with \`gh pr view ${pr}\` (title, description, checks) and \`gh pr diff ${pr}\` (the full diff). If \`gh\` is missing or not authenticated, say so and stop.
|
|
18373
|
+
2. Review the diff with a focus on ${focus}. Flag anything risky, surprising, broken, or inconsistent with the surrounding code and conventions. Note missing tests or edge cases where they matter.
|
|
18374
|
+
3. Be concrete \u2014 reference file paths and line numbers, group findings by severity, and skip praise and restating the obvious. If the diff looks clean, say so plainly.
|
|
18375
|
+
|
|
18376
|
+
Write your review in the same language and script as this request.`;
|
|
18377
|
+
}
|
|
18337
18378
|
|
|
18338
18379
|
// src/commands/rewind.ts
|
|
18339
18380
|
import { relative as relative4 } from "path";
|
|
@@ -18936,8 +18977,8 @@ function registerBuiltinSlashCommands(ctx) {
|
|
|
18936
18977
|
});
|
|
18937
18978
|
ctx.registry.register({
|
|
18938
18979
|
name: "review",
|
|
18939
|
-
description: "review the
|
|
18940
|
-
argHint: "[focus\u2026]",
|
|
18980
|
+
description: "review the uncommitted diff, or a GitHub PR by number (read-only)",
|
|
18981
|
+
argHint: "[PR# | focus\u2026]",
|
|
18941
18982
|
source: { kind: "builtin" },
|
|
18942
18983
|
run: (_c, args) => handleReview(args)
|
|
18943
18984
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asathinkeroops/nova-code",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.6",
|
|
4
4
|
"description": "A terminal coding agent, deeply tuned for DeepSeek.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@anthropic-ai/sandbox-runtime": "0.0.52",
|
|
39
|
-
"@anthropic-ai/sdk": "^0.
|
|
39
|
+
"@anthropic-ai/sdk": "^0.111.0",
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
41
|
"@vscode/ripgrep": "^1.18.0",
|
|
42
42
|
"cli-highlight": "^2.1.11",
|
|
@@ -59,21 +59,22 @@
|
|
|
59
59
|
"@types/react": "^18.3.0",
|
|
60
60
|
"tsup": "^8.0.2",
|
|
61
61
|
"tsx": "^4.7.2",
|
|
62
|
-
"@nova/core": "0.1.0",
|
|
63
62
|
"@nova/context": "0.1.0",
|
|
64
63
|
"@nova/agent": "0.1.0",
|
|
64
|
+
"@nova/core": "0.1.0",
|
|
65
65
|
"@nova/external": "0.1.0",
|
|
66
|
-
"@nova/lsp": "0.1.0",
|
|
67
66
|
"@nova/observability": "0.1.0",
|
|
68
|
-
"@nova/sandbox": "0.1.0",
|
|
69
67
|
"@nova/runtime": "0.1.0",
|
|
70
|
-
"@nova/
|
|
68
|
+
"@nova/sandbox": "0.1.0",
|
|
71
69
|
"@nova/subagent": "0.1.0",
|
|
72
|
-
"@nova/safety": "0.1.0"
|
|
70
|
+
"@nova/safety": "0.1.0",
|
|
71
|
+
"@nova/tools": "0.1.0",
|
|
72
|
+
"@nova/lsp": "0.1.0"
|
|
73
73
|
},
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build": "tsup",
|
|
76
76
|
"dev": "tsx src/index.ts",
|
|
77
|
+
"prepub": "pnpm publish --access public --tag beta --no-git-checks --registry=https://registry.npmjs.org/ && npm dist-tag add $npm_package_name@$npm_package_version latest --registry=https://registry.npmjs.org/",
|
|
77
78
|
"typecheck": "tsc --noEmit"
|
|
78
79
|
}
|
|
79
80
|
}
|