attestari 0.0.0-stage → 2.9.0
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/LICENSE +21 -0
- package/README.md +55 -2
- package/dist/hook.js +2416 -0
- package/package.json +29 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 The Elite360 Corporation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,56 @@
|
|
|
1
|
-
#
|
|
1
|
+
# attestari
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Attestari Protect hook: the one file each agent (Claude Code first) runs itself.
|
|
4
|
+
|
|
5
|
+
- `dist/hook.js` is the whole hook. It is built from `src/` by esbuild, committed, and has no runtime
|
|
6
|
+
dependency: it requires only Node's own modules (`node:fs`, `node:path`, `node:os`, and the like).
|
|
7
|
+
- Build: `npm install && npm run build`. Test: `npm test` (builds, then runs `node --test` on the built file).
|
|
8
|
+
Type check: `npm run check`.
|
|
9
|
+
- `node dist/hook.js status` prints each agent folder under `~/.attestari/`; every unbuilt subcommand exits 2.
|
|
10
|
+
- Built for Claude Code: `pair --code <code>`, `claude-code session-start` (resolves the configured servers of its
|
|
11
|
+
folder and starts the check-in detached), `claude-code refresh` (the check-in: the policy, the events,
|
|
12
|
+
and the agent's own `deniedMcpServers` entries) and `claude-code pre-tool-use` (decides each MCP call, and starts the
|
|
13
|
+
refresh when the last check-in is over an hour old). `ATTESTARI_ACCOUNTS_URL` points the hook at another accounts
|
|
14
|
+
service only on loopback (`127.0.0.1`, `::1`, `localhost`: the tests' local server); any other address is ignored
|
|
15
|
+
with one line on stderr.
|
|
16
|
+
- What it resolves: `npx`/`bunx`/`pnpx`/`pnpm dlx`/`yarn dlx` an npm package, `uvx`/`pipx run` a PyPI package, a URL a
|
|
17
|
+
remote, any other command (`docker`, `node file.js`, an executable) a local tool. A registry runner whose package
|
|
18
|
+
it cannot name (an alias, a git, tarball, file or URL spec, a second package, `${PKG}`, or any flag but `-y`,
|
|
19
|
+
`--yes`, `-q`, `--quiet`, `-p`/`--package`, uvx's `--from`, `--python` and `-p` (python) and pipx's `--spec`) is left out of the resolution,
|
|
20
|
+
reported to nobody, and denied as not checked, never a local tool; stderr says "its package could not be named"
|
|
21
|
+
with the key.
|
|
22
|
+
- What it keeps, under `~/.attestari/claude-code/`: `token`, `secret` (the key of a local tool's hash), `policy.json`
|
|
23
|
+
and `policy.etag`, `resolved/<folder>.json` and `written/<folder>.json` (per working folder: `<folder>` is the first
|
|
24
|
+
16 hexadecimal characters of the SHA-256 of the session's `cwd`; the resolution holds the folder's path, and both
|
|
25
|
+
are dropped at a check-in once the folder is gone or its resolution was not rewritten by a session start for 30
|
|
26
|
+
days, its deny entries taken back when it was read whole), `sessions/<session_id>` (the folder a session
|
|
27
|
+
started in, its id and path, written at SessionStart; pruned after 30 days at a check-in), `events.jsonl`, and the
|
|
28
|
+
times `checked_in_at`, `refresh_started_at` (with the refresh's process id) and `next_refresh_at`. A call is decided
|
|
29
|
+
by the `resolved/` file of its session's start folder (the call's `cwd` follows Claude's `cd`; it is used only when
|
|
30
|
+
the session has no file); the check-in reports the union of them all, a key launching different packages in two folders
|
|
31
|
+
once per folder as `<key>/<8 hex of the folder's hash>`. `refresh --cwd <folder>` resolves that folder first when
|
|
32
|
+
it has no file yet. A check-in answered 401 `invalid_token` (the agent was removed) deletes `token`, `policy.json`
|
|
33
|
+
and `policy.etag`, so every MCP call is then denied until the agent is paired again; the deny entries are written
|
|
34
|
+
only when `~/.claude/settings.json` is unchanged between the reading and the rename.
|
|
35
|
+
- The build also copies `dist/hook.js` to `plugins/attestari/hooks/hook.js`, the Claude Code plugin's copy (the
|
|
36
|
+
marketplace is `plugins/`); `test/build.test.mjs` refuses a difference, and CI refuses a committed copy older than
|
|
37
|
+
the build. `pair` installs the plugin when `claude` is on the PATH (`claude plugin marketplace add
|
|
38
|
+
attestari-ai/plugins`, then `claude plugin install attestari@attestari --scope user`; `ATTESTARI_MARKETPLACE` names
|
|
39
|
+
another marketplace, such as a local `plugins/` folder) and otherwise prints the two commands. What the hook reads
|
|
40
|
+
and writes on a computer: `docs/app.attestari.ai/hook.md`.
|
|
41
|
+
- The build also makes `dist/gateway.js` (from `src/gateway-main.ts`; not committed itself, but copied byte for byte to
|
|
42
|
+
`extension/server/gateway.js`, which is, and packed into `attestari.mcpb` by `npm run pack:extension`): the Claude
|
|
43
|
+
Desktop extension's gateway (M2.5), one MCP server on stdio that starts the child servers it is given, in the home
|
|
44
|
+
folder, and relays them under `<key>__`, with its own `attestari_status` tool. Run with no argument (as Claude
|
|
45
|
+
Desktop runs it) it first runs a provisional plan from the policy held (no network call before `initialize` is
|
|
46
|
+
answered), then pairs by `ATTESTARI_INSTALL_CODE`, checks in as `Claude Desktop`, decides from the policy which
|
|
47
|
+
servers of `~/.attestari/claude-desktop/servers.json` to start (`desktop.ts`), and checks in again hourly, stopping
|
|
48
|
+
and starting children as the policy moves; `checkin.ts` is the check-in it makes (session.ts's refresh without the
|
|
49
|
+
Claude Code parts; session.ts keeps its own copy so `dist/hook.js` does not move). `--servers <file>` runs it on a
|
|
50
|
+
`{servers, refused, notice}` file instead, bypassing the policy, and only with `ATTESTARI_GATEWAY_UNSAFE_FILE=1` and
|
|
51
|
+
a loopback `ATTESTARI_ACCOUNTS_URL` (the tests'; the same condition holds for `ATTESTARI_GATEWAY_REFRESH_MS`). Once
|
|
52
|
+
paired it moves Claude Desktop's own servers (`claude_desktop_config.json`'s `mcpServers`) into `servers.json` when
|
|
53
|
+
`ATTESTARI_MOVE_SERVERS` is `"true"`, with a dated backup beside the config, and puts them back when it is `"false"`
|
|
54
|
+
(`adapters/claude-desktop.ts`). What it reads, sends and writes: `docs/app.attestari.ai/hook.md`,
|
|
55
|
+
"Claude Desktop".
|
|
56
|
+
- The sources, the tests and the built file are LF everywhere.
|