@hybridaione/hybridclaw 0.25.2 → 0.25.3
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/AGENTS.md +7 -0
- package/CHANGELOG.md +44 -0
- package/README.md +11 -3
- package/console/package.json +1 -1
- package/container/dist/mcp/config-watcher.js +22 -2
- package/container/dist/mcp/config-watcher.js.map +1 -1
- package/container/npm-shrinkwrap.json +2 -2
- package/container/package-lock.json +2 -2
- package/container/package.json +1 -1
- package/container/src/mcp/config-watcher.ts +24 -2
- package/dist/gateway/gateway-http-server.d.ts.map +1 -1
- package/dist/gateway/gateway-http-server.js +18 -1
- package/dist/gateway/gateway-http-server.js.map +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +33 -8
- package/dist/workspace.js.map +1 -1
- package/docs/content/README.md +7 -1
- package/docs/content/channels/overview.md +27 -0
- package/docs/content/getting-started/installation.md +11 -7
- package/docs/content/getting-started/quickstart.md +136 -119
- package/docs/content/guides/bundled-skills.md +2 -2
- package/docs/index.html +21 -11
- package/npm-shrinkwrap.json +53 -61
- package/package.json +5 -5
- package/skills/langfuse/NOTICE.md +40 -0
- package/skills/langfuse/SKILL.md +287 -0
- package/skills/langfuse/evals/scenarios.json +83 -0
- package/skills/langfuse/langfuse.cjs +856 -0
- package/skills/langfuse/references/ci-cd.md +35 -0
- package/skills/langfuse/references/cli.md +59 -0
- package/skills/langfuse/references/error-analysis.md +107 -0
- package/skills/langfuse/references/instrumentation.md +134 -0
- package/skills/langfuse/references/judge-calibration.md +288 -0
- package/skills/langfuse/references/operator-setup.md +77 -0
- package/skills/langfuse/references/prompt-migration.md +234 -0
- package/skills/langfuse/references/sdk-upgrade.md +175 -0
- package/skills/langfuse/references/skill-feedback.md +52 -0
- package/skills/langfuse/references/user-feedback.md +88 -0
- package/skills/skill-creator/scripts/quick_validate.py +1 -0
package/AGENTS.md
CHANGED
|
@@ -264,6 +264,13 @@ hybridclaw gateway status # gateway liveness, PID, build/version dia
|
|
|
264
264
|
`await import()` and static `import` for the same module in production paths.
|
|
265
265
|
- **Dependencies:** root `package.json` is for gateway/CLI deps. Container-only
|
|
266
266
|
deps go in `container/package.json`. Never add container deps to root.
|
|
267
|
+
- When changing npm dependencies, update every generated dependency artifact in
|
|
268
|
+
the same change: the relevant `package-lock.json`, matching
|
|
269
|
+
`npm-shrinkwrap.json`, and the approved lockfile hashes in
|
|
270
|
+
`scripts/dependency-policy-baseline.json`. Use `npm run deps:update-lockfile`
|
|
271
|
+
when practical, or copy the updated lockfile to its shrinkwrap pair and
|
|
272
|
+
update the baseline hash after reviewing the lockfile diff. Run
|
|
273
|
+
`npm run deps:policy` before handing off.
|
|
267
274
|
|
|
268
275
|
### Git Discipline
|
|
269
276
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.25.3](https://github.com/HybridAIOne/hybridclaw/tree/v0.25.3) - 2026-06-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Langfuse skill**: LLM observability and evaluation based on the official
|
|
10
|
+
Langfuse skill (`github.com/langfuse/skills`, MIT). Reads traces, observations,
|
|
11
|
+
sessions, scores, prompts, datasets, models, and metrics, and creates scores,
|
|
12
|
+
comments, datasets, dataset items, and prompt versions through the
|
|
13
|
+
gateway-proxied `langfuse.cjs` helper. Auth uses a SecretRef-backed
|
|
14
|
+
`Authorization: Basic <secret:LANGFUSE_BASIC_AUTH>` header with a
|
|
15
|
+
`LANGFUSE_HOST` config variable; reads are green and writes are grant-gated.
|
|
16
|
+
Bundles the upstream reference docs (instrumentation, prompt migration, error
|
|
17
|
+
analysis, judge calibration, SDK upgrade, CI/CD) plus Langfuse documentation
|
|
18
|
+
lookup (llms.txt / markdown / search-docs).
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **Quick Start guide**: Rewrote the getting-started quickstart into a
|
|
23
|
+
zero-to-working funnel -- a fast HybridAI Cloud path (model preselected,
|
|
24
|
+
already in web chat) and a numbered local path (onboard -> start gateway ->
|
|
25
|
+
confirm healthy with `gateway status` / `doctor` -> open chat -> send a first
|
|
26
|
+
message) with explicit success signals, a troubleshooting block, and a command
|
|
27
|
+
cheat sheet. Relocated the per-channel startup auto-connect conditions into the
|
|
28
|
+
Channels overview.
|
|
29
|
+
- **Apple desktop release**: README and docs point at the signed/notarized Apple
|
|
30
|
+
Silicon DMG, and the desktop wrapper captures gateway startup logs, recent
|
|
31
|
+
child output, spawn failures, and early exits so packaged app launch failures
|
|
32
|
+
are diagnosable.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **MCP server startup isolation**: A single MCP server that fails to connect or
|
|
37
|
+
disconnect is logged and skipped instead of aborting the whole chat turn, and
|
|
38
|
+
unchanged failed server configs are not retried every turn.
|
|
39
|
+
- **Empty heartbeat context**: Workspace bootstrap context skips the default
|
|
40
|
+
empty `HEARTBEAT.md` template and legacy "no recurring heartbeat tasks"
|
|
41
|
+
placeholders, avoiding noise in agent startup context.
|
|
42
|
+
|
|
5
43
|
## [0.25.2](https://github.com/HybridAIOne/hybridclaw/tree/v0.25.2) - 2026-06-20
|
|
6
44
|
|
|
7
45
|
### Fixed
|
|
@@ -13,6 +51,12 @@
|
|
|
13
51
|
|
|
14
52
|
## [0.25.1](https://github.com/HybridAIOne/hybridclaw/tree/v0.25.1) - 2026-06-20
|
|
15
53
|
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- **Desktop packaging**: Desktop build commands rebuild the app before
|
|
57
|
+
packaging, reuse current icon/runtime stages, cache the staged Node runtime,
|
|
58
|
+
and strip non-runtime dependency files from packaged desktop bundles.
|
|
59
|
+
|
|
16
60
|
### Fixed
|
|
17
61
|
|
|
18
62
|
- **HybridAI cloud admin sessions**: HybridAI-launched sessions without scoped
|
package/README.md
CHANGED
|
@@ -69,7 +69,15 @@ HybridClaw on HybridAI Cloud in a few minutes at
|
|
|
69
69
|
|
|
70
70
|
Fastest managed launch: [HybridClaw on HybridAI Cloud](https://hybridclaw.io).
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
Apple Desktop App for macOS:
|
|
73
|
+
|
|
74
|
+
- Download the signed and notarized Apple Silicon DMG:
|
|
75
|
+
[HybridClaw-0.25.3-arm64.dmg](https://github.com/HybridAIOne/hybridclaw/releases/download/v0.25.3/HybridClaw-0.25.3-arm64.dmg)
|
|
76
|
+
- Open the DMG, drag `HybridClaw.app` into `/Applications`, and launch it.
|
|
77
|
+
- The desktop app starts the local gateway and opens the chat, agents, and
|
|
78
|
+
admin surfaces in a native macOS window.
|
|
79
|
+
|
|
80
|
+
Linux/macOS CLI one-line installer:
|
|
73
81
|
|
|
74
82
|
```bash
|
|
75
83
|
curl -fsSL https://raw.githubusercontent.com/HybridAIOne/hybridclaw/main/scripts/install.sh | bash
|
|
@@ -98,7 +106,7 @@ After the gateway starts, open:
|
|
|
98
106
|
| TUI | `hybridclaw tui` | Terminal chat, approvals, status, resume |
|
|
99
107
|
| OpenAI-compatible API | `http://127.0.0.1:9090/v1/chat/completions` | Local evals and compatible clients |
|
|
100
108
|
|
|
101
|
-
For signed macOS desktop builds, use the
|
|
109
|
+
For signed macOS desktop builds and future architectures, use the
|
|
102
110
|
[GitHub Releases](https://github.com/HybridAIOne/hybridclaw/releases/latest)
|
|
103
111
|
page.
|
|
104
112
|
|
|
@@ -220,7 +228,7 @@ Core pieces:
|
|
|
220
228
|
| Build desktop releases | [Desktop Release Builds](https://hybridaione.github.io/hybridclaw/docs/developer-guide/desktop-release) |
|
|
221
229
|
| Contribute | [CONTRIBUTING.md](./CONTRIBUTING.md), [docs/content/README.md](./docs/content/README.md) |
|
|
222
230
|
|
|
223
|
-
Latest release: [v0.25.
|
|
231
|
+
Latest release: [v0.25.3](https://github.com/HybridAIOne/hybridclaw/releases/tag/v0.25.3).
|
|
224
232
|
Release notes: [CHANGELOG.md](./CHANGELOG.md)
|
|
225
233
|
|
|
226
234
|
## Development
|
package/console/package.json
CHANGED
|
@@ -28,12 +28,28 @@ export class McpConfigWatcher {
|
|
|
28
28
|
for (const name of Object.keys(previous)) {
|
|
29
29
|
if (nextNames.has(name))
|
|
30
30
|
continue;
|
|
31
|
-
|
|
31
|
+
// Tearing down one server must not abort the whole apply.
|
|
32
|
+
try {
|
|
33
|
+
await this.manager.removeClient(name);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
this.logServerFailure('disconnect', name, error);
|
|
37
|
+
}
|
|
32
38
|
}
|
|
33
39
|
for (const [name, config] of Object.entries(nextConfig)) {
|
|
34
|
-
if (
|
|
40
|
+
if (configsEqual(previous[name], config))
|
|
41
|
+
continue;
|
|
42
|
+
// A single MCP server failing to connect (e.g. an expired OAuth token
|
|
43
|
+
// answering the initial POST with 401/invalid_token) must NOT reject
|
|
44
|
+
// applyConfig — that rejection propagates up through syncMcpConfig into
|
|
45
|
+
// the chat turn and crashes it, taking down ALL chat for the agent.
|
|
46
|
+
// Log and skip the bad server so the turn proceeds with the rest.
|
|
47
|
+
try {
|
|
35
48
|
await this.manager.replaceClient(name, config);
|
|
36
49
|
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.logServerFailure('connect', name, error);
|
|
52
|
+
}
|
|
37
53
|
}
|
|
38
54
|
this.lastConfig = nextConfig;
|
|
39
55
|
this.lastHash = nextHash;
|
|
@@ -43,5 +59,9 @@ export class McpConfigWatcher {
|
|
|
43
59
|
this.lastConfig = {};
|
|
44
60
|
this.lastHash = stableHash('{}');
|
|
45
61
|
}
|
|
62
|
+
logServerFailure(phase, name, error) {
|
|
63
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
64
|
+
console.error(`[mcp:${name}] failed to ${phase}: ${detail}`);
|
|
65
|
+
}
|
|
46
66
|
}
|
|
47
67
|
//# sourceMappingURL=config-watcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../src/mcp/config-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,SAAS,WAAW,CAClB,OAAoD;IAEpD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,CAG9C,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,YAAY,CACnB,IAAiC,EACjC,KAAsB;IAEtB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,OAAO,gBAAgB;IAIE;IAHrB,UAAU,GAAoC,EAAE,CAAC;IACjD,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAEpC,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,KAAK,CAAC,OAAyC;QACnD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,WAAW,CACf,OAAyC;QAEzC,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;QACxD,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE7C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAEnD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClC,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../src/mcp/config-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hybridclaw-agent",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "hybridclaw-agent",
|
|
9
|
-
"version": "0.25.
|
|
9
|
+
"version": "0.25.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
12
12
|
"@mozilla/readability": "0.6.0",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hybridclaw-agent",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "hybridclaw-agent",
|
|
9
|
-
"version": "0.25.
|
|
9
|
+
"version": "0.25.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
12
12
|
"@mozilla/readability": "0.6.0",
|
package/container/package.json
CHANGED
|
@@ -45,12 +45,25 @@ export class McpConfigWatcher {
|
|
|
45
45
|
|
|
46
46
|
for (const name of Object.keys(previous)) {
|
|
47
47
|
if (nextNames.has(name)) continue;
|
|
48
|
-
|
|
48
|
+
// Tearing down one server must not abort the whole apply.
|
|
49
|
+
try {
|
|
50
|
+
await this.manager.removeClient(name);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
this.logServerFailure('disconnect', name, error);
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
for (const [name, config] of Object.entries(nextConfig)) {
|
|
52
|
-
if (
|
|
57
|
+
if (configsEqual(previous[name], config)) continue;
|
|
58
|
+
// A single MCP server failing to connect (e.g. an expired OAuth token
|
|
59
|
+
// answering the initial POST with 401/invalid_token) must NOT reject
|
|
60
|
+
// applyConfig — that rejection propagates up through syncMcpConfig into
|
|
61
|
+
// the chat turn and crashes it, taking down ALL chat for the agent.
|
|
62
|
+
// Log and skip the bad server so the turn proceeds with the rest.
|
|
63
|
+
try {
|
|
53
64
|
await this.manager.replaceClient(name, config);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
this.logServerFailure('connect', name, error);
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
|
|
@@ -63,4 +76,13 @@ export class McpConfigWatcher {
|
|
|
63
76
|
this.lastConfig = {};
|
|
64
77
|
this.lastHash = stableHash('{}');
|
|
65
78
|
}
|
|
79
|
+
|
|
80
|
+
private logServerFailure(
|
|
81
|
+
phase: 'connect' | 'disconnect',
|
|
82
|
+
name: string,
|
|
83
|
+
error: unknown,
|
|
84
|
+
): void {
|
|
85
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
86
|
+
console.error(`[mcp:${name}] failed to ${phase}: ${detail}`);
|
|
87
|
+
}
|
|
66
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-http-server.d.ts","sourceRoot":"","sources":["../../src/gateway/gateway-http-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gateway-http-server.d.ts","sourceRoot":"","sources":["../../src/gateway/gateway-http-server.ts"],"names":[],"mappings":"AA40NA,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAw3B1D"}
|
|
@@ -1584,6 +1584,17 @@ function resolveRequestOrigin(req, bodyBaseUrl) {
|
|
|
1584
1584
|
const host = forwardedHost || req.headers.host || `127.0.0.1:${HEALTH_PORT}`;
|
|
1585
1585
|
return `${proto}://${host}`;
|
|
1586
1586
|
}
|
|
1587
|
+
function resolveA2AAgentCardOrigin(req) {
|
|
1588
|
+
const configuredPublicUrl = getRuntimeConfig().deployment.public_url.trim();
|
|
1589
|
+
if (configuredPublicUrl) {
|
|
1590
|
+
const origin = normalizePublicBaseUrl(configuredPublicUrl);
|
|
1591
|
+
if (origin)
|
|
1592
|
+
return origin;
|
|
1593
|
+
logger.warn({ publicUrl: configuredPublicUrl }, 'Invalid deployment.public_url for A2A Agent Card');
|
|
1594
|
+
return null;
|
|
1595
|
+
}
|
|
1596
|
+
return resolveRequestOrigin(req);
|
|
1597
|
+
}
|
|
1587
1598
|
function buildMobileLaunchUrl(params) {
|
|
1588
1599
|
const url = new URL('/chat/continue', params.origin);
|
|
1589
1600
|
url.searchParams.set('token', params.token);
|
|
@@ -5057,7 +5068,13 @@ export function startGatewayHttpServer() {
|
|
|
5057
5068
|
}
|
|
5058
5069
|
const voicePaths = resolveVoiceWebhookPaths(getRuntimeConfig().voice.webhookPath);
|
|
5059
5070
|
if (pathname === '/.well-known/agent.json' && method === 'GET') {
|
|
5060
|
-
const origin =
|
|
5071
|
+
const origin = resolveA2AAgentCardOrigin(req);
|
|
5072
|
+
if (!origin) {
|
|
5073
|
+
sendJson(res, 500, {
|
|
5074
|
+
error: 'deployment.public_url must be an HTTP(S) URL.',
|
|
5075
|
+
});
|
|
5076
|
+
return;
|
|
5077
|
+
}
|
|
5061
5078
|
const trust = resolveA2AAgentCardPeerTrust({
|
|
5062
5079
|
authorization: req.headers.authorization || '',
|
|
5063
5080
|
audience: new URL('/.well-known/agent.json', origin).toString(),
|