aquaman-coder 0.12.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 +126 -0
- package/dist/adapters/claude-code/hook.d.ts +65 -0
- package/dist/adapters/claude-code/hook.d.ts.map +1 -0
- package/dist/adapters/claude-code/hook.js +161 -0
- package/dist/adapters/claude-code/hook.js.map +1 -0
- package/dist/adapters/claude-code/setup.d.ts +41 -0
- package/dist/adapters/claude-code/setup.d.ts.map +1 -0
- package/dist/adapters/claude-code/setup.js +102 -0
- package/dist/adapters/claude-code/setup.js.map +1 -0
- package/dist/broker-client.d.ts +39 -0
- package/dist/broker-client.d.ts.map +1 -0
- package/dist/broker-client.js +94 -0
- package/dist/broker-client.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +368 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/projects.d.ts +47 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +124 -0
- package/dist/projects.js.map +1 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tech4242
|
|
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
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# aquaman-coder
|
|
2
|
+
|
|
3
|
+
**Vault adapter for AI coding agents.** Keep API keys, secrets, and `.env` contents out of your coding agent's memory and transcripts.
|
|
4
|
+
|
|
5
|
+
Pair with [`aquaman-proxy`](../proxy) (the vault + daemon + audit core). Together: `aquaman-proxy` holds credentials in a separate process; `aquaman-coder` hooks into your coding agent so per-tool-call commands get credentials materialized over UDS, run with output redacted, and the agent never sees raw keys.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
1. **Inject vault-backed credentials per Bash tool call.** No `.env` files in your project. The agent runs `gh pr list` → the hook rewrites the command to wrap it under `aquaman-coder exec --` → that wrapper fetches `GH_TOKEN` from the vault, injects it into the subprocess env, runs, and exits. The agent's own process never sees the credential.
|
|
10
|
+
2. **Redact secrets from tool output.** `aquaman-coder exec` pipes stdout/stderr through a pattern redactor before printing — secret-shaped strings (AWS, GitHub, Stripe, Slack, OpenAI, Anthropic, JWTs, PEM private keys) become `[REDACTED:kind]` before they enter the agent's transcript.
|
|
11
|
+
3. **Stay isolated from the proxy.** `aquaman-coder` only talks to `aquaman-proxy` over `~/.aquaman/proxy.sock` (UDS, `chmod 0o600`) via the broker endpoint `POST /broker/resolve`. No shared memory, no network exposure.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g aquaman-proxy aquaman-coder
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Requires `aquaman-proxy` (same version) running as a daemon — start it once per machine session with `aquaman daemon &` (or have it managed by your shell's init).
|
|
20
|
+
|
|
21
|
+
## Quick Start (Claude Code)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
aquaman setup # vault wizard (one-time)
|
|
25
|
+
aquaman daemon & # start the proxy
|
|
26
|
+
|
|
27
|
+
aquaman coder project add my-app --path ~/code/my-app \
|
|
28
|
+
--env ANTHROPIC_API_KEY=aquaman://anthropic/api_key \
|
|
29
|
+
--env GITHUB_TOKEN=aquaman://github/token
|
|
30
|
+
aquaman coder setup claude-code # install hook in ~/.claude/settings.json
|
|
31
|
+
aquaman coder doctor # verify
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**See it for yourself (the 30-second aha):** restart Claude Code, open a new session inside `~/code/my-app`, and ask the agent to run:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
printenv | grep ANTHROPIC_API_KEY
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
You'll see this in the transcript:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
ANTHROPIC_API_KEY=[REDACTED:injected-value]
|
|
44
|
+
|
|
45
|
+
⏺ ANTHROPIC_API_KEY is set and available (injected via aquaman vault).
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The *child* process saw the real key (your tests, builds, MCP servers, import scripts — anything that actually needs it works). The *agent* — the thing that decides what code to run on your machine — never sees the value, and so neither does the conversation history, neither does the model provider's logs, neither does anyone who later screenshots your terminal.
|
|
49
|
+
|
|
50
|
+
When Claude Code runs a Bash tool in `~/code/my-app`, aquaman's hook rewrites the command via `updatedInput.command` to wrap it under `aquaman-coder exec`. That wrapper:
|
|
51
|
+
|
|
52
|
+
- Resolves each `aquaman://service/key` reference via the broker (`POST /broker/resolve` over UDS) — credentials are materialized for one command, not for the agent's lifetime.
|
|
53
|
+
- Pipes stdout/stderr through a redactor that prepends a value-based pattern for each resolved value: **whatever string was injected gets redacted, regardless of shape** (Atlassian tokens, Notion secrets, internal-API keys — none of them need to match a known provider format). Generic shape-based patterns (sk-ant-, ghp_, sk_live_, AKIA…, JWTs, PEM blocks, ATATT3xF…) still run after as defense-in-depth for secrets the child surfaces that we did NOT inject.
|
|
54
|
+
- Cleans up when the command exits.
|
|
55
|
+
|
|
56
|
+
## CLI surface
|
|
57
|
+
|
|
58
|
+
The unified CLI lives in `aquaman-proxy` and delegates `coder` subcommands here:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
aquaman coder
|
|
62
|
+
├── setup <agent> Install hooks for an agent (claude-code today)
|
|
63
|
+
├── doctor Deep diagnostic — projects, broker, per-project vault checks
|
|
64
|
+
├── status Configured projects + hook wiring + broker connectivity
|
|
65
|
+
├── project list/add/remove ~/.aquaman/projects.yaml CRUD
|
|
66
|
+
├── get <ref> Resolve an aquaman://service/key reference once
|
|
67
|
+
├── exec <cmd> [args...] Run a command with project env injected + output redacted
|
|
68
|
+
└── hook Stdio hook handler (invoked by Claude Code; not user-facing)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The `aquaman-coder` binary works directly too — `aquaman coder X` ≡ `aquaman-coder X`. The unified form is the documented one; the standalone binary is what Claude Code's hook contract executes per tool call (faster, skips the shim).
|
|
72
|
+
|
|
73
|
+
## Architecture
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
Claude Code / Codex / OpenCode / Cursor
|
|
77
|
+
│ hook stdin/stdout JSON
|
|
78
|
+
▼
|
|
79
|
+
aquaman-coder (this package)
|
|
80
|
+
│ HTTP over UDS
|
|
81
|
+
▼
|
|
82
|
+
aquaman-proxy daemon
|
|
83
|
+
│
|
|
84
|
+
▼
|
|
85
|
+
Vault backends (Keychain, 1Password, HashiCorp Vault, KeePassXC,
|
|
86
|
+
encrypted-file, systemd-creds, Bitwarden)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The hook uses Claude Code's real protocol (verified against the live docs):
|
|
90
|
+
|
|
91
|
+
- **PreToolUse** on Bash: emits `{ hookSpecificOutput: { permissionDecision: "allow", updatedInput: { command: "aquaman-coder exec -- sh -c '...'" } } }`. Claude Code runs the rewritten command in its child shell; the wrapper does the broker resolve.
|
|
92
|
+
- **PostToolUse**: emits `{ hookSpecificOutput: { additionalContext: "aquaman: tool output contained secret patterns…" } }` if the redactor finds secrets in the output. Note: PostToolUse can't *rewrite* output (the tool already ran) — real scrubbing happens inside `aquaman-coder exec`'s stdout pipeline. PostToolUse is purely an alert.
|
|
93
|
+
|
|
94
|
+
See [`docs/PACKAGES.md`](../../docs/PACKAGES.md) for cross-package import rules.
|
|
95
|
+
|
|
96
|
+
## projects.yaml
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
# ~/.aquaman/projects.yaml
|
|
100
|
+
version: 1
|
|
101
|
+
projects:
|
|
102
|
+
my-app:
|
|
103
|
+
paths:
|
|
104
|
+
- ~/code/my-app
|
|
105
|
+
env:
|
|
106
|
+
ANTHROPIC_API_KEY: aquaman://anthropic/api_key
|
|
107
|
+
GITHUB_TOKEN: aquaman://github/token
|
|
108
|
+
DATABASE_URL: aquaman://supabase/db_url
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Each project owns one or more filesystem paths. When the agent runs a Bash tool whose `cwd` matches a project path (longest-prefix wins), every `aquaman://service/key` reference is resolved via the broker and injected into the subprocess env.
|
|
112
|
+
|
|
113
|
+
The file is `chmod 0o600`. Both the service and key components are validated against safe regexes before any broker lookup.
|
|
114
|
+
|
|
115
|
+
## Adapter status
|
|
116
|
+
|
|
117
|
+
| Adapter | Status | Release |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Claude Code | shipped | v0.12.0 |
|
|
120
|
+
| Codex CLI | planned | v0.13.0 |
|
|
121
|
+
| OpenCode (sst) | planned | v0.14.0 |
|
|
122
|
+
| Cursor | planned | v0.15.0 |
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hook handler.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code's hook protocol (verified against https://code.claude.com/docs/en/hooks):
|
|
5
|
+
* - The hook receives a JSON event on stdin.
|
|
6
|
+
* - Structured decisions: write JSON to stdout, exit 0.
|
|
7
|
+
* - Blocking errors: write a message to stderr, exit 2.
|
|
8
|
+
*
|
|
9
|
+
* PreToolUse hookSpecificOutput supports `permissionDecision`,
|
|
10
|
+
* `permissionDecisionReason`, `updatedInput`, and `additionalContext`.
|
|
11
|
+
* There is NO env-injection API on PreToolUse — to scope credentials
|
|
12
|
+
* to a single tool call we rewrite the Bash command itself via
|
|
13
|
+
* `updatedInput.command` to invoke it under `aquaman-coder exec`,
|
|
14
|
+
* which runs the broker resolve + redaction pipeline server-side.
|
|
15
|
+
*
|
|
16
|
+
* PostToolUse hookSpecificOutput only supports `additionalContext` and
|
|
17
|
+
* cannot mutate the tool output (the tool has already run). When the
|
|
18
|
+
* redactor finds secrets we emit a warning notice via additionalContext
|
|
19
|
+
* — the actual scrubbing must happen inside `aquaman-coder exec` itself
|
|
20
|
+
* so leaked secrets never reach the model.
|
|
21
|
+
*/
|
|
22
|
+
import { BrokerClient } from '../../broker-client.js';
|
|
23
|
+
export interface HookEvent {
|
|
24
|
+
hook_event_name?: string;
|
|
25
|
+
tool_name?: string;
|
|
26
|
+
tool_input?: Record<string, unknown>;
|
|
27
|
+
tool_response?: unknown;
|
|
28
|
+
cwd?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface HookDecision {
|
|
31
|
+
hookSpecificOutput?: Record<string, unknown>;
|
|
32
|
+
decision?: 'block' | 'approve';
|
|
33
|
+
reason?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface HookContext {
|
|
36
|
+
/** Override for testing. Defaults to BrokerClient with default UDS. */
|
|
37
|
+
broker?: BrokerClient;
|
|
38
|
+
/** Override projects.yaml path for testing. */
|
|
39
|
+
projectsPath?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Wrapper command prefix injected into Bash commands. Default
|
|
42
|
+
* `aquaman-coder exec --` — change in tests to assert the rewrite.
|
|
43
|
+
*/
|
|
44
|
+
wrapperPrefix?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* If the project map has env bindings AND this is a Bash tool call AND
|
|
48
|
+
* the command isn't already wrapped, rewrite it to run under the
|
|
49
|
+
* `aquaman-coder exec` wrapper. The wrapper resolves env via the broker
|
|
50
|
+
* and pipes stdout/stderr through the redactor.
|
|
51
|
+
*/
|
|
52
|
+
export declare function handlePreToolUse(event: HookEvent, ctx?: HookContext): Promise<HookDecision | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Inspect tool output for leaked secrets. Cannot rewrite — the tool has
|
|
55
|
+
* already run — but we surface a warning to Claude via additionalContext.
|
|
56
|
+
* Pair with `aquaman-coder exec`'s stdout/stderr redactor for real
|
|
57
|
+
* prevention.
|
|
58
|
+
*/
|
|
59
|
+
export declare function handlePostToolUse(event: HookEvent): HookDecision | null;
|
|
60
|
+
/**
|
|
61
|
+
* Stdio entry point: read JSON from stdin, dispatch by hook_event_name,
|
|
62
|
+
* write decision to stdout (exit 0) or error to stderr (exit 2).
|
|
63
|
+
*/
|
|
64
|
+
export declare function runHookFromStdin(_argv: string[], ctx?: HookContext): Promise<number>;
|
|
65
|
+
//# sourceMappingURL=hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/adapters/claude-code/hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAUD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAChB,GAAG,GAAE,WAAgB,GACpB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmD9B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,YAAY,GAAG,IAAI,CAmBvE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,GAAE,WAAgB,GACpB,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hook handler.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code's hook protocol (verified against https://code.claude.com/docs/en/hooks):
|
|
5
|
+
* - The hook receives a JSON event on stdin.
|
|
6
|
+
* - Structured decisions: write JSON to stdout, exit 0.
|
|
7
|
+
* - Blocking errors: write a message to stderr, exit 2.
|
|
8
|
+
*
|
|
9
|
+
* PreToolUse hookSpecificOutput supports `permissionDecision`,
|
|
10
|
+
* `permissionDecisionReason`, `updatedInput`, and `additionalContext`.
|
|
11
|
+
* There is NO env-injection API on PreToolUse — to scope credentials
|
|
12
|
+
* to a single tool call we rewrite the Bash command itself via
|
|
13
|
+
* `updatedInput.command` to invoke it under `aquaman-coder exec`,
|
|
14
|
+
* which runs the broker resolve + redaction pipeline server-side.
|
|
15
|
+
*
|
|
16
|
+
* PostToolUse hookSpecificOutput only supports `additionalContext` and
|
|
17
|
+
* cannot mutate the tool output (the tool has already run). When the
|
|
18
|
+
* redactor finds secrets we emit a warning notice via additionalContext
|
|
19
|
+
* — the actual scrubbing must happen inside `aquaman-coder exec` itself
|
|
20
|
+
* so leaked secrets never reach the model.
|
|
21
|
+
*/
|
|
22
|
+
// Note: imported from `aquaman-proxy` (which re-exports from its
|
|
23
|
+
// merged core/). There is no separate `aquaman-core` npm package since
|
|
24
|
+
// v0.7.0; the vitest alias resolves the same path for tests.
|
|
25
|
+
import { redact } from 'aquaman-proxy';
|
|
26
|
+
import { findProjectForCwd, loadProjects } from '../../projects.js';
|
|
27
|
+
import { BrokerClient } from '../../broker-client.js';
|
|
28
|
+
// Default wrapper uses the direct binary form (`aquaman-coder exec`) rather
|
|
29
|
+
// than the unified-CLI form (`aquaman coder exec`) to skip the shim's
|
|
30
|
+
// process-spawn overhead on every Bash tool call. Both forms work; the
|
|
31
|
+
// rewrite check below matches either so manually-wrapped commands aren't
|
|
32
|
+
// double-wrapped.
|
|
33
|
+
const DEFAULT_WRAPPER = 'aquaman-coder exec --';
|
|
34
|
+
const AQUAMAN_WRAPPER_MARKS = ['aquaman-coder exec', 'aquaman coder exec'];
|
|
35
|
+
/**
|
|
36
|
+
* If the project map has env bindings AND this is a Bash tool call AND
|
|
37
|
+
* the command isn't already wrapped, rewrite it to run under the
|
|
38
|
+
* `aquaman-coder exec` wrapper. The wrapper resolves env via the broker
|
|
39
|
+
* and pipes stdout/stderr through the redactor.
|
|
40
|
+
*/
|
|
41
|
+
export async function handlePreToolUse(event, ctx = {}) {
|
|
42
|
+
if (event.tool_name !== 'Bash')
|
|
43
|
+
return null;
|
|
44
|
+
const cwd = event.cwd || process.cwd();
|
|
45
|
+
const projects = loadProjects(ctx.projectsPath);
|
|
46
|
+
const match = findProjectForCwd(cwd, projects);
|
|
47
|
+
if (!match)
|
|
48
|
+
return null;
|
|
49
|
+
// No env bindings → nothing for the wrapper to inject; skip.
|
|
50
|
+
if (Object.keys(match.config.env).length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
const command = String(event.tool_input?.command ?? '');
|
|
53
|
+
if (!command)
|
|
54
|
+
return null;
|
|
55
|
+
// Avoid wrapping ourselves recursively.
|
|
56
|
+
if (AQUAMAN_WRAPPER_MARKS.some((m) => command.includes(m)))
|
|
57
|
+
return null;
|
|
58
|
+
// Quick health check on the broker — if the proxy isn't running, deny
|
|
59
|
+
// loudly so the user knows the credentials won't be available.
|
|
60
|
+
const broker = ctx.broker ?? new BrokerClient();
|
|
61
|
+
try {
|
|
62
|
+
await broker.health();
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return {
|
|
66
|
+
hookSpecificOutput: {
|
|
67
|
+
hookEventName: 'PreToolUse',
|
|
68
|
+
permissionDecision: 'deny',
|
|
69
|
+
permissionDecisionReason: `aquaman: proxy not reachable (${err.message}). ` +
|
|
70
|
+
`Start it with: aquaman daemon`,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const wrapper = ctx.wrapperPrefix ?? DEFAULT_WRAPPER;
|
|
75
|
+
const wrapped = `${wrapper} sh -c ${shellQuote(command)}`;
|
|
76
|
+
return {
|
|
77
|
+
hookSpecificOutput: {
|
|
78
|
+
hookEventName: 'PreToolUse',
|
|
79
|
+
permissionDecision: 'allow',
|
|
80
|
+
updatedInput: {
|
|
81
|
+
...event.tool_input,
|
|
82
|
+
command: wrapped,
|
|
83
|
+
},
|
|
84
|
+
additionalContext: `aquaman: wrapped command under \`${wrapper}\` so credentials ` +
|
|
85
|
+
`(${Object.keys(match.config.env).join(', ')}) are injected ` +
|
|
86
|
+
`from the vault only for the duration of this command.`,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Inspect tool output for leaked secrets. Cannot rewrite — the tool has
|
|
92
|
+
* already run — but we surface a warning to Claude via additionalContext.
|
|
93
|
+
* Pair with `aquaman-coder exec`'s stdout/stderr redactor for real
|
|
94
|
+
* prevention.
|
|
95
|
+
*/
|
|
96
|
+
export function handlePostToolUse(event) {
|
|
97
|
+
const out = event.tool_response ?? event.tool_output;
|
|
98
|
+
if (out === undefined || out === null)
|
|
99
|
+
return null;
|
|
100
|
+
const text = typeof out === 'string' ? out : JSON.stringify(out);
|
|
101
|
+
const { findings } = redact(text);
|
|
102
|
+
if (findings.length === 0)
|
|
103
|
+
return null;
|
|
104
|
+
const summary = findings.map((f) => `${f.kind}×${f.count}`).join(', ');
|
|
105
|
+
return {
|
|
106
|
+
hookSpecificOutput: {
|
|
107
|
+
hookEventName: 'PostToolUse',
|
|
108
|
+
additionalContext: `aquaman: tool output contained secret patterns (${summary}). ` +
|
|
109
|
+
`These were detected after the fact — to scrub before output ` +
|
|
110
|
+
`reaches the model, ensure agent-invoked commands route through ` +
|
|
111
|
+
`\`aquaman-coder exec\`.`,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Stdio entry point: read JSON from stdin, dispatch by hook_event_name,
|
|
117
|
+
* write decision to stdout (exit 0) or error to stderr (exit 2).
|
|
118
|
+
*/
|
|
119
|
+
export async function runHookFromStdin(_argv, ctx = {}) {
|
|
120
|
+
let stdin = '';
|
|
121
|
+
for await (const chunk of process.stdin) {
|
|
122
|
+
stdin += chunk;
|
|
123
|
+
}
|
|
124
|
+
let event;
|
|
125
|
+
try {
|
|
126
|
+
event = JSON.parse(stdin);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
process.stderr.write(`aquaman-coder: malformed hook input: ${err.message}\n`);
|
|
130
|
+
return 2;
|
|
131
|
+
}
|
|
132
|
+
let decision = null;
|
|
133
|
+
try {
|
|
134
|
+
switch (event.hook_event_name) {
|
|
135
|
+
case 'PreToolUse':
|
|
136
|
+
decision = await handlePreToolUse(event, ctx);
|
|
137
|
+
break;
|
|
138
|
+
case 'PostToolUse':
|
|
139
|
+
decision = handlePostToolUse(event);
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
process.stderr.write(`aquaman-coder: hook failed: ${err.message}\n`);
|
|
147
|
+
return 2;
|
|
148
|
+
}
|
|
149
|
+
if (!decision)
|
|
150
|
+
return 0;
|
|
151
|
+
process.stdout.write(JSON.stringify(decision));
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* POSIX single-quote-safe shell escape. Single quotes inside become
|
|
156
|
+
* `'\''` per the standard idiom.
|
|
157
|
+
*/
|
|
158
|
+
function shellQuote(s) {
|
|
159
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code setup — writes the hook configuration into
|
|
3
|
+
* `~/.claude/settings.json` so Claude Code invokes aquaman-coder on
|
|
4
|
+
* each tool call.
|
|
5
|
+
*
|
|
6
|
+
* Never overwrites unrelated keys. Atomic write via .tmp + rename.
|
|
7
|
+
*/
|
|
8
|
+
export interface ClaudeSettings {
|
|
9
|
+
hooks?: Record<string, Array<{
|
|
10
|
+
matcher?: string;
|
|
11
|
+
hooks: Array<{
|
|
12
|
+
type: 'command';
|
|
13
|
+
command: string;
|
|
14
|
+
}>;
|
|
15
|
+
}>>;
|
|
16
|
+
apiKeyHelper?: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export declare function defaultSettingsPath(): string;
|
|
20
|
+
export interface SetupOptions {
|
|
21
|
+
settingsPath?: string;
|
|
22
|
+
hookCommand?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SetupResult {
|
|
25
|
+
path: string;
|
|
26
|
+
changed: boolean;
|
|
27
|
+
before: ClaudeSettings | null;
|
|
28
|
+
after: ClaudeSettings;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ensure ~/.claude/settings.json has PreToolUse + PostToolUse hooks
|
|
32
|
+
* pointing at `aquaman coder hook` (the canonical unified-CLI form;
|
|
33
|
+
* the `aquaman` binary's `coder` shim execs `aquaman-coder` under the hood).
|
|
34
|
+
*/
|
|
35
|
+
export declare function installClaudeCodeHooks(opts?: SetupOptions): SetupResult;
|
|
36
|
+
/**
|
|
37
|
+
* Remove aquaman coder hooks from settings.json (matches both legacy
|
|
38
|
+
* `aquaman-coder hook` and canonical `aquaman coder hook` forms).
|
|
39
|
+
*/
|
|
40
|
+
export declare function uninstallClaudeCodeHooks(opts?: SetupOptions): SetupResult;
|
|
41
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/adapters/claude-code/setup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,SAAS,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC,CAAC;IACxG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,cAAc,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,YAAiB,GAAG,WAAW,CAsD3E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,GAAE,YAAiB,GAAG,WAAW,CAwC7E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code setup — writes the hook configuration into
|
|
3
|
+
* `~/.claude/settings.json` so Claude Code invokes aquaman-coder on
|
|
4
|
+
* each tool call.
|
|
5
|
+
*
|
|
6
|
+
* Never overwrites unrelated keys. Atomic write via .tmp + rename.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as os from 'node:os';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
export function defaultSettingsPath() {
|
|
12
|
+
return path.join(os.homedir(), '.claude', 'settings.json');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Ensure ~/.claude/settings.json has PreToolUse + PostToolUse hooks
|
|
16
|
+
* pointing at `aquaman coder hook` (the canonical unified-CLI form;
|
|
17
|
+
* the `aquaman` binary's `coder` shim execs `aquaman-coder` under the hood).
|
|
18
|
+
*/
|
|
19
|
+
export function installClaudeCodeHooks(opts = {}) {
|
|
20
|
+
const settingsPath = opts.settingsPath ?? defaultSettingsPath();
|
|
21
|
+
const hookCommand = opts.hookCommand ?? 'aquaman coder hook';
|
|
22
|
+
const dir = path.dirname(settingsPath);
|
|
23
|
+
if (!fs.existsSync(dir)) {
|
|
24
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
25
|
+
}
|
|
26
|
+
let before = null;
|
|
27
|
+
let settings = {};
|
|
28
|
+
if (fs.existsSync(settingsPath)) {
|
|
29
|
+
const raw = fs.readFileSync(settingsPath, 'utf-8');
|
|
30
|
+
try {
|
|
31
|
+
before = JSON.parse(raw);
|
|
32
|
+
settings = JSON.parse(raw);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`Existing ${settingsPath} is not valid JSON: ${err.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
settings.hooks = settings.hooks ?? {};
|
|
39
|
+
for (const event of ['PreToolUse', 'PostToolUse']) {
|
|
40
|
+
const list = settings.hooks[event] ?? [];
|
|
41
|
+
// Match by substring so wrapper-script variants like
|
|
42
|
+
// "/path/to/wrap aquaman coder hook --debug" still count as installed.
|
|
43
|
+
// Also matches the legacy `aquaman-coder hook` form so v0.11.x installs
|
|
44
|
+
// don't get a duplicate appended on upgrade.
|
|
45
|
+
const alreadyInstalled = list.some((entry) => entry.hooks?.some((h) => h.command?.includes('aquaman coder hook') ||
|
|
46
|
+
h.command?.includes('aquaman-coder hook')));
|
|
47
|
+
if (alreadyInstalled)
|
|
48
|
+
continue;
|
|
49
|
+
list.push({
|
|
50
|
+
matcher: '*',
|
|
51
|
+
hooks: [{ type: 'command', command: hookCommand }],
|
|
52
|
+
});
|
|
53
|
+
settings.hooks[event] = list;
|
|
54
|
+
}
|
|
55
|
+
const after = settings;
|
|
56
|
+
const changed = JSON.stringify(before) !== JSON.stringify(after);
|
|
57
|
+
if (changed) {
|
|
58
|
+
const tmp = settingsPath + '.tmp';
|
|
59
|
+
fs.writeFileSync(tmp, JSON.stringify(after, null, 2), { mode: 0o600 });
|
|
60
|
+
fs.renameSync(tmp, settingsPath);
|
|
61
|
+
}
|
|
62
|
+
return { path: settingsPath, changed, before, after };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Remove aquaman coder hooks from settings.json (matches both legacy
|
|
66
|
+
* `aquaman-coder hook` and canonical `aquaman coder hook` forms).
|
|
67
|
+
*/
|
|
68
|
+
export function uninstallClaudeCodeHooks(opts = {}) {
|
|
69
|
+
const settingsPath = opts.settingsPath ?? defaultSettingsPath();
|
|
70
|
+
const hookCommand = opts.hookCommand ?? 'aquaman coder hook';
|
|
71
|
+
if (!fs.existsSync(settingsPath)) {
|
|
72
|
+
return { path: settingsPath, changed: false, before: null, after: {} };
|
|
73
|
+
}
|
|
74
|
+
const raw = fs.readFileSync(settingsPath, 'utf-8');
|
|
75
|
+
const before = JSON.parse(raw);
|
|
76
|
+
const settings = JSON.parse(raw);
|
|
77
|
+
if (settings.hooks) {
|
|
78
|
+
for (const event of Object.keys(settings.hooks)) {
|
|
79
|
+
settings.hooks[event] = settings.hooks[event]
|
|
80
|
+
.map((entry) => ({
|
|
81
|
+
...entry,
|
|
82
|
+
hooks: entry.hooks.filter((h) => !h.command?.includes('aquaman coder hook') &&
|
|
83
|
+
!h.command?.includes('aquaman-coder hook')),
|
|
84
|
+
}))
|
|
85
|
+
.filter((entry) => entry.hooks.length > 0);
|
|
86
|
+
if (settings.hooks[event].length === 0) {
|
|
87
|
+
delete settings.hooks[event];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
91
|
+
delete settings.hooks;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const changed = JSON.stringify(before) !== JSON.stringify(settings);
|
|
95
|
+
if (changed) {
|
|
96
|
+
const tmp = settingsPath + '.tmp';
|
|
97
|
+
fs.writeFileSync(tmp, JSON.stringify(settings, null, 2), { mode: 0o600 });
|
|
98
|
+
fs.renameSync(tmp, settingsPath);
|
|
99
|
+
}
|
|
100
|
+
return { path: settingsPath, changed, before, after: settings };
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/adapters/claude-code/setup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAC7D,CAAC;AAcD;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAqB,EAAE;IAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,EAAE,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAE7D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,GAA0B,IAAI,CAAC;IACzC,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAClC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;YAC3C,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,YAAY,YAAY,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACzC,qDAAqD;QACrD,uEAAuE;QACvE,wEAAwE;QACxE,6CAA6C;QAC7C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3C,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC;YACzC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAC1C,CACF,CAAC;QACF,IAAI,gBAAgB;YAAE,SAAS;QAE/B,IAAI,CAAC,IAAI,CAAC;YACR,OAAO,EAAE,GAAG;YACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SACnD,CAAC,CAAC;QACH,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC;IACvB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAEjE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,YAAY,GAAG,MAAM,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAqB,EAAE;IAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,EAAE,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAE7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAEnD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;iBAC1C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACf,GAAG,KAAK;gBACR,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9B,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC;oBAC1C,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAC3C;aACF,CAAC,CAAC;iBACF,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC7C,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvC,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7C,OAAO,QAAQ,CAAC,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,YAAY,GAAG,MAAM,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broker client — talks to the aquaman-proxy daemon over UDS to
|
|
3
|
+
* materialize credentials per tool call.
|
|
4
|
+
*
|
|
5
|
+
* Wraps `POST /broker/resolve` with retry, timeout, and clean errors.
|
|
6
|
+
*/
|
|
7
|
+
export interface BrokerResolveOptions {
|
|
8
|
+
service: string;
|
|
9
|
+
key: string;
|
|
10
|
+
ttlSeconds?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface BrokerResolveResult {
|
|
13
|
+
value: string;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
}
|
|
16
|
+
export interface BrokerClientOptions {
|
|
17
|
+
socketPath?: string;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function defaultSocketPath(): string;
|
|
21
|
+
export declare class BrokerClient {
|
|
22
|
+
private socketPath;
|
|
23
|
+
private timeoutMs;
|
|
24
|
+
constructor(opts?: BrokerClientOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Materialize a credential. Throws if the proxy is unreachable,
|
|
27
|
+
* the credential is not found, or the request is policy-denied.
|
|
28
|
+
*/
|
|
29
|
+
resolve(opts: BrokerResolveOptions): Promise<BrokerResolveResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Check whether the proxy is up and responsive.
|
|
32
|
+
*/
|
|
33
|
+
health(): Promise<{
|
|
34
|
+
status: string;
|
|
35
|
+
version?: string;
|
|
36
|
+
}>;
|
|
37
|
+
private request;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=broker-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-client.d.ts","sourceRoot":"","sources":["../src/broker-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,GAAE,mBAAwB;IAK1C;;;OAGG;IACG,OAAO,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA+BvE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ7D,OAAO,CAAC,OAAO;CA6ChB"}
|