@bivy/bivy 0.16.8 → 0.16.9-staging.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.
- package/bin/agent-manifest.json +1 -1
- package/bin/bivy.mjs +8 -2
- package/bin/install-kind.mjs +20 -0
- package/dist/agents/claude-code/integration.js +1 -1
- package/dist/agents/codex/integration.js +1 -1
- package/dist/agents/profiles.js +1 -1
- package/dist/certification/generated.js +3 -3
- package/dist/runtime/bivy-provider-catalog.js +2 -0
- package/dist/runtime/tool-call-map.js +21 -8
- package/dist/server.js +6 -1
- package/package.json +3 -2
package/bin/agent-manifest.json
CHANGED
package/bin/bivy.mjs
CHANGED
|
@@ -41,7 +41,7 @@ import { renderManagedBlock, upsertManagedBlock, removeManagedBlock, rcFileForSh
|
|
|
41
41
|
import { removeInstallAndState } from "./uninstall-paths.mjs";
|
|
42
42
|
import { findAvailablePort, reconcilePort } from "./port-picker.mjs";
|
|
43
43
|
import { resolveAttachSessionId } from "./attach-session-id.mjs";
|
|
44
|
-
import { detectInstallKind as classifyInstallKind } from "./install-kind.mjs";
|
|
44
|
+
import { detectInstallKind as classifyInstallKind, npmGlobalPrefix } from "./install-kind.mjs";
|
|
45
45
|
import { hasConfiguredService as configuredServiceExists } from "./service-state.mjs";
|
|
46
46
|
|
|
47
47
|
const selfScript = fileURLToPath(import.meta.url);
|
|
@@ -4447,7 +4447,13 @@ async function runUpdate(args = []) {
|
|
|
4447
4447
|
|
|
4448
4448
|
if (kind === "npm-global") {
|
|
4449
4449
|
console.log(c.dim(`Updating the globally-installed bivy package (channel: ${channel})…`));
|
|
4450
|
-
|
|
4450
|
+
// npm's configured global prefix may not be the prefix that owns this
|
|
4451
|
+
// executable (for example, `npm config get prefix` can remain /usr after
|
|
4452
|
+
// installing Bivy with --prefix ~/.local). Always update the installation
|
|
4453
|
+
// that is actually running this command.
|
|
4454
|
+
const prefix = npmGlobalPrefix(repoRoot);
|
|
4455
|
+
const prefixArgs = prefix ? ["--prefix", prefix] : [];
|
|
4456
|
+
const code = await run("npm", ["install", "-g", ...prefixArgs, `@bivy/bivy@${channel}`, "--no-audit", "--no-fund"]);
|
|
4451
4457
|
if (code !== 0) {
|
|
4452
4458
|
console.log(c.yellow(`npm reported an issue (exit ${code}). Try: sudo npm i -g @bivy/bivy@${channel}`));
|
|
4453
4459
|
process.exit(code);
|
package/bin/install-kind.mjs
CHANGED
|
@@ -18,3 +18,23 @@ export function detectInstallKind(repoRoot, existsSync = fs.existsSync) {
|
|
|
18
18
|
if (inNodeModules) return "npm-global";
|
|
19
19
|
return "packaged";
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Return the npm prefix that owns a package installed below node_modules.
|
|
24
|
+
* npm uses <prefix>/lib/node_modules on Unix and <prefix>/node_modules on
|
|
25
|
+
* other platforms. The running npm process may have a different configured
|
|
26
|
+
* prefix, so deriving it from the package path is important for user-local
|
|
27
|
+
* installs.
|
|
28
|
+
*/
|
|
29
|
+
export function npmGlobalPrefix(repoRoot) {
|
|
30
|
+
let current = path.resolve(repoRoot);
|
|
31
|
+
while (true) {
|
|
32
|
+
if (path.basename(current) === "node_modules") {
|
|
33
|
+
const parent = path.dirname(current);
|
|
34
|
+
return path.basename(parent) === "lib" ? path.dirname(parent) : parent;
|
|
35
|
+
}
|
|
36
|
+
const parent = path.dirname(current);
|
|
37
|
+
if (parent === current) return undefined;
|
|
38
|
+
current = parent;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -4,7 +4,7 @@ import { defineAgentIntegration } from "../definition.js";
|
|
|
4
4
|
import { withExactCapabilitySurface } from "../../runtime/types.js";
|
|
5
5
|
import { createCredentialStore } from "../../runtime/credentials.js";
|
|
6
6
|
import { ClaudeCodeRuntime, claudeRuntimeFromEnv, claudeSdkInstalled, } from "./runtime.js";
|
|
7
|
-
export const CLAUDE_TESTED_VERSION = "0.3.
|
|
7
|
+
export const CLAUDE_TESTED_VERSION = "0.3.258";
|
|
8
8
|
const CLAUDE_CAPABILITIES = withExactCapabilitySurface({
|
|
9
9
|
toolInterception: true,
|
|
10
10
|
modelSelection: true,
|
|
@@ -9,7 +9,7 @@ import { codexCredentialPreflight } from "../../runtime/codex-preflight.js";
|
|
|
9
9
|
import { deleteCodexSession, discoverNativeCodexSessions, loadCodexTranscript, writeCodexRollout, exportCodexRollout, importCodexRollout, } from "../../runtime/codex-sessions.js";
|
|
10
10
|
import { ProtocolRuntime } from "../../runtime/protocol.js";
|
|
11
11
|
import { codexSlashCommands } from "../../runtime/slash-commands.js";
|
|
12
|
-
export const CODEX_TESTED_VERSION = "0.
|
|
12
|
+
export const CODEX_TESTED_VERSION = "0.152.1";
|
|
13
13
|
const CODEX_AVAILABLE_CACHE = new Map();
|
|
14
14
|
function codexCommand() {
|
|
15
15
|
return process.env.BIVY_CODEX_BIN?.trim() || "codex";
|
package/dist/agents/profiles.js
CHANGED
|
@@ -43,7 +43,7 @@ export const AGENT_PROFILES = {
|
|
|
43
43
|
// Approve/Deny + session/load resume + a real model picker), the same bar Pi,
|
|
44
44
|
// Claude Code, and Codex clear. See `acp` below for the version fallback.
|
|
45
45
|
supportTier: "supported",
|
|
46
|
-
testedVersion: "1.18.
|
|
46
|
+
testedVersion: "1.18.27",
|
|
47
47
|
blurb: "The most widely used open-source coding harness (OpenCode CLI).",
|
|
48
48
|
// `opencode run -s <id> "<prompt>"` continues a prior session by its own id
|
|
49
49
|
// (`-s, --session session id to continue`, per `opencode run --help`).
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
export const CERTIFICATION_MATRIX = {
|
|
4
4
|
schemaVersion: 1,
|
|
5
5
|
agents: [
|
|
6
|
-
{ id: "claude-code-sdk", status: "active", executionMode: "protocol", pinnedVersion: "0.3.
|
|
7
|
-
{ id: "codex-approvals", status: "active", executionMode: "protocol", pinnedVersion: "0.
|
|
6
|
+
{ id: "claude-code-sdk", status: "active", executionMode: "protocol", pinnedVersion: "0.3.258", capabilities: ["toolInterception", "modelSelection", "resume"] },
|
|
7
|
+
{ id: "codex-approvals", status: "active", executionMode: "protocol", pinnedVersion: "0.152.1", capabilities: ["toolInterception", "modelSelection", "resume"] },
|
|
8
8
|
{ id: "pi", status: "active", executionMode: "protocol", pinnedVersion: "0.84.4", capabilities: ["toolInterception", "modelSelection", "resume"] },
|
|
9
|
-
{ id: "opencode", status: "active", executionMode: "protocol", pinnedVersion: "1.18.
|
|
9
|
+
{ id: "opencode", status: "active", executionMode: "protocol", pinnedVersion: "1.18.27", capabilities: ["toolInterception", "modelSelection", "resume"] },
|
|
10
10
|
]
|
|
11
11
|
};
|
|
@@ -16,6 +16,7 @@ const reference = { kind: "reference", label: "Password manager or environment"
|
|
|
16
16
|
/** Authoritative common providers and the offline baseline models Bivy ships. */
|
|
17
17
|
export const BIVY_PROVIDER_CATALOG = [
|
|
18
18
|
{ id: "anthropic", name: "Anthropic", authMethods: [oauth("Claude Pro / Max", "anthropic"), apiKey("Anthropic API key", "https://console.anthropic.com/settings/keys"), reference], env: ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN"], compatibility: "anthropic", helpUrl: "https://docs.anthropic.com/", models: [
|
|
19
|
+
{ id: "claude-opus-4-8", name: "Claude Opus 4.8", reasoning: true },
|
|
19
20
|
{ id: "claude-opus-4-1", name: "Claude Opus 4.1", reasoning: true },
|
|
20
21
|
{ id: "claude-sonnet-4-5", name: "Claude Sonnet 4.5", reasoning: true },
|
|
21
22
|
{ id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5" },
|
|
@@ -26,6 +27,7 @@ export const BIVY_PROVIDER_CATALOG = [
|
|
|
26
27
|
{ id: "gpt-4o", name: "GPT-4o" },
|
|
27
28
|
] },
|
|
28
29
|
{ id: "openai-codex", name: "OpenAI — ChatGPT subscription", aliases: ["codex"], authMethods: [oauth("ChatGPT Plus / Pro", "openai-codex")], compatibility: "openai", models: [
|
|
30
|
+
{ id: "gpt-5.6-sol", name: "GPT-5.6 Sol", reasoning: true },
|
|
29
31
|
{ id: "gpt-5.3-codex-spark", name: "GPT-5.3 Codex Spark", reasoning: true },
|
|
30
32
|
{ id: "gpt-5-codex", name: "GPT-5 Codex", reasoning: true },
|
|
31
33
|
] },
|
|
@@ -45,6 +45,19 @@ function decorate(detail, toolName, input, context) {
|
|
|
45
45
|
function canon(name) {
|
|
46
46
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
47
47
|
}
|
|
48
|
+
/** Match both native names and namespaced MCP/ACP names. Providers commonly
|
|
49
|
+
* expose a tool as `mcp__server__read_file` or `functions.exec`; the final
|
|
50
|
+
* component still has the same portable meaning. Keep this exact (rather than
|
|
51
|
+
* substring) matching so `multitasker` cannot become a delegation by accident. */
|
|
52
|
+
function inToolSet(set, rawName, key) {
|
|
53
|
+
if (set.has(key))
|
|
54
|
+
return true;
|
|
55
|
+
const separator = rawName.lastIndexOf("__");
|
|
56
|
+
const dot = rawName.lastIndexOf(".");
|
|
57
|
+
const slash = rawName.lastIndexOf("/");
|
|
58
|
+
const index = Math.max(separator, dot, slash);
|
|
59
|
+
return index >= 0 && set.has(canon(rawName.slice(index + (separator === index ? 2 : 1))));
|
|
60
|
+
}
|
|
48
61
|
function asRecord(input) {
|
|
49
62
|
return input && typeof input === "object" && !Array.isArray(input)
|
|
50
63
|
? input
|
|
@@ -97,11 +110,11 @@ const PATH_KEYS = ["path", "file_path", "filePath", "filename", "fileName", "fil
|
|
|
97
110
|
export function mapToolCall(toolName, input, context = {}) {
|
|
98
111
|
const key = canon(toolName);
|
|
99
112
|
const o = asRecord(input);
|
|
100
|
-
if (SHELL
|
|
113
|
+
if (inToolSet(SHELL, toolName, key)) {
|
|
101
114
|
const command = str(o, "command", "cmd", "script", "input", "args");
|
|
102
115
|
return command ? decorate({ kind: "shell", command, ...(str(o, "cwd", "workdir", "workingDir", "directory") ? { cwd: str(o, "cwd", "workdir", "workingDir", "directory") } : {}) }, toolName, input, context) : undefined;
|
|
103
116
|
}
|
|
104
|
-
if (EDIT
|
|
117
|
+
if (inToolSet(EDIT, toolName, key)) {
|
|
105
118
|
let path = str(o, ...PATH_KEYS);
|
|
106
119
|
// Codex `apply_patch`/`file_change` carries a `changes` map keyed by path.
|
|
107
120
|
if (!path) {
|
|
@@ -118,26 +131,26 @@ export function mapToolCall(toolName, input, context = {}) {
|
|
|
118
131
|
const newText = str(o, "new_string", "newString", "new", "after", "replace", "replacement");
|
|
119
132
|
return decorate({ kind: "edit", path, ...(oldText ? { oldText } : {}), ...(newText ? { newText } : {}) }, toolName, input, context);
|
|
120
133
|
}
|
|
121
|
-
if (WRITE
|
|
134
|
+
if (inToolSet(WRITE, toolName, key)) {
|
|
122
135
|
const path = str(o, ...PATH_KEYS);
|
|
123
136
|
return path ? decorate({ kind: "write", path }, toolName, input, context) : undefined;
|
|
124
137
|
}
|
|
125
|
-
if (READ
|
|
138
|
+
if (inToolSet(READ, toolName, key)) {
|
|
126
139
|
const path = str(o, ...PATH_KEYS);
|
|
127
140
|
return path ? decorate({ kind: "read", path }, toolName, input, context) : undefined;
|
|
128
141
|
}
|
|
129
|
-
if (SEARCH
|
|
142
|
+
if (inToolSet(SEARCH, toolName, key)) {
|
|
130
143
|
const query = str(o, "pattern", "query", "q", "search", "regex", "searchTerm");
|
|
131
144
|
return query ? decorate({ kind: "search", query, ...(str(o, "path", "dir", "directory", "include") ? { path: str(o, "path", "dir", "directory", "include") } : {}) }, toolName, input, context) : undefined;
|
|
132
145
|
}
|
|
133
|
-
if (FETCH
|
|
146
|
+
if (inToolSet(FETCH, toolName, key)) {
|
|
134
147
|
const url = str(o, "url", "uri", "href", "link");
|
|
135
148
|
return url ? decorate({ kind: "fetch", url }, toolName, input, context) : undefined;
|
|
136
149
|
}
|
|
137
|
-
if (PLAN
|
|
150
|
+
if (inToolSet(PLAN, toolName, key)) {
|
|
138
151
|
return decorate({ kind: "plan", ...(str(o, "plan", "text", "content", "message") ? { text: str(o, "plan", "text", "content", "message") } : {}) }, toolName, input, context);
|
|
139
152
|
}
|
|
140
|
-
if (DELEGATE
|
|
153
|
+
if (inToolSet(DELEGATE, toolName, key)) {
|
|
141
154
|
const label = str(o, "subagent_type", "subagentType", "agent", "agentType", "role", "name");
|
|
142
155
|
const description = str(o, "description", "task", "prompt", "instructions", "goal", "message");
|
|
143
156
|
return decorate({ kind: "delegation", ...(label ? { label } : {}), ...(description ? { description } : {}) }, toolName, input, context);
|
package/dist/server.js
CHANGED
|
@@ -723,7 +723,12 @@ function runBivyUpdate() {
|
|
|
723
723
|
const child = spawn(process.execPath, [script, "update"], {
|
|
724
724
|
detached: true,
|
|
725
725
|
stdio: "ignore",
|
|
726
|
-
|
|
726
|
+
// The daemon is commonly itself managed by systemd/launchd. Mark this
|
|
727
|
+
// invocation as terminal-style so the CLI moves the real update into a
|
|
728
|
+
// process that survives the service restart (systemd-run on Linux).
|
|
729
|
+
// Otherwise stopping bivy.service kills the updater before it can install
|
|
730
|
+
// anything, leaving the client stuck on “Updating…”.
|
|
731
|
+
env: { ...process.env, BIVY_TERMINAL: "1" },
|
|
727
732
|
});
|
|
728
733
|
child.unref();
|
|
729
734
|
return { ok: true };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bivy/bivy",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.9-staging.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"zod": "^4.0.0"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
53
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
53
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.258",
|
|
54
54
|
"@earendil-works/pi-ai": "0.84.4",
|
|
55
55
|
"@earendil-works/pi-coding-agent": "0.84.4",
|
|
56
56
|
"node-pty": "^1.1.0"
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"undici": "8.10.0"
|
|
64
64
|
},
|
|
65
65
|
"brace-expansion": "5.0.9",
|
|
66
|
+
"fast-uri": "4.1.4",
|
|
66
67
|
"nanoid": "3.3.18",
|
|
67
68
|
"undici": "8.10.0"
|
|
68
69
|
},
|