@kyde/score 0.1.0 → 0.9.5
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 +18 -13
- package/bin/kyde.js +90 -17
- package/package.json +16 -18
package/README.md
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
# @kyde/score
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Behavioral drift scoring for AI agents — [score.kyde.com](https://score.kyde.com).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Paste this into your coding agent (Claude Code, Grok CLI, Codex, Cursor):
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
Read https://score.kyde.com/llms.txt and set up kyde score for this machine.
|
|
5
|
+
```sh
|
|
6
|
+
npx @kyde/score init
|
|
11
7
|
```
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
One step, safe to rerun, written so an agent can run it alone:
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
1. Creates a scoring key (or uses `$KYDE_KEY`) — shown once, hand it to
|
|
12
|
+
your human.
|
|
13
|
+
2. Points Claude Code's OpenTelemetry export at score.kyde.com
|
|
14
|
+
(`~/.claude/settings.json`, global `env` block — never the agent
|
|
15
|
+
name; names belong where each agent is launched).
|
|
16
|
+
3. Installs the hook: after a tool call Kyde can warn the agent in its
|
|
17
|
+
own context; on a deviating score or loop alarm the next tool call
|
|
18
|
+
pauses for the human (`KYDE_BLOCK=deny` blocks outright,
|
|
19
|
+
`KYDE_BLOCK=off` keeps warnings only).
|
|
20
|
+
4. Sends a test event and confirms that Kyde sees this machine.
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
Equivalent to `curl -fsSL https://score.kyde.com/install.sh | sh` — this
|
|
23
|
+
package fetches and runs exactly that installer, so the two never drift.
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
Docs for agents and humans: <https://score.kyde.com/llms.txt> ·
|
|
26
|
+
Dashboard: <https://score.kyde.com/dashboard>
|
package/bin/kyde.js
CHANGED
|
@@ -1,28 +1,101 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// `npx @kyde/score init` — one-step KYDE Score setup for an agent harness
|
|
3
|
+
// (Claude Code first). A thin wrapper by design (KYDE-421): it fetches
|
|
4
|
+
// the canonical installer from the service and runs it, so the install
|
|
5
|
+
// logic lives in exactly one place (deploy/landing/install.sh, shipped
|
|
6
|
+
// by CI) and `npx @kyde/score init` can never drift from
|
|
7
|
+
// `curl -fsSL https://score.kyde.com/install.sh | sh`.
|
|
8
|
+
//
|
|
9
|
+
// Environment (all optional, passed straight through to the installer):
|
|
10
|
+
// KYDE_KEY use this scoring key instead of creating one
|
|
11
|
+
// KYDE_ENDPOINT service base URL (default https://score.kyde.com)
|
|
12
|
+
// KYDE_BLOCK hook mode: ask (default) | deny | off
|
|
13
|
+
// KYDE_REMOVE_GLOBAL_NAME=1 drop a global OTEL_SERVICE_NAME from settings
|
|
2
14
|
"use strict";
|
|
3
15
|
|
|
4
|
-
const
|
|
5
|
-
|
|
16
|
+
const { spawnSync } = require("node:child_process");
|
|
17
|
+
const fs = require("node:fs");
|
|
18
|
+
const os = require("node:os");
|
|
19
|
+
const path = require("node:path");
|
|
6
20
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
Call metadata only, never the conversation.
|
|
21
|
+
const BASE = process.env.KYDE_ENDPOINT || "https://score.kyde.com";
|
|
22
|
+
const VERSION = require("../package.json").version;
|
|
10
23
|
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
function usage(code) {
|
|
25
|
+
const out = code ? process.stderr : process.stdout;
|
|
26
|
+
out.write(`kyde ${VERSION} — behavioral drift scoring for AI agents
|
|
13
27
|
|
|
14
|
-
|
|
28
|
+
Usage:
|
|
29
|
+
npx @kyde/score init set up this machine: scoring key, OpenTelemetry
|
|
30
|
+
export to ${BASE}, and the warn/pause
|
|
31
|
+
hook for Claude Code. Safe to rerun.
|
|
15
32
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
33
|
+
Options via environment: KYDE_KEY, KYDE_ENDPOINT, KYDE_BLOCK (ask|deny|off),
|
|
34
|
+
KYDE_REMOVE_GLOBAL_NAME=1 — see https://score.kyde.com/llms.txt
|
|
35
|
+
`);
|
|
36
|
+
process.exit(code);
|
|
37
|
+
}
|
|
19
38
|
|
|
20
|
-
|
|
39
|
+
async function fetchInstaller() {
|
|
40
|
+
const res = await fetch(`${BASE}/install.sh`, {
|
|
41
|
+
redirect: "follow",
|
|
42
|
+
signal: AbortSignal.timeout(20000),
|
|
43
|
+
});
|
|
44
|
+
if (!res.ok) {
|
|
45
|
+
throw new Error(`GET ${BASE}/install.sh -> HTTP ${res.status}`);
|
|
46
|
+
}
|
|
47
|
+
return await res.text();
|
|
48
|
+
}
|
|
21
49
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
50
|
+
async function init() {
|
|
51
|
+
if (process.platform === "win32" && !process.env.SHELL) {
|
|
52
|
+
process.stderr.write(
|
|
53
|
+
"kyde init needs a POSIX shell (sh), python3 and curl, which plain " +
|
|
54
|
+
"Windows does not provide.\nRun it inside WSL or Git Bash, or " +
|
|
55
|
+
"follow the manual steps: https://score.kyde.com/llms.txt\n",
|
|
56
|
+
);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
let script;
|
|
60
|
+
try {
|
|
61
|
+
script = await fetchInstaller();
|
|
62
|
+
} catch (err) {
|
|
63
|
+
process.stderr.write(
|
|
64
|
+
`kyde init: could not fetch the installer (${err.message}).\n` +
|
|
65
|
+
`Check outbound HTTPS to ${BASE}, or follow the manual steps: ` +
|
|
66
|
+
`${BASE}/llms.txt\n`,
|
|
67
|
+
);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "kyde-init-"));
|
|
71
|
+
const file = path.join(dir, "install.sh");
|
|
72
|
+
try {
|
|
73
|
+
fs.writeFileSync(file, script, { mode: 0o700 });
|
|
74
|
+
const run = spawnSync("sh", [file], {
|
|
75
|
+
stdio: "inherit",
|
|
76
|
+
env: { ...process.env, KYDE_INSTALL_SOURCE: "npx" },
|
|
77
|
+
});
|
|
78
|
+
if (run.error) {
|
|
79
|
+
process.stderr.write(
|
|
80
|
+
`kyde init: could not run sh (${run.error.message}). ` +
|
|
81
|
+
`Manual steps: ${BASE}/llms.txt\n`,
|
|
82
|
+
);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
process.exit(run.status === null ? 1 : run.status);
|
|
86
|
+
} finally {
|
|
87
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const arg = process.argv[2];
|
|
92
|
+
if (arg === "init") {
|
|
93
|
+
init();
|
|
94
|
+
} else if (!arg || arg === "--help" || arg === "-h" || arg === "help") {
|
|
95
|
+
usage(arg ? 0 : 2);
|
|
96
|
+
} else if (arg === "--version" || arg === "-v") {
|
|
97
|
+
process.stdout.write(VERSION + "\n");
|
|
26
98
|
} else {
|
|
27
|
-
|
|
99
|
+
process.stderr.write(`kyde: unknown command "${arg}"\n\n`);
|
|
100
|
+
usage(2);
|
|
28
101
|
}
|
package/package.json
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kyde/score",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"bin": {
|
|
6
|
-
"kyde": "bin/kyde.js"
|
|
7
|
-
},
|
|
8
|
-
"files": [
|
|
9
|
-
"bin/",
|
|
10
|
-
"README.md"
|
|
11
|
-
],
|
|
3
|
+
"version": "0.9.5",
|
|
4
|
+
"description": "KYDE Score setup: `npx @kyde/score init` wires an agent harness (Claude Code first) to score.kyde.com — OpenTelemetry export plus the warn/pause hook, in one step.",
|
|
12
5
|
"keywords": [
|
|
13
|
-
"
|
|
14
|
-
"agent-monitoring",
|
|
15
|
-
"drift",
|
|
6
|
+
"agent",
|
|
16
7
|
"observability",
|
|
17
8
|
"opentelemetry",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
9
|
+
"claude-code",
|
|
10
|
+
"drift",
|
|
11
|
+
"monitoring"
|
|
20
12
|
],
|
|
21
13
|
"homepage": "https://score.kyde.com",
|
|
22
14
|
"license": "MIT",
|
|
23
|
-
"author": "KYDE",
|
|
24
|
-
"engines": {
|
|
25
|
-
"node": ">=18"
|
|
26
|
-
},
|
|
27
15
|
"publishConfig": {
|
|
28
16
|
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"author": "KYDE (https://kyde.com)",
|
|
19
|
+
"bin": {
|
|
20
|
+
"kyde": "bin/kyde.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
29
27
|
}
|
|
30
28
|
}
|