oathbound 0.16.0 → 0.17.1
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 +48 -21
- package/dist/cli.cjs +391 -54
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,53 +1,80 @@
|
|
|
1
1
|
# oathbound
|
|
2
2
|
|
|
3
|
-
Install and
|
|
3
|
+
Install, verify, and publish Claude Code skills and agents from the [Oath Bound](https://oathbound.ai) registry.
|
|
4
4
|
|
|
5
|
-
Skills are downloaded as tarballs from the registry and verified using SHA-256 content hashing. Every session start and every tool invocation can be checked against the registry to detect tampering.
|
|
5
|
+
Skills and agents are downloaded as tarballs from the registry and verified using SHA-256 content hashing. Every session start and every tool invocation can be checked against the registry to detect tampering.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```sh
|
|
10
|
+
npm install -g oathbound
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or via npx (no install required):
|
|
10
14
|
|
|
11
15
|
```sh
|
|
12
|
-
|
|
16
|
+
npx oathbound <command>
|
|
13
17
|
```
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
## Quick start
|
|
16
20
|
|
|
17
21
|
```sh
|
|
18
|
-
|
|
22
|
+
oathbound init
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
The `init` wizard sets up Claude Code hooks (globally and in the current project) so that skills are verified on every session start and tool invocation.
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
22
28
|
|
|
23
|
-
###
|
|
29
|
+
### Skills
|
|
24
30
|
|
|
25
31
|
```sh
|
|
26
|
-
oathbound pull <namespace/skill
|
|
27
|
-
oathbound
|
|
32
|
+
oathbound pull <namespace/skill[@version]> [--global] # Download & verify a skill
|
|
33
|
+
oathbound push [path] [--private] # Publish a skill to the registry
|
|
34
|
+
oathbound search [query] # Search skills in the registry
|
|
35
|
+
oathbound list # List all public skills
|
|
28
36
|
```
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
`pull` (aliases: `install`, `i`) downloads the latest version of a skill from the registry, verifies the tarball hash, and extracts it into `.claude/skills/`. Pin a specific version with `@1.2.3`. Use `--global` to install into `~/.claude/skills/` instead of the project directory.
|
|
39
|
+
|
|
40
|
+
### Agents
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
```sh
|
|
43
|
+
oathbound agent pull <namespace/name[@version]> # Download an agent
|
|
44
|
+
oathbound agent push [path] [--private] # Publish an agent .md file
|
|
45
|
+
oathbound agent search [query] # Search agents in the registry
|
|
46
|
+
oathbound agent list # List all public agents
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Verification (hooks)
|
|
33
50
|
|
|
34
51
|
```sh
|
|
35
|
-
oathbound verify
|
|
52
|
+
oathbound verify # SessionStart hook — verify all installed skills
|
|
53
|
+
oathbound verify --check # PreToolUse hook — check skill integrity mid-session
|
|
36
54
|
```
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
### Auth
|
|
39
57
|
|
|
40
|
-
|
|
58
|
+
```sh
|
|
59
|
+
oathbound login # Authenticate with oathbound.ai
|
|
60
|
+
oathbound logout # Clear stored credentials
|
|
61
|
+
oathbound whoami # Show current user
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Setup
|
|
41
65
|
|
|
42
66
|
```sh
|
|
43
|
-
oathbound
|
|
67
|
+
oathbound init [--global|--local] # Interactive setup wizard
|
|
68
|
+
oathbound setup # Non-interactive (runs via npm prepare hook)
|
|
44
69
|
```
|
|
45
70
|
|
|
46
|
-
|
|
71
|
+
`init` configures Claude Code hooks in your settings. By default it sets up both global (`~/.claude/settings.json`) and local (`.claude/settings.json`) hooks. Pass `--global` or `--local` to configure only one scope.
|
|
72
|
+
|
|
73
|
+
`setup` is meant to run automatically via the `prepare` script when someone installs your project's dependencies. It reads `.oathbound.jsonc` and merges hooks into `.claude/settings.json` without prompts.
|
|
47
74
|
|
|
48
75
|
## Hook integration
|
|
49
76
|
|
|
50
|
-
oathbound is designed to run as [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks).
|
|
77
|
+
oathbound is designed to run as [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks). The easiest way to set this up is `oathbound init`, which adds the hooks to your `.claude/settings.json`:
|
|
51
78
|
|
|
52
79
|
```json
|
|
53
80
|
{
|
|
@@ -70,14 +97,14 @@ oathbound is designed to run as [Claude Code hooks](https://docs.anthropic.com/e
|
|
|
70
97
|
|
|
71
98
|
## How it works
|
|
72
99
|
|
|
73
|
-
1. **Pull**: Downloads a skill tarball from
|
|
100
|
+
1. **Pull**: Downloads a skill tarball from the registry, verifies the SHA-256 hash of the tarball, and extracts the skill into `.claude/skills/`.
|
|
74
101
|
|
|
75
102
|
2. **SessionStart verification**: Walks each subdirectory in `.claude/skills/`, collects all files (excluding `node_modules`, lockfiles, and `.DS_Store`), sorts them by path, hashes each file with SHA-256, then hashes the combined manifest. The resulting content hash is compared against the registry. Verified hashes are written to a temporary session state file.
|
|
76
103
|
|
|
77
104
|
3. **PreToolUse verification**: Re-hashes the skill directory on disk and compares it against the hash saved at session start. If the content has changed since verification, the tool invocation is denied. This detects mid-session tampering.
|
|
78
105
|
|
|
79
|
-
The content hash algorithm is deterministic: files are sorted lexicographically by relative path, each file is individually hashed, and the concatenated `path\0hash` lines are hashed together. The same algorithm runs on both the registry
|
|
106
|
+
The content hash algorithm is deterministic: files are sorted lexicographically by relative path, each file is individually hashed, and the concatenated `path\0hash` lines are hashed together. The same algorithm runs on both the registry and the CLI to guarantee parity.
|
|
80
107
|
|
|
81
108
|
## License
|
|
82
109
|
|
|
83
|
-
|
|
110
|
+
MIT
|
package/dist/cli.cjs
CHANGED
|
@@ -11518,12 +11518,12 @@ var require_resolve_flow_scalar = __commonJS((exports2) => {
|
|
|
11518
11518
|
};
|
|
11519
11519
|
}
|
|
11520
11520
|
const valueEnd = offset + source.length;
|
|
11521
|
-
const
|
|
11521
|
+
const re2 = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
|
|
11522
11522
|
return {
|
|
11523
11523
|
value,
|
|
11524
11524
|
type: _type,
|
|
11525
|
-
comment:
|
|
11526
|
-
range: [offset, valueEnd,
|
|
11525
|
+
comment: re2.comment,
|
|
11526
|
+
range: [offset, valueEnd, re2.offset]
|
|
11527
11527
|
};
|
|
11528
11528
|
}
|
|
11529
11529
|
function plainValue(source, onError) {
|
|
@@ -11895,10 +11895,10 @@ var require_compose_node = __commonJS((exports2) => {
|
|
|
11895
11895
|
if (alias.source.endsWith(":"))
|
|
11896
11896
|
onError(offset + source.length - 1, "BAD_ALIAS", "Alias ending in : is ambiguous", true);
|
|
11897
11897
|
const valueEnd = offset + source.length;
|
|
11898
|
-
const
|
|
11899
|
-
alias.range = [offset, valueEnd,
|
|
11900
|
-
if (
|
|
11901
|
-
alias.comment =
|
|
11898
|
+
const re2 = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
|
|
11899
|
+
alias.range = [offset, valueEnd, re2.offset];
|
|
11900
|
+
if (re2.comment)
|
|
11901
|
+
alias.comment = re2.comment;
|
|
11902
11902
|
return alias;
|
|
11903
11903
|
}
|
|
11904
11904
|
exports2.composeEmptyNode = composeEmptyNode;
|
|
@@ -11936,10 +11936,10 @@ var require_compose_doc = __commonJS((exports2) => {
|
|
|
11936
11936
|
}
|
|
11937
11937
|
doc.contents = value ? composeNode.composeNode(ctx, value, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
|
|
11938
11938
|
const contentEnd = doc.contents.range[2];
|
|
11939
|
-
const
|
|
11940
|
-
if (
|
|
11941
|
-
doc.comment =
|
|
11942
|
-
doc.range = [offset, contentEnd,
|
|
11939
|
+
const re2 = resolveEnd.resolveEnd(end, contentEnd, false, onError);
|
|
11940
|
+
if (re2.comment)
|
|
11941
|
+
doc.comment = re2.comment;
|
|
11942
|
+
doc.range = [offset, contentEnd, re2.offset];
|
|
11943
11943
|
return doc;
|
|
11944
11944
|
}
|
|
11945
11945
|
exports2.composeDoc = composeDoc;
|
|
@@ -16704,7 +16704,15 @@ function W(t, e) {
|
|
|
16704
16704
|
const s = t;
|
|
16705
16705
|
s.isTTY && s.setRawMode(e);
|
|
16706
16706
|
}
|
|
16707
|
+
var rt = (t) => ("columns" in t) && typeof t.columns == "number" ? t.columns : 80;
|
|
16707
16708
|
var nt = (t) => ("rows" in t) && typeof t.rows == "number" ? t.rows : 20;
|
|
16709
|
+
function Bt(t, e, s, i = s) {
|
|
16710
|
+
const r = rt(t ?? import_node_process.stdout);
|
|
16711
|
+
return K(e, r - s.length, { hard: true, trim: false }).split(`
|
|
16712
|
+
`).map((n, u) => `${u === 0 ? i : s}${n}`).join(`
|
|
16713
|
+
`);
|
|
16714
|
+
}
|
|
16715
|
+
|
|
16708
16716
|
class B {
|
|
16709
16717
|
input;
|
|
16710
16718
|
output;
|
|
@@ -16973,6 +16981,33 @@ class yt extends B {
|
|
|
16973
16981
|
});
|
|
16974
16982
|
}
|
|
16975
16983
|
}
|
|
16984
|
+
class Tt extends B {
|
|
16985
|
+
options;
|
|
16986
|
+
cursor = 0;
|
|
16987
|
+
get _selectedValue() {
|
|
16988
|
+
return this.options[this.cursor];
|
|
16989
|
+
}
|
|
16990
|
+
changeValue() {
|
|
16991
|
+
this.value = this._selectedValue.value;
|
|
16992
|
+
}
|
|
16993
|
+
constructor(e) {
|
|
16994
|
+
super(e, false), this.options = e.options;
|
|
16995
|
+
const s = this.options.findIndex(({ value: r }) => r === e.initialValue), i = s === -1 ? 0 : s;
|
|
16996
|
+
this.cursor = this.options[i].disabled ? x(i, 1, this.options) : i, this.changeValue(), this.on("cursor", (r) => {
|
|
16997
|
+
switch (r) {
|
|
16998
|
+
case "left":
|
|
16999
|
+
case "up":
|
|
17000
|
+
this.cursor = x(this.cursor, -1, this.options);
|
|
17001
|
+
break;
|
|
17002
|
+
case "down":
|
|
17003
|
+
case "right":
|
|
17004
|
+
this.cursor = x(this.cursor, 1, this.options);
|
|
17005
|
+
break;
|
|
17006
|
+
}
|
|
17007
|
+
this.changeValue();
|
|
17008
|
+
});
|
|
17009
|
+
}
|
|
17010
|
+
}
|
|
16976
17011
|
|
|
16977
17012
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
16978
17013
|
var import_node_util2 = require("node:util");
|
|
@@ -17021,13 +17056,234 @@ var W2 = (e) => {
|
|
|
17021
17056
|
return import_node_util2.styleText("green", V);
|
|
17022
17057
|
}
|
|
17023
17058
|
};
|
|
17059
|
+
var ve = (e) => {
|
|
17060
|
+
switch (e) {
|
|
17061
|
+
case "initial":
|
|
17062
|
+
case "active":
|
|
17063
|
+
return import_node_util2.styleText("cyan", h);
|
|
17064
|
+
case "cancel":
|
|
17065
|
+
return import_node_util2.styleText("red", h);
|
|
17066
|
+
case "error":
|
|
17067
|
+
return import_node_util2.styleText("yellow", h);
|
|
17068
|
+
case "submit":
|
|
17069
|
+
return import_node_util2.styleText("green", h);
|
|
17070
|
+
}
|
|
17071
|
+
};
|
|
17072
|
+
var mt2 = (e) => e === 161 || e === 164 || e === 167 || e === 168 || e === 170 || e === 173 || e === 174 || e >= 176 && e <= 180 || e >= 182 && e <= 186 || e >= 188 && e <= 191 || e === 198 || e === 208 || e === 215 || e === 216 || e >= 222 && e <= 225 || e === 230 || e >= 232 && e <= 234 || e === 236 || e === 237 || e === 240 || e === 242 || e === 243 || e >= 247 && e <= 250 || e === 252 || e === 254 || e === 257 || e === 273 || e === 275 || e === 283 || e === 294 || e === 295 || e === 299 || e >= 305 && e <= 307 || e === 312 || e >= 319 && e <= 322 || e === 324 || e >= 328 && e <= 331 || e === 333 || e === 338 || e === 339 || e === 358 || e === 359 || e === 363 || e === 462 || e === 464 || e === 466 || e === 468 || e === 470 || e === 472 || e === 474 || e === 476 || e === 593 || e === 609 || e === 708 || e === 711 || e >= 713 && e <= 715 || e === 717 || e === 720 || e >= 728 && e <= 731 || e === 733 || e === 735 || e >= 768 && e <= 879 || e >= 913 && e <= 929 || e >= 931 && e <= 937 || e >= 945 && e <= 961 || e >= 963 && e <= 969 || e === 1025 || e >= 1040 && e <= 1103 || e === 1105 || e === 8208 || e >= 8211 && e <= 8214 || e === 8216 || e === 8217 || e === 8220 || e === 8221 || e >= 8224 && e <= 8226 || e >= 8228 && e <= 8231 || e === 8240 || e === 8242 || e === 8243 || e === 8245 || e === 8251 || e === 8254 || e === 8308 || e === 8319 || e >= 8321 && e <= 8324 || e === 8364 || e === 8451 || e === 8453 || e === 8457 || e === 8467 || e === 8470 || e === 8481 || e === 8482 || e === 8486 || e === 8491 || e === 8531 || e === 8532 || e >= 8539 && e <= 8542 || e >= 8544 && e <= 8555 || e >= 8560 && e <= 8569 || e === 8585 || e >= 8592 && e <= 8601 || e === 8632 || e === 8633 || e === 8658 || e === 8660 || e === 8679 || e === 8704 || e === 8706 || e === 8707 || e === 8711 || e === 8712 || e === 8715 || e === 8719 || e === 8721 || e === 8725 || e === 8730 || e >= 8733 && e <= 8736 || e === 8739 || e === 8741 || e >= 8743 && e <= 8748 || e === 8750 || e >= 8756 && e <= 8759 || e === 8764 || e === 8765 || e === 8776 || e === 8780 || e === 8786 || e === 8800 || e === 8801 || e >= 8804 && e <= 8807 || e === 8810 || e === 8811 || e === 8814 || e === 8815 || e === 8834 || e === 8835 || e === 8838 || e === 8839 || e === 8853 || e === 8857 || e === 8869 || e === 8895 || e === 8978 || e >= 9312 && e <= 9449 || e >= 9451 && e <= 9547 || e >= 9552 && e <= 9587 || e >= 9600 && e <= 9615 || e >= 9618 && e <= 9621 || e === 9632 || e === 9633 || e >= 9635 && e <= 9641 || e === 9650 || e === 9651 || e === 9654 || e === 9655 || e === 9660 || e === 9661 || e === 9664 || e === 9665 || e >= 9670 && e <= 9672 || e === 9675 || e >= 9678 && e <= 9681 || e >= 9698 && e <= 9701 || e === 9711 || e === 9733 || e === 9734 || e === 9737 || e === 9742 || e === 9743 || e === 9756 || e === 9758 || e === 9792 || e === 9794 || e === 9824 || e === 9825 || e >= 9827 && e <= 9829 || e >= 9831 && e <= 9834 || e === 9836 || e === 9837 || e === 9839 || e === 9886 || e === 9887 || e === 9919 || e >= 9926 && e <= 9933 || e >= 9935 && e <= 9939 || e >= 9941 && e <= 9953 || e === 9955 || e === 9960 || e === 9961 || e >= 9963 && e <= 9969 || e === 9972 || e >= 9974 && e <= 9977 || e === 9979 || e === 9980 || e === 9982 || e === 9983 || e === 10045 || e >= 10102 && e <= 10111 || e >= 11094 && e <= 11097 || e >= 12872 && e <= 12879 || e >= 57344 && e <= 63743 || e >= 65024 && e <= 65039 || e === 65533 || e >= 127232 && e <= 127242 || e >= 127248 && e <= 127277 || e >= 127280 && e <= 127337 || e >= 127344 && e <= 127373 || e === 127375 || e === 127376 || e >= 127387 && e <= 127404 || e >= 917760 && e <= 917999 || e >= 983040 && e <= 1048573 || e >= 1048576 && e <= 1114109;
|
|
17073
|
+
var gt2 = (e) => e === 12288 || e >= 65281 && e <= 65376 || e >= 65504 && e <= 65510;
|
|
17074
|
+
var ft2 = (e) => e >= 4352 && e <= 4447 || e === 8986 || e === 8987 || e === 9001 || e === 9002 || e >= 9193 && e <= 9196 || e === 9200 || e === 9203 || e === 9725 || e === 9726 || e === 9748 || e === 9749 || e >= 9800 && e <= 9811 || e === 9855 || e === 9875 || e === 9889 || e === 9898 || e === 9899 || e === 9917 || e === 9918 || e === 9924 || e === 9925 || e === 9934 || e === 9940 || e === 9962 || e === 9970 || e === 9971 || e === 9973 || e === 9978 || e === 9981 || e === 9989 || e === 9994 || e === 9995 || e === 10024 || e === 10060 || e === 10062 || e >= 10067 && e <= 10069 || e === 10071 || e >= 10133 && e <= 10135 || e === 10160 || e === 10175 || e === 11035 || e === 11036 || e === 11088 || e === 11093 || e >= 11904 && e <= 11929 || e >= 11931 && e <= 12019 || e >= 12032 && e <= 12245 || e >= 12272 && e <= 12287 || e >= 12289 && e <= 12350 || e >= 12353 && e <= 12438 || e >= 12441 && e <= 12543 || e >= 12549 && e <= 12591 || e >= 12593 && e <= 12686 || e >= 12688 && e <= 12771 || e >= 12783 && e <= 12830 || e >= 12832 && e <= 12871 || e >= 12880 && e <= 19903 || e >= 19968 && e <= 42124 || e >= 42128 && e <= 42182 || e >= 43360 && e <= 43388 || e >= 44032 && e <= 55203 || e >= 63744 && e <= 64255 || e >= 65040 && e <= 65049 || e >= 65072 && e <= 65106 || e >= 65108 && e <= 65126 || e >= 65128 && e <= 65131 || e >= 94176 && e <= 94180 || e === 94192 || e === 94193 || e >= 94208 && e <= 100343 || e >= 100352 && e <= 101589 || e >= 101632 && e <= 101640 || e >= 110576 && e <= 110579 || e >= 110581 && e <= 110587 || e === 110589 || e === 110590 || e >= 110592 && e <= 110882 || e === 110898 || e >= 110928 && e <= 110930 || e === 110933 || e >= 110948 && e <= 110951 || e >= 110960 && e <= 111355 || e === 126980 || e === 127183 || e === 127374 || e >= 127377 && e <= 127386 || e >= 127488 && e <= 127490 || e >= 127504 && e <= 127547 || e >= 127552 && e <= 127560 || e === 127568 || e === 127569 || e >= 127584 && e <= 127589 || e >= 127744 && e <= 127776 || e >= 127789 && e <= 127797 || e >= 127799 && e <= 127868 || e >= 127870 && e <= 127891 || e >= 127904 && e <= 127946 || e >= 127951 && e <= 127955 || e >= 127968 && e <= 127984 || e === 127988 || e >= 127992 && e <= 128062 || e === 128064 || e >= 128066 && e <= 128252 || e >= 128255 && e <= 128317 || e >= 128331 && e <= 128334 || e >= 128336 && e <= 128359 || e === 128378 || e === 128405 || e === 128406 || e === 128420 || e >= 128507 && e <= 128591 || e >= 128640 && e <= 128709 || e === 128716 || e >= 128720 && e <= 128722 || e >= 128725 && e <= 128727 || e >= 128732 && e <= 128735 || e === 128747 || e === 128748 || e >= 128756 && e <= 128764 || e >= 128992 && e <= 129003 || e === 129008 || e >= 129292 && e <= 129338 || e >= 129340 && e <= 129349 || e >= 129351 && e <= 129535 || e >= 129648 && e <= 129660 || e >= 129664 && e <= 129672 || e >= 129680 && e <= 129725 || e >= 129727 && e <= 129733 || e >= 129742 && e <= 129755 || e >= 129760 && e <= 129768 || e >= 129776 && e <= 129784 || e >= 131072 && e <= 196605 || e >= 196608 && e <= 262141;
|
|
17075
|
+
var we = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
17076
|
+
var re = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
17077
|
+
var ie = /\t{1,1000}/y;
|
|
17078
|
+
var Ae = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
17079
|
+
var ne = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
17080
|
+
var Ft2 = /\p{M}+/gu;
|
|
17024
17081
|
var yt2 = { limit: 1 / 0, ellipsis: "" };
|
|
17082
|
+
var Le = (e, r = {}, s = {}) => {
|
|
17083
|
+
const i = r.limit ?? 1 / 0, a = r.ellipsis ?? "", o = r?.ellipsisWidth ?? (a ? Le(a, yt2, s).width : 0), u = s.ansiWidth ?? 0, l = s.controlWidth ?? 0, n = s.tabWidth ?? 8, c = s.ambiguousWidth ?? 1, p = s.emojiWidth ?? 2, f = s.fullWidthWidth ?? 2, g = s.regularWidth ?? 1, E = s.wideWidth ?? 2;
|
|
17084
|
+
let $ = 0, m = 0, d = e.length, F = 0, y2 = false, v = d, C = Math.max(0, i - o), A = 0, b = 0, w = 0, S2 = 0;
|
|
17085
|
+
e:
|
|
17086
|
+
for (;; ) {
|
|
17087
|
+
if (b > A || m >= d && m > $) {
|
|
17088
|
+
const T2 = e.slice(A, b) || e.slice($, m);
|
|
17089
|
+
F = 0;
|
|
17090
|
+
for (const M2 of T2.replaceAll(Ft2, "")) {
|
|
17091
|
+
const O2 = M2.codePointAt(0) || 0;
|
|
17092
|
+
if (gt2(O2) ? S2 = f : ft2(O2) ? S2 = E : c !== g && mt2(O2) ? S2 = c : S2 = g, w + S2 > C && (v = Math.min(v, Math.max(A, $) + F)), w + S2 > i) {
|
|
17093
|
+
y2 = true;
|
|
17094
|
+
break e;
|
|
17095
|
+
}
|
|
17096
|
+
F += M2.length, w += S2;
|
|
17097
|
+
}
|
|
17098
|
+
A = b = 0;
|
|
17099
|
+
}
|
|
17100
|
+
if (m >= d)
|
|
17101
|
+
break;
|
|
17102
|
+
if (ne.lastIndex = m, ne.test(e)) {
|
|
17103
|
+
if (F = ne.lastIndex - m, S2 = F * g, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / g))), w + S2 > i) {
|
|
17104
|
+
y2 = true;
|
|
17105
|
+
break;
|
|
17106
|
+
}
|
|
17107
|
+
w += S2, A = $, b = m, m = $ = ne.lastIndex;
|
|
17108
|
+
continue;
|
|
17109
|
+
}
|
|
17110
|
+
if (we.lastIndex = m, we.test(e)) {
|
|
17111
|
+
if (w + u > C && (v = Math.min(v, m)), w + u > i) {
|
|
17112
|
+
y2 = true;
|
|
17113
|
+
break;
|
|
17114
|
+
}
|
|
17115
|
+
w += u, A = $, b = m, m = $ = we.lastIndex;
|
|
17116
|
+
continue;
|
|
17117
|
+
}
|
|
17118
|
+
if (re.lastIndex = m, re.test(e)) {
|
|
17119
|
+
if (F = re.lastIndex - m, S2 = F * l, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / l))), w + S2 > i) {
|
|
17120
|
+
y2 = true;
|
|
17121
|
+
break;
|
|
17122
|
+
}
|
|
17123
|
+
w += S2, A = $, b = m, m = $ = re.lastIndex;
|
|
17124
|
+
continue;
|
|
17125
|
+
}
|
|
17126
|
+
if (ie.lastIndex = m, ie.test(e)) {
|
|
17127
|
+
if (F = ie.lastIndex - m, S2 = F * n, w + S2 > C && (v = Math.min(v, m + Math.floor((C - w) / n))), w + S2 > i) {
|
|
17128
|
+
y2 = true;
|
|
17129
|
+
break;
|
|
17130
|
+
}
|
|
17131
|
+
w += S2, A = $, b = m, m = $ = ie.lastIndex;
|
|
17132
|
+
continue;
|
|
17133
|
+
}
|
|
17134
|
+
if (Ae.lastIndex = m, Ae.test(e)) {
|
|
17135
|
+
if (w + p > C && (v = Math.min(v, m)), w + p > i) {
|
|
17136
|
+
y2 = true;
|
|
17137
|
+
break;
|
|
17138
|
+
}
|
|
17139
|
+
w += p, A = $, b = m, m = $ = Ae.lastIndex;
|
|
17140
|
+
continue;
|
|
17141
|
+
}
|
|
17142
|
+
m += 1;
|
|
17143
|
+
}
|
|
17144
|
+
return { width: y2 ? C : w, index: y2 ? v : d, truncated: y2, ellipsed: y2 && i >= o };
|
|
17145
|
+
};
|
|
17025
17146
|
var Et2 = { limit: 1 / 0, ellipsis: "", ellipsisWidth: 0 };
|
|
17147
|
+
var D2 = (e, r = {}) => Le(e, Et2, r).width;
|
|
17148
|
+
var ae = "\x1B";
|
|
17149
|
+
var je = "";
|
|
17150
|
+
var vt2 = 39;
|
|
17026
17151
|
var Ce = "\x07";
|
|
17027
17152
|
var ke = "[";
|
|
17028
17153
|
var wt2 = "]";
|
|
17154
|
+
var Ve = "m";
|
|
17029
17155
|
var Se = `${wt2}8;;`;
|
|
17030
17156
|
var He = new RegExp(`(?:\\${ke}(?<code>\\d+)m|\\${Se}(?<uri>.*)${Ce})`, "y");
|
|
17157
|
+
var At2 = (e) => {
|
|
17158
|
+
if (e >= 30 && e <= 37 || e >= 90 && e <= 97)
|
|
17159
|
+
return 39;
|
|
17160
|
+
if (e >= 40 && e <= 47 || e >= 100 && e <= 107)
|
|
17161
|
+
return 49;
|
|
17162
|
+
if (e === 1 || e === 2)
|
|
17163
|
+
return 22;
|
|
17164
|
+
if (e === 3)
|
|
17165
|
+
return 23;
|
|
17166
|
+
if (e === 4)
|
|
17167
|
+
return 24;
|
|
17168
|
+
if (e === 7)
|
|
17169
|
+
return 27;
|
|
17170
|
+
if (e === 8)
|
|
17171
|
+
return 28;
|
|
17172
|
+
if (e === 9)
|
|
17173
|
+
return 29;
|
|
17174
|
+
if (e === 0)
|
|
17175
|
+
return 0;
|
|
17176
|
+
};
|
|
17177
|
+
var Ue = (e) => `${ae}${ke}${e}${Ve}`;
|
|
17178
|
+
var Ke = (e) => `${ae}${Se}${e}${Ce}`;
|
|
17179
|
+
var Ct2 = (e) => e.map((r) => D2(r));
|
|
17180
|
+
var Ie = (e, r, s) => {
|
|
17181
|
+
const i = r[Symbol.iterator]();
|
|
17182
|
+
let a = false, o = false, u = e.at(-1), l = u === undefined ? 0 : D2(u), n = i.next(), c = i.next(), p = 0;
|
|
17183
|
+
for (;!n.done; ) {
|
|
17184
|
+
const f = n.value, g = D2(f);
|
|
17185
|
+
l + g <= s ? e[e.length - 1] += f : (e.push(f), l = 0), (f === ae || f === je) && (a = true, o = r.startsWith(Se, p + 1)), a ? o ? f === Ce && (a = false, o = false) : f === Ve && (a = false) : (l += g, l === s && !c.done && (e.push(""), l = 0)), n = c, c = i.next(), p += f.length;
|
|
17186
|
+
}
|
|
17187
|
+
u = e.at(-1), !l && u !== undefined && u.length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
|
|
17188
|
+
};
|
|
17189
|
+
var St2 = (e) => {
|
|
17190
|
+
const r = e.split(" ");
|
|
17191
|
+
let s = r.length;
|
|
17192
|
+
for (;s > 0 && !(D2(r[s - 1]) > 0); )
|
|
17193
|
+
s--;
|
|
17194
|
+
return s === r.length ? e : r.slice(0, s).join(" ") + r.slice(s).join("");
|
|
17195
|
+
};
|
|
17196
|
+
var It2 = (e, r, s = {}) => {
|
|
17197
|
+
if (s.trim !== false && e.trim() === "")
|
|
17198
|
+
return "";
|
|
17199
|
+
let i = "", a, o;
|
|
17200
|
+
const u = e.split(" "), l = Ct2(u);
|
|
17201
|
+
let n = [""];
|
|
17202
|
+
for (const [$, m] of u.entries()) {
|
|
17203
|
+
s.trim !== false && (n[n.length - 1] = (n.at(-1) ?? "").trimStart());
|
|
17204
|
+
let d = D2(n.at(-1) ?? "");
|
|
17205
|
+
if ($ !== 0 && (d >= r && (s.wordWrap === false || s.trim === false) && (n.push(""), d = 0), (d > 0 || s.trim === false) && (n[n.length - 1] += " ", d++)), s.hard && l[$] > r) {
|
|
17206
|
+
const F = r - d, y2 = 1 + Math.floor((l[$] - F - 1) / r);
|
|
17207
|
+
Math.floor((l[$] - 1) / r) < y2 && n.push(""), Ie(n, m, r);
|
|
17208
|
+
continue;
|
|
17209
|
+
}
|
|
17210
|
+
if (d + l[$] > r && d > 0 && l[$] > 0) {
|
|
17211
|
+
if (s.wordWrap === false && d < r) {
|
|
17212
|
+
Ie(n, m, r);
|
|
17213
|
+
continue;
|
|
17214
|
+
}
|
|
17215
|
+
n.push("");
|
|
17216
|
+
}
|
|
17217
|
+
if (d + l[$] > r && s.wordWrap === false) {
|
|
17218
|
+
Ie(n, m, r);
|
|
17219
|
+
continue;
|
|
17220
|
+
}
|
|
17221
|
+
n[n.length - 1] += m;
|
|
17222
|
+
}
|
|
17223
|
+
s.trim !== false && (n = n.map(($) => St2($)));
|
|
17224
|
+
const c = n.join(`
|
|
17225
|
+
`), p = c[Symbol.iterator]();
|
|
17226
|
+
let f = p.next(), g = p.next(), E = 0;
|
|
17227
|
+
for (;!f.done; ) {
|
|
17228
|
+
const $ = f.value, m = g.value;
|
|
17229
|
+
if (i += $, $ === ae || $ === je) {
|
|
17230
|
+
He.lastIndex = E + 1;
|
|
17231
|
+
const y2 = He.exec(c)?.groups;
|
|
17232
|
+
if (y2?.code !== undefined) {
|
|
17233
|
+
const v = Number.parseFloat(y2.code);
|
|
17234
|
+
a = v === vt2 ? undefined : v;
|
|
17235
|
+
} else
|
|
17236
|
+
y2?.uri !== undefined && (o = y2.uri.length === 0 ? undefined : y2.uri);
|
|
17237
|
+
}
|
|
17238
|
+
const d = a ? At2(a) : undefined;
|
|
17239
|
+
m === `
|
|
17240
|
+
` ? (o && (i += Ke("")), a && d && (i += Ue(d))) : $ === `
|
|
17241
|
+
` && (a && d && (i += Ue(a)), o && (i += Ke(o))), E += $.length, f = g, g = p.next();
|
|
17242
|
+
}
|
|
17243
|
+
return i;
|
|
17244
|
+
};
|
|
17245
|
+
function J(e, r, s) {
|
|
17246
|
+
return String(e).normalize().replaceAll(`\r
|
|
17247
|
+
`, `
|
|
17248
|
+
`).split(`
|
|
17249
|
+
`).map((i) => It2(i, r, s)).join(`
|
|
17250
|
+
`);
|
|
17251
|
+
}
|
|
17252
|
+
var bt2 = (e, r, s, i, a) => {
|
|
17253
|
+
let o = r, u = 0;
|
|
17254
|
+
for (let l = s;l < i; l++) {
|
|
17255
|
+
const n = e[l];
|
|
17256
|
+
if (o = o - n.length, u++, o <= a)
|
|
17257
|
+
break;
|
|
17258
|
+
}
|
|
17259
|
+
return { lineCount: o, removals: u };
|
|
17260
|
+
};
|
|
17261
|
+
var X2 = ({ cursor: e, options: r, style: s, output: i = process.stdout, maxItems: a = Number.POSITIVE_INFINITY, columnPadding: o = 0, rowPadding: u = 4 }) => {
|
|
17262
|
+
const l = rt(i) - o, n = nt(i), c = import_node_util2.styleText("dim", "..."), p = Math.max(n - u, 0), f = Math.max(Math.min(a, p), 5);
|
|
17263
|
+
let g = 0;
|
|
17264
|
+
e >= f - 3 && (g = Math.max(Math.min(e - f + 3, r.length - f), 0));
|
|
17265
|
+
let E = f < r.length && g > 0, $ = f < r.length && g + f < r.length;
|
|
17266
|
+
const m = Math.min(g + f, r.length), d = [];
|
|
17267
|
+
let F = 0;
|
|
17268
|
+
E && F++, $ && F++;
|
|
17269
|
+
const y2 = g + (E ? 1 : 0), v = m - ($ ? 1 : 0);
|
|
17270
|
+
for (let A = y2;A < v; A++) {
|
|
17271
|
+
const b = J(s(r[A], A === e), l, { hard: true, trim: false }).split(`
|
|
17272
|
+
`);
|
|
17273
|
+
d.push(b), F += b.length;
|
|
17274
|
+
}
|
|
17275
|
+
if (F > p) {
|
|
17276
|
+
let A = 0, b = 0, w = F;
|
|
17277
|
+
const S2 = e - y2, T2 = (M2, O2) => bt2(d, w, M2, O2, p);
|
|
17278
|
+
E ? ({ lineCount: w, removals: A } = T2(0, S2), w > p && ({ lineCount: w, removals: b } = T2(S2 + 1, d.length))) : ({ lineCount: w, removals: b } = T2(S2 + 1, d.length), w > p && ({ lineCount: w, removals: A } = T2(0, S2))), A > 0 && (E = true, d.splice(0, A)), b > 0 && ($ = true, d.splice(d.length - b, b));
|
|
17279
|
+
}
|
|
17280
|
+
const C = [];
|
|
17281
|
+
E && C.push(c);
|
|
17282
|
+
for (const A of d)
|
|
17283
|
+
for (const b of A)
|
|
17284
|
+
C.push(b);
|
|
17285
|
+
return $ && C.push(c), C;
|
|
17286
|
+
};
|
|
17031
17287
|
var Rt = (e) => {
|
|
17032
17288
|
const r = e.active ?? "Yes", s = e.inactive ?? "No";
|
|
17033
17289
|
return new kt({ active: r, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
|
|
@@ -17074,6 +17330,51 @@ ${import_node_util2.styleText("gray", x2)} ` : "";
|
|
|
17074
17330
|
`);
|
|
17075
17331
|
};
|
|
17076
17332
|
var ze = { light: I2("─", "-"), heavy: I2("━", "="), block: I2("█", "#") };
|
|
17333
|
+
var oe = (e, r) => e.includes(`
|
|
17334
|
+
`) ? e.split(`
|
|
17335
|
+
`).map((s) => r(s)).join(`
|
|
17336
|
+
`) : r(e);
|
|
17337
|
+
var Jt = (e) => {
|
|
17338
|
+
const r = (s, i) => {
|
|
17339
|
+
const a = s.label ?? String(s.value);
|
|
17340
|
+
switch (i) {
|
|
17341
|
+
case "disabled":
|
|
17342
|
+
return `${import_node_util2.styleText("gray", H2)} ${oe(a, (o) => import_node_util2.styleText("gray", o))}${s.hint ? ` ${import_node_util2.styleText("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
|
|
17343
|
+
case "selected":
|
|
17344
|
+
return `${oe(a, (o) => import_node_util2.styleText("dim", o))}`;
|
|
17345
|
+
case "active":
|
|
17346
|
+
return `${import_node_util2.styleText("green", z2)} ${a}${s.hint ? ` ${import_node_util2.styleText("dim", `(${s.hint})`)}` : ""}`;
|
|
17347
|
+
case "cancelled":
|
|
17348
|
+
return `${oe(a, (o) => import_node_util2.styleText(["strikethrough", "dim"], o))}`;
|
|
17349
|
+
default:
|
|
17350
|
+
return `${import_node_util2.styleText("dim", H2)} ${oe(a, (o) => import_node_util2.styleText("dim", o))}`;
|
|
17351
|
+
}
|
|
17352
|
+
};
|
|
17353
|
+
return new Tt({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, render() {
|
|
17354
|
+
const s = e.withGuide ?? _.withGuide, i = `${W2(this.state)} `, a = `${ve(this.state)} `, o = Bt(e.output, e.message, a, i), u = `${s ? `${import_node_util2.styleText("gray", h)}
|
|
17355
|
+
` : ""}${o}
|
|
17356
|
+
`;
|
|
17357
|
+
switch (this.state) {
|
|
17358
|
+
case "submit": {
|
|
17359
|
+
const l = s ? `${import_node_util2.styleText("gray", h)} ` : "", n = Bt(e.output, r(this.options[this.cursor], "selected"), l);
|
|
17360
|
+
return `${u}${n}`;
|
|
17361
|
+
}
|
|
17362
|
+
case "cancel": {
|
|
17363
|
+
const l = s ? `${import_node_util2.styleText("gray", h)} ` : "", n = Bt(e.output, r(this.options[this.cursor], "cancelled"), l);
|
|
17364
|
+
return `${u}${n}${s ? `
|
|
17365
|
+
${import_node_util2.styleText("gray", h)}` : ""}`;
|
|
17366
|
+
}
|
|
17367
|
+
default: {
|
|
17368
|
+
const l = s ? `${import_node_util2.styleText("cyan", h)} ` : "", n = s ? import_node_util2.styleText("cyan", x2) : "", c = u.split(`
|
|
17369
|
+
`).length, p = s ? 2 : 1;
|
|
17370
|
+
return `${u}${l}${X2({ output: e.output, cursor: this.cursor, options: this.options, maxItems: e.maxItems, columnPadding: l.length, rowPadding: c + p, style: (f, g) => r(f, f.disabled ? "disabled" : g ? "active" : "inactive") }).join(`
|
|
17371
|
+
${l}`)}
|
|
17372
|
+
${n}
|
|
17373
|
+
`;
|
|
17374
|
+
}
|
|
17375
|
+
}
|
|
17376
|
+
} }).prompt();
|
|
17377
|
+
};
|
|
17077
17378
|
var Qe = `${import_node_util2.styleText("gray", h)} `;
|
|
17078
17379
|
|
|
17079
17380
|
// ui.ts
|
|
@@ -17285,6 +17586,16 @@ function mergeClaudeSettings(targetDir) {
|
|
|
17285
17586
|
`);
|
|
17286
17587
|
return "merged";
|
|
17287
17588
|
}
|
|
17589
|
+
function settingsHaveOathboundHooks(settingsPath) {
|
|
17590
|
+
if (!import_node_fs.existsSync(settingsPath))
|
|
17591
|
+
return false;
|
|
17592
|
+
try {
|
|
17593
|
+
const settings = JSON.parse(import_node_fs.readFileSync(settingsPath, "utf-8"));
|
|
17594
|
+
return hasOathboundHooks(settings);
|
|
17595
|
+
} catch {
|
|
17596
|
+
return false;
|
|
17597
|
+
}
|
|
17598
|
+
}
|
|
17288
17599
|
|
|
17289
17600
|
// update.ts
|
|
17290
17601
|
var import_node_fs2 = require("node:fs");
|
|
@@ -17554,7 +17865,7 @@ function findSkillsDirs() {
|
|
|
17554
17865
|
}
|
|
17555
17866
|
return results;
|
|
17556
17867
|
}
|
|
17557
|
-
function propagateToProject() {
|
|
17868
|
+
function propagateToProject(version3) {
|
|
17558
17869
|
try {
|
|
17559
17870
|
const cwd = process.cwd();
|
|
17560
17871
|
const localSkills = import_node_path5.join(cwd, ".claude", "skills");
|
|
@@ -17571,7 +17882,7 @@ function propagateToProject() {
|
|
|
17571
17882
|
const raw = import_node_fs5.readFileSync(pkgPath, "utf-8");
|
|
17572
17883
|
const pkg = JSON.parse(raw);
|
|
17573
17884
|
if (!pkg.devDependencies?.oathbound && !pkg.dependencies?.oathbound) {
|
|
17574
|
-
pkg.devDependencies = { ...pkg.devDependencies ?? {}, oathbound:
|
|
17885
|
+
pkg.devDependencies = { ...pkg.devDependencies ?? {}, oathbound: `^${version3}` };
|
|
17575
17886
|
const indent = raw.match(/^(\s+)/m)?.[1]?.length ?? 2;
|
|
17576
17887
|
import_node_fs5.writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + `
|
|
17577
17888
|
`);
|
|
@@ -17643,6 +17954,13 @@ ${TEAL}${BOLD}⬡ oathbound${RESET} ${YELLOW}⚠ Warning:${RESET} skill ${BOLD}"
|
|
|
17643
17954
|
`);
|
|
17644
17955
|
process.exit(0);
|
|
17645
17956
|
}
|
|
17957
|
+
function enforceSkill(skillName, reason, enforcement) {
|
|
17958
|
+
if (enforcement === "warn") {
|
|
17959
|
+
warnSkill(skillName, reason);
|
|
17960
|
+
} else {
|
|
17961
|
+
denySkill(skillName, reason, enforcement);
|
|
17962
|
+
}
|
|
17963
|
+
}
|
|
17646
17964
|
function isExternalSkillAccess(toolName, toolInput, knownDirs, baseName) {
|
|
17647
17965
|
const resolvedDirs = knownDirs.map((d) => import_node_path5.resolve(d));
|
|
17648
17966
|
const isUnderKnownDir = (p) => {
|
|
@@ -17685,7 +18003,7 @@ function parseSkillVersion(skillDir) {
|
|
|
17685
18003
|
return null;
|
|
17686
18004
|
}
|
|
17687
18005
|
}
|
|
17688
|
-
async function verify(supabaseUrl, supabaseAnonKey) {
|
|
18006
|
+
async function verify(supabaseUrl, supabaseAnonKey, version3) {
|
|
17689
18007
|
let input;
|
|
17690
18008
|
try {
|
|
17691
18009
|
input = JSON.parse(await readStdin());
|
|
@@ -17701,7 +18019,7 @@ async function verify(supabaseUrl, supabaseAnonKey) {
|
|
|
17701
18019
|
process.exit(1);
|
|
17702
18020
|
}
|
|
17703
18021
|
const skillsDirs = findSkillsDirs();
|
|
17704
|
-
propagateToProject();
|
|
18022
|
+
propagateToProject(version3);
|
|
17705
18023
|
if (skillsDirs.length === 0) {
|
|
17706
18024
|
const state2 = { verified: {}, rejected: [], ok: true };
|
|
17707
18025
|
import_node_fs5.writeFileSync(sessionStatePath(sessionId), JSON.stringify(state2));
|
|
@@ -17754,11 +18072,11 @@ async function verify(supabaseUrl, supabaseAnonKey) {
|
|
|
17754
18072
|
const warnings = [];
|
|
17755
18073
|
process.stderr.write(`${BRAND} ${TEAL}verifying skills...${RESET}
|
|
17756
18074
|
`);
|
|
17757
|
-
for (const [name, { hash: localHash, version:
|
|
18075
|
+
for (const [name, { hash: localHash, version: version4 }] of Object.entries(localSkills)) {
|
|
17758
18076
|
const versionMap = registryMap.get(name);
|
|
17759
|
-
const entry = versionMap?.get(
|
|
18077
|
+
const entry = versionMap?.get(version4);
|
|
17760
18078
|
if (!entry) {
|
|
17761
|
-
process.stderr.write(`${DIM} ${name}@${
|
|
18079
|
+
process.stderr.write(`${DIM} ${name}@${version4}: ${localHash} (not in registry)${RESET}
|
|
17762
18080
|
`);
|
|
17763
18081
|
if (enforcement === "warn") {
|
|
17764
18082
|
warnings.push({ name, reason: "not in registry" });
|
|
@@ -17767,7 +18085,7 @@ async function verify(supabaseUrl, supabaseAnonKey) {
|
|
|
17767
18085
|
rejected.push({ name, reason: "not in registry" });
|
|
17768
18086
|
}
|
|
17769
18087
|
} else if (localHash !== entry.hash) {
|
|
17770
|
-
process.stderr.write(`${RED} ${name}@${
|
|
18088
|
+
process.stderr.write(`${RED} ${name}@${version4}: ${localHash} ≠ ${entry.hash}${RESET}
|
|
17771
18089
|
`);
|
|
17772
18090
|
if (enforcement === "warn") {
|
|
17773
18091
|
warnings.push({ name, reason: `content hash mismatch (local: ${localHash.slice(0, 8)}…, registry: ${entry.hash.slice(0, 8)}…)` });
|
|
@@ -17776,11 +18094,11 @@ async function verify(supabaseUrl, supabaseAnonKey) {
|
|
|
17776
18094
|
rejected.push({ name, reason: `content hash mismatch (local: ${localHash.slice(0, 8)}…, registry: ${entry.hash.slice(0, 8)}…)` });
|
|
17777
18095
|
}
|
|
17778
18096
|
} else if (enforcement === "audited" && !entry.audited) {
|
|
17779
|
-
process.stderr.write(`${YELLOW} ${name}@${
|
|
18097
|
+
process.stderr.write(`${YELLOW} ${name}@${version4}: ${localHash} (registered but not audited)${RESET}
|
|
17780
18098
|
`);
|
|
17781
18099
|
rejected.push({ name, reason: "no passed audit" });
|
|
17782
18100
|
} else {
|
|
17783
|
-
process.stderr.write(`${GREEN} ${name}@${
|
|
18101
|
+
process.stderr.write(`${GREEN} ${name}@${version4}: ${localHash} ✓${RESET}
|
|
17784
18102
|
`);
|
|
17785
18103
|
verified[name] = localHash;
|
|
17786
18104
|
}
|
|
@@ -17901,27 +18219,15 @@ async function verifyCheck() {
|
|
|
17901
18219
|
process.exit(0);
|
|
17902
18220
|
}
|
|
17903
18221
|
if (!skillDir || !import_node_fs5.existsSync(skillDir) || !import_node_fs5.statSync(skillDir).isDirectory()) {
|
|
17904
|
-
|
|
17905
|
-
warnSkill(baseName, "not installed locally");
|
|
17906
|
-
} else {
|
|
17907
|
-
denySkill(baseName, "not installed locally", enforcement);
|
|
17908
|
-
}
|
|
18222
|
+
enforceSkill(baseName, "not installed locally", enforcement);
|
|
17909
18223
|
}
|
|
17910
18224
|
const currentHash = hashSkillDir(skillDir);
|
|
17911
18225
|
const sessionHash = state.verified[baseName];
|
|
17912
18226
|
if (!sessionHash) {
|
|
17913
|
-
|
|
17914
|
-
warnSkill(baseName, "not verified at session start");
|
|
17915
|
-
} else {
|
|
17916
|
-
denySkill(baseName, "not verified at session start", enforcement);
|
|
17917
|
-
}
|
|
18227
|
+
enforceSkill(baseName, "not verified at session start", enforcement);
|
|
17918
18228
|
}
|
|
17919
18229
|
if (currentHash !== sessionHash) {
|
|
17920
|
-
|
|
17921
|
-
warnSkill(baseName, `modified since session start (${currentHash.slice(0, 8)}… ≠ ${sessionHash.slice(0, 8)}…)`);
|
|
17922
|
-
} else {
|
|
17923
|
-
denySkill(baseName, `modified since session start — tampering detected (${currentHash.slice(0, 8)}… ≠ ${sessionHash.slice(0, 8)}…)`, enforcement);
|
|
17924
|
-
}
|
|
18230
|
+
enforceSkill(baseName, `modified since session start (${currentHash.slice(0, 8)}… ≠ ${sessionHash.slice(0, 8)}…)`, enforcement);
|
|
17925
18231
|
}
|
|
17926
18232
|
process.stderr.write(`${GREEN} ${baseName}: ${currentHash} ✓${RESET}
|
|
17927
18233
|
`);
|
|
@@ -17934,9 +18240,13 @@ var import_node_fs6 = require("node:fs");
|
|
|
17934
18240
|
var import_node_http = require("node:http");
|
|
17935
18241
|
var import_node_path6 = require("node:path");
|
|
17936
18242
|
var import_node_os3 = require("node:os");
|
|
18243
|
+
|
|
18244
|
+
// constants.ts
|
|
17937
18245
|
var SUPABASE_URL = "https://mjnfqagwuewhgwbtrdgs.supabase.co";
|
|
17938
18246
|
var SUPABASE_ANON_KEY = "sb_publishable_T-rk0azNRqAMLLGCyadyhQ_ulk9685n";
|
|
17939
18247
|
var API_BASE = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18248
|
+
|
|
18249
|
+
// auth.ts
|
|
17940
18250
|
var AUTH_DIR = import_node_path6.join(import_node_os3.homedir(), ".oathbound");
|
|
17941
18251
|
var AUTH_FILE = import_node_path6.join(AUTH_DIR, "auth.json");
|
|
17942
18252
|
function saveSession(session) {
|
|
@@ -18072,7 +18382,7 @@ async function getAccessToken() {
|
|
|
18072
18382
|
saveSession({
|
|
18073
18383
|
access_token: data.session.access_token,
|
|
18074
18384
|
refresh_token: data.session.refresh_token,
|
|
18075
|
-
expires_at: data.session.expires_at
|
|
18385
|
+
expires_at: data.session.expires_at ?? Math.floor(Date.now() / 1000) + 3600
|
|
18076
18386
|
});
|
|
18077
18387
|
return data.session.access_token;
|
|
18078
18388
|
}
|
|
@@ -18097,7 +18407,6 @@ ${BRAND}`);
|
|
|
18097
18407
|
var import_node_fs7 = require("node:fs");
|
|
18098
18408
|
var import_node_path7 = require("node:path");
|
|
18099
18409
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
18100
|
-
var API_BASE2 = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18101
18410
|
async function push(pathArg, options) {
|
|
18102
18411
|
Wt2(BRAND);
|
|
18103
18412
|
const skillDir = resolveSkillDir(pathArg);
|
|
@@ -18141,7 +18450,7 @@ async function push(pathArg, options) {
|
|
|
18141
18450
|
console.log(`${DIM} ${files.length} file(s)${RESET}`);
|
|
18142
18451
|
const token = await getAccessToken();
|
|
18143
18452
|
const spin = spinner("Pushing...");
|
|
18144
|
-
const response = await fetch(`${
|
|
18453
|
+
const response = await fetch(`${API_BASE}/api/skills`, {
|
|
18145
18454
|
method: "POST",
|
|
18146
18455
|
headers: {
|
|
18147
18456
|
"Content-Type": "application/json",
|
|
@@ -18195,7 +18504,6 @@ function parseFrontmatter(content) {
|
|
|
18195
18504
|
}
|
|
18196
18505
|
|
|
18197
18506
|
// search.ts
|
|
18198
|
-
var API_BASE3 = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18199
18507
|
function parseSearchArgs(args) {
|
|
18200
18508
|
const opts = {};
|
|
18201
18509
|
let i = 0;
|
|
@@ -18234,7 +18542,7 @@ async function search(opts) {
|
|
|
18234
18542
|
params.set("limit", String(opts.limit));
|
|
18235
18543
|
if (opts.offset != null)
|
|
18236
18544
|
params.set("offset", String(opts.offset));
|
|
18237
|
-
const url = `${
|
|
18545
|
+
const url = `${API_BASE}/api/skills?${params}`;
|
|
18238
18546
|
const sp = spinner("Searching...");
|
|
18239
18547
|
let res;
|
|
18240
18548
|
try {
|
|
@@ -18307,7 +18615,6 @@ ${BRAND} ${TEAL}${showing}${RESET}
|
|
|
18307
18615
|
var import_node_fs8 = require("node:fs");
|
|
18308
18616
|
var import_node_path8 = require("node:path");
|
|
18309
18617
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
18310
|
-
var API_BASE4 = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18311
18618
|
function parseAgentFrontmatter(content) {
|
|
18312
18619
|
const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
18313
18620
|
if (!match)
|
|
@@ -18409,7 +18716,7 @@ async function agentPush(pathArg, options) {
|
|
|
18409
18716
|
visibility
|
|
18410
18717
|
};
|
|
18411
18718
|
const spin = spinner("Pushing...");
|
|
18412
|
-
const response = await fetch(`${
|
|
18719
|
+
const response = await fetch(`${API_BASE}/api/agents`, {
|
|
18413
18720
|
method: "POST",
|
|
18414
18721
|
headers: {
|
|
18415
18722
|
"Content-Type": "application/json",
|
|
@@ -18433,7 +18740,6 @@ async function agentPush(pathArg, options) {
|
|
|
18433
18740
|
}
|
|
18434
18741
|
|
|
18435
18742
|
// agent-search.ts
|
|
18436
|
-
var API_BASE5 = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18437
18743
|
function parseAgentSearchArgs(args) {
|
|
18438
18744
|
const opts = {};
|
|
18439
18745
|
let i = 0;
|
|
@@ -18472,7 +18778,7 @@ async function agentSearch(opts) {
|
|
|
18472
18778
|
params.set("limit", String(opts.limit));
|
|
18473
18779
|
if (opts.offset != null)
|
|
18474
18780
|
params.set("offset", String(opts.offset));
|
|
18475
|
-
const url = `${
|
|
18781
|
+
const url = `${API_BASE}/api/agents?${params}`;
|
|
18476
18782
|
const sp = spinner("Searching agents...");
|
|
18477
18783
|
let res;
|
|
18478
18784
|
try {
|
|
@@ -18544,10 +18850,7 @@ ${BRAND} ${TEAL}${showing}${RESET}
|
|
|
18544
18850
|
}
|
|
18545
18851
|
}
|
|
18546
18852
|
// cli.ts
|
|
18547
|
-
var VERSION = "0.
|
|
18548
|
-
var SUPABASE_URL2 = "https://mjnfqagwuewhgwbtrdgs.supabase.co";
|
|
18549
|
-
var SUPABASE_ANON_KEY2 = "sb_publishable_T-rk0azNRqAMLLGCyadyhQ_ulk9685n";
|
|
18550
|
-
var API_BASE6 = process.env.OATHBOUND_API_URL ?? "https://www.oathbound.ai";
|
|
18853
|
+
var VERSION = "0.17.1";
|
|
18551
18854
|
function parseSkillArg(arg) {
|
|
18552
18855
|
const slash = arg.indexOf("/");
|
|
18553
18856
|
if (slash < 1 || slash === arg.length - 1)
|
|
@@ -18686,15 +18989,49 @@ async function init(options = {}) {
|
|
|
18686
18989
|
}
|
|
18687
18990
|
Gt(`\uD83C\uDF89 Oath Bound set up complete!`);
|
|
18688
18991
|
}
|
|
18992
|
+
async function ensureInitialized() {
|
|
18993
|
+
const globalSettings = import_node_path9.join(import_node_os4.homedir(), ".claude", "settings.json");
|
|
18994
|
+
const localSettings = import_node_path9.join(process.cwd(), ".claude", "settings.json");
|
|
18995
|
+
if (settingsHaveOathboundHooks(globalSettings) || settingsHaveOathboundHooks(localSettings)) {
|
|
18996
|
+
return;
|
|
18997
|
+
}
|
|
18998
|
+
if (!process.stdin.isTTY) {
|
|
18999
|
+
process.stderr.write("oathbound: no hooks configured. Run `npx oathbound init` first.\n");
|
|
19000
|
+
process.exit(1);
|
|
19001
|
+
}
|
|
19002
|
+
process.stderr.write(`
|
|
19003
|
+
${BRAND} ${YELLOW}No oathbound hooks detected.${RESET}
|
|
19004
|
+
`);
|
|
19005
|
+
process.stderr.write(`${DIM} Hooks verify skills on every Claude Code session.${RESET}
|
|
19006
|
+
|
|
19007
|
+
`);
|
|
19008
|
+
const scope = await Jt({
|
|
19009
|
+
message: "Where should oathbound install hooks?",
|
|
19010
|
+
options: [
|
|
19011
|
+
{ value: "both", label: "Global + this project", hint: "recommended" },
|
|
19012
|
+
{ value: "global", label: "Global only", hint: "~/.claude/settings.json" },
|
|
19013
|
+
{ value: "local", label: "This project only", hint: ".claude/settings.json" }
|
|
19014
|
+
]
|
|
19015
|
+
});
|
|
19016
|
+
if (Ct(scope)) {
|
|
19017
|
+
Nt("Pull cancelled.");
|
|
19018
|
+
process.exit(1);
|
|
19019
|
+
}
|
|
19020
|
+
if (scope === "both" || scope === "global")
|
|
19021
|
+
initGlobal();
|
|
19022
|
+
if (scope === "both" || scope === "local")
|
|
19023
|
+
await initLocal();
|
|
19024
|
+
}
|
|
18689
19025
|
async function pull(skillArg, options = {}) {
|
|
18690
19026
|
const parsed = parseSkillArg(skillArg);
|
|
18691
19027
|
if (!parsed)
|
|
18692
19028
|
usage();
|
|
18693
19029
|
const { namespace, name, version: version3 } = parsed;
|
|
18694
19030
|
const fullName = `${namespace}/${name}`;
|
|
19031
|
+
await ensureInitialized();
|
|
18695
19032
|
console.log(`
|
|
18696
19033
|
${BRAND} ${TEAL}↓ Pulling ${fullName}${version3 ? `@${version3}` : ""}...${RESET}`);
|
|
18697
|
-
const supabase = createClient(
|
|
19034
|
+
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
18698
19035
|
let skill;
|
|
18699
19036
|
if (version3 !== null) {
|
|
18700
19037
|
const { data, error } = await supabase.from("skills").select("id, name, namespace, version, tar_hash, storage_path").eq("namespace", namespace).eq("name", name).eq("version", version3).single();
|
|
@@ -18748,7 +19085,7 @@ ${BRAND} ${TEAL}↓ Pulling ${fullName}${version3 ? `@${version3}` : ""}...${RES
|
|
|
18748
19085
|
}
|
|
18749
19086
|
import_node_fs9.unlinkSync(tarFile);
|
|
18750
19087
|
try {
|
|
18751
|
-
const trackRes = await fetch(`${
|
|
19088
|
+
const trackRes = await fetch(`${API_BASE}/api/downloads`, {
|
|
18752
19089
|
method: "POST",
|
|
18753
19090
|
headers: { "Content-Type": "application/json" },
|
|
18754
19091
|
body: JSON.stringify({ skill_id: skill.id, version: skill.version })
|
|
@@ -18770,7 +19107,7 @@ async function agentPull(agentArg) {
|
|
|
18770
19107
|
const fullName = `${namespace}/${name}`;
|
|
18771
19108
|
console.log(`
|
|
18772
19109
|
${BRAND} ${TEAL}↓ Pulling agent ${fullName}${version3 ? `@${version3}` : ""}...${RESET}`);
|
|
18773
|
-
const supabase = createClient(
|
|
19110
|
+
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
|
|
18774
19111
|
let agent;
|
|
18775
19112
|
if (version3 !== null) {
|
|
18776
19113
|
const { data, error } = await supabase.from("agents").select("id, name, namespace, version, content_hash, storage_path, config").eq("namespace", namespace).eq("name", name).eq("version", version3).single();
|
|
@@ -18833,7 +19170,7 @@ ${YELLOW}${BOLD} ⚠ This agent defines MCP servers (external connections):${RES
|
|
|
18833
19170
|
}
|
|
18834
19171
|
import_node_fs9.writeFileSync(targetPath, content);
|
|
18835
19172
|
try {
|
|
18836
|
-
const trackRes = await fetch(`${
|
|
19173
|
+
const trackRes = await fetch(`${API_BASE}/api/downloads`, {
|
|
18837
19174
|
method: "POST",
|
|
18838
19175
|
headers: { "Content-Type": "application/json" },
|
|
18839
19176
|
body: JSON.stringify({ agent_id: agent.id, version: agent.version })
|
|
@@ -18898,7 +19235,7 @@ if (require.main == module) {
|
|
|
18898
19235
|
setup();
|
|
18899
19236
|
} else if (subcommand === "verify") {
|
|
18900
19237
|
const isCheck = args.includes("--check");
|
|
18901
|
-
const run = isCheck ? verifyCheck : () => verify(
|
|
19238
|
+
const run = isCheck ? verifyCheck : () => verify(SUPABASE_URL, SUPABASE_ANON_KEY, VERSION);
|
|
18902
19239
|
await run().catch((err) => {
|
|
18903
19240
|
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
18904
19241
|
process.stderr.write(`oathbound verify: ${msg}
|